For lerped frames (refEntity_t frame not equal oldframe) IQM joint
matrices may have incorrect axis scale. This can cause significant model
distortion. The matrix lerp is linear causing each vector to move in a
straight line between frames instead of arcing like a circle. Each joint
frame can have a different scale so can't just normalize the joint
matrix.
Store joints as quaternions and spherical lerp between them and then
convert to a matrix. For my test model, setting up the skeleton is four
times slower now but it still seems to be fast enough to be usable.
Bounds are optional for animated IQM models but are not possible to
include with unanimated models (seems intended for use with separate
model containing animations and bounds). Calculating bounds for
unanimated IQM models fixes culling and head model on HUD which
calculates position from model bounds.
The axis returned for IQM tag was the animation's joint rotation without
the base frame joint rotation. It only worked correct for models that
did not rotate the base frame joints.
Using GPU vertex skinning is significantly faster than CPU vertex
skinning. Especially since OpenGL2 has to run R_VaoPackNormal() and
R_VaoPackTangent() each vertex each frame which causes CPU vertex
skinning to be significantly slower than OpenGL1 renderer.
Only calculate vertex blend matrix for each unique bone indexes/weights
combination once per-surface instead of recalculating for each vertex.
For best performance the model surfaces needs to use few vertex bone
indexes and weights combinations.
Unroll loops so GCC better optimizes them.
In my tests drawing animated IQM may take 50% as long in opengl1 and
70% as long in opengl2. It will vary by model though and might not
help much at all.
Made unanimated IQM models skip matrix math altogether.
- Only allocate memory for vertex arrays that are present in the IQM
file and are actually used (may not have colors or blend index/weights,
don't load tangents in opengl1). (Colors is fixed to next commit.)
- Explicitly handle loading IQM files without meshes (bones only).
- Better IQM validation. Header data offset 0 mean data is not present
in file. Check if required vertex arrays are present.
This involved a lot of white space changes and moving code around.
Models don't have a surface limit; skins shouldn't either. Some player
models require more than 32 surfaces since vanilla Quake 3 did not
enforce the limit.
Skins are now limited to 256 surfaces because having no limit would
require parsing the skin file twice. The skin surfaces are dynamically
allocated so it doesn't increase memory usage when less surfaces
are used.
Set the variables that use tess.numVertexes after calling RB_CHECKOVERFLOW() as it may set tess.numVertexes to 0!
Could cause visual issues and error "RB_EndSurface() - SHADER_MAX_VERTEXES hit".
It use to return pose joint's offset from base at the lerped frame, now it returns the joint's origin at the lerped frame.
Patch by Axel Isouard and Zack Middleton.