- Viewer: additional bugfixes while trying to get the animations to work

- added anim interpolation for anim playback
- Bugfix: FindInvalidDataProcess was still mixed up a bit

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@219 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
ulfjorensen 2008-11-02 17:20:29 +00:00
parent ac200212a9
commit d965f0d06a
5 changed files with 100 additions and 19 deletions

View File

@ -79,6 +79,14 @@ struct aiQuaternion
bool operator!= (const aiQuaternion& o) const
{return !(*this == o);}
/** Performs a spherical interpolation between two quaternions and writes the result into the third.
* @param pOut Target object to received the interpolated rotation.
* @param pStart Start rotation of the interpolation at factor == 0.
* @param pEnd End rotation, factor == 1.
* @param pFactor Interpolation factor between 0 and 1. Values outside of this range yield undefined results.
*/
static void Interpolate( aiQuaternion& pOut, const aiQuaternion& pStart, const aiQuaternion& pEnd, float pFactor);
#endif // __cplusplus
//! w,x,y,z components of the quaternion
@ -197,7 +205,48 @@ inline aiQuaternion::aiQuaternion( aiVector3D normalized)
}
// ---------------------------------------------------------------------------
// Performs a spherical interpolation between two quaternions
// Implementation adopted from the gmtl project. All others I found on the net fail in some cases.
// Congrats, gmtl!
inline void aiQuaternion::Interpolate( aiQuaternion& pOut, const aiQuaternion& pStart, const aiQuaternion& pEnd, float pFactor)
{
// calc cosine theta
float cosom = pStart.x * pEnd.x + pStart.y * pEnd.y + pStart.z * pEnd.z + pStart.w * pEnd.w;
// adjust signs (if necessary)
aiQuaternion end = pEnd;
if( cosom < 0.0f)
{
cosom = -cosom;
end.x = -end.x; // Reverse all signs
end.y = -end.y;
end.z = -end.z;
end.w = -end.w;
}
// Calculate coefficients
float sclp, sclq;
if( (1.0f - cosom) > 0.0001f) // 0.0001 -> some epsillon
{
// Standard case (slerp)
float omega, sinom;
omega = acos( cosom); // extract theta from dot product's cos theta
sinom = sin( omega);
sclp = sin( (1.0f - pFactor) * omega) / sinom;
sclq = sin( pFactor * omega) / sinom;
} else
{
// Very close, do linear interp (because it's faster)
sclp = 1.0f - pFactor;
sclq = pFactor;
}
pOut.x = sclp * pStart.x + sclq * end.x;
pOut.y = sclp * pStart.y + sclq * end.y;
pOut.z = sclp * pStart.z + sclq * end.z;
pOut.w = sclp * pStart.w + sclq * end.w;
}
} // end extern "C"
#endif // __cplusplus

View File

@ -89,8 +89,15 @@ void AnimEvaluator::Evaluate( double pTime)
frame++;
}
// TODO: (thom) interpolation maybe?
presentPosition = channel->mPositionKeys[frame].mValue;
// interpolate between this frame's value and next frame's value
unsigned int nextFrame = (frame + 1) % channel->mNumPositionKeys;
const aiVectorKey& key = channel->mPositionKeys[frame];
const aiVectorKey& nextKey = channel->mPositionKeys[nextFrame];
double diffTime = nextKey.mTime - key.mTime;
if( diffTime < 0.0)
diffTime += mAnim->mDuration;
float factor = (time - key.mTime) / diffTime;
presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
mLastPositions[a].get<0>() = frame;
}
@ -106,8 +113,16 @@ void AnimEvaluator::Evaluate( double pTime)
frame++;
}
// TODO: (thom) quaternions are a prime target for interpolation
presentRotation = channel->mRotationKeys[frame].mValue;
// interpolate between this frame's value and next frame's value
unsigned int nextFrame = (frame + 1) % channel->mNumRotationKeys;
const aiQuatKey& key = channel->mRotationKeys[frame];
const aiQuatKey& nextKey = channel->mRotationKeys[nextFrame];
double diffTime = nextKey.mTime - key.mTime;
if( diffTime < 0.0)
diffTime += mAnim->mDuration;
float factor = (time - key.mTime) / diffTime;
aiQuaternion::Interpolate( presentRotation, key.mValue, nextKey.mValue, factor);
mLastPositions[a].get<1>() = frame;
}

View File

@ -697,10 +697,11 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SKINNING \n"
"float4 weights = IN.BlendWeights; \n"
"weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
"float3 objPos = mul( IN.Position, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
"objPos += mul( IN.Position, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
"objPos += mul( IN.Position, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
"objPos += mul( IN.Position, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
"float4 localPos = float4( IN.Position, 1.0f); \n"
"float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
"objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
"objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
"objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
"#else \n"
"float3 objPos = IN.Position; \n"
"#endif // AV_SKINNING \n"
@ -733,10 +734,11 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SKINNING \n"
"float4 weights = IN.BlendWeights; \n"
"weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
"float3 objPos = mul( IN.Position, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
"objPos += mul( IN.Position, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
"objPos += mul( IN.Position, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
"objPos += mul( IN.Position, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
"float4 localPos = float4( IN.Position, 1.0f); \n"
"float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
"objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
"objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
"objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
"#else \n"
"float3 objPos = IN.Position; \n"
"#endif // AV_SKINNING \n"
@ -770,10 +772,11 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SKINNING \n"
"float4 weights = IN.BlendWeights; \n"
"weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
"float3 objPos = mul( IN.Position, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
"objPos += mul( IN.Position, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
"objPos += mul( IN.Position, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
"objPos += mul( IN.Position, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
"float4 localPos = float4( IN.Position, 1.0f); \n"
"float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
"objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
"objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
"objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
"#else \n"
"float3 objPos = IN.Position; \n"
"#endif // AV_SKINNING \n"

View File

@ -65,7 +65,6 @@ Global
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug_DLL|x64.Build.0 = Debug_DLL|x64
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug|Win32.ActiveCfg = Debug|Win32
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug|x64.ActiveCfg = Debug|x64
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug|x64.Build.0 = Debug|x64
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release_DLL|Win32.ActiveCfg = Release_DLL|Win32
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release_DLL|Win32.Build.0 = Release_DLL|Win32
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release_DLL|x64.ActiveCfg = Release_DLL|x64
@ -78,7 +77,6 @@ Global
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug_DLL|x64.ActiveCfg = Debug|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|Win32.ActiveCfg = Debug|Win32
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|x64.ActiveCfg = Debug|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|x64.Build.0 = Debug|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|Win32.ActiveCfg = Release|Win32
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|x64.ActiveCfg = Release|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|Win32.ActiveCfg = Release|Win32

View File

@ -836,6 +836,14 @@
RelativePath="..\..\code\SceneCombiner.h"
>
</File>
<File
RelativePath="..\..\code\ScenePreprocessor.cpp"
>
</File>
<File
RelativePath="..\..\code\ScenePreprocessor.h"
>
</File>
<File
RelativePath="..\..\code\SGSpatialSort.cpp"
>
@ -963,6 +971,14 @@
<Filter
Name="Loaders"
>
<File
RelativePath="..\..\code\Q3DLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\Q3DLoader.h"
>
</File>
<Filter
Name="3DS"
>