mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-11-23 12:29:43 +00:00
Logic for crossing between rooms
This commit is contained in:
parent
d1d8ed9b76
commit
0b66517cca
@ -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
|
||||
|
Binary file not shown.
@ -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);
|
||||
|
||||
|
@ -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]];
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user