mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-19 22:27:36 -04:00
Rework player collider
This commit is contained in:
parent
a6aba230c5
commit
bbe5c38eff
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,4 +84,82 @@ struct ColliderCallbacks gCollisionSphereCallbacks = {
|
|||
NULL, // TODO
|
||||
collisionSphereSolidMofI,
|
||||
collisionSphereBoundingBox,
|
||||
};
|
||||
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;
|
||||
}
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ enum PlayerFlags {
|
|||
struct Player {
|
||||
struct CollisionObject collisionObject;
|
||||
struct RigidBody body;
|
||||
struct Transform lookTransform;
|
||||
short grabbingThroughPortal;
|
||||
struct RigidBody* grabbing;
|
||||
float pitchVelocity;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue