diff --git a/README.md b/README.md index 07aece9..eedb9ac 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,10 @@ where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where blender ## Current TODO list -Cylinder touching bug Create elevator geometry -Allow player to press button Collide player with objects in scene +Cylinder touching bug +Allow player to press button Radio Create radio model Create radio texture diff --git a/src/physics/collision.h b/src/physics/collision.h index 5599803..edf2a88 100644 --- a/src/physics/collision.h +++ b/src/physics/collision.h @@ -21,6 +21,7 @@ enum CollisionShapeType { struct ColliderTypeData; struct CollisionObject; struct RaycastHit; +struct CollisionSphere; typedef float (*MomentOfInertiaCalculator)(struct ColliderTypeData* typeData, float mass); typedef void (*BoundingBoxCalculator)(struct ColliderTypeData* typeData, struct Transform* transform, struct Box3D* box); @@ -31,12 +32,15 @@ typedef int (*RaycastCollider)(struct CollisionObject* object, struct Ray* ray, typedef int (*MinkowsiSumWithBasis)(void* data, struct Basis* basis, struct Vector3* direction, struct Vector3* output); +typedef int (*CollideWithSphere)(void* data, struct Transform* transform, struct CollisionSphere* sphere, struct Vector3* spherePos, struct ContactManifold* contact); + struct ColliderCallbacks { CollideWithQuad collideWithQuad; RaycastCollider raycast; MomentOfInertiaCalculator mofICalculator; BoundingBoxCalculator boundingBoxCalculator; MinkowsiSumWithBasis minkowsiSum; + CollideWithSphere collideWithSphere; }; struct ColliderTypeData { diff --git a/src/physics/collision_object.c b/src/physics/collision_object.c index 59f3940..477ea57 100644 --- a/src/physics/collision_object.c +++ b/src/physics/collision_object.c @@ -17,6 +17,10 @@ int collisionObjectIsActive(struct CollisionObject* object) { return object->body && (object->body->flags & (RigidBodyIsKinematic | RigidBodyIsSleeping)) == 0; } +int collisionObjectShouldGenerateConctacts(struct CollisionObject* object) { + return collisionObjectIsActive(object) || (object->body->flags & RigidBodyGenerateContacts) != 0; +} + void collisionObjectCollideWithQuad(struct CollisionObject* object, struct CollisionObject* quadObject, struct ContactSolver* contactSolver) { if ((object->collisionLayers | quadObject->collisionLayers) == 0) { return; diff --git a/src/physics/collision_object.h b/src/physics/collision_object.h index e065473..aaa6e32 100644 --- a/src/physics/collision_object.h +++ b/src/physics/collision_object.h @@ -18,6 +18,7 @@ struct CollisionObject { }; int collisionObjectIsActive(struct CollisionObject* object); +int collisionObjectShouldGenerateConctacts(struct CollisionObject* object); void collisionObjectInit(struct CollisionObject* object, struct ColliderTypeData *collider, struct RigidBody* body, float mass, int collisionLayers); diff --git a/src/physics/collision_scene.c b/src/physics/collision_scene.c index 0f71af3..99932a8 100644 --- a/src/physics/collision_scene.c +++ b/src/physics/collision_scene.c @@ -515,7 +515,7 @@ void collisionSceneWalkBroadphase(struct CollisionScene* collisionScene, struct continue; } - if (!collisionObjectIsActive(existing) && !collisionObjectIsActive(subject)) { + if (!collisionObjectShouldGenerateConctacts(existing) && !collisionObjectShouldGenerateConctacts(subject)) { continue; } @@ -571,7 +571,7 @@ void collisionSceneUpdateDynamics() { contactSolverRemoveUnusedContacts(&gContactSolver); for (unsigned i = 0; i < gCollisionScene.dynamicObjectCount; ++i) { - if (!collisionObjectIsActive(gCollisionScene.dynamicObjects[i])) { + if (!collisionObjectShouldGenerateConctacts(gCollisionScene.dynamicObjects[i])) { continue; } @@ -585,9 +585,14 @@ void collisionSceneUpdateDynamics() { for (unsigned i = 0; i < gCollisionScene.dynamicObjectCount; ++i) { struct CollisionObject* collisionObject = gCollisionScene.dynamicObjects[i]; if (!collisionObjectIsActive(collisionObject)) { - // clear out any velocities - collisionObject->body->velocity = gZeroVec; - collisionObject->body->angularVelocity = gZeroVec; + // kind of a hack, but the player is the only kinematic body that + // also generates contacts and the player velocty should not be + // cleared + if (!collisionObjectShouldGenerateConctacts(collisionObject)) { + // clear out any velocities + collisionObject->body->velocity = gZeroVec; + collisionObject->body->angularVelocity = gZeroVec; + } continue; } diff --git a/src/physics/collision_sphere.c b/src/physics/collision_sphere.c index 4f44c58..e50392a 100644 --- a/src/physics/collision_sphere.c +++ b/src/physics/collision_sphere.c @@ -84,4 +84,82 @@ struct ColliderCallbacks gCollisionSphereCallbacks = { NULL, // TODO collisionSphereSolidMofI, collisionSphereBoundingBox, -}; \ No newline at end of file + NULL, + collisionSphereCollideWithSphere, +}; + +int collisionSphereCheckWithNearestPoint(struct Vector3* nearestPoint, struct CollisionSphere* otherSphere, struct Vector3* spherePos, struct ContactManifold* contact) { + vector3Sub(spherePos, nearestPoint, &contact->normal); + + float distanceSqrd = vector3MagSqrd(&contact->normal); + + if (distanceSqrd > otherSphere->radius * otherSphere->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, otherSphere->radius); + vector3Scale(&contact->normal, &contactPoint->contactBWorld, -otherSphere->radius); + + contactPoint->bias = 0.0f; + contactPoint->id = 0; + contactPoint->normalImpulse = 0.0f; + contactPoint->normalMass = 0.0f; + contactPoint->penetration = distance - otherSphere->radius; + contactPoint->tangentImpulse[0] = 0.0f; + contactPoint->tangentImpulse[1] = 0.0f; + contactPoint->tangentMass[0] = 0.0f; + contactPoint->tangentMass[0] = 0.0f; + + return 1; +} + +int collisionSphereCollideWithSphere(void* data, struct Transform* transform, struct CollisionSphere* otherSphere, struct Vector3* spherePos, struct ContactManifold* contact) { + struct CollisionSphere* sphere = (struct CollisionSphere*)data; + + vector3Sub(spherePos, &transform->position, &contact->normal); + + float radiusSum = sphere->radius + otherSphere->radius; + + float distanceSqrd = vector3MagSqrd(&contact->normal); + + if (distanceSqrd > radiusSum * radiusSum) { + 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, sphere->radius); + vector3Scale(&contact->normal, &contactPoint->contactBWorld, -otherSphere->radius); + + contactPoint->bias = 0.0f; + contactPoint->id = 0; + contactPoint->normalImpulse = 0.0f; + contactPoint->normalMass = 0.0f; + contactPoint->penetration = distance - radiusSum; + 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 diff --git a/src/physics/collision_sphere.h b/src/physics/collision_sphere.h index 90910ed..7cf2562 100644 --- a/src/physics/collision_sphere.h +++ b/src/physics/collision_sphere.h @@ -11,6 +11,7 @@ struct CollisionSphere { int collisionSphereCollideQuad(void* data, struct Transform* boxTransform, struct CollisionQuad* quad, struct ContactManifold* output); float collisionSphereSolidMofI(struct ColliderTypeData* typeData, float mass); - +int collisionSphereCheckWithNearestPoint(struct Vector3* nearestPoint, struct CollisionSphere* otherSphere, struct Vector3* spherePos, struct ContactManifold* contact); +int collisionSphereCollideWithSphere(void* data, struct Transform* transform, struct CollisionSphere* otherSphere, struct Vector3* spherePos, struct ContactManifold* contact); #endif \ No newline at end of file diff --git a/src/physics/contact_solver.c b/src/physics/contact_solver.c index a9fbe1a..f272372 100644 --- a/src/physics/contact_solver.c +++ b/src/physics/contact_solver.c @@ -475,6 +475,8 @@ struct ContactManifold* contactSolverGetContactManifold(struct ContactSolver* so struct ContactManifold* contactSolverNextManifold(struct ContactSolver* solver, struct CollisionObject* forObject, struct ContactManifold* current) { if (!current) { current = solver->activeContacts; + } else { + current = current->next; } while (current) { diff --git a/src/physics/rigid_body.c b/src/physics/rigid_body.c index 135492d..2997533 100644 --- a/src/physics/rigid_body.c +++ b/src/physics/rigid_body.c @@ -24,7 +24,7 @@ void rigidBodyInit(struct RigidBody* rigidBody, float mass, float momentOfIniter basisFromQuat(&rigidBody->rotationBasis, &rigidBody->transform.rotation); } -void rigitBodyMarkKinematic(struct RigidBody* rigidBody) { +void rigidBodyMarkKinematic(struct RigidBody* rigidBody) { rigidBody->flags |= RigidBodyIsKinematic; rigidBody->mass = 1000000000000000.0f; rigidBody->massInv = 0.0f; diff --git a/src/physics/rigid_body.h b/src/physics/rigid_body.h index fb7d990..8d08215 100644 --- a/src/physics/rigid_body.h +++ b/src/physics/rigid_body.h @@ -17,6 +17,9 @@ enum RigidBodyFlags { RigidBodyIsKinematic = (1 << 8), RigidBodyIsSleeping = (1 << 9), + // for kinematic bodies that should generate + // contacts with other kinematic bodies + RigidBodyGenerateContacts = (1 << 10), }; struct RigidBody { @@ -41,7 +44,7 @@ struct RigidBody { }; void rigidBodyInit(struct RigidBody* rigidBody, float mass, float momentOfIniteria); -void rigitBodyMarkKinematic(struct RigidBody* rigidBody); +void rigidBodyMarkKinematic(struct RigidBody* rigidBody); void rigidBodyAppyImpulse(struct RigidBody* rigidBody, struct Vector3* worldPoint, struct Vector3* impulse); void rigidBodyUpdate(struct RigidBody* rigidBody); void rigidBodyVelocityAtLocalPoint(struct RigidBody* rigidBody, struct Vector3* localPoint, struct Vector3* worldVelocity); diff --git a/src/player/player.c b/src/player/player.c index a9e73e2..4c16e31 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -1,36 +1,51 @@ #include "player.h" -#include "../controls/controller.h" -#include "../util/time.h" -#include "../defs.h" -#include "../physics/point_constraint.h" -#include "../math/mathf.h" -#include "physics/collision_sphere.h" -#include "physics/collision_scene.h" -#include "physics/config.h" -#include "../levels/levels.h" -#include "../audio/soundplayer.h" #include "../audio/clips.h" +#include "../audio/soundplayer.h" +#include "../controls/controller.h" +#include "../defs.h" +#include "../levels/levels.h" +#include "../math/mathf.h" +#include "../physics/collision_cylinder.h" +#include "../physics/collision_scene.h" +#include "../physics/collision.h" +#include "../physics/config.h" +#include "../physics/point_constraint.h" +#include "../util/time.h" #define GRAB_RAYCAST_DISTANCE 2.5f struct Vector3 gGrabDistance = {0.0f, 0.0f, -1.5f}; struct Vector3 gCameraOffset = {0.0f, 0.0f, 0.0f}; -struct CollisionSphere gPlayerCollider = { +struct Vector2 gPlayerColliderEdgeVectors[] = { + {0.0f, 1.0f}, + {0.707f, 0.707f}, + {1.0f, 0.0f}, + {0.707f, -0.707f}, +}; + +struct CollisionCylinder gPlayerCollider = { 0.25f, + 0.7f, + gPlayerColliderEdgeVectors, + sizeof(gPlayerColliderEdgeVectors) / sizeof(*gPlayerColliderEdgeVectors), }; struct ColliderTypeData gPlayerColliderData = { - CollisionShapeTypeSphere, + CollisionShapeTypeCylinder, &gPlayerCollider, - 0.1f, - 0.5f, - &gCollisionSphereCallbacks, + 0.0f, + 0.6f, + &gCollisionCylinderCallbacks, }; void playerInit(struct Player* player, struct Location* startLocation) { collisionObjectInit(&player->collisionObject, &gPlayerColliderData, &player->body, 1.0f, COLLISION_LAYERS_TANGIBLE); + rigidBodyMarkKinematic(&player->body); + player->body.flags |= RigidBodyGenerateContacts; + collisionSceneAddDynamicObject(&player->collisionObject); + player->grabbingThroughPortal = PLAYER_GRABBING_THROUGH_NOTHING; player->grabbing = NULL; player->pitchVelocity = 0.0f; @@ -38,13 +53,16 @@ void playerInit(struct Player* player, struct Location* startLocation) { player->flags = 0; if (startLocation) { - player->body.transform = startLocation->transform; + player->lookTransform = startLocation->transform; player->body.currentRoom = startLocation->roomIndex; } else { - transformInitIdentity(&player->body.transform); + transformInitIdentity(&player->lookTransform); player->body.currentRoom = 0; } - player->body.transform.position.y += PLAYER_HEAD_HEIGHT; + player->lookTransform.position.y += PLAYER_HEAD_HEIGHT; + player->body.transform = player->lookTransform; + + collisionObjectUpdateBB(&player->collisionObject); } #define PLAYER_SPEED (3.0f) @@ -57,16 +75,33 @@ void playerInit(struct Player* player, struct Location* startLocation) { #define JUMP_IMPULSE 3.2f -void playerHandleCollision(void* data, struct ContactManifold* contact) { - struct Player* player = (struct Player*)data; +void playerHandleCollision(struct Player* player) { + struct ContactManifold* contact = contactSolverNextManifold(&gContactSolver, &player->collisionObject, NULL); - if (contact->contactCount == 1 && contact->contacts[0].penetration < 0.0f) { - vector3AddScaled( - &player->body.transform.position, - &contact->normal, - -contact->contacts[0].penetration, - &player->body.transform.position - ); + while (contact) { + float offset = 0.0f; + + for (int i = 0; i < contact->contactCount; ++i) { + struct ContactPoint* contactPoint = &contact->contacts[i]; + offset = MIN(offset, contactPoint->penetration); + } + + if (offset != 0.0f) { + vector3AddScaled( + &player->body.transform.position, + &contact->normal, + (contact->shapeA == &player->collisionObject ? offset : -offset) * 0.9f, + &player->body.transform.position + ); + + float relativeVelocity = vector3Dot(&contact->normal, &player->body.velocity); + + if ((contact->shapeA == &player->collisionObject) == (relativeVelocity > 0.0f)) { + vector3ProjectPlane(&player->body.velocity, &contact->normal, &player->body.velocity); + } + } + + contact = contactSolverNextManifold(&gContactSolver, &player->collisionObject, contact); } } @@ -85,8 +120,8 @@ void playerUpdateGrabbedObject(struct Player* player) { } else { struct Ray ray; - ray.origin = player->body.transform.position; - quatMultVector(&player->body.transform.rotation, &gForward, &ray.dir); + ray.origin = player->lookTransform.position; + quatMultVector(&player->lookTransform.rotation, &gForward, &ray.dir); vector3Negate(&ray.dir, &ray.dir); struct RaycastHit hit; @@ -121,9 +156,9 @@ void playerUpdateGrabbedObject(struct Player* player) { } struct Vector3 grabPoint; - struct Quaternion grabRotation = player->body.transform.rotation; + struct Quaternion grabRotation = player->lookTransform.rotation; - transformPoint(&player->body.transform, &gGrabDistance, &grabPoint); + transformPoint(&player->lookTransform, &gGrabDistance, &grabPoint); if (player->grabbingThroughPortal != PLAYER_GRABBING_THROUGH_NOTHING) { if (!collisionSceneIsPortalOpen()) { @@ -169,9 +204,9 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) { struct Vector3 forward; struct Vector3 right; - int doorwayMask = worldCheckDoorwaySides(&gCurrentLevel->world, &player->body.transform.position, player->body.currentRoom); + int doorwayMask = worldCheckDoorwaySides(&gCurrentLevel->world, &player->lookTransform.position, player->body.currentRoom); - struct Transform* transform = &player->body.transform; + struct Transform* transform = &player->lookTransform; quatMultVector(&transform->rotation, &gForward, &forward); quatMultVector(&transform->rotation, &gRight, &right); @@ -218,12 +253,13 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) { vector3Dot(&player->body.velocity, &targetVelocity) > 0.0f ? PLAYER_ACCEL * FIXED_DELTA_TIME : PLAYER_STOP_ACCEL * FIXED_DELTA_TIME, &player->body.velocity ); + player->body.angularVelocity = gZeroVec; player->body.velocity.y += GRAVITY_CONSTANT * FIXED_DELTA_TIME; - vector3AddScaled(&transform->position, &player->body.velocity, FIXED_DELTA_TIME, &transform->position); + vector3AddScaled(&player->body.transform.position, &player->body.velocity, FIXED_DELTA_TIME, &player->body.transform.position); - collisionObjectQueryScene(&player->collisionObject, &gCollisionScene, player, playerHandleCollision); + playerHandleCollision(player); struct RaycastHit hit; struct Ray ray; @@ -238,8 +274,14 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) { player->flags &= ~PlayerFlagsGrounded; } + player->body.transform.rotation = player->lookTransform.rotation; + int didPassThroughPortal = rigidBodyCheckPortals(&player->body); + player->lookTransform.position = player->body.transform.position; + player->lookTransform.rotation = player->body.transform.rotation; + quatIdent(&player->body.transform.rotation); + if (didPassThroughPortal) { soundPlayerPlay(soundsPortalEnter[didPassThroughPortal - 1], 0.75f, 1.0f); soundPlayerPlay(soundsPortalExit[2 - didPassThroughPortal], 0.75f, 1.0f); @@ -263,13 +305,13 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) { struct Vector3 lookingForward; vector3Negate(&gForward, &lookingForward); - quatMultVector(&player->body.transform.rotation, &lookingForward, &lookingForward); + quatMultVector(&player->lookTransform.rotation, &lookingForward, &lookingForward); // if player is looking close to directly up or down, don't correct the rotation if (fabsf(lookingForward.y) < 0.99f) { struct Quaternion upRotation; quatLook(&lookingForward, &gUp, &upRotation); - quatLerp(&upRotation, &player->body.transform.rotation, 0.9f, &player->body.transform.rotation); + quatLerp(&upRotation, &player->lookTransform.rotation, 0.9f, &player->lookTransform.rotation); } @@ -277,18 +319,18 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) { struct Quaternion deltaRotate; quatAxisAngle(&gUp, player->yawVelocity * FIXED_DELTA_TIME, &deltaRotate); struct Quaternion tempRotation; - quatMultiply(&deltaRotate, &player->body.transform.rotation, &tempRotation); + quatMultiply(&deltaRotate, &player->lookTransform.rotation, &tempRotation); // pitch quatAxisAngle(&gRight, player->pitchVelocity * FIXED_DELTA_TIME, &deltaRotate); - quatMultiply(&tempRotation, &deltaRotate, &player->body.transform.rotation); + quatMultiply(&tempRotation, &deltaRotate, &player->lookTransform.rotation); // prevent player from looking too far up or down vector3Negate(&gForward, &lookingForward); quatMultVector(&tempRotation, &lookingForward, &lookingForward); struct Vector3 newLookingForward; vector3Negate(&gForward, &newLookingForward); - quatMultVector(&player->body.transform.rotation, &newLookingForward, &newLookingForward); + quatMultVector(&player->lookTransform.rotation, &newLookingForward, &newLookingForward); float pitchSign = signf(player->pitchVelocity); @@ -297,15 +339,15 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) { newForward.y = pitchSign; struct Vector3 newUp; quatMultVector(&tempRotation, &gUp, &newUp); - quatLook(&newForward, &newUp, &player->body.transform.rotation); + quatLook(&newForward, &newUp, &player->lookTransform.rotation); player->pitchVelocity = 0.0f; } - cameraTransform->rotation = player->body.transform.rotation; - transformPoint(transform, &gCameraOffset, &cameraTransform->position); + cameraTransform->rotation = player->lookTransform.rotation; + cameraTransform->position = player->lookTransform.position; playerUpdateGrabbedObject(player); collisionObjectUpdateBB(&player->collisionObject); - player->body.currentRoom = worldCheckDoorwayCrossings(&gCurrentLevel->world, &player->body.transform.position, player->body.currentRoom, doorwayMask); + player->body.currentRoom = worldCheckDoorwayCrossings(&gCurrentLevel->world, &player->lookTransform.position, player->body.currentRoom, doorwayMask); } diff --git a/src/player/player.h b/src/player/player.h index aa6dd94..e53f2c3 100644 --- a/src/player/player.h +++ b/src/player/player.h @@ -18,6 +18,7 @@ enum PlayerFlags { struct Player { struct CollisionObject collisionObject; struct RigidBody body; + struct Transform lookTransform; short grabbingThroughPortal; struct RigidBody* grabbing; float pitchVelocity; diff --git a/src/scene/button.c b/src/scene/button.c index b4d08c1..ebde373 100644 --- a/src/scene/button.c +++ b/src/scene/button.c @@ -55,7 +55,7 @@ void buttonRender(void* data, struct RenderScene* renderScene) { void buttonInit(struct Button* button, struct ButtonDefinition* definition) { collisionObjectInit(&button->collisionObject, &gButtonCollider, &button->rigidBody, 1.0f, COLLISION_LAYERS_TANGIBLE); - rigitBodyMarkKinematic(&button->rigidBody); + rigidBodyMarkKinematic(&button->rigidBody); collisionSceneAddDynamicObject(&button->collisionObject); button->rigidBody.transform.position = definition->location; diff --git a/src/scene/door.c b/src/scene/door.c index 9f11728..ad99d0c 100644 --- a/src/scene/door.c +++ b/src/scene/door.c @@ -51,7 +51,7 @@ void doorRender(void* data, struct RenderScene* renderScene) { void doorInit(struct Door* door, struct DoorDefinition* doorDefinition, struct World* world) { collisionObjectInit(&door->collisionObject, &gDoorCollider, &door->rigidBody, 1.0f, COLLISION_LAYERS_TANGIBLE); - rigitBodyMarkKinematic(&door->rigidBody); + rigidBodyMarkKinematic(&door->rigidBody); collisionSceneAddDynamicObject(&door->collisionObject); door->rigidBody.transform.position = doorDefinition->location; diff --git a/src/scene/scene.c b/src/scene/scene.c index 48abbcb..4fdb966 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -134,10 +134,10 @@ void sceneRenderPerformanceMetrics(struct Scene* scene, struct RenderState* rend void sceneRenderPortalGun(struct Scene* scene, struct RenderState* renderState) { struct Transform gunTransform; - transformPoint(&scene->player.body.transform, &gPortalGunOffset, &gunTransform.position); + transformPoint(&scene->player.lookTransform, &gPortalGunOffset, &gunTransform.position); struct Quaternion relativeRotation; quatLook(&gPortalGunForward, &gPortalGunUp, &relativeRotation); - quatMultiply(&scene->player.body.transform.rotation, &relativeRotation, &gunTransform.rotation); + quatMultiply(&scene->player.lookTransform.rotation, &relativeRotation, &gunTransform.rotation); gunTransform.scale = gOneVec; Mtx* matrix = renderStateRequestMatrices(renderState, 1); transformToMatrixL(&gunTransform, matrix, SCENE_SCALE); @@ -178,10 +178,10 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr void sceneCheckPortals(struct Scene* scene) { struct Ray raycastRay; struct Vector3 playerUp; - raycastRay.origin = scene->player.body.transform.position; + raycastRay.origin = scene->player.lookTransform.position; vector3Negate(&gForward, &raycastRay.dir); - quatMultVector(&scene->player.body.transform.rotation, &raycastRay.dir, &raycastRay.dir); - quatMultVector(&scene->player.body.transform.rotation, &gUp, &playerUp); + quatMultVector(&scene->player.lookTransform.rotation, &raycastRay.dir, &raycastRay.dir); + quatMultVector(&scene->player.lookTransform.rotation, &gUp, &playerUp); if (controllerGetButtonDown(0, Z_TRIG)) { sceneFirePortal(scene, &raycastRay, &playerUp, 0, scene->player.body.currentRoom); @@ -217,7 +217,7 @@ void sceneUpdate(struct Scene* scene) { collisionSceneUpdateDynamics(); - levelCheckTriggers(&scene->player.body.transform.position); + levelCheckTriggers(&scene->player.lookTransform.position); cutsceneRunnerUpdate(&gCutsceneRunner); scene->cpuTime = osGetTime() - frameStart;