void CPUSkinningAlgorithm::transformGeometry( SkinnedGeometry *skinGeo, Skeleton *skel, CPUSkinningDataAttachment *data) { const SkinnedGeometry::MFPropIndicesType *mfOrigIdx = skinGeo->getMFPropIndices(); const SkinnedGeometry::MFPropertiesType *mfOrigProps = skinGeo->getMFProperties(); SkinnedGeometry::MFPropertiesType *mfProps = data->editMFProperties(); const GeoVec4fProperty *jointIdxProp = dynamic_cast<const GeoVec4fProperty *>( (*mfOrigProps)[skinGeo->getJointIndexProperty()]); const GeoVec4fProperty *jointWeightProp = dynamic_cast<const GeoVec4fProperty *>( (*mfOrigProps)[skinGeo->getJointWeightProperty()]); if(skinGeo->getIndex(skinGeo->getJointIndexProperty ()) != skinGeo->getIndex(skinGeo->getJointWeightProperty()) ) { SWARNING << "CPUSkinningAlgorithm::transformGeometry: " << "Multi indexed geometry not supported!" << std::endl; return; } mfProps->resize(mfOrigProps->size(), NULL); const MFMatrix *mfJointMat = NULL; const MFMatrix *mfJointNormalMat = NULL; // if the geometry has a non-identity bind shape matrix // premultiply joint matrices with bind shape matrix and store in data // attachment if(skinGeo->getBindShapeMatrix().equals(Matrix::identity(), Eps) == false) { mfJointMat = skel->getMFJointMatrices (); MFMatrix *mfJointBindMat = data->editMFJointMatrices(); mfJointBindMat->resize(mfJointMat->size()); for(UInt32 i = 0; i < mfJointMat->size(); ++i) { (*mfJointBindMat)[i] = (*mfJointMat)[i]; (*mfJointBindMat)[i].mult(skinGeo->getBindShapeMatrix()); } mfJointMat = data->getMFJointMatrices(); if(skel->getCalcNormalMatrices() == true) { mfJointNormalMat = skel->getMFJointNormalMatrices (); MFMatrix *mfJointNormalBindMat = data->editMFJointNormalMatrices(); mfJointNormalBindMat->resize(mfJointNormalMat->size()); for(UInt32 i = 0; i < mfJointNormalMat->size(); ++i) { (*mfJointNormalBindMat)[i] = (*mfJointNormalMat)[i]; (*mfJointNormalBindMat)[i].mult(skinGeo->getBindShapeMatrix()); } mfJointNormalMat = data->getMFJointNormalMatrices(); } else { mfJointNormalMat = data->getMFJointMatrices(); } } else { mfJointMat = skel->getMFJointMatrices(); if(skel->getCalcNormalMatrices() == true) { mfJointNormalMat = skel->getMFJointNormalMatrices(); } else { mfJointNormalMat = skel->getMFJointMatrices(); } } // transform all properties for(UInt16 i = 0; i < mfProps->size(); ++i) { // do not transform the vertex joint indices/weights if(i == skinGeo->getJointIndexProperty () || i == skinGeo->getJointWeightProperty() ) { continue; } GeoIntegralProperty *origPropIdx = (*mfOrigIdx )[i]; GeoVectorProperty *origProp = (*mfOrigProps)[i]; GeoVectorProperty *prop = (*mfProps )[i]; if(origProp == NULL) continue; if(prop == NULL) { GeoVectorPropertyUnrecPtr newProp = dynamic_pointer_cast<GeoVectorProperty>(origProp->clone()); mfProps->replace(i, newProp); prop = newProp; } else if(prop->size() != origProp->size()) { prop->resize(origProp->size()); } switch(origProp->getUsage() & GeoProperty::UsageSpaceMask) { case GeoProperty::UsageObjectSpace: { transformObjectSpaceProperty( mfJointMat, jointIdxProp, jointWeightProp, origPropIdx, origProp, prop); } break; case GeoProperty::UsageTangentSpace: { transformTangentSpaceProperty( mfJointNormalMat, jointIdxProp, jointWeightProp, origPropIdx, origProp, prop); } break; default: // only need to transform object/tangent space properties break; } } }