From a946b027cfcf2cd218f36a7f008d84c9bf0bd02a Mon Sep 17 00:00:00 2001 From: Weston Salinas Date: Wed, 29 Mar 2023 22:07:11 -0500 Subject: [PATCH] Portal Gun Movement Cleanup - the portal gun has much cleaner movement now - portal gun has a recoil timer when it shoots for more game accurate animation - portal gun is being "clamped" to an invisible sphere around its constraint point, so it can only go so far in one direction. --- src/physics/point_constraint.c | 18 +++++++++++++++--- src/physics/point_constraint.h | 1 + src/player/player.c | 12 +++++------- src/scene/portal_gun.c | 29 ++++++++++++++++------------- src/scene/portal_gun.h | 5 +++-- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/physics/point_constraint.c b/src/physics/point_constraint.c index 37b12a1..df33c19 100644 --- a/src/physics/point_constraint.c +++ b/src/physics/point_constraint.c @@ -3,11 +3,11 @@ #include "../util/time.h" #define BREAK_CONSTRAINT_DISTANCE 2.0f +#define CLAMP_CONSTRAINT_DISTANCE 0.07f int pointConstraintMoveToPoint(struct CollisionObject* object, struct Vector3* worldPoint, float maxImpulse, int teleportOnBreak, float movementScaleFactor) { struct RigidBody* rigidBody = object->body; - struct Vector3 targetVelocity; vector3Sub(worldPoint, &rigidBody->transform.position, &targetVelocity); @@ -18,8 +18,20 @@ int pointConstraintMoveToPoint(struct CollisionObject* object, struct Vector3* w } return 0; } - - vector3Scale(&targetVelocity, &targetVelocity, 1.0f / FIXED_DELTA_TIME); + if (teleportOnBreak){ + if (fabsf(sqrtf(vector3DistSqrd(worldPoint, &rigidBody->transform.position))) > CLAMP_CONSTRAINT_DISTANCE){ + while(sqrtf(vector3DistSqrd(worldPoint, &rigidBody->transform.position)) > CLAMP_CONSTRAINT_DISTANCE){ + vector3Lerp(&rigidBody->transform.position, worldPoint, 0.01, &rigidBody->transform.position); + } + vector3Sub(worldPoint, &rigidBody->transform.position, &targetVelocity); + vector3Scale(&targetVelocity, &targetVelocity, (1.0f / FIXED_DELTA_TIME)); + vector3Scale(&targetVelocity, &targetVelocity, 0.5); + rigidBody->velocity = targetVelocity; + return 1; + } + } + + vector3Scale(&targetVelocity, &targetVelocity, (1.0f / FIXED_DELTA_TIME)); struct ContactManifold* contact = contactSolverNextManifold(&gContactSolver, object, NULL); diff --git a/src/physics/point_constraint.h b/src/physics/point_constraint.h index d686e51..56b2e22 100644 --- a/src/physics/point_constraint.h +++ b/src/physics/point_constraint.h @@ -3,6 +3,7 @@ #include "rigid_body.h" #include "collision_object.h" +#include "../math/mathf.h" struct PointConstraint { struct PointConstraint* nextConstraint; diff --git a/src/player/player.c b/src/player/player.c index c2c2aa8..e8f8ed8 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -32,10 +32,10 @@ struct Vector3 gGrabDistance = {0.0f, 0.0f, -1.5f}; struct Vector3 gCameraOffset = {0.0f, 0.0f, 0.0f}; -struct Vector3 gPortalGunOffset = {0.150957, -0.153587, -0.355}; -struct Vector3 gPortalGunShootOffset = {0.150957, -0.153587, 0.1}; +struct Vector3 gPortalGunOffset = {0.120957, -0.113587, -0.20916}; +struct Vector3 gPortalGunShootOffset = {0.120957, -0.113587, -0.08}; struct Vector3 gPortalGunForward = {0.1f, -0.1f, 1.0f}; -struct Vector3 gPortalGunShootForward = {0.1f, -0.25f, 1.0f}; +struct Vector3 gPortalGunShootForward = {0.3f, -0.25f, 1.0f}; struct Vector3 gPortalGunUp = {0.0f, 1.0f, 0.0f}; struct Vector2 gPlayerColliderEdgeVectors[] = { @@ -173,7 +173,7 @@ void playerInit(struct Player* player, struct Location* startLocation, struct Ve dynamicSceneSetRoomFlags(player->dynamicId, ROOM_FLAG_FROM_INDEX(player->body.currentRoom)); - pointConstraintInit(&player->gunConstraint, portalGunObject, 20.0f, 2.5f, 1, 0.9f); + pointConstraintInit(&player->gunConstraint, portalGunObject, 20.0f, 2.5f, 1, 0.5f); contactSolverAddPointConstraint(&gContactSolver, &player->gunConstraint); } @@ -389,11 +389,9 @@ void playerUpdateGunObject(struct Player* player) { struct Vector3 offset; if (player->flags & PlayerJustShotPortalGun){ - player->flags &= ~PlayerJustShotPortalGun; forward = gPortalGunShootForward; offset = gPortalGunShootOffset; - } - else{ + }else{ forward = gPortalGunForward; offset = gPortalGunOffset; } diff --git a/src/scene/portal_gun.c b/src/scene/portal_gun.c index f708943..04c0f79 100644 --- a/src/scene/portal_gun.c +++ b/src/scene/portal_gun.c @@ -4,6 +4,8 @@ #include "../physics/collision_cylinder.h" #include "models/models.h" +#define PORTAL_GUN_RECOIL_TIME (0.18f) + struct Vector2 gGunColliderEdgeVectors[] = { {0.0f, 1.0f}, {0.707f, 0.707f}, @@ -37,16 +39,9 @@ void portalGunInit(struct PortalGun* portalGun, struct Transform* at){ portalGun->rigidBody.currentRoom = 0; portalGun->rigidBody.velocity = gZeroVec; portalGun->rigidBody.angularVelocity = gZeroVec; - portalGun->dynamicId = dynamicSceneAdd(portalGun, portalGunDummyRender, &portalGun->rigidBody.transform.position, 0.05f); portalGun->portalGunVisible = 0; + portalGun->shootAnimationTimer = 0.0; - collisionObjectUpdateBB(&portalGun->collisionObject); - dynamicSceneSetRoomFlags(portalGun->dynamicId, ROOM_FLAG_FROM_INDEX(portalGun->rigidBody.currentRoom)); - -} - -void portalGunDummyRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState){ - return; } void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState){ @@ -65,14 +60,22 @@ void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* render } } - - void portalGunUpdate(struct PortalGun* portalGun, struct Player* player){ if (player->flags & (PlayerHasFirstPortalGun | PlayerHasSecondPortalGun)){ portalGun->portalGunVisible = 1; - } - else{ + }else{ portalGun->portalGunVisible = 0; } - dynamicSceneSetRoomFlags(portalGun->dynamicId, ROOM_FLAG_FROM_INDEX(portalGun->rigidBody.currentRoom)); + + if (player->flags & PlayerJustShotPortalGun && portalGun->shootAnimationTimer <= 0.0f){ + portalGun->shootAnimationTimer = PORTAL_GUN_RECOIL_TIME; + } + + if (portalGun->shootAnimationTimer >= 0.0f){ + portalGun->shootAnimationTimer -= FIXED_DELTA_TIME; + if (portalGun->shootAnimationTimer <= 0.0f){ + portalGun->shootAnimationTimer = 0.0f; + player->flags &= ~PlayerJustShotPortalGun; + } + } } \ No newline at end of file diff --git a/src/scene/portal_gun.h b/src/scene/portal_gun.h index 65aee13..21b04a1 100644 --- a/src/scene/portal_gun.h +++ b/src/scene/portal_gun.h @@ -8,16 +8,17 @@ #include "../physics/collision_object.h" #include "../scene/dynamic_scene.h" #include "../player/player.h" +#include "../util/time.h" struct PortalGun { struct CollisionObject collisionObject; struct RigidBody rigidBody; int portalGunVisible; - short dynamicId; + float shootAnimationTimer; }; void portalGunInit(struct PortalGun* portalGun, struct Transform* at); -void portalGunDummyRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState); +// void portalGunDummyRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState); void portalGunUpdate(struct PortalGun* portalGun, struct Player* player); void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState);