Skip to content
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

Revamp "AnimationContext" Docs, now called "AnimTaskQueue" #1941

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

fig02
Copy link
Collaborator

@fig02 fig02 commented Apr 11, 2024

I got sent down a rabbit hole while doing Player docs which required a better understanding of what we used to call "AnimationContext".

After learning about it, I decided the current names for basically all of this system could be improved. After a few iterations I ended up calling it the "AnimTaskQueue" and changed a bunch of terminology throughout.
It sounds quite generic, but it kinda has to be. The various tasks aren't very correlated, other than the fact that they are related to animations.

All of the relevant functions in skelanime have comments at the top that hopefully explain everything, but let me know if anything else needs to be clarified.

@fig02 fig02 changed the title Revamp "AnimContext" Docs, now called "AnimTaskQueue" Revamp "AnimationContext" Docs, now called "AnimTaskQueue" Apr 11, 2024
@fig02 fig02 changed the title Revamp "AnimationContext" Docs, now called "AnimTaskQueue" Revamp "AnimationContext" Docs, now called "AnimationTaskQueue" Apr 11, 2024
@fig02 fig02 changed the title Revamp "AnimationContext" Docs, now called "AnimationTaskQueue" Revamp "AnimationContext" Docs, now called "AnimTaskQueue" Apr 11, 2024
include/z64animation.h Outdated Show resolved Hide resolved
/* 0x004 */ Vec3s* dst;
/* 0x008 */ Vec3s* src;
} AnimEntryCopyAll; // size = 0xC
/* 0x00 */ u8 group;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

group makes it sound like this is an id, but I was surprised to find that this is a bitset. Maybe groups or groupFlags?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if this became clear as you read more of the code, but its always going to be just one group number. it is handled with bits yes, but this value within each task will never hold multiple groups/bit numbers. it is a single group number that increments as "1, 2, 4, 8..." instead of "1, 2, 3..."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I still think conceptually the group ids are 0, 1, 2, ... and that this field really represents 1 << group rather than the group id itself. Maybe a comment to that effect?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can think of them as "regular" incrementing number sure, but the system never operates on it that way. The current group number is initialized with 1 (bit position 0) and incremented with <<= 1.
I would feel different if there was some interface with which a user can pass a group number as a "whole number" and the system does the shifting interpretation on its end. but this isnt the case.

It could be called a groupBit or something, but this is being more obtuse than needed imo, its still a single number that identifies a group, even if it doesnt count up normally.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I think sDisableAnimQueueFlags/sDisabledTransformTaskGroups is important here. It doesn't really make sense to or-together the different group ids; normally the only thing you're allowed to do with ids is compare them for equality. And the if (!(task->group & sDisabledTransformTaskGroups)) is also pretty mysterious.

But it becomes clearer if you think of sDisabledTransformTaskGroups as a bitset where each bit represents a group i.e. group 0 is represented by bit 0, group 1 is represented by bit 1, and so on. Then group and sCurAnimTaskGroup are also group bitsets with one element set, or (1 << group_num) where group_num is the "real" group number (although it's never actually written down anywhere), and so if (!(task->group & sDisabledTransformTaskGroups)) is testing whether the group number is contained in the set of disabled groups.

In summary: I still think this and sCurAnimTaskGroup should be thought of as (1 << group_num), rather than single number that identifies a group, based on how sDisabledTransformTaskGroups is used. I think the names and comments should hint at that. Maybe group and sCurAnimTaskGroup is fine and my issue is more with the comment wording, the comments seem to treat this bit-twiddling as some kind of arcane implementation detail but it becomes easier to explain if you treat group numbers as bit numbers rather than powers of 2.

Copy link
Contributor

@mzxrules mzxrules Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignoring the id value aspect thing for a moment, I don't understand what's being "grouped"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different tasks or "entries" are being grouped together. Then, when AnimTaskQueue_DisableTransformTasksForGroup is called, the "transformative tasks" only for the currently active group (at the time of calling) will be skipped for that frame.

In practice, there are only two "groups" that get used. all of Links anim tasks are in one group, and all other actors tasks are in another. This lets Link disable the transformative tasks for his stuff, without affecting others.
The same could be done in reverse, but AnimTaskQueue_DisableTransformTasksForGroup is only called by player.

src/code/z_skelanime.c Outdated Show resolved Hide resolved
* Task groups allow for disabling "transformative" tasks for a defined group.
* For more information see `AnimTaskQueue_DisableTransformTasksForGroup`.
*
* Note that `sCurAnimTaskGroup` is not a whole number that increments, it is handled at the bit-level.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer this comment to go on sCurAnimTaskGroup instead (something like that this is a bitset where exactly one bit it set for the current group)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I was learning about this system for the first time I personally would first look at functions that interface with the system, rather than the piece of data itself. Maybe its worth commenting on both idk

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to look at the data first. As the saying goes: "Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won’t usually need your flowcharts; they’ll be obvious."

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Group numbers are indicated by a single bit that increments by shifting 1 position to the left. See AnimTaskQueue_SetNextGroup for more details"

would you be fine with this comment on the data member?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something general about group numbers would be helpful, but for the data members I'd prefer the comment to be more precise about what the data member itself represents, e.g.

// A bitset where the `i`th bit is set if the `i`th task group is disabled.
static u32 sDisabledTransformTaskGroups = 0;
// `(1 << i)` where `i` is the current task group.
static u32 sCurAnimTaskGroup;

Armed with this knowledge, the reader can guess that sCurAnimTaskGroup <<= 1 is conceptually incrementing the "current task group", and something like sCurAnimTaskGroup & sDisabledTransformTaskGroups is testing whether the "current task group" is "disabled".

include/z64animation.h Show resolved Hide resolved
src/code/z_skelanime.c Outdated Show resolved Hide resolved
src/code/z_skelanime.c Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants