ScaleCommand.cpp dnacalib/commands/ScaleCommand.h dnacalib/CommandImplBase.h dnacalib/dna/DNA.h dnacalib/dna/DNACalibDNAReaderImpl.h dnacalib/types/Aliases.h cstdint dnac::ScaleCommand::Impl dnac //CopyrightEpicGames,Inc.AllRightsReserved. #include"dnacalib/commands/ScaleCommand.h" #include"dnacalib/CommandImplBase.h" #include"dnacalib/dna/DNA.h" #include"dnacalib/dna/DNACalibDNAReaderImpl.h" #include"dnacalib/types/Aliases.h" #include<cstdint> namespacednac{ staticconstexprstd::uint16_tjointAttributeCount=9u; staticconstexprstd::uint16_trotationOffset=3u; classScaleCommand::Impl:publicCommandImplBase<Impl>{ private: usingSuper=CommandImplBase<Impl>; public: explicitImpl(MemoryResource*memRes_): Super{memRes_}, origin{}, scale{1.0f}{ } voidsetScale(floatscale_){ scale=scale_; } voidsetOrigin(Vector3origin_){ origin=origin_; } voidrun(DNACalibDNAReaderImpl*output){ if(scale!=1.0f){ scaleNeutralJoints(output); scaleJointBehavior(output); scaleGeometry(output); } } private: voidscaleNeutralJoints(DNACalibDNAReaderImpl*output){ constautoxs=output->getNeutralJointTranslationXs(); constautoys=output->getNeutralJointTranslationYs(); constautozs=output->getNeutralJointTranslationZs(); assert((xs.size()==ys.size())&&(ys.size()==zs.size())); RawVector3Vectortranslations{xs,ys,zs,output->getMemoryResource()}; for(std::uint16_ti=0ul;i<translations.size();++i){ constboolisRootJoint=(output->getJointParentIndex(i)==i); if(isRootJoint){ translations.xs[i]-=origin.x; translations.ys[i]-=origin.y; translations.zs[i]-=origin.z; translations.xs[i]*=scale; translations.ys[i]*=scale; translations.zs[i]*=scale; translations.xs[i]+=origin.x; translations.ys[i]+=origin.y; translations.zs[i]+=origin.z; }else{ translations.xs[i]*=scale; translations.ys[i]*=scale; translations.zs[i]*=scale; } } output->setNeutralJointTranslations(std::move(translations)); } voidscaleJointBehavior(DNACalibDNAReaderImpl*output){ for(std::uint16_tjointGroupIndex=0u;jointGroupIndex<output->getJointGroupCount();++jointGroupIndex){ constautovalues=output->getJointGroupValues(jointGroupIndex); constautooutputIndices=output->getJointGroupOutputIndices(jointGroupIndex); constautoinputIndices=output->getJointGroupInputIndices(jointGroupIndex); constautocolumnCount=inputIndices.size(); AlignedDynArray<float>newValues{values.begin(),values.end(),output->getMemoryResource()}; for(std::size_trow=0ul;row<outputIndices.size();++row){ //Onlythetranslationattributesneedtobescaled constautorelAttributeIndex=(outputIndices[row]%jointAttributeCount); if(relAttributeIndex<rotationOffset){ for(std::size_tcolumn=0ul;column<columnCount;++column){ newValues[row*columnCount+column]*=scale; } } } output->setJointGroupValues(jointGroupIndex,std::move(newValues)); } } voidscaleGeometry(DNACalibDNAReaderImpl*output){ for(std::uint16_tmeshIndex=0u;meshIndex<output->getMeshCount();++meshIndex){ scaleVertexPositions(output,meshIndex); scaleBlendShapeTargetDeltas(output,meshIndex); } } voidscaleVertexPositions(DNACalibDNAReaderImpl*output,std::uint16_tmeshIndex){ constautoxs=output->getVertexPositionXs(meshIndex); constautoys=output->getVertexPositionYs(meshIndex); constautozs=output->getVertexPositionZs(meshIndex); assert((xs.size()==ys.size())&&(ys.size()==zs.size())); RawVector3Vectorvertices{xs,ys,zs,output->getMemoryResource()}; for(std::uint32_ti=0u;i<vertices.size();++i){ vertices.xs[i]-=origin.x; vertices.ys[i]-=origin.y; vertices.zs[i]-=origin.z; vertices.xs[i]*=scale; vertices.ys[i]*=scale; vertices.zs[i]*=scale; vertices.xs[i]+=origin.x; vertices.ys[i]+=origin.y; vertices.zs[i]+=origin.z; } output->setVertexPositions(meshIndex,std::move(vertices)); } voidscaleBlendShapeTargetDeltas(DNACalibDNAReaderImpl*output,std::uint16_tmeshIndex){ 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::uint32_ti=0u;i<deltas.size();++i){ deltas.xs[i]*=scale; deltas.ys[i]*=scale; deltas.zs[i]*=scale; } output->setBlendShapeTargetDeltas(meshIndex,blendShapeTargetIndex,std::move(deltas)); } } private: Vector3origin; floatscale; }; ScaleCommand::ScaleCommand(MemoryResource*memRes):pImpl{makeScoped<Impl>(memRes)}{ } ScaleCommand::ScaleCommand(floatscale,Vector3origin,MemoryResource*memRes): pImpl{makeScoped<Impl>(memRes)}{ pImpl->setScale(scale); pImpl->setOrigin(origin); } ScaleCommand::~ScaleCommand()=default; ScaleCommand::ScaleCommand(ScaleCommand&&)=default; ScaleCommand&ScaleCommand::operator=(ScaleCommand&&)=default; voidScaleCommand::setScale(floatscale){ pImpl->setScale(scale); } voidScaleCommand::setOrigin(Vector3origin){ pImpl->setOrigin(origin); } voidScaleCommand::run(DNACalibDNAReader*output){ pImpl->run(static_cast<DNACalibDNAReaderImpl*>(output)); } }//namespacednac