Assimp & Collada - wrong animation

Started by Phobeus, June 05, 2017, 20:35:27

Previous topic - Next topic

Phobeus

Hi guys,

I am working since a while on a skeletal animation system for my project and using assimp and the collada format for loading models from blender. While having certain success moments already (static model or default pose seems to be loading fine), I am encoutering certain issues with the actual animation that is going weird at certain points. But lets focus on a single aspect for the moment, I got stuck at the moment.

1. I am not sure how to determinate the number of frames that does exist within the model. My expectation was that there would be at AIAnimation some kind of numFrames that would allow to determinate the amount of frames that exists within the model. How can I determinate it? At the moment, I need to set the amount of frames for each model on my own.

2. The data, I am getting from the model seems to be wrong. For example, in Blender i have a "Bone" having for the first frame a rotation of "x,y,z=0,w=1", second frame of "x,y=0,z=0.383,w=0,0924" and the third being a move back to the original position.

I am basically loading the animation as follow:
private List<KeyFrame> loadKeyFrames(AIAnimation animationData) {
[...]
		PointerBuffer channels = animationData.mChannels();
		for (int ch = 0 ; ch < animationData.mNumChannels(); ch ++) {
			System.out.println("Channel "+ch);
			AINodeAnim channel = AINodeAnim.create(channels.get(ch));			
			for (int frame=0; frame < frames; frame++) {
//				AIVector3D positionData = channel.mPositionKeys().get(frame).mValue();
				AIQuaternion rotationData = channel.mRotationKeys().get(frame).mValue();
				System.out.println("mRot "+ModelUtils.aiQuaternion(rotationData));				
				Quaternionf rotation = new Quaternionf(rotationData.x(), rotationData.y(), rotationData.z(),
						rotationData.w());
				System.out.println("fRot:"+rotation.toString(new DecimalFormat("#.######## ")));
			}			
		}
[...]

The utility method is basically just a string formatter. You can see also the way how I migrate the Quaternion into the lwjgl format. The result for the first channel is as follow:
QuoteDetected channels are 4
Channel 0
mRot #AIQuaternion [x=0.70710677,y=0.0,z=0.0,w=0.70710677]
fRot:(0,70710677  0  0  0,70710677 )
mRot #AIQuaternion [x=0.65328145,y=-0.27059805,z=0.27059805,w=0.6532815]
fRot:(0,65328145  -0,27059805  0,27059805  0,65328151 )
mRot #AIQuaternion [x=0.70710677,y=0.0,z=0.0,w=0.70710677]
fRot:(0,70710677  0  0  0,70710677 )
mRot #AIQuaternion [x=0.65328145,y=0.27059805,z=-0.27059805,w=0.6532815]
fRot:(0,65328145  0,27059805  -0,27059805  0,65328151 )
mRot #AIQuaternion [x=0.70710677,y=0.0,z=0.0,w=0.70710677]
fRot:(0,70710677  0  0  0,70710677 )
As you can see, the migration does not make a difference. However I am having lots of value I am actually not expecting from what I see at blender. The first rotation should not have any rotation for the bone after all, but it seems to be rotated.

I assume that this would be rather something stupid, but I would like to understand why the values does not match the expected onces from what I can see in blender. Especially as the code is not doing any manipulation with the data. Is this a bug in a blender exporter, assimp or did I miss some other information? I am really starting to run out of ideas and appreciate any good hint. The model can be also accessed:  http://phobeus.de/tmp/base-sphere.dae

Many thanks for your help in advance!
Phobeus

spasi

Quote from: Phobeus on June 05, 2017, 20:35:271. I am not sure how to determinate the number of frames that does exist within the model. My expectation was that there would be at AIAnimation some kind of numFrames that would allow to determinate the amount of frames that exists within the model. How can I determinate it? At the moment, I need to set the amount of frames for each model on my own.

The AINodeAnim struct has the mNumPositionKeys, mNumRotationKeys and mNumScalingKeys members. These are the number of frames in the animation. Or you can use .remaining() of the buffer returned by mRotationKeys() for example.

Quote from: Phobeus on June 05, 2017, 20:35:272. The data, I am getting from the model seems to be wrong. For example, in Blender i have a "Bone" having for the first frame a rotation of "x,y,z=0,w=1", second frame of "x,y=0,z=0.383,w=0,0924" and the third being a move back to the original position.

The animation was exported as matrices in the collada file, not quaternions. These are the rotation keys for "Bone":

1 0 0 0
0 0 -1 0
0 1 0 0
0 0 0 1

0.7071068 -0.7071068 0 0
0 0 -1 0
0.7071068 0.7071068 0 0
0 0 0 1

1 0 0 0
0 0 -1 0
0 1 0 0
0 0 0 1

0.7071068 0.7071068 0 0
0 0 -1 0
-0.7071068 0.7071068 0 0
0 0 0 1

1 0 0 0
0 0 -1 0
0 1 0 0
0 0 0 1


Afaict, the quaternion values you're seeing from Assimp have been correctly converted from the above matrices. I don't know why the matrix values are so weird, could be a problem with the export procedure.