Refactor level generation code to be function instead of object oriented
This commit is contained in:
parent
8083c5082a
commit
6d1961fb55
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -25,8 +25,8 @@ struct DisplayListSettings {
|
|||
bool mExportGeometry;
|
||||
bool mIncludeCulling;
|
||||
|
||||
aiMatrix4x4 CreateGlobalTransform();
|
||||
aiMatrix4x4 CreateCollisionTransform();
|
||||
aiMatrix4x4 CreateGlobalTransform() const;
|
||||
aiMatrix4x4 CreateCollisionTransform() const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,16 +5,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
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<CollisionGeneratorOutput> generateCollision(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups) {
|
||||
std::shared_ptr<CollisionGeneratorOutput> output(new CollisionGeneratorOutput());
|
||||
|
||||
std::unique_ptr<StructureDataChunk> collidersChunk(new StructureDataChunk());
|
||||
std::unique_ptr<StructureDataChunk> colliderTypeChunk(new StructureDataChunk());
|
||||
std::unique_ptr<StructureDataChunk> 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<NodeWithArguments> nodes = nodeGroups.NodesForType("@collision");
|
||||
|
||||
sortNodesWithArgsByRoom(nodes, roomOutput);
|
||||
|
||||
std::vector<aiAABB> roomBoxes;
|
||||
std::vector<int> 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<StructureDataChunk> 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;
|
||||
}
|
|
@ -27,19 +27,6 @@ struct CollisionGeneratorOutput {
|
|||
std::vector<CollisionGrid> 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<CollisionGeneratorOutput> generateCollision(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups);
|
||||
|
||||
#endif
|
|
@ -104,7 +104,7 @@ CollisionQuad::CollisionQuad(aiMesh* mesh, const aiMatrix4x4& transform) {
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<DataChunk> CollisionQuad::Generate() {
|
||||
std::unique_ptr<DataChunk> CollisionQuad::Generate() const {
|
||||
std::unique_ptr<StructureDataChunk> result(new StructureDataChunk());
|
||||
|
||||
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(corner)));
|
||||
|
@ -126,7 +126,7 @@ std::unique_ptr<DataChunk> 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);
|
||||
|
|
|
@ -14,9 +14,9 @@ struct CollisionQuad {
|
|||
float edgeBLength;
|
||||
aiVector3D normal;
|
||||
|
||||
std::unique_ptr<DataChunk> Generate();
|
||||
std::unique_ptr<DataChunk> 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;
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#include "DefinitionGenerator.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#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<NodeWithArguments>& 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<void(aiNode*)>& callback) {
|
||||
if (!node) {
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
#include <assimp/scene.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
#include "../CFileDefinition.h"
|
||||
|
||||
|
@ -23,6 +26,24 @@ protected:
|
|||
std::vector<aiNode*> mIncludedNodes;
|
||||
};
|
||||
|
||||
struct NodeWithArguments {
|
||||
aiNode* node;
|
||||
std::vector<std::string> arguments;
|
||||
};
|
||||
|
||||
class NodeGroups {
|
||||
public:
|
||||
NodeGroups(const aiScene* scene);
|
||||
|
||||
std::vector<NodeWithArguments>& NodesForType(const std::string& typeName);
|
||||
void PrintUnusedTypes();
|
||||
private:
|
||||
void AddNode(aiNode* node);
|
||||
|
||||
std::map<std::string, std::vector<NodeWithArguments>> mNodesByType;
|
||||
std::set<std::string> mTypesReferenced;
|
||||
};
|
||||
|
||||
void forEachNode(aiNode* node, const std::function<void(aiNode*)>& callback);
|
||||
|
||||
#endif
|
|
@ -11,20 +11,6 @@ std::set<std::string> 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<StructureDataChunk> LevelGenerator::CalculatePortalSingleSurface(CFileDefinition& fileDefinition, CollisionQuad& quad, ExtendedMesh& mesh, float scale) {
|
||||
std::unique_ptr<StructureDataChunk> calculatePortalSingleSurface(CFileDefinition& fileDefinition, const CollisionQuad& quad, ExtendedMesh& mesh, float scale) {
|
||||
std::unique_ptr<StructureDataChunk> portalSurface(new StructureDataChunk());
|
||||
|
||||
std::unique_ptr<StructureDataChunk> vertices(new StructureDataChunk());
|
||||
|
@ -122,20 +108,20 @@ std::unique_ptr<StructureDataChunk> 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<StructureDataChunk> portalSurfaceIndices(new StructureDataChunk());
|
||||
std::unique_ptr<StructureDataChunk> 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<StructureDataChunk> boundingBoxes(new StructureDataChunk());
|
||||
|
||||
for (auto& mesh : mStaticOutput.staticMeshes) {
|
||||
for (auto& mesh : staticOutput.staticMeshes) {
|
||||
std::unique_ptr<StructureDataChunk> 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<StructureDataChunk> triggers(new StructureDataChunk());
|
||||
|
||||
for (auto& trigger : mTriggerOutput.triggers) {
|
||||
for (auto& trigger : triggerOutput.triggers) {
|
||||
std::unique_ptr<StructureDataChunk> triggerData(new StructureDataChunk());
|
||||
|
||||
std::unique_ptr<StructureDataChunk> 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<StructureDataChunk> 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<DataChunk>(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<std::vector<int>> roomDoorways;
|
||||
|
||||
for (int i = 0; i < mRoomOutput.roomCount; ++i) {
|
||||
for (int i = 0; i < roomOutput.roomCount; ++i) {
|
||||
roomDoorways.push_back(std::vector<int>());
|
||||
}
|
||||
|
||||
|
@ -261,7 +249,7 @@ void LevelGenerator::CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefini
|
|||
|
||||
std::unique_ptr<StructureDataChunk> 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<StructureDataChunk> rooms(new StructureDataChunk());
|
||||
|
||||
for (int i = 0; i < mRoomOutput.roomCount; ++i) {
|
||||
for (int i = 0; i < roomOutput.roomCount; ++i) {
|
||||
std::unique_ptr<StructureDataChunk> 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<StructureDataChunk> 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<StructureDataChunk> doors(new StructureDataChunk());
|
||||
|
||||
aiMatrix4x4 baseTransform = mSettings.CreateCollisionTransform();
|
||||
aiMatrix4x4 baseTransform = settings.CreateCollisionTransform();
|
||||
|
||||
for (auto& door : mRoomOutput.doors) {
|
||||
for (auto& door : roomOutput.doors) {
|
||||
std::unique_ptr<StructureDataChunk> 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<StructureDataChunk> 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<StructureDataChunk> 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<FileDefinition>(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef))));
|
||||
}
|
|
@ -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<StructureDataChunk> 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
|
|
@ -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<RenderChunk>& renderChunks) {
|
||||
void MeshDefinitionGenerator::AppendRenderChunks(const aiScene* scene, aiNode* node, CFileDefinition& fileDefinition, const DisplayListSettings& settings, std::vector<RenderChunk>& renderChunks) {
|
||||
for (unsigned meshIndex = 0; meshIndex < node->mNumMeshes; ++meshIndex) {
|
||||
std::shared_ptr<ExtendedMesh> mesh = fileDefinition.GetExtendedMesh(scene->mMeshes[node->mMeshes[meshIndex]]);
|
||||
|
||||
|
|
|
@ -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<RenderChunk>& renderChunks);
|
||||
static void AppendRenderChunks(const aiScene* scene, aiNode* node, CFileDefinition& fileDefinition, const DisplayListSettings& settings, std::vector<RenderChunk>& renderChunks);
|
||||
private:
|
||||
DisplayListSettings mSettings;
|
||||
};
|
||||
|
|
|
@ -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<aiNode*>& 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<NodeWithArguments>& 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<RoomBlock>& 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<RoomGeneratorOutput> generateRooms(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, NodeGroups& nodeGroups) {
|
||||
std::vector<RoomBlock> roomBlocks;
|
||||
std::shared_ptr<RoomGeneratorOutput> 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;
|
||||
}
|
|
@ -41,18 +41,8 @@ struct RoomGeneratorOutput {
|
|||
};
|
||||
|
||||
void sortNodesByRoom(std::vector<aiNode*>& nodes, const RoomGeneratorOutput& roomOutput);
|
||||
void sortNodesWithArgsByRoom(std::vector<NodeWithArguments>& 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<RoomGeneratorOutput> generateRooms(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, NodeGroups& nodeGroups);
|
||||
|
||||
#endif
|
|
@ -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<StaticGeneratorOutput> 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<StaticGeneratorOutput> output(new StaticGeneratorOutput());
|
||||
|
||||
std::vector<StaticContentElement> elements;
|
||||
|
||||
BoneHierarchy unusedBones;
|
||||
|
||||
sortNodesByRoom(mIncludedNodes, mRoomMapping);
|
||||
std::vector<NodeWithArguments> nodes = nodeGroups.NodesForType("@static");
|
||||
|
||||
for (auto node = mIncludedNodes.begin(); node != mIncludedNodes.end(); ++node) {
|
||||
sortNodesWithArgsByRoom(nodes, roomMapping);
|
||||
|
||||
for (auto& nodeInfo : nodes) {
|
||||
std::vector<RenderChunk> 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<RenderChunk> 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<FileDefinition> fileDef(new DataFileDefinition("struct StaticContentElement", mOutput.staticContentName, true, "_geo", std::move(staticContentList)));
|
||||
std::unique_ptr<FileDefinition> 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<StructureDataChunk> 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<StructureDataChunk> 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<FileDefinition>(new DataFileDefinition("struct Rangeu16", mOutput.roomMappingName, true, "_geo", std::move(roomToStaticMapping))));
|
||||
}
|
||||
output->roomMappingName = fileDefinition.GetUniqueName("static_room_mapping");
|
||||
fileDefinition.AddDefinition(std::unique_ptr<FileDefinition>(new DataFileDefinition("struct Rangeu16", output->roomMappingName, true, "_geo", std::move(roomToStaticMapping))));
|
||||
|
||||
const StaticGeneratorOutput& StaticGenerator::GetOutput() const {
|
||||
return mOutput;
|
||||
return output;
|
||||
}
|
|
@ -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<StaticGeneratorOutput> generateStatic(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, RoomGeneratorOutput& roomMapping, NodeGroups& nodeGroups);
|
||||
|
||||
#endif
|
|
@ -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<StructureDataChunk> TriggerGenerator::GenerateCutsceneStep(CutsceneStep& step) {
|
||||
std::unique_ptr<StructureDataChunk> generateCutsceneStep(CutsceneStep& step, const RoomGeneratorOutput& roomOutput) {
|
||||
std::unique_ptr<StructureDataChunk> result(new StructureDataChunk());
|
||||
|
||||
if ((step.command == "play_sound" || step.command == "start_sound") && step.args.size() >= 1) {
|
||||
|
@ -67,7 +61,7 @@ std::unique_ptr<StructureDataChunk> 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<const char*>("CutsceneStepTypeOpenPortal");
|
||||
|
@ -85,15 +79,12 @@ std::unique_ptr<StructureDataChunk> TriggerGenerator::GenerateCutsceneStep(Cutsc
|
|||
return result;
|
||||
}
|
||||
|
||||
void TriggerGenerator::GenerateCutscenes(std::map<std::string, std::shared_ptr<Cutscene>>& output, CFileDefinition& fileDefinition) {
|
||||
void generateCutscenes(std::map<std::string, std::shared_ptr<Cutscene>>& output, CFileDefinition& fileDefinition, const RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups) {
|
||||
std::vector<std::shared_ptr<CutsceneStep>> steps;
|
||||
|
||||
for (auto& node : mIncludedNodes) {
|
||||
if (!StartsWith(node->mName.C_Str(), CUTSCENE_PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
for (auto& nodeInfo : nodeGroups.NodesForType(CUTSCENE_PREFIX)) {
|
||||
std::vector<std::string> 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::map<std::string, std::shared_ptr<C
|
|||
aiVector3D scale;
|
||||
aiVector3D pos;
|
||||
aiQuaternion rot;
|
||||
node->mTransformation.Decompose(scale, rot, pos);
|
||||
nodeInfo.node->mTransformation.Decompose(scale, rot, pos);
|
||||
|
||||
std::shared_ptr<CutsceneStep> step(new CutsceneStep(command, cutsceneParts, pos, rot));
|
||||
|
||||
|
@ -142,7 +133,7 @@ void TriggerGenerator::GenerateCutscenes(std::map<std::string, std::shared_ptr<C
|
|||
std::unique_ptr<StructureDataChunk> 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<std::string, std::shared_ptr<C
|
|||
}
|
||||
}
|
||||
|
||||
void TriggerGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) {
|
||||
std::shared_ptr<TriggerGeneratorOutput> generateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups) {
|
||||
std::shared_ptr<TriggerGeneratorOutput> output(new TriggerGeneratorOutput());
|
||||
|
||||
std::map<std::string, std::shared_ptr<Cutscene>> 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> 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;
|
||||
}
|
|
@ -31,21 +31,6 @@ struct Cutscene {
|
|||
std::vector<std::shared_ptr<CutsceneStep>> 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<std::string, std::shared_ptr<Cutscene>>& output, CFileDefinition& fileDefinition);
|
||||
std::unique_ptr<StructureDataChunk> GenerateCutsceneStep(CutsceneStep& step);
|
||||
};
|
||||
std::shared_ptr<TriggerGeneratorOutput> generateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue