mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-19 22:27:36 -04:00
Add ball burn marks
This commit is contained in:
parent
26c8fa5f99
commit
e0789a13fc
5
Makefile
5
Makefile
|
@ -185,7 +185,8 @@ MODEL_LIST = assets/models/cube/cube.blend \
|
|||
assets/models/portal/portal_orange_filled.blend \
|
||||
assets/models/portal/portal_orange_face.blend \
|
||||
assets/models/pedestal.blend \
|
||||
assets/models/grav_flare.blend
|
||||
assets/models/grav_flare.blend \
|
||||
assets/models/fleck_ash2.blend
|
||||
|
||||
ANIM_LIST = build/assets/models/pedestal_anim.o \
|
||||
build/assets/models/props/box_dropper_anim.o \
|
||||
|
@ -220,7 +221,7 @@ build/src/scene/switch.o: build/assets/models/props/switch001.h build/assets/mat
|
|||
|
||||
build/src/player/player.o: build/assets/models/player/chell.h build/assets/materials/static.h
|
||||
|
||||
build/src/scene/ball.o: build/assets/models/grav_flare.h build/assets/materials/static.h
|
||||
build/src/scene/ball.o: build/assets/models/grav_flare.h build/assets/models/fleck_ash2.h build/assets/materials/static.h
|
||||
|
||||
build/src/scene/ball_launcher.o: build/assets/models/props/combine_ball_launcher.h build/assets/materials/static.h
|
||||
|
||||
|
|
|
@ -84,10 +84,6 @@ Where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where Blender
|
|||
|
||||
## Current TODO list
|
||||
|
||||
- [ ] close portal in elevator
|
||||
- [ ] checkpoint in elevator
|
||||
- [ ] keep stationary portal with fizzle grids
|
||||
- [ ] add more fizzle grids
|
||||
- [ ] red light district
|
||||
- [ ] burn marks
|
||||
- [ ] Skips audio sometimes
|
||||
|
@ -100,6 +96,10 @@ Where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where Blender
|
|||
- [ ] Presort portal gun polygon order
|
||||
- [ ] Signage should not always be on
|
||||
- [ ] Camera shake
|
||||
- [x] close portal in elevator
|
||||
- [x] keep stationary portal with fizzle grids
|
||||
- [x] add more fizzle grids
|
||||
- [x] checkpoint in elevator
|
||||
- [x] preserve gun between test chambers
|
||||
- [x] Finish up animation pieces (collider/portable surface/culling logic)
|
||||
- [x] Implement pedestal button
|
||||
|
|
1
assets/materials/decals/orange_spot.ims
Normal file
1
assets/materials/decals/orange_spot.ims
Normal file
|
@ -0,0 +1 @@
|
|||
-crop 128x128+0+0 -alpha extract -resize 32x32
|
1
assets/materials/effects/fleck_ash2.ims
Normal file
1
assets/materials/effects/fleck_ash2.ims
Normal file
|
@ -0,0 +1 @@
|
|||
-alpha extract
|
|
@ -679,4 +679,46 @@ materials:
|
|||
|
||||
properties:
|
||||
tileSizeS: 2
|
||||
tileSizeT: 2
|
||||
tileSizeT: 2
|
||||
|
||||
orange_spot:
|
||||
gDPSetTile:
|
||||
filename: ../../portal_pak_modified/materials/decals/orange_spot.png
|
||||
fmt: G_IM_FMT_I
|
||||
siz: G_IM_SIZ_4b
|
||||
s:
|
||||
mirror: true
|
||||
t:
|
||||
mirror: true
|
||||
|
||||
gDPSetRenderMode: G_RM_ZB_XLU_DECAL
|
||||
|
||||
gSPGeometryMode:
|
||||
clear: [G_LIGHTING, G_SHADE]
|
||||
gDPSetCombineMode:
|
||||
color: ["0", "0", "0", "PRIMITIVE"]
|
||||
alpha: ["0", "0", "0", "TEXEL0"]
|
||||
|
||||
gDPSetPrimColor:
|
||||
r: 230
|
||||
g: 103
|
||||
b: 36
|
||||
|
||||
fleck_ash2:
|
||||
gDPSetTile:
|
||||
filename: ../../portal_pak_modified/materials/effects/fleck_ash2.png
|
||||
fmt: G_IM_FMT_I
|
||||
siz: G_IM_SIZ_4b
|
||||
|
||||
gDPSetRenderMode: G_RM_ZB_XLU_DECAL
|
||||
|
||||
gSPGeometryMode:
|
||||
clear: [G_LIGHTING, G_SHADE]
|
||||
gDPSetCombineMode:
|
||||
color: ["0", "0", "0", "PRIMITIVE"]
|
||||
alpha: ["0", "0", "0", "TEXEL0"]
|
||||
|
||||
gDPSetPrimColor:
|
||||
r: 3
|
||||
g: 3
|
||||
b: 3
|
BIN
assets/models/fleck_ash2.blend
Normal file
BIN
assets/models/fleck_ash2.blend
Normal file
Binary file not shown.
1
assets/models/fleck_ash2.flags
Normal file
1
assets/models/fleck_ash2.flags
Normal file
|
@ -0,0 +1 @@
|
|||
-r 0,0,0 -m assets/materials/static.skm.yaml --default-material grav_flare
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -90,7 +90,7 @@ void decorObjectInit(struct DecorObject* object, struct DecorObjectDefinition* d
|
|||
collisionObjectUpdateBB(&object->collisionObject);
|
||||
}
|
||||
|
||||
object->dynamicId = dynamicSceneAdd(object, decorObjectRender, &object->rigidBody.transform, definition->radius);
|
||||
object->dynamicId = dynamicSceneAdd(object, decorObjectRender, &object->rigidBody.transform.position, definition->radius);
|
||||
|
||||
dynamicSceneSetRoomFlags(object->dynamicId, ROOM_FLAG_FROM_INDEX(room));
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
|
|||
quatMultVector(&location->transform.rotation, &gRight, &transformUp);
|
||||
vector3Negate(&transformUp, &transformUp);
|
||||
vector3AddScaled(&location->transform.position, &firingRay.dir, -0.1f, &firingRay.origin);
|
||||
sceneFirePortal(&gScene, &firingRay, &transformUp, step->openPortal.portalIndex, location->roomIndex);
|
||||
sceneFirePortal(&gScene, &firingRay, &transformUp, step->openPortal.portalIndex, location->roomIndex, 0);
|
||||
break;
|
||||
}
|
||||
case CutsceneStepTypeSetSignal:
|
||||
|
|
|
@ -17,6 +17,7 @@ struct Transform* levelRelativeTransform();
|
|||
struct Vector3* levelRelativeVelocity();
|
||||
|
||||
extern struct LevelDefinition* gCurrentLevel;
|
||||
extern int gCurrentLevelIndex;
|
||||
|
||||
int levelMaterialCount();
|
||||
int levelMaterialTransparentStart();
|
||||
|
|
|
@ -161,7 +161,7 @@ static void gameProc(void* arg) {
|
|||
contactSolverInit(&gContactSolver);
|
||||
portalSurfaceCleanupQueueInit();
|
||||
savefileNew();
|
||||
levelLoad(0);
|
||||
levelLoad(4);
|
||||
cutsceneRunnerReset();
|
||||
controllersInit();
|
||||
initAudio(fps);
|
||||
|
|
|
@ -125,7 +125,7 @@ void playerInit(struct Player* player, struct Location* startLocation, struct Ve
|
|||
player->flags |= PlayerHasSecondPortalGun;
|
||||
}
|
||||
|
||||
player->dynamicId = dynamicSceneAdd(player, playerRender, &player->body.transform, 1.5f);
|
||||
player->dynamicId = dynamicSceneAdd(player, playerRender, &player->body.transform.position, 1.5f);
|
||||
dynamicSceneSetFlags(player->dynamicId, DYNAMIC_SCENE_OBJECT_SKIP_ROOT);
|
||||
|
||||
if (startLocation) {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "../util/time.h"
|
||||
|
||||
#include "../build/assets/models/grav_flare.h"
|
||||
#include "../build/assets/models/fleck_ash2.h"
|
||||
#include "../build/assets/models/cube/cube.h"
|
||||
#include "../build/assets/materials/static.h"
|
||||
|
||||
|
@ -26,6 +27,32 @@ struct ColliderTypeData gBallCollider = {
|
|||
&gCollisionBoxCallbacks,
|
||||
};
|
||||
|
||||
struct BallBurnMark gBurnMarks[MAX_BURN_MARKS];
|
||||
short gCurrentBurnIndex;
|
||||
|
||||
void ballBurnMarkInit() {
|
||||
gCurrentBurnIndex = 0;
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
gBurnMarks[i].dynamicId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void ballBurnFilterOnPortal(struct Transform* portalTransform, int portalIndex) {
|
||||
for (int i = 0; i < MAX_BURN_MARKS; ++i) {
|
||||
struct BallBurnMark* burnMark = &gBurnMarks[i];
|
||||
|
||||
if (burnMark->dynamicId == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (collisionSceneIsTouchingSinglePortal(&burnMark->at, &burnMark->normal, portalTransform, portalIndex)) {
|
||||
dynamicSceneRemove(burnMark->dynamicId);
|
||||
burnMark->dynamicId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ballRender(void* data, struct RenderScene* renderScene, struct Transform* fromView) {
|
||||
struct Ball* ball = (struct Ball*)data;
|
||||
struct Transform transform;
|
||||
|
@ -40,6 +67,19 @@ void ballRender(void* data, struct RenderScene* renderScene, struct Transform* f
|
|||
renderSceneAdd(renderScene, grav_flare_model_gfx, mtx, GRAV_FLARE_INDEX, &ball->rigidBody.transform.position, NULL);
|
||||
}
|
||||
|
||||
void ballBurnRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState) {
|
||||
struct BallBurnMark* burn = (struct BallBurnMark*)data;
|
||||
|
||||
dynamicRenderListAddData(
|
||||
renderList,
|
||||
fleck_ash2_model_gfx,
|
||||
&burn->matrix,
|
||||
FLECK_ASH2_INDEX,
|
||||
&burn->at,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
void ballInitInactive(struct Ball* ball) {
|
||||
ball->targetSpeed = 0.0f;
|
||||
ball->flags = 0;
|
||||
|
@ -61,7 +101,7 @@ void ballInit(struct Ball* ball, struct Vector3* position, struct Vector3* veloc
|
|||
|
||||
ball->targetSpeed = sqrtf(vector3MagSqrd(&ball->rigidBody.velocity));
|
||||
|
||||
ball->dynamicId = dynamicSceneAddViewDependant(ball, ballRender, &ball->rigidBody.transform, BALL_RADIUS);
|
||||
ball->dynamicId = dynamicSceneAddViewDependant(ball, ballRender, &ball->rigidBody.transform.position, BALL_RADIUS);
|
||||
|
||||
dynamicSceneSetRoomFlags(ball->dynamicId, ROOM_FLAG_FROM_INDEX(startingRoom));
|
||||
}
|
||||
|
@ -70,6 +110,46 @@ void ballTurnOnCollision(struct Ball* ball) {
|
|||
ball->collisionObject.collisionLayers |= COLLISION_LAYERS_BLOCK_BALL;
|
||||
}
|
||||
|
||||
void ballInitBurn(struct Ball* ball, struct ContactManifold* manifold) {
|
||||
if (!manifold || manifold->contactCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// only add burn marks to static objects
|
||||
if (manifold->shapeA->body != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct BallBurnMark* burn = &gBurnMarks[gCurrentBurnIndex];
|
||||
|
||||
struct BallBurnMark* lastBurn = &gBurnMarks[(gCurrentBurnIndex == 0 ? MAX_BURN_MARKS : gCurrentBurnIndex) - 1];
|
||||
|
||||
struct Transform burnTransform;
|
||||
burnTransform.position = manifold->contacts[0].contactAWorld;
|
||||
|
||||
// don't double up burns
|
||||
if (vector3DistSqrd(&burnTransform.position, &lastBurn->at) < 0.1f) {
|
||||
return;
|
||||
}
|
||||
|
||||
++gCurrentBurnIndex;
|
||||
|
||||
if (gCurrentBurnIndex == MAX_BURN_MARKS) {
|
||||
gCurrentBurnIndex = 0;
|
||||
}
|
||||
|
||||
if (burn->dynamicId == -1) {
|
||||
burn->dynamicId = dynamicSceneAdd(burn, ballBurnRender, &burn->at, 0.2f);
|
||||
}
|
||||
|
||||
quatLook(&manifold->normal, &gUp, &burnTransform.rotation);
|
||||
burnTransform.scale = gOneVec;
|
||||
|
||||
transformToMatrixL(&burnTransform, &burn->matrix, SCENE_SCALE);
|
||||
burn->at = burnTransform.position;
|
||||
burn->normal = manifold->normal;
|
||||
}
|
||||
|
||||
void ballUpdate(struct Ball* ball) {
|
||||
if (ball->targetSpeed == 0.0f || ballIsCaught(ball)) {
|
||||
return;
|
||||
|
@ -96,6 +176,9 @@ void ballUpdate(struct Ball* ball) {
|
|||
dynamicSceneRemove(ball->dynamicId);
|
||||
}
|
||||
}
|
||||
|
||||
struct ContactManifold* manifold = contactSolverNextManifold(&gContactSolver, &ball->collisionObject, NULL);
|
||||
ballInitBurn(ball, manifold);
|
||||
}
|
||||
|
||||
int ballIsActive(struct Ball* ball) {
|
||||
|
|
|
@ -6,20 +6,33 @@
|
|||
#define BALL_VELOCITY 2.0f
|
||||
#define BALL_FADE_TIME 3.0f
|
||||
|
||||
#define MAX_BURN_MARKS 3
|
||||
|
||||
enum BallFlags {
|
||||
BallFlagsCaught = (1 << 0),
|
||||
BallFlagsPowering = (1 << 1),
|
||||
};
|
||||
|
||||
struct BallBurnMark {
|
||||
Mtx matrix;
|
||||
struct Vector3 at;
|
||||
struct Vector3 normal;
|
||||
short dynamicId;
|
||||
};
|
||||
|
||||
struct Ball {
|
||||
struct CollisionObject collisionObject;
|
||||
struct RigidBody rigidBody;
|
||||
|
||||
float targetSpeed;
|
||||
float lifetime;
|
||||
short dynamicId;
|
||||
short flags;
|
||||
};
|
||||
|
||||
void ballBurnMarkInit();
|
||||
void ballBurnFilterOnPortal(struct Transform* portalTransform, int portalIndex);
|
||||
|
||||
void ballInitInactive(struct Ball* ball);
|
||||
void ballInit(struct Ball* ball, struct Vector3* position, struct Vector3* velocity, short startingRoom, float ballLifetime);
|
||||
void ballTurnOnCollision(struct Ball* ball);
|
||||
|
|
|
@ -71,7 +71,7 @@ void ballCatcherInit(struct BallCatcher* catcher, struct BallCatcherDefinition*
|
|||
|
||||
collisionObjectUpdateBB(&catcher->collisionObject);
|
||||
|
||||
catcher->dynamicId = dynamicSceneAdd(catcher, ballCatcherRender, &catcher->rigidBody.transform, 1.0f);
|
||||
catcher->dynamicId = dynamicSceneAdd(catcher, ballCatcherRender, &catcher->rigidBody.transform.position, 1.0f);
|
||||
|
||||
dynamicSceneSetRoomFlags(catcher->dynamicId, ROOM_FLAG_FROM_INDEX(catcher->rigidBody.currentRoom));
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ void ballLauncherInit(struct BallLauncher* launcher, struct BallLauncherDefiniti
|
|||
|
||||
collisionObjectUpdateBB(&launcher->collisionObject);
|
||||
|
||||
launcher->dynamicId = dynamicSceneAdd(launcher, ballLauncherRender, &launcher->rigidBody.transform, 1.0f);
|
||||
launcher->dynamicId = dynamicSceneAdd(launcher, ballLauncherRender, &launcher->rigidBody.transform.position, 1.0f);
|
||||
|
||||
dynamicSceneSetRoomFlags(launcher->dynamicId, ROOM_FLAG_FROM_INDEX(launcher->rigidBody.currentRoom));
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ void boxDropperRender(void* data, struct DynamicRenderDataList* renderList, stru
|
|||
}
|
||||
|
||||
void boxDropperInit(struct BoxDropper* dropper, struct BoxDropperDefinition* definition) {
|
||||
dropper->dynamicId = dynamicSceneAdd(dropper, boxDropperRender, &dropper->transform, 1.5f);
|
||||
dropper->dynamicId = dynamicSceneAdd(dropper, boxDropperRender, &dropper->transform.position, 1.5f);
|
||||
|
||||
dropper->transform.position = definition->position;
|
||||
quatIdent(&dropper->transform.rotation);
|
||||
|
|
|
@ -80,7 +80,7 @@ void buttonInit(struct Button* button, struct ButtonDefinition* definition) {
|
|||
|
||||
collisionObjectUpdateBB(&button->collisionObject);
|
||||
|
||||
button->dynamicId = dynamicSceneAdd(button, buttonRender, &button->rigidBody.transform, 0.84f);
|
||||
button->dynamicId = dynamicSceneAdd(button, buttonRender, &button->rigidBody.transform.position, 0.84f);
|
||||
button->signalIndex = definition->signalIndex;
|
||||
|
||||
button->originalPos = definition->location;
|
||||
|
|
|
@ -71,7 +71,7 @@ void doorInit(struct Door* door, struct DoorDefinition* doorDefinition, struct W
|
|||
|
||||
collisionObjectUpdateBB(&door->collisionObject);
|
||||
|
||||
door->dynamicId = dynamicSceneAdd(door, doorRender, &door->rigidBody.transform, 1.7f);
|
||||
door->dynamicId = dynamicSceneAdd(door, doorRender, &door->rigidBody.transform.position, 1.7f);
|
||||
door->signalIndex = doorDefinition->signalIndex;
|
||||
door->openAmount = 0.0f;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ void dynamicRenderListPopulate(struct DynamicRenderDataList* list, struct Render
|
|||
int visibleStages = 0;
|
||||
|
||||
struct Vector3 scaledPos;
|
||||
vector3Scale(&object->transform->position, &scaledPos, SCENE_SCALE);
|
||||
vector3Scale(object->position, &scaledPos, SCENE_SCALE);
|
||||
|
||||
for (int stageIndex = 0; stageIndex < stageCount; ++stageIndex) {
|
||||
if ((stages[stageIndex].visiblerooms & object->roomFlags) == 0) {
|
||||
|
@ -117,7 +117,7 @@ void dynamicRenderPopulateRenderScene(
|
|||
}
|
||||
|
||||
struct Vector3 scaledPos;
|
||||
vector3Scale(&object->transform->position, &scaledPos, SCENE_SCALE);
|
||||
vector3Scale(object->position, &scaledPos, SCENE_SCALE);
|
||||
|
||||
if (isSphereOutsideFrustrum(cullingInfo, &scaledPos, object->scaledRadius)) {
|
||||
continue;
|
||||
|
|
|
@ -15,7 +15,7 @@ void dynamicSceneInit() {
|
|||
}
|
||||
}
|
||||
|
||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform* transform, float radius) {
|
||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Vector3* position, float radius) {
|
||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||
struct DynamicSceneObject* object = &gDynamicScene.objects[i];
|
||||
if (!(object->flags & DYNAMIC_SCENE_OBJECT_FLAGS_USED)) {
|
||||
|
@ -23,7 +23,7 @@ int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform*
|
|||
object->flags = DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE;
|
||||
object->data = data;
|
||||
object->renderCallback = renderCallback;
|
||||
object->transform = transform;
|
||||
object->position = position;
|
||||
object->scaledRadius = radius * SCENE_SCALE;
|
||||
object->roomFlags = ~0;
|
||||
return i;
|
||||
|
@ -33,7 +33,7 @@ int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform*
|
|||
return INVALID_DYNAMIC_OBJECT;
|
||||
}
|
||||
|
||||
int dynamicSceneAddViewDependant(void* data, DynamicViewRender renderCallback, struct Transform* transform, float radius) {
|
||||
int dynamicSceneAddViewDependant(void* data, DynamicViewRender renderCallback, struct Vector3* position, float radius) {
|
||||
for (int i = 0; i < MAX_VIEW_DEPENDANT_OBJECTS; ++i) {
|
||||
struct DynamicSceneViewDependantObject* object = &gDynamicScene.viewDependantObjects[i];
|
||||
if (!(object->flags & DYNAMIC_SCENE_OBJECT_FLAGS_USED)) {
|
||||
|
@ -41,7 +41,7 @@ int dynamicSceneAddViewDependant(void* data, DynamicViewRender renderCallback, s
|
|||
object->flags = DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE;
|
||||
object->data = data;
|
||||
object->renderCallback = renderCallback;
|
||||
object->transform = transform;
|
||||
object->position = position;
|
||||
object->scaledRadius = radius * SCENE_SCALE;
|
||||
object->roomFlags = ~0;
|
||||
return i + MAX_DYNAMIC_SCENE_OBJECTS;
|
||||
|
|
|
@ -11,7 +11,7 @@ struct DynamicRenderDataList;
|
|||
typedef void (*DynamicRender)(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState);
|
||||
typedef void (*DynamicViewRender)(void* data, struct RenderScene* renderScene, struct Transform* fromView);
|
||||
|
||||
#define MAX_DYNAMIC_SCENE_OBJECTS 32
|
||||
#define MAX_DYNAMIC_SCENE_OBJECTS 64
|
||||
#define MAX_VIEW_DEPENDANT_OBJECTS 8
|
||||
|
||||
#define DYNAMIC_SCENE_OBJECT_FLAGS_USED (1 << 0)
|
||||
|
@ -25,7 +25,7 @@ typedef void (*DynamicViewRender)(void* data, struct RenderScene* renderScene, s
|
|||
struct DynamicSceneObject {
|
||||
void* data;
|
||||
DynamicRender renderCallback;
|
||||
struct Transform* transform;
|
||||
struct Vector3* position;
|
||||
float scaledRadius;
|
||||
u16 flags;
|
||||
u64 roomFlags;
|
||||
|
@ -34,7 +34,7 @@ struct DynamicSceneObject {
|
|||
struct DynamicSceneViewDependantObject {
|
||||
void* data;
|
||||
DynamicViewRender renderCallback;
|
||||
struct Transform* transform;
|
||||
struct Vector3* position;
|
||||
float scaledRadius;
|
||||
u16 flags;
|
||||
u64 roomFlags;
|
||||
|
@ -47,8 +47,8 @@ struct DynamicScene {
|
|||
|
||||
void dynamicSceneInit();
|
||||
|
||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform* transform, float radius);
|
||||
int dynamicSceneAddViewDependant(void* data, DynamicViewRender renderCallback, struct Transform* transform, float radius);
|
||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Vector3* position, float radius);
|
||||
int dynamicSceneAddViewDependant(void* data, DynamicViewRender renderCallback, struct Vector3* position, float radius);
|
||||
void dynamicSceneRemove(int id);
|
||||
void dynamicSceneSetFlags(int id, int flags);
|
||||
void dynamicSceneClearFlags(int id, int flags);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "../../build/assets/materials/static.h"
|
||||
|
||||
#define AUTO_OPEN_DISTANCE 4.0f
|
||||
#define INSIDE_DISTANCE 1.0f
|
||||
#define INSIDE_DISTANCE 1.2f
|
||||
#define SAME_LEVEL_HEIGHT 3.0f
|
||||
#define OPEN_SPEED 2.0f
|
||||
|
||||
|
@ -95,7 +95,7 @@ void elevatorInit(struct Elevator* elevator, struct ElevatorDefinition* elevator
|
|||
|
||||
collisionObjectUpdateBB(&elevator->collisionObject);
|
||||
|
||||
elevator->dynamicId = dynamicSceneAdd(elevator, elevatorRender, &elevator->rigidBody.transform, 3.9f);
|
||||
elevator->dynamicId = dynamicSceneAdd(elevator, elevatorRender, &elevator->rigidBody.transform.position, 3.9f);
|
||||
elevator->flags = elevatorDefinition->targetElevator == -1 ? ElevatorFlagsIsExit : 0;
|
||||
elevator->openAmount = 0.0f;
|
||||
elevator->roomIndex = elevatorDefinition->roomIndex;
|
||||
|
|
|
@ -152,7 +152,7 @@ void fizzlerInit(struct Fizzler* fizzler, struct Transform* transform, float wid
|
|||
}
|
||||
|
||||
fizzler->oldestParticleIndex = 0;
|
||||
fizzler->dynamicId = dynamicSceneAdd(fizzler, fizzlerRender, &fizzler->rigidBody.transform, sqrtf(width * width + height * height) * 0.5f);
|
||||
fizzler->dynamicId = dynamicSceneAdd(fizzler, fizzlerRender, &fizzler->rigidBody.transform.position, sqrtf(width * width + height * height) * 0.5f);
|
||||
|
||||
dynamicSceneSetRoomFlags(fizzler->dynamicId, ROOM_FLAG_FROM_INDEX(room));
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ void pedestalInit(struct Pedestal* pedestal, struct PedestalDefinition* definiti
|
|||
|
||||
skAnimatorInit(&pedestal->animator, PEDESTAL_DEFAULT_BONES_COUNT);
|
||||
|
||||
pedestal->dynamicId = dynamicSceneAdd(pedestal, pedestalRender, &pedestal->transform, 0.8f);
|
||||
pedestal->dynamicId = dynamicSceneAdd(pedestal, pedestalRender, &pedestal->transform.position, 0.8f);
|
||||
|
||||
dynamicSceneSetRoomFlags(pedestal->dynamicId, ROOM_FLAG_FROM_INDEX(definition->roomIndex));
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
enum PortalFlags {
|
||||
PortalFlagsOddParity = (1 << 0),
|
||||
PortalFlagsNeedsNewHole = (1 << 1),
|
||||
PortalFlagsPlayerPortal = (1 << 2),
|
||||
};
|
||||
|
||||
struct Portal {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "../physics/collision_scene.h"
|
||||
#include "../levels/static_render.h"
|
||||
#include "../levels/levels.h"
|
||||
#include "../levels/checkpoint.h"
|
||||
#include "../scene/portal_surface.h"
|
||||
#include "../math/mathf.h"
|
||||
#include "./hud.h"
|
||||
|
@ -36,6 +37,9 @@ struct Vector3 gPortalGunUp = {0.0f, 1.0f, 0.0f};
|
|||
|
||||
Lights1 gSceneLights = gdSPDefLights1(128, 128, 128, 128, 128, 128, 0, 127, 0);
|
||||
|
||||
#define LEVEL_INDEX_WITH_GUN_0 2
|
||||
#define LEVEL_INDEX_WITH_GUN_1 8
|
||||
|
||||
void sceneUpdateListeners(struct Scene* scene);
|
||||
|
||||
void sceneInitDynamicColliders(struct Scene* scene) {
|
||||
|
@ -77,6 +81,14 @@ void sceneInit(struct Scene* scene) {
|
|||
playerInit(&scene->player, &combinedLocation, &startVelocity);
|
||||
sceneUpdateListeners(scene);
|
||||
|
||||
if (gCurrentLevelIndex >= LEVEL_INDEX_WITH_GUN_0) {
|
||||
playerGivePortalGun(&scene->player, PlayerHasFirstPortalGun);
|
||||
}
|
||||
|
||||
if (gCurrentLevelIndex >= LEVEL_INDEX_WITH_GUN_1) {
|
||||
playerGivePortalGun(&scene->player, PlayerHasSecondPortalGun);
|
||||
}
|
||||
|
||||
portalInit(&scene->portals[0], 0);
|
||||
portalInit(&scene->portals[1], PortalFlagsOddParity);
|
||||
|
||||
|
@ -147,6 +159,8 @@ void sceneInit(struct Scene* scene) {
|
|||
switchInit(&scene->switches[i], &gCurrentLevel->switches[i]);
|
||||
}
|
||||
|
||||
ballBurnMarkInit();
|
||||
|
||||
scene->ballLancherCount = gCurrentLevel->ballLauncherCount;
|
||||
scene->ballLaunchers = malloc(sizeof(struct BallLauncher) * scene->ballLancherCount);
|
||||
for (int i = 0; i < scene->ballLancherCount; ++i) {
|
||||
|
@ -257,18 +271,22 @@ void sceneCheckPortals(struct Scene* scene) {
|
|||
quatMultVector(&scene->player.lookTransform.rotation, &gUp, &playerUp);
|
||||
|
||||
if (controllerGetButtonDown(0, Z_TRIG) && (scene->player.flags & PlayerHasSecondPortalGun)) {
|
||||
sceneFirePortal(scene, &raycastRay, &playerUp, 0, scene->player.body.currentRoom);
|
||||
sceneFirePortal(scene, &raycastRay, &playerUp, 0, scene->player.body.currentRoom, 1);
|
||||
soundPlayerPlay(soundsPortalgunShoot[0], 1.0f, 1.0f, NULL);
|
||||
}
|
||||
|
||||
if (controllerGetButtonDown(0, R_TRIG | L_TRIG) && (scene->player.flags & PlayerHasFirstPortalGun)) {
|
||||
sceneFirePortal(scene, &raycastRay, &playerUp, 1, scene->player.body.currentRoom);
|
||||
sceneFirePortal(scene, &raycastRay, &playerUp, 1, scene->player.body.currentRoom, 1);
|
||||
soundPlayerPlay(soundsPortalgunShoot[1], 1.0f, 1.0f, NULL);
|
||||
}
|
||||
|
||||
if (scene->player.body.flags & RigidBodyFizzled) {
|
||||
sceneClosePortal(scene, 0);
|
||||
sceneClosePortal(scene, 1);
|
||||
if (scene->portals[0].flags & PortalFlagsPlayerPortal) {
|
||||
sceneClosePortal(scene, 0);
|
||||
}
|
||||
if (scene->portals[1].flags & PortalFlagsPlayerPortal) {
|
||||
sceneClosePortal(scene, 1);
|
||||
}
|
||||
scene->player.body.flags &= ~RigidBodyFizzled;
|
||||
}
|
||||
|
||||
|
@ -437,6 +455,9 @@ void sceneUpdate(struct Scene* scene) {
|
|||
&gZeroVec,
|
||||
scene->elevators[teleportTo].roomIndex
|
||||
);
|
||||
checkpointSave(&gScene);
|
||||
sceneClosePortal(&gScene, 0);
|
||||
sceneClosePortal(&gScene, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -508,7 +529,7 @@ void sceneUpdate(struct Scene* scene) {
|
|||
}
|
||||
}
|
||||
|
||||
int sceneOpenPortal(struct Scene* scene, struct Transform* at, int transformIndex, int portalIndex, struct PortalSurfaceMappingRange surfaceMapping, struct CollisionObject* collisionObject, int roomIndex) {
|
||||
int sceneOpenPortal(struct Scene* scene, struct Transform* at, int transformIndex, int portalIndex, struct PortalSurfaceMappingRange surfaceMapping, struct CollisionObject* collisionObject, int roomIndex, int fromPlayer) {
|
||||
struct Transform finalAt;
|
||||
|
||||
struct Transform relativeToTransform;
|
||||
|
@ -547,12 +568,19 @@ int sceneOpenPortal(struct Scene* scene, struct Transform* at, int transformInde
|
|||
gCollisionScene.portalTransforms[portalIndex] = &portal->transform;
|
||||
gCollisionScene.portalRooms[portalIndex] = roomIndex;
|
||||
|
||||
if (fromPlayer) {
|
||||
portal->flags |= PortalFlagsPlayerPortal;
|
||||
} else {
|
||||
portal->flags &= ~PortalFlagsPlayerPortal;
|
||||
}
|
||||
|
||||
if (collisionSceneIsPortalOpen()) {
|
||||
// the second portal is fully transparent right away
|
||||
portal->opacity = 0.0f;
|
||||
}
|
||||
|
||||
contactSolverCheckPortalContacts(&gContactSolver, collisionObject);
|
||||
ballBurnFilterOnPortal(&portal->transform, portalIndex);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -588,7 +616,7 @@ int sceneDetermineSurfaceMapping(struct Scene* scene, struct CollisionObject* hi
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* playerUp, int portalIndex, int roomIndex) {
|
||||
int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* playerUp, int portalIndex, int roomIndex, int fromPlayer) {
|
||||
struct RaycastHit hit;
|
||||
|
||||
if (!collisionSceneRaycast(&gCollisionScene, roomIndex, ray, COLLISION_LAYERS_STATIC | COLLISION_LAYERS_BLOCK_PORTAL, 1000000.0f, 0, &hit)) {
|
||||
|
@ -626,7 +654,7 @@ int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* player
|
|||
quatLook(&hitDirection, &upDir, &portalLocation.rotation);
|
||||
}
|
||||
|
||||
return sceneOpenPortal(scene, &portalLocation, relativeIndex, portalIndex, mappingRange, hit.object, hit.roomIndex);
|
||||
return sceneOpenPortal(scene, &portalLocation, relativeIndex, portalIndex, mappingRange, hit.object, hit.roomIndex, fromPlayer);
|
||||
}
|
||||
|
||||
void sceneClosePortal(struct Scene* scene, int portalIndex) {
|
||||
|
|
|
@ -63,7 +63,7 @@ void sceneInit(struct Scene* scene);
|
|||
void sceneRender(struct Scene* scene, struct RenderState* renderState, struct GraphicsTask* task);
|
||||
void sceneUpdate(struct Scene* scene);
|
||||
|
||||
int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* playerUp, int portalIndex, int roomIndex);
|
||||
int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* playerUp, int portalIndex, int roomIndex, int fromPlayer);
|
||||
void sceneClosePortal(struct Scene* scene, int portalIndex);
|
||||
|
||||
#endif
|
|
@ -143,7 +143,7 @@ void signageInit(struct Signage* signage, struct SignageDefinition* definition)
|
|||
signage->roomIndex = definition->roomIndex;
|
||||
signage->testChamberNumber = definition->testChamberNumber;
|
||||
|
||||
int dynamicId = dynamicSceneAdd(signage, signageRender, &signage->transform, 1.7f);
|
||||
int dynamicId = dynamicSceneAdd(signage, signageRender, &signage->transform.position, 1.7f);
|
||||
|
||||
dynamicSceneSetRoomFlags(dynamicId, ROOM_FLAG_FROM_INDEX(definition->roomIndex));
|
||||
}
|
|
@ -81,7 +81,7 @@ void switchInit(struct Switch* switchObj, struct SwitchDefinition* definition) {
|
|||
|
||||
collisionObjectUpdateBB(&switchObj->collisionObject);
|
||||
|
||||
switchObj->dynamicId = dynamicSceneAdd(switchObj, switchRender, &switchObj->rigidBody.transform, COLLIDER_HEIGHT * 0.5f);
|
||||
switchObj->dynamicId = dynamicSceneAdd(switchObj, switchRender, &switchObj->rigidBody.transform.position, COLLIDER_HEIGHT * 0.5f);
|
||||
switchObj->signalIndex = definition->signalIndex;
|
||||
|
||||
dynamicSceneSetRoomFlags(switchObj->dynamicId, ROOM_FLAG_FROM_INDEX(switchObj->rigidBody.currentRoom));
|
||||
|
|
Loading…
Reference in a new issue