From ba67c38665f50b94a79b69c174b8d49d80cdfa4b Mon Sep 17 00:00:00 2001 From: James Lambert Date: Sun, 1 Oct 2023 20:41:25 -0600 Subject: [PATCH] Wake up objects when portals are shot underneath then --- README.md | 2 +- src/physics/collision_capsule.c | 38 +-------------------------------- src/physics/contact_solver.c | 9 +++++--- src/physics/contact_solver.h | 2 +- src/physics/debug_renderer.c | 4 ++-- src/scene/scene.c | 5 +++-- src/util/profile.c | 31 +++++++++++++++++++++++++++ src/util/profile.h | 13 +++++++++++ 8 files changed, 58 insertions(+), 46 deletions(-) create mode 100644 src/util/profile.c create mode 100644 src/util/profile.h diff --git a/README.md b/README.md index dd6612b..814096f 100644 --- a/README.md +++ b/README.md @@ -141,12 +141,12 @@ That will generate the rom at `/build/portal64.z64`
## Current New Feature TODO List -- [ ] wake up objects after opening a portal under them - [ ] rumble pak support? - [ ] Investigate crash after falling into death water on test chamber 8 - [ ] Add auto save checkpoints - [ ] Correct elevator timing - [ ] pausing while glados is speaking can end her speech early +- [x] wake up objects after opening a portal under them - [x] button prompts - [x] investigate no_portals surface under portal pedestal - [x] Adding loading notice between levels #45 diff --git a/src/physics/collision_capsule.c b/src/physics/collision_capsule.c index c9a4276..93e08c3 100644 --- a/src/physics/collision_capsule.c +++ b/src/physics/collision_capsule.c @@ -89,40 +89,4 @@ struct ColliderCallbacks gCollisionCapsuleCallbacks = { collisionCapsuleSolidMofI, collisionCapsuleBoundingBox, collisionCapsuleMinkowsiSum, -}; - -int collisionCapsuleCheckWithNearestPoint(struct Vector3* nearestPoint, struct CollisionCapsule* otherCapsule, struct Vector3* capsulePos, struct ContactManifold* contact) { - vector3Sub(capsulePos, nearestPoint, &contact->normal); - - float distanceSqrd = vector3MagSqrd(&contact->normal); - - if (distanceSqrd > otherCapsule->radius * otherCapsule->radius) { - return 0; - } - - float distance = 0.0f; - - if (distanceSqrd < 0.00001f) { - contact->normal = gRight; - } else { - distance = sqrtf(distanceSqrd); - vector3Scale(&contact->normal, &contact->normal, 1.0f / distance); - } - - struct ContactPoint* contactPoint = &contact->contacts[0]; - - vector3Scale(&contact->normal, &contactPoint->contactAWorld, otherCapsule->radius); - vector3Scale(&contact->normal, &contactPoint->contactBWorld, -otherCapsule->radius); - - contactPoint->bias = 0.0f; - contactPoint->id = 0; - contactPoint->normalImpulse = 0.0f; - contactPoint->normalMass = 0.0f; - contactPoint->penetration = distance - otherCapsule->radius; - contactPoint->tangentImpulse[0] = 0.0f; - contactPoint->tangentImpulse[1] = 0.0f; - contactPoint->tangentMass[0] = 0.0f; - contactPoint->tangentMass[0] = 0.0f; - - return 1; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/physics/contact_solver.c b/src/physics/contact_solver.c index bba413c..79a9701 100644 --- a/src/physics/contact_solver.c +++ b/src/physics/contact_solver.c @@ -139,15 +139,18 @@ void contactSolverCheckPortalManifoldContacts(struct ContactManifold* manifold) ++writeIndex; } - manifold->contactCount = writeIndex; + if (writeIndex != manifold->contactCount) { + manifold->contactCount = writeIndex; + manifold->shapeB->body->flags &= ~RigidBodyIsSleeping; + } } -void contactSolverCheckPortalContacts(struct ContactSolver* contactSolver, struct CollisionObject* objectWithNewPortal) { +void contactSolverCheckPortalContacts(struct ContactSolver* contactSolver) { struct ContactManifold* curr = contactSolver->activeContacts; struct ContactManifold* prev = NULL; while (curr) { - if (curr->shapeA == objectWithNewPortal) { + if (curr->shapeA->body == NULL) { contactSolverCheckPortalManifoldContacts(curr); } diff --git a/src/physics/contact_solver.h b/src/physics/contact_solver.h index ed4eb49..c477768 100644 --- a/src/physics/contact_solver.h +++ b/src/physics/contact_solver.h @@ -64,7 +64,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); +void contactSolverCheckPortalContacts(struct ContactSolver* contactSolver); void contactSolverCleanupManifold(struct ContactManifold* manifold); float contactPenetration(struct ContactManifold* contact); diff --git a/src/physics/debug_renderer.c b/src/physics/debug_renderer.c index ad3e1ca..ce90213 100644 --- a/src/physics/debug_renderer.c +++ b/src/physics/debug_renderer.c @@ -48,10 +48,10 @@ void contactConstraintStateDebugDraw(struct ContactManifold* constraintState, st mat[2][2] = constraintState->tangentVectors[1].z; mat[2][3] = 0.0f; - struct Vector3 pos = contact->contactBLocal; + struct Vector3 pos = contact->contactBWorld; if (constraintState->shapeB->body) { - transformPoint(&constraintState->shapeB->body->transform, &pos, &pos); + vector3Add(&constraintState->shapeB->body->transform.position, &pos, &pos); } mat[3][0] = pos.x * SCENE_SCALE; diff --git a/src/scene/scene.c b/src/scene/scene.c index aa12e03..70ef3c2 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -301,6 +301,8 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr renderPlanBuild(&renderPlan, scene, renderState); renderPlanExecute(&renderPlan, scene, staticMatrices, renderState); + // contactSolverDebugDraw(&gContactSolver, renderState); + if (scene->portalGun.portalGunVisible){ portalGunRenderReal(&scene->portalGun, renderState, &scene->camera); } @@ -317,7 +319,6 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr // sceneRenderPerformanceMetrics(scene, renderState, task); - // contactSolverDebugDraw(&gContactSolver, renderState); } @@ -814,7 +815,7 @@ int sceneOpenPortal(struct Scene* scene, struct Transform* at, int transformInde } } - contactSolverCheckPortalContacts(&gContactSolver, collisionObject); + contactSolverCheckPortalContacts(&gContactSolver); ballBurnFilterOnPortal(&portal->rigidBody.transform, portalIndex); playerSignalPortalChanged(&scene->player); return 1; diff --git a/src/util/profile.c b/src/util/profile.c new file mode 100644 index 0000000..aee9f85 --- /dev/null +++ b/src/util/profile.c @@ -0,0 +1,31 @@ +#include "profile.h" + +#ifdef PORTAL64_WITH_DEBUGGER +#include "../debugger/serial.h" +#endif + +struct ProfileData { + u64 lastReportStart; + u64 timeAccumulation[MAX_PROFILE_BINS]; +}; + +struct ProfileData gProfileData; + +void profileEnd(u64 startTime, int bin) { + gProfileData.timeAccumulation[bin] += OS_CYCLES_TO_USEC(osGetTime() - startTime); +} + +void profileReport() { +#ifdef PORTAL64_WITH_DEBUGGER + OSTime reportStartTime = osGetTime(); + + gProfileData.lastReportStart = OS_CYCLES_TO_USEC(reportStartTime - gProfileData.lastReportStart); + // gdbSendMessage(GDBDataTypeRawBinary, (char*)&gProfileData, sizeof(struct ProfileData)); + + for (int i = 0; i < MAX_PROFILE_BINS; ++i) { + gProfileData.timeAccumulation[i] = 0; + } + + gProfileData.lastReportStart = reportStartTime; +#endif +} \ No newline at end of file diff --git a/src/util/profile.h b/src/util/profile.h new file mode 100644 index 0000000..2f594c7 --- /dev/null +++ b/src/util/profile.h @@ -0,0 +1,13 @@ +#ifndef __UTIL_PROFILE_H__ +#define __UTIL_PROFILE_H__ + +#include + +#define profileStart() osGetTime() +void profileEnd(u64 startTime, int bin); + +void profileReport(); + +#define MAX_PROFILE_BINS 8 + +#endif \ No newline at end of file