Created attachment 2949[details]
IQM joint matrices fix
The joint matrices calculated when loading an IQM don't match the ones the IQM example code uses. This causes the model to appear deformed when rendered.
Here's a patch that fixes it, based on the IQM demo.cpp code (which is public domain).
Created attachment 2950[details]
IQM joint matrices fix - gimhael's suggestions version
After corresponding with gimhael, he mentioned that there were a couple bugs that if fixed might fix the problem. I wrote a patch and tested it, and this version does work, and has a smaller footprint.
I tend to think my old patch is more straightforward, and I can (and have) optimize it on my side to have fewer math ops, but this is just nitpicking at this point.
Thank you. I don't care much about the patch's footprint since most independent projects wont have changed this code anyways.
Which of the two solutions is the best in terms of maintainability/speed?
With maintainability I mean deviation from the IQM sample implementation, and how much effort it takes to try to understand the code
The IQM format uses quaternions to store the rotation part of the joint matrixes.
For the animation it also needs the inverse joint matrixes. The reference implementation just uses an adhoc matrix inversion algorithm while I computed the same result by computing the matrix of the inverse quaternion (but I made some mistakes so it worked only when scale == 1.0).
The matrix inversion is not a general matrix inversion as you find it in a math book, but it's specialized to the matrixes produced by JointToMatrix, so I was a bit suspicious that it works in all cases and chose the inverse quaternion solution instead. The operational cost of both is basically the same.
Created attachment 2951[details]
IQM joint matrices fix v2
Here's a version of the patch that resembles the example code as much as possible. It's still comparable in performance, 27 mults in this vs. 36 mults in the other patch, though I haven't actually run benchmarks or anything. :)
Outside of that, the easiest to read solution would probably involve writing a proper matrix inversion function, instead of this function which assumes the matrix is a combination of scales, rotations, and translations. I haven't tested this function with non-uniform scales though, so I don't know if it works in all cases.
Readability probably isn't that important as long as it matches the example code though, since it's unlikely to change unless the example code does. Assuming the example code is correct, anyway.
Created attachment 2949 [details] IQM joint matrices fix The joint matrices calculated when loading an IQM don't match the ones the IQM example code uses. This causes the model to appear deformed when rendered. Here's a patch that fixes it, based on the IQM demo.cpp code (which is public domain).
Created attachment 2950 [details] IQM joint matrices fix - gimhael's suggestions version After corresponding with gimhael, he mentioned that there were a couple bugs that if fixed might fix the problem. I wrote a patch and tested it, and this version does work, and has a smaller footprint. I tend to think my old patch is more straightforward, and I can (and have) optimize it on my side to have fewer math ops, but this is just nitpicking at this point.
Created attachment 2951 [details] IQM joint matrices fix v2 Here's a version of the patch that resembles the example code as much as possible. It's still comparable in performance, 27 mults in this vs. 36 mults in the other patch, though I haven't actually run benchmarks or anything. :) Outside of that, the easiest to read solution would probably involve writing a proper matrix inversion function, instead of this function which assumes the matrix is a combination of scales, rotations, and translations. I haven't tested this function with non-uniform scales though, so I don't know if it works in all cases. Readability probably isn't that important as long as it matches the example code though, since it's unlikely to change unless the example code does. Assuming the example code is correct, anyway.