Polish up fail portal splash particle effect

This commit is contained in:
James Lambert 2023-09-13 20:46:01 -06:00
parent 5aba1b3e77
commit 6a48f7e405
8 changed files with 79 additions and 36 deletions

View file

@ -1 +1 @@
-resize 16x16
-set colorspace Gray -separate -average -resize 32x32

View file

@ -1060,17 +1060,14 @@ materials:
portal_1_particle:
gDPSetTile:
filename: ../../portal_pak_modified/materials/effects/portal_1_particle.png
fmt: G_IM_FMT_RGBA
siz: G_IM_SIZ_32b
s:
shift: 1
t:
shift: 1
fmt: G_IM_FMT_I
siz: G_IM_SIZ_4b
gDPSetRenderMode: G_RM_ZB_XLU_SURF
gDPSetCombineMode:
color: ["0", "0", "0", "TEXEL0"]
alpha: ["0", "0", "0", "TEXEL0"]
color: ["0", "0", "0", "SHADE"]
alpha: ["SHADE", "0", "TEXEL0", "0"]
gSPGeometryMode:
clear: [G_CULL_BACK, G_CULL_FRONT]
clear: [G_CULL_BACK, G_CULL_FRONT, G_LIGHTING]
set: [G_SHADE]

View file

@ -2,14 +2,33 @@
#include "../build/assets/materials/static.h"
struct SplashParticleDefinition gFailPortalSplash = {
.particleLifetime = 1.0f,
struct SplashParticleDefinition gFailPortalSplash[2] = {
{
.particleLifetime = 0.5f,
.fullWidthTime = 0.125f,
.fadeStartTime = 0.25f,
.particleTailDelay = 0.1f,
.minNormalVelocity = 2.0f,
.maxNormalVelocity = 3.0f,
.minTangentVelocity = 3.0f,
.maxTangentVelocity = 4.0f,
.particleCount = 15,
.minNormalVelocity = 0.5f,
.maxNormalVelocity = 1.0f,
.minTangentVelocity = 1.0f,
.maxTangentVelocity = 2.0f,
.particleCount = 16,
.materialIndex = PORTAL_1_PARTICLE_INDEX,
.particleHalfWidth = 0.05f,
.particleColor = {200, 100, 50, 255},
},
{
.particleLifetime = 0.5f,
.fullWidthTime = 0.125f,
.fadeStartTime = 0.25f,
.particleTailDelay = 0.1f,
.minNormalVelocity = 0.5f,
.maxNormalVelocity = 1.0f,
.minTangentVelocity = 1.0f,
.maxTangentVelocity = 2.0f,
.particleCount = 16,
.materialIndex = PORTAL_1_PARTICLE_INDEX,
.particleHalfWidth = 0.05f,
.particleColor = {50, 70, 200, 255},
},
};

View file

@ -3,6 +3,6 @@
#include "splash_particle_effect.h"
extern struct SplashParticleDefinition gFailPortalSplash;
extern struct SplashParticleDefinition gFailPortalSplash[2];
#endif

View file

@ -7,16 +7,16 @@
#include "../scene/dynamic_scene.h"
#include "../defs.h"
void splashParticleEffectBuildVtx(Vtx* vtx, struct SplashParticle* particle, int index) {
void splashParticleEffectBuildVtx(Vtx* vtx, struct SplashParticle* particle, int index, struct Coloru8* color, float widthScalar) {
int posIndex = index >> 1;
int widthSign = index & 0x1;
struct Vector3 finalPos;
if (widthSign) {
vector3Add(&particle->position[posIndex], &particle->widthOffset, &finalPos);
vector3AddScaled(&particle->position[posIndex], &particle->widthOffset, widthScalar, &finalPos);
} else {
vector3Sub(&particle->position[posIndex], &particle->widthOffset, &finalPos);
vector3AddScaled(&particle->position[posIndex], &particle->widthOffset, -widthScalar, &finalPos);
}
vtx->v.ob[0] = (short)(finalPos.x * SCENE_SCALE);
@ -28,10 +28,10 @@ void splashParticleEffectBuildVtx(Vtx* vtx, struct SplashParticle* particle, int
vtx->v.tc[0] = posIndex ? 0 : (32 << 5);
vtx->v.tc[1] = widthSign ? 0 : (32 << 5);
vtx->v.cn[0] = 255;
vtx->v.cn[1] = 255;
vtx->v.cn[2] = 255;
vtx->v.cn[3] = 255;
vtx->v.cn[0] = color->r;
vtx->v.cn[1] = color->g;
vtx->v.cn[2] = color->b;
vtx->v.cn[3] = color->a;
}
void splashParticleEffectRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState) {
@ -40,20 +40,37 @@ void splashParticleEffectRender(void* data, struct DynamicRenderDataList* render
Vtx* vertices = renderStateRequestVertices(renderState, effect->def->particleCount * 4);
Vtx* curr = vertices;
struct Coloru8 color = effect->def->particleColor;
float width = 1.0f;
if (effect->time < effect->def->fullWidthTime) {
width = (effect->time + 0.5f) / (effect->def->fullWidthTime + 0.5f);
}
if (effect->time > effect->def->fadeStartTime) {
int alpha = (int)(255.0f * (effect->def->fadeStartTime - effect->time) / (effect->def->particleLifetime - effect->def->fadeStartTime));
if (alpha > 255) {
alpha = 255;
}
color.a = alpha;
}
for (int i = 0; i < effect->def->particleCount; ++i) {
splashParticleEffectBuildVtx(&curr[0], &effect->particles[i], 0);
splashParticleEffectBuildVtx(&curr[1], &effect->particles[i], 1);
splashParticleEffectBuildVtx(&curr[2], &effect->particles[i], 2);
splashParticleEffectBuildVtx(&curr[3], &effect->particles[i], 3);
splashParticleEffectBuildVtx(&curr[0], &effect->particles[i], 0, &color, width);
splashParticleEffectBuildVtx(&curr[1], &effect->particles[i], 1, &color, width);
splashParticleEffectBuildVtx(&curr[2], &effect->particles[i], 2, &color, width);
splashParticleEffectBuildVtx(&curr[3], &effect->particles[i], 3, &color, width);
curr += 4;
}
Gfx* displayList = renderStateAllocateDLChunk(renderState, effect->def->particleCount + (effect->def->particleCount >> 5) + 1);
Gfx* displayList = renderStateAllocateDLChunk(renderState, effect->def->particleCount + ((effect->def->particleCount + 7) >> 3) + 1);
Gfx* dl = displayList;
for (int i = 0; i < effect->def->particleCount; ++i) {
int relativeVertex = i & 0x1f;
int relativeVertex = (i << 2) & 0x1f;
if (relativeVertex == 0) {
int verticesLeft = (effect->def->particleCount - i) << 2;
@ -153,6 +170,7 @@ void splashParticleEffectUpdate(struct SplashParticleEffect* effect) {
// tailPos.y = tailPos.y + yVelocity * FIXED_DELTA_TIME - effect->def->particleTailDelay * GRAVITY_CONSTANT * FIXED_DELTA_TIME
particle->position[1].y -= effect->def->particleTailDelay * (GRAVITY_CONSTANT * FIXED_DELTA_TIME);
particle->velocity.y += FIXED_DELTA_TIME * GRAVITY_CONSTANT;
}

View file

@ -2,9 +2,12 @@
#define __SPLASH_PARTICLE_EFFECT_H__
#include "../math/vector3.h"
#include "../graphics/color.h"
struct SplashParticleDefinition {
float particleLifetime;
float fadeStartTime;
float fullWidthTime;
float particleTailDelay;
float minNormalVelocity;
float maxNormalVelocity;
@ -13,6 +16,7 @@ struct SplashParticleDefinition {
short particleCount;
short materialIndex;
float particleHalfWidth;
struct Coloru8 particleColor;
};
struct SplashParticle {

View file

@ -130,6 +130,11 @@ int meshColliderRaycast(struct CollisionObject* object, struct Ray* ray, float m
for (int i = 0; i < meshCollider->childrenCount; ++i) {
struct RaycastHit localHit;
if (!meshCollider->children[i].collisionLayers) {
continue;
}
if (raycastQuad(&meshCollider->children[i], &localRay, maxDistance, &localHit) && localHit.distance < maxDistance) {
maxDistance = localHit.distance;
*contact = localHit;

View file

@ -892,7 +892,7 @@ int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* player
if (!sceneDetermineSurfaceMapping(scene, hit.object, &mappingRange, &relativeIndex)) {
if (!just_checking) {
effectsSplashPlay(&scene->effects, &gFailPortalSplash, &hit.at, &hit.normal);
effectsSplashPlay(&scene->effects, &gFailPortalSplash[portalIndex], &hit.at, &hit.normal);
}
return 0;
}
@ -932,7 +932,7 @@ int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* player
}
if (!just_checking) {
effectsSplashPlay(&scene->effects, &gFailPortalSplash, &hit.at, &hit.normal);
effectsSplashPlay(&scene->effects, &gFailPortalSplash[portalIndex], &hit.at, &hit.normal);
}
return 0;