mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
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
This commit is contained in:
parent
e4d9e57924
commit
5fc0590ffb
|
@ -82,6 +82,24 @@ float rigidBodyMassInverseAtLocalPoint(struct RigidBody* rigidBody, struct Vecto
|
||||||
return rigidBody->massInv + rigidBody->momentOfInertiaInv * vector3MagSqrd(&crossPoint);
|
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) {
|
int rigidBodyCheckPortals(struct RigidBody* rigidBody) {
|
||||||
if (!gCollisionScene.portalTransforms[0] || !gCollisionScene.portalTransforms[1]) {
|
if (!gCollisionScene.portalTransforms[0] || !gCollisionScene.portalTransforms[1]) {
|
||||||
|
@ -94,6 +112,14 @@ int rigidBodyCheckPortals(struct RigidBody* rigidBody) {
|
||||||
|
|
||||||
enum RigidBodyFlags newFlags = 0;
|
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) {
|
if (rigidBody->flags & RigidBodyIsTouchingPortalA) {
|
||||||
newFlags |= RigidBodyWasTouchingPortalA;
|
newFlags |= RigidBodyWasTouchingPortalA;
|
||||||
}
|
}
|
||||||
|
@ -109,20 +135,9 @@ int rigidBodyCheckPortals(struct RigidBody* rigidBody) {
|
||||||
|
|
||||||
int mask = (RigidBodyFlagsInFrontPortal0 << i);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (localPoint.z < 0.0f) {
|
if (localPoint.z < 0.0f) {
|
||||||
newFlags |= mask;
|
newFlags |= mask;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!((RigidBodyIsTouchingPortalA << i) & rigidBody->flags) && !((RigidBodyWasTouchingPortalA << i) & rigidBody->flags)) {
|
if (!((RigidBodyIsTouchingPortalA << i) & rigidBody->flags) && !((RigidBodyWasTouchingPortalA << i) & rigidBody->flags)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -188,27 +203,6 @@ void rigidBodyTeleport(struct RigidBody* rigidBody, struct Transform* from, stru
|
||||||
|
|
||||||
transformPointInverseNoScale(from, &rigidBody->transform.position, &localPoint);
|
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);
|
transformPoint(to, &localPoint, &rigidBody->transform.position);
|
||||||
|
|
||||||
struct Quaternion inverseARotation;
|
struct Quaternion inverseARotation;
|
||||||
|
|
|
@ -10,10 +10,8 @@
|
||||||
|
|
||||||
#define RIGID_BODY_NO_ROOM 0xFFFF
|
#define RIGID_BODY_NO_ROOM 0xFFFF
|
||||||
|
|
||||||
#define MAX_PORTAL_SPEED (500.0f / 64.0f)
|
#define MAX_PORTAL_SPEED (1000.0f / 64.0f)
|
||||||
#define PLAYER_PORTAL_ENTRY_Z_DISTANCE (0.05f)
|
#define PORTAL_EXIT_XY_CLAMP_DISTANCE (0.15f)
|
||||||
#define PLAYER_PORTAL_EXIT_Z_DISTANCE (0.1f)
|
|
||||||
#define PORTAL_EXIT_XY_CLAMP_DISTANCE (0.07f)
|
|
||||||
|
|
||||||
enum RigidBodyFlags {
|
enum RigidBodyFlags {
|
||||||
RigidBodyFlagsInFrontPortal0 = (1 << 0),
|
RigidBodyFlagsInFrontPortal0 = (1 << 0),
|
||||||
|
|
Loading…
Reference in a new issue