Can grab objects through portals
This commit is contained in:
parent
b693328ecd
commit
dae161d206
|
@ -102,7 +102,7 @@ void rigidBodyCheckPortals(struct RigidBody* rigidBody) {
|
||||||
int xorMask = i == 0 ? 0 : mask;
|
int xorMask = i == 0 ? 0 : mask;
|
||||||
|
|
||||||
// check if the body crossed the portal
|
// check if the body crossed the portal
|
||||||
if (!((~newFlags ^ xorMask) & (rigidBody->flags ^ xorMask))) {
|
if (!((~newFlags ^ xorMask) & (rigidBody->flags ^ xorMask) & mask)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ enum RigidBodyFlags {
|
||||||
RigidBodyFlagsPortalsInactive = (1 << 2),
|
RigidBodyFlagsPortalsInactive = (1 << 2),
|
||||||
RigidBodyFlagsCrossedPortal0 = (1 << 3),
|
RigidBodyFlagsCrossedPortal0 = (1 << 3),
|
||||||
RigidBodyFlagsCrossedPortal1 = (1 << 4),
|
RigidBodyFlagsCrossedPortal1 = (1 << 4),
|
||||||
|
RigidBodyFlagsGrabbable = (1 << 5),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RigidBody {
|
struct RigidBody {
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "physics/collision_scene.h"
|
#include "physics/collision_scene.h"
|
||||||
#include "physics/config.h"
|
#include "physics/config.h"
|
||||||
|
|
||||||
|
#define GRAB_RAYCAST_DISTANCE 3.5f
|
||||||
|
|
||||||
struct Vector3 gGrabDistance = {0.0f, 0.0f, -2.5f};
|
struct Vector3 gGrabDistance = {0.0f, 0.0f, -2.5f};
|
||||||
struct Vector3 gCameraOffset = {0.0f, 0.0f, 0.0f};
|
struct Vector3 gCameraOffset = {0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
@ -26,11 +28,11 @@ struct ColliderTypeData gPlayerColliderData = {
|
||||||
|
|
||||||
void playerInit(struct Player* player) {
|
void playerInit(struct Player* player) {
|
||||||
collisionObjectInit(&player->collisionObject, &gPlayerColliderData, &player->body, 1.0f);
|
collisionObjectInit(&player->collisionObject, &gPlayerColliderData, &player->body, 1.0f);
|
||||||
player->grabbing = NULL;
|
|
||||||
player->yaw = 0.0f;
|
|
||||||
player->pitch = 0.0f;
|
|
||||||
|
|
||||||
player->grabbingThroughPortal = PLAYER_GRABBING_THROUGH_NOTHING;
|
player->grabbingThroughPortal = PLAYER_GRABBING_THROUGH_NOTHING;
|
||||||
|
player->grabbing = NULL;
|
||||||
|
player->pitchVelocity = 0.0f;
|
||||||
|
player->yawVelocity = 0.0f;
|
||||||
|
player->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PLAYER_SPEED (5.0f)
|
#define PLAYER_SPEED (5.0f)
|
||||||
|
@ -41,6 +43,8 @@ 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)
|
||||||
|
|
||||||
|
#define JUMP_IMPULSE 3.2f
|
||||||
|
|
||||||
void playerHandleCollision(void* data, struct ContactConstraintState* contact) {
|
void playerHandleCollision(void* data, struct ContactConstraintState* contact) {
|
||||||
struct Player* player = (struct Player*)data;
|
struct Player* player = (struct Player*)data;
|
||||||
|
|
||||||
|
@ -63,6 +67,30 @@ void playerApplyPortalGrab(struct Player* player, int portalIndex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerUpdateGrabbedObject(struct Player* player) {
|
void playerUpdateGrabbedObject(struct Player* player) {
|
||||||
|
if (controllerGetButtonDown(0, B_BUTTON)) {
|
||||||
|
if (player->grabbing) {
|
||||||
|
player->grabbing = NULL;
|
||||||
|
} else {
|
||||||
|
struct Ray ray;
|
||||||
|
|
||||||
|
ray.origin = player->body.transform.position;
|
||||||
|
quatMultVector(&player->body.transform.rotation, &gForward, &ray.dir);
|
||||||
|
vector3Negate(&ray.dir, &ray.dir);
|
||||||
|
|
||||||
|
struct RaycastHit hit;
|
||||||
|
|
||||||
|
if (collisionSceneRaycast(&gCollisionScene, &ray, GRAB_RAYCAST_DISTANCE, 1, &hit) && hit.object->body && (hit.object->body->flags & RigidBodyFlagsGrabbable)) {
|
||||||
|
player->grabbing = hit.object->body;
|
||||||
|
|
||||||
|
if (hit.throughPortal) {
|
||||||
|
player->grabbingThroughPortal = hit.throughPortal == gCollisionScene.portalTransforms[0] ? 0 : 1;
|
||||||
|
} else {
|
||||||
|
player->grabbingThroughPortal = PLAYER_GRABBING_THROUGH_NOTHING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (player->grabbing) {
|
if (player->grabbing) {
|
||||||
if (player->body.flags & RigidBodyFlagsCrossedPortal0) {
|
if (player->body.flags & RigidBodyFlagsCrossedPortal0) {
|
||||||
playerApplyPortalGrab(player, 1);
|
playerApplyPortalGrab(player, 1);
|
||||||
|
@ -121,6 +149,11 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
||||||
vector3Normalize(&gForward, &gForward);
|
vector3Normalize(&gForward, &gForward);
|
||||||
vector3Normalize(&gRight, &gRight);
|
vector3Normalize(&gRight, &gRight);
|
||||||
|
|
||||||
|
|
||||||
|
if ((player->flags & PlayerFlagsGrounded) && controllerGetButtonDown(0, A_BUTTON)) {
|
||||||
|
player->body.velocity.y = JUMP_IMPULSE;
|
||||||
|
}
|
||||||
|
|
||||||
OSContPad* controllerInput = controllersGetControllerData(0);
|
OSContPad* controllerInput = controllersGetControllerData(0);
|
||||||
|
|
||||||
struct Vector3 targetVelocity;
|
struct Vector3 targetVelocity;
|
||||||
|
@ -151,6 +184,9 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
||||||
vector3AddScaled(&hit.at, &gUp, PLAYER_HEAD_HEIGHT, &player->body.transform.position);
|
vector3AddScaled(&hit.at, &gUp, PLAYER_HEAD_HEIGHT, &player->body.transform.position);
|
||||||
|
|
||||||
player->body.velocity.y = 0.0f;
|
player->body.velocity.y = 0.0f;
|
||||||
|
player->flags |= PlayerFlagsGrounded;
|
||||||
|
} else {
|
||||||
|
player->flags &= ~PlayerFlagsGrounded;
|
||||||
}
|
}
|
||||||
|
|
||||||
rigidBodyCheckPortals(&player->body);
|
rigidBodyCheckPortals(&player->body);
|
||||||
|
|
|
@ -10,15 +10,18 @@
|
||||||
|
|
||||||
#define PLAYER_HEAD_HEIGHT 1.2f
|
#define PLAYER_HEAD_HEIGHT 1.2f
|
||||||
|
|
||||||
|
enum PlayerFlags {
|
||||||
|
PlayerFlagsGrounded = (1 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
struct Player {
|
struct Player {
|
||||||
struct CollisionObject collisionObject;
|
struct CollisionObject collisionObject;
|
||||||
struct RigidBody body;
|
struct RigidBody body;
|
||||||
short grabbingThroughPortal;
|
short grabbingThroughPortal;
|
||||||
struct RigidBody* grabbing;
|
struct RigidBody* grabbing;
|
||||||
float pitch;
|
|
||||||
float pitchVelocity;
|
float pitchVelocity;
|
||||||
float yaw;
|
|
||||||
float yawVelocity;
|
float yawVelocity;
|
||||||
|
enum PlayerFlags flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
void playerInit(struct Player* player);
|
void playerInit(struct Player* player);
|
||||||
|
|
|
@ -60,6 +60,8 @@ struct ColliderTypeData gCubeCollider = {
|
||||||
void cubeInit(struct Cube* cube) {
|
void cubeInit(struct Cube* cube) {
|
||||||
collisionObjectInit(&cube->collisionObject, &gCubeCollider, &cube->rigidBody, 1.0f);
|
collisionObjectInit(&cube->collisionObject, &gCubeCollider, &cube->rigidBody, 1.0f);
|
||||||
collisionSceneAddDynamicObject(&cube->collisionObject);
|
collisionSceneAddDynamicObject(&cube->collisionObject);
|
||||||
|
|
||||||
|
cube->collisionObject.body->flags |= RigidBodyFlagsGrabbable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cubeUpdate(struct Cube* cube) {
|
void cubeUpdate(struct Cube* cube) {
|
||||||
|
|
|
@ -68,6 +68,18 @@ void sceneRenderWithProperties(void* data, struct RenderProps* properties, struc
|
||||||
|
|
||||||
#define SOLID_COLOR 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT
|
#define SOLID_COLOR 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT
|
||||||
|
|
||||||
|
void sceneRenderPerformanceMetrics(struct Scene* scene, struct RenderState* renderState, struct GraphicsTask* task) {
|
||||||
|
gDPSetCycleType(renderState->dl++, G_CYC_1CYCLE);
|
||||||
|
gDPSetFillColor(renderState->dl++, (GPACK_RGBA5551(0, 0, 0, 1) << 16 | GPACK_RGBA5551(0, 0, 0, 1)));
|
||||||
|
gDPSetCombineMode(renderState->dl++, SOLID_COLOR, SOLID_COLOR);
|
||||||
|
gDPSetEnvColor(renderState->dl++, 32, 32, 32, 255);
|
||||||
|
gSPTextureRectangle(renderState->dl++, 32 << 2, 32 << 2, (32 + 256) << 2, (32 + 16) << 2, 0, 0, 0, 1, 1);
|
||||||
|
gDPPipeSync(renderState->dl++);
|
||||||
|
gDPSetEnvColor(renderState->dl++, 32, 255, 32, 255);
|
||||||
|
gSPTextureRectangle(renderState->dl++, 33 << 2, 33 << 2, (32 + 254 * scene->cpuTime / scene->lastFrameTime) << 2, (32 + 14) << 2, 0, 0, 0, 1, 1);
|
||||||
|
gDPPipeSync(renderState->dl++);
|
||||||
|
}
|
||||||
|
|
||||||
void sceneRender(struct Scene* scene, struct RenderState* renderState, struct GraphicsTask* task) {
|
void sceneRender(struct Scene* scene, struct RenderState* renderState, struct GraphicsTask* task) {
|
||||||
struct RenderProps renderProperties;
|
struct RenderProps renderProperties;
|
||||||
|
|
||||||
|
@ -83,17 +95,9 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
|
||||||
gDPSetRenderMode(renderState->dl++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
|
gDPSetRenderMode(renderState->dl++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
|
||||||
gSPGeometryMode(renderState->dl++, G_ZBUFFER | G_LIGHTING | G_CULL_BOTH, G_SHADE);
|
gSPGeometryMode(renderState->dl++, G_ZBUFFER | G_LIGHTING | G_CULL_BOTH, G_SHADE);
|
||||||
|
|
||||||
gDPSetCycleType(renderState->dl++, G_CYC_1CYCLE);
|
// sceneRenderPerformanceMetrics(scene, renderState, task);
|
||||||
gDPSetFillColor(renderState->dl++, (GPACK_RGBA5551(0, 0, 0, 1) << 16 | GPACK_RGBA5551(0, 0, 0, 1)));
|
|
||||||
gDPSetCombineMode(renderState->dl++, SOLID_COLOR, SOLID_COLOR);
|
|
||||||
gDPSetEnvColor(renderState->dl++, 32, 32, 32, 255);
|
|
||||||
gSPTextureRectangle(renderState->dl++, 32 << 2, 32 << 2, (32 + 256) << 2, (32 + 16) << 2, 0, 0, 0, 1, 1);
|
|
||||||
gDPPipeSync(renderState->dl++);
|
|
||||||
gDPSetEnvColor(renderState->dl++, 32, 255, 32, 255);
|
|
||||||
gSPTextureRectangle(renderState->dl++, 33 << 2, 33 << 2, (32 + 254 * scene->cpuTime / scene->lastFrameTime) << 2, (32 + 14) << 2, 0, 0, 0, 1, 1);
|
|
||||||
gDPPipeSync(renderState->dl++);
|
|
||||||
|
|
||||||
contactSolverDebugDraw(&gContactSolver, renderState);
|
// contactSolverDebugDraw(&gContactSolver, renderState);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ignoreInputFrames = 10;
|
unsigned ignoreInputFrames = 10;
|
||||||
|
@ -106,15 +110,6 @@ void sceneUpdate(struct Scene* scene) {
|
||||||
|
|
||||||
collisionSceneUpdateDynamics();
|
collisionSceneUpdateDynamics();
|
||||||
|
|
||||||
if (controllerGetButtonDown(0, B_BUTTON)) {
|
|
||||||
if (scene->player.grabbing) {
|
|
||||||
scene->player.grabbing = NULL;
|
|
||||||
} else {
|
|
||||||
scene->player.grabbing = &scene->cube.rigidBody;
|
|
||||||
scene->player.grabbingThroughPortal = PLAYER_GRABBING_THROUGH_NOTHING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scene->cpuTime = osGetTime() - frameStart;
|
scene->cpuTime = osGetTime() - frameStart;
|
||||||
scene->lastFrameStart = frameStart;
|
scene->lastFrameStart = frameStart;
|
||||||
}
|
}
|
Loading…
Reference in a new issue