Work on skinned meshes
This commit is contained in:
parent
31bb18af90
commit
4a9986a75b
Binary file not shown.
|
@ -27,16 +27,11 @@ Bone* Bone::GetParent() {
|
|||
return mParent;
|
||||
}
|
||||
|
||||
std::unique_ptr<DataChunk> Bone::GenerateRestPosiitonData(float scale, aiQuaternion rotation) {
|
||||
aiVector3D restPosition = rotation.Rotate(mRestPosition);
|
||||
aiQuaternion restRotation = rotation * mRestRotation;
|
||||
|
||||
std::unique_ptr<DataChunk> Bone::GenerateRestPosiitonData() {
|
||||
std::unique_ptr<StructureDataChunk> result(new StructureDataChunk());
|
||||
|
||||
restPosition = restPosition * scale;
|
||||
|
||||
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(restPosition)));
|
||||
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(restRotation)));
|
||||
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(mRestPosition)));
|
||||
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(mRestRotation)));
|
||||
result->Add(std::unique_ptr<DataChunk>(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<Bone>(new Bone(
|
||||
mBones.size(),
|
||||
boneName,
|
||||
parent,
|
||||
restPosition,
|
||||
restRotation,
|
||||
restScale
|
||||
)));
|
||||
|
||||
mBoneByName.insert(std::pair<std::string, Bone*>(boneName, mBones.back().get()));
|
||||
}
|
||||
}
|
||||
|
||||
void BoneHierarchy::SearchForBones(aiNode* node, Bone* currentBoneParent, std::set<std::string>& 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<StructureDataChunk> 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<FileDefinition>(new DataFileDefinition("struct Transform", variableName, true, "_anim", std::move(transformData))));
|
||||
std::unique_ptr<FileDefinition> 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 {
|
||||
|
|
|
@ -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<std::unique_ptr<AnimationNodeInfo>> nodesWithAnimation;
|
||||
};
|
||||
|
||||
class CFileDefinition;
|
||||
|
||||
class Bone {
|
||||
|
@ -25,7 +36,7 @@ public:
|
|||
const std::string& GetName();
|
||||
Bone* GetParent();
|
||||
|
||||
std::unique_ptr<DataChunk> GenerateRestPosiitonData(float scale, aiQuaternion rotation);
|
||||
std::unique_ptr<DataChunk> 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<Bone*> mChildren;
|
||||
};
|
||||
|
@ -53,12 +64,15 @@ class BoneHierarchy {
|
|||
public:
|
||||
void SearchForBones(aiNode* node, Bone* currentBoneParent, std::set<std::string>& 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<std::unique_ptr<Bone>> mBones;
|
||||
std::map<std::string, Bone*> mBoneByName;
|
||||
|
|
|
@ -402,4 +402,8 @@ std::shared_ptr<ExtendedMesh> CFileDefinition::GetExtendedMesh(aiMesh* mesh) {
|
|||
mMeshes[mesh] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BoneHierarchy& CFileDefinition::GetBoneHierarchy() {
|
||||
return mBoneHierarchy;
|
||||
}
|
|
@ -53,6 +53,8 @@ public:
|
|||
bool GetResourceName(const void* resource, std::string& result) const;
|
||||
|
||||
std::shared_ptr<ExtendedMesh> GetExtendedMesh(aiMesh* mesh);
|
||||
|
||||
BoneHierarchy& GetBoneHierarchy();
|
||||
private:
|
||||
std::string mPrefix;
|
||||
float mModelScale;
|
||||
|
|
|
@ -137,6 +137,8 @@ std::unique_ptr<DataChunk> PushMatrixCommand::GenerateCommand() {
|
|||
} else {
|
||||
flags += "G_MTX_PUSH";
|
||||
}
|
||||
|
||||
result->AddPrimitive(flags);
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
|
|
@ -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) :
|
||||
|
|
|
@ -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<FileDefinition> dlResult = displayList.Generate(fileSuffix);
|
||||
|
||||
|
||||
if (fileDefinition.GetBoneHierarchy().HasData()) {
|
||||
dlResult->AddTypeHeader("\"sk64/skelatool_defs.h\"");
|
||||
}
|
||||
|
||||
fileDefinition.AddDefinition(std::move(dlResult));
|
||||
|
||||
return displayList.GetName();
|
||||
|
|
|
@ -15,28 +15,7 @@
|
|||
#include "AnimationTranslator.h"
|
||||
#include "MeshWriter.h"
|
||||
#include "FileUtils.h"
|
||||
|
||||
std::vector<SKAnimationHeader> generateAnimationData(const aiScene* scene, BoneHierarchy& bones, CFileDefinition& fileDef, float modelScale, unsigned short targetTicksPerSecond, aiQuaternion rotate) {
|
||||
std::vector<SKAnimationHeader> 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<StructureDataChunk> animationNameData(new StructureDataChunk());
|
||||
|
||||
int index = 0;
|
||||
for (auto it = animations.begin(); it != animations.end(); ++it) {
|
||||
std::unique_ptr<StructureDataChunk> 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<FileDefinition>(new DataFileDefinition("struct SKAnimationHeader", animationsName, true, "_anim", std::move(animationNameData))));
|
||||
|
||||
std::unique_ptr<StructureDataChunk> 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<FileDefinition>(new DataFileDefinition("unsigned short", boneParentName, true, "_anim", std::move(boneParentDataChunk))));
|
||||
generateAnimationForScene(scene, fileDefinition, settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
141
skelatool64/src/definition_generator/AnimationGenerator.cpp
Normal file
141
skelatool64/src/definition_generator/AnimationGenerator.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
#include "AnimationGenerator.h"
|
||||
|
||||
#include "./DefinitionGenerator.h"
|
||||
#include "../AnimationTranslator.h"
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
std::shared_ptr<NodeAnimationInfo> findNodesForWithAnimation(const aiScene* scene, const aiMatrix4x4& baseTransform) {
|
||||
std::set<std::string> 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<aiNode*> 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<const aiNode*, int> 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<NodeAnimationInfo> result(new NodeAnimationInfo());
|
||||
|
||||
for (auto node : nodesWithAnimationData) {
|
||||
std::unique_ptr<AnimationNodeInfo> 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<AnimationNodeInfo>& a, const std::unique_ptr<AnimationNodeInfo>& b) -> bool {
|
||||
return nodeOrder[a->node] < nodeOrder[b->node];
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<SKAnimationHeader> generateAnimationData(const aiScene* scene, BoneHierarchy& bones, CFileDefinition& fileDef, float modelScale, unsigned short targetTicksPerSecond, aiQuaternion rotate) {
|
||||
std::vector<SKAnimationHeader> 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<StructureDataChunk> animationNameData(new StructureDataChunk());
|
||||
|
||||
int index = 0;
|
||||
for (auto it = animations.begin(); it != animations.end(); ++it) {
|
||||
std::unique_ptr<StructureDataChunk> 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<DataFileDefinition> 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<StructureDataChunk> 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<FileDefinition>(new DataFileDefinition("unsigned short", boneParentName, true, "_geo", std::move(boneParentDataChunk))));
|
||||
}
|
17
skelatool64/src/definition_generator/AnimationGenerator.h
Normal file
17
skelatool64/src/definition_generator/AnimationGenerator.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef __ANIMATION_GENERATOR_H__
|
||||
#define __ANIMATION_GENERATOR_H__
|
||||
|
||||
#include <assimp/scene.h>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "../CFileDefinition.h"
|
||||
#include "../DisplayListSettings.h"
|
||||
#include "../Animation.h"
|
||||
|
||||
std::shared_ptr<NodeAnimationInfo> findNodesForWithAnimation(const aiScene* scene, const aiMatrix4x4& baseTransform);
|
||||
|
||||
std::vector<SKAnimationHeader> 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
|
|
@ -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<void(aiNode*)>& 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);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
#include <assimp/scene.h>
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include "../CFileDefinition.h"
|
||||
|
||||
|
@ -20,8 +21,8 @@ public:
|
|||
virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) = 0;
|
||||
protected:
|
||||
std::vector<aiNode*> mIncludedNodes;
|
||||
private:
|
||||
void TraverseNodes(aiNode* node);
|
||||
};
|
||||
|
||||
void forEachNode(aiNode* node, const std::function<void(aiNode*)>& callback);
|
||||
|
||||
#endif
|
|
@ -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<Bone*, Bone*>(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<RenderChunk> 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);
|
||||
}
|
||||
}
|
|
@ -20,6 +20,8 @@ void StaticGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition&
|
|||
|
||||
std::vector<StaticContentElement> elements;
|
||||
|
||||
BoneHierarchy unusedBones;
|
||||
|
||||
sortNodesByRoom(mIncludedNodes, mRoomMapping);
|
||||
|
||||
for (auto node = mIncludedNodes.begin(); node != mIncludedNodes.end(); ++node) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue