149{
151 m_pSkeleton->GetKeyLibraryInstance().GetLibrary() !=
TNULL )
152 {
154
155 const auto QInterpFn = m_pSkeleton->GetQInterpFn();
156 TFLOAT fOneOverTotalWeight = 1.0f;
157
158 if ( 1.0f < m_fTotalWeight )
159 fOneOverTotalWeight = 1.0f / m_fTotalWeight;
160
162
163 for (
TINT i = 0; i < m_pSkeleton->GetAutoBoneCount(); i++ )
164 {
166
168 auto pBone = m_pSkeleton->GetBone( i );
169
170 if ( m_BaseAnimations.IsEmpty() )
171 {
172 rBoneCache.Rotation = pBone->GetRotation();
173 rBoneCache.Position = pBone->GetPosition();
174 }
175 else
176 {
177 TFLOAT fWeightTotalRatio = 0.0f;
179
181 {
182 auto pSeq = m_pSkeleton->GetSequence( it->GetSequence() );
183 auto pSeqBone = pSeq->GetBone( i );
184
185 TINT iCurrentKeyframePos =
TINT( ( it->GetSeqTime() / pSeq->GetDuration() ) * 65535 );
186
189 TFLOAT fLerpProgress = pSeqBone->GetKeyPair( iCurrentKeyframePos, *it->GetBone( i ), iLerpFromIndex, iLerpToIndex );
190
191 TFLOAT fWeightRatio = it->GetWeight() * fOneOverTotalWeight;
192
193 if ( fWeightRatio > 0.0f && pSeqBone->GetKeyCount() != 0 )
194 {
195 auto pFromKey = pSeqBone->GetKey( iLerpFromIndex );
196 auto pToKey = pSeqBone->GetKey( iLerpToIndex );
197
198 auto& rKeyLibrary = m_pSkeleton->GetKeyLibraryInstance();
199 auto pFromQuat = rKeyLibrary.GetQ( pFromKey[ 1 ] );
200 auto pToQuat = rKeyLibrary.GetQ( pToKey[ 1 ] );
201
202 if ( it == m_BaseAnimations.Head() )
203 {
204 bBoneHasState =
TTRUE;
205 fWeightTotalRatio = fWeightRatio;
206 QInterpFn( rBoneCache.Rotation, *pFromQuat, *pToQuat, fLerpProgress );
207
208 if ( pSeqBone->IsTranslateAnimated() )
209 {
210 auto pFromTranslation = rKeyLibrary.GetT( pFromKey[ 2 ] );
211 auto pToTranslation = rKeyLibrary.GetT( pToKey[ 2 ] );
212
213 rBoneCache.Position.Lerp( *pFromTranslation, *pToTranslation, fLerpProgress );
214 }
215 else
216 {
217 rBoneCache.Position = pBone->GetPosition();
218 }
219 }
220 else
221 {
222 TVector4 position;
223 TQuaternion rotation;
224
225 QInterpFn( rotation, *pFromQuat, *pToQuat, fLerpProgress );
226
227 if ( pSeqBone->IsTranslateAnimated() )
228 {
229 auto pFromTranslation = rKeyLibrary.GetT( pFromKey[ 2 ] );
230 auto pToTranslation = rKeyLibrary.GetT( pToKey[ 2 ] );
231
232 position.
Lerp3( *pFromTranslation, *pToTranslation, fLerpProgress );
233 }
234
235 fWeightTotalRatio += fWeightRatio;
236 QInterpFn( rBoneCache.Rotation, rBoneCache.Rotation, rotation, fWeightRatio / fWeightTotalRatio );
237
238 const TVector3* pLerpToVec = pSeqBone->IsTranslateAnimated() ? &position.
AsVector3() : &pBone->GetPosition();
239 rBoneCache.Position.
Lerp( *pLerpToVec, fWeightRatio / fWeightTotalRatio );
240 }
241 }
242 }
243
244 if ( !bBoneHasState )
245 {
246 rBoneCache.Rotation = pBone->GetRotation();
247 rBoneCache.Position = pBone->GetPosition();
248 }
249 }
250
252 {
253 if ( it->GetWeight() != 0.0f )
254 {
255 auto pSeq = m_pSkeleton->GetSequence( it->GetSequence() );
256 auto pSeqBone = pSeq->GetBone( i );
257
258 if ( !pSeqBone->IsOverlayAnimated() && pSeqBone->GetKeyCount() != 0 )
259 {
260 TINT iCurrentKeyframePos =
TINT( ( it->GetSeqTime() / pSeq->GetDuration() ) * 65535 );
261
264 TFLOAT fLerpProgress = pSeqBone->GetKeyPair( iCurrentKeyframePos, *it->GetBone( i ), iLerpFromIndex, iLerpToIndex );
265
266 auto pFromKey = pSeqBone->GetKey( iLerpFromIndex );
267 auto pToKey = pSeqBone->GetKey( iLerpToIndex );
268
269 auto& rKeyLibrary = m_pSkeleton->GetKeyLibraryInstance();
270 auto pFromQuat = rKeyLibrary.GetQ( pFromKey[ 1 ] );
271 auto pToQuat = rKeyLibrary.GetQ( pToKey[ 1 ] );
272
273 TVector4 position;
274 TQuaternion rotation;
275
276 QInterpFn( rotation, rBoneCache.Rotation, *pToQuat, fLerpProgress );
277 QInterpFn( rBoneCache.Rotation, rBoneCache.Rotation, rotation, it->GetWeight() );
278
279 const TVector3* pLerpToVec;
280 if ( pSeqBone->IsTranslateAnimated() )
281 {
282 auto pFromTranslation = rKeyLibrary.GetT( pFromKey[ 2 ] );
283 auto pToTranslation = rKeyLibrary.GetT( pToKey[ 2 ] );
284
285 position.
Lerp3( *pFromTranslation, *pToTranslation, fLerpProgress );
287 }
288 else
289 {
290 pLerpToVec = &pBone->GetPosition();
291 }
292
293 rBoneCache.Position.
Lerp( *pLerpToVec, it->GetWeight() );
294 }
295 }
296 }
297
298
300 auto iParentBone = pBone->GetParentBone();
301
303 {
304
305 rMatrix.SetFromQuaternion( rBoneCache.Rotation );
306 rMatrix.SetTranslation( rBoneCache.Position );
307 }
308 else
309 {
310
311 TMatrix44 boneTransform;
315 }
316
317 m_pBones[ i ].m_Transform.Multiply( rMatrix, pBone->GetTransformInv() );
318 }
319 }
320}
LoadLibrary TOSHI_NAMESPACE_START constexpr TINT TANIMATION_MAXBONES
TSystemManager g_oSystemManager
void SetTranslation(const TVector4 &a_rTranslation)
TMatrix44 & SetFromQuaternion(const TQuaternion &a_rQuaternion)
constexpr void Lerp(const TVector3 &finish, float t)
constexpr void Lerp3(const TVector4 &finish, TFLOAT t)
static TMatrix44 g_aForwardMatrices[TANIMATION_MAXBONES]
static BoneCache g_aBonesCaches[TANIMATION_MAXBONES]
TUINT32 GetFrameCount() const