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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
contactSolverAssign(contact, &localContact);
|
contactSolverAssign(contact, &localContact, 1);
|
||||||
} else if (contact) {
|
} else if (contact) {
|
||||||
contactSolverRemoveContact(contactSolver, contact);
|
contactSolverRemoveContact(contactSolver, contact);
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,11 @@ void collisionObjectCollideWithQuad(struct CollisionObject* object, struct Colli
|
||||||
struct ContactConstraintState* contact = contactSolverPeekContact(contactSolver, quad, object);
|
struct ContactConstraintState* contact = contactSolverPeekContact(contactSolver, quad, object);
|
||||||
|
|
||||||
if (quadCollider(object->collider->data, &object->body->transform, quad->collider->data, &localContact)) {
|
if (quadCollider(object->collider->data, &object->body->transform, quad->collider->data, &localContact)) {
|
||||||
|
|
||||||
if (!contact) {
|
if (!contact) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
contactSolverAssign(contact, &localContact);
|
contactSolverAssign(contact, &localContact, 1);
|
||||||
} else if (contact) {
|
} else if (contact) {
|
||||||
contactSolverRemoveContact(contactSolver, contact);
|
contactSolverRemoveContact(contactSolver, contact);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "collision_scene.h"
|
#include "collision_scene.h"
|
||||||
|
|
||||||
|
#include "math/mathf.h"
|
||||||
|
|
||||||
struct CollisionScene gCollisionScene;
|
struct CollisionScene gCollisionScene;
|
||||||
|
|
||||||
void collisionSceneInit(struct CollisionScene* scene, struct CollisionObject* quads, int quadCount) {
|
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) {
|
void collisionObjectQueryScene(struct CollisionObject* object, struct CollisionScene* scene, void* data, ManifoldCallback callback) {
|
||||||
CollideWithQuad quadCollider = object->collider->callbacks->collideWithQuad;
|
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) {
|
for (int i = 0; i < scene->quadCount; ++i) {
|
||||||
localContact.contactCount = 0;
|
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);
|
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"
|
#include "collision_object.h"
|
||||||
|
|
||||||
|
#define PORTAL_THICKNESS 0.11f
|
||||||
|
|
||||||
struct CollisionScene {
|
struct CollisionScene {
|
||||||
struct CollisionObject* quads;
|
struct CollisionObject* quads;
|
||||||
int quadCount;
|
int quadCount;
|
||||||
|
struct Transform* portalTransforms[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*ManifoldCallback)(void* data, struct ContactConstraintState* contact);
|
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 collisionSceneInit(struct CollisionScene* scene, struct CollisionObject* quads, int quadCount);
|
||||||
void collisionObjectCollideWithScene(struct CollisionObject* object, struct CollisionScene* scene, struct ContactSolver* contactSolver);
|
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);
|
void collisionObjectQueryScene(struct CollisionObject* object, struct CollisionScene* scene, void* data, ManifoldCallback callback);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../math/mathf.h"
|
#include "../math/mathf.h"
|
||||||
#include "rigid_body.h"
|
#include "rigid_body.h"
|
||||||
#include "collision_object.h"
|
#include "collision_object.h"
|
||||||
|
#include "collision_scene.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -378,7 +379,7 @@ struct ContactState* contactSolverGetContact(struct ContactConstraintState* cont
|
||||||
return result;
|
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) {
|
for (int sourceIndex = 0; sourceIndex < from->contactCount; ++sourceIndex) {
|
||||||
int targetIndex;
|
int targetIndex;
|
||||||
|
|
||||||
|
@ -397,11 +398,18 @@ void contactSolverAssign(struct ContactConstraintState* into, struct ContactCons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int copiedCount = 0;
|
||||||
|
|
||||||
for (int sourceIndex = 0; sourceIndex < from->contactCount; ++sourceIndex) {
|
for (int sourceIndex = 0; sourceIndex < from->contactCount; ++sourceIndex) {
|
||||||
into->contacts[sourceIndex] = from->contacts[sourceIndex];
|
if (filterPortalContacts && collisionSceneIsTouchingPortal(&from->contacts[sourceIndex].ra)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
into->contactCount = from->contactCount;
|
into->contacts[copiedCount] = from->contacts[sourceIndex];
|
||||||
|
++copiedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
into->contactCount = copiedCount;
|
||||||
into->tangentVectors[0] = from->tangentVectors[0];
|
into->tangentVectors[0] = from->tangentVectors[0];
|
||||||
into->tangentVectors[1] = from->tangentVectors[1];
|
into->tangentVectors[1] = from->tangentVectors[1];
|
||||||
into->normal = from->normal;
|
into->normal = from->normal;
|
||||||
|
|
|
@ -62,7 +62,7 @@ void contactSolverRemoveContact(struct ContactSolver* solver, struct ContactCons
|
||||||
|
|
||||||
struct ContactState* contactSolverGetContact(struct ContactConstraintState* contact, int id);
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "physics/collision_scene.h"
|
#include "physics/collision_scene.h"
|
||||||
|
|
||||||
struct Vector3 gGrabDistance = {0.0f, 0.0f, -2.5f};
|
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 = {
|
struct CollisionSphere gPlayerCollider = {
|
||||||
0.25f,
|
0.25f,
|
||||||
|
|
|
@ -15,10 +15,11 @@
|
||||||
#include "../physics/point_constraint.h"
|
#include "../physics/point_constraint.h"
|
||||||
#include "../physics/debug_renderer.h"
|
#include "../physics/debug_renderer.h"
|
||||||
#include "../controls/controller.h"
|
#include "../controls/controller.h"
|
||||||
|
#include "../physics/collision_scene.h"
|
||||||
|
|
||||||
#include "../levels/test_chamber_00_0/header.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) {
|
void sceneInit(struct Scene* scene) {
|
||||||
cameraInit(&scene->camera, 45.0f, 0.125f * SCENE_SCALE, 80.0f * SCENE_SCALE);
|
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.y = 1.0f;
|
||||||
scene->portals[1].transform.position.z = -6.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);
|
quatAxisAngle(&gUp, M_PI * 0.5f, &scene->portals[1].transform.rotation);
|
||||||
|
|
||||||
cubeInit(&scene->cube);
|
cubeInit(&scene->cube);
|
||||||
|
|
Loading…
Reference in a new issue