Misc bug fixes
This commit is contained in:
parent
56b278a47f
commit
5bcb339dcc
|
@ -57,9 +57,11 @@ where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where blender
|
|||
|
||||
## Current TODO list
|
||||
|
||||
Doorway collision
|
||||
Implement collider bitmask
|
||||
Raycast through doorways
|
||||
Cylinder touching bug
|
||||
Create elevator geometry
|
||||
Allow player to press button
|
||||
Collide player with objects in scene
|
||||
Radio
|
||||
Create radio model
|
||||
Create radio texture
|
||||
|
|
Binary file not shown.
|
@ -70,6 +70,8 @@ std::shared_ptr<CollisionGeneratorOutput> generateCollision(const aiScene* scene
|
|||
for (unsigned i = 0; i < nodeInfo.node->mNumMeshes; ++i) {
|
||||
aiMesh* mesh = scene->mMeshes[nodeInfo.node->mMeshes[i]];
|
||||
|
||||
bool isTransparent = std::find(nodeInfo.arguments.begin(), nodeInfo.arguments.end(), "transparent") != nodeInfo.arguments.end();
|
||||
|
||||
CollisionQuad collider(mesh, globalTransform * nodeInfo.node->mTransformation);
|
||||
collidersChunk->Add(std::move(collider.Generate()));
|
||||
|
||||
|
@ -85,6 +87,9 @@ std::shared_ptr<CollisionGeneratorOutput> generateCollision(const aiScene* scene
|
|||
collisionObject->AddPrimitive(std::string("&" + colliderTypesName + "[" + std::to_string(meshCount) + "]"));
|
||||
collisionObject->AddPrimitive<const char*>("NULL");
|
||||
collisionObject->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(collider.BoundingBox())));
|
||||
collisionObject->AddPrimitive<const char*>(isTransparent ?
|
||||
"COLLISION_LAYERS_STATIC | COLLISION_LAYERS_TRANSPARENT | COLLISION_LAYERS_TANGIBLE" :
|
||||
"COLLISION_LAYERS_STATIC | COLLISION_LAYERS_TANGIBLE");
|
||||
collisionObjectChunk->Add(std::move(collisionObject));
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ struct DecorObject* decorObjectNew(struct DecorObjectDefinition* definition, str
|
|||
}
|
||||
|
||||
void decorObjectInit(struct DecorObject* object, struct DecorObjectDefinition* definition, struct Transform* at, int room) {
|
||||
collisionObjectInit(&object->collisionObject, &definition->colliderType, &object->rigidBody, definition->mass);
|
||||
collisionObjectInit(&object->collisionObject, &definition->colliderType, &object->rigidBody, definition->mass, COLLISION_LAYERS_TANGIBLE | COLLISION_LAYERS_GRABBABLE);
|
||||
collisionSceneAddDynamicObject(&object->collisionObject);
|
||||
|
||||
object->rigidBody.transform = *at;
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
#include "collision_scene.h"
|
||||
#include "../math/mathf.h"
|
||||
|
||||
void collisionObjectInit(struct CollisionObject* object, struct ColliderTypeData *collider, struct RigidBody* body, float mass) {
|
||||
void collisionObjectInit(struct CollisionObject* object, struct ColliderTypeData *collider, struct RigidBody* body, float mass, int collisionLayers) {
|
||||
object->collider = collider;
|
||||
object->body = body;
|
||||
rigidBodyInit(body, mass, collider->callbacks->mofICalculator(collider, mass));
|
||||
collisionObjectUpdateBB(object);
|
||||
object->collisionLayers = collisionLayers;
|
||||
}
|
||||
|
||||
int collisionObjectIsActive(struct CollisionObject* object) {
|
||||
|
@ -17,6 +18,10 @@ int collisionObjectIsActive(struct CollisionObject* object) {
|
|||
}
|
||||
|
||||
void collisionObjectCollideWithQuad(struct CollisionObject* object, struct CollisionObject* quadObject, struct ContactSolver* contactSolver) {
|
||||
if ((object->collisionLayers | quadObject->collisionLayers) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!box3DHasOverlap(&object->boundingBox, &quadObject->boundingBox)) {
|
||||
return;
|
||||
}
|
||||
|
@ -51,12 +56,8 @@ void collisionObjectCollideWithQuad(struct CollisionObject* object, struct Colli
|
|||
return;
|
||||
}
|
||||
|
||||
contact->friction = 0.5f;
|
||||
contact->restitution = 0.0f;
|
||||
|
||||
if (isnan(result.penetration) || isnan(result.contactA.x) || isnan(result.contactB.x) || isnan(result.normal.x)) {
|
||||
return;
|
||||
}
|
||||
contact->friction = MAX(object->collider->friction, quadObject->collider->friction);
|
||||
contact->restitution = MIN(object->collider->bounce, quadObject->collider->bounce);
|
||||
|
||||
transformPointInverseNoScale(&object->body->transform, &result.contactB, &result.contactB);
|
||||
contactInsert(contact, &result);
|
||||
|
|
|
@ -5,15 +5,21 @@
|
|||
#include "collision.h"
|
||||
#include "../math/box3d.h"
|
||||
|
||||
#define COLLISION_LAYERS_STATIC (1 << 0)
|
||||
#define COLLISION_LAYERS_TRANSPARENT (1 << 1)
|
||||
#define COLLISION_LAYERS_TANGIBLE (1 << 2)
|
||||
#define COLLISION_LAYERS_GRABBABLE (1 << 3)
|
||||
|
||||
struct CollisionObject {
|
||||
struct ColliderTypeData *collider;
|
||||
struct RigidBody* body;
|
||||
struct Box3D boundingBox;
|
||||
int collisionLayers;
|
||||
};
|
||||
|
||||
int collisionObjectIsActive(struct CollisionObject* object);
|
||||
|
||||
void collisionObjectInit(struct CollisionObject* object, struct ColliderTypeData *collider, struct RigidBody* body, float mass);
|
||||
void collisionObjectInit(struct CollisionObject* object, struct ColliderTypeData *collider, struct RigidBody* body, float mass, int collisionLayers);
|
||||
|
||||
void collisionObjectCollideWithQuad(struct CollisionObject* object, struct CollisionObject* quad, struct ContactSolver* contactSolver);
|
||||
void collisionObjectCollideTwoObjects(struct CollisionObject* a, struct CollisionObject* b, struct ContactSolver* contactSolver);
|
||||
|
|
|
@ -145,7 +145,13 @@ void collisionObjectQueryScene(struct CollisionObject* object, struct CollisionS
|
|||
for (int i = 0; i < quadCount; ++i) {
|
||||
localContact.contactCount = 0;
|
||||
|
||||
if (quadCollider(object->collider->data, &object->body->transform, scene->quads[colliderIndices[i]].collider->data, &localContact) &&
|
||||
struct CollisionObject* quadObject = &scene->quads[colliderIndices[i]];
|
||||
|
||||
if ((quadObject->collisionLayers & object->collisionLayers) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (quadCollider(object->collider->data, &object->body->transform, quadObject->collider->data, &localContact) &&
|
||||
collisionSceneFilterPortalContacts(&localContact)) {
|
||||
callback(data, &localContact);
|
||||
}
|
||||
|
@ -192,7 +198,7 @@ int collisionSceneIsPortalOpen() {
|
|||
return gCollisionScene.portalTransforms[0] != NULL && gCollisionScene.portalTransforms[1] != NULL;
|
||||
}
|
||||
|
||||
void collisionSceneRaycastRoom(struct CollisionScene* scene, struct Room* room, struct Ray* ray, struct RaycastHit* hit) {
|
||||
void collisionSceneRaycastRoom(struct CollisionScene* scene, struct Room* room, struct Ray* ray, int collisionLayers, struct RaycastHit* hit) {
|
||||
int currX = GRID_CELL_X(room, ray->origin.x);
|
||||
int currZ = GRID_CELL_Z(room, ray->origin.z);
|
||||
|
||||
|
@ -207,7 +213,13 @@ void collisionSceneRaycastRoom(struct CollisionScene* scene, struct Room* room,
|
|||
for (int i = range->min; i < range->max; ++i) {
|
||||
struct RaycastHit hitTest;
|
||||
|
||||
if (raycastQuad(&scene->quads[room->quadIndices[i]], ray, hit->distance, &hitTest) && hitTest.distance < hit->distance && vector3Dot(&hitTest.normal, &ray->dir) < 0.0f) {
|
||||
struct CollisionObject* collisionObject = &scene->quads[room->quadIndices[i]];
|
||||
|
||||
if ((collisionObject->collisionLayers & collisionLayers) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (raycastQuad(collisionObject, ray, hit->distance, &hitTest) && hitTest.distance < hit->distance && vector3Dot(&hitTest.normal, &ray->dir) < 0.0f) {
|
||||
hit->at = hitTest.at;
|
||||
hit->normal = hitTest.normal;
|
||||
hit->distance = hitTest.distance;
|
||||
|
@ -260,6 +272,10 @@ int collisionSceneRaycastDoorways(struct CollisionScene* scene, struct Room* roo
|
|||
|
||||
struct Doorway* doorway = &scene->world->doorways[room->doorwayIndices[i]];
|
||||
|
||||
if ((doorway->flags & DoorwayFlagsOpen) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (raycastQuadShape(&doorway->quad, ray, roomDistance, &hitTest) && hitTest.distance < roomDistance) {
|
||||
roomDistance = hitTest.distance;
|
||||
// check that the doorway wasn't hit from the wrong side
|
||||
|
@ -275,7 +291,7 @@ int collisionSceneRaycastDoorways(struct CollisionScene* scene, struct Room* roo
|
|||
return nextRoom;
|
||||
}
|
||||
|
||||
int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ray* ray, float maxDistance, int passThroughPortals, struct RaycastHit* hit) {
|
||||
int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ray* ray, int collisionLayers, float maxDistance, int passThroughPortals, struct RaycastHit* hit) {
|
||||
hit->distance = maxDistance;
|
||||
hit->throughPortal = NULL;
|
||||
|
||||
|
@ -283,7 +299,7 @@ int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ra
|
|||
|
||||
while (roomsToCheck && roomIndex != -1) {
|
||||
struct Room* room = &scene->world->rooms[roomIndex];
|
||||
collisionSceneRaycastRoom(scene, room, ray, hit);
|
||||
collisionSceneRaycastRoom(scene, room, ray, collisionLayers, hit);
|
||||
|
||||
if (hit->distance != maxDistance) {
|
||||
hit->roomIndex = roomIndex;
|
||||
|
@ -302,6 +318,10 @@ int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ra
|
|||
|
||||
struct CollisionObject* object = scene->dynamicObjects[i];
|
||||
|
||||
if ((object->collisionLayers & collisionLayers) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (object->collider->callbacks->raycast &&
|
||||
object->collider->callbacks->raycast(object, ray, hit->distance, &hitTest) &&
|
||||
hitTest.distance < hit->distance) {
|
||||
|
@ -328,7 +348,7 @@ int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ra
|
|||
|
||||
struct RaycastHit newHit;
|
||||
|
||||
int result = collisionSceneRaycast(scene, gCollisionScene.portalRooms[1 - i], &newRay, maxDistance - hit->distance, 0, &newHit);
|
||||
int result = collisionSceneRaycast(scene, gCollisionScene.portalRooms[1 - i], &newRay, collisionLayers, maxDistance - hit->distance, 0, &newHit);
|
||||
|
||||
if (result) {
|
||||
newHit.distance += hit->distance;
|
||||
|
@ -466,6 +486,10 @@ void collisionSceneWalkBroadphase(struct CollisionScene* collisionScene, struct
|
|||
for (int objectIndex = 0; objectIndex < broadphase->objectInRangeCount; ++objectIndex) {
|
||||
struct CollisionObject* existing = broadphase->objectsInCurrentRange[objectIndex];
|
||||
|
||||
if ((existing->collisionLayers & subject->collisionLayers) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!collisionObjectIsActive(existing) && !collisionObjectIsActive(subject)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ int collisionSceneIsPortalOpen();
|
|||
|
||||
void collisionObjectQueryScene(struct CollisionObject* object, struct CollisionScene* scene, void* data, ManifoldCallback callback);
|
||||
|
||||
int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ray* ray, float maxDistance, int passThroughPortals, struct RaycastHit* hit);
|
||||
int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ray* ray, int collisionLayers, float maxDistance, int passThroughPortals, struct RaycastHit* hit);
|
||||
|
||||
void collisionSceneGetPortalTransform(int fromPortal, struct Transform* out);
|
||||
|
||||
|
|
|
@ -103,6 +103,53 @@ void contactSolverRemoveUnusedContacts(struct ContactSolver* contactSolver) {
|
|||
}
|
||||
}
|
||||
|
||||
void contactSolverCheckPortalManifoldContacts(struct ContactManifold* manifold) {
|
||||
int writeIndex = 0;
|
||||
|
||||
for (int readIndex = 0; readIndex < manifold->contactCount; ++readIndex) {
|
||||
struct ContactPoint* contactPoint = &manifold->contacts[readIndex];
|
||||
|
||||
if (collisionSceneIsTouchingPortal(&contactPoint->contactAWorld, &manifold->normal)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (readIndex != writeIndex) {
|
||||
manifold->contacts[writeIndex] = *contactPoint;
|
||||
}
|
||||
|
||||
++writeIndex;
|
||||
}
|
||||
|
||||
manifold->contactCount = writeIndex;
|
||||
}
|
||||
|
||||
void contactSolverCheckPortalContacts(struct ContactSolver* contactSolver, struct CollisionObject* objectWithNewPortal) {
|
||||
struct ContactManifold* curr = contactSolver->activeContacts;
|
||||
struct ContactManifold* prev = NULL;
|
||||
|
||||
while (curr) {
|
||||
if (curr->shapeA == objectWithNewPortal) {
|
||||
contactSolverCheckPortalManifoldContacts(curr);
|
||||
}
|
||||
|
||||
if (curr->contactCount == 0) {
|
||||
if (prev) {
|
||||
prev->next = curr->next;
|
||||
} else {
|
||||
contactSolver->activeContacts = curr->next;
|
||||
}
|
||||
|
||||
struct ContactManifold* next = curr->next;
|
||||
curr->next = contactSolver->unusedContacts;
|
||||
contactSolver->unusedContacts = curr;
|
||||
curr = next;
|
||||
} else {
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void contactSolverInit(struct ContactSolver* contactSolver) {
|
||||
int solverSize = sizeof(struct ContactSolver);
|
||||
memset(contactSolver, 0, solverSize);
|
||||
|
|
|
@ -63,6 +63,7 @@ struct ContactManifold* contactSolverGetContactManifold(struct ContactSolver* so
|
|||
struct ContactManifold* contactSolverNextManifold(struct ContactSolver* solver, struct CollisionObject* forObject, struct ContactManifold* current);
|
||||
|
||||
void contactSolverRemoveUnusedContacts(struct ContactSolver* contactSolver);
|
||||
void contactSolverCheckPortalContacts(struct ContactSolver* contactSolver, struct CollisionObject* objectWithNewPortal);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ struct ColliderTypeData gPlayerColliderData = {
|
|||
};
|
||||
|
||||
void playerInit(struct Player* player, struct Location* startLocation) {
|
||||
collisionObjectInit(&player->collisionObject, &gPlayerColliderData, &player->body, 1.0f);
|
||||
collisionObjectInit(&player->collisionObject, &gPlayerColliderData, &player->body, 1.0f, COLLISION_LAYERS_TANGIBLE);
|
||||
player->grabbingThroughPortal = PLAYER_GRABBING_THROUGH_NOTHING;
|
||||
player->grabbing = NULL;
|
||||
player->pitchVelocity = 0.0f;
|
||||
|
@ -91,7 +91,7 @@ void playerUpdateGrabbedObject(struct Player* player) {
|
|||
|
||||
struct RaycastHit hit;
|
||||
|
||||
if (collisionSceneRaycast(&gCollisionScene, player->body.currentRoom, &ray, GRAB_RAYCAST_DISTANCE, 1, &hit) && hit.object->body && (hit.object->body->flags & RigidBodyFlagsGrabbable)) {
|
||||
if (collisionSceneRaycast(&gCollisionScene, player->body.currentRoom, &ray, COLLISION_LAYERS_GRABBABLE | COLLISION_LAYERS_TANGIBLE, GRAB_RAYCAST_DISTANCE, 1, &hit) && hit.object->body && (hit.object->body->flags & RigidBodyFlagsGrabbable)) {
|
||||
player->grabbing = hit.object->body;
|
||||
|
||||
if (hit.throughPortal) {
|
||||
|
@ -229,7 +229,7 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
|||
struct Ray ray;
|
||||
ray.origin = player->body.transform.position;
|
||||
vector3Scale(&gUp, &ray.dir, -1.0f);
|
||||
if (collisionSceneRaycast(&gCollisionScene, player->body.currentRoom, &ray, PLAYER_HEAD_HEIGHT, 1, &hit)) {
|
||||
if (collisionSceneRaycast(&gCollisionScene, player->body.currentRoom, &ray, COLLISION_LAYERS_TANGIBLE, PLAYER_HEAD_HEIGHT, 1, &hit)) {
|
||||
vector3AddScaled(&hit.at, &gUp, PLAYER_HEAD_HEIGHT, &player->body.transform.position);
|
||||
|
||||
player->body.velocity.y = 0.0f;
|
||||
|
|
|
@ -54,7 +54,7 @@ void buttonRender(void* data, struct RenderScene* renderScene) {
|
|||
}
|
||||
|
||||
void buttonInit(struct Button* button, struct ButtonDefinition* definition) {
|
||||
collisionObjectInit(&button->collisionObject, &gButtonCollider, &button->rigidBody, 1.0f);
|
||||
collisionObjectInit(&button->collisionObject, &gButtonCollider, &button->rigidBody, 1.0f, COLLISION_LAYERS_TANGIBLE);
|
||||
rigitBodyMarkKinematic(&button->rigidBody);
|
||||
collisionSceneAddDynamicObject(&button->collisionObject);
|
||||
|
||||
|
|
|
@ -11,45 +11,6 @@ struct CollisionBox gCubeCollisionBox = {
|
|||
{0.3165f, 0.3165f, 0.3165f}
|
||||
};
|
||||
|
||||
struct Plane gFloor = {{0.0f, 1.0f, 0.0f}, 0.0f};
|
||||
|
||||
struct ColliderTypeData gFloorColliderType = {
|
||||
CollisionShapeTypeQuad,
|
||||
&gFloor,
|
||||
0.0f,
|
||||
1.0f,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct CollisionObject gFloorObject = {
|
||||
&gFloorColliderType,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct CollisionQuad gFloatingQuad = {
|
||||
{-1.0f, 0.0f, 0.0f},
|
||||
{1.0f, 0.0f, 0.0f},
|
||||
2.0f,
|
||||
{0.0f, 1.0f, 0.0f},
|
||||
2.0f,
|
||||
{{0.0f, 0.0f, -1.0}, 0.0f},
|
||||
0xF,
|
||||
};
|
||||
|
||||
struct ColliderTypeData gFloatingQuadCollider = {
|
||||
CollisionShapeTypeQuad,
|
||||
&gFloatingQuad,
|
||||
0.0f,
|
||||
1.0f,
|
||||
NULL,
|
||||
} ;
|
||||
|
||||
|
||||
struct CollisionObject gFloatingQuadObject = {
|
||||
&gFloatingQuadCollider,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct ColliderTypeData gCubeCollider = {
|
||||
CollisionShapeTypeBox,
|
||||
&gCubeCollisionBox,
|
||||
|
@ -67,7 +28,7 @@ void cubeRender(void* data, struct RenderScene* renderScene) {
|
|||
}
|
||||
|
||||
void cubeInit(struct Cube* cube) {
|
||||
collisionObjectInit(&cube->collisionObject, &gCubeCollider, &cube->rigidBody, 2.0f);
|
||||
collisionObjectInit(&cube->collisionObject, &gCubeCollider, &cube->rigidBody, 2.0f, COLLISION_LAYERS_TANGIBLE | COLLISION_LAYERS_GRABBABLE);
|
||||
collisionSceneAddDynamicObject(&cube->collisionObject);
|
||||
|
||||
cube->collisionObject.body->flags |= RigidBodyFlagsGrabbable;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "signals.h"
|
||||
#include "../math/mathf.h"
|
||||
#include "../util/time.h"
|
||||
#include "../physics/collision_box.h"
|
||||
#include "../physics/collision_scene.h"
|
||||
|
||||
#include "../build/assets/models/props/door_01.h"
|
||||
|
||||
|
@ -14,10 +16,27 @@
|
|||
|
||||
#define OPEN_WIDTH 0.625
|
||||
|
||||
struct CollisionBox gDoorCollisionBox = {
|
||||
{1.0f, 1.0f, 0.1125f}
|
||||
};
|
||||
|
||||
struct ColliderTypeData gDoorCollider = {
|
||||
CollisionShapeTypeBox,
|
||||
&gDoorCollisionBox,
|
||||
0.0f,
|
||||
0.5f,
|
||||
&gCollisionBoxCallbacks,
|
||||
};
|
||||
|
||||
void doorRender(void* data, struct RenderScene* renderScene) {
|
||||
struct Door* door = (struct Door*)data;
|
||||
Mtx* matrix = renderStateRequestMatrices(renderScene->renderState, 1);
|
||||
transformToMatrixL(&door->rigidBody.transform, matrix, SCENE_SCALE);
|
||||
struct Transform originalTransform;
|
||||
originalTransform.position = door->doorDefinition->location;
|
||||
originalTransform.rotation = door->doorDefinition->rotation;
|
||||
originalTransform.scale = gOneVec;
|
||||
|
||||
transformToMatrixL(&originalTransform, matrix, SCENE_SCALE);
|
||||
|
||||
props_door_01_default_bones[PROPS_DOOR_01_DOORL_BONE].position.x = door->openAmount * -0.625f * SCENE_SCALE;
|
||||
props_door_01_default_bones[PROPS_DOOR_01_DOORR_BONE].position.x = door->openAmount * 0.625f * SCENE_SCALE;
|
||||
|
@ -31,15 +50,17 @@ void doorRender(void* data, struct RenderScene* renderScene) {
|
|||
}
|
||||
|
||||
void doorInit(struct Door* door, struct DoorDefinition* doorDefinition, struct World* world) {
|
||||
// collisionObjectInit(&cube->collisionObject, &gCubeCollider, &cube->rigidBody, 1.0f);
|
||||
// collisionSceneAddDynamicObject(&cube->collisionObject);
|
||||
|
||||
// cube->collisionObject.body->flags |= RigidBodyFlagsGrabbable;
|
||||
collisionObjectInit(&door->collisionObject, &gDoorCollider, &door->rigidBody, 1.0f, COLLISION_LAYERS_TANGIBLE);
|
||||
rigitBodyMarkKinematic(&door->rigidBody);
|
||||
collisionSceneAddDynamicObject(&door->collisionObject);
|
||||
|
||||
door->rigidBody.transform.position = doorDefinition->location;
|
||||
door->rigidBody.transform.position.y += 1.0f;
|
||||
door->rigidBody.transform.rotation = doorDefinition->rotation;
|
||||
door->rigidBody.transform.scale = gOneVec;
|
||||
|
||||
collisionObjectUpdateBB(&door->collisionObject);
|
||||
|
||||
door->dynamicId = dynamicSceneAdd(door, doorRender, &door->rigidBody.transform, 1.7f);
|
||||
door->signalIndex = doorDefinition->signalIndex;
|
||||
door->openAmount = 0.0f;
|
||||
|
@ -50,6 +71,8 @@ void doorInit(struct Door* door, struct DoorDefinition* doorDefinition, struct W
|
|||
} else {
|
||||
door->forDoorway = NULL;
|
||||
}
|
||||
|
||||
door->doorDefinition = doorDefinition;
|
||||
}
|
||||
|
||||
void doorUpdate(struct Door* door) {
|
||||
|
@ -59,8 +82,10 @@ void doorUpdate(struct Door* door) {
|
|||
if (door->forDoorway) {
|
||||
if (door->openAmount == 0.0f) {
|
||||
door->forDoorway->flags &= ~DoorwayFlagsOpen;
|
||||
door->collisionObject.collisionLayers = COLLISION_LAYERS_TANGIBLE;
|
||||
} else {
|
||||
door->forDoorway->flags |= DoorwayFlagsOpen;
|
||||
door->collisionObject.collisionLayers = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ struct Door {
|
|||
struct CollisionObject collisionObject;
|
||||
struct RigidBody rigidBody;
|
||||
struct Doorway* forDoorway;
|
||||
struct DoorDefinition* doorDefinition;
|
||||
short dynamicId;
|
||||
short signalIndex;
|
||||
float openAmount;
|
||||
|
|
|
@ -224,10 +224,29 @@ void sceneUpdate(struct Scene* scene) {
|
|||
scene->lastFrameStart = frameStart;
|
||||
}
|
||||
|
||||
int sceneOpenPortal(struct Scene* scene, struct Transform* at, int portalIndex, int quadIndex, int roomIndex) {
|
||||
struct PortalSurfaceMapping surfaceMapping = gCurrentLevel->portalSurfaceMapping[quadIndex];
|
||||
|
||||
for (int i = surfaceMapping.minPortalIndex; i < surfaceMapping.maxPortalIndex; ++i) {
|
||||
if (portalSurfaceGenerate(&gCurrentLevel->portalSurfaces[i], at, NULL, NULL)) {
|
||||
soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f);
|
||||
|
||||
scene->portals[portalIndex].transform = *at;
|
||||
gCollisionScene.portalTransforms[portalIndex] = &scene->portals[portalIndex].transform;
|
||||
gCollisionScene.portalRooms[portalIndex] = roomIndex;
|
||||
|
||||
contactSolverCheckPortalContacts(&gContactSolver, &gCurrentLevel->collisionQuads[quadIndex]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* playerUp, int portalIndex, int roomIndex) {
|
||||
struct RaycastHit hit;
|
||||
|
||||
if (!collisionSceneRaycast(&gCollisionScene, roomIndex, ray, 1000000.0f, 0, &hit)) {
|
||||
if (!collisionSceneRaycast(&gCollisionScene, roomIndex, ray, COLLISION_LAYERS_STATIC, 1000000.0f, 0, &hit)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -254,21 +273,4 @@ int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* player
|
|||
}
|
||||
|
||||
return sceneOpenPortal(scene, &portalLocation, portalIndex, quadIndex, hit.roomIndex);
|
||||
}
|
||||
|
||||
int sceneOpenPortal(struct Scene* scene, struct Transform* at, int portalIndex, int quadIndex, int roomIndex) {
|
||||
struct PortalSurfaceMapping surfaceMapping = gCurrentLevel->portalSurfaceMapping[quadIndex];
|
||||
|
||||
for (int i = surfaceMapping.minPortalIndex; i < surfaceMapping.maxPortalIndex; ++i) {
|
||||
if (portalSurfaceGenerate(&gCurrentLevel->portalSurfaces[i], at, NULL, NULL)) {
|
||||
soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f);
|
||||
|
||||
scene->portals[portalIndex].transform = *at;
|
||||
gCollisionScene.portalTransforms[portalIndex] = &scene->portals[portalIndex].transform;
|
||||
gCollisionScene.portalRooms[portalIndex] = roomIndex;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -40,6 +40,5 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
|
|||
void sceneUpdate(struct Scene* scene);
|
||||
|
||||
int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* playerUp, int portalIndex, int roomIndex);
|
||||
int sceneOpenPortal(struct Scene* scene, struct Transform* at, int portalIndex, int quadIndex, int roomIndex);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue