From 1b002dcc82ca4fbb8e466c2d569d5e1c0fc9566a Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Wed, 4 Aug 2021 11:48:16 +0200 Subject: [PATCH] Saving node chunk v2 and adapting the chunk processor and importer to it Signed-off-by: Benjamin Jillich --- .../ExporterLib/Exporter/NodeExport.cpp | 50 +++--------------- .../Source/Importer/ActorFileFormat.h | 8 +-- .../Source/Importer/ChunkProcessors.cpp | 52 ++----------------- .../Source/Importer/ChunkProcessors.h | 3 +- .../EMotionFX/Source/Importer/Importer.cpp | 4 +- 5 files changed, 18 insertions(+), 99 deletions(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/NodeExport.cpp b/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/NodeExport.cpp index c66c3ca8ef..79861be4b8 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/NodeExport.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/NodeExport.cpp @@ -18,21 +18,6 @@ namespace ExporterLib { - void WriteObbToNodeChunk(EMotionFX::FileFormat::Actor_Node& nodeChunk, const MCore::OBB& obb) - { - AZ::Transform obbMatrix = obb.GetTransformation(); - obbMatrix.GetBasisX().StoreToFloat3(nodeChunk.mOBB); - nodeChunk.mOBB[3] = 0.0f; - obbMatrix.GetBasisY().StoreToFloat3(nodeChunk.mOBB + 4); - nodeChunk.mOBB[7] = 0.0f; - obbMatrix.GetBasisZ().StoreToFloat3(nodeChunk.mOBB + 8); - nodeChunk.mOBB[11] = 0.0f; - nodeChunk.mOBB[12] = 0.0f; - nodeChunk.mOBB[13] = 0.0f; - nodeChunk.mOBB[14] = 0.0f; - nodeChunk.mOBB[15] = 1.0f; - } - void SaveNode(MCore::Stream* file, EMotionFX::Actor* actor, EMotionFX::Node* node, MCore::Endian::EEndianType targetEndianType) { MCORE_ASSERT(file); @@ -47,7 +32,7 @@ namespace ExporterLib const uint32 numChilds = node->GetNumChildNodes(); const EMotionFX::Transform& transform = actor->GetBindPose()->GetLocalSpaceTransform(nodeIndex); AZ::PackedVector3f position = AZ::PackedVector3f(transform.mPosition); - AZ::Quaternion rotation = transform.mRotation.GetNormalized();; + AZ::Quaternion rotation = transform.mRotation.GetNormalized(); #ifndef EMFX_SCALE_DISABLED AZ::PackedVector3f scale = AZ::PackedVector3f(transform.mScale); @@ -56,14 +41,13 @@ namespace ExporterLib #endif // create the node chunk and copy over the information - EMotionFX::FileFormat::Actor_Node nodeChunk; - memset(&nodeChunk, 0, sizeof(EMotionFX::FileFormat::Actor_Node)); + EMotionFX::FileFormat::Actor_Node2 nodeChunk; + memset(&nodeChunk, 0, sizeof(EMotionFX::FileFormat::Actor_Node2)); CopyVector(nodeChunk.mLocalPos, position); CopyQuaternion(nodeChunk.mLocalQuat, rotation); CopyVector(nodeChunk.mLocalScale, scale); - //nodeChunk.mImportanceFactor = FLT_MAX;//importance; nodeChunk.mNumChilds = numChilds; nodeChunk.mParentIndex = parentIndex; @@ -98,10 +82,6 @@ namespace ExporterLib nodeChunk.mNodeFlags &= ~EMotionFX::Node::ENodeFlags::FLAG_CRITICAL; } - // OBB - WriteObbToNodeChunk(nodeChunk, actor->GetNodeOBB(node->GetNodeIndex())); - - // log the node chunk information MCore::LogDetailedInfo("- Node: name='%s' index=%i", actor->GetSkeleton()->GetNode(nodeIndex)->GetName(), nodeIndex); if (parentIndex == MCORE_INVALIDINDEX32) @@ -140,19 +120,13 @@ namespace ExporterLib ConvertUnsignedInt(&nodeChunk.mNumChilds, targetEndianType); ConvertUnsignedInt(&nodeChunk.mSkeletalLODs, targetEndianType); - for (uint32 j = 0; j < 16; ++j) - { - ConvertFloat(&nodeChunk.mOBB[j], targetEndianType); - } - // write it - file->Write(&nodeChunk, sizeof(EMotionFX::FileFormat::Actor_Node)); + file->Write(&nodeChunk, sizeof(EMotionFX::FileFormat::Actor_Node2)); // write the name of the node and parent SaveString(node->GetName(), file, targetEndianType); } - void SaveNodes(MCore::Stream* file, EMotionFX::Actor* actor, MCore::Endian::EEndianType targetEndianType) { uint32 i; @@ -167,10 +141,10 @@ namespace ExporterLib // chunk information EMotionFX::FileFormat::FileChunk chunkHeader; chunkHeader.mChunkID = EMotionFX::FileFormat::ACTOR_CHUNK_NODES; - chunkHeader.mVersion = 1; + chunkHeader.mVersion = 2; // get the nodes chunk size - chunkHeader.mSizeInBytes = sizeof(EMotionFX::FileFormat::Actor_Nodes) + numNodes * sizeof(EMotionFX::FileFormat::Actor_Node); + chunkHeader.mSizeInBytes = sizeof(EMotionFX::FileFormat::Actor_Nodes2) + numNodes * sizeof(EMotionFX::FileFormat::Actor_Node2); for (i = 0; i < numNodes; i++) { chunkHeader.mSizeInBytes += GetStringChunkSize(actor->GetSkeleton()->GetNode(i)->GetName()); @@ -181,23 +155,15 @@ namespace ExporterLib file->Write(&chunkHeader, sizeof(EMotionFX::FileFormat::FileChunk)); // nodes chunk - EMotionFX::FileFormat::Actor_Nodes nodesChunk; + EMotionFX::FileFormat::Actor_Nodes2 nodesChunk; nodesChunk.mNumNodes = numNodes; nodesChunk.mNumRootNodes = actor->GetSkeleton()->GetNumRootNodes(); - nodesChunk.mStaticBoxMin.mX = actor->GetStaticAabb().GetMin().GetX(); - nodesChunk.mStaticBoxMin.mY = actor->GetStaticAabb().GetMin().GetY(); - nodesChunk.mStaticBoxMin.mZ = actor->GetStaticAabb().GetMin().GetZ(); - nodesChunk.mStaticBoxMax.mX = actor->GetStaticAabb().GetMax().GetX(); - nodesChunk.mStaticBoxMax.mY = actor->GetStaticAabb().GetMax().GetY(); - nodesChunk.mStaticBoxMax.mZ = actor->GetStaticAabb().GetMax().GetZ(); // endian conversion and write it ConvertUnsignedInt(&nodesChunk.mNumNodes, targetEndianType); ConvertUnsignedInt(&nodesChunk.mNumRootNodes, targetEndianType); - ConvertFileVector3(&nodesChunk.mStaticBoxMin, targetEndianType); - ConvertFileVector3(&nodesChunk.mStaticBoxMax, targetEndianType); - file->Write(&nodesChunk, sizeof(EMotionFX::FileFormat::Actor_Nodes)); + file->Write(&nodesChunk, sizeof(EMotionFX::FileFormat::Actor_Nodes2)); // write the nodes for (uint32 n = 0; n < numNodes; n++) diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ActorFileFormat.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ActorFileFormat.h index b8a5cc9616..402c70c8a1 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ActorFileFormat.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ActorFileFormat.h @@ -108,7 +108,7 @@ namespace EMotionFX // a node header // (not aligned) - struct Actor_Node + struct Actor_Node2 { FileQuaternion mLocalQuat; // the local rotation (before hierarchy) FileVector3 mLocalPos; // the local translation (before hierarchy) @@ -117,7 +117,6 @@ namespace EMotionFX uint32 mParentIndex;// parent node number, or 0xFFFFFFFF in case of a root node uint32 mNumChilds; // the number of child nodes uint8 mNodeFlags; // #1 bit boolean specifies whether we have to include this node in the bounds calculation or not - float mOBB[16]; // followed by: // string : node name (the unique name of the node) @@ -200,14 +199,11 @@ namespace EMotionFX // uint16 [mNumNodes] }; - // (aligned) - struct Actor_Nodes + struct Actor_Nodes2 { uint32 mNumNodes; uint32 mNumRootNodes; - FileVector3 mStaticBoxMin; - FileVector3 mStaticBoxMax; // followed by Actor_Node4[mNumNodes] or Actor_NODE5[mNumNodes] (for v2) }; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp index 7e7a9ae1c2..ddb240841b 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp @@ -355,12 +355,9 @@ namespace EMotionFX return mLoggingActive; } - //================================================================================================= - - // a chunk that contains all nodes in one chunk - bool ChunkProcessorActorNodes::Process(MCore::File* file, Importer::ImportParameters& importParams) + bool ChunkProcessorActorNodes2::Process(MCore::File* file, Importer::ImportParameters& importParams) { const MCore::Endian::EEndianType endianType = importParams.mEndianType; Actor* actor = importParams.mActor; @@ -369,28 +366,12 @@ namespace EMotionFX MCORE_ASSERT(actor); Skeleton* skeleton = actor->GetSkeleton(); - FileFormat::Actor_Nodes nodesHeader; - file->Read(&nodesHeader, sizeof(FileFormat::Actor_Nodes)); + FileFormat::Actor_Nodes2 nodesHeader; + file->Read(&nodesHeader, sizeof(FileFormat::Actor_Nodes2)); // convert endian MCore::Endian::ConvertUnsignedInt32(&nodesHeader.mNumNodes, endianType); MCore::Endian::ConvertUnsignedInt32(&nodesHeader.mNumRootNodes, endianType); - MCore::Endian::ConvertFloat(&nodesHeader.mStaticBoxMin.mX, endianType); - MCore::Endian::ConvertFloat(&nodesHeader.mStaticBoxMin.mY, endianType); - MCore::Endian::ConvertFloat(&nodesHeader.mStaticBoxMin.mZ, endianType); - MCore::Endian::ConvertFloat(&nodesHeader.mStaticBoxMax.mX, endianType); - MCore::Endian::ConvertFloat(&nodesHeader.mStaticBoxMax.mY, endianType); - MCore::Endian::ConvertFloat(&nodesHeader.mStaticBoxMax.mZ, endianType); - - // convert endian and coord system of the static box - AZ::Vector3 boxMin(nodesHeader.mStaticBoxMin.mX, nodesHeader.mStaticBoxMin.mY, nodesHeader.mStaticBoxMin.mZ); - AZ::Vector3 boxMax(nodesHeader.mStaticBoxMax.mX, nodesHeader.mStaticBoxMax.mY, nodesHeader.mStaticBoxMax.mZ); - - // build the box and set it - MCore::AABB staticBox; - staticBox.SetMin(boxMin); - staticBox.SetMax(boxMax); - actor->SetStaticAABB(staticBox); // pre-allocate space for the nodes actor->SetNumNodes(nodesHeader.mNumNodes); @@ -410,8 +391,8 @@ namespace EMotionFX for (uint32 n = 0; n < nodesHeader.mNumNodes; ++n) { // read the node header - FileFormat::Actor_Node nodeChunk; - file->Read(&nodeChunk, sizeof(FileFormat::Actor_Node)); + FileFormat::Actor_Node2 nodeChunk; + file->Read(&nodeChunk, sizeof(FileFormat::Actor_Node2)); // read the node name const char* nodeName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType); @@ -420,7 +401,6 @@ namespace EMotionFX MCore::Endian::ConvertUnsignedInt32(&nodeChunk.mParentIndex, endianType); MCore::Endian::ConvertUnsignedInt32(&nodeChunk.mSkeletalLODs, endianType); MCore::Endian::ConvertUnsignedInt32(&nodeChunk.mNumChilds, endianType); - MCore::Endian::ConvertFloat(&nodeChunk.mOBB[0], endianType, 16); // show the name of the node, the parent and the number of children if (GetLogging()) @@ -453,11 +433,6 @@ namespace EMotionFX ConvertScale(&scale, endianType); ConvertQuaternion(&rot, endianType); - // make sure the input data is normalized - // TODO: this isn't really needed as we already normalized? - //rot.FastNormalize(); - //scaleRot.FastNormalize(); - // set the local transform Transform bindTransform; bindTransform.mPosition = pos; @@ -503,23 +478,6 @@ namespace EMotionFX skeleton->AddRootNode(nodeIndex); } - // OBB - AZ::Matrix4x4 obbMatrix4x4 = AZ::Matrix4x4::CreateFromRowMajorFloat16(nodeChunk.mOBB); - - const AZ::Vector3 obbCenter = obbMatrix4x4.GetTranslation(); - const AZ::Vector3 obbExtents = obbMatrix4x4.GetRowAsVector3(3); - - // initialize the OBB - MCore::OBB obb; - obb.SetCenter(obbCenter); - obb.SetExtents(obbExtents); - - // need to transpose to go from row major to column major - const AZ::Matrix3x3 obbMatrix3x3 = AZ::Matrix3x3::CreateFromMatrix4x4(obbMatrix4x4).GetTranspose(); - const AZ::Transform obbTransform = AZ::Transform::CreateFromMatrix3x3AndTranslation(obbMatrix3x3, obbExtents); - obb.SetTransformation(obbTransform); - actor->SetNodeOBB(nodeIndex, obb); - if (GetLogging()) { MCore::LogDetailedInfo(" - Position: x=%f, y=%f, z=%f", diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h index 306e4af0c8..56822c6940 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h @@ -256,7 +256,6 @@ namespace EMotionFX virtual ~ChunkProcessor(); }; - //------------------------------------------------------------------------------------------------- /** @@ -287,7 +286,7 @@ namespace EMotionFX EMFX_CHUNKPROCESSOR(ChunkProcessorActorInfo3, FileFormat::ACTOR_CHUNK_INFO, 3) EMFX_CHUNKPROCESSOR(ChunkProcessorActorProgMorphTarget, FileFormat::ACTOR_CHUNK_STDPROGMORPHTARGET, 1) EMFX_CHUNKPROCESSOR(ChunkProcessorActorNodeGroups, FileFormat::ACTOR_CHUNK_NODEGROUPS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorActorNodes, FileFormat::ACTOR_CHUNK_NODES, 1) + EMFX_CHUNKPROCESSOR(ChunkProcessorActorNodes2, FileFormat::ACTOR_CHUNK_NODES, 2) EMFX_CHUNKPROCESSOR(ChunkProcessorActorProgMorphTargets, FileFormat::ACTOR_CHUNK_STDPMORPHTARGETS, 1) EMFX_CHUNKPROCESSOR(ChunkProcessorActorProgMorphTargets2, FileFormat::ACTOR_CHUNK_STDPMORPHTARGETS, 2) EMFX_CHUNKPROCESSOR(ChunkProcessorActorNodeMotionSources, FileFormat::ACTOR_CHUNK_NODEMOTIONSOURCES, 1) diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp index 67cbb91c06..82da9ccd86 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp @@ -352,7 +352,7 @@ namespace EMotionFX } // post create init - actor->PostCreateInit(actorSettings.mMakeGeomLODsCompatibleWithSkeletalLODs, false, actorSettings.mUnitTypeConvert); + actor->PostCreateInit(actorSettings.mMakeGeomLODsCompatibleWithSkeletalLODs, actorSettings.mUnitTypeConvert); } // close the file and return a pointer to the actor we loaded @@ -846,7 +846,7 @@ namespace EMotionFX RegisterChunkProcessor(aznew ChunkProcessorActorInfo3()); RegisterChunkProcessor(aznew ChunkProcessorActorProgMorphTarget()); RegisterChunkProcessor(aznew ChunkProcessorActorNodeGroups()); - RegisterChunkProcessor(aznew ChunkProcessorActorNodes()); + RegisterChunkProcessor(aznew ChunkProcessorActorNodes2()); RegisterChunkProcessor(aznew ChunkProcessorActorProgMorphTargets()); RegisterChunkProcessor(aznew ChunkProcessorActorProgMorphTargets2()); RegisterChunkProcessor(aznew ChunkProcessorActorNodeMotionSources());