Support out of order channels
parent
847573b9ed
commit
8fba4ce7cf
|
@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
@ -461,6 +462,13 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
aiNodeAnim* nodeAnim = new aiNodeAnim;
|
aiNodeAnim* nodeAnim = new aiNodeAnim;
|
||||||
anim->mChannels[a] = nodeAnim;
|
anim->mChannels[a] = nodeAnim;
|
||||||
nodeAnim->mNodeName.Set( nodeName);
|
nodeAnim->mNodeName.Set( nodeName);
|
||||||
|
std::map<BVHLoader::ChannelType, int> channelMap;
|
||||||
|
|
||||||
|
//Build map of channels
|
||||||
|
for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel)
|
||||||
|
{
|
||||||
|
channelMap[node.mChannels[channel]] = channel;
|
||||||
|
}
|
||||||
|
|
||||||
// translational part, if given
|
// translational part, if given
|
||||||
if( node.mChannels.size() == 6)
|
if( node.mChannels.size() == 6)
|
||||||
|
@ -472,15 +480,23 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
{
|
{
|
||||||
poskey->mTime = double( fr);
|
poskey->mTime = double( fr);
|
||||||
|
|
||||||
// Now compute all translations in the right order
|
// Now compute all translations
|
||||||
for( unsigned int channel = 0; channel < 3; ++channel)
|
for(BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel +1))
|
||||||
{
|
{
|
||||||
switch( node.mChannels[channel])
|
//Find channel in node
|
||||||
|
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
|
||||||
|
|
||||||
|
if (mapIter == channelMap.end())
|
||||||
|
throw DeadlyImportError("Missing position channel in node " + nodeName);
|
||||||
|
else {
|
||||||
|
int channelIdx = mapIter->second;
|
||||||
|
switch (channel)
|
||||||
{
|
{
|
||||||
case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channelIdx]; break;
|
||||||
case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channelIdx]; break;
|
||||||
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channelIdx]; break;
|
||||||
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++poskey;
|
++poskey;
|
||||||
|
@ -497,12 +513,6 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
|
|
||||||
// rotation part. Always present. First find value offsets
|
// rotation part. Always present. First find value offsets
|
||||||
{
|
{
|
||||||
unsigned int rotOffset = 0;
|
|
||||||
if( node.mChannels.size() == 6)
|
|
||||||
{
|
|
||||||
// Offset all further calculations
|
|
||||||
rotOffset = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then create the number of rotation keys
|
// Then create the number of rotation keys
|
||||||
nodeAnim->mNumRotationKeys = mAnimNumFrames;
|
nodeAnim->mNumRotationKeys = mAnimNumFrames;
|
||||||
|
@ -512,19 +522,25 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
{
|
{
|
||||||
aiMatrix4x4 temp;
|
aiMatrix4x4 temp;
|
||||||
aiMatrix3x3 rotMatrix;
|
aiMatrix3x3 rotMatrix;
|
||||||
|
for (BVHLoader::ChannelType channel = Channel_RotationX; channel <= Channel_RotationZ; channel = (BVHLoader::ChannelType)(channel + 1))
|
||||||
for( unsigned int channel = 0; channel < 3; ++channel)
|
|
||||||
{
|
{
|
||||||
|
//Find channel in node
|
||||||
|
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
|
||||||
|
|
||||||
|
if (mapIter == channelMap.end())
|
||||||
|
throw DeadlyImportError("Missing rotation channel in node " + nodeName);
|
||||||
|
else {
|
||||||
|
int channelIdx = mapIter->second;
|
||||||
// translate ZXY euler angels into a quaternion
|
// translate ZXY euler angels into a quaternion
|
||||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
|
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
||||||
|
|
||||||
// Compute rotation transformations in the right order
|
// Compute rotation transformations in the right order
|
||||||
switch (node.mChannels[rotOffset+channel])
|
switch (channel)
|
||||||
{
|
{
|
||||||
case Channel_RotationX: aiMatrix4x4::RotationX(angle, temp); rotMatrix *= aiMatrix3x3(temp); break;
|
case Channel_RotationX: aiMatrix4x4::RotationX(angle, temp); rotMatrix *= aiMatrix3x3(temp); break;
|
||||||
case Channel_RotationY: aiMatrix4x4::RotationY(angle, temp); rotMatrix *= aiMatrix3x3(temp); break;
|
case Channel_RotationY: aiMatrix4x4::RotationY(angle, temp); rotMatrix *= aiMatrix3x3(temp); break;
|
||||||
case Channel_RotationZ: aiMatrix4x4::RotationZ(angle, temp); rotMatrix *= aiMatrix3x3(temp); break;
|
case Channel_RotationZ: aiMatrix4x4::RotationZ(angle, temp); rotMatrix *= aiMatrix3x3(temp); break;
|
||||||
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue