DNACalibDNAReaderImpl.cpp dnacalib/dna/DNACalibDNAReaderImpl.h dnacalib/TypeDefs.h dnacalib/dna/filters/AnimatedMapFilter.h dnacalib/dna/filters/BlendShapeFilter.h dnacalib/dna/filters/JointFilter.h dnacalib/dna/filters/MeshFilter.h dnacalib/utils/Extd.h dnac //CopyrightEpicGames,Inc.AllRightsReserved. #include"dnacalib/dna/DNACalibDNAReaderImpl.h" #include"dnacalib/TypeDefs.h" #include"dnacalib/dna/filters/AnimatedMapFilter.h" #include"dnacalib/dna/filters/BlendShapeFilter.h" #include"dnacalib/dna/filters/JointFilter.h" #include"dnacalib/dna/filters/MeshFilter.h" #include"dnacalib/utils/Extd.h" namespacednac{ DNACalibDNAReader::~DNACalibDNAReader()=default; DNACalibDNAReaderImpl::~DNACalibDNAReaderImpl()=default; DNACalibDNAReader*DNACalibDNAReader::create(MemoryResource*memRes){ PolyAllocator<DNACalibDNAReaderImpl>alloc{memRes}; returnalloc.newObject(memRes); } DNACalibDNAReader*DNACalibDNAReader::create(constdna::Reader*reader,MemoryResource*memRes){ autoinstance=static_cast<DNACalibDNAReaderImpl*>(create(memRes)); instance->setFrom(reader,dna::DataLayer::All,memRes); returninstance; } voidDNACalibDNAReader::destroy(DNACalibDNAReader*instance){ //NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast) autoptr=static_cast<DNACalibDNAReaderImpl*>(instance); PolyAllocator<DNACalibDNAReaderImpl>alloc{ptr->getMemoryResource()}; alloc.deleteObject(ptr); } DNACalibDNAReaderImpl::DNACalibDNAReaderImpl(MemoryResource*memRes_): BaseImpl{memRes_}, ReaderImpl{memRes_}, WriterImpl{memRes_}{ } voidDNACalibDNAReaderImpl::setLODCount(std::uint16_tlodCount){ dna.descriptor.lodCount=lodCount; } voidDNACalibDNAReaderImpl::setNeutralJointTranslations(ConstArrayView<float>xs, ConstArrayView<float>ys, ConstArrayView<float>zs){ dna.definition.neutralJointTranslations.xs.assign(xs.begin(),xs.end()); dna.definition.neutralJointTranslations.ys.assign(ys.begin(),ys.end()); dna.definition.neutralJointTranslations.zs.assign(zs.begin(),zs.end()); } voidDNACalibDNAReaderImpl::setNeutralJointTranslations(RawVector3Vector&&translations){ dna.definition.neutralJointTranslations=std::move(translations); } voidDNACalibDNAReaderImpl::setNeutralJointTranslation(std::uint16_tindex,constVector3&translation){ if(index>=dna.definition.neutralJointTranslations.size()){ dna.definition.neutralJointTranslations.xs.resize(index+1ul,0.0f); dna.definition.neutralJointTranslations.ys.resize(index+1ul,0.0f); dna.definition.neutralJointTranslations.zs.resize(index+1ul,0.0f); } dna.definition.neutralJointTranslations.xs[index]=translation.x; dna.definition.neutralJointTranslations.ys[index]=translation.y; dna.definition.neutralJointTranslations.zs[index]=translation.z; } voidDNACalibDNAReaderImpl::setNeutralJointRotations(ConstArrayView<float>xs,ConstArrayView<float>ys, ConstArrayView<float>zs){ dna.definition.neutralJointRotations.xs.assign(xs.begin(),xs.end()); dna.definition.neutralJointRotations.ys.assign(ys.begin(),ys.end()); dna.definition.neutralJointRotations.zs.assign(zs.begin(),zs.end()); } voidDNACalibDNAReaderImpl::setNeutralJointRotations(RawVector3Vector&&rotations){ dna.definition.neutralJointRotations=std::move(rotations); } voidDNACalibDNAReaderImpl::setNeutralJointRotation(std::uint16_tindex,constVector3&rotation){ if(index>=dna.definition.neutralJointTranslations.size()){ dna.definition.neutralJointRotations.xs.resize(index+1ul,0.0f); dna.definition.neutralJointRotations.ys.resize(index+1ul,0.0f); dna.definition.neutralJointRotations.zs.resize(index+1ul,0.0f); } dna.definition.neutralJointRotations.xs[index]=rotation.x; dna.definition.neutralJointRotations.ys[index]=rotation.y; dna.definition.neutralJointRotations.zs[index]=rotation.z; } voidDNACalibDNAReaderImpl::setJointGroupValues(std::uint16_tjointGroupIndex,AlignedDynArray<float>&&values){ ensureHasSize(dna.behavior.joints.jointGroups,jointGroupIndex+1ul,memRes); dna.behavior.joints.jointGroups[jointGroupIndex].values=std::move(values); } voidDNACalibDNAReaderImpl::setVertexPositions(std::uint16_tmeshIndex, ConstArrayView<float>xs, ConstArrayView<float>ys, ConstArrayView<float>zs){ ensureHasSize(dna.geometry.meshes,meshIndex+1ul,memRes); dna.geometry.meshes[meshIndex].positions.xs.assign(xs.begin(),xs.end()); dna.geometry.meshes[meshIndex].positions.ys.assign(ys.begin(),ys.end()); dna.geometry.meshes[meshIndex].positions.zs.assign(zs.begin(),zs.end()); } voidDNACalibDNAReaderImpl::setVertexPositions(std::uint16_tmeshIndex,RawVector3Vector&&positions){ ensureHasSize(dna.geometry.meshes,meshIndex+1ul,memRes); dna.geometry.meshes[meshIndex].positions=std::move(positions); } voidDNACalibDNAReaderImpl::setBlendShapeTargetDeltas(std::uint16_tmeshIndex, std::uint16_tblendShapeTargetIndex, ConstArrayView<float>xs, ConstArrayView<float>ys, ConstArrayView<float>zs){ ensureHasSize(dna.geometry.meshes,meshIndex+1ul,memRes); ensureHasSize(dna.geometry.meshes[meshIndex].blendShapeTargets,blendShapeTargetIndex+1ul,memRes); dna.geometry.meshes[meshIndex].blendShapeTargets[blendShapeTargetIndex].deltas.xs.assign(xs.begin(),xs.end()); dna.geometry.meshes[meshIndex].blendShapeTargets[blendShapeTargetIndex].deltas.ys.assign(ys.begin(),ys.end()); dna.geometry.meshes[meshIndex].blendShapeTargets[blendShapeTargetIndex].deltas.zs.assign(zs.begin(),zs.end()); } voidDNACalibDNAReaderImpl::setBlendShapeTargetDeltas(std::uint16_tmeshIndex, std::uint16_tblendShapeTargetIndex, RawVector3Vector&&deltas){ ensureHasSize(dna.geometry.meshes,meshIndex+1ul,memRes); ensureHasSize(dna.geometry.meshes[meshIndex].blendShapeTargets,blendShapeTargetIndex+1ul,memRes); dna.geometry.meshes[meshIndex].blendShapeTargets[blendShapeTargetIndex].deltas=std::move(deltas); } voidDNACalibDNAReaderImpl::setBlendShapeTargetVertexIndices(std::uint16_tmeshIndex, std::uint16_tblendShapeTargetIndex, ConstArrayView<std::uint32_t>vertexIndices){ ensureHasSize(dna.geometry.meshes,meshIndex+1ul,memRes); ensureHasSize(dna.geometry.meshes[meshIndex].blendShapeTargets,blendShapeTargetIndex+1ul,memRes); dna.geometry.meshes[meshIndex].blendShapeTargets[blendShapeTargetIndex].vertexIndices.assign(vertexIndices.begin(), vertexIndices.end()); } voidDNACalibDNAReaderImpl::pruneBlendShapeTargets(floatthreshold){ constfloatthreshold2=threshold*threshold; for(auto&mesh:dna.geometry.meshes){ for(auto&bst:mesh.blendShapeTargets){ std::size_tdi{}; for(std::size_tsi{};si<bst.deltas.size();++si){ constfloatmagnitude2=(bst.deltas.xs[si]*bst.deltas.xs[si])+ (bst.deltas.ys[si]*bst.deltas.ys[si])+ (bst.deltas.zs[si]*bst.deltas.zs[si]); if(magnitude2>threshold2){ bst.deltas.xs[di]=bst.deltas.xs[si]; bst.deltas.ys[di]=bst.deltas.ys[si]; bst.deltas.zs[di]=bst.deltas.zs[si]; bst.vertexIndices[di]=bst.vertexIndices[si]; ++di; } } bst.deltas.resize(di); bst.vertexIndices.resize(di); } } } voidDNACalibDNAReaderImpl::removeMeshes(ConstArrayView<std::uint16_t>meshIndices){ //Filterandremapmeshnamesandindices dna.definition.lodMeshMapping.filterIndices([meshIndices](std::uint16_tvalue){ return(!extd::contains(meshIndices,value)); }); //CollectalldistinctelementpositionindicesthatarereferencedbythepresentLODs UnorderedSet<std::uint16_t>allowedMeshIndices=dna.definition.lodMeshMapping.getCombinedDistinctIndices(memRes); MeshFiltermeshFilter{memRes}; meshFilter.configure(static_cast<std::uint16_t>(dna.definition.meshNames.size()),std::move(allowedMeshIndices)); meshFilter.apply(dna.definition); //Removemeshgeometry extd::filter(dna.geometry.meshes,[&meshFilter](constRawMesh&/*unused*/,std::size_tindex){ returnmeshFilter.passes(static_cast<std::uint16_t>(index)); }); //Repopulatecacheof(mesh,blendshape)mappingperLOD cache.meshBlendShapeMappingIndices.reset(); cache.populate(this); } voidDNACalibDNAReaderImpl::removeJoints(ConstArrayView<std::uint16_t>jointIndices){ //TofindjointsthatarenotinanyLOD,findthejointsthatarenotinLOD0(thecurrentmaxLOD,atindex0),asit //containsjointsfromalllowerLODs. Vector<std::uint16_t>jointsNotInLOD0{memRes}; constautojointIndicesForLOD0=dna.definition.lodJointMapping.getIndices(0); for(std::uint16_tidx=0;idx<dna.definition.jointNames.size();++idx){ if(extd::contains(jointIndices,idx)){ //Donotaddthejointtoremove. continue; } if(std::find(jointIndicesForLOD0.begin(),jointIndicesForLOD0.end(),idx)==jointIndicesForLOD0.end()){ jointsNotInLOD0.push_back(idx); } } //Filterandremapjointnamesandindices dna.definition.lodJointMapping.filterIndices([jointIndices](std::uint16_tvalue){ return(!extd::contains(jointIndices,value)); }); //CollectalldistinctelementpositionindicesthatarereferencedbythepresentLODs UnorderedSet<std::uint16_t>allowedJointIndices=dna.definition.lodJointMapping.getCombinedDistinctIndices(memRes); //InordertokeepjointsthatarenotinanyLOD,addthemtothelistofjointstokeepwhenfiltering. allowedJointIndices.insert(jointsNotInLOD0.begin(),jointsNotInLOD0.end()); JointFilterjointFilter{memRes}; jointFilter.configure(static_cast<std::uint16_t>(dna.definition.jointNames.size()),std::move(allowedJointIndices)); jointFilter.apply(dna.definition); //Filterandremaprelatedjointbehaviordata jointFilter.apply(dna.behavior); //Removeskinweightsrelatedtothisjointandnormalizethem for(auto&mesh:dna.geometry.meshes){ for(auto&skinWeights:mesh.skinWeights){ jointFilter.apply(skinWeights); } } } voidDNACalibDNAReaderImpl::removeJointAnimations(ConstArrayView<std::uint16_t>jointIndices){ UnorderedSet<std::uint16_t>allowedJointIndices=dna.definition.lodJointMapping.getCombinedDistinctIndices(memRes); for(constautojointIndex:jointIndices){ allowedJointIndices.erase(jointIndex); } JointFilterjointFilter{memRes}; jointFilter.configure(static_cast<std::uint16_t>(dna.definition.jointNames.size()), std::move(allowedJointIndices), JointFilter::Option::AnimationOnly); jointFilter.apply(dna.behavior); } voidDNACalibDNAReaderImpl::removeBlendShapes(ConstArrayView<std::uint16_t>blendShapeIndices){ //FilterblendshapesfromLODblendshapemapping dna.definition.lodBlendShapeMapping.filterIndices([blendShapeIndices](std::uint16_tvalue){ return(!extd::contains(blendShapeIndices,value)); }); Vector<std::uint16_t>blendShapeLODs{dna.definition.lodBlendShapeMapping.getLODCount(),0u,memRes}; for(std::uint16_tlodIndex=0;lodIndex<blendShapeLODs.size();++lodIndex){ blendShapeLODs[lodIndex]=static_cast<std::uint16_t>(dna.definition.lodBlendShapeMapping.getIndices(lodIndex).size()); } UnorderedSet<std::uint16_t>allowedBlendShapeIndices=dna.definition.lodBlendShapeMapping.getCombinedDistinctIndices(memRes); BlendShapeFilterblendShapeFilter{memRes}; blendShapeFilter.configure(static_cast<std::uint16_t>(dna.definition.blendShapeChannelNames.size()), std::move(allowedBlendShapeIndices),std::move(blendShapeLODs)); //Removeblendshapefromdefinition blendShapeFilter.apply(dna.definition); //Removeblendshapefrombehavior blendShapeFilter.apply(dna.behavior); //Removeblendshapefromgeometry for(auto&mesh:dna.geometry.meshes){ blendShapeFilter.apply(mesh); } } voidDNACalibDNAReaderImpl::removeAnimatedMaps(ConstArrayView<std::uint16_t>animatedMapIndices){ //KeeptrackofanimatedmapindicesperLODbeforefilteringandremapping Matrix<std::uint16_t>lodIndices{dna.definition.lodAnimatedMapMapping.getLODCount(),Vector<std::uint16_t>{memRes},memRes}; for(std::uint16_tlodIndex=0;lodIndex<static_cast<std::uint16_t>(lodIndices.size());++lodIndex){ constauto&indices=dna.definition.lodAnimatedMapMapping.getIndices(lodIndex); lodIndices[lodIndex].assign(indices.begin(),indices.end()); } //Filterandremapanimatedmapnamesandindices dna.definition.lodAnimatedMapMapping.filterIndices([animatedMapIndices](std::uint16_tvalue){ return(!extd::contains(animatedMapIndices,value)); }); //CollectalldistinctelementpositionindicesthatarereferencedbythepresentLODs UnorderedSet<std::uint16_t>allowedAnimatedMapIndices= dna.definition.lodAnimatedMapMapping.getCombinedDistinctIndices(memRes); AnimatedMapFilteranimatedMapFilter{memRes}; animatedMapFilter.configure(static_cast<std::uint16_t>(dna.definition.animatedMapNames.size()), std::move(allowedAnimatedMapIndices),std::move(lodIndices)); animatedMapFilter.apply(dna.definition); animatedMapFilter.apply(dna.behavior); } }//namespacednac