Work on portal gun pedestal

work on movement polish
This commit is contained in:
James Lambert 2022-08-04 12:58:10 -06:00
parent 6ced424472
commit ec0c6a79dc
21 changed files with 247 additions and 35 deletions

View file

@ -173,8 +173,10 @@ MODEL_LIST = assets/models/cube/cube.blend \
assets/models/portal/portal_blue_face.blend \
assets/models/portal/portal_orange.blend \
assets/models/portal/portal_orange_filled.blend \
assets/models/portal/portal_orange_face.blend
assets/models/portal/portal_orange_face.blend \
assets/models/pedestal.blend
ANIM_LIST = build/assets/models/pedestal_anim.o
MODEL_HEADERS = $(MODEL_LIST:%.blend=build/%.h)
MODEL_OBJECTS = $(MODEL_LIST:%.blend=build/%_geo.o)
@ -188,6 +190,12 @@ build/src/decor/decor_object_list.o: $(MODEL_HEADERS)
build/src/scene/portal.o: $(MODEL_HEADERS)
build/assets/models/%_anim.o: build/assets/models/%.h
build/anims.ld: $(ANIM_LIST) tools/generate_animation_ld.js
@mkdir -p $(@D)
node tools/generate_animation_ld.js $@ $(ANIM_LIST)
####################
## Test Chambers
####################
@ -271,6 +279,8 @@ build/src/audio/clips.h: tools/generate_sound_ids.js $(SOUND_CLIPS)
build/src/audio/clips.o: build/src/audio/clips.h
build/src/decor/decor_object_list.o: build/src/audio/clips.h
build/src/scene/pedestal.o: build/assets/models/pedestal.h
####################
## Linking
####################
@ -292,7 +302,7 @@ $(CODESEGMENT)_no_debug.o: $(CODEOBJECTS_NO_DEBUG)
$(LD) -o $(CODESEGMENT)_no_debug.o -r $(CODEOBJECTS_NO_DEBUG) $(LDFLAGS)
$(CP_LD_SCRIPT)_no_debug.ld: $(LD_SCRIPT) build/levels.ld
$(CP_LD_SCRIPT)_no_debug.ld: $(LD_SCRIPT) build/levels.ld build/anims.ld
cpp -P -Wno-trigraphs $(LCDEFS) -DCODE_SEGMENT=$(CODESEGMENT)_no_debug.o -o $@ $<
$(BASE_TARGET_NAME).z64: $(CODESEGMENT)_no_debug.o $(OBJECTS) $(CP_LD_SCRIPT)_no_debug.ld
@ -310,7 +320,7 @@ endif
$(CODESEGMENT)_debug.o: $(CODEOBJECTS_DEBUG)
$(LD) -o $(CODESEGMENT)_debug.o -r $(CODEOBJECTS_DEBUG) $(LDFLAGS)
$(CP_LD_SCRIPT)_debug.ld: $(LD_SCRIPT) build/levels.ld
$(CP_LD_SCRIPT)_debug.ld: $(LD_SCRIPT) build/levels.ld build/anims.ld
cpp -P -Wno-trigraphs $(LCDEFS) -DCODE_SEGMENT=$(CODESEGMENT)_debug.o -o $@ $<
$(BASE_TARGET_NAME)_debug.z64: $(CODESEGMENT)_debug.o $(OBJECTS) $(CP_LD_SCRIPT)_debug.ld

View file

@ -84,20 +84,14 @@ Where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where Blender
## Current TODO list
- [ ] Fix bug where opening a portal can trigger a teleportation
- [ ] Prevent Glados from talking over herself
- [ ] Elevator and door sounds
- [ ] Portal gun pedistal
- [ ] Turn level indicator board into a game object
- [ ] Presort portal gun polygon order
- [ ] Implement level transitions
- Implement loading levels from the cartridge
- [ ] Change the way player standing logic works
- [ ] Cube dispenser
- [ ] NAN in overlap
- [x] Implement "Elevator"
- [x] Implement "Emancipation grid"
- [x] Cut holes in portal walls
- [x] Get an optimized build working
- [x] Portal animations
- [x] Figure out why clip is silent
- [x] Fix z fighting in elevator
- [x] Fix crash
- [x] Determine why bad gfx cause RDP crash
- [x] Fix portal overlapping bug
- [x] Fix bug where opening a portal can trigger a teleportation
- [x] Implement level transitions

View file

@ -105,3 +105,31 @@ materials:
set: [G_LIGHTING, G_SHADE]
gDPSetCombineMode:
color: ["SHADE", "0", "PRIMITIVE", "0"]
solid_white:
gDPSetPrimColor:
r: 255
g: 255
b: 255
gSPGeometryMode:
set: [G_LIGHTING, G_SHADE]
gDPSetCombineMode:
color: ["PRIMITIVE", "0", "SHADE", "0"]
solid_black:
gDPSetPrimColor:
r: 32
g: 32
b: 32
gSPGeometryMode:
set: [G_LIGHTING, G_SHADE]
gDPSetCombineMode:
color: ["PRIMITIVE", "0", "SHADE", "0"]
blue_glow:
gDPSetPrimColor:
r: 32
g: 32
b: 32
gDPSetCombineMode:
color: ["0", "0", "0", "PRIMITIVE"]

Binary file not shown.

View file

@ -0,0 +1 @@
-r 90,0,0 -m assets/materials/static.skm.yaml -m assets/materials/objects.skm.yaml --default-material default

View file

@ -71,6 +71,7 @@ SECTIONS
END_SEG(sound_data)
#include "build/levels.ld"
#include "build/anims.ld"
/* Discard everything not specifically mentioned above. */
/DISCARD/ :

View file

@ -664,6 +664,44 @@ void generateElevatorDefinitions(
levelDef.AddPrimitive("elevatorCount", elevatorCount);
}
void generatePedestalDefinitions(
const aiScene* scene,
CFileDefinition& fileDefinition,
StructureDataChunk& levelDef,
const RoomGeneratorOutput& roomOutput,
const DisplayListSettings& settings,
NodeGroups& nodeGroups) {
int pedestalCount = 0;
std::unique_ptr<StructureDataChunk> pedestals(new StructureDataChunk());
aiMatrix4x4 baseTransform = settings.CreateCollisionTransform();
for (auto& nodeInfo : nodeGroups.NodesForType("@pedestal")) {
std::unique_ptr<StructureDataChunk> pedestalsData(new StructureDataChunk());
aiVector3D pos;
aiQuaternion rot;
aiVector3D scale;
(baseTransform * nodeInfo.node->mTransformation).Decompose(scale, rot, pos);
pedestalsData->Add(std::unique_ptr<StructureDataChunk>(new StructureDataChunk(pos)));
pedestalsData->AddPrimitive(roomOutput.RoomForNode(nodeInfo.node));
pedestals->Add(std::move(pedestalsData));
++pedestalCount;
}
std::string pedestalsCount = fileDefinition.AddDataDefinition(
"pedestals",
"struct PedestalDefinition",
true,
"_geo",
std::move(pedestals)
);
levelDef.AddPrimitive("pedestals", pedestalsCount);
levelDef.AddPrimitive("pedestalCount", pedestalCount);
}
void generateLevel(
const aiScene* scene,
CFileDefinition& fileDefinition,
@ -707,5 +745,7 @@ void generateLevel(
generateElevatorDefinitions(scene, fileDefinition, *levelDef, roomOutput, settings, signals, nodeGroups);
generatePedestalDefinitions(scene, fileDefinition, *levelDef, roomOutput, settings, nodeGroups);
fileDefinition.AddDefinition(std::unique_ptr<FileDefinition>(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef))));
}

View file

@ -130,6 +130,11 @@ struct ElevatorDefinition {
short isExit;
};
struct PedestalDefinition {
struct Vector3 position;
short roomIndex;
};
struct LevelDefinition {
struct CollisionObject* collisionQuads;
struct StaticContentElement *staticContent;
@ -149,6 +154,7 @@ struct LevelDefinition {
struct DecorDefinition* decor;
struct FizzlerDefinition* fizzlers;
struct ElevatorDefinition* elevators;
struct PedestalDefinition* pedestals;
short collisionQuadCount;
short staticContentCount;
short portalSurfaceCount;
@ -161,6 +167,7 @@ struct LevelDefinition {
short decorCount;
short fizzlerCount;
short elevatorCount;
short pedestalCount;
short startLocation;
};

View file

@ -76,6 +76,7 @@ struct LevelDefinition* levelFixPointers(struct LevelDefinition* from, int point
result->decor = ADJUST_POINTER_POS(result->decor, pointerOffset);
result->fizzlers = ADJUST_POINTER_POS(result->fizzlers, pointerOffset);
result->elevators = ADJUST_POINTER_POS(result->elevators, pointerOffset);
result->pedestals = ADJUST_POINTER_POS(result->pedestals, pointerOffset);
return result;
}

View file

@ -149,7 +149,7 @@ static void gameProc(void* arg) {
dynamicSceneInit();
contactSolverInit(&gContactSolver);
levelLoad(1);
levelLoad(0);
controllersInit();
initAudio();
soundPlayerInit();

View file

@ -79,7 +79,7 @@ void playerInit(struct Player* player, struct Location* startLocation) {
#define ROTATE_RATE_DELTA (M_PI * 0.125f)
#define ROTATE_RATE_STOP_DELTA (M_PI * 0.25f)
#define JUMP_IMPULSE 3.2f
#define JUMP_IMPULSE 2.7f
void playerHandleCollision(struct Player* player) {
struct ContactManifold* contact = contactSolverNextManifold(&gContactSolver, &player->collisionObject, NULL);

View file

@ -9,7 +9,7 @@
#define PLAYER_GRABBING_THROUGH_NOTHING -1
#define PLAYER_HEAD_HEIGHT 0.8f
#define PLAYER_HEAD_HEIGHT 1.0f
enum PlayerFlags {
PlayerFlagsGrounded = (1 << 0),

View file

@ -3,6 +3,7 @@
#include "math/transform.h"
#include "defs.h"
#include "../graphics/graphics.h"
#include "../math/mathf.h"
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingBoxs16* boundingBox) {
for (int i = 0; i < frustrum->usedClippingPlaneCount; ++i) {
@ -90,6 +91,10 @@ void cameraExtractClippingPlane(float viewPersp[4][4], struct Plane* output, int
output->d *= mult;
}
int cameraIsValidMatrix(float matrix[4][4]) {
return fabsf(matrix[3][0]) <= 0x7fff && fabsf(matrix[3][1]) <= 0x7fff && fabsf(matrix[3][2]) <= 0x7fff;
}
Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState, float aspectRatio, u16* perspNorm, Vp* viewport, struct FrustrumCullingInformation* clippingInfo) {
Mtx* viewProjMatrix = renderStateRequestMatrices(renderState, 2);
@ -97,6 +102,8 @@ Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState,
return NULL;
}
Gfx* renderStateStart = renderState->dl;
guMtxIdent(&viewProjMatrix[0]);
gSPMatrix(renderState->dl++, osVirtualToPhysical(&viewProjMatrix[0]), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
@ -117,6 +124,11 @@ Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState,
cameraBuildViewMatrix(camera, view);
guMtxCatF(view, persp, combined);
if (!cameraIsValidMatrix(combined)) {
goto error;
}
guMtxF2L(combined, &viewProjMatrix[1]);
if (clippingInfo) {
@ -137,4 +149,8 @@ Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState,
}
return &viewProjMatrix[1];
error:
renderState->dl = renderStateStart;
return NULL;
}

44
src/scene/pedestal.c Normal file
View file

@ -0,0 +1,44 @@
#include "pedestal.h"
#include "../scene/dynamic_scene.h"
#include "../defs.h"
#include "../build/assets/materials/static.h"
#include "../build/assets/models/pedestal.h"
void pedestalRender(void* data, struct RenderScene* renderScene) {
struct Pedestal* pedestal = (struct Pedestal*)data;
Mtx* matrix = renderStateRequestMatrices(renderScene->renderState, 1);
transformToMatrixL(&pedestal->transform, matrix, SCENE_SCALE);
Mtx* armature = renderStateRequestMatrices(renderScene->renderState, pedestal->armature.numberOfBones);
skCalculateTransforms(&pedestal->armature, armature);
renderSceneAdd(
renderScene,
pedestal->armature.displayList,
matrix,
DEFAULT_INDEX,
&pedestal->transform.position,
armature
);
}
void pedestalInit(struct Pedestal* pedestal, struct PedestalDefinition* definition) {
transformInitIdentity(&pedestal->transform);
pedestal->transform.position = definition->position;
pedestal->roomIndex = definition->roomIndex;
skArmatureInit(
&pedestal->armature,
pedestal_model_gfx,
PEDESTAL_DEFAULT_BONES_COUNT,
pedestal_default_bones,
pedestal_bone_parent
);
pedestal->dynamicId = dynamicSceneAdd(pedestal, pedestalRender, &pedestal->transform, 0.8f);
}

17
src/scene/pedestal.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef __SCENE_PEDESTAL_H__
#define __SCENE_PEDESTAL_H__
#include "../sk64/skelatool_armature.h"
#include "../levels/level_definition.h"
struct Pedestal {
struct Transform transform;
struct SKArmature armature;
short dynamicId;
short roomIndex;
};
void pedestalInit(struct Pedestal* pedestal, struct PedestalDefinition* definition);
#endif

View file

@ -173,7 +173,7 @@ Vp* renderPropsBuildViewport(struct RenderProps* props, struct RenderState* rend
return viewport;
}
void renderPropsNext(struct RenderProps* current, struct RenderProps* next, struct Transform* fromPortal, struct Transform* toPortal, struct RenderState* renderState) {
int renderPropsNext(struct RenderProps* current, struct RenderProps* next, struct Transform* fromPortal, struct Transform* toPortal, struct RenderState* renderState) {
struct Transform otherInverse;
transformInvert(fromPortal, &otherInverse);
struct Transform portalCombined;
@ -200,7 +200,10 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru
}
// render any objects halfway through portals
cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, current->viewport, NULL);
if (!cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, current->viewport, NULL)) {
return 0;
}
dynamicSceneRenderTouchingPortal(&next->camera.transform, &current->cullingInfo, renderState);
next->currentDepth = current->currentDepth - 1;
@ -240,6 +243,8 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru
gSPViewport(renderState->dl++, viewport);
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, next->minX, next->minY, next->maxX, next->maxY);
#endif
return 1;
}
void portalInit(struct Portal* portal, enum PortalFlags flags) {
@ -337,6 +342,19 @@ void portalRenderScreenCover(struct Vector2s16* points, int pointCount, struct R
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
}
void portalRenderCover(struct Portal* portal, float portalTransform[4][4], struct RenderState* renderState) {
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
guMtxF2L(portalTransform, matrix);
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
if (portal->flags & PortalFlagsOddParity) {
gSPDisplayList(renderState->dl++, portal_portal_blue_filled_model_gfx);
} else {
gSPDisplayList(renderState->dl++, portal_portal_orange_filled_model_gfx);
}
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
}
void portalRender(struct Portal* portal, struct Portal* otherPortal, struct RenderProps* props, SceneRenderCallback sceneRenderer, void* data, struct RenderState* renderState) {
struct Vector3 forward = gForward;
if (!(portal->flags & PortalFlagsOddParity)) {
@ -370,16 +388,7 @@ void portalRender(struct Portal* portal, struct Portal* otherPortal, struct Rend
transformToMatrix(&finalTransform, portalTransform, SCENE_SCALE);
if (props->currentDepth == 0 || !otherPortal) {
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
guMtxF2L(portalTransform, matrix);
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
if (portal->flags & PortalFlagsOddParity) {
gSPDisplayList(renderState->dl++, portal_portal_blue_filled_model_gfx);
} else {
gSPDisplayList(renderState->dl++, portal_portal_orange_filled_model_gfx);
}
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
portalRenderCover(portal, portalTransform, renderState);
return;
}
@ -408,7 +417,11 @@ void portalRender(struct Portal* portal, struct Portal* otherPortal, struct Rend
}
if (nextProps.minX < nextProps.maxX && nextProps.minY < nextProps.maxY) {
renderPropsNext(props, &nextProps, &portal->transform, &otherPortal->transform, renderState);
if (!renderPropsNext(props, &nextProps, &portal->transform, &otherPortal->transform, renderState)) {
portalRenderCover(portal, portalTransform, renderState);
return;
}
sceneRenderer(data, &nextProps, renderState);
// revert to previous state

View file

@ -56,7 +56,7 @@ struct RenderProps {
};
void renderPropsInit(struct RenderProps* props, struct Camera* camera, float aspectRatio, struct RenderState* renderState, u16 roomIndex);
void renderPropsNext(struct RenderProps* current, struct RenderProps* next, struct Transform* fromPortal, struct Transform* toPortal, struct RenderState* renderState);
int renderPropsNext(struct RenderProps* current, struct RenderProps* next, struct Transform* fromPortal, struct Transform* toPortal, struct RenderState* renderState);
void portalInit(struct Portal* portal, enum PortalFlags flags);
void portalUpdate(struct Portal* portal, int isOpen);

View file

@ -95,6 +95,12 @@ void sceneInit(struct Scene* scene) {
for (int i = 0; i < scene->elevatorCount; ++i) {
elevatorInit(&scene->elevators[i], &gCurrentLevel->elevators[i]);
}
scene->pedestalCount = gCurrentLevel->pedestalCount;
scene->pedestals = malloc(sizeof(struct Pedestal) * scene->pedestalCount);
for (int i = 0; i < scene->pedestalCount; ++i) {
pedestalInit(&scene->pedestals[i], &gCurrentLevel->pedestals[i]);
}
}
void sceneRenderWithProperties(void* data, struct RenderProps* properties, struct RenderState* renderState) {
@ -103,7 +109,7 @@ void sceneRenderWithProperties(void* data, struct RenderProps* properties, struc
u64 visibleRooms = 0;
staticRenderDetermineVisibleRooms(&properties->cullingInfo, properties->fromRoom, &visibleRooms);
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].transform.position) < vector3DistSqrd(&properties->camera.transform.position, &scene->portals[1].transform.position) ? 0 : 1;
int otherPortal = 1 - closerPortal;
for (int i = 0; i < 2; ++i) {

View file

@ -13,6 +13,7 @@
#include "./door.h"
#include "./fizzler.h"
#include "elevator.h"
#include "pedestal.h"
struct Scene {
struct Camera camera;
@ -23,6 +24,7 @@ struct Scene {
struct Door* doors;
struct Fizzler* fizzlers;
struct Elevator* elevators;
struct Pedestal* pedestals;
OSTime cpuTime;
OSTime lastFrameStart;
OSTime lastFrameTime;
@ -31,6 +33,7 @@ struct Scene {
u8 doorCount;
u8 fizzlerCount;
u8 elevatorCount;
u8 pedestalCount;
};
extern struct Scene gScene;

View file

@ -7,9 +7,16 @@
void skArmatureInit(struct SKArmature* object, Gfx* displayList, u32 numberOfBones, struct Transform* initialPose, unsigned short* boneParentIndex) {
object->displayList = displayList;
object->numberOfBones = numberOfBones;
object->boneTransforms = malloc(sizeof(Mtx) * numberOfBones);
unsigned transformSize = sizeof(Mtx) * numberOfBones;
object->boneTransforms = malloc(transformSize);
if (initialPose) {
romCopy((void*)initialPose, (void*)object->boneTransforms, sizeof(Mtx) * numberOfBones);
if (IS_KSEG0(initialPose)) {
memCopy(object->boneTransforms, initialPose, transformSize);
} else {
romCopy((void*)initialPose, (void*)object->boneTransforms, transformSize);
}
}
object->boneParentIndex = boneParentIndex;
}

View file

@ -0,0 +1,24 @@
const fs = require('fs');
const path = require('path');
function generateLD(objectLocation) {
return `
${objectLocation}(.data);
${objectLocation}(.bss);
`;
}
function generateData(objectLocations) {
return `
BEGIN_SEG(animation_segment, 0x0D000000)
{
${objectLocations.map(objectLocation => generateLD(objectLocation)).join('\n')}
}
END_SEG(animation_segment)
`;
}
const output = process.argv[2];
fs.writeFileSync(output, generateData(process.argv.slice(3)));