Breakup level definition generatoin

This commit is contained in:
James Lambert 2022-06-05 12:53:55 -06:00
parent b603808fe3
commit da514b91a3
9 changed files with 136 additions and 66 deletions

View file

@ -148,9 +148,10 @@ int main(int argc, char *argv[]) {
if (args.mIsLevel) {
NodeGroups nodesByGroup(scene);
Signals signals;
std::cout << "Grouping objects by room" << std::endl;
auto roomOutput = generateRooms(scene, fileDef, settings, nodesByGroup);
auto roomOutput = generateRooms(scene, fileDef, settings, signals, nodesByGroup);
std::cout << "Generating collider definitions" << std::endl;
auto collisionOutput = generateCollision(scene, fileDef, settings, *roomOutput, nodesByGroup);
@ -158,7 +159,7 @@ int main(int argc, char *argv[]) {
std::cout << "Generating static definitions" << std::endl;
auto staticOutput = generateStatic(scene, fileDef, settings, *roomOutput, nodesByGroup);
auto triggerOutput = generateTriggers(scene, fileDef, settings, *roomOutput, nodesByGroup);
auto triggerOutput = generateTriggers(scene, fileDef, settings, *roomOutput, signals, nodesByGroup);
std::cout << "Generating level definitions" << std::endl;
generateLevel(

View file

@ -108,7 +108,7 @@ std::unique_ptr<StructureDataChunk> calculatePortalSingleSurface(CFileDefinition
return portalSurface;
}
int calculatePortalSurfaces(const aiScene* scene, CFileDefinition& fileDefinition, const CollisionGeneratorOutput& collisionOutput, const StaticGeneratorOutput& staticOutput, const DisplayListSettings& settings, std::string& surfacesName, std::string& surfaceMappingName) {
void generatePortalSurfacesDefinition(const aiScene* scene, CFileDefinition& fileDefinition, StructureDataChunk& levelDef, const CollisionGeneratorOutput& collisionOutput, const StaticGeneratorOutput& staticOutput, const DisplayListSettings& settings) {
int surfaceCount = 0;
std::unique_ptr<StructureDataChunk> portalSurfaceIndices(new StructureDataChunk());
@ -150,18 +150,20 @@ int calculatePortalSurfaces(const aiScene* scene, CFileDefinition& fileDefinitio
portalSurfaceIndices->Add(std::move(indices));
}
surfacesName = fileDefinition.GetUniqueName("portal_surfaces");
std::string surfacesName = fileDefinition.GetUniqueName("portal_surfaces");
std::unique_ptr<FileDefinition> portalSurfacesDef(new DataFileDefinition("struct PortalSurface", surfacesName, true, "_geo", std::move(portalSurfaces)));
portalSurfacesDef->AddTypeHeader("\"scene/portal_surface.h\"");
fileDefinition.AddDefinition(std::move(portalSurfacesDef));
surfaceMappingName = fileDefinition.GetUniqueName("collider_to_surface");
std::string surfaceMappingName = fileDefinition.GetUniqueName("collider_to_surface");
fileDefinition.AddDefinition(std::unique_ptr<FileDefinition>(new DataFileDefinition("struct PortalSurfaceMapping", surfaceMappingName, true, "_geo", std::move(portalSurfaceIndices))));
return surfaceCount;
levelDef.AddPrimitive("portalSurfaces", surfacesName);
levelDef.AddPrimitive("portalSurfaceMapping", surfaceMappingName);
levelDef.AddPrimitive("portalSurfaceCount", surfaceCount);
}
void calculateBoundingBoxes(const aiScene* scene, CFileDefinition& fileDefinition, const StaticGeneratorOutput& staticOutput, const DisplayListSettings& settings, std::string& boundingBoxesName) {
void generateBoundingBoxesDefinition(const aiScene* scene, CFileDefinition& fileDefinition, StructureDataChunk& levelDef, const StaticGeneratorOutput& staticOutput, const DisplayListSettings& settings) {
std::unique_ptr<StructureDataChunk> boundingBoxes(new StructureDataChunk());
for (auto& mesh : staticOutput.staticMeshes) {
@ -178,12 +180,14 @@ void calculateBoundingBoxes(const aiScene* scene, CFileDefinition& fileDefinitio
boundingBoxes->Add(std::move(sphere));
}
boundingBoxesName = fileDefinition.GetUniqueName("bounding_boxes");
std::string boundingBoxesName = fileDefinition.GetUniqueName("bounding_boxes");
std::unique_ptr<FileDefinition> boundingBoxDef(new DataFileDefinition("struct BoundingBoxs16", boundingBoxesName, true, "_geo", std::move(boundingBoxes)));
fileDefinition.AddDefinition(std::move(boundingBoxDef));
levelDef.AddPrimitive("staticBoundingBoxes", boundingBoxesName);
}
void calculateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const TriggerGeneratorOutput& triggerOutput, std::string& triggersName) {
void generateTriggerDefinition(const aiScene* scene, CFileDefinition& fileDefinition, StructureDataChunk& levelDef, const TriggerGeneratorOutput& triggerOutput) {
std::unique_ptr<StructureDataChunk> triggers(new StructureDataChunk());
for (auto& trigger : triggerOutput.triggers) {
@ -200,17 +204,20 @@ void calculateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, co
triggers->Add(std::move(triggerData));
}
triggersName = fileDefinition.GetUniqueName("triggers");
std::string triggersName = fileDefinition.GetUniqueName("triggers");
std::unique_ptr<FileDefinition> triggersDef(new DataFileDefinition("struct Trigger", triggersName, true, "_geo", std::move(triggers)));
fileDefinition.AddDefinition(std::move(triggersDef));
levelDef.AddPrimitive("triggers", triggersName);
levelDef.AddPrimitive("triggerCount", triggerOutput.triggers.size());
}
void calculateLocations(const aiScene* scene, CFileDefinition& fileDefinition, const RoomGeneratorOutput& roomOuptut, const DisplayListSettings& settings, std::string& locationsName) {
void generateLocationDefinition(const aiScene* scene, CFileDefinition& fileDefinition, StructureDataChunk& levelDef, const RoomGeneratorOutput& roomOutput, const DisplayListSettings& settings) {
aiMatrix4x4 baseTransfrom = settings.CreateCollisionTransform();
std::unique_ptr<StructureDataChunk> locations(new StructureDataChunk());
for (auto& location : roomOuptut.namedLocations) {
for (auto& location : roomOutput.namedLocations) {
aiMatrix4x4 nodeTransform = baseTransfrom * location.node->mTransformation;
aiVector3D position;
@ -226,19 +233,22 @@ void calculateLocations(const aiScene* scene, CFileDefinition& fileDefinition, c
transform->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(scale)));
locationData->Add(std::move(transform));
auto roomIndex = roomOuptut.roomIndexMapping.find(location.node);
auto roomIndex = roomOutput.roomIndexMapping.find(location.node);
locationData->AddPrimitive(roomIndex == roomOuptut.roomIndexMapping.end() ? 0 : roomIndex->second);
locationData->AddPrimitive(roomIndex == roomOutput.roomIndexMapping.end() ? 0 : roomIndex->second);
locations->Add(std::move(locationData));
}
locationsName = fileDefinition.GetUniqueName("locations");
std::string locationsName = fileDefinition.GetUniqueName("locations");
std::unique_ptr<FileDefinition> triggersDef(new DataFileDefinition("struct Location", locationsName, true, "_geo", std::move(locations)));
fileDefinition.AddDefinition(std::move(triggersDef));
levelDef.AddPrimitive("locations", locationsName);
levelDef.AddPrimitive("locationCount", roomOutput.namedLocations.size());
}
void calculateDoorwaysAndRooms(const aiScene* scene, CFileDefinition& fileDefinition, const RoomGeneratorOutput& roomOutput, const CollisionGeneratorOutput& collisionOutput, std::string& doorwaysName, std::string& roomsName) {
void generateWorldDefinition(const aiScene* scene, CFileDefinition& fileDefinition, StructureDataChunk& levelDef, const RoomGeneratorOutput& roomOutput, const CollisionGeneratorOutput& collisionOutput) {
std::vector<std::vector<int>> roomDoorways;
for (int i = 0; i < roomOutput.roomCount; ++i) {
@ -262,7 +272,7 @@ void calculateDoorwaysAndRooms(const aiScene* scene, CFileDefinition& fileDefini
++doorwayIndex;
}
doorwaysName = fileDefinition.AddDataDefinition(
std::string doorwaysName = fileDefinition.AddDataDefinition(
"doorways",
"struct Doorway",
true,
@ -338,16 +348,24 @@ void calculateDoorwaysAndRooms(const aiScene* scene, CFileDefinition& fileDefini
rooms->Add(std::move(room));
}
roomsName = fileDefinition.AddDataDefinition(
std::string roomsName = fileDefinition.AddDataDefinition(
"rooms",
"struct Room",
true,
"_geo",
std::move(rooms)
);
std::unique_ptr<StructureDataChunk> worldDef(new StructureDataChunk());
worldDef->AddPrimitive("rooms", roomsName);
worldDef->AddPrimitive("doorways", doorwaysName);
worldDef->AddPrimitive("roomCount", roomOutput.roomCount);
worldDef->AddPrimitive("doorwayCount", roomOutput.doorways.size());
levelDef.Add("world", std::move(worldDef));
}
void calculateDoors(const aiScene* scene, CFileDefinition& fileDefinition, const RoomGeneratorOutput& roomOutput, const DisplayListSettings& settings, std::string& doorsName) {
void generateDoorsDefinition(const aiScene* scene, CFileDefinition& fileDefinition, StructureDataChunk& levelDef, const RoomGeneratorOutput& roomOutput, const DisplayListSettings& settings) {
std::unique_ptr<StructureDataChunk> doors(new StructureDataChunk());
aiMatrix4x4 baseTransform = settings.CreateCollisionTransform();
@ -361,16 +379,20 @@ void calculateDoors(const aiScene* scene, CFileDefinition& fileDefinition, const
doorData->Add(std::unique_ptr<StructureDataChunk>(new StructureDataChunk(pos)));
doorData->Add(std::unique_ptr<StructureDataChunk>(new StructureDataChunk(rot)));
doorData->AddPrimitive(door.doorwayIndex);
doorData->AddPrimitive(door.signalIndex);
doors->Add(std::move(doorData));
}
doorsName = fileDefinition.AddDataDefinition(
std::string doorsName = fileDefinition.AddDataDefinition(
"doors",
"struct DoorDefinition",
true,
"_geo",
std::move(doors)
);
levelDef.AddPrimitive("doors", doorsName);
levelDef.AddPrimitive("doorCount", roomOutput.doors.size());
}
void generateLevel(
@ -382,52 +404,28 @@ void generateLevel(
const TriggerGeneratorOutput& triggerOutput,
const RoomGeneratorOutput& roomOutput
) {
std::string portalSurfaces;
std::string portalSurfaceMapping;
int portalSurfacesCount = calculatePortalSurfaces(scene, fileDefinition, collisionOutput, staticOutput, settings, portalSurfaces, portalSurfaceMapping);
std::string boundingBoxes;
calculateBoundingBoxes(scene, fileDefinition, staticOutput, settings, boundingBoxes);
std::string triggers;
calculateTriggers(scene, fileDefinition, triggerOutput, triggers);
std::string locations;
calculateLocations(scene, fileDefinition, roomOutput, settings, locations);
std::string doorways;
std::string rooms;
calculateDoorwaysAndRooms(scene, fileDefinition, roomOutput, collisionOutput, doorways, rooms);
std::string doors;
calculateDoors(scene, fileDefinition, roomOutput, settings, doors);
std::unique_ptr<StructureDataChunk> levelDef(new StructureDataChunk());
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);
levelDef->AddPrimitive("triggers", triggers);
levelDef->AddPrimitive("locations", locations);
std::unique_ptr<StructureDataChunk> worldDef(new StructureDataChunk());
worldDef->AddPrimitive("rooms", rooms);
worldDef->AddPrimitive("doorways", doorways);
worldDef->AddPrimitive("roomCount", roomOutput.roomCount);
worldDef->AddPrimitive("doorwayCount", roomOutput.doorways.size());
levelDef->Add("world", std::move(worldDef));
levelDef->AddPrimitive("doors", doors);
levelDef->AddPrimitive("collisionQuadCount", collisionOutput.quads.size());
levelDef->AddPrimitive("staticContentCount", staticOutput.staticMeshes.size());
levelDef->AddPrimitive("portalSurfaceCount", portalSurfacesCount);
levelDef->AddPrimitive("triggerCount", triggerOutput.triggers.size());
levelDef->AddPrimitive("locationCount", roomOutput.namedLocations.size());
levelDef->AddPrimitive("doorCount", roomOutput.doors.size());
levelDef->AddPrimitive("startLocation", roomOutput.FindLocationIndex("start"));
generatePortalSurfacesDefinition(scene, fileDefinition, *levelDef, collisionOutput, staticOutput, settings);
generateBoundingBoxesDefinition(scene, fileDefinition, *levelDef, staticOutput, settings);
generateTriggerDefinition(scene, fileDefinition, *levelDef, triggerOutput);
generateLocationDefinition(scene, fileDefinition, *levelDef, roomOutput, settings);
generateWorldDefinition(scene, fileDefinition, *levelDef, roomOutput, collisionOutput);
generateDoorsDefinition(scene, fileDefinition, *levelDef, roomOutput, settings);
generateButtonsDefinition(fileDefinition, *levelDef, triggerOutput.buttons);
fileDefinition.AddDefinition(std::unique_ptr<FileDefinition>(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef))));
}

View file

@ -17,7 +17,7 @@ Doorway::Doorway(const aiNode* node, const CollisionQuad& quad):
}
Door::Door(const aiNode* node): node(node) {}
Door::Door(const aiNode* node, int signalIndex): node(node), signalIndex(signalIndex) {}
short RoomGeneratorOutput::FindLocationRoom(const std::string& name) const {
for (auto& location : namedLocations) {
@ -98,7 +98,7 @@ int findClosestRoom(const aiNode* node, const aiScene* scene, CFileDefinition& f
}
std::shared_ptr<RoomGeneratorOutput> generateRooms(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, NodeGroups& nodeGroups) {
std::shared_ptr<RoomGeneratorOutput> generateRooms(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, Signals& signals, NodeGroups& nodeGroups) {
std::vector<RoomBlock> roomBlocks;
std::shared_ptr<RoomGeneratorOutput> output(new RoomGeneratorOutput());
@ -143,7 +143,7 @@ std::shared_ptr<RoomGeneratorOutput> generateRooms(const aiScene* scene, CFileDe
}
for (auto& nodeInfo : nodeGroups.NodesForType(DOOR_PREFIX)) {
output->doors.push_back(Door(nodeInfo.node));
output->doors.push_back(Door(nodeInfo.node, nodeInfo.arguments.size() ? signals.SignalIndexForName(nodeInfo.arguments[0]): -1));
}
if (roomBlocks.size() == 0) {

View file

@ -4,6 +4,7 @@
#include "DefinitionGenerator.h"
#include "CollisionQuad.h"
#include "../DisplayListSettings.h"
#include "./Signals.h"
#include <map>
@ -22,9 +23,10 @@ struct Doorway {
};
struct Door {
Door(const aiNode* node);
Door(const aiNode* node, int signalIndex);
const aiNode* node;
int signalIndex;
int doorwayIndex;
};
@ -43,6 +45,6 @@ struct RoomGeneratorOutput {
void sortNodesByRoom(std::vector<aiNode*>& nodes, const RoomGeneratorOutput& roomOutput);
void sortNodesWithArgsByRoom(std::vector<NodeWithArguments>& nodes, const RoomGeneratorOutput& roomOutput);
std::shared_ptr<RoomGeneratorOutput> generateRooms(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, NodeGroups& nodeGroups);
std::shared_ptr<RoomGeneratorOutput> generateRooms(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, Signals& signals, NodeGroups& nodeGroups);
#endif

View file

@ -3,6 +3,7 @@
#include "../MathUtl.h"
#define TRIGGER_PREFIX "@trigger"
#define BUTTON_PREFIX "@button"
#define CUTSCENE_PREFIX "@cutscene"
@ -144,7 +145,7 @@ void generateCutscenes(std::map<std::string, std::shared_ptr<Cutscene>>& output,
}
}
std::shared_ptr<TriggerGeneratorOutput> generateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups) {
std::shared_ptr<TriggerGeneratorOutput> generateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput, Signals& signals, NodeGroups& nodeGroups) {
std::shared_ptr<TriggerGeneratorOutput> output(new TriggerGeneratorOutput());
std::map<std::string, std::shared_ptr<Cutscene>> cutscenes;
@ -177,5 +178,36 @@ std::shared_ptr<TriggerGeneratorOutput> generateTriggers(const aiScene* scene, C
output->triggers.push_back(trigger);
}
aiMatrix4x4 baseTransform = settings.CreateCollisionTransform();
for (auto& nodeInfo : nodeGroups.NodesForType(BUTTON_PREFIX)) {
aiQuaternion rot;
Button button;
(baseTransform * nodeInfo.node->mTransformation).DecomposeNoScaling(rot, button.position);
button.signalIndex = nodeInfo.arguments.size() ? signals.SignalIndexForName(nodeInfo.arguments[0]) : -1;
output->buttons.push_back(button);
}
return output;
}
void generateButtonsDefinition(CFileDefinition& fileDefinition, StructureDataChunk& levelDefinitionChunk, const std::vector<Button>& buttons) {
std::unique_ptr<StructureDataChunk> buttonData(new StructureDataChunk());
for (auto& ref : buttons) {
std::unique_ptr<StructureDataChunk> singleButton(new StructureDataChunk());
singleButton->Add(std::unique_ptr<StructureDataChunk>(new StructureDataChunk(ref.position)));
singleButton->AddPrimitive(ref.signalIndex);
buttonData->Add(std::move(singleButton));
}
std::string buttonsName = fileDefinition.AddDataDefinition("buttons", "struct ButtonDefinition", true, "_geo", std::move(buttonData));
levelDefinitionChunk.AddPrimitive("buttons", buttonsName);
levelDefinitionChunk.AddPrimitive("buttonCount", buttons.size());
}

View file

@ -4,6 +4,7 @@
#include "DefinitionGenerator.h"
#include "../DisplayListSettings.h"
#include "RoomGenerator.h"
#include "./Signals.h"
#include <map>
struct Trigger {
@ -12,8 +13,14 @@ struct Trigger {
aiAABB bb;
};
struct Button {
aiVector3D position;
int signalIndex;
};
struct TriggerGeneratorOutput {
std::vector<std::shared_ptr<Trigger>> triggers;
std::vector<Button> buttons;
};
struct CutsceneStep {
@ -31,6 +38,8 @@ struct Cutscene {
std::vector<std::shared_ptr<CutsceneStep>> steps;
};
std::shared_ptr<TriggerGeneratorOutput> generateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput, NodeGroups& nodeGroups);
std::shared_ptr<TriggerGeneratorOutput> generateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput, Signals& signals, NodeGroups& nodeGroups);
void generateButtonsDefinition(CFileDefinition& fileDefinition, StructureDataChunk& levelDefinitionChunk, const std::vector<Button>& buttons);
#endif

View file

@ -3,6 +3,7 @@
#include "../physics/world.h"
#include "../scene/portal_surface.h"
#include "../scene/signals.h"
#include "../math/boxs16.h"
#include "../math/box3d.h"
#include "../math/range.h"
@ -66,6 +67,12 @@ struct DoorDefinition {
struct Vector3 location;
struct Quaternion rotation;
short doorwayIndex;
short signalIndex;
};
struct ButtonDefinition {
struct Vector3 location;
short signalIndex;
};
struct LevelDefinition {
@ -80,12 +87,16 @@ struct LevelDefinition {
struct Location* locations;
struct World world;
struct DoorDefinition* doors;
struct ButtonDefinition* buttons;
struct SignalOperator* signalOperators;
short collisionQuadCount;
short staticContentCount;
short portalSurfaceCount;
short triggerCount;
short locationCount;
short doorCount;
short buttonCount;
short signalOperatorCount;
short startLocation;
};

View file

@ -85,7 +85,7 @@ void sceneInit(struct Scene* scene) {
doorTransform.position = gCurrentLevel->doors[i].location;
doorTransform.rotation = gCurrentLevel->doors[i].rotation;
doorTransform.scale = gOneVec;
doorInit(&scene->doors[i], &doorTransform, 0, 0, gCurrentLevel->doors[i].doorwayIndex, 0);
doorInit(&scene->doors[i], &doorTransform, 0, 0, gCurrentLevel->doors[i].doorwayIndex, gCurrentLevel->doors[i].signalIndex);
}
// scene->player.grabbing = &scene->cubes[0].rigidBody;

View file

@ -7,4 +7,21 @@ int signalsRead(unsigned signalIndex);
void signalsSend(unsigned signalIndex);
void signalsSetDefault(unsigned signalIndex, int value);
enum SignalOperatorType {
SignalOperatorTypeAnd,
SignalOperatorTypeOr,
SignalOperatorTypeNot,
SignalOperatorTypeTimer,
};
struct SignalOperator {
unsigned char type;
unsigned char outputSignal;
unsigned char inputSignals[2];
union {
char additionalInputs[2];
short duration;
} data;
};
#endif