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
cgame: parse modelRotation for player models, fix modelScale #2988
base: master
Are you sure you want to change the base?
Conversation
What is this needed for? The cgame model code really sucks by the way. The code for different categories of thing (weapon/player/buildable/etc.) all randomly works differently for no reason. When using the same model as both a weapon and a missile I found that not only did they turn out different sizes; on one of them (but not the other) the faces were actually inside out and I had to set RF_SWAPCULL. So it would be unfortunate if we added a bunch of rotation code with no documentation as to what the angles are and resulting in a different effect in each place it is used. |
1. Unifying file syntax and feature supportWe support About
The purpose is precisely to track down and reduce some of those discrepancies. It's a step forward unifying the features and code. At some point after doing steps like this after other steps like this we may become able to make reusable functions usable for all models kinds. 2. Compatibility with legacy assetsWe have different models that have a different rotation in static position (when displayed without animation) than in animations. Basically it happens that some ouf our modelers, when they had to rotate their model to fit in the game, rotated the animation instead of the model. The medistation is one of them, to be displayed properly in both netradiant and in game, it is orientated at asset build time in the way the base position (not animated) is correct, since netradiant doesn't play animations. But then it is rotated in-game using On the left, static position (no animation), on the right, animation position (first frame): On the left is how those models are displayed on every model editor/viewer not playing any animations, on the right is how it would display when animated in game if we don't workaround the model rotation in game. I don't know why the medistation animation is rotated (we can do it in game), but the fact the human animation is rotated is very likely a bad workaround from the animator because of the lack of We now have a tool that can rotate a IQM model with its skeleton and animations at build time, but we did not have this at the time. The last people having put his hands onto the model before inclusion in game was the one who did the animation, and he likely received a non-animated model from the modeler that was using another projection convention and rotated the model at this point to fit the need of the game. But being an animator, he rotated the animation in his animation editor. The medistation rotation is likely because of the same reason but with the animator not knowing there was a It is important that the static position in a model is the right one. For buildables, it is because NetRadiant displays the model for buildables entities. For human models, the need for display in NetRadiant is less common, but it was not rare to bake player models as decorations in maps (there are usages that fit the lore), and both NetRadiant and q3map2 rely on the static rotation for display and baking. One can also temporarily import the models in map editor to check the map compatibility with the it, like the model size, this is why I make efforts that the static pose of our models in dpk archives we distributes are always using the correct scale and rotation, even if the game has to scale/rotate it back if the animator made a mistake and scaled/rotated the animations. It would be better to fix the animation rotation and scale, while keeping the static rotation and scale unmodified, but this requires skills that are harder to find. And we're lacking this skill for years now, even myself don't know how to rotate them separately. 3. Compatibility with third-party assetsIt's good to provide a way for a modder to be able to import a model and make it compatible with the game just by writing two lines in the |
That's my fault. I didn't know proper coding practices back then. |
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.
Need to address comments in CG_Corpse too
@@ -2733,7 +2733,7 @@ void CG_Player( centity_t *cent ) | |||
int renderfx; | |||
entityState_t *es = ¢->currentState; | |||
class_t class_ = (class_t) ( ( es->misc >> 8 ) & 0xFF ); | |||
float scale; | |||
const classModelConfig_t *cmc = BG_ClassModelConfig( class_ ); |
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.
You should use ci->modelScale
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.
The ci->modelScale
value comes from the character.cfg
, not from the .model.cfg
file.
The ci->modelScale
value is then sent to the engine for the in-engine scaling.
Setting a non-1 scale in both character.cfg
and cmc->modelScale
will probably multiply the scales, we may do the multiplication in cgame and delete the scaling code in engine, but that is out of scope of this PR.
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.
The model code is messed up right now. I recommend sticking with the status quo for now instead of having multiplied scales. We can refactor and bring consistency later.
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'm not saying we want to multiply the scale, I'm just guessing what is happening if both mechanisms exist and are used.
Actually the modelScale in character.cfg
looks like a hack. Quoting the human model character.cfg
:
// modelScale is used to customize player models made originally for Quake4
// Quake4 player models are taller than Q3A player models and need to be sized down
// by a factor of 0.83 in each coordinate axis
// if modelScale is not specified it defaults to 1 1 1
There is no modelScale
in ioq3 neither in etlegacy. It looks to be a quirk inherited from XreaL. Doing it in character.cfg
is hacky, we better do it in .model.cfg
files like buildables and missiles already do. The implementation itself is hacky.
Actually once this is merged I will probably go next by NUKING the character.cfg
's modelScale feature from both cgame and engine (and then multiplication will not be a concern).
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.
Then let's bring zOffset too, since that is a model characteristic in the character.cfg
} | ||
|
||
// Apply scale from config. | ||
if ( cmc->modelScale != 1.0f ) |
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.
Only if not skeletal. Skeleton scaling is done in CG_TransformSkeleton.
How can copy and pasting the same code to several places be good from this point of view? It just adds to the stuff that would have to be cleaned up to make reusable code. |
Bug fix:
The
modelScale
field fromconfigs/classes/*.model.cfg
was unused with skeletals models, unlikeconfigs/buildables/*.model.cfg
andconfigs/missiles/*.model.cfg
.Feature implementation:
The
modelRotation
field was not implemented inconfigs/classes/*.model.cfg
, unlikeconfigs/buildables/*.model.cfg
andconfigs/missiles/*.model.cfg
.Clean-up:
A
MODEL_ROTATION
enum value was set but had no usage.