Writer.cpp dna/Writer.h dna/Reader.h dna/DataLayerBitmask.h dna/TypeDefs.h dna/types/Vector3.h functional dna dna::anonymous_namespace{Writer.cpp} //CopyrightEpicGames,Inc.AllRightsReserved. #include"dna/Writer.h" #include"dna/Reader.h" #include"dna/DataLayerBitmask.h" #include"dna/TypeDefs.h" #include"dna/types/Vector3.h" #ifdef_MSC_VER #pragmawarning(push) #pragmawarning(disable:43654987) #endif #include<functional> #ifdef_MSC_VER #pragmawarning(pop) #endif namespacedna{ namespace{ usingVector3Vector=Vector<Vector3>; usingTextureCoordinateVector=Vector<TextureCoordinate>; usingVertexLayoutVector=Vector<VertexLayout>; }//namespace DescriptorWriter::~DescriptorWriter()=default; DefinitionWriter::~DefinitionWriter()=default; BehaviorWriter::~BehaviorWriter()=default; GeometryWriter::~GeometryWriter()=default; Writer::~Writer()=default; template<typenameTVector,typenameTGetter> staticTVectorcollect_n(std::size_tcount,TGettergetter,MemoryResource*memRes){ TVectorretval{memRes}; retval.reserve(count); for(std::size_ti=0ul;i<count;++i){ retval.push_back(getter(i)); } returnretval; } staticvoidcopyDescriptor(constDescriptorReader*source,DescriptorWriter*destination,MemoryResource*/*unused*/){ destination->setName(source->getName()); destination->setArchetype(source->getArchetype()); destination->setGender(source->getGender()); destination->setAge(source->getAge()); destination->clearMetaData(); for(std::uint32_ti=0u;i<source->getMetaDataCount();++i){ constautokey=source->getMetaDataKey(i); constautovalue=source->getMetaDataValue(key); destination->setMetaData(key,value); } destination->setTranslationUnit(source->getTranslationUnit()); destination->setRotationUnit(source->getRotationUnit()); destination->setCoordinateSystem(source->getCoordinateSystem()); destination->setLODCount(source->getLODCount()); destination->setDBMaxLOD(source->getDBMaxLOD()); destination->setDBComplexity(source->getDBComplexity()); destination->setDBName(source->getDBName()); } staticstd::pair<bool,std::uint16_t>findIndices(constMatrix<std::uint16_t>&source,ConstArrayView<std::uint16_t>indices){ //InthecommonscenarioeachLODhasit'suniquesetofindices for(std::size_ti=0ul;i<source.size();++i){ ConstArrayView<std::uint16_t>candidate{source[i].data(),source[i].size()}; if(indices==candidate){ //UnlesstheindicesarethesamebetweenmultipleLODs,inwhichcaseusethe //alreadyregisteredindex return{true,static_cast<std::uint16_t>(i)}; } } return{false,static_cast<std::uint16_t>(0)}; } usingIndicesGetter=std::function<ConstArrayView<std::uint16_t>(std::uint16_t)>; usingIndicesSetter=std::function<void(std::uint16_t,conststd::uint16_t*,std::uint16_t)>; usingLODMappingSetter=std::function<void(std::uint16_t,std::uint16_t)>; staticvoidcopyNameIndices(IndicesGettergetIndices, IndicesSettersetIndices, LODMappingSettersetLODMapping, std::uint16_tlodCount, MemoryResource*memRes){ Matrix<std::uint16_t>allIndices{memRes}; std::uint16_tindex=0u; for(std::uint16_tlod=0u;lod<lodCount;++lod){ autoindices=getIndices(lod); //CheckifthesesameindiceswereperhapsalreadyusedforpreviousLODs autofound=findIndices(allIndices,indices); if(!found.first){ setIndices(index,indices.data(),static_cast<std::uint16_t>(indices.size())); setLODMapping(lod,index); allIndices.emplace_back(indices.begin(),indices.end()); ++index; }else{ //Alreadyusedsodonotreplicatethesamedatatwice setLODMapping(lod,found.second); } } } staticvoidcopyDefinition(constDefinitionReader*source,DefinitionWriter*destination,MemoryResource*memRes){ destination->clearGUIControlNames(); destination->clearRawControlNames(); destination->clearJointNames(); destination->clearBlendShapeChannelNames(); destination->clearAnimatedMapNames(); destination->clearMeshNames(); destination->clearJointIndices(); destination->clearLODJointMappings(); destination->clearBlendShapeChannelIndices(); destination->clearLODBlendShapeChannelMappings(); destination->clearAnimatedMapIndices(); destination->clearLODAnimatedMapMappings(); destination->clearMeshIndices(); destination->clearLODMeshMappings(); destination->clearMeshBlendShapeChannelMappings(); constautolodCount=source->getLODCount(); for(std::uint16_ti=source->getGUIControlCount();i>0u;--i){ constautoidx=static_cast<std::uint16_t>(i-1u); destination->setGUIControlName(idx,source->getGUIControlName(idx).data()); } for(std::uint16_ti=source->getRawControlCount();i>0u;--i){ constautoidx=static_cast<std::uint16_t>(i-1u); destination->setRawControlName(idx,source->getRawControlName(idx).data()); } for(std::uint16_ti=source->getJointCount();i>0u;--i){ constautoidx=static_cast<std::uint16_t>(i-1u); destination->setJointName(idx,source->getJointName(idx).data()); } for(std::uint16_ti=source->getBlendShapeChannelCount();i>0u;--i){ constautoidx=static_cast<std::uint16_t>(i-1u); destination->setBlendShapeChannelName(idx,source->getBlendShapeChannelName(idx).data()); } for(std::uint16_ti=source->getAnimatedMapCount();i>0u;--i){ constautoidx=static_cast<std::uint16_t>(i-1u); destination->setAnimatedMapName(idx,source->getAnimatedMapName(idx)); } for(std::uint16_ti=source->getMeshCount();i>0u;--i){ constautoidx=static_cast<std::uint16_t>(i-1u); destination->setMeshName(idx,source->getMeshName(idx).data()); } usingnamespacestd::placeholders; copyNameIndices( std::bind(&DefinitionReader::getJointIndicesForLOD,source,_1), std::bind(&DefinitionWriter::setJointIndices,destination,_1,_2,_3), std::bind(&DefinitionWriter::setLODJointMapping,destination,_1,_2), lodCount, memRes); copyNameIndices( std::bind(&DefinitionReader::getBlendShapeChannelIndicesForLOD,source,_1), std::bind(&DefinitionWriter::setBlendShapeChannelIndices,destination,_1,_2,_3), std::bind(&DefinitionWriter::setLODBlendShapeChannelMapping,destination,_1,_2), lodCount, memRes); copyNameIndices( std::bind(&DefinitionReader::getAnimatedMapIndicesForLOD,source,_1), std::bind(&DefinitionWriter::setAnimatedMapIndices,destination,_1,_2,_3), std::bind(&DefinitionWriter::setLODAnimatedMapMapping,destination,_1,_2), lodCount, memRes); copyNameIndices( std::bind(&DefinitionReader::getMeshIndicesForLOD,source,_1), std::bind(&DefinitionWriter::setMeshIndices,destination,_1,_2,_3), std::bind(&DefinitionWriter::setLODMeshMapping,destination,_1,_2), lodCount, memRes); Vector<std::uint16_t>jointHierarchy{memRes}; jointHierarchy.reserve(source->getJointCount()); for(std::uint16_ti=0u;i<source->getJointCount();++i){ jointHierarchy.push_back(source->getJointParentIndex(i)); } destination->setJointHierarchy(jointHierarchy.data(),static_cast<std::uint16_t>(jointHierarchy.size())); for(std::uint16_ti=0u;i<source->getMeshBlendShapeChannelMappingCount();++i){ automapping=source->getMeshBlendShapeChannelMapping(i); destination->setMeshBlendShapeChannelMapping(i,mapping.meshIndex,mapping.blendShapeChannelIndex); } autojointCount=source->getJointCount(); autotranslations=collect_n<Vector3Vector>(jointCount,[source](std::size_tindex){ returnsource->getNeutralJointTranslation(static_cast<std::uint16_t>(index)); },memRes); destination->setNeutralJointTranslations(translations.data(),static_cast<std::uint16_t>(translations.size())); autorotations=collect_n<Vector3Vector>(jointCount,[source](std::size_tindex){ returnsource->getNeutralJointRotation(static_cast<std::uint16_t>(index)); },memRes); destination->setNeutralJointRotations(rotations.data(),static_cast<std::uint16_t>(rotations.size())); } staticvoidcopyBehavior(constBehaviorReader*source,BehaviorWriter*destination,MemoryResource*/*unused*/){ destination->clearJointGroups(); autoguiToRawInputIndices=source->getGUIToRawInputIndices(); destination->setGUIToRawInputIndices(guiToRawInputIndices.data(),static_cast<std::uint16_t>(guiToRawInputIndices.size())); autoguiToRawOutputIndices=source->getGUIToRawOutputIndices(); destination->setGUIToRawOutputIndices(guiToRawOutputIndices.data(),static_cast<std::uint16_t>(guiToRawOutputIndices.size())); autoguiToRawFromValues=source->getGUIToRawFromValues(); destination->setGUIToRawFromValues(guiToRawFromValues.data(),static_cast<std::uint16_t>(guiToRawFromValues.size())); autoguiToRawToValues=source->getGUIToRawToValues(); destination->setGUIToRawToValues(guiToRawToValues.data(),static_cast<std::uint16_t>(guiToRawToValues.size())); autoguiToRawSlopeValues=source->getGUIToRawSlopeValues(); destination->setGUIToRawSlopeValues(guiToRawSlopeValues.data(),static_cast<std::uint16_t>(guiToRawSlopeValues.size())); autoguiToRawCutValues=source->getGUIToRawCutValues(); destination->setGUIToRawCutValues(guiToRawCutValues.data(),static_cast<std::uint16_t>(guiToRawCutValues.size())); destination->setPSDCount(source->getPSDCount()); autopsdRowIndices=source->getPSDRowIndices(); destination->setPSDRowIndices(psdRowIndices.data(),static_cast<std::uint16_t>(psdRowIndices.size())); autopsdColumnIndices=source->getPSDColumnIndices(); destination->setPSDColumnIndices(psdColumnIndices.data(),static_cast<std::uint16_t>(psdColumnIndices.size())); autopsdValues=source->getPSDValues(); destination->setPSDValues(psdValues.data(),static_cast<std::uint16_t>(psdValues.size())); destination->setJointRowCount(source->getJointRowCount()); destination->setJointColumnCount(source->getJointColumnCount()); for(std::uint16_tjointGroupIndexPlusOne=source->getJointGroupCount(); jointGroupIndexPlusOne>0u; --jointGroupIndexPlusOne){ constautojointGroupIndex=static_cast<std::uint16_t>(jointGroupIndexPlusOne-1u); autojointGroupLODs=source->getJointGroupLODs(jointGroupIndex); destination->setJointGroupLODs(jointGroupIndex,jointGroupLODs.data(),static_cast<std::uint16_t>(jointGroupLODs.size())); autojointGroupInputIndices=source->getJointGroupInputIndices(jointGroupIndex); destination->setJointGroupInputIndices(jointGroupIndex,jointGroupInputIndices.data(), static_cast<std::uint16_t>(jointGroupInputIndices.size())); autojointGroupOutputIndices=source->getJointGroupOutputIndices(jointGroupIndex); destination->setJointGroupOutputIndices(jointGroupIndex,jointGroupOutputIndices.data(), static_cast<std::uint16_t>(jointGroupOutputIndices.size())); autojointGroupValues=source->getJointGroupValues(jointGroupIndex); destination->setJointGroupValues(jointGroupIndex,jointGroupValues.data(), static_cast<std::uint32_t>(jointGroupValues.size())); autojointGroupJointIndices=source->getJointGroupJointIndices(jointGroupIndex); destination->setJointGroupJointIndices(jointGroupIndex,jointGroupJointIndices.data(), static_cast<std::uint16_t>(jointGroupJointIndices.size())); } autoblendShapeLODs=source->getBlendShapeChannelLODs(); destination->setBlendShapeChannelLODs(blendShapeLODs.data(),static_cast<std::uint16_t>(blendShapeLODs.size())); autoblendShapeInputIndices=source->getBlendShapeChannelInputIndices(); destination->setBlendShapeChannelInputIndices(blendShapeInputIndices.data(), static_cast<std::uint16_t>(blendShapeInputIndices.size())); autoblendShapeOutputIndices=source->getBlendShapeChannelOutputIndices(); destination->setBlendShapeChannelOutputIndices(blendShapeOutputIndices.data(), static_cast<std::uint16_t>(blendShapeOutputIndices.size())); autoanimatedMapLODs=source->getAnimatedMapLODs(); destination->setAnimatedMapLODs(animatedMapLODs.data(),static_cast<std::uint16_t>(animatedMapLODs.size())); autoanimatedMapInputIndices=source->getAnimatedMapInputIndices(); destination->setAnimatedMapInputIndices(animatedMapInputIndices.data(), static_cast<std::uint16_t>(animatedMapInputIndices.size())); autoanimatedMapOutputIndices=source->getAnimatedMapOutputIndices(); destination->setAnimatedMapOutputIndices(animatedMapOutputIndices.data(), static_cast<std::uint16_t>(animatedMapOutputIndices.size())); autoanimatedMapFromValues=source->getAnimatedMapFromValues(); destination->setAnimatedMapFromValues(animatedMapFromValues.data(),static_cast<std::uint16_t>(animatedMapFromValues.size())); autoanimatedMapToValues=source->getAnimatedMapToValues(); destination->setAnimatedMapToValues(animatedMapToValues.data(),static_cast<std::uint16_t>(animatedMapToValues.size())); autoanimatedMapSlopeValues=source->getAnimatedMapSlopeValues(); destination->setAnimatedMapSlopeValues(animatedMapSlopeValues.data(), static_cast<std::uint16_t>(animatedMapSlopeValues.size())); autoanimatedMapCutValues=source->getAnimatedMapCutValues(); destination->setAnimatedMapCutValues(animatedMapCutValues.data(),static_cast<std::uint16_t>(animatedMapCutValues.size())); } staticboolhasGeometry(constGeometryReader*source){ //HeuristicfordeterminingwhethersourceDNAactuallyhasanygeometrydata,ormeshcountisnon-zeroonly //becauseofmeshnamesstoredindefinitionlayer std::uint32_ttotalVertexCount={}; std::uint32_ttotalVertexNormalCount={}; std::uint32_ttotalTextureCoordCount={}; std::uint32_ttotalVertexLayoutCount={}; std::uint32_ttotalSkinWeightCount={}; for(std::uint16_tmeshIndex={};meshIndex<source->getMeshCount();++meshIndex){ totalVertexCount+=source->getVertexPositionCount(meshIndex); totalVertexNormalCount+=source->getVertexNormalCount(meshIndex); totalTextureCoordCount+=source->getVertexTextureCoordinateCount(meshIndex); totalVertexLayoutCount+=source->getVertexLayoutCount(meshIndex); totalSkinWeightCount+=source->getSkinWeightsCount(meshIndex); } return((totalVertexCount!=0u)||(totalVertexNormalCount!=0u)||(totalTextureCoordCount!=0u)|| (totalVertexLayoutCount!=0u)||(totalSkinWeightCount!=0u)); } staticvoidcopyGeometry(constGeometryReader*source,GeometryWriter*destination,MemoryResource*memRes){ destination->clearMeshes(); if(!hasGeometry(source)){ //SourceDNAwasloadedwithoutgeometrylayer return; } for(std::uint16_tmeshIndexPlusOne=source->getMeshCount();meshIndexPlusOne>0u;--meshIndexPlusOne){ constautomeshIndex=static_cast<std::uint16_t>(meshIndexPlusOne-1u); autovertexCount=source->getVertexPositionCount(meshIndex); autopositions=collect_n<Vector3Vector>(vertexCount,[source,meshIndex](std::size_tindex){ returnsource->getVertexPosition(meshIndex,static_cast<std::uint32_t>(index)); },memRes); destination->setVertexPositions(meshIndex,positions.data(),static_cast<std::uint32_t>(positions.size())); autotextureCoordinateCount=source->getVertexTextureCoordinateCount(meshIndex); autotextureCoordinates=collect_n<TextureCoordinateVector>(textureCoordinateCount, [source,meshIndex](std::size_tindex){ returnsource->getVertexTextureCoordinate(meshIndex,static_cast<std::uint32_t>(index)); },memRes); destination->setVertexTextureCoordinates(meshIndex,textureCoordinates.data(), static_cast<std::uint32_t>(textureCoordinates.size())); autonormalCount=source->getVertexNormalCount(meshIndex); autonormals=collect_n<Vector3Vector>(normalCount,[source,meshIndex](std::size_tindex){ returnsource->getVertexNormal(meshIndex,static_cast<std::uint32_t>(index)); },memRes); destination->setVertexNormals(meshIndex,normals.data(),static_cast<std::uint32_t>(normals.size())); autolayoutCount=source->getVertexLayoutCount(meshIndex); autolayouts=collect_n<VertexLayoutVector>(layoutCount,[source,meshIndex](std::size_tindex){ returnsource->getVertexLayout(meshIndex,static_cast<std::uint32_t>(index)); },memRes); destination->setVertexLayouts(meshIndex,layouts.data(),static_cast<std::uint32_t>(layouts.size())); for(std::uint32_tfaceIndexPlusOne=source->getFaceCount(meshIndex);faceIndexPlusOne>0u;--faceIndexPlusOne){ constautofaceIndex=faceIndexPlusOne-1u; autofaceVertices=source->getFaceVertexLayoutIndices(meshIndex,faceIndex); destination->setFaceVertexLayoutIndices(meshIndex,faceIndex,faceVertices.data(), static_cast<std::uint32_t>(faceVertices.size())); } destination->setMaximumInfluencePerVertex(meshIndex,source->getMaximumInfluencePerVertex(meshIndex)); constautoskinWeightsCount=source->getSkinWeightsCount(meshIndex); for(std::uint32_tskinWeightsIndexPlusOne=skinWeightsCount;skinWeightsIndexPlusOne>0u;--skinWeightsIndexPlusOne){ constautoskinWeightsIndex=skinWeightsIndexPlusOne-1u; autoskinWeights=source->getSkinWeightsValues(meshIndex,skinWeightsIndex); destination->setSkinWeightsValues(meshIndex,skinWeightsIndex,skinWeights.data(), static_cast<std::uint16_t>(skinWeights.size())); autoskinWeightsJoints=source->getSkinWeightsJointIndices(meshIndex,skinWeightsIndex); destination->setSkinWeightsJointIndices(meshIndex,skinWeightsIndex,skinWeightsJoints.data(), static_cast<std::uint16_t>(skinWeightsJoints.size())); } } } staticboolhasBlendShapeTargets(constGeometryReader*source){ //HeuristicfordeterminingwhethersourceDNAactuallyhasanyblendshapetargetdata,ormeshcountisnon-zeroonly //becauseofmeshnamesstoredindefinitionlayer std::uint32_ttotalBlendShapeTargetCount={}; for(std::uint16_tmeshIndex={};meshIndex<source->getMeshCount();++meshIndex){ totalBlendShapeTargetCount+=source->getBlendShapeTargetCount(meshIndex); } return(totalBlendShapeTargetCount!=0u); } staticvoidcopyBlendShapeTargets(constGeometryReader*source,GeometryWriter*destination,MemoryResource*memRes){ if(!hasBlendShapeTargets(source)){ //SourceDNAwasloadedwithoutblendshapetargets return; } for(std::uint16_tmeshIndexPlusOne=source->getMeshCount();meshIndexPlusOne>0u;--meshIndexPlusOne){ constautomeshIndex=static_cast<std::uint16_t>(meshIndexPlusOne-1u); for(std::uint16_tblendShapeTargetIndexPlusOne=source->getBlendShapeTargetCount(meshIndex); blendShapeTargetIndexPlusOne>0u; --blendShapeTargetIndexPlusOne){ constautoblendShapeTargetIndex=static_cast<std::uint16_t>(blendShapeTargetIndexPlusOne-1u); autochannelIndex=source->getBlendShapeChannelIndex(meshIndex,blendShapeTargetIndex); destination->setBlendShapeChannelIndex(meshIndex,blendShapeTargetIndex,channelIndex); autodeltaCount=source->getBlendShapeTargetDeltaCount(meshIndex,blendShapeTargetIndex); autodeltas=collect_n<Vector3Vector>(deltaCount,[source,meshIndex,blendShapeTargetIndex](std::size_tindex){ returnsource->getBlendShapeTargetDelta(meshIndex,blendShapeTargetIndex, static_cast<std::uint32_t>(index)); },memRes); destination->setBlendShapeTargetDeltas(meshIndex,blendShapeTargetIndex,deltas.data(), static_cast<std::uint32_t>(deltas.size())); autodeltasVertices=source->getBlendShapeTargetVertexIndices(meshIndex,blendShapeTargetIndex); destination->setBlendShapeTargetVertexIndices(meshIndex,blendShapeTargetIndex,deltasVertices.data(), static_cast<std::uint32_t>(deltasVertices.size())); } } } voidWriter::setFrom(constReader*source,DataLayerlayer,MemoryResource*memRes){ if(source==nullptr){ return; } constautobitmask=computeDataLayerBitmask(layer); copyDescriptor(source,this,memRes); if(contains(bitmask,DataLayerBitmask::Definition)){ copyDefinition(source,this,memRes); } if(contains(bitmask,DataLayerBitmask::Behavior)){ copyBehavior(source,this,memRes); } if(contains(bitmask,DataLayerBitmask::GeometryRest)){ copyGeometry(source,this,memRes); } if(contains(bitmask,DataLayerBitmask::GeometryBlendShapesOnly)){ copyBlendShapeTargets(source,this,memRes); } } }//namespacedna