Implement fizzler for cube

This commit is contained in:
James Lambert 2022-06-15 21:09:38 -06:00
parent 3e0194aa32
commit 7db1d880c8
15 changed files with 202 additions and 91 deletions

View file

@ -59,7 +59,6 @@ where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where blender
implement elevator implement elevator
mesh collider type mesh collider type
implement emancipation grid
Change the way player standing logic works Change the way player standing logic works
cube dispenser cube dispenser
nan in overlap nan in overlap

View file

@ -6,6 +6,8 @@ materials:
gDPSetTexturePersp: G_TP_PERSP gDPSetTexturePersp: G_TP_PERSP
gDPSetCycleType: G_CYC_1CYCLE
gSPGeometryMode: gSPGeometryMode:
set: [G_CULL_BACK, G_ZBUFFER] set: [G_CULL_BACK, G_ZBUFFER]
clear: [G_CULL_FRONT] clear: [G_CULL_FRONT]
@ -137,6 +139,41 @@ materials:
gDPSetCombineMode: gDPSetCombineMode:
color: ["SHADE", "0", "TEXEL0", "0"] color: ["SHADE", "0", "TEXEL0", "0"]
cube_fizzled:
gDPSetTile:
filename:
../images/cube.png
siz: G_IM_SIZ_16b
fmt: G_IM_FMT_RGBA
s:
mirror: true
t:
mirror: true
gDPSetRenderMode:
- blend: ["G_BL_CLR_IN", "G_BL_A_IN", "G_BL_CLR_FOG", "G_BL_1MA"]
- G_RM_ZB_XLU_SURF
gDPSetCycleType: G_CYC_2CYCLE
gSPGeometryMode:
set: [G_LIGHTING, G_SHADE]
gDPSetCombineMode:
- color: ["SHADE", "0", "TEXEL0", "0"]
alpha: ["0", "0", "0", "PRIMITIVE"]
- color: ["NOISE", "COMBINED", "PRIMITIVE", "COMBINED"]
alpha: ["0", "0", "0", "PRIMITIVE"]
gDPSetFogColor:
r: 0
g: 0
b: 0
gDPSetPrimColor:
r: 100
g: 100
b: 200
a: 128
door_01: door_01:
gDPSetTile: gDPSetTile:
filename: filename:

View file

@ -0,0 +1 @@
-c 1

View file

@ -40,36 +40,92 @@
] ]
}, },
"renderMode": { "renderMode": {
"type": "object", "anyOf": [
"properties": { {
"flags": { "enum": [
"type": "array", "G_RM_AA_ZB_OPA_SURF",
"items": { "G_RM_RA_ZB_OPA_SURF",
"enum": [ "G_RM_AA_ZB_XLU_SURF",
"AA_EN", "G_RM_AA_ZB_OPA_DECAL",
"Z_CMP", "G_RM_RA_ZB_OPA_DECAL",
"Z_UPD", "G_RM_AA_ZB_XLU_DECAL",
"IM_RD", "G_RM_AA_ZB_OPA_INTER",
"CLR_ON_CVG", "G_RM_RA_ZB_OPA_INTER",
"CVG_X_ALPHA", "G_RM_AA_ZB_XLU_INTER",
"ALPHA_CVG_SEL", "G_RM_AA_ZB_XLU_LINE",
"FORCE_BL", "G_RM_AA_ZB_DEC_LINE",
"CVG_DST_CLAMP", "G_RM_AA_ZB_TEX_EDGE",
"CVG_DST_WRAP", "G_RM_AA_ZB_TEX_INTER",
"CVG_DST_FULL", "G_RM_AA_ZB_SUB_SURF",
"CVG_DST_SAVE", "G_RM_AA_ZB_PCL_SURF",
"ZMODE_OPA", "G_RM_AA_ZB_OPA_TERR",
"ZMODE_INTER", "G_RM_AA_ZB_TEX_TERR",
"ZMODE_XLU", "G_RM_AA_ZB_SUB_TERR",
"ZMODE_DEC" "G_RM_AA_OPA_SURF",
] "G_RM_RA_OPA_SURF",
}, "G_RM_AA_XLU_SURF",
"uniqueItems": true "G_RM_AA_XLU_LINE",
"G_RM_AA_DEC_LINE",
"G_RM_AA_TEX_EDGE",
"G_RM_AA_SUB_SURF",
"G_RM_AA_PCL_SURF",
"G_RM_AA_OPA_TERR",
"G_RM_AA_TEX_TERR",
"G_RM_AA_SUB_TERR",
"G_RM_ZB_OPA_SURF",
"G_RM_ZB_XLU_SURF",
"G_RM_ZB_OPA_DECAL",
"G_RM_ZB_XLU_DECAL",
"G_RM_ZB_CLD_SURF",
"G_RM_ZB_OVL_SURF",
"G_RM_ZB_PCL_SURF",
"G_RM_OPA_SURF",
"G_RM_XLU_SURF",
"G_RM_TEX_EDGE",
"G_RM_CLD_SURF",
"G_RM_PCL_SURF",
"G_RM_ADD",
"G_RM_NOOP",
"G_RM_VISCVG",
"G_RM_OPA_CI",
"G_RM_FOG_SHADE_A",
"G_RM_FOG_PRIM_A",
"G_RM_PASS"
]
}, },
"blend": { {
"$ref": "#/definitions/renderBlendModes" "type": "object",
"properties": {
"flags": {
"type": "array",
"items": {
"enum": [
"AA_EN",
"Z_CMP",
"Z_UPD",
"IM_RD",
"CLR_ON_CVG",
"CVG_X_ALPHA",
"ALPHA_CVG_SEL",
"FORCE_BL",
"CVG_DST_CLAMP",
"CVG_DST_WRAP",
"CVG_DST_FULL",
"CVG_DST_SAVE",
"ZMODE_OPA",
"ZMODE_INTER",
"ZMODE_XLU",
"ZMODE_DEC"
]
},
"uniqueItems": true
},
"blend": {
"$ref": "#/definitions/renderBlendModes"
}
}
} }
} ]
}, },
"geometryModeArray": { "geometryModeArray": {
"type": "array", "type": "array",
@ -518,59 +574,15 @@
"gDPSetRenderMode": { "gDPSetRenderMode": {
"anyOf": [ "anyOf": [
{ {
"enum": [ "$ref": "#/definitions/renderMode"
"G_RM_AA_ZB_OPA_SURF",
"G_RM_RA_ZB_OPA_SURF",
"G_RM_AA_ZB_XLU_SURF",
"G_RM_AA_ZB_OPA_DECAL",
"G_RM_RA_ZB_OPA_DECAL",
"G_RM_AA_ZB_XLU_DECAL",
"G_RM_AA_ZB_OPA_INTER",
"G_RM_RA_ZB_OPA_INTER",
"G_RM_AA_ZB_XLU_INTER",
"G_RM_AA_ZB_XLU_LINE",
"G_RM_AA_ZB_DEC_LINE",
"G_RM_AA_ZB_TEX_EDGE",
"G_RM_AA_ZB_TEX_INTER",
"G_RM_AA_ZB_SUB_SURF",
"G_RM_AA_ZB_PCL_SURF",
"G_RM_AA_ZB_OPA_TERR",
"G_RM_AA_ZB_TEX_TERR",
"G_RM_AA_ZB_SUB_TERR",
"G_RM_AA_OPA_SURF",
"G_RM_RA_OPA_SURF",
"G_RM_AA_XLU_SURF",
"G_RM_AA_XLU_LINE",
"G_RM_AA_DEC_LINE",
"G_RM_AA_TEX_EDGE",
"G_RM_AA_SUB_SURF",
"G_RM_AA_PCL_SURF",
"G_RM_AA_OPA_TERR",
"G_RM_AA_TEX_TERR",
"G_RM_AA_SUB_TERR",
"G_RM_ZB_OPA_SURF",
"G_RM_ZB_XLU_SURF",
"G_RM_ZB_OPA_DECAL",
"G_RM_ZB_XLU_DECAL",
"G_RM_ZB_CLD_SURF",
"G_RM_ZB_OVL_SURF",
"G_RM_ZB_PCL_SURF",
"G_RM_OPA_SURF",
"G_RM_XLU_SURF",
"G_RM_TEX_EDGE",
"G_RM_CLD_SURF",
"G_RM_PCL_SURF",
"G_RM_ADD",
"G_RM_NOOP",
"G_RM_VISCVG",
"G_RM_OPA_CI",
"G_RM_FOG_SHADE_A",
"G_RM_FOG_PRIM_A",
"G_RM_PASS"
]
}, },
{ {
"$ref": "#/definitions/renderMode" "type": "array",
"items": [{
"$ref": "#/definitions/renderMode"
}, {
"$ref": "#/definitions/renderMode"
}]
} }
] ]
}, },

View file

@ -16,11 +16,12 @@ int sortOrderForMaterial(const Material& material) {
return 0; return 0;
} }
if (material.mState.cycle1RenderMode.GetZMode() == ZMODE_DEC) { if (material.mState.cycle1RenderMode.GetZMode() == ZMODE_DEC ||
material.mState.cycle2RenderMode.GetZMode() == ZMODE_DEC) {
return 1; return 1;
} }
if (material.mState.cycle1RenderMode.data & FORCE_BL) { if ((material.mState.cycle1RenderMode.data | material.mState.cycle2RenderMode.data) & FORCE_BL) {
return 2; return 2;
} }

View file

@ -347,7 +347,7 @@ int parseBlendMode(const YAML::Node& node, ParseResult& output) {
std::string asString = element.as<std::string>(); std::string asString = element.as<std::string>();
if (!renderModeGetBlendModeValue(asString, i, params[i])) { if (!renderModeGetBlendModeValue(asString, i, params[i])) {
output.mErrors.push_back(ParseError(formatError("Invalid blend mode", node.Mark()))); output.mErrors.push_back(ParseError(formatError(std::string("Invalid blend mode ") + asString, node.Mark())));
} }
} }
@ -391,7 +391,7 @@ void parseRenderMode(const YAML::Node& node, MaterialState& state, ParseResult&
if (node.IsSequence() && node.size() == 2) { if (node.IsSequence() && node.size() == 2) {
parseSingleRenderMode(node[0], state.cycle1RenderMode, output); parseSingleRenderMode(node[0], state.cycle1RenderMode, output);
parseSingleRenderMode(node[1], state.cycle1RenderMode, output); parseSingleRenderMode(node[1], state.cycle2RenderMode, output);
return; return;
} }

View file

@ -20,3 +20,5 @@ unsigned short soundsPortalgunShoot[2] = {
}; };
unsigned short soundsPortalOpen2 = SOUNDS_PORTAL_OPEN2; unsigned short soundsPortalOpen2 = SOUNDS_PORTAL_OPEN2;
unsigned short soundsPortalFizzle = SOUNDS_PORTAL_FIZZLE2;

View file

@ -8,4 +8,6 @@ extern unsigned short soundsPortalgunShoot[2];
extern unsigned short soundsPortalOpen2; extern unsigned short soundsPortalOpen2;
extern unsigned short soundsPortalFizzle;
#endif #endif

View file

@ -4,13 +4,44 @@
#include "../scene/dynamic_scene.h" #include "../scene/dynamic_scene.h"
#include "../util/memory.h" #include "../util/memory.h"
#include "../audio/soundplayer.h" #include "../audio/soundplayer.h"
#include "../util/time.h"
#define TIME_TO_FIZZLE 2.0f
#define FIZZLE_TIME_STEP (FIXED_DELTA_TIME / TIME_TO_FIZZLE)
void decorObjectRender(void* data, struct RenderScene* renderScene) { void decorObjectRender(void* data, struct RenderScene* renderScene) {
struct DecorObject* object = (struct DecorObject*)data; struct DecorObject* object = (struct DecorObject*)data;
Mtx* matrix = renderStateRequestMatrices(renderScene->renderState, 1); Mtx* matrix = renderStateRequestMatrices(renderScene->renderState, 1);
transformToMatrixL(&object->rigidBody.transform, matrix, SCENE_SCALE); transformToMatrixL(&object->rigidBody.transform, matrix, SCENE_SCALE);
renderSceneAdd(renderScene, object->definition->graphics, matrix, object->definition->materialIndex, &object->rigidBody.transform.position, NULL); Gfx* gfxToRender;
if (object->fizzleTime > 0.0f) {
gfxToRender = renderStateAllocateDLChunk(renderScene->renderState, 3);
Gfx* curr = gfxToRender;
int fizzleTimeAsInt = (int)(255.0f * object->fizzleTime);
if (fizzleTimeAsInt > 255) {
fizzleTimeAsInt = 255;
}
gDPSetPrimColor(curr++, 255, 255, fizzleTimeAsInt, fizzleTimeAsInt, fizzleTimeAsInt, 255 - fizzleTimeAsInt);
gSPDisplayList(curr++, object->definition->graphics);
gSPEndDisplayList(curr++);
} else {
gfxToRender = object->definition->graphics;
}
renderSceneAdd(
renderScene,
gfxToRender,
matrix,
(object->fizzleTime > 0.0f) ? object->definition->materialIndexFizzled : object->definition->materialIndex,
&object->rigidBody.transform.position,
NULL
);
} }
struct DecorObject* decorObjectNew(struct DecorObjectDefinition* definition, struct Transform* at, int room) { struct DecorObject* decorObjectNew(struct DecorObjectDefinition* definition, struct Transform* at, int room) {
@ -27,6 +58,7 @@ void decorObjectInit(struct DecorObject* object, struct DecorObjectDefinition* d
object->rigidBody.flags |= RigidBodyFlagsGrabbable; object->rigidBody.flags |= RigidBodyFlagsGrabbable;
object->rigidBody.currentRoom = room; object->rigidBody.currentRoom = room;
object->definition = definition; object->definition = definition;
object->fizzleTime = 0.0f;
collisionObjectUpdateBB(&object->collisionObject); collisionObjectUpdateBB(&object->collisionObject);
@ -55,4 +87,15 @@ void decorObjectUpdate(struct DecorObject* decorObject) {
} else { } else {
dynamicSceneClearFlags(decorObject->dynamicId, DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL); dynamicSceneClearFlags(decorObject->dynamicId, DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL);
} }
if (decorObject->rigidBody.flags & RigidBodyFizzled) {
if (decorObject->fizzleTime == 0.0f) {
vector3Scale(&decorObject->rigidBody.velocity, &decorObject->rigidBody.velocity, 0.25f);
vector3AddScaled(&decorObject->rigidBody.angularVelocity, &decorObject->rigidBody.velocity, 0.5f, &decorObject->rigidBody.angularVelocity);
}
decorObject->fizzleTime += FIZZLE_TIME_STEP;
decorObject->collisionObject.body->flags &= ~RigidBodyFlagsGrabbable;
decorObject->collisionObject.body->flags |= RigidBodyDisableGravity;
}
} }

View file

@ -11,6 +11,7 @@ struct DecorObjectDefinition {
float radius; float radius;
Gfx* graphics; Gfx* graphics;
short materialIndex; short materialIndex;
short materialIndexFizzled;
short soundClipId; short soundClipId;
}; };
@ -20,6 +21,7 @@ struct DecorObject {
struct DecorObjectDefinition* definition; struct DecorObjectDefinition* definition;
short dynamicId; short dynamicId;
ALSndId playingSound; ALSndId playingSound;
float fizzleTime;
}; };
struct DecorObject* decorObjectNew(struct DecorObjectDefinition* definition, struct Transform* at, int room); struct DecorObject* decorObjectNew(struct DecorObjectDefinition* definition, struct Transform* at, int room);

View file

@ -46,7 +46,7 @@ struct DecorObjectDefinition gDecorObjectDefinitions[] = {
1.0f, 1.0f,
0.92f, 0.92f,
&props_cylinder_test_model_gfx[0], &props_cylinder_test_model_gfx[0],
PLASTIC_PLASTICWALL001A_INDEX, .materialIndex = PLASTIC_PLASTICWALL001A_INDEX,
.soundClipId = -1, .soundClipId = -1,
}, },
[DECOR_TYPE_RADIO] = { [DECOR_TYPE_RADIO] = {
@ -60,7 +60,7 @@ struct DecorObjectDefinition gDecorObjectDefinitions[] = {
0.2f, 0.2f,
0.4f, 0.4f,
&props_radio_model_gfx[0], &props_radio_model_gfx[0],
RADIO_INDEX, .materialIndex = RADIO_INDEX,
.soundClipId = SOUNDS_LOOPING_RADIO_MIX, .soundClipId = SOUNDS_LOOPING_RADIO_MIX,
}, },
[DECOR_TYPE_CUBE] = { [DECOR_TYPE_CUBE] = {
@ -74,7 +74,9 @@ struct DecorObjectDefinition gDecorObjectDefinitions[] = {
2.0f, 2.0f,
0.55f, 0.55f,
&cube_cube_model_gfx[0], &cube_cube_model_gfx[0],
CUBE_INDEX, .materialIndex = CUBE_INDEX,
.materialIndexFizzled = CUBE_FIZZLED_INDEX,
.soundClipId = -1,
}, },
}; };

View file

@ -46,7 +46,9 @@ void rigidBodyAppyImpulse(struct RigidBody* rigidBody, struct Vector3* worldPoin
#define ENERGY_SCALE_PER_STEP 0.99f #define ENERGY_SCALE_PER_STEP 0.99f
void rigidBodyUpdate(struct RigidBody* rigidBody) { void rigidBodyUpdate(struct RigidBody* rigidBody) {
rigidBody->velocity.y += GRAVITY_CONSTANT * FIXED_DELTA_TIME; if (!(rigidBody->flags & RigidBodyDisableGravity)) {
rigidBody->velocity.y += GRAVITY_CONSTANT * FIXED_DELTA_TIME;
}
vector3AddScaled(&rigidBody->transform.position, &rigidBody->velocity, FIXED_DELTA_TIME, &rigidBody->transform.position); vector3AddScaled(&rigidBody->transform.position, &rigidBody->velocity, FIXED_DELTA_TIME, &rigidBody->transform.position);
quatApplyAngularVelocity(&rigidBody->transform.rotation, &rigidBody->angularVelocity, FIXED_DELTA_TIME, &rigidBody->transform.rotation); quatApplyAngularVelocity(&rigidBody->transform.rotation, &rigidBody->angularVelocity, FIXED_DELTA_TIME, &rigidBody->transform.rotation);

View file

@ -22,6 +22,7 @@ enum RigidBodyFlags {
RigidBodyGenerateContacts = (1 << 10), RigidBodyGenerateContacts = (1 << 10),
RigidBodyFizzled = (1 << 11), RigidBodyFizzled = (1 << 11),
RigidBodyDisableGravity = (1 << 12),
}; };
struct RigidBody { struct RigidBody {

View file

@ -148,6 +148,10 @@ void playerUpdateGrabbedObject(struct Player* player) {
} }
} }
if (player->grabbing && (player->grabbing->body->flags & RigidBodyFlagsGrabbable) == 0) {
player->grabbing = NULL;
}
if (player->grabbing) { if (player->grabbing) {
if (player->body.flags & RigidBodyFlagsCrossedPortal0) { if (player->body.flags & RigidBodyFlagsCrossedPortal0) {
playerApplyPortalGrab(player, 1); playerApplyPortalGrab(player, 1);

View file

@ -312,5 +312,8 @@ int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* player
} }
void sceneClosePortal(struct Scene* scene, int portalIndex) { void sceneClosePortal(struct Scene* scene, int portalIndex) {
gCollisionScene.portalTransforms[portalIndex] = NULL; if (gCollisionScene.portalTransforms[portalIndex]) {
soundPlayerPlay(soundsPortalFizzle, 1.0f, 1.0f, &gCollisionScene.portalTransforms[portalIndex]->position);
gCollisionScene.portalTransforms[portalIndex] = NULL;
}
} }