New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Player doc: some rotation logic/data #1443
base: main
Are you sure you want to change the base?
Conversation
include/z64player.h
Outdated
@@ -557,15 +567,11 @@ typedef struct Player { | |||
/* 0x06A8 */ Actor* unk_6A8; | |||
/* 0x06AC */ s8 unk_6AC; | |||
/* 0x06AD */ u8 unk_6AD; | |||
/* 0x06AE */ u16 unk_6AE; | |||
/* 0x06B0 */ s16 unk_6B0; | |||
/* 0x06AE */ u16 rotsNoRestFlags; // See `NOREST_ROT_` macros. If its flag isn't set, a rot steps to a rest value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why "No Rest"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when the flag is set, the rotation does not step to a rest value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Next question, what is a rest value? Something like the idle value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question and I'm open to suggestions on changing that
I got the term from Blender (a 3d modeling piece of software https://www.blender.org/ ), let me define a few terms
- armature = skeleton, made of bones
- pose = rotations and locations of the bones in an armature
For example when animated the armature has a different pose every frame
The "rest pose" is the pose the armature has when all its bones aren't transformed (all rotations/translations/... are 0/identity)
Back to OoT, all rotations involved with NOREST_ROT_
are stepped to 0 when their flag isn't set
For all these rotations, 0 corresponds visually to a neutral pose of Link, with only the animation affecting his bones, so I refered to those as "rest" values
Also the use case for these flags is when setting these rots to specific values, typically to look at something, which also can be seen as deviating from the "rest" animation-provided pose
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you maybe think of this as a "hold and release" system? So the rot
is held to a target when the flag is set, and released back to rest when the flag is unset? So something like HOLD_ROT_
? Or would that conflate with the "HOLD" action of "holding" something above Link's Head?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's because no rest
is two words, so it feels more separate, while non-rest
is one word, so it's easier to group together as a single concept?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to review the pr in full again, but I think in general itd be good to try a positive name instead of a negative one, like "modified" instead of "no rest" (which i interpret to mean "non default, offset from the rotation the animation is applying)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is related to three rotations / rotation offsets: focus, head, upper (body)
I'm not sure what's up with the focus one, but head and upper are I guess used to make Link face something
The flags control if these rotations are stepped toward "0" (not actually always 0 but something that is "normal"/"default" hence "rest")
- flag unset = rotations are stepped toward "0"
- flag set = rotations are not stepped toward "0"
Phrased this way it makes it arduous to make a positive name but I'm not sure how to phrase it another way
maybe like "flag set = rot is active" but idk I don't have many ideas
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can tell down below, it seems like setting this flag just stops rotation back to the rest position (0). You might have been slightly joking, but activeRot
doesn't seem too bad. Could possibly also do something like stayRot/remainRot
, or maybe keepRot
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just brainstorming: what about something a little more general like overrideRot
or overrideRotFlags
, and leave it to the comments to describe that the default behaviour is to restore the rot to resting position, and that by setting this flag, it gives you manual control to control the rotations?
* | ||
* @return The amount by which the value overflowed the absolute range defined by `overflowRange` | ||
*/ | ||
s32 Player_ScaledStepBinangClamped(s16* pValue, s16 target, s16 step, s16 overflowRange, s16 constraintMid, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if Constrained
should be used instead of Clamped
in some way.
Player_ScaledStepBinangConstrained
Player_ConstrainedBinangScaledStep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the args are named with constraint
, I think this would make sense.
200, 4000, this->headLimbRot.x, 10000); | ||
|
||
// Step the upper body and head yaw to the focus yaw. | ||
// Eventually prefers turning the upper body rather than the head. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does Eventually
mean here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When turning towards something, both the head and upper body rotate towards the target
Since the head is attached to the upper body (citation needed), it turns faster overall and faces the target before the upper body does
The upper body then continues to turn towards the target, with the head turning backwards to accommodate for the upper body rotating and to keep looking the right way
So eventually the upper body is turned towards the target, with the head actually having no rotation of its own (relative to the upper body)
Does that make sense?
(at least this is what I understood of this when I first looked at it and wrote this. maybe it's wrong 😰 )
include/z64player.h
Outdated
/* 0x06B6 */ Vec3s headLimbRot; | ||
/* 0x06BC */ Vec3s upperLimbRot; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Limb
necessary here? Which limbs are encompassed in upperLimbRot
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It corresponds to PLAYER_LIMB_UPPER
include/z64player.h
Outdated
/* 0x06AE */ u16 unk_6AE; | ||
/* 0x06B0 */ s16 unk_6B0; | ||
/* 0x06AE */ u16 rotsNoRestFlags; // See `NOREST_ROT_` macros. If its flag isn't set, a rot steps to a rest value. | ||
/* 0x06B0 */ s16 upperLimbYawSecondary; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/* 0x06B0 */ s16 upperLimbYawSecondary; | |
/* 0x06B0 */ s16 upperLimbYawOffset; |
Maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not
"secondary" is because
if (!(this->rotsNoRestFlags & NOREST_ROT_UPPER_Y)) {
if (this->upperLimbYawSecondary != 0) {
Player_ApproachZeroBinang(&this->upperLimbYawSecondary);
} else {
Player_ApproachZeroBinang(&this->upperLimbRot.y);
}
}
, it steps this one to 0 before the main one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the name of "upper limb" needs to change at some point, but obv not in scope here
I tried to document TargetContext but there were too many player unks in the way, including these
Take that, player unks