Radium Engine  1.5.20
Loading...
Searching...
No Matches
LinearBlendSkinning.cpp
1#include <Core/Animation/LinearBlendSkinning.hpp>
2
3#include <Core/Animation/SkinningData.hpp>
4
5namespace Ra {
6namespace Core {
7namespace Animation {
8
9void linearBlendSkinning( const SkinningRefData& refData,
10 const Vector3Array& tangents,
11 const Vector3Array& bitangents,
12 SkinningFrameData& frameData ) {
13 const auto& W = refData.m_weights;
14 const auto& vertices = refData.m_referenceMesh.vertices();
15 const auto& normals = refData.m_referenceMesh.normals();
16 const auto& bindMatrix = refData.m_bindMatrices;
17 const auto& pose = frameData.m_skeleton.getPose( HandleArray::SpaceType::MODEL );
18#pragma omp parallel for
19 for ( int i = 0; i < int( frameData.m_currentPosition.size() ); ++i ) {
20 frameData.m_currentPosition[i] = Vector3::Zero();
21 frameData.m_currentNormal[i] = Vector3::Zero();
22 frameData.m_currentTangent[i] = Vector3::Zero();
23 frameData.m_currentBitangent[i] = Vector3::Zero();
24 }
25 for ( int k = 0; k < W.outerSize(); ++k ) {
26 const int nonZero = W.col( k ).nonZeros();
27 WeightMatrix::InnerIterator it0( W, k );
28#pragma omp parallel for
29 for ( int nz = 0; nz < nonZero; ++nz ) {
30 WeightMatrix::InnerIterator it = it0 + Eigen::Index( nz );
31 const uint i = it.row();
32 const uint j = it.col();
33 const Scalar w = it.value();
34 // prepare the pose w.r.t. the bind matrix and the mesh transform
35 const Transform M = refData.m_meshTransformInverse * pose[j] * bindMatrix[j];
36 // apply LBS
37 frameData.m_currentPosition[i] += w * ( M * vertices[i] );
38 frameData.m_currentNormal[i] += w * ( M.linear() * normals[i] );
39 frameData.m_currentTangent[i] += w * ( M.linear() * tangents[i] );
40 frameData.m_currentBitangent[i] += w * ( M.linear() * bitangents[i] );
41 }
42 }
43}
44
45} // namespace Animation
46} // namespace Core
47} // namespace Ra
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3