diff --git a/assets/models/props/button.blend b/assets/models/props/button.blend index 516fdc7..74f6f35 100644 Binary files a/assets/models/props/button.blend and b/assets/models/props/button.blend differ diff --git a/skelatool64/src/BoneHierarchy.cpp b/skelatool64/src/BoneHierarchy.cpp index 35156de..90289cf 100644 --- a/skelatool64/src/BoneHierarchy.cpp +++ b/skelatool64/src/BoneHierarchy.cpp @@ -27,16 +27,11 @@ Bone* Bone::GetParent() { return mParent; } -std::unique_ptr Bone::GenerateRestPosiitonData(float scale, aiQuaternion rotation) { - aiVector3D restPosition = rotation.Rotate(mRestPosition); - aiQuaternion restRotation = rotation * mRestRotation; - +std::unique_ptr Bone::GenerateRestPosiitonData() { std::unique_ptr result(new StructureDataChunk()); - restPosition = restPosition * scale; - - result->Add(std::unique_ptr(new StructureDataChunk(restPosition))); - result->Add(std::unique_ptr(new StructureDataChunk(restRotation))); + result->Add(std::unique_ptr(new StructureDataChunk(mRestPosition))); + result->Add(std::unique_ptr(new StructureDataChunk(mRestRotation))); result->Add(std::unique_ptr(new StructureDataChunk(mRestScale))); return std::move(result); @@ -98,6 +93,41 @@ int Bone::GetBoneIndex(Bone* a) { } } +void BoneHierarchy::PopulateWithAnimationNodeInfo(const NodeAnimationInfo& animInfo) { + for (auto& node : animInfo.nodesWithAnimation) { + Bone* parent = nullptr; + + if (node->parent) { + auto parentFind = mBoneByName.find(node->parent->mName.C_Str()); + + if (parentFind != mBoneByName.end()) { + parent = parentFind->second; + } + } + + std::string boneName = node->node->mName.C_Str(); + + aiVector3D restPosition; + aiQuaternion restRotation; + aiVector3D restScale; + + aiMatrix4x4 fullRestTransform = node->relativeTransform * node->node->mTransformation; + + fullRestTransform.Decompose(restScale, restRotation, restPosition); + + mBones.push_back(std::unique_ptr(new Bone( + mBones.size(), + boneName, + parent, + restPosition, + restRotation, + restScale + ))); + + mBoneByName.insert(std::pair(boneName, mBones.back().get())); + } +} + void BoneHierarchy::SearchForBones(aiNode* node, Bone* currentBoneParent, std::set& knownBones, bool parentIsBone) { if (knownBones.find(node->mName.C_Str()) != knownBones.end()) { aiVector3D restPosition; @@ -153,17 +183,13 @@ Bone* BoneHierarchy::BoneForName(std::string name) { } } -void BoneHierarchy::GenerateRestPosiitonData(CFileDefinition& fileDef, const std::string& variableName, float scale, aiQuaternion rotation) { +void BoneHierarchy::GenerateRestPosiitonData(CFileDefinition& fileDef, const std::string& variableName) { if (mBones.size() == 0) return; std::unique_ptr transformData(new StructureDataChunk()); for (unsigned int boneIndex = 0; boneIndex < mBones.size(); ++boneIndex) { - if (mBones[boneIndex]->GetParent()) { - transformData->Add(std::move(mBones[boneIndex]->GenerateRestPosiitonData(scale, aiQuaternion()))); - } else { - transformData->Add(std::move(mBones[boneIndex]->GenerateRestPosiitonData(scale, rotation))); - } + transformData->Add(std::move(mBones[boneIndex]->GenerateRestPosiitonData())); std::string boneName = fileDef.GetUniqueName(mBones[boneIndex]->GetName() + "_BONE"); std::transform(boneName.begin(), boneName.end(), boneName.begin(), ::toupper); @@ -171,7 +197,9 @@ void BoneHierarchy::GenerateRestPosiitonData(CFileDefinition& fileDef, const std fileDef.AddMacro(boneName, std::to_string(boneIndex)); } - fileDef.AddDefinition(std::unique_ptr(new DataFileDefinition("struct Transform", variableName, true, "_anim", std::move(transformData)))); + std::unique_ptr restPosDef(new DataFileDefinition("struct Transform", variableName, true, "_geo", std::move(transformData))); + restPosDef->AddTypeHeader("\"math/transform.h\""); + fileDef.AddDefinition(std::move(restPosDef)); } bool BoneHierarchy::HasData() const { diff --git a/skelatool64/src/BoneHierarchy.h b/skelatool64/src/BoneHierarchy.h index a1f871b..41efa11 100644 --- a/skelatool64/src/BoneHierarchy.h +++ b/skelatool64/src/BoneHierarchy.h @@ -15,6 +15,17 @@ #include "ErrorCode.h" #include "./definitions/DataChunk.h" +struct AnimationNodeInfo { + const aiNode* node; + // the ancestor of this node that is also a bone + const aiNode* parent; + aiMatrix4x4 relativeTransform; +}; + +struct NodeAnimationInfo { + std::vector> nodesWithAnimation; +}; + class CFileDefinition; class Bone { @@ -25,7 +36,7 @@ public: const std::string& GetName(); Bone* GetParent(); - std::unique_ptr GenerateRestPosiitonData(float scale, aiQuaternion rotation); + std::unique_ptr GenerateRestPosiitonData(); static Bone* FindCommonAncestor(Bone* a, Bone* b); /** @@ -44,7 +55,7 @@ private: Bone* mParent; aiVector3D mRestPosition; aiQuaternion mRestRotation; - aiQuaternion mRestScale; + aiVector3D mRestScale; std::vector mChildren; }; @@ -53,12 +64,15 @@ class BoneHierarchy { public: void SearchForBones(aiNode* node, Bone* currentBoneParent, std::set& knownBones, bool parentIsBone); void SearchForBonesInScene(const aiScene* scene); + + void PopulateWithAnimationNodeInfo(const NodeAnimationInfo& animInfo); + Bone* BoneByIndex(unsigned index); Bone* BoneForName(std::string name); bool HasData() const; unsigned int GetBoneCount() const; - void GenerateRestPosiitonData(CFileDefinition& fileDef, const std::string& variableName, float scale, aiQuaternion rotation); + void GenerateRestPosiitonData(CFileDefinition& fileDef, const std::string& variableName); private: std::vector> mBones; std::map mBoneByName; diff --git a/skelatool64/src/CFileDefinition.cpp b/skelatool64/src/CFileDefinition.cpp index 8333205..13db278 100644 --- a/skelatool64/src/CFileDefinition.cpp +++ b/skelatool64/src/CFileDefinition.cpp @@ -402,4 +402,8 @@ std::shared_ptr CFileDefinition::GetExtendedMesh(aiMesh* mesh) { mMeshes[mesh] = result; return result; +} + +BoneHierarchy& CFileDefinition::GetBoneHierarchy() { + return mBoneHierarchy; } \ No newline at end of file diff --git a/skelatool64/src/CFileDefinition.h b/skelatool64/src/CFileDefinition.h index ef2794a..b23c895 100644 --- a/skelatool64/src/CFileDefinition.h +++ b/skelatool64/src/CFileDefinition.h @@ -53,6 +53,8 @@ public: bool GetResourceName(const void* resource, std::string& result) const; std::shared_ptr GetExtendedMesh(aiMesh* mesh); + + BoneHierarchy& GetBoneHierarchy(); private: std::string mPrefix; float mModelScale; diff --git a/skelatool64/src/DisplayList.cpp b/skelatool64/src/DisplayList.cpp index 35e6d9b..9433b4b 100644 --- a/skelatool64/src/DisplayList.cpp +++ b/skelatool64/src/DisplayList.cpp @@ -137,6 +137,8 @@ std::unique_ptr PushMatrixCommand::GenerateCommand() { } else { flags += "G_MTX_PUSH"; } + + result->AddPrimitive(flags); return std::move(result); } diff --git a/skelatool64/src/ExtendedMesh.cpp b/skelatool64/src/ExtendedMesh.cpp index dfe7014..25c24bb 100644 --- a/skelatool64/src/ExtendedMesh.cpp +++ b/skelatool64/src/ExtendedMesh.cpp @@ -63,6 +63,12 @@ ExtendedMesh::ExtendedMesh(const ExtendedMesh& other): mBoneSpanningFaces[it.first] = faces; } + + for (auto& it : mNormalInverseTransform) { + if (it) { + it = new aiMatrix3x3(*it); + } + } } ExtendedMesh::ExtendedMesh(aiMesh* mesh, BoneHierarchy& boneHierarchy) : diff --git a/skelatool64/src/MeshWriter.cpp b/skelatool64/src/MeshWriter.cpp index c53d780..fb1a6f7 100644 --- a/skelatool64/src/MeshWriter.cpp +++ b/skelatool64/src/MeshWriter.cpp @@ -125,6 +125,12 @@ std::string generateMesh(const aiScene* scene, CFileDefinition& fileDefinition, DisplayList displayList(fileDefinition.GetUniqueName("model_gfx")); generateMeshIntoDL(scene, fileDefinition, renderChunks, settings, displayList, fileSuffix); std::unique_ptr dlResult = displayList.Generate(fileSuffix); + + + if (fileDefinition.GetBoneHierarchy().HasData()) { + dlResult->AddTypeHeader("\"sk64/skelatool_defs.h\""); + } + fileDefinition.AddDefinition(std::move(dlResult)); return displayList.GetName(); diff --git a/skelatool64/src/SceneWriter.cpp b/skelatool64/src/SceneWriter.cpp index 0dce4e2..05a9c60 100644 --- a/skelatool64/src/SceneWriter.cpp +++ b/skelatool64/src/SceneWriter.cpp @@ -15,28 +15,7 @@ #include "AnimationTranslator.h" #include "MeshWriter.h" #include "FileUtils.h" - -std::vector generateAnimationData(const aiScene* scene, BoneHierarchy& bones, CFileDefinition& fileDef, float modelScale, unsigned short targetTicksPerSecond, aiQuaternion rotate) { - std::vector animations; - - for (unsigned i = 0; i < scene->mNumAnimations; ++i) { - SKAnimation animation; - if (translateAnimationToSK(*scene->mAnimations[i], animation, bones, modelScale, targetTicksPerSecond, rotate)) { - std::string animationName = fileDef.GetUniqueName(scene->mAnimations[i]->mName.C_Str()); - unsigned short firstChunkSize = formatAnimationChunks(animationName, animation.chunks, fileDef); - - SKAnimationHeader header; - header.firstChunkSize = firstChunkSize; - header.ticksPerSecond = targetTicksPerSecond; - header.maxTicks = animation.maxTicks; - header.animationName = animationName; - - animations.push_back(header); - } - } - - return animations; -} +#include "./definition_generator/AnimationGenerator.h" void generateMeshFromScene(const aiScene* scene, CFileDefinition& fileDefinition, DisplayListSettings& settings) { BoneHierarchy bones; @@ -67,51 +46,7 @@ void generateMeshFromScene(const aiScene* scene, CFileDefinition& fileDefinition } if (shouldExportAnimations) { - std::string bonesName = fileDefinition.GetUniqueName("default_bones"); - std::string boneParentName = fileDefinition.GetUniqueName("bone_parent"); - bones.GenerateRestPosiitonData(fileDefinition, bonesName, settings.mGraphicsScale, settings.mRotateModel); - std::string boneCountName = bonesName + "_COUNT"; - std::transform(boneCountName.begin(), boneCountName.end(), boneCountName.begin(), ::toupper); - fileDefinition.AddMacro(boneCountName, std::to_string(bones.GetBoneCount())); - - std::string animationsName = fileDefinition.GetUniqueName("animations"); - auto animations = generateAnimationData(scene, bones, fileDefinition, settings.mGraphicsScale, settings.mTicksPerSecond, settings.mRotateModel); - - std::unique_ptr animationNameData(new StructureDataChunk()); - - int index = 0; - for (auto it = animations.begin(); it != animations.end(); ++it) { - std::unique_ptr animationChunk(new StructureDataChunk()); - - animationChunk->AddPrimitive(it->firstChunkSize); - animationChunk->AddPrimitive(it->ticksPerSecond); - animationChunk->AddPrimitive(it->maxTicks); - animationChunk->AddPrimitive(0); - animationChunk->AddPrimitive(std::string("(struct SKAnimationChunk*)") + it->animationName); - animationChunk->AddPrimitive(0); - - animationNameData->Add(std::move(animationChunk)); - - std::string animationIndex = fileDefinition.GetUniqueName(it->animationName + "_INDEX"); - std::transform(animationIndex.begin(), animationIndex.end(), animationIndex.begin(), ::toupper); - fileDefinition.AddMacro(animationIndex, std::to_string(index)); - - ++index; - } - fileDefinition.AddDefinition(std::unique_ptr(new DataFileDefinition("struct SKAnimationHeader", animationsName, true, "_anim", std::move(animationNameData)))); - - std::unique_ptr boneParentDataChunk(new StructureDataChunk()); - - for (unsigned int boneIndex = 0; boneIndex < bones.GetBoneCount(); ++boneIndex) { - Bone* bone = bones.BoneByIndex(boneIndex); - if (bone->GetParent()) { - boneParentDataChunk->AddPrimitive(bone->GetParent()->GetIndex()); - } else { - boneParentDataChunk->AddPrimitive(0xFFFF); - } - } - - fileDefinition.AddDefinition(std::unique_ptr(new DataFileDefinition("unsigned short", boneParentName, true, "_anim", std::move(boneParentDataChunk)))); + generateAnimationForScene(scene, fileDefinition, settings); } } diff --git a/skelatool64/src/definition_generator/AnimationGenerator.cpp b/skelatool64/src/definition_generator/AnimationGenerator.cpp new file mode 100644 index 0000000..9441406 --- /dev/null +++ b/skelatool64/src/definition_generator/AnimationGenerator.cpp @@ -0,0 +1,141 @@ +#include "AnimationGenerator.h" + +#include "./DefinitionGenerator.h" +#include "../AnimationTranslator.h" +#include +#include +#include + +std::shared_ptr findNodesForWithAnimation(const aiScene* scene, const aiMatrix4x4& baseTransform) { + std::set animatedNodeNames; + + for (unsigned animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex) { + aiAnimation* animation = scene->mAnimations[animIndex]; + + for (unsigned channelIndex = 0; channelIndex < animation->mNumChannels; ++channelIndex) { + animatedNodeNames.insert(animation->mChannels[channelIndex]->mNodeName.C_Str()); + } + } + + std::set nodesWithAnimationData; + + for (unsigned meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { + aiMesh* mesh = scene->mMeshes[meshIndex]; + for (unsigned boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) { + animatedNodeNames.insert(mesh->mBones[boneIndex]->mName.C_Str()); + } + } + + std::map nodeOrder; + + forEachNode(scene->mRootNode, [&](aiNode* node) -> void { + if (animatedNodeNames.find(node->mName.C_Str()) != animatedNodeNames.end()) { + nodesWithAnimationData.insert(node); + } + + nodeOrder.insert(std::make_pair(node, nodeOrder.size())); + }); + + std::shared_ptr result(new NodeAnimationInfo()); + + for (auto node : nodesWithAnimationData) { + std::unique_ptr nodeInfo(new AnimationNodeInfo()); + + aiNode* currentNode = node; + + while (currentNode->mParent && nodesWithAnimationData.find(currentNode->mParent) == nodesWithAnimationData.end()) { + currentNode = currentNode->mParent; + + nodeInfo->relativeTransform = currentNode->mTransformation * nodeInfo->relativeTransform; + } + + if (!currentNode->mParent) { + nodeInfo->relativeTransform = baseTransform * nodeInfo->relativeTransform; + } + + nodeInfo->node = node; + nodeInfo->parent = currentNode->mParent; + + result->nodesWithAnimation.push_back(std::move(nodeInfo)); + } + + std::sort(result->nodesWithAnimation.begin(), result->nodesWithAnimation.end(), [&](const std::unique_ptr& a, const std::unique_ptr& b) -> bool { + return nodeOrder[a->node] < nodeOrder[b->node]; + }); + + return result; +} + +std::vector generateAnimationData(const aiScene* scene, BoneHierarchy& bones, CFileDefinition& fileDef, float modelScale, unsigned short targetTicksPerSecond, aiQuaternion rotate) { + std::vector animations; + + for (unsigned i = 0; i < scene->mNumAnimations; ++i) { + SKAnimation animation; + if (translateAnimationToSK(*scene->mAnimations[i], animation, bones, modelScale, targetTicksPerSecond, rotate)) { + std::string animationName = fileDef.GetUniqueName(scene->mAnimations[i]->mName.C_Str()); + unsigned short firstChunkSize = formatAnimationChunks(animationName, animation.chunks, fileDef); + + SKAnimationHeader header; + header.firstChunkSize = firstChunkSize; + header.ticksPerSecond = targetTicksPerSecond; + header.maxTicks = animation.maxTicks; + header.animationName = animationName; + + animations.push_back(header); + } + } + + return animations; +} + +void generateAnimationForScene(const aiScene* scene, CFileDefinition &fileDefinition, DisplayListSettings& settings) { + BoneHierarchy& bones = fileDefinition.GetBoneHierarchy(); + + std::string bonesName = fileDefinition.GetUniqueName("default_bones"); + std::string boneParentName = fileDefinition.GetUniqueName("bone_parent"); + bones.GenerateRestPosiitonData(fileDefinition, bonesName); + std::string boneCountName = bonesName + "_COUNT"; + std::transform(boneCountName.begin(), boneCountName.end(), boneCountName.begin(), ::toupper); + fileDefinition.AddMacro(boneCountName, std::to_string(bones.GetBoneCount())); + + std::string animationsName = fileDefinition.GetUniqueName("animations"); + auto animations = generateAnimationData(scene, bones, fileDefinition, settings.mGraphicsScale, settings.mTicksPerSecond, settings.mRotateModel); + + std::unique_ptr animationNameData(new StructureDataChunk()); + + int index = 0; + for (auto it = animations.begin(); it != animations.end(); ++it) { + std::unique_ptr animationChunk(new StructureDataChunk()); + + animationChunk->AddPrimitive(it->firstChunkSize); + animationChunk->AddPrimitive(it->ticksPerSecond); + animationChunk->AddPrimitive(it->maxTicks); + animationChunk->AddPrimitive(0); + animationChunk->AddPrimitive(std::string("(struct SKAnimationChunk*)") + it->animationName); + animationChunk->AddPrimitive(0); + + animationNameData->Add(std::move(animationChunk)); + + std::string animationIndex = fileDefinition.GetUniqueName(it->animationName + "_INDEX"); + std::transform(animationIndex.begin(), animationIndex.end(), animationIndex.begin(), ::toupper); + fileDefinition.AddMacro(animationIndex, std::to_string(index)); + + ++index; + } + std::unique_ptr headerDef(new DataFileDefinition("struct SKAnimationHeader", animationsName, true, "_geo", std::move(animationNameData))); + headerDef->AddTypeHeader("\"sk64/skelatool_clip.h\""); + fileDefinition.AddDefinition(std::move(headerDef)); + + std::unique_ptr boneParentDataChunk(new StructureDataChunk()); + + for (unsigned int boneIndex = 0; boneIndex < bones.GetBoneCount(); ++boneIndex) { + Bone* bone = bones.BoneByIndex(boneIndex); + if (bone->GetParent()) { + boneParentDataChunk->AddPrimitive(bone->GetParent()->GetIndex()); + } else { + boneParentDataChunk->AddPrimitive(0xFFFF); + } + } + + fileDefinition.AddDefinition(std::unique_ptr(new DataFileDefinition("unsigned short", boneParentName, true, "_geo", std::move(boneParentDataChunk)))); +} \ No newline at end of file diff --git a/skelatool64/src/definition_generator/AnimationGenerator.h b/skelatool64/src/definition_generator/AnimationGenerator.h new file mode 100644 index 0000000..ad434ed --- /dev/null +++ b/skelatool64/src/definition_generator/AnimationGenerator.h @@ -0,0 +1,17 @@ +#ifndef __ANIMATION_GENERATOR_H__ +#define __ANIMATION_GENERATOR_H__ + +#include +#include +#include + +#include "../CFileDefinition.h" +#include "../DisplayListSettings.h" +#include "../Animation.h" + +std::shared_ptr findNodesForWithAnimation(const aiScene* scene, const aiMatrix4x4& baseTransform); + +std::vector generateAnimationData(const aiScene* scene, BoneHierarchy& bones, CFileDefinition& fileDef, float modelScale, unsigned short targetTicksPerSecond, aiQuaternion rotate); +void generateAnimationForScene(const aiScene* scene, CFileDefinition &fileDefinition, DisplayListSettings& settings); + +#endif \ No newline at end of file diff --git a/skelatool64/src/definition_generator/DefinitionGenerator.cpp b/skelatool64/src/definition_generator/DefinitionGenerator.cpp index 4c333f1..98a97dc 100644 --- a/skelatool64/src/definition_generator/DefinitionGenerator.cpp +++ b/skelatool64/src/definition_generator/DefinitionGenerator.cpp @@ -9,21 +9,25 @@ void DefinitionGenerator::TraverseScene(const aiScene* scene) { } BeforeTraversal(scene); - TraverseNodes(scene->mRootNode); + + forEachNode(scene->mRootNode, [&](aiNode* node) -> void { + if (ShouldIncludeNode(node)) { + mIncludedNodes.push_back(node); + } + }); } void DefinitionGenerator::BeforeTraversal(const aiScene* scene) {} -void DefinitionGenerator::TraverseNodes(aiNode* node) { + +void forEachNode(aiNode* node, const std::function& callback) { if (!node) { return; } - if (ShouldIncludeNode(node)) { - mIncludedNodes.push_back(node); - } + callback(node); for (unsigned int i = 0; i < node->mNumChildren; ++i) { - TraverseNodes(node->mChildren[i]); + forEachNode(node->mChildren[i], callback); } } \ No newline at end of file diff --git a/skelatool64/src/definition_generator/DefinitionGenerator.h b/skelatool64/src/definition_generator/DefinitionGenerator.h index 043cf97..41788f1 100644 --- a/skelatool64/src/definition_generator/DefinitionGenerator.h +++ b/skelatool64/src/definition_generator/DefinitionGenerator.h @@ -4,6 +4,7 @@ #include #include +#include #include "../CFileDefinition.h" @@ -20,8 +21,8 @@ public: virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) = 0; protected: std::vector mIncludedNodes; -private: - void TraverseNodes(aiNode* node); }; +void forEachNode(aiNode* node, const std::function& callback); + #endif \ No newline at end of file diff --git a/skelatool64/src/definition_generator/MeshDefinitionGenerator.cpp b/skelatool64/src/definition_generator/MeshDefinitionGenerator.cpp index 59d92ce..0e35271 100644 --- a/skelatool64/src/definition_generator/MeshDefinitionGenerator.cpp +++ b/skelatool64/src/definition_generator/MeshDefinitionGenerator.cpp @@ -2,6 +2,7 @@ #include "../RenderChunk.h" #include "../MeshWriter.h" +#include "AnimationGenerator.h" bool extractMaterialAutoTileParameters(Material* material, double& sTile, double& tTile) { if (!material) { @@ -58,20 +59,34 @@ void MeshDefinitionGenerator::AppendRenderChunks(const aiScene* scene, aiNode* n ); } - renderChunks.push_back(RenderChunk( - std::pair(NULL, NULL), - mesh, - materialPtr - )); + + for (auto boneSegment = mesh->mFacesForBone.begin(); boneSegment != mesh->mFacesForBone.end(); ++boneSegment) { + renderChunks.push_back(RenderChunk( + std::make_pair(boneSegment->first, boneSegment->first), + mesh, + materialPtr + )); + } + + for (auto pairSegment = mesh->mBoneSpanningFaces.begin(); pairSegment != mesh->mBoneSpanningFaces.end(); ++pairSegment) { + renderChunks.push_back(RenderChunk(pairSegment->first, mesh, materialPtr)); + } } } void MeshDefinitionGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) { std::vector renderChunks; + auto animInfo = findNodesForWithAnimation(scene, mSettings.CreateCollisionTransform()); + fileDefinition.GetBoneHierarchy().PopulateWithAnimationNodeInfo(*animInfo); + for (auto node = mIncludedNodes.begin(); node != mIncludedNodes.end(); ++node) { AppendRenderChunks(scene, *node, fileDefinition, mSettings, renderChunks); } generateMesh(scene, fileDefinition, renderChunks, mSettings, "_geo"); + + if (fileDefinition.GetBoneHierarchy().HasData()) { + generateAnimationForScene(scene, fileDefinition, mSettings); + } } \ No newline at end of file diff --git a/skelatool64/src/definition_generator/StaticGenerator.cpp b/skelatool64/src/definition_generator/StaticGenerator.cpp index 16d0144..772e430 100644 --- a/skelatool64/src/definition_generator/StaticGenerator.cpp +++ b/skelatool64/src/definition_generator/StaticGenerator.cpp @@ -20,6 +20,8 @@ void StaticGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& std::vector elements; + BoneHierarchy unusedBones; + sortNodesByRoom(mIncludedNodes, mRoomMapping); for (auto node = mIncludedNodes.begin(); node != mIncludedNodes.end(); ++node) { diff --git a/src/physics/collision_sphere.c b/src/physics/collision_sphere.c index 8d61aa1..4f44c58 100644 --- a/src/physics/collision_sphere.c +++ b/src/physics/collision_sphere.c @@ -55,6 +55,11 @@ int collisionSphereCollideQuad(void* data, struct Transform* boxTransform, struc contact->tangentImpulse[0] = 0.0f; contact->tangentImpulse[1] = 0.0f; + contact->contactALocal = contact->contactAWorld; + struct Quaternion inverseRotation; + quatConjugate(&boxTransform->rotation, &inverseRotation); + quatMultVector(&inverseRotation, &contact->contactBWorld, &contact->contactBLocal); + return 1; }