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 60374bf..b33aca1 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/decor/decor_object_list.c b/src/decor/decor_object_list.c index f22d18e..d8263f2 100644 --- a/src/decor/decor_object_list.c +++ b/src/decor/decor_object_list.c @@ -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[] = { diff --git a/src/physics/collision_cylinder.c b/src/physics/collision_cylinder.c index c8a485a..9f5a254 100644 --- a/src/physics/collision_cylinder.c +++ b/src/physics/collision_cylinder.c @@ -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) { @@ -34,4 +36,50 @@ void collisionCylinderBoundingBox(struct ColliderTypeData* typeData, struct Tran quatRotatedBoundingBoxSize(&transform->rotation, &radius, &halfSize); 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)); } \ No newline at end of file diff --git a/src/physics/collision_cylinder.h b/src/physics/collision_cylinder.h index f4ac4ec..80a9265 100644 --- a/src/physics/collision_cylinder.h +++ b/src/physics/collision_cylinder.h @@ -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 \ No newline at end of file diff --git a/src/physics/collision_object.c b/src/physics/collision_object.c index 3a17ce1..b93bee7 100644 --- a/src/physics/collision_object.c +++ b/src/physics/collision_object.c @@ -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); } diff --git a/src/physics/epa.c b/src/physics/epa.c index af4346e..577e077 100644 --- a/src/physics/epa.c +++ b/src/physics/epa.c @@ -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; } diff --git a/src/scene/scene.c b/src/scene/scene.c index 52e0371..840c69a 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -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();