mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-19 22:27:36 -04:00
Add freecam
This commit is contained in:
parent
964a8f3fd1
commit
f767fdf8ab
4
Makefile
4
Makefile
|
@ -17,7 +17,7 @@ $(SKELATOOL64):
|
|||
skelatool64/setup_dependencies.sh
|
||||
make -C skelatool64
|
||||
|
||||
OPTIMIZER := -O0
|
||||
OPTIMIZER := -O2
|
||||
LCDEFS := -DDEBUG -g -Isrc/ -I/usr/include/n64/nustd -Werror -Wall
|
||||
N64LIB := -lultra_rom -lnustd
|
||||
|
||||
|
@ -218,7 +218,7 @@ TEST_CHAMBER_OBJECTS = $(TEST_CHAMBERS:%.blend=build/%_geo.o)
|
|||
|
||||
build/%.fbx: %.blend
|
||||
@mkdir -p $(@D)
|
||||
$(BLENDER_2_9) $< --background --python tools/export_fbx.py -- $@
|
||||
$(BLENDER_3_0) $< --background --python tools/export_fbx.py -- $@
|
||||
|
||||
build/assets/test_chambers/%.h build/assets/test_chambers/%_geo.c: build/assets/test_chambers/%.fbx build/assets/materials/static.h $(SKELATOOL64) $(TEXTURE_IMAGES)
|
||||
$(SKELATOOL64) --level --fixed-point-scale 256 --model-scale 0.01 --name $(<:build/assets/test_chambers/%.fbx=%) -m assets/materials/static.skm.yaml -o $(<:%.fbx=%.h) $<
|
||||
|
|
|
@ -6,7 +6,7 @@ A demake of portal for the Nintendo 64
|
|||
|
||||
First, you will need to setup [modern sdk](https://crashoveride95.github.io/n64hbrew/modernsdk/startoff.html)
|
||||
|
||||
Next, you will need to download blender 2.9 or higher. Then set the environment variable `BLENDER_2_9` to be the absolute path where the blender executable is located on your system.
|
||||
Next, you will need to download blender 3.0 or higher. Then set the environment variable `BLENDER_3_0` to be the absolute path where the blender executable is located on your system.
|
||||
|
||||
<br />
|
||||
|
||||
|
@ -63,12 +63,12 @@ docker build . -t portal64
|
|||
Then build
|
||||
```sh
|
||||
# Set the environment variable
|
||||
BLENDER_2_9=/blender/blender
|
||||
BLENDER_3_0=/blender/blender
|
||||
|
||||
# Build using docker
|
||||
docker run \
|
||||
-v /home/james/Blender/blender-2.93.1-linux-x64:/blender \
|
||||
-e BLENDER_2_9 -v /home/james/portal/portal64/vpk:/usr/src/app/vpk \
|
||||
-e BLENDER_3_0 -v /home/james/portal/portal64/vpk:/usr/src/app/vpk \
|
||||
-t -v /home/james/portal/portal64/docker-output:/usr/src/app/build portal64
|
||||
```
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -10,6 +10,7 @@
|
|||
#define KEYFRAME_REMOVE_TOLERNACE 8
|
||||
|
||||
struct SKBoneKeyframeChain {
|
||||
SKBoneKeyframeChain();
|
||||
SKBoneKeyframe keyframe;
|
||||
unsigned short tick;
|
||||
bool isNeeded;
|
||||
|
@ -18,6 +19,15 @@ struct SKBoneKeyframeChain {
|
|||
struct SKBoneKeyframeChain* prev;
|
||||
};
|
||||
|
||||
SKBoneKeyframeChain::SKBoneKeyframeChain():
|
||||
tick(0),
|
||||
isNeeded(false),
|
||||
removalScore(0),
|
||||
next(nullptr),
|
||||
prev(nullptr) {
|
||||
|
||||
}
|
||||
|
||||
bool chainIsLess(SKBoneKeyframeChain* a, SKBoneKeyframeChain* b) {
|
||||
return a->removalScore > b->removalScore;
|
||||
}
|
||||
|
@ -136,7 +146,7 @@ bool keyframeSortFn(const SKBoneKeyframeChain& a, const SKBoneKeyframeChain& b)
|
|||
return (a.keyframe.usedAttributes & 0x7) < (b.keyframe.usedAttributes & 0x7);
|
||||
}
|
||||
|
||||
void populateKeyframes(const aiAnimation& input, BoneHierarchy& bones, float fixedPointScale, float modelScale, const aiQuaternion& rotation, float timeScalar, std::vector<SKBoneKeyframeChain>& output) {
|
||||
void populateKeyframes(const aiAnimation& input, BoneHierarchy& bones, float fixedPointScale, float modelScale, const aiQuaternion& rotation, std::vector<SKBoneKeyframeChain>& output) {
|
||||
for (unsigned i = 0; i < input.mNumChannels; ++i) {
|
||||
aiNodeAnim* node = input.mChannels[i];
|
||||
|
||||
|
@ -150,7 +160,7 @@ void populateKeyframes(const aiAnimation& input, BoneHierarchy& bones, float fix
|
|||
aiVectorKey* vectorKey = &node->mPositionKeys[keyIndex];
|
||||
|
||||
SKBoneKeyframeChain keyframe;
|
||||
keyframe.tick = (unsigned short)(vectorKey->mTime * timeScalar + 0.5f);
|
||||
keyframe.tick = (unsigned short)(vectorKey->mTime);
|
||||
keyframe.next = nullptr;
|
||||
keyframe.prev = nullptr;
|
||||
keyframe.keyframe.usedAttributes = SKBoneAttrMaskPosition;
|
||||
|
@ -173,7 +183,7 @@ void populateKeyframes(const aiAnimation& input, BoneHierarchy& bones, float fix
|
|||
aiQuatKey* quatKey = &node->mRotationKeys[keyIndex];
|
||||
|
||||
SKBoneKeyframeChain keyframe;
|
||||
keyframe.tick = (unsigned short)(quatKey->mTime * timeScalar + 0.5f);
|
||||
keyframe.tick = (unsigned short)(quatKey->mTime);
|
||||
keyframe.next = nullptr;
|
||||
keyframe.prev = nullptr;
|
||||
keyframe.keyframe.usedAttributes = SKBoneAttrMaskRotation;
|
||||
|
@ -190,7 +200,7 @@ void populateKeyframes(const aiAnimation& input, BoneHierarchy& bones, float fix
|
|||
aiVectorKey* vectorKey = &node->mScalingKeys[keyIndex];
|
||||
|
||||
SKBoneKeyframeChain keyframe;
|
||||
keyframe.tick = (unsigned short)(vectorKey->mTime * timeScalar + 0.5f);
|
||||
keyframe.tick = (unsigned short)(vectorKey->mTime);
|
||||
keyframe.next = nullptr;
|
||||
keyframe.prev = nullptr;
|
||||
keyframe.keyframe.usedAttributes = SKBoneAttrMaskScale;
|
||||
|
@ -375,10 +385,8 @@ void buildInitialState(std::map<unsigned short, SKBoneKeyframeChain*>& firstKeyF
|
|||
}
|
||||
|
||||
bool translateAnimationToSK(const aiAnimation& input, struct SKAnimation& output, BoneHierarchy& bones, float fixedPointScale, float modelScale, const aiQuaternion& rotation, unsigned short targetTicksPerSecond) {
|
||||
float timeScalar = (float)targetTicksPerSecond / (float)1000.0f;
|
||||
|
||||
std::vector<SKBoneKeyframeChain> keyframes;
|
||||
populateKeyframes(input, bones, fixedPointScale, modelScale, rotation, timeScalar, keyframes);
|
||||
populateKeyframes(input, bones, fixedPointScale, modelScale, rotation, keyframes);
|
||||
|
||||
if (keyframes.size() == 0) {
|
||||
return false;
|
||||
|
@ -397,8 +405,8 @@ bool translateAnimationToSK(const aiAnimation& input, struct SKAnimation& output
|
|||
|
||||
buildInitialState(firstKeyFrame, currentChunk);
|
||||
|
||||
output.ticksPerSecond = targetTicksPerSecond;
|
||||
output.maxTicks = (unsigned short)(input.mDuration * timeScalar);
|
||||
output.ticksPerSecond = (unsigned short)input.mTicksPerSecond;
|
||||
output.maxTicks = (unsigned short)(input.mDuration);
|
||||
|
||||
while (currentIndex < keyframes.size()) {
|
||||
unsigned short tick = keyframes[currentIndex].tick;
|
||||
|
|
|
@ -154,7 +154,7 @@ static void gameProc(void* arg) {
|
|||
dynamicSceneInit();
|
||||
contactSolverInit(&gContactSolver);
|
||||
portalSurfaceCleanupQueueInit();
|
||||
levelLoad(2);
|
||||
levelLoad(0);
|
||||
cutsceneRunnerReset();
|
||||
controllersInit();
|
||||
initAudio();
|
||||
|
|
|
@ -221,30 +221,30 @@ float playerCleanupStickInput(s8 input) {
|
|||
return ((float)input + (input > 0 ? -DEADZONE_SIZE : DEADZONE_SIZE)) * (1.0f / (MAX_JOYSTICK_RANGE - DEADZONE_SIZE));
|
||||
}
|
||||
|
||||
void playerGetMoveBasis(struct Transform* transform, struct Vector3* forward, struct Vector3* right) {
|
||||
quatMultVector(&transform->rotation, &gForward, forward);
|
||||
quatMultVector(&transform->rotation, &gRight, right);
|
||||
|
||||
if (forward->y > 0.7f) {
|
||||
quatMultVector(&transform->rotation, &gUp, forward);
|
||||
vector3Negate(forward, forward);
|
||||
} else if (forward->y < -0.7f) {
|
||||
quatMultVector(&transform->rotation, &gUp, forward);
|
||||
}
|
||||
|
||||
forward->y = 0.0f;
|
||||
right->y = 0.0f;
|
||||
|
||||
vector3Normalize(forward, forward);
|
||||
vector3Normalize(right, right);
|
||||
}
|
||||
|
||||
void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
||||
struct Vector3 forward;
|
||||
struct Vector3 right;
|
||||
|
||||
int doorwayMask = worldCheckDoorwaySides(&gCurrentLevel->world, &player->lookTransform.position, player->body.currentRoom);
|
||||
|
||||
struct Transform* transform = &player->lookTransform;
|
||||
|
||||
quatMultVector(&transform->rotation, &gForward, &forward);
|
||||
quatMultVector(&transform->rotation, &gRight, &right);
|
||||
|
||||
if (forward.y > 0.7f) {
|
||||
quatMultVector(&transform->rotation, &gUp, &forward);
|
||||
vector3Negate(&forward, &forward);
|
||||
} else if (forward.y < -0.7f) {
|
||||
quatMultVector(&transform->rotation, &gUp, &forward);
|
||||
}
|
||||
|
||||
forward.y = 0.0f;
|
||||
right.y = 0.0f;
|
||||
|
||||
vector3Normalize(&gForward, &gForward);
|
||||
vector3Normalize(&gRight, &gRight);
|
||||
|
||||
playerGetMoveBasis(&player->lookTransform, &forward, &right);
|
||||
|
||||
if ((player->flags & PlayerFlagsGrounded) && controllerGetButtonDown(0, A_BUTTON)) {
|
||||
player->body.velocity.y = JUMP_IMPULSE;
|
||||
|
|
|
@ -31,4 +31,6 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform);
|
|||
|
||||
void playerRender(struct Player* player, struct RenderState* renderState);
|
||||
|
||||
void playerGetMoveBasis(struct Transform* transform, struct Vector3* forward, struct Vector3* right);
|
||||
|
||||
#endif
|
|
@ -115,6 +115,8 @@ void sceneInit(struct Scene* scene) {
|
|||
for (int i = 0; i < scene->boxDropperCount; ++i) {
|
||||
boxDropperInit(&scene->boxDroppers[i], &gCurrentLevel->boxDroppers[i]);
|
||||
}
|
||||
|
||||
scene->freeCameraOffset = gZeroVec;
|
||||
}
|
||||
|
||||
void sceneRenderWithProperties(void* data, struct RenderProps* properties, struct RenderState* renderState) {
|
||||
|
@ -277,6 +279,8 @@ struct Transform gRelativeElevatorTransform = {
|
|||
{1.0f, 1.0f, 1.0f},
|
||||
};
|
||||
|
||||
#define FREE_CAM_VELOCITY 2.0f
|
||||
|
||||
void sceneUpdate(struct Scene* scene) {
|
||||
OSTime frameStart = osGetTime();
|
||||
scene->lastFrameTime = frameStart - scene->lastFrameStart;
|
||||
|
@ -361,6 +365,49 @@ void sceneUpdate(struct Scene* scene) {
|
|||
|
||||
scene->cpuTime = osGetTime() - frameStart;
|
||||
scene->lastFrameStart = frameStart;
|
||||
|
||||
OSContPad* freecam = controllersGetControllerData(1);
|
||||
|
||||
|
||||
struct Vector3 lookDir;
|
||||
struct Vector3 rightDir;
|
||||
|
||||
playerGetMoveBasis(&scene->camera.transform, &lookDir, &rightDir);
|
||||
|
||||
if (freecam->stick_y) {
|
||||
if (controllerGetButton(1, Z_TRIG)) {
|
||||
vector3AddScaled(
|
||||
&scene->freeCameraOffset,
|
||||
&lookDir,
|
||||
-freecam->stick_y * (FREE_CAM_VELOCITY * FIXED_DELTA_TIME / 80.0f),
|
||||
&scene->freeCameraOffset
|
||||
);
|
||||
} else {
|
||||
scene->freeCameraOffset.y += freecam->stick_y * (FREE_CAM_VELOCITY * FIXED_DELTA_TIME / 80.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (freecam->stick_x) {
|
||||
vector3AddScaled(
|
||||
&scene->freeCameraOffset,
|
||||
&rightDir,
|
||||
freecam->stick_x * (FREE_CAM_VELOCITY * FIXED_DELTA_TIME / 80.0f),
|
||||
&scene->freeCameraOffset
|
||||
);
|
||||
}
|
||||
|
||||
if (controllerGetButtonDown(1, START_BUTTON)) {
|
||||
scene->freeCameraOffset = gZeroVec;
|
||||
}
|
||||
|
||||
vector3Add(&scene->camera.transform.position, &scene->freeCameraOffset, &scene->camera.transform.position);
|
||||
|
||||
if (controllerGetButtonDown(1, L_TRIG)) {
|
||||
struct Transform identityTransform;
|
||||
transformInitIdentity(&identityTransform);
|
||||
identityTransform.position.y = 1.0f;
|
||||
levelQueueLoad(NEXT_LEVEL, &identityTransform, &gZeroVec);
|
||||
}
|
||||
}
|
||||
|
||||
int sceneOpenPortal(struct Scene* scene, struct Transform* at, int portalIndex, int quadIndex, int roomIndex) {
|
||||
|
|
|
@ -29,6 +29,7 @@ struct Scene {
|
|||
struct Pedestal* pedestals;
|
||||
struct Signage* signage;
|
||||
struct BoxDropper* boxDroppers;
|
||||
struct Vector3 freeCameraOffset;
|
||||
OSTime cpuTime;
|
||||
OSTime lastFrameStart;
|
||||
OSTime lastFrameTime;
|
||||
|
|
Loading…
Reference in a new issue