diff --git a/skelatool64/main.cpp b/skelatool64/main.cpp index 0090cf2..1c7569a 100644 --- a/skelatool64/main.cpp +++ b/skelatool64/main.cpp @@ -147,34 +147,31 @@ int main(int argc, char *argv[]) { if (args.mIsLevel) { + NodeGroups nodesByGroup(scene); + std::cout << "Grouping objects by room" << std::endl; - RoomGenerator roomGenerator(settings); - roomGenerator.TraverseScene(scene); - roomGenerator.GenerateDefinitions(scene, fileDef); + auto roomOutput = generateRooms(scene, fileDef, settings, nodesByGroup); std::cout << "Generating collider definitions" << std::endl; - CollisionGenerator colliderGenerator(settings, roomGenerator.GetOutput()); - colliderGenerator.TraverseScene(scene); - colliderGenerator.GenerateDefinitions(scene, fileDef); + auto collisionOutput = generateCollision(scene, fileDef, settings, *roomOutput, nodesByGroup); std::cout << "Generating static definitions" << std::endl; - StaticGenerator staticGenerator(settings, roomGenerator.GetOutput()); - staticGenerator.TraverseScene(scene); - staticGenerator.GenerateDefinitions(scene, fileDef); + auto staticOutput = generateStatic(scene, fileDef, settings, *roomOutput, nodesByGroup); - TriggerGenerator triggerGenerator(settings, roomGenerator.GetOutput()); - triggerGenerator.TraverseScene(scene); - triggerGenerator.GenerateDefinitions(scene, fileDef); + auto triggerOutput = generateTriggers(scene, fileDef, settings, *roomOutput, nodesByGroup); std::cout << "Generating level definitions" << std::endl; - LevelGenerator levelGenerator( + generateLevel( + scene, + fileDef, settings, - staticGenerator.GetOutput(), - colliderGenerator.GetOutput(), - triggerGenerator.GetOutput(), - roomGenerator.GetOutput() + *staticOutput, + *collisionOutput, + *triggerOutput, + *roomOutput ); - levelGenerator.GenerateDefinitions(scene, fileDef); + + nodesByGroup.PrintUnusedTypes(); } std::cout << "Writing output" << std::endl; diff --git a/skelatool64/src/DisplayListSettings.cpp b/skelatool64/src/DisplayListSettings.cpp index 981682a..e69f6c3 100644 --- a/skelatool64/src/DisplayListSettings.cpp +++ b/skelatool64/src/DisplayListSettings.cpp @@ -16,7 +16,7 @@ DisplayListSettings::DisplayListSettings(): mIncludeCulling(true) { } -aiMatrix4x4 DisplayListSettings::CreateGlobalTransform() { +aiMatrix4x4 DisplayListSettings::CreateGlobalTransform() const { aiMatrix4x4 scale; aiMatrix4x4::Scaling(aiVector3D(1, 1, 1) * mGraphicsScale, scale); aiMatrix4x4 rotation(mRotateModel.GetMatrix()); @@ -24,7 +24,7 @@ aiMatrix4x4 DisplayListSettings::CreateGlobalTransform() { return rotation * scale; } -aiMatrix4x4 DisplayListSettings::CreateCollisionTransform() { +aiMatrix4x4 DisplayListSettings::CreateCollisionTransform() const { aiMatrix4x4 scale; aiMatrix4x4::Scaling(aiVector3D(1, 1, 1) * mCollisionScale, scale); aiMatrix4x4 rotation(mRotateModel.GetMatrix()); diff --git a/skelatool64/src/DisplayListSettings.h b/skelatool64/src/DisplayListSettings.h index 6c7f4d1..25847f5 100644 --- a/skelatool64/src/DisplayListSettings.h +++ b/skelatool64/src/DisplayListSettings.h @@ -25,8 +25,8 @@ struct DisplayListSettings { bool mExportGeometry; bool mIncludeCulling; - aiMatrix4x4 CreateGlobalTransform(); - aiMatrix4x4 CreateCollisionTransform(); + aiMatrix4x4 CreateGlobalTransform() const; + aiMatrix4x4 CreateCollisionTransform() const; }; #endif \ No newline at end of file diff --git a/skelatool64/src/definition_generator/CollisionGenerator.cpp b/skelatool64/src/definition_generator/CollisionGenerator.cpp index 30a37a1..26a6973 100644 --- a/skelatool64/src/definition_generator/CollisionGenerator.cpp +++ b/skelatool64/src/definition_generator/CollisionGenerator.cpp @@ -5,16 +5,6 @@ #include -CollisionGenerator::CollisionGenerator(const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput) : - DefinitionGenerator(), - mSettings(settings), - mRoomOutput(roomOutput) {} - - -bool CollisionGenerator::ShouldIncludeNode(aiNode* node) { - return StartsWith(node->mName.C_Str(), "@collision "); -} - CollisionGrid::CollisionGrid(const aiAABB& boundaries) { x = floor(boundaries.mMin.x); z = floor(boundaries.mMin.z); @@ -50,12 +40,14 @@ void CollisionGrid::AddToCells(const aiAABB& box, short value) { } } -void CollisionGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) { +std::shared_ptr generateCollision(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups) { + std::shared_ptr output(new CollisionGeneratorOutput()); + std::unique_ptr collidersChunk(new StructureDataChunk()); std::unique_ptr colliderTypeChunk(new StructureDataChunk()); std::unique_ptr collisionObjectChunk(new StructureDataChunk()); - aiMatrix4x4 globalTransform = mSettings.CreateCollisionTransform(); + aiMatrix4x4 globalTransform = settings.CreateCollisionTransform(); int meshCount = 0; @@ -63,20 +55,22 @@ void CollisionGenerator::GenerateDefinitions(const aiScene* scene, CFileDefiniti std::string colliderTypesName = fileDefinition.GetUniqueName("collider_types"); std::string collisionObjectsName = fileDefinition.GetUniqueName("collision_objects"); - sortNodesByRoom(mIncludedNodes, mRoomOutput); + std::vector nodes = nodeGroups.NodesForType("@collision"); + + sortNodesWithArgsByRoom(nodes, roomOutput); std::vector roomBoxes; std::vector quadRooms; - for (int i = 0; i < mRoomOutput.roomCount; ++i) { + for (int i = 0; i < roomOutput.roomCount; ++i) { roomBoxes.push_back(aiAABB()); } - for (auto node : mIncludedNodes) { - for (unsigned i = 0; i < node->mNumMeshes; ++i) { - aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; + for (auto nodeInfo : nodes) { + for (unsigned i = 0; i < nodeInfo.node->mNumMeshes; ++i) { + aiMesh* mesh = scene->mMeshes[nodeInfo.node->mMeshes[i]]; - CollisionQuad collider(mesh, globalTransform * node->mTransformation); + CollisionQuad collider(mesh, globalTransform * nodeInfo.node->mTransformation); collidersChunk->Add(std::move(collider.Generate())); std::unique_ptr colliderType(new StructureDataChunk()); @@ -94,9 +88,9 @@ void CollisionGenerator::GenerateDefinitions(const aiScene* scene, CFileDefiniti collisionObjectChunk->Add(std::move(collisionObject)); - mOutput.quads.push_back(collider); + output->quads.push_back(collider); - int room = mRoomOutput.RoomForNode(node); + int room = roomOutput.RoomForNode(nodeInfo.node); quadRooms.push_back(room); aiAABB bb = collider.BoundingBox(); @@ -113,13 +107,13 @@ void CollisionGenerator::GenerateDefinitions(const aiScene* scene, CFileDefiniti } } - for (int i = 0; i < mRoomOutput.roomCount; ++i) { - mOutput.roomGrids.push_back(CollisionGrid(roomBoxes[i])); + for (int i = 0; i < roomOutput.roomCount; ++i) { + output->roomGrids.push_back(CollisionGrid(roomBoxes[i])); } int quadIndex = 0; - for (auto& quad : mOutput.quads) { - mOutput.roomGrids[quadRooms[quadIndex]].AddToCells(quad.BoundingBox(), quadIndex); + for (auto& quad : output->quads) { + output->roomGrids[quadRooms[quadIndex]].AddToCells(quad.BoundingBox(), quadIndex); quadIndex++; } @@ -155,9 +149,7 @@ void CollisionGenerator::GenerateDefinitions(const aiScene* scene, CFileDefiniti fileDefinition.AddMacro(fileDefinition.GetMacroName("QUAD_COLLIDERS_COUNT"), std::to_string(meshCount)); - mOutput.quadsName = collisionObjectsName; -} + output->quadsName = collisionObjectsName; -const CollisionGeneratorOutput& CollisionGenerator::GetOutput() const { - return mOutput; + return output; } \ No newline at end of file diff --git a/skelatool64/src/definition_generator/CollisionGenerator.h b/skelatool64/src/definition_generator/CollisionGenerator.h index 34e4aeb..f94cc77 100644 --- a/skelatool64/src/definition_generator/CollisionGenerator.h +++ b/skelatool64/src/definition_generator/CollisionGenerator.h @@ -27,19 +27,6 @@ struct CollisionGeneratorOutput { std::vector roomGrids; }; -class CollisionGenerator : public DefinitionGenerator { -public: - CollisionGenerator(const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput); - - virtual bool ShouldIncludeNode(aiNode* node); - virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition); - - const CollisionGeneratorOutput& GetOutput() const; -private: - DisplayListSettings mSettings; - RoomGeneratorOutput mRoomOutput; - - CollisionGeneratorOutput mOutput; -}; +std::shared_ptr generateCollision(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups); #endif \ No newline at end of file diff --git a/skelatool64/src/definition_generator/CollisionQuad.cpp b/skelatool64/src/definition_generator/CollisionQuad.cpp index dd96d05..1c2fd24 100644 --- a/skelatool64/src/definition_generator/CollisionQuad.cpp +++ b/skelatool64/src/definition_generator/CollisionQuad.cpp @@ -104,7 +104,7 @@ CollisionQuad::CollisionQuad(aiMesh* mesh, const aiMatrix4x4& transform) { } } -std::unique_ptr CollisionQuad::Generate() { +std::unique_ptr CollisionQuad::Generate() const { std::unique_ptr result(new StructureDataChunk()); result->Add(std::unique_ptr(new StructureDataChunk(corner))); @@ -126,7 +126,7 @@ std::unique_ptr CollisionQuad::Generate() { #define FIXED_POINT_PRECISION 8 #define FIXED_POINT_SCALAR (1 << FIXED_POINT_PRECISION) -void CollisionQuad::ToLocalCoords(const aiVector3D& input, short& outX, short& outY) { +void CollisionQuad::ToLocalCoords(const aiVector3D& input, short& outX, short& outY) const { aiVector3D relative = input - corner; outX = (short)(relative * edgeA * FIXED_POINT_SCALAR + 0.5f); diff --git a/skelatool64/src/definition_generator/CollisionQuad.h b/skelatool64/src/definition_generator/CollisionQuad.h index a845f4b..ebcfe16 100644 --- a/skelatool64/src/definition_generator/CollisionQuad.h +++ b/skelatool64/src/definition_generator/CollisionQuad.h @@ -14,9 +14,9 @@ struct CollisionQuad { float edgeBLength; aiVector3D normal; - std::unique_ptr Generate(); + std::unique_ptr Generate() const; - void ToLocalCoords(const aiVector3D& input, short& outX, short& outY); + void ToLocalCoords(const aiVector3D& input, short& outX, short& outY) const; bool IsCoplanar(ExtendedMesh& mesh, float relativeScale) const; bool IsCoplanar(const aiVector3D& input) const; diff --git a/skelatool64/src/definition_generator/DefinitionGenerator.cpp b/skelatool64/src/definition_generator/DefinitionGenerator.cpp index 98a97dc..1992055 100644 --- a/skelatool64/src/definition_generator/DefinitionGenerator.cpp +++ b/skelatool64/src/definition_generator/DefinitionGenerator.cpp @@ -1,5 +1,9 @@ #include "DefinitionGenerator.h" +#include + +#include "../StringUtils.h" + DefinitionGenerator::DefinitionGenerator() {} DefinitionGenerator::~DefinitionGenerator() {} @@ -19,6 +23,36 @@ void DefinitionGenerator::TraverseScene(const aiScene* scene) { void DefinitionGenerator::BeforeTraversal(const aiScene* scene) {} +NodeGroups::NodeGroups(const aiScene* scene) { + forEachNode(scene->mRootNode, [&](aiNode* node) -> void { + if (node->mName.data[0] == '@') { + AddNode(node); + } + }); +} + +std::vector& NodeGroups::NodesForType(const std::string& typeName) { + mTypesReferenced.insert(typeName); + return mNodesByType[typeName]; +} + +void NodeGroups::PrintUnusedTypes() { + for (auto& byType : mNodesByType) { + if (mTypesReferenced.find(byType.first) == mTypesReferenced.end()) { + std::cout << "The node type " << byType.first << " was never referenced." << std::endl; + } + } +} + +void NodeGroups::AddNode(aiNode* node) { + NodeWithArguments result; + SplitString(node->mName.C_Str(), ' ', result.arguments); + std::string typeName = result.arguments[0]; + result.node = node; + result.arguments.erase(result.arguments.begin()); + mNodesByType[typeName].push_back(result); +} + void forEachNode(aiNode* node, const std::function& callback) { if (!node) { diff --git a/skelatool64/src/definition_generator/DefinitionGenerator.h b/skelatool64/src/definition_generator/DefinitionGenerator.h index 41788f1..46f454b 100644 --- a/skelatool64/src/definition_generator/DefinitionGenerator.h +++ b/skelatool64/src/definition_generator/DefinitionGenerator.h @@ -4,7 +4,10 @@ #include #include +#include +#include #include +#include #include "../CFileDefinition.h" @@ -23,6 +26,24 @@ protected: std::vector mIncludedNodes; }; +struct NodeWithArguments { + aiNode* node; + std::vector arguments; +}; + +class NodeGroups { +public: + NodeGroups(const aiScene* scene); + + std::vector& NodesForType(const std::string& typeName); + void PrintUnusedTypes(); +private: + void AddNode(aiNode* node); + + std::map> mNodesByType; + std::set mTypesReferenced; +}; + void forEachNode(aiNode* node, const std::function& callback); #endif \ No newline at end of file diff --git a/skelatool64/src/definition_generator/LevelGenerator.cpp b/skelatool64/src/definition_generator/LevelGenerator.cpp index 23f605c..854cb86 100644 --- a/skelatool64/src/definition_generator/LevelGenerator.cpp +++ b/skelatool64/src/definition_generator/LevelGenerator.cpp @@ -11,20 +11,6 @@ std::set gPortalableSurfaces = { "concrete_modular_floor001a", }; -LevelGenerator::LevelGenerator( - const DisplayListSettings& settings, - const StaticGeneratorOutput& staticOutput, - const CollisionGeneratorOutput& collisionOutput, - const TriggerGeneratorOutput& triggerOutput, - const RoomGeneratorOutput& roomOutput -) : - mSettings(settings), - mStaticOutput(staticOutput), - mCollisionOutput(collisionOutput), - mTriggerOutput(triggerOutput), - mRoomOutput(roomOutput) {} - - int levelEdgeKey(int a, int b) { return (std::max(a, b) << 8) | std::min(a, b); } @@ -34,7 +20,7 @@ struct EdgeIndices { uint8_t b; }; -std::unique_ptr LevelGenerator::CalculatePortalSingleSurface(CFileDefinition& fileDefinition, CollisionQuad& quad, ExtendedMesh& mesh, float scale) { +std::unique_ptr calculatePortalSingleSurface(CFileDefinition& fileDefinition, const CollisionQuad& quad, ExtendedMesh& mesh, float scale) { std::unique_ptr portalSurface(new StructureDataChunk()); std::unique_ptr vertices(new StructureDataChunk()); @@ -122,20 +108,20 @@ std::unique_ptr LevelGenerator::CalculatePortalSingleSurface return portalSurface; } -int LevelGenerator::CalculatePortalSurfaces(const aiScene* scene, CFileDefinition& fileDefinition, std::string& surfacesName, std::string& surfaceMappingName) { +int calculatePortalSurfaces(const aiScene* scene, CFileDefinition& fileDefinition, const CollisionGeneratorOutput& collisionOutput, const StaticGeneratorOutput& staticOutput, const DisplayListSettings& settings, std::string& surfacesName, std::string& surfaceMappingName) { int surfaceCount = 0; std::unique_ptr portalSurfaceIndices(new StructureDataChunk()); std::unique_ptr portalSurfaces(new StructureDataChunk()); - for (auto& collision : mCollisionOutput.quads) { + for (auto& collision : collisionOutput.quads) { int startSurfaceCount = surfaceCount; aiAABB collisionWithPadding = collision.BoundingBox(); collisionWithPadding.mMin = collisionWithPadding.mMin - aiVector3D(0.1f, 0.1f, 0.1f); collisionWithPadding.mMax = collisionWithPadding.mMax + aiVector3D(0.1f, 0.1f, 0.1f); - for (auto mesh : mStaticOutput.staticMeshes) { + for (auto mesh : staticOutput.staticMeshes) { aiMaterial* material = scene->mMaterials[mesh->mMesh->mMaterialIndex]; std::string materialName = ExtendedMesh::GetMaterialName(material); @@ -144,9 +130,9 @@ int LevelGenerator::CalculatePortalSurfaces(const aiScene* scene, CFileDefinitio continue; } - aiAABB meshBB(mesh->bbMin * mSettings.mCollisionScale, mesh->bbMax * mSettings.mCollisionScale); + aiAABB meshBB(mesh->bbMin * settings.mCollisionScale, mesh->bbMax * settings.mCollisionScale); - if (!collision.IsCoplanar(*mesh, mSettings.mCollisionScale)) { + if (!collision.IsCoplanar(*mesh, settings.mCollisionScale)) { continue; } @@ -154,7 +140,7 @@ int LevelGenerator::CalculatePortalSurfaces(const aiScene* scene, CFileDefinitio continue; } - portalSurfaces->Add(std::move(CalculatePortalSingleSurface(fileDefinition, collision, *mesh, mSettings.mCollisionScale))); + portalSurfaces->Add(std::move(calculatePortalSingleSurface(fileDefinition, collision, *mesh, settings.mCollisionScale))); ++surfaceCount; } @@ -175,19 +161,19 @@ int LevelGenerator::CalculatePortalSurfaces(const aiScene* scene, CFileDefinitio return surfaceCount; } -void LevelGenerator::CalculateBoundingBoxes(const aiScene* scene, CFileDefinition& fileDefinition, std::string& boundingBoxesName) { +void calculateBoundingBoxes(const aiScene* scene, CFileDefinition& fileDefinition, const StaticGeneratorOutput& staticOutput, const DisplayListSettings& settings, std::string& boundingBoxesName) { std::unique_ptr boundingBoxes(new StructureDataChunk()); - for (auto& mesh : mStaticOutput.staticMeshes) { + for (auto& mesh : staticOutput.staticMeshes) { std::unique_ptr sphere(new StructureDataChunk()); - sphere->AddPrimitive((short)(mesh->bbMin.x * mSettings.mGraphicsScale + 0.5f)); - sphere->AddPrimitive((short)(mesh->bbMin.y * mSettings.mGraphicsScale + 0.5f)); - sphere->AddPrimitive((short)(mesh->bbMin.z * mSettings.mGraphicsScale + 0.5f)); + sphere->AddPrimitive((short)(mesh->bbMin.x * settings.mGraphicsScale + 0.5f)); + sphere->AddPrimitive((short)(mesh->bbMin.y * settings.mGraphicsScale + 0.5f)); + sphere->AddPrimitive((short)(mesh->bbMin.z * settings.mGraphicsScale + 0.5f)); - sphere->AddPrimitive((short)(mesh->bbMax.x * mSettings.mGraphicsScale + 0.5f)); - sphere->AddPrimitive((short)(mesh->bbMax.y * mSettings.mGraphicsScale + 0.5f)); - sphere->AddPrimitive((short)(mesh->bbMax.z * mSettings.mGraphicsScale + 0.5f)); + sphere->AddPrimitive((short)(mesh->bbMax.x * settings.mGraphicsScale + 0.5f)); + sphere->AddPrimitive((short)(mesh->bbMax.y * settings.mGraphicsScale + 0.5f)); + sphere->AddPrimitive((short)(mesh->bbMax.z * settings.mGraphicsScale + 0.5f)); boundingBoxes->Add(std::move(sphere)); } @@ -197,10 +183,10 @@ void LevelGenerator::CalculateBoundingBoxes(const aiScene* scene, CFileDefinitio fileDefinition.AddDefinition(std::move(boundingBoxDef)); } -void LevelGenerator::CalculateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, std::string& triggersName) { +void calculateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const TriggerGeneratorOutput& triggerOutput, std::string& triggersName) { std::unique_ptr triggers(new StructureDataChunk()); - for (auto& trigger : mTriggerOutput.triggers) { + for (auto& trigger : triggerOutput.triggers) { std::unique_ptr triggerData(new StructureDataChunk()); std::unique_ptr cutsceneDef(new StructureDataChunk()); @@ -219,12 +205,12 @@ void LevelGenerator::CalculateTriggers(const aiScene* scene, CFileDefinition& fi fileDefinition.AddDefinition(std::move(triggersDef)); } -void LevelGenerator::CalculateLocations(const aiScene* scene, CFileDefinition& fileDefinition, std::string& locationsName) { - aiMatrix4x4 baseTransfrom = mSettings.CreateCollisionTransform(); +void calculateLocations(const aiScene* scene, CFileDefinition& fileDefinition, const RoomGeneratorOutput& roomOuptut, const DisplayListSettings& settings, std::string& locationsName) { + aiMatrix4x4 baseTransfrom = settings.CreateCollisionTransform(); std::unique_ptr locations(new StructureDataChunk()); - for (auto& location : mRoomOutput.namedLocations) { + for (auto& location : roomOuptut.namedLocations) { aiMatrix4x4 nodeTransform = baseTransfrom * location.node->mTransformation; aiVector3D position; @@ -240,7 +226,9 @@ void LevelGenerator::CalculateLocations(const aiScene* scene, CFileDefinition& f transform->Add(std::unique_ptr(new StructureDataChunk(scale))); locationData->Add(std::move(transform)); - locationData->AddPrimitive(mRoomOutput.roomIndexMapping[location.node]); + auto roomIndex = roomOuptut.roomIndexMapping.find(location.node); + + locationData->AddPrimitive(roomIndex == roomOuptut.roomIndexMapping.end() ? 0 : roomIndex->second); locations->Add(std::move(locationData)); } @@ -250,10 +238,10 @@ void LevelGenerator::CalculateLocations(const aiScene* scene, CFileDefinition& f fileDefinition.AddDefinition(std::move(triggersDef)); } -void LevelGenerator::CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefinition& fileDefinition, std::string& doorwaysName, std::string& roomsName) { +void calculateDoorwaysAndRooms(const aiScene* scene, CFileDefinition& fileDefinition, const RoomGeneratorOutput& roomOutput, const CollisionGeneratorOutput& collisionOutput, std::string& doorwaysName, std::string& roomsName) { std::vector> roomDoorways; - for (int i = 0; i < mRoomOutput.roomCount; ++i) { + for (int i = 0; i < roomOutput.roomCount; ++i) { roomDoorways.push_back(std::vector()); } @@ -261,7 +249,7 @@ void LevelGenerator::CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefini std::unique_ptr doorways(new StructureDataChunk()); - for (auto& doorway : mRoomOutput.doorways) { + for (auto& doorway : roomOutput.doorways) { roomDoorways[doorway.roomA].push_back(doorwayIndex); roomDoorways[doorway.roomB].push_back(doorwayIndex); @@ -284,7 +272,7 @@ void LevelGenerator::CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefini std::unique_ptr rooms(new StructureDataChunk()); - for (int i = 0; i < mRoomOutput.roomCount; ++i) { + for (int i = 0; i < roomOutput.roomCount; ++i) { std::unique_ptr doorwayList(new StructureDataChunk()); for (auto doorway : roomDoorways[i]) { @@ -304,7 +292,7 @@ void LevelGenerator::CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefini int startIndex = 0; - for (auto& zRange : mCollisionOutput.roomGrids[i].cells) { + for (auto& zRange : collisionOutput.roomGrids[i].cells) { for (auto& indices : zRange) { for (auto index : indices) { quadIndices->AddPrimitive(index); @@ -341,10 +329,10 @@ void LevelGenerator::CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefini std::unique_ptr room(new StructureDataChunk()); room->AddPrimitive(std::move(quadIndicesName)); room->AddPrimitive(std::move(cellContentsName)); - room->AddPrimitive(mCollisionOutput.roomGrids[i].spanX); - room->AddPrimitive(mCollisionOutput.roomGrids[i].spanZ); - room->AddPrimitive(mCollisionOutput.roomGrids[i].x); - room->AddPrimitive(mCollisionOutput.roomGrids[i].z); + room->AddPrimitive(collisionOutput.roomGrids[i].spanX); + room->AddPrimitive(collisionOutput.roomGrids[i].spanZ); + room->AddPrimitive(collisionOutput.roomGrids[i].x); + room->AddPrimitive(collisionOutput.roomGrids[i].z); room->AddPrimitive(std::move(doorwayListName)); room->AddPrimitive(roomDoorways[i].size()); rooms->Add(std::move(room)); @@ -359,12 +347,12 @@ void LevelGenerator::CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefini ); } -void LevelGenerator::CalculateDoors(const aiScene* scene, CFileDefinition& fileDefinition, std::string& doorsName) { +void calculateDoors(const aiScene* scene, CFileDefinition& fileDefinition, const RoomGeneratorOutput& roomOutput, const DisplayListSettings& settings, std::string& doorsName) { std::unique_ptr doors(new StructureDataChunk()); - aiMatrix4x4 baseTransform = mSettings.CreateCollisionTransform(); + aiMatrix4x4 baseTransform = settings.CreateCollisionTransform(); - for (auto& door : mRoomOutput.doors) { + for (auto& door : roomOutput.doors) { std::unique_ptr doorData(new StructureDataChunk()); aiVector3D pos; aiQuaternion rot; @@ -385,33 +373,40 @@ void LevelGenerator::CalculateDoors(const aiScene* scene, CFileDefinition& fileD ); } -void LevelGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) { +void generateLevel( + const aiScene* scene, + CFileDefinition& fileDefinition, + const DisplayListSettings& settings, + const StaticGeneratorOutput& staticOutput, + const CollisionGeneratorOutput& collisionOutput, + const TriggerGeneratorOutput& triggerOutput, + const RoomGeneratorOutput& roomOutput +) { std::string portalSurfaces; std::string portalSurfaceMapping; - int portalSurfacesCount = CalculatePortalSurfaces(scene, fileDefinition, portalSurfaces, portalSurfaceMapping); + int portalSurfacesCount = calculatePortalSurfaces(scene, fileDefinition, collisionOutput, staticOutput, settings, portalSurfaces, portalSurfaceMapping); std::string boundingBoxes; - CalculateBoundingBoxes(scene, fileDefinition, boundingBoxes); + calculateBoundingBoxes(scene, fileDefinition, staticOutput, settings, boundingBoxes); std::string triggers; - CalculateTriggers(scene, fileDefinition, triggers); + calculateTriggers(scene, fileDefinition, triggerOutput, triggers); std::string locations; - CalculateLocations(scene, fileDefinition, locations); + calculateLocations(scene, fileDefinition, roomOutput, settings, locations); std::string doorways; std::string rooms; - CalculateDoorwaysAndRooms(scene, fileDefinition, doorways, rooms); + calculateDoorwaysAndRooms(scene, fileDefinition, roomOutput, collisionOutput, doorways, rooms); std::string doors; - CalculateDoors(scene, fileDefinition, doors); + calculateDoors(scene, fileDefinition, roomOutput, settings, doors); std::unique_ptr levelDef(new StructureDataChunk()); - - levelDef->AddPrimitive("collisionQuads", mCollisionOutput.quadsName); - levelDef->AddPrimitive("staticContent", mStaticOutput.staticContentName); - levelDef->AddPrimitive("roomStaticMapping", mStaticOutput.roomMappingName); + levelDef->AddPrimitive("collisionQuads", collisionOutput.quadsName); + levelDef->AddPrimitive("staticContent", staticOutput.staticContentName); + levelDef->AddPrimitive("roomStaticMapping", staticOutput.roomMappingName); levelDef->AddPrimitive("staticBoundingBoxes", boundingBoxes); levelDef->AddPrimitive("portalSurfaces", portalSurfaces); levelDef->AddPrimitive("portalSurfaceMapping", portalSurfaceMapping); @@ -421,18 +416,18 @@ void LevelGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& std::unique_ptr worldDef(new StructureDataChunk()); worldDef->AddPrimitive("rooms", rooms); worldDef->AddPrimitive("doorways", doorways); - worldDef->AddPrimitive("roomCount", mRoomOutput.roomCount); - worldDef->AddPrimitive("doorwayCount", mRoomOutput.doorways.size()); + worldDef->AddPrimitive("roomCount", roomOutput.roomCount); + worldDef->AddPrimitive("doorwayCount", roomOutput.doorways.size()); levelDef->Add("world", std::move(worldDef)); levelDef->AddPrimitive("doors", doors); - levelDef->AddPrimitive("collisionQuadCount", mCollisionOutput.quads.size()); - levelDef->AddPrimitive("staticContentCount", mStaticOutput.staticMeshes.size()); + levelDef->AddPrimitive("collisionQuadCount", collisionOutput.quads.size()); + levelDef->AddPrimitive("staticContentCount", staticOutput.staticMeshes.size()); levelDef->AddPrimitive("portalSurfaceCount", portalSurfacesCount); - levelDef->AddPrimitive("triggerCount", mTriggerOutput.triggers.size()); - levelDef->AddPrimitive("locationCount", mRoomOutput.namedLocations.size()); - levelDef->AddPrimitive("doorCount", mRoomOutput.doors.size()); - levelDef->AddPrimitive("startLocation", mRoomOutput.FindLocationIndex("start")); + levelDef->AddPrimitive("triggerCount", triggerOutput.triggers.size()); + levelDef->AddPrimitive("locationCount", roomOutput.namedLocations.size()); + levelDef->AddPrimitive("doorCount", roomOutput.doors.size()); + levelDef->AddPrimitive("startLocation", roomOutput.FindLocationIndex("start")); fileDefinition.AddDefinition(std::unique_ptr(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef)))); } \ No newline at end of file diff --git a/skelatool64/src/definition_generator/LevelGenerator.h b/skelatool64/src/definition_generator/LevelGenerator.h index edf5831..55739a1 100644 --- a/skelatool64/src/definition_generator/LevelGenerator.h +++ b/skelatool64/src/definition_generator/LevelGenerator.h @@ -8,36 +8,14 @@ #include "TriggerGenerator.h" #include "RoomGenerator.h" -class LevelGenerator { -public: - LevelGenerator( +void generateLevel( + const aiScene* scene, + CFileDefinition& fileDefinition, const DisplayListSettings& settings, const StaticGeneratorOutput& staticOutput, const CollisionGeneratorOutput& collisionOutput, const TriggerGeneratorOutput& triggerOutput, const RoomGeneratorOutput& roomOutput - ); - - void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition); - -private: - DisplayListSettings mSettings; - StaticGeneratorOutput mStaticOutput; - CollisionGeneratorOutput mCollisionOutput; - TriggerGeneratorOutput mTriggerOutput; - RoomGeneratorOutput mRoomOutput; - - std::unique_ptr CalculatePortalSingleSurface(CFileDefinition& fileDefinition, CollisionQuad& quad, ExtendedMesh& mesh, float scale); - int CalculatePortalSurfaces(const aiScene* scene, CFileDefinition& fileDefinition, std::string& surfacesName, std::string& surfaceMappingName); - void CalculateBoundingBoxes(const aiScene* scene, CFileDefinition& fileDefinition, std::string& boundingBoxesName); - - void CalculateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, std::string& triggersName); - - void CalculateLocations(const aiScene* scene, CFileDefinition& fileDefinition, std::string& locationsName); - - void CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefinition& fileDefinition, std::string& doorwaysName, std::string& roomsName); - - void CalculateDoors(const aiScene* scene, CFileDefinition& fileDefinition, std::string& doorsName); -}; +); #endif \ No newline at end of file diff --git a/skelatool64/src/definition_generator/MeshDefinitionGenerator.cpp b/skelatool64/src/definition_generator/MeshDefinitionGenerator.cpp index 876cd63..c2bee83 100644 --- a/skelatool64/src/definition_generator/MeshDefinitionGenerator.cpp +++ b/skelatool64/src/definition_generator/MeshDefinitionGenerator.cpp @@ -31,7 +31,7 @@ bool MeshDefinitionGenerator::ShouldIncludeNode(aiNode* node) { return node->mName.C_Str()[0] != '@' && node->mNumMeshes > 0; } -void MeshDefinitionGenerator::AppendRenderChunks(const aiScene* scene, aiNode* node, CFileDefinition& fileDefinition, DisplayListSettings& settings, std::vector& renderChunks) { +void MeshDefinitionGenerator::AppendRenderChunks(const aiScene* scene, aiNode* node, CFileDefinition& fileDefinition, const DisplayListSettings& settings, std::vector& renderChunks) { for (unsigned meshIndex = 0; meshIndex < node->mNumMeshes; ++meshIndex) { std::shared_ptr mesh = fileDefinition.GetExtendedMesh(scene->mMeshes[node->mMeshes[meshIndex]]); diff --git a/skelatool64/src/definition_generator/MeshDefinitionGenerator.h b/skelatool64/src/definition_generator/MeshDefinitionGenerator.h index 386e01d..ce4a905 100644 --- a/skelatool64/src/definition_generator/MeshDefinitionGenerator.h +++ b/skelatool64/src/definition_generator/MeshDefinitionGenerator.h @@ -12,7 +12,7 @@ public: virtual bool ShouldIncludeNode(aiNode* node); virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition); - static void AppendRenderChunks(const aiScene* scene, aiNode* node, CFileDefinition& fileDefinition, DisplayListSettings& settings, std::vector& renderChunks); + static void AppendRenderChunks(const aiScene* scene, aiNode* node, CFileDefinition& fileDefinition, const DisplayListSettings& settings, std::vector& renderChunks); private: DisplayListSettings mSettings; }; diff --git a/skelatool64/src/definition_generator/RoomGenerator.cpp b/skelatool64/src/definition_generator/RoomGenerator.cpp index 97f2064..ecc4736 100644 --- a/skelatool64/src/definition_generator/RoomGenerator.cpp +++ b/skelatool64/src/definition_generator/RoomGenerator.cpp @@ -4,13 +4,13 @@ #include "../StringUtils.h" #include "../MathUtl.h" -#define ROOM_PREFIX "@room " +#define ROOM_PREFIX "@room" -#define LOCATION_PREFIX "@location " +#define LOCATION_PREFIX "@location" #define DOORWAY_PREFIX "@doorway" -#define DOOR_PREFIX "@door " +#define DOOR_PREFIX "@door" Doorway::Doorway(const aiNode* node, const CollisionQuad& quad): node(node), quad(quad), roomA(0), roomB(0) { @@ -19,8 +19,6 @@ Doorway::Doorway(const aiNode* node, const CollisionQuad& quad): Door::Door(const aiNode* node): node(node) {} -RoomGenerator::RoomGenerator(const DisplayListSettings& settings): DefinitionGenerator(), mSettings(settings) {} - short RoomGeneratorOutput::FindLocationRoom(const std::string& name) const { for (auto& location : namedLocations) { if (location.name == name) { @@ -56,16 +54,18 @@ struct RoomBlock { int roomIndex; }; -bool RoomGenerator::ShouldIncludeNode(aiNode* node) { - return true; -} - void sortNodesByRoom(std::vector& nodes, const RoomGeneratorOutput& roomOutput) { std::sort(nodes.begin(), nodes.end(), [&](const aiNode* a, const aiNode* b) -> bool { return roomOutput.RoomForNode(a) < roomOutput.RoomForNode(b); }); } +void sortNodesWithArgsByRoom(std::vector& nodes, const RoomGeneratorOutput& roomOutput) { + std::sort(nodes.begin(), nodes.end(), [&](const NodeWithArguments& a, const NodeWithArguments& b) -> bool { + return roomOutput.RoomForNode(a.node) < roomOutput.RoomForNode(b.node); + }); +} + int findClosestRoom(const aiNode* node, const aiScene* scene, CFileDefinition& fileDefinition, const std::vector& roomBlocks, int ignoreRoom, const RoomBlock** foundBlock = NULL) { float distance = INFINITY; int closestRoom = 0; @@ -97,47 +97,53 @@ int findClosestRoom(const aiNode* node, const aiScene* scene, CFileDefinition& f return closestRoom; } -void RoomGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) { + +std::shared_ptr generateRooms(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, NodeGroups& nodeGroups) { std::vector roomBlocks; + std::shared_ptr output(new RoomGeneratorOutput()); - aiMatrix4x4 collisionTransform = mSettings.CreateCollisionTransform(); + aiMatrix4x4 collisionTransform = settings.CreateCollisionTransform(); - mOutput.roomCount = 0; + output->roomCount = 0; - for (auto node : mIncludedNodes) { - std::string nodeName(node->mName.C_Str()); - - if (StartsWith(nodeName, ROOM_PREFIX) && node->mNumMeshes) { - auto mesh = fileDefinition.GetExtendedMesh(scene->mMeshes[node->mMeshes[0]]); - aiVector3D minPoint = node->mTransformation * mesh->bbMin; - aiVector3D maxPoint = node->mTransformation * mesh->bbMax; - - struct RoomBlock roomBlock; - roomBlock.boundingBox.mMin = min(minPoint, maxPoint); - roomBlock.boundingBox.mMax = max(minPoint, maxPoint); - roomBlock.roomIndex = std::atoi(nodeName.substr(strlen(ROOM_PREFIX)).c_str()); - roomBlocks.push_back(roomBlock); + for (auto& nodeInfo : nodeGroups.NodesForType(ROOM_PREFIX)) { + if (!nodeInfo.node->mNumMeshes) { + continue; } - if (StartsWith(nodeName, LOCATION_PREFIX)) { - NamedLocation location; - location.node = node; - location.name = nodeName.substr(strlen(LOCATION_PREFIX)); - location.index = mOutput.namedLocations.size(); + auto mesh = fileDefinition.GetExtendedMesh(scene->mMeshes[nodeInfo.node->mMeshes[0]]); + aiVector3D minPoint = nodeInfo.node->mTransformation * mesh->bbMin; + aiVector3D maxPoint = nodeInfo.node->mTransformation * mesh->bbMax; - mOutput.namedLocations.push_back(location); - } + struct RoomBlock roomBlock; + roomBlock.boundingBox.mMin = min(minPoint, maxPoint); + roomBlock.boundingBox.mMax = max(minPoint, maxPoint); + roomBlock.roomIndex = nodeInfo.arguments.size() ? std::atoi(nodeInfo.arguments[0].c_str()) : 0; + roomBlocks.push_back(roomBlock); + } - if (StartsWith(nodeName, DOORWAY_PREFIX) && node->mNumMeshes) { - mOutput.doorways.push_back(Doorway(node, CollisionQuad( - scene->mMeshes[node->mMeshes[0]], - collisionTransform * node->mTransformation - ))); + for (auto& nodeInfo : nodeGroups.NodesForType(LOCATION_PREFIX)) { + NamedLocation location; + location.node = nodeInfo.node; + if (nodeInfo.arguments.size()) { + location.name = nodeInfo.arguments[0]; + } else { + std::cout << "@location without a name"; } + location.index = output->namedLocations.size(); - if (StartsWith(nodeName, DOOR_PREFIX)) { - mOutput.doors.push_back(Door(node)); - } + output->namedLocations.push_back(location); + } + + for (auto& nodeInfo : nodeGroups.NodesForType(DOORWAY_PREFIX)) { + output->doorways.push_back(Doorway(nodeInfo.node, CollisionQuad( + scene->mMeshes[nodeInfo.node->mMeshes[0]], + collisionTransform * nodeInfo.node->mTransformation + ))); + } + + for (auto& nodeInfo : nodeGroups.NodesForType(DOOR_PREFIX)) { + output->doors.push_back(Door(nodeInfo.node)); } if (roomBlocks.size() == 0) { @@ -146,14 +152,14 @@ void RoomGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& f roomBlocks.push_back(roomBlock); } - for (auto node : mIncludedNodes) { + forEachNode(scene->mRootNode, [&](aiNode* node) -> void { int closestRoom = findClosestRoom(node, scene, fileDefinition, roomBlocks, -1); - mOutput.roomIndexMapping[node] = closestRoom; - mOutput.roomCount = std::max(mOutput.roomCount, closestRoom + 1); - } + output->roomIndexMapping[node] = closestRoom; + output->roomCount = std::max(output->roomCount, closestRoom + 1); + }); - for (auto& doorway : mOutput.doorways) { - doorway.roomA = mOutput.roomIndexMapping[doorway.node]; + for (auto& doorway : output->doorways) { + doorway.roomA = output->roomIndexMapping[doorway.node]; const RoomBlock* roomB = NULL; doorway.roomB = findClosestRoom(doorway.node, scene, fileDefinition, roomBlocks, doorway.roomA, &roomB); @@ -169,15 +175,15 @@ void RoomGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& f } } - mOutput.roomCount = std::max(mOutput.roomCount, doorway.roomB + 1); + output->roomCount = std::max(output->roomCount, doorway.roomB + 1); } - for (auto& door : mOutput.doors) { + for (auto& door : output->doors) { int doorwayIndex = -1; int index = 0; - for (auto& doorway : mOutput.doorways) { + for (auto& doorway : output->doorways) { if (doorway.quad.IsCoplanar(door.node->mTransformation * aiVector3D(0.0f, 0.0f, 0.0f))) { doorwayIndex = index; break; @@ -188,8 +194,6 @@ void RoomGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& f door.doorwayIndex = doorwayIndex; } -} -const RoomGeneratorOutput& RoomGenerator::GetOutput() const { - return mOutput; + return output; } \ No newline at end of file diff --git a/skelatool64/src/definition_generator/RoomGenerator.h b/skelatool64/src/definition_generator/RoomGenerator.h index 11ffc7a..864a699 100644 --- a/skelatool64/src/definition_generator/RoomGenerator.h +++ b/skelatool64/src/definition_generator/RoomGenerator.h @@ -41,18 +41,8 @@ struct RoomGeneratorOutput { }; void sortNodesByRoom(std::vector& nodes, const RoomGeneratorOutput& roomOutput); +void sortNodesWithArgsByRoom(std::vector& nodes, const RoomGeneratorOutput& roomOutput); -class RoomGenerator : public DefinitionGenerator { -public: - RoomGenerator(const DisplayListSettings& settings); - - virtual bool ShouldIncludeNode(aiNode* node); - virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition); - - const RoomGeneratorOutput& GetOutput() const; -private: - DisplayListSettings mSettings; - RoomGeneratorOutput mOutput; -}; +std::shared_ptr generateRooms(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, NodeGroups& nodeGroups); #endif \ No newline at end of file diff --git a/skelatool64/src/definition_generator/StaticGenerator.cpp b/skelatool64/src/definition_generator/StaticGenerator.cpp index b771260..6a937f8 100644 --- a/skelatool64/src/definition_generator/StaticGenerator.cpp +++ b/skelatool64/src/definition_generator/StaticGenerator.cpp @@ -6,45 +6,41 @@ #include "MaterialGenerator.h" #include "../RenderChunk.h" -StaticGenerator::StaticGenerator(const DisplayListSettings& settings, const RoomGeneratorOutput& roomMapping) : DefinitionGenerator(), mSettings(settings), mRoomMapping(roomMapping) { +std::shared_ptr generateStatic(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, RoomGeneratorOutput& roomMapping, NodeGroups& nodeGroups) { + DisplayListSettings settingsCopy = settings; + settingsCopy.mMaterials.clear(); -} - -bool StaticGenerator::ShouldIncludeNode(aiNode* node) { - return StartsWith(node->mName.C_Str(), "@static ") && node->mNumMeshes > 0; -} - -void StaticGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) { - DisplayListSettings settings = mSettings; - settings.mMaterials.clear(); + std::shared_ptr output(new StaticGeneratorOutput()); std::vector elements; BoneHierarchy unusedBones; - sortNodesByRoom(mIncludedNodes, mRoomMapping); + std::vector nodes = nodeGroups.NodesForType("@static"); - for (auto node = mIncludedNodes.begin(); node != mIncludedNodes.end(); ++node) { + sortNodesWithArgsByRoom(nodes, roomMapping); + + for (auto& nodeInfo : nodes) { std::vector renderChunks; - MeshDefinitionGenerator::AppendRenderChunks(scene, *node, fileDefinition, mSettings, renderChunks); + MeshDefinitionGenerator::AppendRenderChunks(scene, nodeInfo.node, fileDefinition, settings, renderChunks); for (auto& chunk : renderChunks) { StaticContentElement element; if (chunk.mMaterial) { - settings.mDefaultMaterialState = chunk.mMaterial->mState; + settingsCopy.mDefaultMaterialState = chunk.mMaterial->mState; element.materialName = MaterialGenerator::MaterialIndexMacroName(chunk.mMaterial->mName); } else { element.materialName = "0"; } std::vector singleChunk; singleChunk.push_back(chunk); - element.meshName = generateMesh(scene, fileDefinition, singleChunk, settings, "_geo"); + element.meshName = generateMesh(scene, fileDefinition, singleChunk, settingsCopy, "_geo"); elements.push_back(element); - mOutput.staticMeshes.push_back(chunk.mMesh); - mOutput.staticRooms.push_back(mRoomMapping.RoomForNode(*node)); + output->staticMeshes.push_back(chunk.mMesh); + output->staticRooms.push_back(roomMapping.RoomForNode(nodeInfo.node)); } } @@ -59,20 +55,20 @@ void StaticGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& staticContentList->Add(std::move(element)); } - mOutput.staticContentName = fileDefinition.GetUniqueName("static"); + output->staticContentName = fileDefinition.GetUniqueName("static"); - std::unique_ptr fileDef(new DataFileDefinition("struct StaticContentElement", mOutput.staticContentName, true, "_geo", std::move(staticContentList))); + std::unique_ptr fileDef(new DataFileDefinition("struct StaticContentElement", output->staticContentName, true, "_geo", std::move(staticContentList))); fileDef->AddTypeHeader("\"levels/level_def_gen.h\""); fileDefinition.AddDefinition(std::move(fileDef)); std::unique_ptr roomToStaticMapping(new StructureDataChunk()); int prevIndex = 0; - for (int roomIndex = 0; roomIndex < mRoomMapping.roomCount; ++roomIndex) { + for (int roomIndex = 0; roomIndex < roomMapping.roomCount; ++roomIndex) { std::unique_ptr singleMapping(new StructureDataChunk()); int currentIndex = prevIndex; - while (currentIndex < (int)mOutput.staticRooms.size() && mOutput.staticRooms[currentIndex] <= roomIndex) { + while (currentIndex < (int)output->staticRooms.size() && output->staticRooms[currentIndex] <= roomIndex) { ++currentIndex; } @@ -84,10 +80,8 @@ void StaticGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& roomToStaticMapping->Add(std::move(singleMapping)); } - mOutput.roomMappingName = fileDefinition.GetUniqueName("static_room_mapping"); - fileDefinition.AddDefinition(std::unique_ptr(new DataFileDefinition("struct Rangeu16", mOutput.roomMappingName, true, "_geo", std::move(roomToStaticMapping)))); -} + output->roomMappingName = fileDefinition.GetUniqueName("static_room_mapping"); + fileDefinition.AddDefinition(std::unique_ptr(new DataFileDefinition("struct Rangeu16", output->roomMappingName, true, "_geo", std::move(roomToStaticMapping)))); -const StaticGeneratorOutput& StaticGenerator::GetOutput() const { - return mOutput; + return output; } \ No newline at end of file diff --git a/skelatool64/src/definition_generator/StaticGenerator.h b/skelatool64/src/definition_generator/StaticGenerator.h index 5f38a7c..b1bc9d9 100644 --- a/skelatool64/src/definition_generator/StaticGenerator.h +++ b/skelatool64/src/definition_generator/StaticGenerator.h @@ -17,19 +17,6 @@ struct StaticGeneratorOutput { std::string roomMappingName; }; -class StaticGenerator : public DefinitionGenerator { -public: - StaticGenerator(const DisplayListSettings& settings, const RoomGeneratorOutput& roomMapping); - - virtual bool ShouldIncludeNode(aiNode* node); - virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition); - - const StaticGeneratorOutput& GetOutput() const; -private: - DisplayListSettings mSettings; - - StaticGeneratorOutput mOutput; - RoomGeneratorOutput mRoomMapping; -}; +std::shared_ptr generateStatic(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, RoomGeneratorOutput& roomMapping, NodeGroups& nodeGroups); #endif \ No newline at end of file diff --git a/skelatool64/src/definition_generator/TriggerGenerator.cpp b/skelatool64/src/definition_generator/TriggerGenerator.cpp index c209e22..d8f57fc 100644 --- a/skelatool64/src/definition_generator/TriggerGenerator.cpp +++ b/skelatool64/src/definition_generator/TriggerGenerator.cpp @@ -2,9 +2,9 @@ #include "../StringUtils.h" #include "../MathUtl.h" -#define TRIGGER_PREFIX "@trigger " +#define TRIGGER_PREFIX "@trigger" -#define CUTSCENE_PREFIX "@cutscene " +#define CUTSCENE_PREFIX "@cutscene" CutsceneStep::CutsceneStep( const std::string& command, @@ -33,13 +33,7 @@ float distanceFromStart(const CutsceneStep& startStep, const CutsceneStep& other return relativeOffset.y; } -TriggerGenerator::TriggerGenerator(const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput): DefinitionGenerator(), mSettings(settings), mRoomOutput(roomOutput) {} - -bool TriggerGenerator::ShouldIncludeNode(aiNode* node) { - return (StartsWith(node->mName.C_Str(), TRIGGER_PREFIX) && node->mNumMeshes >= 1) || StartsWith(node->mName.C_Str(), CUTSCENE_PREFIX); -} - -std::unique_ptr TriggerGenerator::GenerateCutsceneStep(CutsceneStep& step) { +std::unique_ptr generateCutsceneStep(CutsceneStep& step, const RoomGeneratorOutput& roomOutput) { std::unique_ptr result(new StructureDataChunk()); if ((step.command == "play_sound" || step.command == "start_sound") && step.args.size() >= 1) { @@ -67,7 +61,7 @@ std::unique_ptr TriggerGenerator::GenerateCutsceneStep(Cutsc result->AddPrimitive("delay", std::atof(step.args[0].c_str())); return result; } else if (step.command == "open_portal" && step.args.size() >= 1) { - short roomLocation = mRoomOutput.FindLocationIndex(step.args[0]); + short roomLocation = roomOutput.FindLocationIndex(step.args[0]); if (roomLocation != -1) { result->AddPrimitive("CutsceneStepTypeOpenPortal"); @@ -85,15 +79,12 @@ std::unique_ptr TriggerGenerator::GenerateCutsceneStep(Cutsc return result; } -void TriggerGenerator::GenerateCutscenes(std::map>& output, CFileDefinition& fileDefinition) { +void generateCutscenes(std::map>& output, CFileDefinition& fileDefinition, const RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups) { std::vector> steps; - for (auto& node : mIncludedNodes) { - if (!StartsWith(node->mName.C_Str(), CUTSCENE_PREFIX)) { - continue; - } + for (auto& nodeInfo : nodeGroups.NodesForType(CUTSCENE_PREFIX)) { std::vector cutsceneParts; - SplitString(node->mName.C_Str(), ' ', cutsceneParts); + SplitString(nodeInfo.node->mName.C_Str(), ' ', cutsceneParts); if (cutsceneParts.size() <= 1) { continue; @@ -106,7 +97,7 @@ void TriggerGenerator::GenerateCutscenes(std::mapmTransformation.Decompose(scale, rot, pos); + nodeInfo.node->mTransformation.Decompose(scale, rot, pos); std::shared_ptr step(new CutsceneStep(command, cutsceneParts, pos, rot)); @@ -142,7 +133,7 @@ void TriggerGenerator::GenerateCutscenes(std::map steps(new StructureDataChunk()); for (auto& step : cutscene.steps) { - steps->Add(std::move(GenerateCutsceneStep(*step))); + steps->Add(std::move(generateCutsceneStep(*step, roomOutput))); } std::string stepsName = fileDefinition.GetUniqueName(cutscene.name + "_steps"); @@ -153,21 +144,19 @@ void TriggerGenerator::GenerateCutscenes(std::map generateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups) { + std::shared_ptr output(new TriggerGeneratorOutput()); + std::map> cutscenes; - GenerateCutscenes(cutscenes, fileDefinition); + generateCutscenes(cutscenes, fileDefinition, roomOutput, nodeGroups); - for (auto& node : mIncludedNodes) { - if (!StartsWith(node->mName.C_Str(), TRIGGER_PREFIX)) { - continue; - } - - auto mesh = fileDefinition.GetExtendedMesh(scene->mMeshes[node->mMeshes[0]]); + for (auto& nodeInfo : nodeGroups.NodesForType(TRIGGER_PREFIX)) { + auto mesh = fileDefinition.GetExtendedMesh(scene->mMeshes[nodeInfo.node->mMeshes[0]]); std::shared_ptr trigger(new Trigger()); - std::string nodeName = node->mName.C_Str(); + std::string nodeName = nodeInfo.node->mName.C_Str(); auto cutscene = cutscenes.find(nodeName.substr(strlen(TRIGGER_PREFIX))); @@ -179,16 +168,14 @@ void TriggerGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition trigger->stepsCount = cutscene->second->steps.size(); } - aiVector3D minTransformed = node->mTransformation * mesh->bbMin * mSettings.mCollisionScale; - aiVector3D maxTransformed = node->mTransformation * mesh->bbMax * mSettings.mCollisionScale; + aiVector3D minTransformed = nodeInfo.node->mTransformation * mesh->bbMin * settings.mCollisionScale; + aiVector3D maxTransformed = nodeInfo.node->mTransformation * mesh->bbMax * settings.mCollisionScale; trigger->bb.mMin = min(minTransformed, maxTransformed); trigger->bb.mMax = max(minTransformed, maxTransformed); - mOutput.triggers.push_back(trigger); + output->triggers.push_back(trigger); } -} -const TriggerGeneratorOutput& TriggerGenerator::GetOutput() const { - return mOutput; + return output; } \ No newline at end of file diff --git a/skelatool64/src/definition_generator/TriggerGenerator.h b/skelatool64/src/definition_generator/TriggerGenerator.h index 8d8d556..9eadba3 100644 --- a/skelatool64/src/definition_generator/TriggerGenerator.h +++ b/skelatool64/src/definition_generator/TriggerGenerator.h @@ -31,21 +31,6 @@ struct Cutscene { std::vector> steps; }; -class TriggerGenerator : public DefinitionGenerator { -public: - TriggerGenerator(const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput); - - virtual bool ShouldIncludeNode(aiNode* node); - virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition); - - const TriggerGeneratorOutput& GetOutput() const; -private: - DisplayListSettings mSettings; - TriggerGeneratorOutput mOutput; - RoomGeneratorOutput mRoomOutput; - - void GenerateCutscenes(std::map>& output, CFileDefinition& fileDefinition); - std::unique_ptr GenerateCutsceneStep(CutsceneStep& step); -}; +std::shared_ptr generateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups); #endif \ No newline at end of file