RotateCommand.cpp dnacalib/commands/RotateCommand.h dnacalib/CommandImplBase.h dnacalib/dna/DNA.h dnacalib/dna/DNACalibDNAReaderImpl.h dnacalib/types/Aliases.h dnacalib/utils/Algorithm.h tdm/TDM.h dnac::RotateCommand::Impl dnac //CopyrightEpicGames,Inc.AllRightsReserved. #include"dnacalib/commands/RotateCommand.h" #include"dnacalib/CommandImplBase.h" #include"dnacalib/dna/DNA.h" #include"dnacalib/dna/DNACalibDNAReaderImpl.h" #include"dnacalib/types/Aliases.h" #include"dnacalib/utils/Algorithm.h" #include<tdm/TDM.h> namespacednac{ classRotateCommand::Impl:publicCommandImplBase<Impl>{ private: usingSuper=CommandImplBase<Impl>; public: explicitImpl(MemoryResource*memRes_): Super{memRes_}, degrees{}, origin{}{ } voidsetRotation(Vector3degrees_){ degrees=degrees_; } voidsetOrigin(Vector3origin_){ origin=origin_; } voidrun(DNACalibDNAReaderImpl*output){ if(degrees!=Vector3{}){ rotateNeutralJoints(output); rotateVertexPositions(output); rotateBlendShapeTargetDeltas(output); } } private: tdm::mat4<float>getRotationTransformationMatrix()const{ constautoinverseTranslationMatrix=tdm::translate(tdm::fvec3{-origin.x,-origin.y,-origin.z}); constautorotationMatrix=tdm::rotate(tdm::radians(degrees.x),tdm::radians(degrees.y),tdm::radians(degrees.z)); constautotranslationMatrix=tdm::translate(tdm::fvec3{origin.x,origin.y,origin.z}); returninverseTranslationMatrix*rotationMatrix*translationMatrix; } voidrotateNeutralJoints(DNACalibDNAReaderImpl*output){ constautorotationMatrix=getRotationTransformationMatrix(); for(std::uint16_tjointIndex=0u;jointIndex<output->getJointCount();++jointIndex){ constautoparentIndex=output->getJointParentIndex(jointIndex); //Onlyrootjointsarerotated if(jointIndex==parentIndex){ constautojointNeutralRotation=output->getNeutralJointRotation(jointIndex); constautojointNeutralTranslation=output->getNeutralJointTranslation(jointIndex); constautojointRotationMatrix=tdm::rotate(tdm::radians(jointNeutralRotation.x), tdm::radians(jointNeutralRotation.y), tdm::radians(jointNeutralRotation.z)); constautojointTranslationMatrix=tdm::translate(fvec3{jointNeutralTranslation.x, jointNeutralTranslation.y, jointNeutralTranslation.z}); constautotransformMatrix=jointRotationMatrix*jointTranslationMatrix*rotationMatrix; constautot=extractTranslationVector(transformMatrix); constautor=extractRotationVector(transformMatrix); output->setNeutralJointRotation(jointIndex, Vector3{tdm::degrees(r[0]),tdm::degrees(r[1]),tdm::degrees(r[2])}); output->setNeutralJointTranslation(jointIndex,Vector3{t[0],t[1],t[2]}); } } } voidrotateVertexPositions(DNACalibDNAReaderImpl*output){ constautorotationMatrix=getRotationTransformationMatrix(); for(std::uint16_tmeshIndex=0u;meshIndex<output->getMeshCount();++meshIndex){ constautoxs=output->getVertexPositionXs(meshIndex); constautoys=output->getVertexPositionYs(meshIndex); constautozs=output->getVertexPositionZs(meshIndex); assert((xs.size()==ys.size())&&(ys.size()==zs.size())); RawVector3Vectormesh{xs,ys,zs,output->getMemoryResource()}; for(std::size_ti=0ul;i<mesh.size();++i){ consttdm::fvec4vertex{mesh.xs[i],mesh.ys[i],mesh.zs[i],1.0f}; consttdm::fvec4rotatedVertex=vertex*rotationMatrix; mesh.xs[i]=rotatedVertex[0]; mesh.ys[i]=rotatedVertex[1]; mesh.zs[i]=rotatedVertex[2]; } output->setVertexPositions(meshIndex,std::move(mesh)); } } voidrotateBlendShapeTargetDeltas(DNACalibDNAReaderImpl*output){ constautorotationMatrix=getRotationTransformationMatrix(); for(std::uint16_tmeshIndex=0u;meshIndex<output->getMeshCount();++meshIndex){ for(std::uint16_tblendShapeTargetIndex=0u; blendShapeTargetIndex<output->getBlendShapeTargetCount(meshIndex); ++blendShapeTargetIndex){ constautoxs=output->getBlendShapeTargetDeltaXs(meshIndex,blendShapeTargetIndex); constautoys=output->getBlendShapeTargetDeltaYs(meshIndex,blendShapeTargetIndex); constautozs=output->getBlendShapeTargetDeltaZs(meshIndex,blendShapeTargetIndex); assert((xs.size()==ys.size())&&(ys.size()==zs.size())); RawVector3Vectordeltas{xs,ys,zs,output->getMemoryResource()}; for(std::size_ti=0ul;i<deltas.size();++i){ consttdm::fvec4delta{deltas.xs[i],deltas.ys[i],deltas.zs[i],1.0f}; consttdm::fvec4rotatedDelta=delta*rotationMatrix; deltas.xs[i]=rotatedDelta[0]; deltas.ys[i]=rotatedDelta[1]; deltas.zs[i]=rotatedDelta[2]; } output->setBlendShapeTargetDeltas(meshIndex,blendShapeTargetIndex,std::move(deltas)); } } } private: Vector3degrees; Vector3origin; }; RotateCommand::RotateCommand(MemoryResource*memRes):pImpl{makeScoped<Impl>(memRes)}{ } RotateCommand::RotateCommand(Vector3degrees,Vector3origin,MemoryResource*memRes): pImpl{makeScoped<Impl>(memRes)}{ pImpl->setRotation(degrees); pImpl->setOrigin(origin); } RotateCommand::~RotateCommand()=default; RotateCommand::RotateCommand(RotateCommand&&)=default; RotateCommand&RotateCommand::operator=(RotateCommand&&)=default; voidRotateCommand::setRotation(Vector3degrees){ pImpl->setRotation(degrees); } voidRotateCommand::setOrigin(Vector3origin){ pImpl->setOrigin(origin); } voidRotateCommand::run(DNACalibDNAReader*output){ pImpl->run(static_cast<DNACalibDNAReaderImpl*>(output)); } }//namespacednac