Merge branch 'master' into wall-ground-portal-bug
This commit is contained in:
commit
199489f3f7
6
Makefile
6
Makefile
|
@ -167,6 +167,7 @@ MODEL_LIST = assets/models/cube/cube.blend \
|
||||||
assets/models/props/autoportal_frame/autoportal_frame.blend \
|
assets/models/props/autoportal_frame/autoportal_frame.blend \
|
||||||
assets/models/props/button.blend \
|
assets/models/props/button.blend \
|
||||||
assets/models/props/door_01.blend \
|
assets/models/props/door_01.blend \
|
||||||
|
assets/models/props/door_02.blend \
|
||||||
assets/models/props/combine_ball_catcher.blend \
|
assets/models/props/combine_ball_catcher.blend \
|
||||||
assets/models/props/combine_ball_launcher.blend \
|
assets/models/props/combine_ball_launcher.blend \
|
||||||
assets/models/props/cylinder_test.blend \
|
assets/models/props/cylinder_test.blend \
|
||||||
|
@ -193,6 +194,8 @@ ANIM_LIST = build/assets/models/pedestal_anim.o \
|
||||||
build/assets/models/props/box_dropper_anim.o \
|
build/assets/models/props/box_dropper_anim.o \
|
||||||
build/assets/models/props/combine_ball_catcher_anim.o \
|
build/assets/models/props/combine_ball_catcher_anim.o \
|
||||||
build/assets/models/props/combine_ball_launcher_anim.o \
|
build/assets/models/props/combine_ball_launcher_anim.o \
|
||||||
|
build/assets/models/props/door_01_anim.o \
|
||||||
|
build/assets/models/props/door_02_anim.o \
|
||||||
build/assets/models/player/chell_anim.o \
|
build/assets/models/player/chell_anim.o \
|
||||||
build/assets/models/props/switch001_anim.o
|
build/assets/models/props/switch001_anim.o
|
||||||
|
|
||||||
|
@ -228,12 +231,15 @@ build/src/scene/ball_launcher.o: build/assets/models/props/combine_ball_launcher
|
||||||
|
|
||||||
build/src/scene/ball_catcher.o: build/assets/models/props/combine_ball_catcher.h build/assets/materials/static.h
|
build/src/scene/ball_catcher.o: build/assets/models/props/combine_ball_catcher.h build/assets/materials/static.h
|
||||||
|
|
||||||
|
build/src/scene/door.o: build/assets/models/props/door_01.h build/assets/models/props/door_02.h
|
||||||
|
|
||||||
build/assets/models/player/chell.h: assets/materials/chell.skm.yaml
|
build/assets/models/player/chell.h: assets/materials/chell.skm.yaml
|
||||||
|
|
||||||
build/assets/models/props/combine_ball_catcher.h: assets/materials/ball_catcher.skm.yaml
|
build/assets/models/props/combine_ball_catcher.h: assets/materials/ball_catcher.skm.yaml
|
||||||
|
|
||||||
build/assets/models/props/combine_ball_launcher.h: assets/materials/ball_catcher.skm.yaml
|
build/assets/models/props/combine_ball_launcher.h: assets/materials/ball_catcher.skm.yaml
|
||||||
|
|
||||||
|
|
||||||
ANIM_TEST_CHAMBERS = build/assets/test_chambers/test_chamber_03/test_chamber_03_anim.o \
|
ANIM_TEST_CHAMBERS = build/assets/test_chambers/test_chamber_03/test_chamber_03_anim.o \
|
||||||
build/assets/test_chambers/test_chamber_04/test_chamber_04_anim.o \
|
build/assets/test_chambers/test_chamber_04/test_chamber_04_anim.o \
|
||||||
build/assets/test_chambers/test_chamber_06/test_chamber_06_anim.o
|
build/assets/test_chambers/test_chamber_06/test_chamber_06_anim.o
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# Portal64
|
# Portal64
|
||||||
|
![](./assets/images/portal64_readme_logo.gif)
|
||||||
|
|
||||||
A demake of Portal for the Nintendo 64.
|
A demake of Portal for the Nintendo 64.
|
||||||
|
|
||||||
|
@ -106,13 +107,13 @@ Where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where Blender
|
||||||
- [ ] Portal not rendering recursively sometimes
|
- [ ] Portal not rendering recursively sometimes
|
||||||
- [ ] Correct elevator timing
|
- [ ] Correct elevator timing
|
||||||
- [ ] Presort portal gun polygon order
|
- [ ] Presort portal gun polygon order
|
||||||
- [ ] Portal gun movement with player movement/shooting #19
|
|
||||||
- [ ] Camera shake
|
- [ ] Camera shake
|
||||||
- [ ] Adding a menu to game #47
|
- [ ] Adding a menu to game #47
|
||||||
- [ ] Adding y-axis/x-axis inverting options #55
|
- [ ] Adding y-axis/x-axis inverting options #55
|
||||||
- [ ] Adding loading notice between levels #45
|
- [ ] Adding loading notice between levels #45
|
||||||
- [ ] Vertex lighting #39
|
- [ ] Vertex lighting #39
|
||||||
- [ ] Multi controller support #23
|
- [ ] Multi controller support #23
|
||||||
|
- [x] Portal gun movement with player movement/shooting #19
|
||||||
|
|
||||||
## Current New Sounds TODO List
|
## Current New Sounds TODO List
|
||||||
- [ ] Fast flying air whoosh sound
|
- [ ] Fast flying air whoosh sound
|
||||||
|
@ -130,8 +131,6 @@ Where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where Blender
|
||||||
- [ ] Two wall portals next to eachother can be used to clip any object out of any level by pushing it into corner, then dropping.
|
- [ ] Two wall portals next to eachother can be used to clip any object out of any level by pushing it into corner, then dropping.
|
||||||
- [ ] Glass can be walked through from one side on multiple levels (0,1,4,...)
|
- [ ] Glass can be walked through from one side on multiple levels (0,1,4,...)
|
||||||
- [ ] Passing into a ceiling portal can sometimes mess with the player rotation
|
- [ ] Passing into a ceiling portal can sometimes mess with the player rotation
|
||||||
- [ ] Can shoot portals through decor objects
|
|
||||||
- [ ] Can shoot portals while holding an object
|
|
||||||
- [ ] Can shoot portals, and walk through signage
|
- [ ] Can shoot portals, and walk through signage
|
||||||
- [ ] Chell animation problem (fixed itself, investigate)
|
- [ ] Chell animation problem (fixed itself, investigate)
|
||||||
- [ ] Can place portals on ground after final fizzler on all levels
|
- [ ] Can place portals on ground after final fizzler on all levels
|
||||||
|
@ -140,3 +139,4 @@ Where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where Blender
|
||||||
- [ ] various visual glitches when running PAL on NTSC console #65
|
- [ ] various visual glitches when running PAL on NTSC console #65
|
||||||
- [x] Any grabbable object can be clipped through level by wall/floor portals method.
|
- [x] Any grabbable object can be clipped through level by wall/floor portals method.
|
||||||
- [x] Player can clip through any level by placing one portal on wall and another portal right next to it on ground. #13
|
- [x] Player can clip through any level by placing one portal on wall and another portal right next to it on ground. #13
|
||||||
|
- [x] Can shoot portals while holding an object
|
BIN
assets/images/portal64_readme_logo.gif
Normal file
BIN
assets/images/portal64_readme_logo.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 136 KiB |
1
assets/materials/models/props/door_02.ims
Normal file
1
assets/materials/models/props/door_02.ims
Normal file
|
@ -0,0 +1 @@
|
||||||
|
-alpha off -crop 128x256+251+0 -resize 32x64
|
|
@ -342,6 +342,20 @@ materials:
|
||||||
color: ["SHADE", "0", "TEXEL0", "0"]
|
color: ["SHADE", "0", "TEXEL0", "0"]
|
||||||
gDPSetTextureFilter: G_TF_BILERP
|
gDPSetTextureFilter: G_TF_BILERP
|
||||||
|
|
||||||
|
door_02:
|
||||||
|
gDPSetTile:
|
||||||
|
filename:
|
||||||
|
../../portal_pak_modified/materials/models/props/door_02.png
|
||||||
|
siz: G_IM_SIZ_16b
|
||||||
|
fmt: G_IM_FMT_RGBA
|
||||||
|
t:
|
||||||
|
mirror: true
|
||||||
|
gSPGeometryMode:
|
||||||
|
set: [G_LIGHTING, G_SHADE]
|
||||||
|
gDPSetCombineMode:
|
||||||
|
color: ["SHADE", "0", "TEXEL0", "0"]
|
||||||
|
gDPSetTextureFilter: G_TF_BILERP
|
||||||
|
|
||||||
plastic/plasticwall001a:
|
plastic/plasticwall001a:
|
||||||
gDPSetPrimColor:
|
gDPSetPrimColor:
|
||||||
r: 230
|
r: 230
|
||||||
|
|
Binary file not shown.
|
@ -1 +1 @@
|
||||||
-m assets/materials/static.skm.yaml -m assets/materials/objects.skm.yaml --default-material door_01
|
-m assets/materials/static.skm.yaml -m assets/materials/objects.skm.yaml --default-material door_01 --fps 24
|
BIN
assets/models/props/door_02.blend
Normal file
BIN
assets/models/props/door_02.blend
Normal file
Binary file not shown.
1
assets/models/props/door_02.flags
Normal file
1
assets/models/props/door_02.flags
Normal file
|
@ -0,0 +1 @@
|
||||||
|
-m assets/materials/static.skm.yaml -m assets/materials/objects.skm.yaml --default-material door_02
|
Binary file not shown.
|
@ -79,15 +79,20 @@ struct FrameData {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void findStartValue(const T* keys, unsigned keyCount, double at, unsigned& startValue, double& lerp) {
|
void findStartValue(const T* keys, unsigned keyCount, double at, unsigned& startValue, double& lerp) {
|
||||||
|
lerp = 0.0f;
|
||||||
|
|
||||||
for (startValue = 0; startValue < keyCount; ++startValue) {
|
for (startValue = 0; startValue < keyCount; ++startValue) {
|
||||||
if (keys[startValue].mTime >= at) {
|
if (keys[startValue].mTime == at) {
|
||||||
|
lerp = 0.0f;
|
||||||
|
break;
|
||||||
|
} else if (keys[startValue].mTime > at) {
|
||||||
if (startValue == 0) {
|
if (startValue == 0) {
|
||||||
lerp = 0.0f;
|
lerp = 0.0f;
|
||||||
} else {
|
} else {
|
||||||
--startValue;
|
--startValue;
|
||||||
double deltaTime = keys[startValue + 1].mTime - keys[startValue].mTime;
|
double deltaTime = keys[startValue + 1].mTime - keys[startValue].mTime;
|
||||||
|
|
||||||
if (deltaTime == 1.0) {
|
if (deltaTime == 0.0) {
|
||||||
lerp = 0.0f;
|
lerp = 0.0f;
|
||||||
} else {
|
} else {
|
||||||
lerp = (at - keys[startValue].mTime) / deltaTime;
|
lerp = (at - keys[startValue].mTime) / deltaTime;
|
||||||
|
@ -151,7 +156,7 @@ aiQuaternion evaluateQuaternionAt(const aiQuatKey* keys, unsigned keyCount, doub
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateanimationV2(const aiAnimation& animation, BoneHierarchy& bones, CFileDefinition& fileDef, const DisplayListSettings& settings) {
|
void generateanimationV2(const aiAnimation& animation, BoneHierarchy& bones, CFileDefinition& fileDef, const DisplayListSettings& settings) {
|
||||||
int nFrames = ceil(animation.mDuration * settings.mTicksPerSecond / animation.mTicksPerSecond);
|
int nFrames = ceil(animation.mDuration * settings.mTicksPerSecond / animation.mTicksPerSecond) + 1;
|
||||||
|
|
||||||
std::vector<std::vector<FrameData>> allFrameData(nFrames);
|
std::vector<std::vector<FrameData>> allFrameData(nFrames);
|
||||||
|
|
||||||
|
|
|
@ -140,11 +140,17 @@ struct Location {
|
||||||
short roomIndex;
|
short roomIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DoorType {
|
||||||
|
DoorType01,
|
||||||
|
DoorType02,
|
||||||
|
};
|
||||||
|
|
||||||
struct DoorDefinition {
|
struct DoorDefinition {
|
||||||
struct Vector3 location;
|
struct Vector3 location;
|
||||||
struct Quaternion rotation;
|
struct Quaternion rotation;
|
||||||
short doorwayIndex;
|
short doorwayIndex;
|
||||||
short signalIndex;
|
short signalIndex;
|
||||||
|
short doorType;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ButtonDefinition {
|
struct ButtonDefinition {
|
||||||
|
|
|
@ -161,7 +161,7 @@ static void gameProc(void* arg) {
|
||||||
contactSolverInit(&gContactSolver);
|
contactSolverInit(&gContactSolver);
|
||||||
portalSurfaceCleanupQueueInit();
|
portalSurfaceCleanupQueueInit();
|
||||||
savefileNew();
|
savefileNew();
|
||||||
levelLoad(6);
|
levelLoad(2);
|
||||||
cutsceneRunnerReset();
|
cutsceneRunnerReset();
|
||||||
controllersInit();
|
controllersInit();
|
||||||
initAudio(fps);
|
initAudio(fps);
|
||||||
|
|
|
@ -322,7 +322,7 @@ void contactSolverIterateConstraints(struct ContactSolver* contactSolver) {
|
||||||
struct PointConstraint* prev = NULL;
|
struct PointConstraint* prev = NULL;
|
||||||
|
|
||||||
while (curr) {
|
while (curr) {
|
||||||
if (!pointConstraintMoveToPoint(curr->object, &curr->targetPos, curr->maxPosImpulse)) {
|
if (!pointConstraintMoveToPoint(curr->object, &curr->targetPos, curr->maxPosImpulse, curr->teleportOnBreak, curr->movementScaleFactor)) {
|
||||||
struct PointConstraint* next = curr->nextConstraint;
|
struct PointConstraint* next = curr->nextConstraint;
|
||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
|
|
|
@ -4,13 +4,18 @@
|
||||||
|
|
||||||
#define BREAK_CONSTRAINT_DISTANCE 2.0f
|
#define BREAK_CONSTRAINT_DISTANCE 2.0f
|
||||||
|
|
||||||
int pointConstraintMoveToPoint(struct CollisionObject* object, struct Vector3* worldPoint, float maxImpulse) {
|
int pointConstraintMoveToPoint(struct CollisionObject* object, struct Vector3* worldPoint, float maxImpulse, int teleportOnBreak, float movementScaleFactor) {
|
||||||
struct RigidBody* rigidBody = object->body;
|
struct RigidBody* rigidBody = object->body;
|
||||||
|
|
||||||
|
|
||||||
struct Vector3 targetVelocity;
|
struct Vector3 targetVelocity;
|
||||||
vector3Sub(worldPoint, &rigidBody->transform.position, &targetVelocity);
|
vector3Sub(worldPoint, &rigidBody->transform.position, &targetVelocity);
|
||||||
|
|
||||||
if (vector3MagSqrd(&targetVelocity) > BREAK_CONSTRAINT_DISTANCE * BREAK_CONSTRAINT_DISTANCE) {
|
if (vector3MagSqrd(&targetVelocity) > BREAK_CONSTRAINT_DISTANCE * BREAK_CONSTRAINT_DISTANCE) {
|
||||||
|
if (teleportOnBreak){
|
||||||
|
object->body->transform.position = *worldPoint;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,9 +43,11 @@ int pointConstraintMoveToPoint(struct CollisionObject* object, struct Vector3* w
|
||||||
|
|
||||||
struct Vector3 delta;
|
struct Vector3 delta;
|
||||||
vector3Sub(&targetVelocity, &rigidBody->velocity, &delta);
|
vector3Sub(&targetVelocity, &rigidBody->velocity, &delta);
|
||||||
|
|
||||||
|
|
||||||
float deltaSqrd = vector3MagSqrd(&delta);
|
float deltaSqrd = vector3MagSqrd(&delta);
|
||||||
if (deltaSqrd < maxImpulse * maxImpulse) {
|
if (deltaSqrd < maxImpulse * maxImpulse) {
|
||||||
|
vector3Scale(&targetVelocity, &targetVelocity, movementScaleFactor);
|
||||||
rigidBody->velocity = targetVelocity;
|
rigidBody->velocity = targetVelocity;
|
||||||
} else {
|
} else {
|
||||||
vector3AddScaled(&rigidBody->velocity, &delta, maxImpulse / sqrtf(deltaSqrd), &rigidBody->velocity);
|
vector3AddScaled(&rigidBody->velocity, &delta, maxImpulse / sqrtf(deltaSqrd), &rigidBody->velocity);
|
||||||
|
@ -74,13 +81,15 @@ void pointConstraintRotateTo(struct RigidBody* rigidBody, struct Quaternion* wor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pointConstraintInit(struct PointConstraint* constraint, struct CollisionObject* object, float maxPosImpulse, float maxRotImpulse) {
|
void pointConstraintInit(struct PointConstraint* constraint, struct CollisionObject* object, float maxPosImpulse, float maxRotImpulse, int teleportOnBreak, float movementScaleFactor) {
|
||||||
constraint->nextConstraint = NULL;
|
constraint->nextConstraint = NULL;
|
||||||
constraint->object = object;
|
constraint->object = object;
|
||||||
constraint->targetPos = object->body->transform.position;
|
constraint->targetPos = object->body->transform.position;
|
||||||
constraint->targetRot = object->body->transform.rotation;
|
constraint->targetRot = object->body->transform.rotation;
|
||||||
constraint->maxPosImpulse = maxPosImpulse;
|
constraint->maxPosImpulse = maxPosImpulse;
|
||||||
constraint->maxRotImpulse = maxRotImpulse;
|
constraint->maxRotImpulse = maxRotImpulse;
|
||||||
|
constraint->teleportOnBreak = teleportOnBreak;
|
||||||
|
constraint->movementScaleFactor = movementScaleFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pointConstraintUpdateTarget(struct PointConstraint* constraint, struct Vector3* worldPoint, struct Quaternion* worldRotation) {
|
void pointConstraintUpdateTarget(struct PointConstraint* constraint, struct Vector3* worldPoint, struct Quaternion* worldRotation) {
|
||||||
|
|
|
@ -11,12 +11,14 @@ struct PointConstraint {
|
||||||
struct Quaternion targetRot;
|
struct Quaternion targetRot;
|
||||||
float maxPosImpulse;
|
float maxPosImpulse;
|
||||||
float maxRotImpulse;
|
float maxRotImpulse;
|
||||||
|
int teleportOnBreak;
|
||||||
|
float movementScaleFactor;
|
||||||
};
|
};
|
||||||
|
|
||||||
void pointConstraintInit(struct PointConstraint* constraint, struct CollisionObject* object, float maxPosImpulse, float maxRotImpulse);
|
void pointConstraintInit(struct PointConstraint* constraint, struct CollisionObject* object, float maxPosImpulse, float maxRotImpulse, int teleportOnBreak, float movementScaleFactor);
|
||||||
void pointConstraintUpdateTarget(struct PointConstraint* constraint, struct Vector3* worldPoint, struct Quaternion* worldRotation);
|
void pointConstraintUpdateTarget(struct PointConstraint* constraint, struct Vector3* worldPoint, struct Quaternion* worldRotation);
|
||||||
|
|
||||||
int pointConstraintMoveToPoint(struct CollisionObject* object, struct Vector3* worldPoint, float maxImpulse);
|
int pointConstraintMoveToPoint(struct CollisionObject* object, struct Vector3* worldPoint, float maxImpulse, int teleportOnBreak, float movementScaleFactor);
|
||||||
void pointConstraintRotateTo(struct RigidBody* rigidBody, struct Quaternion* worldRotation, float maxImpulse);
|
void pointConstraintRotateTo(struct RigidBody* rigidBody, struct Quaternion* worldRotation, float maxImpulse);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -32,6 +32,12 @@
|
||||||
struct Vector3 gGrabDistance = {0.0f, 0.0f, -1.5f};
|
struct Vector3 gGrabDistance = {0.0f, 0.0f, -1.5f};
|
||||||
struct Vector3 gCameraOffset = {0.0f, 0.0f, 0.0f};
|
struct Vector3 gCameraOffset = {0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
struct Vector3 gPortalGunOffset = {0.150957, -0.153587, -0.355};
|
||||||
|
struct Vector3 gPortalGunShootOffset = {0.150957, -0.153587, 0.1};
|
||||||
|
struct Vector3 gPortalGunForward = {0.1f, -0.1f, 1.0f};
|
||||||
|
struct Vector3 gPortalGunShootForward = {0.1f, -0.25f, 1.0f};
|
||||||
|
struct Vector3 gPortalGunUp = {0.0f, 1.0f, 0.0f};
|
||||||
|
|
||||||
struct Vector2 gPlayerColliderEdgeVectors[] = {
|
struct Vector2 gPlayerColliderEdgeVectors[] = {
|
||||||
{0.0f, 1.0f},
|
{0.0f, 1.0f},
|
||||||
{0.707f, 0.707f},
|
{0.707f, 0.707f},
|
||||||
|
@ -115,8 +121,11 @@ void playerRender(void* data, struct DynamicRenderDataList* renderList, struct R
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerInit(struct Player* player, struct Location* startLocation, struct Vector3* velocity) {
|
void playerInit(struct Player* player, struct Location* startLocation, struct Vector3* velocity, struct CollisionObject* portalGunObject) {
|
||||||
collisionObjectInit(&player->collisionObject, &gPlayerColliderData, &player->body, 1.0f, PLAYER_COLLISION_LAYERS);
|
collisionObjectInit(&player->collisionObject, &gPlayerColliderData, &player->body, 1.0f, PLAYER_COLLISION_LAYERS);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// rigidBodyMarkKinematic(&player->body);
|
// rigidBodyMarkKinematic(&player->body);
|
||||||
player->body.flags |= RigidBodyIsKinematic | RigidBodyIsPlayer;
|
player->body.flags |= RigidBodyIsKinematic | RigidBodyIsPlayer;
|
||||||
collisionSceneAddDynamicObject(&player->collisionObject);
|
collisionSceneAddDynamicObject(&player->collisionObject);
|
||||||
|
@ -130,6 +139,7 @@ void playerInit(struct Player* player, struct Location* startLocation, struct Ve
|
||||||
player->body.velocity = *velocity;
|
player->body.velocity = *velocity;
|
||||||
player->grabbingThroughPortal = PLAYER_GRABBING_THROUGH_NOTHING;
|
player->grabbingThroughPortal = PLAYER_GRABBING_THROUGH_NOTHING;
|
||||||
player->grabConstraint.object = NULL;
|
player->grabConstraint.object = NULL;
|
||||||
|
player->gunConstraint.object = NULL;
|
||||||
player->pitchVelocity = 0.0f;
|
player->pitchVelocity = 0.0f;
|
||||||
player->yawVelocity = 0.0f;
|
player->yawVelocity = 0.0f;
|
||||||
player->flags = 0;
|
player->flags = 0;
|
||||||
|
@ -162,6 +172,9 @@ void playerInit(struct Player* player, struct Location* startLocation, struct Ve
|
||||||
collisionObjectUpdateBB(&player->collisionObject);
|
collisionObjectUpdateBB(&player->collisionObject);
|
||||||
|
|
||||||
dynamicSceneSetRoomFlags(player->dynamicId, ROOM_FLAG_FROM_INDEX(player->body.currentRoom));
|
dynamicSceneSetRoomFlags(player->dynamicId, ROOM_FLAG_FROM_INDEX(player->body.currentRoom));
|
||||||
|
|
||||||
|
pointConstraintInit(&player->gunConstraint, portalGunObject, 20.0f, 2.5f, 1, 0.9f);
|
||||||
|
contactSolverAddPointConstraint(&gContactSolver, &player->gunConstraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PLAYER_SPEED (150.0f / 64.0f)
|
#define PLAYER_SPEED (150.0f / 64.0f)
|
||||||
|
@ -226,13 +239,13 @@ void playerApplyPortalGrab(struct Player* player, int portalIndex) {
|
||||||
|
|
||||||
void playerSetGrabbing(struct Player* player, struct CollisionObject* grabbing) {
|
void playerSetGrabbing(struct Player* player, struct CollisionObject* grabbing) {
|
||||||
if (grabbing && !player->grabConstraint.object) {
|
if (grabbing && !player->grabConstraint.object) {
|
||||||
pointConstraintInit(&player->grabConstraint, grabbing, 8.0f, 5.0f);
|
pointConstraintInit(&player->grabConstraint, grabbing, 8.0f, 5.0f, 0, 1.0f);
|
||||||
contactSolverAddPointConstraint(&gContactSolver, &player->grabConstraint);
|
contactSolverAddPointConstraint(&gContactSolver, &player->grabConstraint);
|
||||||
} else if (!grabbing && player->grabConstraint.object) {
|
} else if (!grabbing && player->grabConstraint.object) {
|
||||||
player->grabConstraint.object = NULL;
|
player->grabConstraint.object = NULL;
|
||||||
contactSolverRemovePointConstraint(&gContactSolver, &player->grabConstraint);
|
contactSolverRemovePointConstraint(&gContactSolver, &player->grabConstraint);
|
||||||
} else if (grabbing != player->grabConstraint.object) {
|
} else if (grabbing != player->grabConstraint.object) {
|
||||||
pointConstraintInit(&player->grabConstraint, grabbing, 8.0f, 5.0f);
|
pointConstraintInit(&player->grabConstraint, grabbing, 8.0f, 5.0f, 0, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,6 +384,33 @@ void playerUpdateGrabbedObject(struct Player* player) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void playerUpdateGunObject(struct Player* player) {
|
||||||
|
struct Vector3 forward;
|
||||||
|
struct Vector3 offset;
|
||||||
|
|
||||||
|
if (player->flags & PlayerJustShotPortalGun){
|
||||||
|
player->flags &= ~PlayerJustShotPortalGun;
|
||||||
|
forward = gPortalGunShootForward;
|
||||||
|
offset = gPortalGunShootOffset;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
forward = gPortalGunForward;
|
||||||
|
offset = gPortalGunOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Quaternion relativeRotation;
|
||||||
|
quatLook(&forward, &gPortalGunUp, &relativeRotation);
|
||||||
|
quatMultiply(&player->lookTransform.rotation, &relativeRotation, &player->gunConstraint.object->body->transform.rotation);
|
||||||
|
|
||||||
|
|
||||||
|
struct Vector3 gunPoint;
|
||||||
|
struct Vector3 temp_gun_dist = offset;
|
||||||
|
transformPoint(&player->lookTransform, &temp_gun_dist, &gunPoint);
|
||||||
|
|
||||||
|
pointConstraintUpdateTarget(&player->gunConstraint, &gunPoint, &player->gunConstraint.object->body->transform.rotation);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#define DEADZONE_SIZE 5
|
#define DEADZONE_SIZE 5
|
||||||
#define MAX_JOYSTICK_RANGE 80
|
#define MAX_JOYSTICK_RANGE 80
|
||||||
|
|
||||||
|
@ -725,6 +765,7 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
||||||
cameraTransform->rotation = player->lookTransform.rotation;
|
cameraTransform->rotation = player->lookTransform.rotation;
|
||||||
cameraTransform->position = player->lookTransform.position;
|
cameraTransform->position = player->lookTransform.position;
|
||||||
playerUpdateGrabbedObject(player);
|
playerUpdateGrabbedObject(player);
|
||||||
|
playerUpdateGunObject(player);
|
||||||
|
|
||||||
collisionObjectUpdateBB(&player->collisionObject);
|
collisionObjectUpdateBB(&player->collisionObject);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ enum PlayerFlags {
|
||||||
PlayerJustLanded = (1 << 8),
|
PlayerJustLanded = (1 << 8),
|
||||||
PlayerJustSelect = (1 << 9),
|
PlayerJustSelect = (1 << 9),
|
||||||
PlayerJustDeniedSelect = (1 << 10),
|
PlayerJustDeniedSelect = (1 << 10),
|
||||||
|
PlayerJustShotPortalGun = (1 << 11),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Player {
|
struct Player {
|
||||||
|
@ -38,6 +39,7 @@ struct Player {
|
||||||
short grabbingThroughPortal;
|
short grabbingThroughPortal;
|
||||||
short dynamicId;
|
short dynamicId;
|
||||||
struct PointConstraint grabConstraint;
|
struct PointConstraint grabConstraint;
|
||||||
|
struct PointConstraint gunConstraint;
|
||||||
float pitchVelocity;
|
float pitchVelocity;
|
||||||
float yawVelocity;
|
float yawVelocity;
|
||||||
enum PlayerFlags flags;
|
enum PlayerFlags flags;
|
||||||
|
@ -49,7 +51,7 @@ struct Player {
|
||||||
int currentFoot; //left=0, right=1
|
int currentFoot; //left=0, right=1
|
||||||
};
|
};
|
||||||
|
|
||||||
void playerInit(struct Player* player, struct Location* startLocation, struct Vector3* velocity);
|
void playerInit(struct Player* player, struct Location* startLocation, struct Vector3* velocity, struct CollisionObject* portalGunObject);
|
||||||
void playerUpdate(struct Player* player, struct Transform* cameraTransform);
|
void playerUpdate(struct Player* player, struct Transform* cameraTransform);
|
||||||
|
|
||||||
void playerGetMoveBasis(struct Transform* transform, struct Vector3* forward, struct Vector3* right);
|
void playerGetMoveBasis(struct Transform* transform, struct Vector3* forward, struct Vector3* right);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "../physics/collision_scene.h"
|
#include "../physics/collision_scene.h"
|
||||||
|
|
||||||
#include "../build/assets/models/props/door_01.h"
|
#include "../build/assets/models/props/door_01.h"
|
||||||
|
#include "../build/assets/models/props/door_02.h"
|
||||||
|
|
||||||
#define OPEN_VELOCITY 8.0f
|
#define OPEN_VELOCITY 8.0f
|
||||||
|
|
||||||
|
@ -28,6 +29,25 @@ struct ColliderTypeData gDoorCollider = {
|
||||||
&gCollisionBoxCallbacks,
|
&gCollisionBoxCallbacks,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DoorTypeDefinition gDoorTypeDefinitions[] = {
|
||||||
|
[DoorType01] = {
|
||||||
|
&props_door_01_armature,
|
||||||
|
&props_door_01_model_gfx[0],
|
||||||
|
&props_door_01_Armature_open_clip,
|
||||||
|
&props_door_01_Armature_close_clip,
|
||||||
|
-1,
|
||||||
|
1.0f,
|
||||||
|
},
|
||||||
|
[DoorType02] = {
|
||||||
|
&props_door_02_armature,
|
||||||
|
&props_door_02_model_gfx[0],
|
||||||
|
&props_door_02_Armature_open_clip,
|
||||||
|
&props_door_02_Armature_close_clip,
|
||||||
|
PROPS_DOOR_02_DOOR_BONE,
|
||||||
|
3.0f,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
void doorRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState) {
|
void doorRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState) {
|
||||||
struct Door* door = (struct Door*)data;
|
struct Door* door = (struct Door*)data;
|
||||||
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
|
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
|
||||||
|
@ -43,18 +63,13 @@ void doorRender(void* data, struct DynamicRenderDataList* renderList, struct Ren
|
||||||
|
|
||||||
transformToMatrixL(&originalTransform, matrix, SCENE_SCALE);
|
transformToMatrixL(&originalTransform, matrix, SCENE_SCALE);
|
||||||
|
|
||||||
props_door_01_default_bones[PROPS_DOOR_01_DOORL_BONE].position.x = door->openAmount * -0.625f * SCENE_SCALE;
|
Mtx* armature = renderStateRequestMatrices(renderState, door->armature.numberOfBones);
|
||||||
props_door_01_default_bones[PROPS_DOOR_01_DOORR_BONE].position.x = door->openAmount * 0.625f * SCENE_SCALE;
|
|
||||||
|
|
||||||
Mtx* armature = renderStateRequestMatrices(renderState, PROPS_DOOR_01_DEFAULT_BONES_COUNT);
|
|
||||||
|
|
||||||
if (!armature) {
|
if (!armature) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transformToMatrixL(&props_door_01_default_bones[PROPS_DOOR_01_FRAME_BONE], &armature[PROPS_DOOR_01_FRAME_BONE], 1.0f);
|
skCalculateTransforms(&door->armature, armature);
|
||||||
transformToMatrixL(&props_door_01_default_bones[PROPS_DOOR_01_DOORL_BONE], &armature[PROPS_DOOR_01_DOORL_BONE], 1.0f);
|
|
||||||
transformToMatrixL(&props_door_01_default_bones[PROPS_DOOR_01_DOORR_BONE], &armature[PROPS_DOOR_01_DOORR_BONE], 1.0f);
|
|
||||||
|
|
||||||
dynamicRenderListAddData(renderList, door_01_gfx, matrix, door_01_material_index, &door->rigidBody.transform.position, armature);
|
dynamicRenderListAddData(renderList, door_01_gfx, matrix, door_01_material_index, &door->rigidBody.transform.position, armature);
|
||||||
}
|
}
|
||||||
|
@ -64,6 +79,11 @@ void doorInit(struct Door* door, struct DoorDefinition* doorDefinition, struct W
|
||||||
rigidBodyMarkKinematic(&door->rigidBody);
|
rigidBodyMarkKinematic(&door->rigidBody);
|
||||||
collisionSceneAddDynamicObject(&door->collisionObject);
|
collisionSceneAddDynamicObject(&door->collisionObject);
|
||||||
|
|
||||||
|
struct DoorTypeDefinition* typeDefinition = &gDoorTypeDefinitions[doorDefinition->doorType];
|
||||||
|
|
||||||
|
skArmatureInit(&door->armature, typeDefinition->armature);
|
||||||
|
skAnimatorInit(&door->animator, typeDefinition->armature->numberOfBones);
|
||||||
|
|
||||||
door->rigidBody.transform.position = doorDefinition->location;
|
door->rigidBody.transform.position = doorDefinition->location;
|
||||||
door->rigidBody.transform.position.y += 1.0f;
|
door->rigidBody.transform.position.y += 1.0f;
|
||||||
door->rigidBody.transform.rotation = doorDefinition->rotation;
|
door->rigidBody.transform.rotation = doorDefinition->rotation;
|
||||||
|
@ -73,7 +93,6 @@ void doorInit(struct Door* door, struct DoorDefinition* doorDefinition, struct W
|
||||||
|
|
||||||
door->dynamicId = dynamicSceneAdd(door, doorRender, &door->rigidBody.transform.position, 1.7f);
|
door->dynamicId = dynamicSceneAdd(door, doorRender, &door->rigidBody.transform.position, 1.7f);
|
||||||
door->signalIndex = doorDefinition->signalIndex;
|
door->signalIndex = doorDefinition->signalIndex;
|
||||||
door->openAmount = 0.0f;
|
|
||||||
|
|
||||||
if (doorDefinition->doorwayIndex >= 0 && doorDefinition->doorwayIndex < world->doorwayCount) {
|
if (doorDefinition->doorwayIndex >= 0 && doorDefinition->doorwayIndex < world->doorwayCount) {
|
||||||
door->forDoorway = &world->doorways[doorDefinition->doorwayIndex];
|
door->forDoorway = &world->doorways[doorDefinition->doorwayIndex];
|
||||||
|
@ -89,31 +108,46 @@ void doorInit(struct Door* door, struct DoorDefinition* doorDefinition, struct W
|
||||||
}
|
}
|
||||||
|
|
||||||
void doorUpdate(struct Door* door) {
|
void doorUpdate(struct Door* door) {
|
||||||
float targetOpenAmount = signalsRead(door->signalIndex) ? 1.0f : 0.0f;
|
struct DoorTypeDefinition* typeDefinition = &gDoorTypeDefinitions[door->doorDefinition->doorType];
|
||||||
door->openAmount = mathfMoveTowards(door->openAmount, targetOpenAmount, OPEN_VELOCITY * FIXED_DELTA_TIME);
|
|
||||||
|
int signal = signalsRead(door->signalIndex);
|
||||||
|
skAnimatorUpdate(&door->animator, door->armature.pose, FIXED_DELTA_TIME);
|
||||||
|
|
||||||
|
int isOpen = (door->flags & DoorFlagsIsOpen) != 0;
|
||||||
|
|
||||||
|
if (isOpen != signal) {
|
||||||
|
if (!skAnimatorIsRunning(&door->animator)) {
|
||||||
|
if (signal) {
|
||||||
|
skAnimatorRunClip(&door->animator, typeDefinition->openClip, 0.0f, 0);
|
||||||
|
} else {
|
||||||
|
skAnimatorRunClip(&door->animator, typeDefinition->closeClip, 0.0f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
soundPlayerPlay(soundsDoor, 3.0f, 0.5f, &door->rigidBody.transform.position, &gZeroVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signal) {
|
||||||
|
door->flags |= DoorFlagsIsOpen;
|
||||||
|
} else {
|
||||||
|
door->flags &= ~DoorFlagsIsOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int isDoorwayOpen = skAnimatorIsRunning(&door->animator) || isOpen;
|
||||||
|
|
||||||
if (door->forDoorway) {
|
if (door->forDoorway) {
|
||||||
if (door->openAmount == 0.0f) {
|
if (isDoorwayOpen) {
|
||||||
door->forDoorway->flags &= ~DoorwayFlagsOpen;
|
|
||||||
} else {
|
|
||||||
door->forDoorway->flags |= DoorwayFlagsOpen;
|
door->forDoorway->flags |= DoorwayFlagsOpen;
|
||||||
|
} else {
|
||||||
|
door->forDoorway->flags &= ~DoorwayFlagsOpen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (door->openAmount == 0.0f) {
|
if (typeDefinition->colliderBoneIndex == -1) {
|
||||||
door->collisionObject.collisionLayers = COLLISION_LAYERS_TANGIBLE|COLLISION_LAYERS_STATIC;
|
door->collisionObject.collisionLayers = isDoorwayOpen ? 0 : (COLLISION_LAYERS_TANGIBLE | COLLISION_LAYERS_STATIC);
|
||||||
door->flags &= ~DoorFlagsJustOpened;
|
|
||||||
if (!(door->flags & DoorFlagsJustClosed)){
|
|
||||||
soundPlayerPlay(soundsDoor, 3.0f, 0.5f, &door->rigidBody.transform.position, &gZeroVec);
|
|
||||||
door->flags |= DoorFlagsJustClosed;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
door->flags &= ~DoorFlagsJustClosed;
|
door->rigidBody.transform.position.y =
|
||||||
if (!(door->flags & DoorFlagsJustOpened)){
|
door->doorDefinition->location.y +
|
||||||
soundPlayerPlay(soundsDoor, 3.0f, 0.5f, &door->rigidBody.transform.position, &gZeroVec);
|
door->armature.pose[typeDefinition->colliderBoneIndex].position.y * (1.0f / SCENE_SCALE);
|
||||||
door->flags |= DoorFlagsJustOpened;
|
|
||||||
}
|
|
||||||
door->collisionObject.collisionLayers = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,20 +5,32 @@
|
||||||
#include "../levels/level_definition.h"
|
#include "../levels/level_definition.h"
|
||||||
#include "../audio/soundplayer.h"
|
#include "../audio/soundplayer.h"
|
||||||
#include "../audio/clips.h"
|
#include "../audio/clips.h"
|
||||||
|
#include "../sk64/skelatool_animator.h"
|
||||||
|
#include "../sk64/skelatool_armature.h"
|
||||||
|
|
||||||
enum DoorFlags {
|
enum DoorFlags {
|
||||||
DoorFlagsJustClosed = (1 << 0),
|
DoorFlagsIsOpen = (1 << 0),
|
||||||
DoorFlagsJustOpened = (1 << 1),
|
};
|
||||||
|
|
||||||
|
struct DoorTypeDefinition {
|
||||||
|
struct SKArmatureDefinition* armature;
|
||||||
|
Gfx* model;
|
||||||
|
struct SKAnimationClip* openClip;
|
||||||
|
struct SKAnimationClip* closeClip;
|
||||||
|
short colliderBoneIndex;
|
||||||
|
float closeSpeed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Door {
|
struct Door {
|
||||||
struct CollisionObject collisionObject;
|
struct CollisionObject collisionObject;
|
||||||
struct RigidBody rigidBody;
|
struct RigidBody rigidBody;
|
||||||
|
struct SKAnimator animator;
|
||||||
|
struct SKArmature armature;
|
||||||
|
|
||||||
struct Doorway* forDoorway;
|
struct Doorway* forDoorway;
|
||||||
struct DoorDefinition* doorDefinition;
|
struct DoorDefinition* doorDefinition;
|
||||||
short dynamicId;
|
short dynamicId;
|
||||||
short signalIndex;
|
short signalIndex;
|
||||||
float openAmount;
|
|
||||||
short flags;
|
short flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
78
src/scene/portal_gun.c
Normal file
78
src/scene/portal_gun.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#include "portal_gun.h"
|
||||||
|
|
||||||
|
#include "../physics/collision_scene.h"
|
||||||
|
#include "../physics/collision_cylinder.h"
|
||||||
|
#include "models/models.h"
|
||||||
|
|
||||||
|
struct Vector2 gGunColliderEdgeVectors[] = {
|
||||||
|
{0.0f, 1.0f},
|
||||||
|
{0.707f, 0.707f},
|
||||||
|
{1.0f, 0.0f},
|
||||||
|
{0.707f, -0.707f},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CollisionQuad gGunColliderFaces[8];
|
||||||
|
|
||||||
|
struct CollisionCylinder gGunCollider = {
|
||||||
|
0.05f,
|
||||||
|
0.1f,
|
||||||
|
gGunColliderEdgeVectors,
|
||||||
|
sizeof(gGunColliderEdgeVectors) / sizeof(*gGunColliderEdgeVectors),
|
||||||
|
gGunColliderFaces,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ColliderTypeData gGunColliderData = {
|
||||||
|
CollisionShapeTypeCylinder,
|
||||||
|
&gGunCollider,
|
||||||
|
0.0f,
|
||||||
|
0.6f,
|
||||||
|
&gCollisionCylinderCallbacks,
|
||||||
|
};
|
||||||
|
|
||||||
|
void portalGunInit(struct PortalGun* portalGun, struct Transform* at){
|
||||||
|
collisionObjectInit(&portalGun->collisionObject, &gGunColliderData, &portalGun->rigidBody, 1.0f, 0);
|
||||||
|
collisionSceneAddDynamicObject(&portalGun->collisionObject);
|
||||||
|
portalGun->rigidBody.transform = *at;
|
||||||
|
portalGun->rigidBody.transform.scale = gOneVec;
|
||||||
|
portalGun->rigidBody.currentRoom = 0;
|
||||||
|
portalGun->rigidBody.velocity = gZeroVec;
|
||||||
|
portalGun->rigidBody.angularVelocity = gZeroVec;
|
||||||
|
portalGun->dynamicId = dynamicSceneAdd(portalGun, portalGunDummyRender, &portalGun->rigidBody.transform.position, 0.05f);
|
||||||
|
portalGun->portalGunVisible = 0;
|
||||||
|
|
||||||
|
collisionObjectUpdateBB(&portalGun->collisionObject);
|
||||||
|
dynamicSceneSetRoomFlags(portalGun->dynamicId, ROOM_FLAG_FROM_INDEX(portalGun->rigidBody.currentRoom));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void portalGunDummyRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState){
|
||||||
|
if (portalGun->portalGunVisible){
|
||||||
|
portalGun->rigidBody.transform.scale = gOneVec;
|
||||||
|
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
|
||||||
|
|
||||||
|
if (!matrix) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
transformToMatrixL(&portalGun->rigidBody.transform, matrix, SCENE_SCALE);
|
||||||
|
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
|
||||||
|
gSPDisplayList(renderState->dl++, v_portal_gun_gfx);
|
||||||
|
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void portalGunUpdate(struct PortalGun* portalGun, struct Player* player){
|
||||||
|
if (player->flags & (PlayerHasFirstPortalGun | PlayerHasSecondPortalGun)){
|
||||||
|
portalGun->portalGunVisible = 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
portalGun->portalGunVisible = 0;
|
||||||
|
}
|
||||||
|
dynamicSceneSetRoomFlags(portalGun->dynamicId, ROOM_FLAG_FROM_INDEX(portalGun->rigidBody.currentRoom));
|
||||||
|
}
|
24
src/scene/portal_gun.h
Normal file
24
src/scene/portal_gun.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef __PORTAL_GUN_H__
|
||||||
|
#define __PORTAL_GUN_H__
|
||||||
|
|
||||||
|
#include "../physics/collision_object.h"
|
||||||
|
#include "../math/transform.h"
|
||||||
|
#include "../graphics/renderstate.h"
|
||||||
|
#include "../physics/rigid_body.h"
|
||||||
|
#include "../physics/collision_object.h"
|
||||||
|
#include "../scene/dynamic_scene.h"
|
||||||
|
#include "../player/player.h"
|
||||||
|
|
||||||
|
struct PortalGun {
|
||||||
|
struct CollisionObject collisionObject;
|
||||||
|
struct RigidBody rigidBody;
|
||||||
|
int portalGunVisible;
|
||||||
|
short dynamicId;
|
||||||
|
};
|
||||||
|
|
||||||
|
void portalGunInit(struct PortalGun* portalGun, struct Transform* at);
|
||||||
|
void portalGunDummyRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState);
|
||||||
|
void portalGunUpdate(struct PortalGun* portalGun, struct Player* player);
|
||||||
|
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState);
|
||||||
|
|
||||||
|
#endif
|
|
@ -31,10 +31,6 @@
|
||||||
#include "signals.h"
|
#include "signals.h"
|
||||||
#include "render_plan.h"
|
#include "render_plan.h"
|
||||||
|
|
||||||
struct Vector3 gPortalGunOffset = {0.120957, -0.113587, -0.20916};
|
|
||||||
struct Vector3 gPortalGunForward = {0.1f, -0.1f, 1.0f};
|
|
||||||
struct Vector3 gPortalGunUp = {0.0f, 1.0f, 0.0f};
|
|
||||||
|
|
||||||
Lights1 gSceneLights = gdSPDefLights1(128, 128, 128, 128, 128, 128, 0, 127, 0);
|
Lights1 gSceneLights = gdSPDefLights1(128, 128, 128, 128, 128, 128, 0, 127, 0);
|
||||||
|
|
||||||
#define LEVEL_INDEX_WITH_GUN_0 2
|
#define LEVEL_INDEX_WITH_GUN_0 2
|
||||||
|
@ -78,7 +74,9 @@ void sceneInit(struct Scene* scene) {
|
||||||
transformConcat(&startLocation->transform, levelRelativeTransform(), &combinedLocation.transform);
|
transformConcat(&startLocation->transform, levelRelativeTransform(), &combinedLocation.transform);
|
||||||
quatMultVector(&startLocation->transform.rotation, levelRelativeVelocity(), &startVelocity);
|
quatMultVector(&startLocation->transform.rotation, levelRelativeVelocity(), &startVelocity);
|
||||||
|
|
||||||
playerInit(&scene->player, &combinedLocation, &startVelocity);
|
portalGunInit(&scene->portalGun, &combinedLocation.transform);
|
||||||
|
|
||||||
|
playerInit(&scene->player, &combinedLocation, &startVelocity, &scene->portalGun.collisionObject);
|
||||||
sceneUpdateListeners(scene);
|
sceneUpdateListeners(scene);
|
||||||
|
|
||||||
if (gCurrentLevelIndex >= LEVEL_INDEX_WITH_GUN_0) {
|
if (gCurrentLevelIndex >= LEVEL_INDEX_WITH_GUN_0) {
|
||||||
|
@ -205,26 +203,6 @@ void sceneRenderPerformanceMetrics(struct Scene* scene, struct RenderState* rend
|
||||||
gDPPipeSync(renderState->dl++);
|
gDPPipeSync(renderState->dl++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sceneRenderPortalGun(struct Scene* scene, struct RenderState* renderState) {
|
|
||||||
struct Transform gunTransform;
|
|
||||||
transformPoint(&scene->player.lookTransform, &gPortalGunOffset, &gunTransform.position);
|
|
||||||
struct Quaternion relativeRotation;
|
|
||||||
quatLook(&gPortalGunForward, &gPortalGunUp, &relativeRotation);
|
|
||||||
quatMultiply(&scene->player.lookTransform.rotation, &relativeRotation, &gunTransform.rotation);
|
|
||||||
gunTransform.scale = gOneVec;
|
|
||||||
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
|
|
||||||
|
|
||||||
if (!matrix) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
transformToMatrixL(&gunTransform, matrix, SCENE_SCALE);
|
|
||||||
|
|
||||||
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
|
|
||||||
gSPDisplayList(renderState->dl++, v_portal_gun_gfx);
|
|
||||||
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
|
||||||
}
|
|
||||||
|
|
||||||
LookAt gLookAt = gdSPDefLookAt(127, 0, 0, 0, 127, 0);
|
LookAt gLookAt = gdSPDefLookAt(127, 0, 0, 0, 127, 0);
|
||||||
|
|
||||||
void sceneRender(struct Scene* scene, struct RenderState* renderState, struct GraphicsTask* task) {
|
void sceneRender(struct Scene* scene, struct RenderState* renderState, struct GraphicsTask* task) {
|
||||||
|
@ -247,9 +225,7 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
|
||||||
renderPlanBuild(&renderPlan, scene, renderState);
|
renderPlanBuild(&renderPlan, scene, renderState);
|
||||||
renderPlanExecute(&renderPlan, scene, staticMatrices, renderState);
|
renderPlanExecute(&renderPlan, scene, staticMatrices, renderState);
|
||||||
|
|
||||||
if (scene->player.flags & (PlayerHasFirstPortalGun | PlayerHasSecondPortalGun)) {
|
portalGunRenderReal(&scene->portalGun, renderState);
|
||||||
sceneRenderPortalGun(scene, renderState);
|
|
||||||
}
|
|
||||||
|
|
||||||
gDPPipeSync(renderState->dl++);
|
gDPPipeSync(renderState->dl++);
|
||||||
gDPSetRenderMode(renderState->dl++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
|
gDPSetRenderMode(renderState->dl++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
|
||||||
|
@ -279,18 +255,24 @@ void sceneCheckPortals(struct Scene* scene) {
|
||||||
quatMultVector(&scene->player.lookTransform.rotation, &raycastRay.dir, &raycastRay.dir);
|
quatMultVector(&scene->player.lookTransform.rotation, &raycastRay.dir, &raycastRay.dir);
|
||||||
quatMultVector(&scene->player.lookTransform.rotation, &gUp, &playerUp);
|
quatMultVector(&scene->player.lookTransform.rotation, &gUp, &playerUp);
|
||||||
|
|
||||||
if (controllerGetButtonDown(0, Z_TRIG) && (scene->player.flags & PlayerHasSecondPortalGun)) {
|
if (controllerGetButtonDown(0, Z_TRIG) && (scene->player.flags & PlayerHasSecondPortalGun) && !playerIsGrabbing(&scene->player)) {
|
||||||
sceneFirePortal(scene, &raycastRay, &playerUp, 0, scene->player.body.currentRoom, 1, 0);
|
sceneFirePortal(scene, &raycastRay, &playerUp, 0, scene->player.body.currentRoom, 1, 0);
|
||||||
|
scene->player.flags |= PlayerJustShotPortalGun;
|
||||||
scene->last_portal_indx_shot=0;
|
scene->last_portal_indx_shot=0;
|
||||||
soundPlayerPlay(soundsPortalgunShoot[0], 1.0f, 1.0f, NULL, NULL);
|
soundPlayerPlay(soundsPortalgunShoot[0], 1.0f, 1.0f, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controllerGetButtonDown(0, R_TRIG | L_TRIG) && (scene->player.flags & PlayerHasFirstPortalGun)) {
|
if (controllerGetButtonDown(0, R_TRIG | L_TRIG) && (scene->player.flags & PlayerHasFirstPortalGun) && !playerIsGrabbing(&scene->player)) {
|
||||||
sceneFirePortal(scene, &raycastRay, &playerUp, 1, scene->player.body.currentRoom, 1, 0);
|
sceneFirePortal(scene, &raycastRay, &playerUp, 1, scene->player.body.currentRoom, 1, 0);
|
||||||
|
scene->player.flags |= PlayerJustShotPortalGun;
|
||||||
scene->last_portal_indx_shot=1;
|
scene->last_portal_indx_shot=1;
|
||||||
soundPlayerPlay(soundsPortalgunShoot[1], 1.0f, 1.0f, NULL, NULL);
|
soundPlayerPlay(soundsPortalgunShoot[1], 1.0f, 1.0f, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (controllerGetButtonDown(0, R_TRIG | L_TRIG | Z_TRIG) && playerIsGrabbing(&scene->player)){
|
||||||
|
playerSetGrabbing(&scene->player, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
scene->looked_wall_portalable_0 = 0;
|
scene->looked_wall_portalable_0 = 0;
|
||||||
scene->looked_wall_portalable_1 = 0;
|
scene->looked_wall_portalable_1 = 0;
|
||||||
|
@ -323,6 +305,7 @@ void sceneCheckPortals(struct Scene* scene) {
|
||||||
|
|
||||||
if (scene->player.flags & PlayerHasFirstPortalGun){
|
if (scene->player.flags & PlayerHasFirstPortalGun){
|
||||||
if (sceneFirePortal(scene, &raycastRay, &playerUp, 0, scene->player.body.currentRoom, 1, 1)){
|
if (sceneFirePortal(scene, &raycastRay, &playerUp, 0, scene->player.body.currentRoom, 1, 1)){
|
||||||
|
|
||||||
scene->looked_wall_portalable_0 = 1;
|
scene->looked_wall_portalable_0 = 1;
|
||||||
}
|
}
|
||||||
if (sceneFirePortal(scene, &raycastRay, &playerUp, 1, scene->player.body.currentRoom, 1, 1)){
|
if (sceneFirePortal(scene, &raycastRay, &playerUp, 1, scene->player.body.currentRoom, 1, 1)){
|
||||||
|
@ -449,6 +432,7 @@ void sceneUpdate(struct Scene* scene) {
|
||||||
|
|
||||||
signalsReset();
|
signalsReset();
|
||||||
|
|
||||||
|
portalGunUpdate(&scene->portalGun, &scene->player);
|
||||||
playerUpdate(&scene->player, &scene->camera.transform);
|
playerUpdate(&scene->player, &scene->camera.transform);
|
||||||
sceneUpdateListeners(scene);
|
sceneUpdateListeners(scene);
|
||||||
sceneCheckPortals(scene);
|
sceneCheckPortals(scene);
|
||||||
|
@ -524,6 +508,14 @@ void sceneUpdate(struct Scene* scene) {
|
||||||
&gZeroVec,
|
&gZeroVec,
|
||||||
scene->elevators[teleportTo].roomIndex
|
scene->elevators[teleportTo].roomIndex
|
||||||
);
|
);
|
||||||
|
rigidBodyTeleport(
|
||||||
|
&scene->portalGun.rigidBody,
|
||||||
|
&scene->elevators[i].rigidBody.transform,
|
||||||
|
&scene->elevators[teleportTo].rigidBody.transform,
|
||||||
|
&gZeroVec,
|
||||||
|
&gZeroVec,
|
||||||
|
scene->elevators[teleportTo].roomIndex
|
||||||
|
);
|
||||||
checkpointSave(&gScene);
|
checkpointSave(&gScene);
|
||||||
sceneClosePortal(&gScene, 0);
|
sceneClosePortal(&gScene, 0);
|
||||||
sceneClosePortal(&gScene, 1);
|
sceneClosePortal(&gScene, 1);
|
||||||
|
|
|
@ -20,10 +20,12 @@
|
||||||
#include "switch.h"
|
#include "switch.h"
|
||||||
#include "ball_launcher.h"
|
#include "ball_launcher.h"
|
||||||
#include "ball_catcher.h"
|
#include "ball_catcher.h"
|
||||||
|
#include "portal_gun.h"
|
||||||
|
|
||||||
struct Scene {
|
struct Scene {
|
||||||
struct Camera camera;
|
struct Camera camera;
|
||||||
struct Player player;
|
struct Player player;
|
||||||
|
struct PortalGun portalGun;
|
||||||
struct Portal portals[2];
|
struct Portal portals[2];
|
||||||
struct Button* buttons;
|
struct Button* buttons;
|
||||||
struct DecorObject** decor;
|
struct DecorObject** decor;
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#define SK_ANIMATION_EVENT_END 0xFFFF
|
#define SK_ANIMATION_EVENT_END 0xFFFF
|
||||||
#define SK_ANIMATION_EVENT_START 0xFFFE
|
#define SK_ANIMATION_EVENT_START 0xFFFE
|
||||||
|
|
||||||
|
#define SK_ANIMATION_CLIP_DURATION(clip) ((clip)->nFrames / (clip)->fps)
|
||||||
|
|
||||||
struct SKU16Vector3 {
|
struct SKU16Vector3 {
|
||||||
short x;
|
short x;
|
||||||
short y;
|
short y;
|
||||||
|
|
|
@ -60,6 +60,14 @@ sk_definition_writer.add_header('"decor/decor_object_list.h"')
|
||||||
|
|
||||||
local doors = {}
|
local doors = {}
|
||||||
|
|
||||||
|
local function parse_door_type(name)
|
||||||
|
if name == '02' then
|
||||||
|
return sk_definition_writer.raw('DoorType02')
|
||||||
|
end
|
||||||
|
|
||||||
|
return sk_definition_writer.raw('DoorType01')
|
||||||
|
end
|
||||||
|
|
||||||
for _, door in pairs(sk_scene.nodes_for_type('@door')) do
|
for _, door in pairs(sk_scene.nodes_for_type('@door')) do
|
||||||
local position, rotation = door.node.full_transformation:decompose()
|
local position, rotation = door.node.full_transformation:decompose()
|
||||||
|
|
||||||
|
@ -68,6 +76,7 @@ for _, door in pairs(sk_scene.nodes_for_type('@door')) do
|
||||||
rotation,
|
rotation,
|
||||||
world.find_coplanar_doorway(position) - 1,
|
world.find_coplanar_doorway(position) - 1,
|
||||||
signals.signal_index_for_name(door.arguments[1] or ''),
|
signals.signal_index_for_name(door.arguments[1] or ''),
|
||||||
|
parse_door_type(door.arguments[2])
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue