1#include <Core/Animation/HandleArray.hpp>
2#include <Core/Animation/HandleWeight.hpp>
3#include <Core/Animation/LinearBlendSkinning.hpp>
4#include <Core/Animation/Skeleton.hpp>
5#include <Core/Animation/SkinningData.hpp>
6#include <Core/CoreMacros.hpp>
7#include <Core/Geometry/IndexedGeometry.hpp>
10#include <Eigen/Geometry>
11#include <Eigen/SparseCore>
19void linearBlendSkinning(
const SkinningRefData& refData,
20 const Vector3Array& tangents,
21 const Vector3Array& bitangents,
22 SkinningFrameData& frameData ) {
23 const auto& W = refData.m_weights;
24 const auto& vertices = refData.m_referenceMesh.vertices();
25 const auto& normals = refData.m_referenceMesh.normals();
26 const auto& bindMatrix = refData.m_bindMatrices;
27 const auto& pose = frameData.m_skeleton.getPose( HandleArray::SpaceType::MODEL );
28#pragma omp parallel for
29 for (
int i = 0; i < int( frameData.m_currentPosition.size() ); ++i ) {
30 frameData.m_currentPosition[i] = Vector3::Zero();
31 frameData.m_currentNormal[i] = Vector3::Zero();
32 frameData.m_currentTangent[i] = Vector3::Zero();
33 frameData.m_currentBitangent[i] = Vector3::Zero();
35 for (
int k = 0; k < W.outerSize(); ++k ) {
36 const int nonZero = W.col( k ).nonZeros();
37 WeightMatrix::InnerIterator it0( W, k );
38#pragma omp parallel for
39 for (
int nz = 0; nz < nonZero; ++nz ) {
40 WeightMatrix::InnerIterator it = it0 + Eigen::Index( nz );
41 const uint i = it.row();
42 const uint j = it.col();
43 const Scalar w = it.value();
45 const Transform M = refData.m_meshTransformInverse * pose[j] * bindMatrix[j];
47 frameData.m_currentPosition[i] += w * ( M * vertices[i] );
48 frameData.m_currentNormal[i] += w * ( M.linear() * normals[i] );
49 frameData.m_currentTangent[i] += w * ( M.linear() * tangents[i] );
50 frameData.m_currentBitangent[i] += w * ( M.linear() * bitangents[i] );
hepler function to manage enum as underlying types in VariableSet