implement cylinder collider

This commit is contained in:
James Lambert 2022-06-02 14:01:59 -06:00
parent e9384716a3
commit 0cbec888d4
7 changed files with 87 additions and 26 deletions

View file

@ -5,9 +5,18 @@
#include "../physics/collision_cylinder.h"
struct Vector2 gCylinderColliderEdgeVectors[] = {
{0.0f, 1.0f},
{0.707f, 0.707f},
{1.0f, 0.0f},
{0.707f, -0.707f},
};
struct CollisionCylinder gCylinderCollider = {
0.3f,
0.35f,
gCylinderColliderEdgeVectors,
sizeof(gCylinderColliderEdgeVectors) / sizeof(*gCylinderColliderEdgeVectors),
};
struct DecorObjectDefinition gDecorObjectDefinitions[] = {

View file

@ -5,12 +5,14 @@
#include "collision_quad.h"
#include "raycasting.h"
#include "line.h"
#include "../math/vector2.h"
struct ColliderCallbacks gCollisionCylinderCallbacks = {
NULL,
raycastCylinder,
collisionCylinderSolidMofI,
collisionCylinderBoundingBox,
collisionCylinderMinkowsiSum,
};
float collisionCylinderSolidMofI(struct ColliderTypeData* typeData, float mass) {
@ -35,3 +37,49 @@ void collisionCylinderBoundingBox(struct ColliderTypeData* typeData, struct Tran
vector3Sub(&transform->position, &halfSize, &box->min);
vector3Add(&transform->position, &halfSize, &box->max);
}
int collisionCylinderMinkowsiSum(void* data, struct Basis* basis, struct Vector3* direction, struct Vector3* output) {
struct CollisionCylinder* cylinder = (struct CollisionCylinder*)data;
int centerDir = vector3Dot(&basis->y, direction) > 0.0f;
vector3Scale(&basis->y, output, centerDir > 0.0f ? cylinder->halfHeight : -cylinder->halfHeight);
struct Vector2 crossDirectionCheck;
crossDirectionCheck.x = vector3Dot(&basis->x, direction);
crossDirectionCheck.y = vector3Dot(&basis->z, direction);
float dotDiff = vector2Dot(&crossDirectionCheck, &cylinder->edgeVectors[0]);
int closest = 0;
for (int i = 1; i < cylinder->edgeCount; ++i) {
float dotCheck = vector2Dot(&crossDirectionCheck, &cylinder->edgeVectors[i]);
if (fabsf(dotCheck) > fabsf(dotDiff)) {
dotDiff = dotCheck;
closest = i;
}
}
struct Vector2 crossDirection;
int faceId = closest;
if (dotDiff < 0.0f) {
faceId += cylinder->edgeCount;
vector2Negate(&cylinder->edgeVectors[closest], &crossDirection);
} else {
crossDirection = cylinder->edgeVectors[closest];
}
int nextId = faceId + 1;
if (faceId == cylinder->edgeCount * 2) {
nextId = 0;
}
vector3AddScaled(output, &basis->x, crossDirection.x * cylinder->radius, output);
vector3AddScaled(output, &basis->z, crossDirection.y * cylinder->radius, output);
return (centerDir ? 0x1 : 0x2) | (1 << (faceId + 2)) | (1 << (nextId + 2));
}

View file

@ -3,15 +3,19 @@
#include "collision_quad.h"
#include "collision.h"
#include "../math/vector2.h"
struct CollisionCylinder {
float radius;
float halfHeight;
struct Vector2* edgeVectors;
int edgeCount;
};
extern struct ColliderCallbacks gCollisionCylinderCallbacks;
float collisionCylinderSolidMofI(struct ColliderTypeData* typeData, float mass);
void collisionCylinderBoundingBox(struct ColliderTypeData* typeData, struct Transform* transform, struct Box3D* box);
int collisionCylinderMinkowsiSum(void* data, struct Basis* basis, struct Vector3* direction, struct Vector3* output);
#endif

View file

@ -41,7 +41,6 @@ void collisionObjectCollideWithQuad(struct CollisionObject* object, struct Colli
return;
}
transformPointInverseNoScale(&object->body->transform, &result.contactB, &result.contactB);
struct ContactManifold* contact = contactSolverGetContactManifold(contactSolver, quadObject, object);
if (!contact) {
@ -55,6 +54,7 @@ void collisionObjectCollideWithQuad(struct CollisionObject* object, struct Colli
return;
}
transformPointInverseNoScale(&object->body->transform, &result.contactB, &result.contactB);
contactInsert(contact, &result);
}

View file

@ -407,7 +407,7 @@ void epaSolve(struct Simplex* startingSimplex, void* objectA, MinkowsiSum object
projection = vector3Dot(&simplex->points[nextIndex], &closestFace->normal);
if ((projection - closestFace->distanceToOrigin) < 0.00000001f) {
if ((projection - closestFace->distanceToOrigin) < 0.001f) {
break;
}

View file

@ -41,17 +41,17 @@ void sceneInit(struct Scene* scene) {
portalInit(&scene->portals[0], 0);
portalInit(&scene->portals[1], PortalFlagsOddParity);
for (int i = 0; i < MAX_CUBES; ++i) {
cubeInit(&scene->cubes[i]);
// for (int i = 0; i < MAX_CUBES; ++i) {
// cubeInit(&scene->cubes[i]);
scene->cubes[i].rigidBody.transform.position.x = 0.0f;
scene->cubes[i].rigidBody.transform.position.y = 0.5f;
scene->cubes[i].rigidBody.transform.position.z = 6.0f + i;
scene->cubes[i].rigidBody.currentRoom = 1;
// scene->cubes[i].rigidBody.transform.position.x = 0.0f;
// scene->cubes[i].rigidBody.transform.position.y = 0.5f;
// scene->cubes[i].rigidBody.transform.position.z = 6.0f + i;
// scene->cubes[i].rigidBody.currentRoom = 1;
quatAxisAngle(&gRight, M_PI * 0.125f, &scene->cubes[i].rigidBody.transform.rotation);
scene->cubes[i].rigidBody.angularVelocity = gOneVec;
}
// quatAxisAngle(&gRight, M_PI * 0.125f, &scene->cubes[i].rigidBody.transform.rotation);
// scene->cubes[i].rigidBody.angularVelocity = gOneVec;
// }
scene->buttonCount = 1;
scene->buttons = malloc(sizeof(struct Button) * scene->buttonCount);
@ -62,14 +62,14 @@ void sceneInit(struct Scene* scene) {
buttonInit(&scene->buttons[0], &buttonPos, 1);
scene->decorCount = 0;
// scene->decor = malloc(sizeof(struct DecorObject*) * scene->decorCount);
// struct Transform decorTransform;
// transformInitIdentity(&decorTransform);
// decorTransform.position.x = 3.0f;
// decorTransform.position.y = 2.0f;
// decorTransform.position.z = 3.0f;
scene->decor = malloc(sizeof(struct DecorObject*) * scene->decorCount);
struct Transform decorTransform;
transformInitIdentity(&decorTransform);
decorTransform.position.x = 3.0f;
decorTransform.position.y = 0.5f;
decorTransform.position.z = 3.0f;
// quatAxisAngle(&gRight, 1.0f, &decorTransform.rotation);
// scene->decor[0] = decorObjectNew(decorObjectDefinitionForId(DECOR_TYPE_CYLINDER), &decorTransform, 1);
scene->decor[0] = decorObjectNew(decorObjectDefinitionForId(DECOR_TYPE_CYLINDER), &decorTransform, 1);
// vector3Scale(&gForward, &scene->decor[0]->rigidBody.angularVelocity, 10.0f);
// scene->decor[0]->rigidBody.velocity.y = 1.0f;
// scene->decor[0]->rigidBody.velocity.z = 1.0f;
@ -203,15 +203,15 @@ void sceneUpdate(struct Scene* scene) {
playerUpdate(&scene->player, &scene->camera.transform);
sceneCheckPortals(scene);
for (int i = 0; i < MAX_CUBES; ++i) {
cubeUpdate(&scene->cubes[i]);
// for (int i = 0; i < MAX_CUBES; ++i) {
// cubeUpdate(&scene->cubes[i]);
if (collisionSceneTestMinkowsiSum(&scene->cubes[i].collisionObject)) {
scene->cubes[i].rigidBody.flags |= RigidBodyDebugFlag;
} else {
scene->cubes[i].rigidBody.flags &= ~RigidBodyDebugFlag;
}
}
// if (collisionSceneTestMinkowsiSum(&scene->cubes[i].collisionObject)) {
// scene->cubes[i].rigidBody.flags |= RigidBodyDebugFlag;
// } else {
// scene->cubes[i].rigidBody.flags &= ~RigidBodyDebugFlag;
// }
// }
collisionSceneUpdateDynamics();