Implement player wall collision detection
This commit is contained in:
parent
7ca5660e11
commit
734401c321
|
@ -12,3 +12,21 @@ void collisionObjectCollideWithScene(struct CollisionObject* object, struct Coll
|
||||||
collisionObjectCollideWithQuad(object, &scene->quads[i], contactSolver);
|
collisionObjectCollideWithQuad(object, &scene->quads[i], contactSolver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collisionObjectQueryScene(struct CollisionObject* object, struct CollisionScene* scene, void* data, ManifoldCallback callback) {
|
||||||
|
CollideWithQuad quadCollider = object->collider->callbacks->collideWithQuad;
|
||||||
|
|
||||||
|
if (!quadCollider) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ContactConstraintState localContact;
|
||||||
|
|
||||||
|
for (int i = 0; i < scene->quadCount; ++i) {
|
||||||
|
localContact.contactCount = 0;
|
||||||
|
|
||||||
|
if (quadCollider(object->collider->data, &object->body->transform, scene->quads[i].collider->data, &localContact)) {
|
||||||
|
callback(data, &localContact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,9 +8,13 @@ struct CollisionScene {
|
||||||
int quadCount;
|
int quadCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*ManifoldCallback)(void* data, struct ContactConstraintState* contact);
|
||||||
|
|
||||||
extern struct CollisionScene gCollisionScene;
|
extern struct CollisionScene gCollisionScene;
|
||||||
|
|
||||||
void collisionSceneInit(struct CollisionScene* scene, struct CollisionObject* quads, int quadCount);
|
void collisionSceneInit(struct CollisionScene* scene, struct CollisionObject* quads, int quadCount);
|
||||||
void collisionObjectCollideWithScene(struct CollisionObject* object, struct CollisionScene* scene, struct ContactSolver* contactSolver);
|
void collisionObjectCollideWithScene(struct CollisionObject* object, struct CollisionScene* scene, struct ContactSolver* contactSolver);
|
||||||
|
|
||||||
|
void collisionObjectQueryScene(struct CollisionObject* object, struct CollisionScene* scene, void* data, ManifoldCallback callback);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -24,13 +24,13 @@ int collisionSphereCollideQuad(void* data, struct Transform* boxTransform, struc
|
||||||
vector3AddScaled(&quad->corner, &quad->edgeA, aLerp, &contact->ra);
|
vector3AddScaled(&quad->corner, &quad->edgeA, aLerp, &contact->ra);
|
||||||
vector3AddScaled(&contact->ra, &quad->edgeB, bLerp, &contact->ra);
|
vector3AddScaled(&contact->ra, &quad->edgeB, bLerp, &contact->ra);
|
||||||
|
|
||||||
vector3Sub(&boxTransform->position, &contact->rb, &output->normal);
|
vector3Sub(&boxTransform->position, &contact->ra, &output->normal);
|
||||||
|
|
||||||
float outputLength = vector3MagSqrd(&output->normal);
|
float outputLength = vector3MagSqrd(&output->normal);
|
||||||
|
|
||||||
float extraRadius = sphere->radius + NEGATIVE_PENETRATION_BIAS;
|
float extraRadius = sphere->radius + NEGATIVE_PENETRATION_BIAS;
|
||||||
|
|
||||||
if (outputLength * outputLength > extraRadius * extraRadius || vector3Dot(&output->normal, &quad->plane.normal) < 0.0f) {
|
if (outputLength * outputLength > extraRadius * extraRadius || vector3Dot(&output->normal, &quad->plane.normal) <= 0.0f) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,26 @@
|
||||||
#include "../defs.h"
|
#include "../defs.h"
|
||||||
#include "../physics/point_constraint.h"
|
#include "../physics/point_constraint.h"
|
||||||
#include "../math/mathf.h"
|
#include "../math/mathf.h"
|
||||||
|
#include "physics/collision_sphere.h"
|
||||||
|
#include "physics/collision_scene.h"
|
||||||
|
|
||||||
struct Vector3 gGrabDistance = {0.0f, 0.0f, -2.5f};
|
struct Vector3 gGrabDistance = {0.0f, 0.0f, -2.5f};
|
||||||
struct Vector3 gCameraOffset = {0.0f, 1.2f, 0.0f};
|
struct Vector3 gCameraOffset = {0.0f, 1.2f, 0.0f};
|
||||||
|
|
||||||
|
struct CollisionSphere gPlayerCollider = {
|
||||||
|
0.25f,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ColliderTypeData gPlayerColliderData = {
|
||||||
|
CollisionShapeTypeSphere,
|
||||||
|
&gPlayerCollider,
|
||||||
|
0.1f,
|
||||||
|
0.5f,
|
||||||
|
&gCollisionSphereCallbacks,
|
||||||
|
};
|
||||||
|
|
||||||
void playerInit(struct Player* player) {
|
void playerInit(struct Player* player) {
|
||||||
transformInitIdentity(&player->transform);
|
collisionObjectInit(&player->collisionObject, &gPlayerColliderData, &player->body, 1.0f);
|
||||||
player->grabbing = NULL;
|
player->grabbing = NULL;
|
||||||
player->yaw = 0.0f;
|
player->yaw = 0.0f;
|
||||||
player->pitch = 0.0f;
|
player->pitch = 0.0f;
|
||||||
|
@ -24,12 +38,27 @@ void playerInit(struct Player* player) {
|
||||||
#define ROTATE_RATE_DELTA (M_PI * 0.25f)
|
#define ROTATE_RATE_DELTA (M_PI * 0.25f)
|
||||||
#define ROTATE_RATE_STOP_DELTA (M_PI * 0.25f)
|
#define ROTATE_RATE_STOP_DELTA (M_PI * 0.25f)
|
||||||
|
|
||||||
|
void playerHandleCollision(void* data, struct ContactConstraintState* contact) {
|
||||||
|
struct Player* player = (struct Player*)data;
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
||||||
struct Vector3 forward;
|
struct Vector3 forward;
|
||||||
struct Vector3 right;
|
struct Vector3 right;
|
||||||
|
|
||||||
quatMultVector(&player->transform.rotation, &gForward, &forward);
|
struct Transform* transform = &player->body.transform;
|
||||||
quatMultVector(&player->transform.rotation, &gRight, &right);
|
|
||||||
|
quatMultVector(&transform->rotation, &gForward, &forward);
|
||||||
|
quatMultVector(&transform->rotation, &gRight, &right);
|
||||||
|
|
||||||
forward.y = 0.0f;
|
forward.y = 0.0f;
|
||||||
right.y = 0.0f;
|
right.y = 0.0f;
|
||||||
|
@ -50,7 +79,9 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
||||||
vector3Dot(&player->velocity, &targetVelocity) > 0.0f ? PLAYER_ACCEL * FIXED_DELTA_TIME : PLAYER_STOP_ACCEL * FIXED_DELTA_TIME,
|
vector3Dot(&player->velocity, &targetVelocity) > 0.0f ? PLAYER_ACCEL * FIXED_DELTA_TIME : PLAYER_STOP_ACCEL * FIXED_DELTA_TIME,
|
||||||
&player->velocity
|
&player->velocity
|
||||||
);
|
);
|
||||||
vector3AddScaled(&player->transform.position, &player->velocity, FIXED_DELTA_TIME, &player->transform.position);
|
vector3AddScaled(&transform->position, &player->velocity, FIXED_DELTA_TIME, &transform->position);
|
||||||
|
|
||||||
|
collisionObjectQueryScene(&player->collisionObject, &gCollisionScene, player, playerHandleCollision);
|
||||||
|
|
||||||
float targetYaw = 0.0f;
|
float targetYaw = 0.0f;
|
||||||
float targetPitch = 0.0f;
|
float targetPitch = 0.0f;
|
||||||
|
@ -81,13 +112,13 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
||||||
player->yaw += player->yawVelocity * FIXED_DELTA_TIME;
|
player->yaw += player->yawVelocity * FIXED_DELTA_TIME;
|
||||||
player->pitch = clampf(player->pitch + player->pitchVelocity * FIXED_DELTA_TIME, -M_PI * 0.5f, M_PI * 0.5f);
|
player->pitch = clampf(player->pitch + player->pitchVelocity * FIXED_DELTA_TIME, -M_PI * 0.5f, M_PI * 0.5f);
|
||||||
|
|
||||||
quatAxisAngle(&gUp, player->yaw, &player->transform.rotation);
|
quatAxisAngle(&gUp, player->yaw, &transform->rotation);
|
||||||
|
|
||||||
struct Quaternion pitch;
|
struct Quaternion pitch;
|
||||||
quatAxisAngle(&gRight, player->pitch, &pitch);
|
quatAxisAngle(&gRight, player->pitch, &pitch);
|
||||||
quatMultiply(&player->transform.rotation, &pitch, &cameraTransform->rotation);
|
quatMultiply(&transform->rotation, &pitch, &cameraTransform->rotation);
|
||||||
|
|
||||||
transformPoint(&player->transform, &gCameraOffset, &cameraTransform->position);
|
transformPoint(transform, &gCameraOffset, &cameraTransform->position);
|
||||||
|
|
||||||
if (player->grabbing) {
|
if (player->grabbing) {
|
||||||
struct Vector3 grabPoint;
|
struct Vector3 grabPoint;
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
#include "../math/transform.h"
|
#include "../math/transform.h"
|
||||||
#include "../graphics/renderstate.h"
|
#include "../graphics/renderstate.h"
|
||||||
#include "../physics/rigid_body.h"
|
#include "../physics/rigid_body.h"
|
||||||
|
#include "../physics/collision_object.h"
|
||||||
|
|
||||||
struct Player {
|
struct Player {
|
||||||
struct Transform transform;
|
struct CollisionObject collisionObject;
|
||||||
|
struct RigidBody body;
|
||||||
struct RigidBody* grabbing;
|
struct RigidBody* grabbing;
|
||||||
struct Vector3 velocity;
|
struct Vector3 velocity;
|
||||||
float pitch;
|
float pitch;
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
struct Vector3 gStartPosition = {5.0f, 0.0f, -5.0f};
|
struct Vector3 gStartPosition = {5.0f, 0.0f, -5.0f};
|
||||||
|
|
||||||
void sceneInit(struct Scene* scene) {
|
void sceneInit(struct Scene* scene) {
|
||||||
cameraInit(&scene->camera, 45.0f, 0.25f * SCENE_SCALE, 80.0f * SCENE_SCALE);
|
cameraInit(&scene->camera, 45.0f, 0.125f * SCENE_SCALE, 80.0f * SCENE_SCALE);
|
||||||
playerInit(&scene->player);
|
playerInit(&scene->player);
|
||||||
|
|
||||||
scene->player.transform.position = gStartPosition;
|
scene->player.body.transform.position = gStartPosition;
|
||||||
scene->player.yaw = M_PI;
|
scene->player.yaw = M_PI;
|
||||||
|
|
||||||
portalInit(&scene->portals[0], 0);
|
portalInit(&scene->portals[0], 0);
|
||||||
|
|
Loading…
Reference in a new issue