diff --git a/Makefile b/Makefile index e9be1e5..e746b30 100644 --- a/Makefile +++ b/Makefile @@ -140,7 +140,10 @@ src/levels/level_def_gen.h: build/assets/materials/static.h build/src/scene/hud.o: build/assets/materials/hud.h -build/src/scene/elevator.o: build/assets/models/props/round_elevator_collision.h +build/src/scene/elevator.o: build/assets/models/props/round_elevator_collision.h \ + build/assets/models/props/round_elevator.h \ + build/assets/models/props/round_elevator_interior.h \ + build/assets/materials/static.h #################### ## Models @@ -156,6 +159,7 @@ MODEL_LIST = assets/models/cube/cube.blend \ assets/models/props/cylinder_test.blend \ assets/models/props/radio.blend \ assets/models/props/round_elevator.blend \ + assets/models/props/round_elevator_interior.blend \ assets/models/props/round_elevator_collision.blend MODEL_HEADERS = $(MODEL_LIST:%.blend=build/%.h) diff --git a/assets/models/props/round_elevator.blend b/assets/models/props/round_elevator.blend index 656dfb8..9f2c567 100644 Binary files a/assets/models/props/round_elevator.blend and b/assets/models/props/round_elevator.blend differ diff --git a/assets/models/props/round_elevator.flags b/assets/models/props/round_elevator.flags index 175f6f4..8c42a56 100644 --- a/assets/models/props/round_elevator.flags +++ b/assets/models/props/round_elevator.flags @@ -1 +1 @@ --r 0,0,0 -m assets/materials/static.skm.yaml -m assets/materials/elevator.skm.yaml -D default \ No newline at end of file +-r 90,0,0 -m assets/materials/static.skm.yaml -m assets/materials/elevator.skm.yaml -D default \ No newline at end of file diff --git a/assets/models/props/round_elevator_collision.blend b/assets/models/props/round_elevator_collision.blend index c42ddbc..739feb8 100644 Binary files a/assets/models/props/round_elevator_collision.blend and b/assets/models/props/round_elevator_collision.blend differ diff --git a/assets/models/props/round_elevator_interior.blend b/assets/models/props/round_elevator_interior.blend new file mode 100644 index 0000000..3cc33bb Binary files /dev/null and b/assets/models/props/round_elevator_interior.blend differ diff --git a/assets/models/props/round_elevator_interior.flags b/assets/models/props/round_elevator_interior.flags new file mode 100644 index 0000000..175f6f4 --- /dev/null +++ b/assets/models/props/round_elevator_interior.flags @@ -0,0 +1 @@ +-r 0,0,0 -m assets/materials/static.skm.yaml -m assets/materials/elevator.skm.yaml -D default \ No newline at end of file diff --git a/assets/test_chambers/test_chamber_00/test_chamber_00_0.blend b/assets/test_chambers/test_chamber_00/test_chamber_00_0.blend index 5b5c43d..089baa1 100644 Binary files a/assets/test_chambers/test_chamber_00/test_chamber_00_0.blend and b/assets/test_chambers/test_chamber_00/test_chamber_00_0.blend differ diff --git a/src/levels/static_render.c b/src/levels/static_render.c index 7b721ee..a7d329d 100644 --- a/src/levels/static_render.c +++ b/src/levels/static_render.c @@ -39,6 +39,10 @@ void staticRenderPopulateRooms(struct FrustrumCullingInformation* cullingInfo, s #define FORCE_RENDER_DOORWAY_DISTANCE 0.1f void staticRenderDetermineVisibleRooms(struct FrustrumCullingInformation* cullingInfo, u16 currentRoom, u64* visitedRooms) { + if (currentRoom == RIGID_BODY_NO_ROOM) { + return; + } + u64 roomMask = 1LL << currentRoom; if (*visitedRooms & roomMask) { diff --git a/src/models/models.c b/src/models/models.c index 389d7a8..abae923 100644 --- a/src/models/models.c +++ b/src/models/models.c @@ -10,7 +10,6 @@ #include "../../build/assets/models/props/button.h" #include "../../build/assets/models/props/door_01.h" #include "../../build/assets/models/props/cylinder_test.h" -#include "../../build/assets/models/props/round_elevator.h" Gfx* v_portal_gun_gfx = &portal_gun_v_portalgun_model_gfx[0]; @@ -23,7 +22,4 @@ short door_01_material_index = DOOR_01_INDEX; Gfx* cylinder_gfx = &props_cylinder_test_model_gfx[0]; short cylinder_material_index = PLASTIC_PLASTICWALL001A_INDEX; -short fizzler_material_index = PORTAL_CLEANSER_INDEX; - -Gfx* elevator_gfx = &props_round_elevator_model_gfx[0]; -short elevator_material_index = DEFAULT_INDEX; \ No newline at end of file +short fizzler_material_index = PORTAL_CLEANSER_INDEX; \ No newline at end of file diff --git a/src/models/models.h b/src/models/models.h index 14c8c0f..c27255c 100644 --- a/src/models/models.h +++ b/src/models/models.h @@ -21,7 +21,4 @@ extern short cylinder_material_index; extern short fizzler_material_index; -extern Gfx* elevator_gfx; -extern short elevator_material_index; - #endif \ No newline at end of file diff --git a/src/physics/rigid_body.h b/src/physics/rigid_body.h index c1dda08..008a498 100644 --- a/src/physics/rigid_body.h +++ b/src/physics/rigid_body.h @@ -5,6 +5,8 @@ #include "../math/transform.h" #include "./collision.h" +#define RIGID_BODY_NO_ROOM 0xFFFF + enum RigidBodyFlags { RigidBodyFlagsInFrontPortal0 = (1 << 0), RigidBodyFlagsInFrontPortal1 = (1 << 1), @@ -43,7 +45,7 @@ struct RigidBody { float momentOfInertiaInv; enum RigidBodyFlags flags; - short currentRoom; + unsigned short currentRoom; }; void rigidBodyInit(struct RigidBody* rigidBody, float mass, float momentOfIniteria); diff --git a/src/physics/world.c b/src/physics/world.c index 7cc204c..a60ac9e 100644 --- a/src/physics/world.c +++ b/src/physics/world.c @@ -1,6 +1,10 @@ #include "world.h" int worldCheckDoorwaySides(struct World* world, struct Vector3* position, int currentRoom) { + if (currentRoom == -1) { + return 0; + } + struct Room* room = &world->rooms[currentRoom]; int sideMask = 0; @@ -15,6 +19,10 @@ int worldCheckDoorwaySides(struct World* world, struct Vector3* position, int cu } int worldCheckDoorwayCrossings(struct World* world, struct Vector3* position, int currentRoom, int sideMask) { + if (currentRoom == RIGID_BODY_NO_ROOM) { + return RIGID_BODY_NO_ROOM; + } + struct Room* room = &world->rooms[currentRoom]; for (int i = 0; i < room->doorwayCount; ++i) { diff --git a/src/scene/elevator.c b/src/scene/elevator.c index 1e19e9b..e57c802 100644 --- a/src/scene/elevator.c +++ b/src/scene/elevator.c @@ -1,10 +1,17 @@ #include "elevator.h" #include "../physics/collision_scene.h" #include "../scene/dynamic_scene.h" -#include "../models/models.h" #include "../physics/mesh_collider.h" #include "../../build/assets/models/props/round_elevator_collision.h" +#include "../../build/assets/models/props/round_elevator_interior.h" +#include "../../build/assets/models/props/round_elevator.h" + +#include "../../build/assets/materials/static.h" + +#define AUTO_OPEN_DISTANCE 4.0f + +#define INSIDE_DISTANCE 1.0f struct ColliderTypeData gElevatorColliderType = { CollisionShapeTypeMesh, @@ -13,23 +20,48 @@ struct ColliderTypeData gElevatorColliderType = { &gMeshColliderCallbacks }; +int gElevatorCollisionLayers = COLLISION_LAYERS_STATIC | COLLISION_LAYERS_TANGIBLE; + +struct Vector3 gOpenPosition = { + -0.275674, + 0.0f, + -0.653916, +}; + void elevatorRender(void* data, struct RenderScene* renderScene) { struct Elevator* elevator = (struct Elevator*)data; Mtx* matrix = renderStateRequestMatrices(renderScene->renderState, 1); transformToMatrixL(&elevator->rigidBody.transform, matrix, SCENE_SCALE); + Mtx* armature = renderStateRequestMatrices(renderScene->renderState, PROPS_ROUND_ELEVATOR_DEFAULT_BONES_COUNT); + + for (int i = 0; i < PROPS_ROUND_ELEVATOR_DEFAULT_BONES_COUNT; ++i) { + transformToMatrixL(&props_round_elevator_default_bones[i], &armature[i], 1.0f); + } + renderSceneAdd( renderScene, - elevator_gfx, + props_round_elevator_model_gfx, matrix, - elevator_material_index, + DEFAULT_INDEX, &elevator->rigidBody.transform.position, - NULL + armature ); + + if (elevator->flags & (ElevatorFlagsIsOpen | ElevatorFlagsContainsPlayer)) { + renderSceneAdd( + renderScene, + props_round_elevator_interior_model_gfx, + matrix, + DEFAULT_INDEX, + &elevator->rigidBody.transform.position, + NULL + ); + } } void elevatorInit(struct Elevator* elevator) { - collisionObjectInit(&elevator->collisionObject, &gElevatorColliderType, &elevator->rigidBody, 1.0f, COLLISION_LAYERS_STATIC | COLLISION_LAYERS_TANGIBLE); + collisionObjectInit(&elevator->collisionObject, &gElevatorColliderType, &elevator->rigidBody, 1.0f, gElevatorCollisionLayers); rigidBodyMarkKinematic(&elevator->rigidBody); collisionSceneAddDynamicObject(&elevator->collisionObject); @@ -39,8 +71,35 @@ void elevatorInit(struct Elevator* elevator) { collisionObjectUpdateBB(&elevator->collisionObject); elevator->dynamicId = dynamicSceneAdd(elevator, elevatorRender, &elevator->rigidBody.transform, 3.9f); + elevator->flags = 0; } -void elevatorUpdate(struct Elevator* elevator) { +void elevatorUpdate(struct Elevator* elevator, struct Player* player) { + struct Vector3 offset; + vector3Sub(&elevator->rigidBody.transform.position, &player->lookTransform.position, &offset); + offset.y = 0.0f; + float horizontalDistance = vector3MagSqrd(&offset); + + int inRange = horizontalDistance < AUTO_OPEN_DISTANCE * AUTO_OPEN_DISTANCE; + int inside = horizontalDistance < INSIDE_DISTANCE * INSIDE_DISTANCE; + + if (inside) { + elevator->flags |= ElevatorFlagsContainsPlayer; + player->body.currentRoom = RIGID_BODY_NO_ROOM; + } + + int shouldBeOpen = inRange && (elevator->flags & ElevatorFlagsContainsPlayer) == 0; + + if (shouldBeOpen) { + props_round_elevator_collision_collider.children[PROPS_ROUND_ELEVATOR_COLLISION_DOOR_RIGHT_COLLISION_INDEX].collisionLayers = 0; + props_round_elevator_collision_collider.children[PROPS_ROUND_ELEVATOR_COLLISION_DOOR_LEFT_COLLISION_INDEX].collisionLayers = 0; + + elevator->flags |= ElevatorFlagsIsOpen; + } else { + props_round_elevator_collision_collider.children[PROPS_ROUND_ELEVATOR_COLLISION_DOOR_RIGHT_COLLISION_INDEX].collisionLayers = gElevatorCollisionLayers; + props_round_elevator_collision_collider.children[PROPS_ROUND_ELEVATOR_COLLISION_DOOR_LEFT_COLLISION_INDEX].collisionLayers = gElevatorCollisionLayers; + + elevator->flags &= ~ElevatorFlagsIsOpen; + } } \ No newline at end of file diff --git a/src/scene/elevator.h b/src/scene/elevator.h index b1b265f..ad17654 100644 --- a/src/scene/elevator.h +++ b/src/scene/elevator.h @@ -3,15 +3,22 @@ #include "../math/transform.h" #include "../physics/collision_object.h" +#include "../player/player.h" + +enum ElevatorFlags { + ElevatorFlagsIsOpen = (1 << 0), + ElevatorFlagsContainsPlayer = (1 << 1), +}; struct Elevator { struct CollisionObject collisionObject; struct RigidBody rigidBody; short dynamicId; + short flags; }; void elevatorInit(struct Elevator* elevator); -void elevatorUpdate(struct Elevator* elevator); +void elevatorUpdate(struct Elevator* elevator, struct Player* player); #endif \ No newline at end of file diff --git a/src/scene/scene.c b/src/scene/scene.c index 84e3bc4..260d019 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -258,7 +258,7 @@ void sceneUpdate(struct Scene* scene) { } for (int i = 0; i < scene->elevatorCount; ++i) { - elevatorUpdate(&scene->elevators[i]); + elevatorUpdate(&scene->elevators[i], &scene->player); } collisionSceneUpdateDynamics();