From 56672ff5623da7a37873dc6f0f268447c6c169b7 Mon Sep 17 00:00:00 2001 From: Deconimus Date: Fri, 29 Mar 2024 00:35:51 +0100 Subject: [PATCH 1/6] grabRotation: snap all grabbed object rotation to cube normals + some related code refactoring --- src/physics/collision_scene.c | 6 +++ src/physics/collision_scene.h | 1 + src/player/player.c | 87 +++++++++++++++++++++++++++++------ src/player/player.h | 4 +- 4 files changed, 83 insertions(+), 15 deletions(-) diff --git a/src/physics/collision_scene.c b/src/physics/collision_scene.c index 073e2045..3c55e60e 100644 --- a/src/physics/collision_scene.c +++ b/src/physics/collision_scene.c @@ -514,6 +514,12 @@ void collisionSceneGetPortalTransform(int fromPortal, struct Transform* out) { transformConcat(gCollisionScene.portalTransforms[1 - fromPortal], &inverseA, out); } +void collisionSceneGetPortalRotation(int fromPortal, struct Quaternion* out) { + struct Quaternion inverse; + quatConjugate(&gCollisionScene.portalTransforms[fromPortal]->rotation, &inverse); + quatMultiply(&gCollisionScene.portalTransforms[1 - fromPortal]->rotation, &inverse, out); +} + void collisionSceneAddDynamicObject(struct CollisionObject* object) { if (gCollisionScene.dynamicObjectCount < MAX_DYNAMIC_OBJECTS) { gCollisionScene.dynamicObjects[gCollisionScene.dynamicObjectCount] = object; diff --git a/src/physics/collision_scene.h b/src/physics/collision_scene.h index 32fe798b..aa514e0d 100644 --- a/src/physics/collision_scene.h +++ b/src/physics/collision_scene.h @@ -49,6 +49,7 @@ int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ra int collisionSceneRaycastOnlyDynamic(struct CollisionScene* scene, struct Ray* ray, int collisionLayers, float maxDistance, struct RaycastHit* hit); void collisionSceneGetPortalTransform(int fromPortal, struct Transform* out); +void collisionSceneGetPortalRotation(int fromPortal, struct Quaternion* out); void collisionSceneAddDynamicObject(struct CollisionObject* object); void collisionSceneRemoveDynamicObject(struct CollisionObject* object); diff --git a/src/player/player.c b/src/player/player.c index beb049a5..7a90ce1c 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -90,7 +90,7 @@ void playerRender(void* data, struct DynamicRenderDataList* renderList, struct R struct Vector3 forwardVector; struct Vector3 unusedRight; - playerGetMoveBasis(&player->lookTransform, &forwardVector, &unusedRight); + playerGetMoveBasis(&player->lookTransform.rotation, &forwardVector, &unusedRight); finalPlayerTransform.position = player->body.transform.position; quatLook(&forwardVector, &gUp, &finalPlayerTransform.rotation); @@ -263,6 +263,47 @@ void playerSetGrabbing(struct Player* player, struct CollisionObject* grabbing) } else if (grabbing != player->grabConstraint.object) { pointConstraintInit(&player->grabConstraint, grabbing, 8.0f, 5.0f, 1.0f); } + + if (player->grabConstraint.object) { + struct Quaternion forwardRotationInv = player->lookTransform.rotation; + playerPortalGrabRotate(player, &forwardRotationInv); + struct Vector3 forward, tmpVec; + playerGetMoveBasis(&forwardRotationInv, &forward, &tmpVec); + vector3Negate(&forward, &tmpVec); + quatLook(&tmpVec, &gUp, &forwardRotationInv); + quatConjugate(&forwardRotationInv, &forwardRotationInv); + + struct Quaternion objectRotation = player->grabConstraint.object->body->transform.rotation; + + // snap target rotation to nearest cube normal + struct Vector3 surfaceNormal, closestNormal; + float closestNormalDot = 1.0f; // has to be negative on success + for (int i = 0; i < 6; ++i) { + if (i == 0) { surfaceNormal = (struct Vector3){ 1.0f, 0.0f, 0.0f}; } + else if (i == 1) { surfaceNormal = (struct Vector3){-1.0f, 0.0f, 0.0f}; } + else if (i == 2) { surfaceNormal = (struct Vector3){ 0.0f, 1.0f, 0.0f}; } + else if (i == 3) { surfaceNormal = (struct Vector3){ 0.0f, -1.0f, 0.0f}; } + else if (i == 4) { surfaceNormal = (struct Vector3){ 0.0f, 0.0f, 1.0f}; } + else if (i == 5) { surfaceNormal = (struct Vector3){ 0.0f, 0.0f, -1.0f}; } + quatMultVector(&objectRotation, &surfaceNormal, &surfaceNormal); + + float normalDot = vector3Dot(&surfaceNormal, &forward); + if (normalDot < 0.0f && normalDot < closestNormalDot) { + closestNormalDot = normalDot; + closestNormal = surfaceNormal; + } + } + if (closestNormalDot < 0.0f) { + struct Quaternion surfaceRotation; + quatLook(&closestNormal, &gUp, &surfaceRotation); + quatMultiply(&forwardRotationInv, &surfaceRotation, &objectRotation); + quatConjugate(&objectRotation, &surfaceRotation); + quatMultiply(&surfaceRotation, &player->grabConstraint.object->body->transform.rotation, &objectRotation); + } + + // untangle objectRotation from relative forwardRotation, store as grabRotationBase + quatMultiply(&forwardRotationInv, &objectRotation, &player->grabRotationBase); + } } void playerShakeUpdate(struct Player* player) { @@ -302,11 +343,11 @@ void playerThrowObject(struct Player* player) { return; } - struct Transform throwTransform = player->lookTransform; - playerPortalGrabTransform(player, &throwTransform.position, &throwTransform.rotation); + struct Quaternion throwRotation = player->lookTransform.rotation; + playerPortalGrabRotate(player, &throwRotation); struct Vector3 forward, right; - playerGetMoveBasis(&throwTransform, &forward, &right); + playerGetMoveBasis(&throwRotation, &forward, &right); struct CollisionObject* object = player->grabConstraint.object; playerSetGrabbing(player, NULL); @@ -356,9 +397,9 @@ void playerUpdateGrabbedObject(struct Player* player) { hit.object->flags |= COLLISION_OBJECT_INTERACTED; if (hit.object->body && (hit.object->body->flags & RigidBodyFlagsGrabbable) && !(hit.object->flags & COLLISION_OBJECT_PLAYER_STANDING)) { - playerSetGrabbing(player, hit.object); player->flags |= PlayerJustSelect; player->grabbingThroughPortal = hit.numPortalsPassed; + playerSetGrabbing(player, hit.object); } else if ((hit.object->body)){ player->flags |= PlayerJustSelect; @@ -431,14 +472,14 @@ void playerUpdateGrabbedObject(struct Player* player) { // keep object at steady XZ-planar distance in front of player struct Quaternion forwardRotation; struct Vector3 forward, forwardNegate, right; - playerGetMoveBasis(&player->lookTransform, &forward, &right); + playerGetMoveBasis(&player->lookTransform.rotation, &forward, &right); vector3Negate(&forward, &forwardNegate); quatLook(&forwardNegate, &gUp, &forwardRotation); quatMultVector(&forwardRotation, &temp_grab_dist, &grabPoint); vector3Add(&player->lookTransform.position, &grabPoint, &grabPoint); grabPoint.y += grabY; - struct Quaternion grabRotation = forwardRotation; + struct Quaternion grabRotation; if (player->grabbingThroughPortal != PLAYER_GRABBING_THROUGH_NOTHING) { if (!collisionSceneIsPortalOpen()) { @@ -447,22 +488,25 @@ void playerUpdateGrabbedObject(struct Player* player) { return; } - playerPortalGrabTransform(player, &grabPoint, &grabRotation); + playerPortalGrabTransform(player, &grabPoint, &forwardRotation); } + + // maintain object's relative rotation + quatMultiply(&forwardRotation, &player->grabRotationBase, &grabRotation); pointConstraintUpdateTarget(&player->grabConstraint, &grabPoint, &grabRotation); } } -void playerGetMoveBasis(struct Transform* transform, struct Vector3* forward, struct Vector3* right) { - quatMultVector(&transform->rotation, &gForward, forward); - quatMultVector(&transform->rotation, &gRight, right); +void playerGetMoveBasis(struct Quaternion* rotation, struct Vector3* forward, struct Vector3* right) { + quatMultVector(rotation, &gForward, forward); + quatMultVector(rotation, &gRight, right); if (forward->y > 0.7f) { - quatMultVector(&transform->rotation, &gUp, forward); + quatMultVector(rotation, &gUp, forward); vector3Negate(forward, forward); } else if (forward->y < -0.7f) { - quatMultVector(&transform->rotation, &gUp, forward); + quatMultVector(rotation, &gUp, forward); } forward->y = 0.0f; @@ -488,6 +532,21 @@ void playerPortalGrabTransform(struct Player* player, struct Vector3* grabPoint, } } +void playerPortalGrabRotate(struct Player* player, struct Quaternion* grabRotation) { + if (player->grabbingThroughPortal == PLAYER_GRABBING_THROUGH_NOTHING) { + return; + } + + struct Quaternion portalRotation; + collisionSceneGetPortalRotation(player->grabbingThroughPortal > 0 ? 0 : 1, &portalRotation); + + for (int i = 0; i < abs(player->grabbingThroughPortal); ++i) { + struct Quaternion finalRotation; + quatMultiply(&portalRotation, grabRotation, &finalRotation); + *grabRotation = finalRotation; + } +} + void playerGivePortalGun(struct Player* player, int flags) { player->flags |= flags; } @@ -731,7 +790,7 @@ void playerUpdate(struct Player* player) { skBlenderUpdate(&player->animator, player->armature.pose, FIXED_DELTA_TIME); int doorwayMask = worldCheckDoorwaySides(&gCurrentLevel->world, &player->lookTransform.position, player->body.currentRoom); - playerGetMoveBasis(&player->lookTransform, &forward, &right); + playerGetMoveBasis(&player->lookTransform.rotation, &forward, &right); int isDead = playerIsDead(player); diff --git a/src/player/player.h b/src/player/player.h index 53d7550d..8fca76f2 100644 --- a/src/player/player.h +++ b/src/player/player.h @@ -41,6 +41,7 @@ struct Player { short grabbingThroughPortal; short dynamicId; struct PointConstraint grabConstraint; + struct Quaternion grabRotationBase; float pitchVelocity; float yawVelocity; enum PlayerFlags flags; @@ -63,8 +64,9 @@ void playerUpdate(struct Player* player); void playerUpdateFooting(struct Player* player, float maxStandDistance); void playerApplyCameraTransform(struct Player* player, struct Transform* cameraTransform); -void playerGetMoveBasis(struct Transform* transform, struct Vector3* forward, struct Vector3* right); +void playerGetMoveBasis(struct Quaternion* rotation, struct Vector3* forward, struct Vector3* right); void playerPortalGrabTransform(struct Player* player, struct Vector3* point, struct Quaternion* rotation); +void playerPortalGrabRotate(struct Player* player, struct Quaternion* grabRotation); void playerGivePortalGun(struct Player* player, int flags); From bce6a41fcbe06e479a34fbc427eee65c1977ede9 Mon Sep 17 00:00:00 2001 From: Deconimus Date: Fri, 29 Mar 2024 15:01:38 +0100 Subject: [PATCH 2/6] fix playerGetMoveBasis call in scene.c --- src/scene/scene.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scene/scene.c b/src/scene/scene.c index 9c0cba6f..12a7ff58 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -778,7 +778,7 @@ void sceneUpdate(struct Scene* scene) { struct Vector3 lookDir; struct Vector3 rightDir; - playerGetMoveBasis(&scene->camera.transform, &lookDir, &rightDir); + playerGetMoveBasis(&scene->camera.transform.rotation, &lookDir, &rightDir); if (freecam->stick_y) { if (controllerGetButton(2, Z_TRIG)) { From 7e3db777319cbe972714810347a5f8779d63af26 Mon Sep 17 00:00:00 2001 From: Deconimus Date: Sat, 30 Mar 2024 23:12:18 +0100 Subject: [PATCH 3/6] fix cube normal snapping (has been broken in cases where object's upwards direction wasn't equal to gUp) --- src/player/player.c | 49 ++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/player/player.c b/src/player/player.c index 7a90ce1c..9690ed92 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -265,19 +265,20 @@ void playerSetGrabbing(struct Player* player, struct CollisionObject* grabbing) } if (player->grabConstraint.object) { - struct Quaternion forwardRotationInv = player->lookTransform.rotation; - playerPortalGrabRotate(player, &forwardRotationInv); - struct Vector3 forward, tmpVec; - playerGetMoveBasis(&forwardRotationInv, &forward, &tmpVec); + struct Quaternion forwardRotation = player->lookTransform.rotation; + struct Vector3 forward, tmpVec, up; + playerGetMoveBasis(&forwardRotation, &forward, &tmpVec); vector3Negate(&forward, &tmpVec); - quatLook(&tmpVec, &gUp, &forwardRotationInv); - quatConjugate(&forwardRotationInv, &forwardRotationInv); + quatLook(&tmpVec, &gUp, &forwardRotation); + playerPortalGrabRotate(player, &forwardRotation); + quatMultVector(&forwardRotation, &gForward, &forward); + quatMultVector(&forwardRotation, &gUp, &up); struct Quaternion objectRotation = player->grabConstraint.object->body->transform.rotation; - // snap target rotation to nearest cube normal - struct Vector3 surfaceNormal, closestNormal; - float closestNormalDot = 1.0f; // has to be negative on success + // snap target rotation to nearest cube normals + struct Vector3 surfaceNormal, closestNormalTowards, closestNormalUp; + float closestNormalTowardsDot = 1.0f, closestNormalUpDot = -1.0f; // has to be negative on success for (int i = 0; i < 6; ++i) { if (i == 0) { surfaceNormal = (struct Vector3){ 1.0f, 0.0f, 0.0f}; } else if (i == 1) { surfaceNormal = (struct Vector3){-1.0f, 0.0f, 0.0f}; } @@ -287,22 +288,28 @@ void playerSetGrabbing(struct Player* player, struct CollisionObject* grabbing) else if (i == 5) { surfaceNormal = (struct Vector3){ 0.0f, 0.0f, -1.0f}; } quatMultVector(&objectRotation, &surfaceNormal, &surfaceNormal); - float normalDot = vector3Dot(&surfaceNormal, &forward); - if (normalDot < 0.0f && normalDot < closestNormalDot) { - closestNormalDot = normalDot; - closestNormal = surfaceNormal; + float dot = vector3Dot(&surfaceNormal, &forward); + if (dot < closestNormalTowardsDot) { + closestNormalTowardsDot = dot; + closestNormalTowards = surfaceNormal; + } + dot = vector3Dot(&surfaceNormal, &up); + if (dot > closestNormalUpDot) { + closestNormalUpDot = dot; + closestNormalUp = surfaceNormal; } } - if (closestNormalDot < 0.0f) { - struct Quaternion surfaceRotation; - quatLook(&closestNormal, &gUp, &surfaceRotation); - quatMultiply(&forwardRotationInv, &surfaceRotation, &objectRotation); - quatConjugate(&objectRotation, &surfaceRotation); - quatMultiply(&surfaceRotation, &player->grabConstraint.object->body->transform.rotation, &objectRotation); - } + quatConjugate(&objectRotation, &objectRotation); + quatMultVector(&objectRotation, &closestNormalTowards, &closestNormalTowards); + quatMultVector(&objectRotation, &closestNormalUp, &closestNormalUp); + struct Quaternion normalRotation; + quatLook(&closestNormalTowards, &closestNormalUp, &normalRotation); + quatConjugate(&normalRotation, &normalRotation); + quatMultiply(&forwardRotation, &normalRotation, &objectRotation); // untangle objectRotation from relative forwardRotation, store as grabRotationBase - quatMultiply(&forwardRotationInv, &objectRotation, &player->grabRotationBase); + quatConjugate(&forwardRotation, &forwardRotation); + quatMultiply(&forwardRotation, &objectRotation, &player->grabRotationBase); } } From 4ca1c484f177b8220441cbfdac9474bf8cfef6c2 Mon Sep 17 00:00:00 2001 From: Deconimus Date: Thu, 4 Apr 2024 12:12:58 +0200 Subject: [PATCH 4/6] player grab rotation cleanup --- src/player/player.c | 123 +++++++++++++++++++++----------------------- src/player/player.h | 2 +- 2 files changed, 59 insertions(+), 66 deletions(-) diff --git a/src/player/player.c b/src/player/player.c index 9690ed92..25f5f16a 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -76,6 +76,15 @@ struct ColliderTypeData gPlayerColliderData = { &gCollisionCapsuleCallbacks, }; +struct Vector3 gCubeNormals[6] = { + { 1.0f, 0.0f, 0.0f }, + { -1.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f }, + { 0.0f, -1.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f }, + { 0.0f, 0.0f, -1.0f } +}; + void playerRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState) { struct Player* player = (struct Player*)data; @@ -264,53 +273,52 @@ void playerSetGrabbing(struct Player* player, struct CollisionObject* grabbing) pointConstraintInit(&player->grabConstraint, grabbing, 8.0f, 5.0f, 1.0f); } - if (player->grabConstraint.object) { - struct Quaternion forwardRotation = player->lookTransform.rotation; - struct Vector3 forward, tmpVec, up; - playerGetMoveBasis(&forwardRotation, &forward, &tmpVec); - vector3Negate(&forward, &tmpVec); - quatLook(&tmpVec, &gUp, &forwardRotation); - playerPortalGrabRotate(player, &forwardRotation); - quatMultVector(&forwardRotation, &gForward, &forward); - quatMultVector(&forwardRotation, &gUp, &up); - - struct Quaternion objectRotation = player->grabConstraint.object->body->transform.rotation; + playerInitGrabRotationBase(player); +} + +void playerInitGrabRotationBase(struct Player* player) { + if (!player->grabConstraint.object) { + return; + } + struct Quaternion forwardRotation = player->lookTransform.rotation; + struct Vector3 forward, tmpVec, up; + playerGetMoveBasis(&forwardRotation, &forward, &tmpVec); + vector3Negate(&forward, &tmpVec); + quatLook(&tmpVec, &gUp, &forwardRotation); + playerPortalGrabTransform(player, NULL, &forwardRotation); + quatMultVector(&forwardRotation, &gForward, &forward); + quatMultVector(&forwardRotation, &gUp, &up); + + struct Quaternion objectRotation = player->grabConstraint.object->body->transform.rotation; + + // snap target rotation to nearest cube normals + struct Vector3 surfaceNormal, closestNormalTowards, closestNormalUp; + float closestNormalTowardsDot = 1.0f, closestNormalUpDot = -1.0f; // has to be negative on success + for (int i = 0; i < 6; ++i) { + quatMultVector(&objectRotation, &gCubeNormals[i], &surfaceNormal); - // snap target rotation to nearest cube normals - struct Vector3 surfaceNormal, closestNormalTowards, closestNormalUp; - float closestNormalTowardsDot = 1.0f, closestNormalUpDot = -1.0f; // has to be negative on success - for (int i = 0; i < 6; ++i) { - if (i == 0) { surfaceNormal = (struct Vector3){ 1.0f, 0.0f, 0.0f}; } - else if (i == 1) { surfaceNormal = (struct Vector3){-1.0f, 0.0f, 0.0f}; } - else if (i == 2) { surfaceNormal = (struct Vector3){ 0.0f, 1.0f, 0.0f}; } - else if (i == 3) { surfaceNormal = (struct Vector3){ 0.0f, -1.0f, 0.0f}; } - else if (i == 4) { surfaceNormal = (struct Vector3){ 0.0f, 0.0f, 1.0f}; } - else if (i == 5) { surfaceNormal = (struct Vector3){ 0.0f, 0.0f, -1.0f}; } - quatMultVector(&objectRotation, &surfaceNormal, &surfaceNormal); - - float dot = vector3Dot(&surfaceNormal, &forward); - if (dot < closestNormalTowardsDot) { - closestNormalTowardsDot = dot; - closestNormalTowards = surfaceNormal; - } - dot = vector3Dot(&surfaceNormal, &up); - if (dot > closestNormalUpDot) { - closestNormalUpDot = dot; - closestNormalUp = surfaceNormal; - } + float dot = vector3Dot(&surfaceNormal, &forward); + if (dot < closestNormalTowardsDot) { + closestNormalTowardsDot = dot; + closestNormalTowards = surfaceNormal; + } + dot = vector3Dot(&surfaceNormal, &up); + if (dot > closestNormalUpDot) { + closestNormalUpDot = dot; + closestNormalUp = surfaceNormal; } - quatConjugate(&objectRotation, &objectRotation); - quatMultVector(&objectRotation, &closestNormalTowards, &closestNormalTowards); - quatMultVector(&objectRotation, &closestNormalUp, &closestNormalUp); - struct Quaternion normalRotation; - quatLook(&closestNormalTowards, &closestNormalUp, &normalRotation); - quatConjugate(&normalRotation, &normalRotation); - quatMultiply(&forwardRotation, &normalRotation, &objectRotation); - - // untangle objectRotation from relative forwardRotation, store as grabRotationBase - quatConjugate(&forwardRotation, &forwardRotation); - quatMultiply(&forwardRotation, &objectRotation, &player->grabRotationBase); } + quatConjugate(&objectRotation, &objectRotation); + quatMultVector(&objectRotation, &closestNormalTowards, &closestNormalTowards); + quatMultVector(&objectRotation, &closestNormalUp, &closestNormalUp); + struct Quaternion normalRotation; + quatLook(&closestNormalTowards, &closestNormalUp, &normalRotation); + quatConjugate(&normalRotation, &normalRotation); + quatMultiply(&forwardRotation, &normalRotation, &objectRotation); + + // untangle objectRotation from relative forwardRotation, store as grabRotationBase + quatConjugate(&forwardRotation, &forwardRotation); + quatMultiply(&forwardRotation, &objectRotation, &player->grabRotationBase); } void playerShakeUpdate(struct Player* player) { @@ -349,9 +357,8 @@ void playerThrowObject(struct Player* player) { if (!playerIsGrabbing(player)) { return; } - struct Quaternion throwRotation = player->lookTransform.rotation; - playerPortalGrabRotate(player, &throwRotation); + playerPortalGrabTransform(player, NULL, &throwRotation); struct Vector3 forward, right; playerGetMoveBasis(&throwRotation, &forward, &right); @@ -475,7 +482,7 @@ void playerUpdateGrabbedObject(struct Player* player) { // determine object target height quatMultVector(&player->lookTransform.rotation, &temp_grab_dist, &grabPoint); float grabY = grabPoint.y; -// + // keep object at steady XZ-planar distance in front of player struct Quaternion forwardRotation; struct Vector3 forward, forwardNegate, right; @@ -527,29 +534,15 @@ void playerPortalGrabTransform(struct Player* player, struct Vector3* grabPoint, if (player->grabbingThroughPortal == PLAYER_GRABBING_THROUGH_NOTHING) { return; } - struct Transform pointTransform; collisionSceneGetPortalTransform(player->grabbingThroughPortal > 0 ? 0 : 1, &pointTransform); - - for (int i = 0; i < abs(player->grabbingThroughPortal); ++i) { - transformPoint(&pointTransform, grabPoint, grabPoint); - struct Quaternion finalRotation; - quatMultiply(&pointTransform.rotation, grabRotation, &finalRotation); - *grabRotation = finalRotation; - } -} - -void playerPortalGrabRotate(struct Player* player, struct Quaternion* grabRotation) { - if (player->grabbingThroughPortal == PLAYER_GRABBING_THROUGH_NOTHING) { - return; - } - - struct Quaternion portalRotation; - collisionSceneGetPortalRotation(player->grabbingThroughPortal > 0 ? 0 : 1, &portalRotation); for (int i = 0; i < abs(player->grabbingThroughPortal); ++i) { + if (grabPoint) { + transformPoint(&pointTransform, grabPoint, grabPoint); + } struct Quaternion finalRotation; - quatMultiply(&portalRotation, grabRotation, &finalRotation); + quatMultiply(&pointTransform.rotation, grabRotation, &finalRotation); *grabRotation = finalRotation; } } diff --git a/src/player/player.h b/src/player/player.h index 8fca76f2..4a2da1b7 100644 --- a/src/player/player.h +++ b/src/player/player.h @@ -66,7 +66,7 @@ void playerApplyCameraTransform(struct Player* player, struct Transform* cameraT void playerGetMoveBasis(struct Quaternion* rotation, struct Vector3* forward, struct Vector3* right); void playerPortalGrabTransform(struct Player* player, struct Vector3* point, struct Quaternion* rotation); -void playerPortalGrabRotate(struct Player* player, struct Quaternion* grabRotation); +void playerInitGrabRotationBase(struct Player* player); void playerGivePortalGun(struct Player* player, int flags); From 97b31b4579df3a1d5023ed787f39052a817dbf5b Mon Sep 17 00:00:00 2001 From: Deconimus Date: Fri, 5 Apr 2024 13:00:23 +0200 Subject: [PATCH 5/6] grab_rotation: simplifying playerInitGrabRotationBase() --- src/player/player.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/player/player.c b/src/player/player.c index 25f5f16a..105390a4 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -292,33 +292,25 @@ void playerInitGrabRotationBase(struct Player* player) { struct Quaternion objectRotation = player->grabConstraint.object->body->transform.rotation; // snap target rotation to nearest cube normals - struct Vector3 surfaceNormal, closestNormalTowards, closestNormalUp; - float closestNormalTowardsDot = 1.0f, closestNormalUpDot = -1.0f; // has to be negative on success + int closestNormalUp = 0, closestNormalTowards = 0; + float closestNormalTowardsDot = 1.0f, closestNormalUpDot = -1.0f; for (int i = 0; i < 6; ++i) { + struct Vector3 surfaceNormal; quatMultVector(&objectRotation, &gCubeNormals[i], &surfaceNormal); float dot = vector3Dot(&surfaceNormal, &forward); if (dot < closestNormalTowardsDot) { closestNormalTowardsDot = dot; - closestNormalTowards = surfaceNormal; + closestNormalTowards = i; } dot = vector3Dot(&surfaceNormal, &up); if (dot > closestNormalUpDot) { closestNormalUpDot = dot; - closestNormalUp = surfaceNormal; + closestNormalUp = i; } } - quatConjugate(&objectRotation, &objectRotation); - quatMultVector(&objectRotation, &closestNormalTowards, &closestNormalTowards); - quatMultVector(&objectRotation, &closestNormalUp, &closestNormalUp); - struct Quaternion normalRotation; - quatLook(&closestNormalTowards, &closestNormalUp, &normalRotation); - quatConjugate(&normalRotation, &normalRotation); - quatMultiply(&forwardRotation, &normalRotation, &objectRotation); - - // untangle objectRotation from relative forwardRotation, store as grabRotationBase - quatConjugate(&forwardRotation, &forwardRotation); - quatMultiply(&forwardRotation, &objectRotation, &player->grabRotationBase); + quatLook(&gCubeNormals[closestNormalTowards], &gCubeNormals[closestNormalUp], &objectRotation); + quatConjugate(&objectRotation, &player->grabRotationBase); } void playerShakeUpdate(struct Player* player) { @@ -535,7 +527,11 @@ void playerPortalGrabTransform(struct Player* player, struct Vector3* grabPoint, return; } struct Transform pointTransform; - collisionSceneGetPortalTransform(player->grabbingThroughPortal > 0 ? 0 : 1, &pointTransform); + if (grabPoint) { + collisionSceneGetPortalTransform(player->grabbingThroughPortal > 0 ? 0 : 1, &pointTransform); + } else { + collisionSceneGetPortalRotation(player->grabbingThroughPortal > 0 ? 0 : 1, &pointTransform.rotation); + } for (int i = 0; i < abs(player->grabbingThroughPortal); ++i) { if (grabPoint) { From 62c49ddcdf9032f97fe1f537262a875ab8dcb827 Mon Sep 17 00:00:00 2001 From: Matt Penny Date: Fri, 5 Apr 2024 20:18:25 -0400 Subject: [PATCH 6/6] Remove collisionSceneGetPortalRotation() --- src/physics/collision_scene.c | 6 ------ src/physics/collision_scene.h | 1 - src/player/player.c | 6 +----- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/physics/collision_scene.c b/src/physics/collision_scene.c index 3c55e60e..073e2045 100644 --- a/src/physics/collision_scene.c +++ b/src/physics/collision_scene.c @@ -514,12 +514,6 @@ void collisionSceneGetPortalTransform(int fromPortal, struct Transform* out) { transformConcat(gCollisionScene.portalTransforms[1 - fromPortal], &inverseA, out); } -void collisionSceneGetPortalRotation(int fromPortal, struct Quaternion* out) { - struct Quaternion inverse; - quatConjugate(&gCollisionScene.portalTransforms[fromPortal]->rotation, &inverse); - quatMultiply(&gCollisionScene.portalTransforms[1 - fromPortal]->rotation, &inverse, out); -} - void collisionSceneAddDynamicObject(struct CollisionObject* object) { if (gCollisionScene.dynamicObjectCount < MAX_DYNAMIC_OBJECTS) { gCollisionScene.dynamicObjects[gCollisionScene.dynamicObjectCount] = object; diff --git a/src/physics/collision_scene.h b/src/physics/collision_scene.h index aa514e0d..32fe798b 100644 --- a/src/physics/collision_scene.h +++ b/src/physics/collision_scene.h @@ -49,7 +49,6 @@ int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ra int collisionSceneRaycastOnlyDynamic(struct CollisionScene* scene, struct Ray* ray, int collisionLayers, float maxDistance, struct RaycastHit* hit); void collisionSceneGetPortalTransform(int fromPortal, struct Transform* out); -void collisionSceneGetPortalRotation(int fromPortal, struct Quaternion* out); void collisionSceneAddDynamicObject(struct CollisionObject* object); void collisionSceneRemoveDynamicObject(struct CollisionObject* object); diff --git a/src/player/player.c b/src/player/player.c index 105390a4..f7ca2efa 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -527,11 +527,7 @@ void playerPortalGrabTransform(struct Player* player, struct Vector3* grabPoint, return; } struct Transform pointTransform; - if (grabPoint) { - collisionSceneGetPortalTransform(player->grabbingThroughPortal > 0 ? 0 : 1, &pointTransform); - } else { - collisionSceneGetPortalRotation(player->grabbingThroughPortal > 0 ? 0 : 1, &pointTransform.rotation); - } + collisionSceneGetPortalTransform(player->grabbingThroughPortal > 0 ? 0 : 1, &pointTransform); for (int i = 0; i < abs(player->grabbingThroughPortal); ++i) { if (grabPoint) {