Add collision to portal border
This commit is contained in:
parent
e4d12713ec
commit
60485246d1
1
Makefile
1
Makefile
|
@ -181,6 +181,7 @@ MODEL_LIST = assets/models/player/chell.blend \
|
|||
assets/models/portal/portal_blue.blend \
|
||||
assets/models/portal/portal_blue_filled.blend \
|
||||
assets/models/portal/portal_blue_face.blend \
|
||||
assets/models/portal/portal_collider.blend \
|
||||
assets/models/portal/portal_orange.blend \
|
||||
assets/models/portal/portal_orange_filled.blend \
|
||||
assets/models/portal/portal_orange_face.blend \
|
||||
|
|
Binary file not shown.
BIN
assets/models/portal/portal_collider.blend
Normal file
BIN
assets/models/portal/portal_collider.blend
Normal file
Binary file not shown.
1
assets/models/portal/portal_collider.flags
Normal file
1
assets/models/portal/portal_collider.flags
Normal file
|
@ -0,0 +1 @@
|
|||
-r 0,0,0 --mesh-collider
|
|
@ -38,9 +38,9 @@ void sceneSerializePortals(struct Serializer* serializer, SerializeAction action
|
|||
char flags = portal->flags;
|
||||
action(serializer, &flags, sizeof(flags));
|
||||
|
||||
action(serializer, &portal->transform, sizeof(struct PartialTransform));
|
||||
action(serializer, &portal->rigidBody.transform, sizeof(struct PartialTransform));
|
||||
action(serializer, &portal->portalSurfaceIndex, sizeof(portal->portalSurfaceIndex));
|
||||
action(serializer, &portal->roomIndex, sizeof(portal->roomIndex));
|
||||
action(serializer, &portal->rigidBody.currentRoom, sizeof(portal->rigidBody.currentRoom));
|
||||
action(serializer, &portal->colliderIndex, sizeof(portal->colliderIndex));
|
||||
action(serializer, &portal->transformIndex, sizeof(portal->transformIndex));
|
||||
|
||||
|
@ -87,12 +87,13 @@ void sceneDeserializePortals(struct Serializer* serializer, struct Scene* scene)
|
|||
serializeRead(serializer, &portal->relativePos, sizeof(portal->relativePos));
|
||||
}
|
||||
|
||||
portal->transform = transform;
|
||||
portal->rigidBody.transform = transform;
|
||||
gCollisionScene.portalVelocity[portalIndex] = gZeroVec;
|
||||
portal->roomIndex = roomIndex;
|
||||
portal->rigidBody.currentRoom = roomIndex;
|
||||
portal->colliderIndex = colliderIndex;
|
||||
portal->scale = 1.0f;
|
||||
collisionSceneSetPortal(portalIndex, &portal->transform, roomIndex, colliderIndex);
|
||||
collisionSceneSetPortal(portalIndex, &portal->rigidBody.transform, roomIndex, colliderIndex);
|
||||
collisionObjectUpdateBB(&portal->collisionObject);
|
||||
|
||||
if (flags & PortalFlagsPlayerPortal) {
|
||||
portal->flags |= PortalFlagsPlayerPortal;
|
||||
|
|
|
@ -10,14 +10,22 @@
|
|||
#include "../util/time.h"
|
||||
#include "../levels/levels.h"
|
||||
#include "./portal_surface_generator.h"
|
||||
#include "../scene/dynamic_scene.h"
|
||||
|
||||
#include "../build/assets/models/portal/portal_blue.h"
|
||||
#include "../build/assets/models/portal/portal_blue_filled.h"
|
||||
#include "../build/assets/models/portal/portal_blue_face.h"
|
||||
#include "../build/assets/models/portal/portal_collider.h"
|
||||
#include "../build/assets/models/portal/portal_orange.h"
|
||||
#include "../build/assets/models/portal/portal_orange_face.h"
|
||||
#include "../build/assets/models/portal/portal_orange_filled.h"
|
||||
|
||||
struct ColliderTypeData gPortalColliderType = {
|
||||
CollisionShapeTypeMesh,
|
||||
&portal_portal_collider_collider,
|
||||
0.0f, 0.6f,
|
||||
&gMeshColliderCallbacks
|
||||
};
|
||||
|
||||
#define CALC_SCREEN_SPACE(clip_space, screen_size) ((clip_space + 1.0f) * ((screen_size) / 2))
|
||||
|
||||
|
@ -38,7 +46,8 @@ struct Vector3 gPortalOutline[PORTAL_LOOP_SIZE] = {
|
|||
#define PORTAL_GROW_TIME 0.3f
|
||||
|
||||
void portalInit(struct Portal* portal, enum PortalFlags flags) {
|
||||
transformInitIdentity(&portal->transform);
|
||||
collisionObjectInit(&portal->collisionObject, &gPortalColliderType, &portal->rigidBody, 1.0f, COLLISION_LAYERS_STATIC | COLLISION_LAYERS_TANGIBLE);
|
||||
rigidBodyMarkKinematic(&portal->rigidBody);
|
||||
portal->flags = flags;
|
||||
portal->opacity = 1.0f;
|
||||
portal->scale = 0.0f;
|
||||
|
@ -70,12 +79,12 @@ void portalUpdate(struct Portal* portal, int isOpen) {
|
|||
|
||||
void portalCalculateBB(struct Portal* portal, struct Box3D* bb) {
|
||||
struct Vector3 portalUp;
|
||||
quatMultVector(&portal->transform.rotation, &gUp, &portalUp);
|
||||
quatMultVector(&portal->rigidBody.transform.rotation, &gUp, &portalUp);
|
||||
struct Vector3 portalRight;
|
||||
quatMultVector(&portal->transform.rotation, &gRight, &portalRight);
|
||||
quatMultVector(&portal->rigidBody.transform.rotation, &gRight, &portalRight);
|
||||
|
||||
vector3AddScaled(
|
||||
&portal->transform.position,
|
||||
&portal->rigidBody.transform.position,
|
||||
&portalUp, PORTAL_COVER_HEIGHT * 0.5f,
|
||||
&bb->min
|
||||
);
|
||||
|
@ -84,7 +93,7 @@ void portalCalculateBB(struct Portal* portal, struct Box3D* bb) {
|
|||
|
||||
struct Vector3 nextPoint;
|
||||
vector3AddScaled(
|
||||
&portal->transform.position,
|
||||
&portal->rigidBody.transform.position,
|
||||
&portalUp, -PORTAL_COVER_HEIGHT * 0.5f,
|
||||
&nextPoint
|
||||
);
|
||||
|
@ -92,7 +101,7 @@ void portalCalculateBB(struct Portal* portal, struct Box3D* bb) {
|
|||
box3DUnionPoint(bb, &nextPoint, bb);
|
||||
|
||||
vector3AddScaled(
|
||||
&portal->transform.position,
|
||||
&portal->rigidBody.transform.position,
|
||||
&portalRight, PORTAL_COVER_WIDTH * 0.25f,
|
||||
&nextPoint
|
||||
);
|
||||
|
@ -100,7 +109,7 @@ void portalCalculateBB(struct Portal* portal, struct Box3D* bb) {
|
|||
box3DUnionPoint(bb, &nextPoint, bb);
|
||||
|
||||
vector3AddScaled(
|
||||
&portal->transform.position,
|
||||
&portal->rigidBody.transform.position,
|
||||
&portalRight, -PORTAL_COVER_WIDTH * 0.25f,
|
||||
&nextPoint
|
||||
);
|
||||
|
@ -130,6 +139,11 @@ int portalAttachToSurface(struct Portal* portal, struct PortalSurface* surface,
|
|||
|
||||
portal->flags |= PortalFlagsNeedsNewHole;
|
||||
portal->fullSizeLoopCenter = correctPosition;
|
||||
|
||||
if (portal->portalSurfaceIndex == -1) {
|
||||
collisionSceneAddDynamicObject(&portal->collisionObject);
|
||||
}
|
||||
|
||||
portal->portalSurfaceIndex = surfaceIndex;
|
||||
|
||||
portalSurfaceInverse(surface, &correctPosition, &portalAt->position);
|
||||
|
@ -161,7 +175,7 @@ int portalSurfaceCutNewHole(struct Portal* portal, int portalIndex) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
portalSurfaceReplace(portal->portalSurfaceIndex, portal->roomIndex, portalIndex, &newSurface);
|
||||
portalSurfaceReplace(portal->portalSurfaceIndex, portal->rigidBody.currentRoom, portalIndex, &newSurface);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "camera.h"
|
||||
#include "static_scene.h"
|
||||
#include "./portal_surface.h"
|
||||
#include "../physics/collision_object.h"
|
||||
|
||||
#define STARTING_RENDER_DEPTH 2
|
||||
#define PORTAL_LOOP_SIZE 8
|
||||
|
@ -20,14 +21,15 @@ enum PortalFlags {
|
|||
};
|
||||
|
||||
struct Portal {
|
||||
struct Transform transform;
|
||||
struct CollisionObject collisionObject;
|
||||
struct RigidBody rigidBody;
|
||||
short dynamicId;
|
||||
enum PortalFlags flags;
|
||||
float opacity;
|
||||
float scale;
|
||||
struct Vector2s16 originCentertedLoop[PORTAL_LOOP_SIZE];
|
||||
struct Vector2s16 fullSizeLoopCenter;
|
||||
short portalSurfaceIndex;
|
||||
short roomIndex;
|
||||
short colliderIndex;
|
||||
// used to attach portals to moving surfaces
|
||||
short transformIndex;
|
||||
|
|
|
@ -82,10 +82,10 @@ void portalRenderScreenCover(struct Vector2s16* points, int pointCount, struct R
|
|||
|
||||
void portalDetermineTransform(struct Portal* portal, float portalTransform[4][4]) {
|
||||
struct Transform finalTransform;
|
||||
finalTransform = portal->transform;
|
||||
finalTransform = portal->rigidBody.transform;
|
||||
|
||||
if (portal->flags & PortalFlagsOddParity) {
|
||||
quatMultiply(&portal->transform.rotation, &gVerticalFlip, &finalTransform.rotation);
|
||||
quatMultiply(&portal->rigidBody.transform.rotation, &gVerticalFlip, &finalTransform.rotation);
|
||||
}
|
||||
|
||||
vector3Scale(&gOneVec, &finalTransform.scale, portal->scale);
|
||||
|
|
|
@ -122,10 +122,10 @@ int renderPlanPortal(struct RenderPlan* renderPlan, struct Scene* scene, struct
|
|||
}
|
||||
|
||||
struct Vector3 worldForward;
|
||||
quatMultVector(&portal->transform.rotation, &forward, &worldForward);
|
||||
quatMultVector(&portal->rigidBody.transform.rotation, &forward, &worldForward);
|
||||
|
||||
struct Vector3 offsetFromCamera;
|
||||
vector3Sub(¤t->camera.transform.position, &portal->transform.position, &offsetFromCamera);
|
||||
vector3Sub(¤t->camera.transform.position, &portal->rigidBody.transform.position, &offsetFromCamera);
|
||||
|
||||
// don't render the portal if it is facing the wrong way
|
||||
if (vector3Dot(&worldForward, &offsetFromCamera) < 0.0f) {
|
||||
|
@ -239,8 +239,8 @@ int renderPlanPortal(struct RenderPlan* renderPlan, struct Scene* scene, struct
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct Transform* fromPortal = &scene->portals[portalIndex].transform;
|
||||
struct Transform* exitPortal = &scene->portals[exitPortalIndex].transform;
|
||||
struct Transform* fromPortal = &scene->portals[portalIndex].rigidBody.transform;
|
||||
struct Transform* exitPortal = &scene->portals[exitPortalIndex].rigidBody.transform;
|
||||
|
||||
struct Transform otherInverse;
|
||||
transformInvert(fromPortal, &otherInverse);
|
||||
|
@ -338,7 +338,7 @@ void renderPlanFinishView(struct RenderPlan* renderPlan, struct Scene* scene, st
|
|||
|
||||
cameraSetupMatrices(&properties->camera, renderState, properties->aspectRatio, properties->viewport, 0, &properties->cameraMatrixInfo);
|
||||
|
||||
int closerPortal = vector3DistSqrd(&properties->camera.transform.position, &scene->portals[0].transform.position) < vector3DistSqrd(&properties->camera.transform.position, &scene->portals[1].transform.position) ? 0 : 1;
|
||||
int closerPortal = vector3DistSqrd(&properties->camera.transform.position, &scene->portals[0].rigidBody.transform.position) < vector3DistSqrd(&properties->camera.transform.position, &scene->portals[1].rigidBody.transform.position) ? 0 : 1;
|
||||
int otherPortal = 1 - closerPortal;
|
||||
|
||||
if (closerPortal) {
|
||||
|
|
|
@ -407,14 +407,14 @@ void sceneCheckPortals(struct Scene* scene) {
|
|||
#define MAX_LISTEN_THROUGH_PORTAL_DISTANCE 3.0f
|
||||
|
||||
int sceneUpdatePortalListener(struct Scene* scene, int portalIndex, int listenerIndex) {
|
||||
if (vector3DistSqrd(&scene->player.lookTransform.position, &scene->portals[portalIndex].transform.position) > MAX_LISTEN_THROUGH_PORTAL_DISTANCE * MAX_LISTEN_THROUGH_PORTAL_DISTANCE) {
|
||||
if (vector3DistSqrd(&scene->player.lookTransform.position, &scene->portals[portalIndex].rigidBody.transform.position) > MAX_LISTEN_THROUGH_PORTAL_DISTANCE * MAX_LISTEN_THROUGH_PORTAL_DISTANCE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct Transform otherInverse;
|
||||
transformInvert(&scene->portals[1 - portalIndex].transform, &otherInverse);
|
||||
transformInvert(&scene->portals[1 - portalIndex].rigidBody.transform, &otherInverse);
|
||||
struct Transform portalCombined;
|
||||
transformConcat(&scene->portals[portalIndex].transform, &otherInverse, &portalCombined);
|
||||
transformConcat(&scene->portals[portalIndex].rigidBody.transform, &otherInverse, &portalCombined);
|
||||
|
||||
struct Transform relativeTransform;
|
||||
transformConcat(&portalCombined, &scene->player.lookTransform, &relativeTransform);
|
||||
|
@ -473,6 +473,7 @@ void sceneUpdatePortalVelocity(struct Scene* scene) {
|
|||
|
||||
// update portal position
|
||||
gCollisionScene.portalTransforms[i]->position = newPos;
|
||||
collisionObjectUpdateBB(&portal->collisionObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -754,19 +755,20 @@ int sceneOpenPortal(struct Scene* scene, struct Transform* at, int transformInde
|
|||
// the portal position may have been adjusted
|
||||
if (transformIndex != NO_TRANSFORM_INDEX) {
|
||||
portal->relativePos = finalAt.position;
|
||||
transformConcat(&relativeToTransform, &finalAt, &portal->transform);
|
||||
transformConcat(&relativeToTransform, &finalAt, &portal->rigidBody.transform);
|
||||
} else {
|
||||
portal->transform = finalAt;
|
||||
portal->rigidBody.transform = finalAt;
|
||||
}
|
||||
|
||||
gCollisionScene.portalVelocity[portalIndex] = gZeroVec;
|
||||
portal->transformIndex = transformIndex;
|
||||
portal->roomIndex = roomIndex;
|
||||
portal->rigidBody.currentRoom = roomIndex;
|
||||
portal->colliderIndex = levelQuadIndex(collisionObject);
|
||||
portal->scale = 0.0f;
|
||||
collisionSceneSetPortal(portalIndex, &portal->transform, roomIndex, portal->colliderIndex);
|
||||
collisionSceneSetPortal(portalIndex, &portal->rigidBody.transform, roomIndex, portal->colliderIndex);
|
||||
collisionObjectUpdateBB(&portal->collisionObject);
|
||||
|
||||
soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f, &portal->transform.position, &gZeroVec);
|
||||
soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f, &portal->rigidBody.transform.position, &gZeroVec);
|
||||
|
||||
if (fromPlayer) {
|
||||
portal->flags |= PortalFlagsPlayerPortal;
|
||||
|
@ -783,7 +785,7 @@ int sceneOpenPortal(struct Scene* scene, struct Transform* at, int transformInde
|
|||
// something changed and play sound near other portal
|
||||
struct Portal* otherPortal = &scene->portals[1 - portalIndex];
|
||||
otherPortal->opacity = 1.0f;
|
||||
soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f, &otherPortal->transform.position, &gZeroVec);
|
||||
soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f, &otherPortal->rigidBody.transform.position, &gZeroVec);
|
||||
}
|
||||
|
||||
sceneCheckSecurityCamera(scene, portal);
|
||||
|
@ -794,7 +796,7 @@ int sceneOpenPortal(struct Scene* scene, struct Transform* at, int transformInde
|
|||
}
|
||||
|
||||
contactSolverCheckPortalContacts(&gContactSolver, collisionObject);
|
||||
ballBurnFilterOnPortal(&portal->transform, portalIndex);
|
||||
ballBurnFilterOnPortal(&portal->rigidBody.transform, portalIndex);
|
||||
playerSignalPortalChanged(&scene->player);
|
||||
return 1;
|
||||
}
|
||||
|
@ -895,6 +897,8 @@ void sceneClosePortal(struct Scene* scene, int portalIndex) {
|
|||
scene->portals[portalIndex].flags |= PortalFlagsNeedsNewHole;
|
||||
scene->portals[portalIndex].portalSurfaceIndex = -1;
|
||||
scene->portals[portalIndex].transformIndex = NO_TRANSFORM_INDEX;
|
||||
|
||||
collisionSceneRemoveDynamicObject(&scene->portals[portalIndex].collisionObject);
|
||||
}
|
||||
return;
|
||||
}
|
Loading…
Reference in a new issue