Logic for crossing between rooms

This commit is contained in:
James Lambert 2022-05-21 21:34:33 -06:00
parent d1d8ed9b76
commit 0b66517cca
12 changed files with 89 additions and 17 deletions

View File

@ -40,7 +40,8 @@ RUN apt install -y binutils-mips-n64 \
cmake \
build-essential \
wget \
unzip
unzip \
sox
COPY skelatool64/src skelatool64/src
COPY skelatool64/main.cpp skelatool64/main.cpp
@ -62,6 +63,7 @@ RUN pip install vpk
COPY Makefile Makefile
COPY tools/export_fbx.py tools/export_fbx.py
COPY tools/generate_level_list.js tools/generate_level_list.js
COPY tools/generate_sound_ids.js tools/generate_sound_ids.js
COPY asm asm
COPY assets assets
COPY src src

View File

@ -153,7 +153,7 @@ int main(int argc, char *argv[]) {
roomGenerator.GenerateDefinitions(scene, fileDef);
std::cout << "Generating collider definitions" << std::endl;
CollisionGenerator colliderGenerator(settings);
CollisionGenerator colliderGenerator(settings, roomGenerator.GetOutput());
colliderGenerator.TraverseScene(scene);
colliderGenerator.GenerateDefinitions(scene, fileDef);

View File

@ -4,9 +4,10 @@
#include <algorithm>
CollisionGenerator::CollisionGenerator(const DisplayListSettings& settings) :
CollisionGenerator::CollisionGenerator(const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput) :
DefinitionGenerator(),
mSettings(settings) {}
mSettings(settings),
mRoomOutput(roomOutput) {}
bool CollisionGenerator::ShouldIncludeNode(aiNode* node) {
@ -26,6 +27,8 @@ void CollisionGenerator::GenerateDefinitions(const aiScene* scene, CFileDefiniti
std::string colliderTypesName = fileDefinition.GetUniqueName("collider_types");
std::string collisionObjectsName = fileDefinition.GetUniqueName("collision_objects");
sortNodesByRoom(mIncludedNodes, mRoomOutput);
for (auto node = mIncludedNodes.begin(); node != mIncludedNodes.end(); ++node) {
for (unsigned i = 0; i < (*node)->mNumMeshes; ++i) {
aiMesh* mesh = scene->mMeshes[(*node)->mMeshes[i]];

View File

@ -4,6 +4,7 @@
#include "DefinitionGenerator.h"
#include "../DisplayListSettings.h"
#include "CollisionQuad.h"
#include "RoomGenerator.h"
struct CollisionGeneratorOutput {
std::string quadsName;
@ -12,7 +13,7 @@ struct CollisionGeneratorOutput {
class CollisionGenerator : public DefinitionGenerator {
public:
CollisionGenerator(const DisplayListSettings& settings);
CollisionGenerator(const DisplayListSettings& settings, const RoomGeneratorOutput& roomOutput);
virtual bool ShouldIncludeNode(aiNode* node);
virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition);
@ -20,6 +21,7 @@ public:
const CollisionGeneratorOutput& GetOutput() const;
private:
DisplayListSettings mSettings;
RoomGeneratorOutput mRoomOutput;
CollisionGeneratorOutput mOutput;
};

View File

@ -20,19 +20,23 @@ RoomGenerator::RoomGenerator(const DisplayListSettings& settings): DefinitionGen
short RoomGeneratorOutput::FindLocationRoom(const std::string& name) const {
for (auto& location : namedLocations) {
if (location.name == name) {
auto room = roomIndexMapping.find(location.node);
if (room == roomIndexMapping.end()) {
return -1;
}
return room->second;
return RoomForNode(location.node);
}
}
return -1;
}
int RoomGeneratorOutput::RoomForNode(const aiNode* node) const {
auto room = roomIndexMapping.find(node);
if (room == roomIndexMapping.end()) {
return -1;
}
return room->second;
}
struct RoomBlock {
aiAABB boundingBox;
int roomIndex;
@ -42,9 +46,9 @@ bool RoomGenerator::ShouldIncludeNode(aiNode* node) {
return true;
}
void sortNodesByRoom(std::vector<aiNode*>& nodes, RoomGeneratorOutput& roomOutput) {
void sortNodesByRoom(std::vector<aiNode*>& nodes, const RoomGeneratorOutput& roomOutput) {
std::sort(nodes.begin(), nodes.end(), [&](const aiNode* a, const aiNode* b) -> bool {
return roomOutput.roomIndexMapping[a] < roomOutput.roomIndexMapping[b];
return roomOutput.RoomForNode(a) < roomOutput.RoomForNode(b);
});
}

View File

@ -28,9 +28,10 @@ struct RoomGeneratorOutput {
int roomCount;
short FindLocationRoom(const std::string& name) const;
int RoomForNode(const aiNode* node) const;
};
void sortNodesByRoom(std::vector<aiNode*>& nodes, RoomGeneratorOutput& roomOutput);
void sortNodesByRoom(std::vector<aiNode*>& nodes, const RoomGeneratorOutput& roomOutput);
class RoomGenerator : public DefinitionGenerator {
public:

View File

@ -20,14 +20,16 @@ CutsceneStep::CutsceneStep(
bool doesBelongToCutscene(const CutsceneStep& startStep, const CutsceneStep& otherStep) {
aiVector3D offset = otherStep.location - startStep.location;
aiVector3D relativeOffset = startStep.direction.Rotate(offset);
aiQuaternion directionCopy = startStep.direction;
aiVector3D relativeOffset = directionCopy.Rotate(offset);
return relativeOffset.y >= 0.0f && relativeOffset.x * relativeOffset.x + relativeOffset.z * relativeOffset.z < 0.1f;
}
float distanceFromStart(const CutsceneStep& startStep, const CutsceneStep& otherStep) {
aiVector3D offset = otherStep.location - startStep.location;
aiVector3D relativeOffset = startStep.direction.Rotate(offset);
aiQuaternion directionCopy = startStep.direction;
aiVector3D relativeOffset = directionCopy.Rotate(offset);
return relativeOffset.y;
}

View File

@ -77,4 +77,42 @@ struct Location* levelGetLocation(short index) {
}
return &gCurrentLevel->locations[index];
}
int levelCheckDoorwaySides(struct Vector3* position, int currentRoom) {
struct Room* room = &gCurrentLevel->rooms[currentRoom];
int sideMask = 0;
for (int i = 0; i < room->doorwayCount; ++i) {
if (planePointDistance(&gCurrentLevel->doorways[room->doorwayIndices[i]].quad.plane, position) > 0) {
sideMask |= 1 << 1;
}
}
return sideMask;
}
int levelCheckDoorwayCrossings(struct Vector3* position, int currentRoom, int sideMask) {
struct Room* room = &gCurrentLevel->rooms[currentRoom];
for (int i = 0; i < room->doorwayCount; ++i) {
struct Doorway* doorway = &gCurrentLevel->doorways[room->doorwayIndices[i]];
int prevSide = (sideMask & (1 << 1)) != 0;
int currSide = planePointDistance(&doorway->quad.plane, position) > 0;
if (prevSide != currSide) {
struct Vector3 posOnFace;
planeProjectPoint(&doorway->quad.plane, position, &posOnFace);
if (collisionQuadDetermineEdges(&posOnFace, &doorway->quad)) {
continue;
}
return doorway->roomA == currentRoom ? doorway->roomB : doorway->roomA;
}
}
return currentRoom;
}

View File

@ -17,6 +17,10 @@ Gfx* levelMaterialRevert(int index);
int levelQuadIndex(struct CollisionObject* pointer);
int levelCheckDoorwaySides(struct Vector3* position, int currentRoom);
int levelCheckDoorwayCrossings(struct Vector3* position, int currentRoom, int sideMask);
void levelCheckTriggers(struct Vector3* playerPos);
struct Location* levelGetLocation(short index);

View File

@ -10,6 +10,17 @@
#define MAX_DYNAMIC_OBJECTS 16
struct BroadphaseEdge {
float xValue;
short quadIndex;
short isStartEdge;
};
struct BroadphaseIndex {
struct BroadphaseEdge* edges;
short edgesCount;
};
struct CollisionScene {
struct CollisionObject* quads;
struct Transform* portalTransforms[2];

View File

@ -8,6 +8,7 @@
#include "physics/collision_sphere.h"
#include "physics/collision_scene.h"
#include "physics/config.h"
#include "../levels/levels.h"
#define GRAB_RAYCAST_DISTANCE 3.5f
@ -147,6 +148,8 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
struct Vector3 forward;
struct Vector3 right;
int doorwayMask = levelCheckDoorwaySides(&player->body.transform.position, player->currentRoom);
struct Transform* transform = &player->body.transform;
quatMultVector(&transform->rotation, &gForward, &forward);
@ -276,4 +279,6 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
cameraTransform->rotation = player->body.transform.rotation;
transformPoint(transform, &gCameraOffset, &cameraTransform->position);
playerUpdateGrabbedObject(player);
player->currentRoom = levelCheckDoorwayCrossings(&player->body.transform.position, player->currentRoom, doorwayMask);
}