Player can walk through portals
This commit is contained in:
parent
734401c321
commit
b64ba2b9b7
|
@ -25,7 +25,7 @@ void collisionObjectCollideWithPlane(struct CollisionObject* object, struct Coll
|
|||
return;
|
||||
}
|
||||
|
||||
contactSolverAssign(contact, &localContact);
|
||||
contactSolverAssign(contact, &localContact, 1);
|
||||
} else if (contact) {
|
||||
contactSolverRemoveContact(contactSolver, contact);
|
||||
}
|
||||
|
@ -44,12 +44,11 @@ void collisionObjectCollideWithQuad(struct CollisionObject* object, struct Colli
|
|||
struct ContactConstraintState* contact = contactSolverPeekContact(contactSolver, quad, object);
|
||||
|
||||
if (quadCollider(object->collider->data, &object->body->transform, quad->collider->data, &localContact)) {
|
||||
|
||||
if (!contact) {
|
||||
return;
|
||||
}
|
||||
|
||||
contactSolverAssign(contact, &localContact);
|
||||
contactSolverAssign(contact, &localContact, 1);
|
||||
} else if (contact) {
|
||||
contactSolverRemoveContact(contactSolver, contact);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "collision_scene.h"
|
||||
|
||||
#include "math/mathf.h"
|
||||
|
||||
struct CollisionScene gCollisionScene;
|
||||
|
||||
void collisionSceneInit(struct CollisionScene* scene, struct CollisionObject* quads, int quadCount) {
|
||||
|
@ -13,6 +15,26 @@ void collisionObjectCollideWithScene(struct CollisionObject* object, struct Coll
|
|||
}
|
||||
}
|
||||
|
||||
int collisionSceneFilterPortalContacts(struct ContactConstraintState* contact) {
|
||||
int writeIndex = 0;
|
||||
|
||||
for (int readIndex = 0; readIndex < contact->contactCount; ++readIndex) {
|
||||
if (collisionSceneIsTouchingPortal(&contact->contacts[readIndex].ra)) {
|
||||
continue;;
|
||||
}
|
||||
|
||||
if (readIndex != writeIndex) {
|
||||
contact->contacts[writeIndex] = contact->contacts[readIndex];
|
||||
}
|
||||
|
||||
++writeIndex;
|
||||
}
|
||||
|
||||
contact->contactCount = writeIndex;
|
||||
|
||||
return writeIndex;
|
||||
}
|
||||
|
||||
void collisionObjectQueryScene(struct CollisionObject* object, struct CollisionScene* scene, void* data, ManifoldCallback callback) {
|
||||
CollideWithQuad quadCollider = object->collider->callbacks->collideWithQuad;
|
||||
|
||||
|
@ -25,8 +47,32 @@ void collisionObjectQueryScene(struct CollisionObject* object, struct CollisionS
|
|||
for (int i = 0; i < scene->quadCount; ++i) {
|
||||
localContact.contactCount = 0;
|
||||
|
||||
if (quadCollider(object->collider->data, &object->body->transform, scene->quads[i].collider->data, &localContact)) {
|
||||
if (quadCollider(object->collider->data, &object->body->transform, scene->quads[i].collider->data, &localContact) &&
|
||||
collisionSceneFilterPortalContacts(&localContact)) {
|
||||
callback(data, &localContact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int collisionSceneIsTouchingPortal(struct Vector3* contactPoint) {
|
||||
if (!gCollisionScene.portalTransforms[0] || !gCollisionScene.portalTransforms[1]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
struct Vector3 localPoint;
|
||||
transformPointInverse(gCollisionScene.portalTransforms[i], contactPoint, &localPoint);
|
||||
|
||||
if (fabsf(localPoint.z) > PORTAL_THICKNESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
localPoint.x *= 2.0f;
|
||||
|
||||
if (vector3MagSqrd(&localPoint) < 1.0f) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -3,9 +3,12 @@
|
|||
|
||||
#include "collision_object.h"
|
||||
|
||||
#define PORTAL_THICKNESS 0.11f
|
||||
|
||||
struct CollisionScene {
|
||||
struct CollisionObject* quads;
|
||||
int quadCount;
|
||||
struct Transform* portalTransforms[0];
|
||||
};
|
||||
|
||||
typedef void (*ManifoldCallback)(void* data, struct ContactConstraintState* contact);
|
||||
|
@ -15,6 +18,8 @@ extern struct CollisionScene gCollisionScene;
|
|||
void collisionSceneInit(struct CollisionScene* scene, struct CollisionObject* quads, int quadCount);
|
||||
void collisionObjectCollideWithScene(struct CollisionObject* object, struct CollisionScene* scene, struct ContactSolver* contactSolver);
|
||||
|
||||
int collisionSceneIsTouchingPortal(struct Vector3* contactPoint);
|
||||
|
||||
void collisionObjectQueryScene(struct CollisionObject* object, struct CollisionScene* scene, void* data, ManifoldCallback callback);
|
||||
|
||||
#endif
|
|
@ -4,6 +4,7 @@
|
|||
#include "../math/mathf.h"
|
||||
#include "rigid_body.h"
|
||||
#include "collision_object.h"
|
||||
#include "collision_scene.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -378,7 +379,7 @@ struct ContactState* contactSolverGetContact(struct ContactConstraintState* cont
|
|||
return result;
|
||||
}
|
||||
|
||||
void contactSolverAssign(struct ContactConstraintState* into, struct ContactConstraintState* from) {
|
||||
void contactSolverAssign(struct ContactConstraintState* into, struct ContactConstraintState* from, int filterPortalContacts) {
|
||||
for (int sourceIndex = 0; sourceIndex < from->contactCount; ++sourceIndex) {
|
||||
int targetIndex;
|
||||
|
||||
|
@ -397,11 +398,18 @@ void contactSolverAssign(struct ContactConstraintState* into, struct ContactCons
|
|||
}
|
||||
}
|
||||
|
||||
int copiedCount = 0;
|
||||
|
||||
for (int sourceIndex = 0; sourceIndex < from->contactCount; ++sourceIndex) {
|
||||
into->contacts[sourceIndex] = from->contacts[sourceIndex];
|
||||
if (filterPortalContacts && collisionSceneIsTouchingPortal(&from->contacts[sourceIndex].ra)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
into->contacts[copiedCount] = from->contacts[sourceIndex];
|
||||
++copiedCount;
|
||||
}
|
||||
|
||||
into->contactCount = from->contactCount;
|
||||
into->contactCount = copiedCount;
|
||||
into->tangentVectors[0] = from->tangentVectors[0];
|
||||
into->tangentVectors[1] = from->tangentVectors[1];
|
||||
into->normal = from->normal;
|
||||
|
|
|
@ -62,7 +62,7 @@ void contactSolverRemoveContact(struct ContactSolver* solver, struct ContactCons
|
|||
|
||||
struct ContactState* contactSolverGetContact(struct ContactConstraintState* contact, int id);
|
||||
|
||||
void contactSolverAssign(struct ContactConstraintState* into, struct ContactConstraintState* from);
|
||||
void contactSolverAssign(struct ContactConstraintState* into, struct ContactConstraintState* from, int filterPortalContacts);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "physics/collision_scene.h"
|
||||
|
||||
struct Vector3 gGrabDistance = {0.0f, 0.0f, -2.5f};
|
||||
struct Vector3 gCameraOffset = {0.0f, 1.2f, 0.0f};
|
||||
struct Vector3 gCameraOffset = {0.0f, 0.0f, 0.0f};
|
||||
|
||||
struct CollisionSphere gPlayerCollider = {
|
||||
0.25f,
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
#include "../physics/point_constraint.h"
|
||||
#include "../physics/debug_renderer.h"
|
||||
#include "../controls/controller.h"
|
||||
#include "../physics/collision_scene.h"
|
||||
|
||||
#include "../levels/test_chamber_00_0/header.h"
|
||||
|
||||
struct Vector3 gStartPosition = {5.0f, 0.0f, -5.0f};
|
||||
struct Vector3 gStartPosition = {5.0f, 1.2f, -5.0f};
|
||||
|
||||
void sceneInit(struct Scene* scene) {
|
||||
cameraInit(&scene->camera, 45.0f, 0.125f * SCENE_SCALE, 80.0f * SCENE_SCALE);
|
||||
|
@ -38,6 +39,9 @@ void sceneInit(struct Scene* scene) {
|
|||
scene->portals[1].transform.position.y = 1.0f;
|
||||
scene->portals[1].transform.position.z = -6.0f;
|
||||
|
||||
gCollisionScene.portalTransforms[0] = &scene->portals[0].transform;
|
||||
gCollisionScene.portalTransforms[1] = &scene->portals[1].transform;
|
||||
|
||||
quatAxisAngle(&gUp, M_PI * 0.5f, &scene->portals[1].transform.rotation);
|
||||
|
||||
cubeInit(&scene->cube);
|
||||
|
|
Loading…
Reference in a new issue