Finish up portal trail effect
This commit is contained in:
parent
65eebe53d3
commit
55fa62c57e
|
@ -1146,7 +1146,7 @@ materials:
|
|||
|
||||
gDPSetCombineMode:
|
||||
color: ["1", "PRIMITIVE", "TEXEL0", "PRIMITIVE"]
|
||||
alpha: ["TEXEL0", "0", "SHADE", "0"]
|
||||
alpha: ["TEXEL0", "PRIMITIVE", "SHADE", "0"]
|
||||
gSPGeometryMode:
|
||||
clear: [G_CULL_BACK, G_CULL_FRONT, G_ZBUFFER]
|
||||
set: [G_FOG]
|
|
@ -1 +1 @@
|
|||
-m assets/materials/static.skm.yaml --rotate 0,0,0 --sort-dir 0,1,0 --default-material brightglow_y
|
||||
-m assets/materials/static.skm.yaml --default-material portal_trail
|
|
@ -1,41 +1,81 @@
|
|||
#include "portal_trail.h"
|
||||
|
||||
#include "../math/vector2.h"
|
||||
#include "../math/mathf.h"
|
||||
#include "../defs.h"
|
||||
|
||||
#include "../build/assets/models/portal_gun/ball_trail.h"
|
||||
#include "../build/assets/materials/static.h"
|
||||
#include "../graphics/color.h"
|
||||
|
||||
#include "../util/time.h"
|
||||
|
||||
#define TRAIL_LENGTH 8.0f
|
||||
#define FADE_IN_LENGTH 4.0f
|
||||
#define SEGMENT_LENGTH 2.0f
|
||||
#define SEGMENT_ROTATION (152 * M_PI / 180.0f)
|
||||
|
||||
struct Transform gTrailSectionOffset = {
|
||||
{0.0f, 0.0f, -8.0f},
|
||||
{0.0f, 0.0f, -SEGMENT_LENGTH},
|
||||
{0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{1.0f, 1.0f, 1.0f},
|
||||
};
|
||||
|
||||
void portalTrailInit(struct PortalTrail* trail) {
|
||||
quatAxisAngle(&gForward, SEGMENT_ROTATION, &gTrailSectionOffset.rotation);
|
||||
transformToMatrixL(&gTrailSectionOffset, &trail->sectionOffset, SCENE_SCALE);
|
||||
guMtxIdent(&trail->baseTransform[0]);
|
||||
guMtxIdent(&trail->baseTransform[1]);
|
||||
|
||||
trail->currentBaseTransform = 0;
|
||||
trail->lastDistance = 0.0f;
|
||||
trail->maxDistance = -TRAIL_LENGTH;
|
||||
}
|
||||
|
||||
void portalTrailUpdateBaseTransform(struct PortalTrail* trail) {
|
||||
trail->currentBaseTransform ^= 1;
|
||||
transformToMatrixL(&trail->trailTransform, &trail->baseTransform[trail->currentBaseTransform], SCENE_SCALE);
|
||||
osWritebackDCache(&trail->baseTransform[trail->currentBaseTransform], sizeof(Mtx));
|
||||
}
|
||||
|
||||
void portalTrailPlay(struct PortalTrail* trail, struct Vector3* from, struct Vector3* to) {
|
||||
trail->trailTransform.position = *from;
|
||||
struct Vector3 dir;
|
||||
vector3Sub(to, from, &dir);
|
||||
quatLook(&dir, &gUp, &trail->trailTransform.rotation);
|
||||
struct Vector3 randomUp;
|
||||
randomUp.x = randomInRangef(-1.0f, 1.0f);
|
||||
randomUp.y = randomInRangef(-1.0f, 1.0f);
|
||||
randomUp.z = randomInRangef(-1.0f, 1.0f);
|
||||
quatLook(&dir, &randomUp, &trail->trailTransform.rotation);
|
||||
vector3Normalize(&dir, &trail->direction);
|
||||
trail->trailTransform.scale = gOneVec;
|
||||
|
||||
trail->currentBaseTransform ^= 1;
|
||||
portalTrailUpdateBaseTransform(trail);
|
||||
|
||||
transformToMatrixL(&trail->trailTransform, &trail->baseTransform[trail->currentBaseTransform], SCENE_SCALE);
|
||||
osWritebackDCache(&trail->baseTransform[trail->currentBaseTransform], sizeof(Mtx));
|
||||
trail->lastDistance = 0.0f;
|
||||
trail->maxDistance = vector3Dot(&dir, &trail->direction);
|
||||
|
||||
if (trail->maxDistance < SEGMENT_LENGTH) {
|
||||
trail->maxDistance = -TRAIL_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
void portalTrailUpdate(struct PortalTrail* trail, float distance) {
|
||||
void portalTrailUpdate(struct PortalTrail* trail) {
|
||||
if (trail->lastDistance >= trail->maxDistance + TRAIL_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
trail->lastDistance += FIXED_DELTA_TIME * PORTAL_PROJECTILE_SPEED;
|
||||
|
||||
if (trail->lastDistance > TRAIL_LENGTH + SEGMENT_LENGTH) {
|
||||
trail->lastDistance -= SEGMENT_LENGTH;
|
||||
trail->maxDistance -= SEGMENT_LENGTH;
|
||||
|
||||
struct Transform tmp;
|
||||
transformConcat(&trail->trailTransform, &gTrailSectionOffset, &tmp);
|
||||
trail->trailTransform = tmp;
|
||||
portalTrailUpdateBaseTransform(trail);
|
||||
}
|
||||
}
|
||||
|
||||
struct Coloru8 gTrailColor[] = {
|
||||
|
@ -43,16 +83,73 @@ struct Coloru8 gTrailColor[] = {
|
|||
{50, 70, 200, 255},
|
||||
};
|
||||
|
||||
void portalTrailRender(struct PortalTrail* trail, struct RenderState* renderState, struct MaterialState* materialState) {
|
||||
void portalTrailRender(struct PortalTrail* trail, struct RenderState* renderState, struct MaterialState* materialState, struct Camera* fromCamera, int portalIndex) {
|
||||
if (trail->lastDistance >= trail->maxDistance + TRAIL_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
materialStateSet(materialState, PORTAL_TRAIL_INDEX, renderState);
|
||||
|
||||
struct Coloru8* color = &gTrailColor[0];
|
||||
gSPFogPosition(renderState->dl++, 800, 999);
|
||||
gDPSetPrimColor(renderState->dl++, 255, 255, color->r, color->g, color->b, color->a);
|
||||
struct Coloru8* color = &gTrailColor[portalIndex];
|
||||
|
||||
struct Ray cameraRay;
|
||||
cameraRay.origin = fromCamera->transform.position;
|
||||
quatMultVector(&fromCamera->transform.rotation, &gForward, &cameraRay.dir);
|
||||
vector3Negate(&cameraRay.dir, &cameraRay.dir);
|
||||
|
||||
struct Vector3 pointAlongTrail;
|
||||
vector3AddScaled(&trail->trailTransform.position, &trail->direction, trail->lastDistance - TRAIL_LENGTH, &pointAlongTrail);
|
||||
int minDistance = fogIntValue(cameraClipDistance(fromCamera, rayDetermineDistance(&cameraRay, &pointAlongTrail)));
|
||||
|
||||
vector3AddScaled(&trail->trailTransform.position, &trail->direction, trail->lastDistance, &pointAlongTrail);
|
||||
int maxDistance = fogIntValue(cameraClipDistance(fromCamera, rayDetermineDistance(&cameraRay, &pointAlongTrail)));
|
||||
|
||||
if (maxDistance <= minDistance) {
|
||||
maxDistance = minDistance + 1;
|
||||
|
||||
if (maxDistance > 1000) {
|
||||
maxDistance = 1000;
|
||||
minDistance = 999;
|
||||
}
|
||||
}
|
||||
|
||||
float currentDistance = trail->lastDistance - TRAIL_LENGTH;
|
||||
|
||||
int alpha = 0;
|
||||
|
||||
if (currentDistance < -(TRAIL_LENGTH - FADE_IN_LENGTH)) {
|
||||
alpha = (int)(((TRAIL_LENGTH - FADE_IN_LENGTH) + currentDistance) * (-255.0f / TRAIL_LENGTH));
|
||||
|
||||
if (alpha < 0) {
|
||||
alpha = 0;
|
||||
}
|
||||
|
||||
if (alpha > 255) {
|
||||
alpha = 255;
|
||||
}
|
||||
}
|
||||
|
||||
gSPFogPosition(renderState->dl++, minDistance, maxDistance);
|
||||
gDPSetPrimColor(renderState->dl++, 255, 255, color->r, color->g, color->b, alpha);
|
||||
gSPMatrix(renderState->dl++, &trail->baseTransform[trail->currentBaseTransform], G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
|
||||
|
||||
gSPDisplayList(renderState->dl++, portal_gun_ball_trail_model_gfx);
|
||||
int hasMore = 1;
|
||||
|
||||
while (hasMore) {
|
||||
currentDistance += SEGMENT_LENGTH;
|
||||
|
||||
hasMore = currentDistance < trail->lastDistance && currentDistance < trail->maxDistance;
|
||||
|
||||
if (currentDistance <= 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gSPDisplayList(renderState->dl++, portal_gun_ball_trail_model_gfx);
|
||||
|
||||
if (hasMore) {
|
||||
gSPMatrix(renderState->dl++, &trail->sectionOffset, G_MTX_MODELVIEW | G_MTX_NOPUSH | G_MTX_MUL);
|
||||
}
|
||||
}
|
||||
|
||||
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
||||
}
|
|
@ -8,18 +8,23 @@
|
|||
#include "../math/transform.h"
|
||||
#include "../graphics/renderstate.h"
|
||||
#include "../levels/material_state.h"
|
||||
#include "../scene/camera.h"
|
||||
|
||||
#define PORTAL_PROJECTILE_SPEED 50.0f
|
||||
|
||||
struct PortalTrail {
|
||||
struct Transform trailTransform;
|
||||
Mtx sectionOffset;
|
||||
Mtx baseTransform[2];
|
||||
struct Vector3 chunkOffset;
|
||||
struct Vector3 direction;
|
||||
short currentBaseTransform;
|
||||
float lastDistance;
|
||||
float maxDistance;
|
||||
};
|
||||
|
||||
void portalTrailInit(struct PortalTrail* trail);
|
||||
void portalTrailPlay(struct PortalTrail* trail, struct Vector3* from, struct Vector3* to);
|
||||
void portalTrailUpdate(struct PortalTrail* trail, float distance);
|
||||
void portalTrailRender(struct PortalTrail* trail, struct RenderState* renderState, struct MaterialState* materialState);
|
||||
void portalTrailUpdate(struct PortalTrail* trail);
|
||||
void portalTrailRender(struct PortalTrail* trail, struct RenderState* renderState, struct MaterialState* materialState, struct Camera* fromCamera, int portalIndex);
|
||||
|
||||
#endif
|
|
@ -194,4 +194,16 @@ float cameraClipDistance(struct Camera* camera, float distance) {
|
|||
}
|
||||
|
||||
return -((camera->nearPlane + camera->farPlane) * modifiedDistance + 2.0f * camera->nearPlane * camera->farPlane) / denom;
|
||||
}
|
||||
|
||||
int fogIntValue(float floatValue) {
|
||||
if (floatValue < -1.0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (floatValue > 1.0) {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
return (int)((floatValue + 1.0f) * 500.0f);
|
||||
}
|
|
@ -47,4 +47,6 @@ int cameraApplyMatrices(struct RenderState* renderState, struct CameraMatrixInfo
|
|||
|
||||
float cameraClipDistance(struct Camera* camera, float distance);
|
||||
|
||||
int fogIntValue(float floatValue);
|
||||
|
||||
#endif
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#define PORTAL_GUN_RECOIL_TIME (0.18f)
|
||||
|
||||
#define PORTAL_GUN_NEAR_PLANE 0.05f
|
||||
|
||||
struct Vector2 gGunColliderEdgeVectors[] = {
|
||||
{0.0f, 1.0f},
|
||||
{0.707f, 0.707f},
|
||||
|
@ -108,20 +110,20 @@ void portalBallRender(struct PortalGunProjectile* projectile, struct RenderState
|
|||
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Transform* fromView) {
|
||||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera) {
|
||||
struct MaterialState materialState;
|
||||
materialStateInit(&materialState, DEFAULT_INDEX);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
struct PortalGunProjectile* projectile = &portalGun->projectiles[i];
|
||||
|
||||
portalTrailRender(&projectile->trail, renderState, &materialState);
|
||||
portalTrailRender(&projectile->trail, renderState, &materialState, fromCamera, i);
|
||||
|
||||
if (projectile->roomIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
portalBallRender(projectile, renderState, &materialState, fromView, i);
|
||||
portalBallRender(projectile, renderState, &materialState, &fromCamera->transform, i);
|
||||
}
|
||||
|
||||
portalGun->rigidBody.transform.scale = gOneVec;
|
||||
|
@ -131,6 +133,8 @@ void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* render
|
|||
return;
|
||||
}
|
||||
|
||||
cameraModifyProjectionViewForPortalGun(fromCamera, renderState, PORTAL_GUN_NEAR_PLANE * SCENE_SCALE, (float)SCREEN_WD / (float)SCREEN_HT);
|
||||
|
||||
transformToMatrixL(&portalGun->rigidBody.transform, matrix, SCENE_SCALE);
|
||||
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
|
||||
gSPDisplayList(renderState->dl++, portal_gun_v_portalgun_model_gfx);
|
||||
|
@ -138,7 +142,6 @@ void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* render
|
|||
}
|
||||
|
||||
#define NO_HIT_DISTANCE 20.0f
|
||||
#define PORTAL_PROJECTILE_SPEED 50.0f
|
||||
#define MAX_PROJECTILE_DISTANCE 100.0f
|
||||
|
||||
void portalGunUpdate(struct PortalGun* portalGun, struct Player* player) {
|
||||
|
@ -163,6 +166,8 @@ void portalGunUpdate(struct PortalGun* portalGun, struct Player* player) {
|
|||
for (int i = 0; i < 2; ++i) {
|
||||
struct PortalGunProjectile* projectile = &portalGun->projectiles[i];
|
||||
|
||||
portalTrailUpdate(&projectile->trail);
|
||||
|
||||
if (projectile->roomIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../player/player.h"
|
||||
#include "../util/time.h"
|
||||
#include "../effects/portal_trail.h"
|
||||
#include "../scene/camera.h"
|
||||
|
||||
struct PortalGunProjectile {
|
||||
struct Ray positionDirection;
|
||||
|
@ -38,7 +39,7 @@ struct PortalGun {
|
|||
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, struct Transform* fromView);
|
||||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera);
|
||||
|
||||
void portalGunFire(struct PortalGun* portalGun, int portalIndex, struct Ray* ray, struct Vector3* playerUp, int roomIndex);
|
||||
|
||||
|
|
|
@ -471,18 +471,6 @@ void renderPlanBuild(struct RenderPlan* renderPlan, struct Scene* scene, struct
|
|||
#define MIN_FOG_DISTANCE 1.0f
|
||||
#define MAX_FOG_DISTANCE 2.5f
|
||||
|
||||
int fogIntValue(float floatValue) {
|
||||
if (floatValue < -1.0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (floatValue > 1.0) {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
return (int)((floatValue + 1.0f) * 500.0f);
|
||||
}
|
||||
|
||||
void renderPlanExecute(struct RenderPlan* renderPlan, struct Scene* scene, Mtx* staticTransforms, struct RenderState* renderState) {
|
||||
struct DynamicRenderDataList* dynamicList = dynamicRenderListNew(renderState, MAX_DYNAMIC_SCENE_OBJECTS);
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#define DEFAULT_FAR_PLANE 30.0f
|
||||
#define DEFAULT_NEAR_PLANE 0.125f
|
||||
#define PORTAL_GUN_NEAR_PLANE 0.05f
|
||||
|
||||
#define MAX_PORTAL_STEPS 6
|
||||
|
||||
|
|
|
@ -306,8 +306,7 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
|
|||
renderPlanExecute(&renderPlan, scene, staticMatrices, renderState);
|
||||
|
||||
if (scene->portalGun.portalGunVisible){
|
||||
cameraModifyProjectionViewForPortalGun(&scene->camera, renderState, PORTAL_GUN_NEAR_PLANE * SCENE_SCALE, renderPlan.stageProps[0].aspectRatio);
|
||||
portalGunRenderReal(&scene->portalGun, renderState, &scene->camera.transform);
|
||||
portalGunRenderReal(&scene->portalGun, renderState, &scene->camera);
|
||||
}
|
||||
|
||||
gDPPipeSync(renderState->dl++);
|
||||
|
|
Loading…
Reference in a new issue