From e654225970563660319d79a2c8488ec5bba9ce99 Mon Sep 17 00:00:00 2001 From: Weston Salinas Date: Sun, 26 Mar 2023 15:54:18 -0500 Subject: [PATCH 1/4] Fixes players and objects clipping out of stage with wall/ground portal - this fix was implemented by simply clamping the x and y of the localPoint to -0.1-0.1 and -0.2-0.2 respectively. - objects can no longer clip through stage - player can no longer clip through stage Fixes #13 --- README.md | 6 +++--- src/physics/rigid_body.c | 3 +++ src/physics/rigid_body.h | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e58430b..7bf0209 100644 --- a/README.md +++ b/README.md @@ -124,11 +124,9 @@ Where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where Blender - [ ] Ambient background loop ## Current Bug TODO List (Hardware Verified) (High->Low priority) -- [ ] Player can clip through any level by placing one portal on wall and another portal right next to it on ground. #13 - [ ] Player can clip through chamber 7 by walking back up the stairs (near the top). - [ ] player can clip through back of elevator by jumping and strafeing at the back corners while inside. -- [ ] Player can strap themselves in chamber 5 by following instructions issue #75 -- [ ] Any grabbable object can be clipped through level by wall/floor portals method. +- [ ] Player can trap themselves in chamber 5 by following instructions issue #75 - [ ] Two wall portals next to eachother can be used to clip any object out of any level by pushing it into corner, then dropping. - [ ] Glass can be walked through from one side on multiple levels (0,1,4,...) - [ ] Passing into a ceiling portal can sometimes mess with the player rotation @@ -140,3 +138,5 @@ Where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where Blender - [ ] Door at end of room 2, chamber 10 isnt rendered properly - [ ] various visual glitches when running NTSC on PAL console #65 - [ ] various visual glitches when running PAL on NTSC console #65 +- [x] Any grabbable object can be clipped through level by wall/floor portals method. +- [x] Player can clip through any level by placing one portal on wall and another portal right next to it on ground. #13 diff --git a/src/physics/rigid_body.c b/src/physics/rigid_body.c index ac4209e..f6945e0 100644 --- a/src/physics/rigid_body.c +++ b/src/physics/rigid_body.c @@ -177,6 +177,9 @@ void rigidBodyTeleport(struct RigidBody* rigidBody, struct Transform* from, stru transformPointInverseNoScale(from, &rigidBody->transform.position, &localPoint); + localPoint.x = clampf(localPoint.x, -0.1, 0.1); + localPoint.y = clampf(localPoint.y, -0.2, 0.2); + transformPoint(to, &localPoint, &rigidBody->transform.position); struct Quaternion inverseARotation; diff --git a/src/physics/rigid_body.h b/src/physics/rigid_body.h index 2b18c24..96fa34e 100644 --- a/src/physics/rigid_body.h +++ b/src/physics/rigid_body.h @@ -3,6 +3,7 @@ #include "../math/basis.h" #include "../math/transform.h" +#include "../math/mathf.h" #include "./collision.h" #define KILL_PLANE_Y -10.0f From 064214603449625da70d49b6b53d410a015706e0 Mon Sep 17 00:00:00 2001 From: Weston Salinas Date: Mon, 27 Mar 2023 16:10:32 -0500 Subject: [PATCH 2/4] Implemented oval clipping suggestions, and player boundry --- src/physics/rigid_body.c | 37 +++++++++++++++++++++++++++++++++---- src/physics/rigid_body.h | 5 ++++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/physics/rigid_body.c b/src/physics/rigid_body.c index f6945e0..7f970fa 100644 --- a/src/physics/rigid_body.c +++ b/src/physics/rigid_body.c @@ -109,9 +109,20 @@ int rigidBodyCheckPortals(struct RigidBody* rigidBody) { int mask = (RigidBodyFlagsInFrontPortal0 << i); - if (localPoint.z < 0.0f) { - newFlags |= mask; + if (rigidBody->flags & RigidBodyIsPlayer){ + if (localPoint.z < -PLAYER_PORTAL_ENTRY_Z_DISTANCE && i==0) { + newFlags |= mask; + } + else if (localPoint.z < PLAYER_PORTAL_ENTRY_Z_DISTANCE && i==1) { + newFlags |= mask; + } } + else{ + if (localPoint.z < 0.0f) { + newFlags |= mask; + } + } + if (!((RigidBodyIsTouchingPortalA << i) & rigidBody->flags) && !((RigidBodyWasTouchingPortalA << i) & rigidBody->flags)) { continue; @@ -177,8 +188,26 @@ void rigidBodyTeleport(struct RigidBody* rigidBody, struct Transform* from, stru transformPointInverseNoScale(from, &rigidBody->transform.position, &localPoint); - localPoint.x = clampf(localPoint.x, -0.1, 0.1); - localPoint.y = clampf(localPoint.y, -0.2, 0.2); + //clamping the x and y of local point to a slightly smaller oval on the output portal + struct Vector3 clampedLocalPoint; + clampedLocalPoint = localPoint; + clampedLocalPoint.y /= 2.0f; + clampedLocalPoint.z = 0.0f; + while(sqrtf(vector3MagSqrd(&clampedLocalPoint))>PORTAL_EXIT_XY_CLAMP_DISTANCE){ + vector3Scale(&clampedLocalPoint, &clampedLocalPoint, 0.90f); + } + clampedLocalPoint.y *= 2.0f; + localPoint.y = clampedLocalPoint.y; + localPoint.x = clampedLocalPoint.x; + + //the to portal will teleport the player slightly in front of it. (altering the z) + if (rigidBody->flags & RigidBodyIsPlayer){ + if (localPoint.z >= 0){ + localPoint.z = minf(localPoint.z, -PLAYER_PORTAL_EXIT_Z_DISTANCE); + }else{ + localPoint.z = maxf(localPoint.z, PLAYER_PORTAL_EXIT_Z_DISTANCE); + } + } transformPoint(to, &localPoint, &rigidBody->transform.position); diff --git a/src/physics/rigid_body.h b/src/physics/rigid_body.h index 96fa34e..21bdbad 100644 --- a/src/physics/rigid_body.h +++ b/src/physics/rigid_body.h @@ -10,7 +10,10 @@ #define RIGID_BODY_NO_ROOM 0xFFFF -#define MAX_PORTAL_SPEED (1000.0f / 64.0f) +#define MAX_PORTAL_SPEED (500.0f / 64.0f) +#define PLAYER_PORTAL_ENTRY_Z_DISTANCE (0.05f) +#define PLAYER_PORTAL_EXIT_Z_DISTANCE (0.07f) +#define PORTAL_EXIT_XY_CLAMP_DISTANCE (0.07f) enum RigidBodyFlags { RigidBodyFlagsInFrontPortal0 = (1 << 0), From 5682481ec94a745c3fede864d87d48a387baf305 Mon Sep 17 00:00:00 2001 From: Weston Salinas Date: Mon, 27 Mar 2023 16:38:31 -0500 Subject: [PATCH 3/4] oops flipped a negative --- src/physics/rigid_body.c | 4 ++-- src/physics/rigid_body.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/physics/rigid_body.c b/src/physics/rigid_body.c index 7f970fa..c25c3a3 100644 --- a/src/physics/rigid_body.c +++ b/src/physics/rigid_body.c @@ -203,9 +203,9 @@ void rigidBodyTeleport(struct RigidBody* rigidBody, struct Transform* from, stru //the to portal will teleport the player slightly in front of it. (altering the z) if (rigidBody->flags & RigidBodyIsPlayer){ if (localPoint.z >= 0){ - localPoint.z = minf(localPoint.z, -PLAYER_PORTAL_EXIT_Z_DISTANCE); + localPoint.z = minf(localPoint.z, PLAYER_PORTAL_EXIT_Z_DISTANCE); }else{ - localPoint.z = maxf(localPoint.z, PLAYER_PORTAL_EXIT_Z_DISTANCE); + localPoint.z = maxf(localPoint.z, -PLAYER_PORTAL_EXIT_Z_DISTANCE); } } diff --git a/src/physics/rigid_body.h b/src/physics/rigid_body.h index 21bdbad..fea22aa 100644 --- a/src/physics/rigid_body.h +++ b/src/physics/rigid_body.h @@ -12,7 +12,7 @@ #define MAX_PORTAL_SPEED (500.0f / 64.0f) #define PLAYER_PORTAL_ENTRY_Z_DISTANCE (0.05f) -#define PLAYER_PORTAL_EXIT_Z_DISTANCE (0.07f) +#define PLAYER_PORTAL_EXIT_Z_DISTANCE (0.1f) #define PORTAL_EXIT_XY_CLAMP_DISTANCE (0.07f) enum RigidBodyFlags { From 5fc0590ffb098187953368f938799f65b0b79647 Mon Sep 17 00:00:00 2001 From: Weston Salinas Date: Tue, 28 Mar 2023 16:14:10 -0500 Subject: [PATCH 4/4] Final Version of Wall/Ground Portal Fix - This version implements a function that clamps all objects to an oval shape if they are touching a single portal - This aleviates player clipping out of stage with wall/ground portal - This aleviates physics objects clipping out of stage with wall/ground portal - player can no longer walk partially into a wall portal then walk into the wall Fixes #3 Fixes #13 --- src/physics/rigid_body.c | 62 ++++++++++++++++++---------------------- src/physics/rigid_body.h | 6 ++-- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/physics/rigid_body.c b/src/physics/rigid_body.c index c25c3a3..6fd8f8b 100644 --- a/src/physics/rigid_body.c +++ b/src/physics/rigid_body.c @@ -82,6 +82,24 @@ float rigidBodyMassInverseAtLocalPoint(struct RigidBody* rigidBody, struct Vecto return rigidBody->massInv + rigidBody->momentOfInertiaInv * vector3MagSqrd(&crossPoint); } +void rigidBodyClampToPortal(struct RigidBody* rigidBody, struct Transform* portal) { + struct Vector3 localPoint; + + transformPointInverseNoScale(portal, &rigidBody->transform.position, &localPoint); + + //clamping the x and y of local point to a slightly smaller oval on the output portal + struct Vector3 clampedLocalPoint; + clampedLocalPoint = localPoint; + clampedLocalPoint.y /= 2.0f; + clampedLocalPoint.z = 0.0f; + while(sqrtf(vector3MagSqrd(&clampedLocalPoint))>PORTAL_EXIT_XY_CLAMP_DISTANCE){ + vector3Scale(&clampedLocalPoint, &clampedLocalPoint, 0.90f); + } + clampedLocalPoint.y *= 2.0f; + localPoint.x = clampedLocalPoint.x; + localPoint.y = clampedLocalPoint.y; + transformPoint(portal, &localPoint, &rigidBody->transform.position); +} int rigidBodyCheckPortals(struct RigidBody* rigidBody) { if (!gCollisionScene.portalTransforms[0] || !gCollisionScene.portalTransforms[1]) { @@ -94,6 +112,14 @@ int rigidBodyCheckPortals(struct RigidBody* rigidBody) { enum RigidBodyFlags newFlags = 0; + //if only touching one portal, clamp object to edges of that portal + if ((rigidBody->flags & RigidBodyIsTouchingPortalA) && !(rigidBody->flags & RigidBodyIsTouchingPortalB)){ + rigidBodyClampToPortal(rigidBody, gCollisionScene.portalTransforms[0]); + } + else if ((rigidBody->flags & RigidBodyIsTouchingPortalB) && !(rigidBody->flags & RigidBodyIsTouchingPortalA)){ + rigidBodyClampToPortal(rigidBody, gCollisionScene.portalTransforms[1]); + } + if (rigidBody->flags & RigidBodyIsTouchingPortalA) { newFlags |= RigidBodyWasTouchingPortalA; } @@ -109,20 +135,9 @@ int rigidBodyCheckPortals(struct RigidBody* rigidBody) { int mask = (RigidBodyFlagsInFrontPortal0 << i); - if (rigidBody->flags & RigidBodyIsPlayer){ - if (localPoint.z < -PLAYER_PORTAL_ENTRY_Z_DISTANCE && i==0) { - newFlags |= mask; - } - else if (localPoint.z < PLAYER_PORTAL_ENTRY_Z_DISTANCE && i==1) { - newFlags |= mask; - } + if (localPoint.z < 0.0f) { + newFlags |= mask; } - else{ - if (localPoint.z < 0.0f) { - newFlags |= mask; - } - } - if (!((RigidBodyIsTouchingPortalA << i) & rigidBody->flags) && !((RigidBodyWasTouchingPortalA << i) & rigidBody->flags)) { continue; @@ -188,27 +203,6 @@ void rigidBodyTeleport(struct RigidBody* rigidBody, struct Transform* from, stru transformPointInverseNoScale(from, &rigidBody->transform.position, &localPoint); - //clamping the x and y of local point to a slightly smaller oval on the output portal - struct Vector3 clampedLocalPoint; - clampedLocalPoint = localPoint; - clampedLocalPoint.y /= 2.0f; - clampedLocalPoint.z = 0.0f; - while(sqrtf(vector3MagSqrd(&clampedLocalPoint))>PORTAL_EXIT_XY_CLAMP_DISTANCE){ - vector3Scale(&clampedLocalPoint, &clampedLocalPoint, 0.90f); - } - clampedLocalPoint.y *= 2.0f; - localPoint.y = clampedLocalPoint.y; - localPoint.x = clampedLocalPoint.x; - - //the to portal will teleport the player slightly in front of it. (altering the z) - if (rigidBody->flags & RigidBodyIsPlayer){ - if (localPoint.z >= 0){ - localPoint.z = minf(localPoint.z, PLAYER_PORTAL_EXIT_Z_DISTANCE); - }else{ - localPoint.z = maxf(localPoint.z, -PLAYER_PORTAL_EXIT_Z_DISTANCE); - } - } - transformPoint(to, &localPoint, &rigidBody->transform.position); struct Quaternion inverseARotation; diff --git a/src/physics/rigid_body.h b/src/physics/rigid_body.h index fea22aa..fd161ba 100644 --- a/src/physics/rigid_body.h +++ b/src/physics/rigid_body.h @@ -10,10 +10,8 @@ #define RIGID_BODY_NO_ROOM 0xFFFF -#define MAX_PORTAL_SPEED (500.0f / 64.0f) -#define PLAYER_PORTAL_ENTRY_Z_DISTANCE (0.05f) -#define PLAYER_PORTAL_EXIT_Z_DISTANCE (0.1f) -#define PORTAL_EXIT_XY_CLAMP_DISTANCE (0.07f) +#define MAX_PORTAL_SPEED (1000.0f / 64.0f) +#define PORTAL_EXIT_XY_CLAMP_DISTANCE (0.15f) enum RigidBodyFlags { RigidBodyFlagsInFrontPortal0 = (1 << 0),