added simple demoreel and ps2 skeleton coded by claude fable 5

This commit is contained in:
aap
2026-08-09 01:39:54 +02:00
parent 92851aa1ed
commit 0a7eb48ce3
18 changed files with 1482 additions and 9 deletions
+155
View File
@@ -0,0 +1,155 @@
#include <math.h>
#include "demoreel.h"
// Classic endless tunnel: fly along a wobbling closed loop,
// vertices regenerated on the CPU every frame, im3d rendering.
using namespace rw;
#define SIDES 16
#define RINGS 48
#define NUMVERTS ((SIDES+1)*(RINGS+1))
#define NUMINDICES (SIDES*RINGS*6)
#define LOOPRADIUS 60.0f
static RWDEVICE::Im3DVertex tunnelVerts[NUMVERTS];
static uint16 tunnelIndices[NUMINDICES];
static Texture *gridTex;
static Matrix identMat;
static float pathPos;
// closed loop in space with some vertical wobble
static V3d
tunnelPath(float s)
{
V3d p;
p.x = LOOPRADIUS*cosf(s) + 8.0f*cosf(3.0f*s);
p.y = LOOPRADIUS*sinf(s) + 8.0f*sinf(2.0f*s);
p.z = 14.0f*sinf(2.0f*s) + 5.0f*sinf(5.0f*s);
return p;
}
static float
tunnelRadius(float s)
{
return 6.0f + 1.5f*sinf(5.0f*s + DemoTime*2.0f);
}
static void
pathFrame(float s, V3d *pos, V3d *t, V3d *n, V3d *b)
{
static V3d worldup = { 0.0f, 0.0f, 1.0f };
*pos = tunnelPath(s);
*t = normalize(sub(tunnelPath(s+0.01f), *pos));
*n = normalize(cross(worldup, *t));
*b = cross(*t, *n);
}
static void
TunnelInit(void)
{
int i, j, v;
gridTex = MakeGridTexture();
identMat.setIdentity();
pathPos = 0.0f;
v = 0;
for(i = 0; i < RINGS; i++)
for(j = 0; j < SIDES; j++){
int r0 = i*(SIDES+1) + j;
int r1 = (i+1)*(SIDES+1) + j;
tunnelIndices[v++] = r0;
tunnelIndices[v++] = r1;
tunnelIndices[v++] = r0+1;
tunnelIndices[v++] = r0+1;
tunnelIndices[v++] = r1;
tunnelIndices[v++] = r1+1;
}
}
static void
TunnelTerm(void)
{
if(gridTex){
gridTex->destroy();
gridTex = nil;
}
}
static void
TunnelUpdate(float dt)
{
pathPos += dt*0.30f;
// camera rides the tunnel, slightly off center
V3d pos, t, n, b;
pathFrame(pathPos, &pos, &t, &n, &b);
V3d target = tunnelPath(pathPos + 0.15f);
pos = add(pos, scale(b, -1.5f*sinf(DemoTime*0.7f)));
pos = add(pos, scale(n, 1.5f*cosf(DemoTime*0.5f)));
LookAt(Scene.camera->getFrame(), pos, target);
// rebuild the tube
float ds = 0.028f;
float hue = DemoTime*0.03f;
// V texcoords must stay small: the GS wraps texel
// coordinates beyond ~1024, so shift out the integer part
float vscale = 4.0f;
float vbase = floorf(pathPos*vscale);
int i, j, v;
v = 0;
for(i = 0; i <= RINGS; i++){
float s = pathPos - ds + i*ds;
V3d c, tt, nn, bb;
pathFrame(s, &c, &tt, &nn, &bb);
float rad = tunnelRadius(s);
// brightness: fade out towards the far end, pulses running along
float fade = 1.0f - (float)i/RINGS;
fade = fade*fade;
float pulse = 0.55f + 0.45f*sinf(s*18.0f - DemoTime*6.0f);
float bright = fade*(0.35f + 0.65f*pulse);
RGBA col = HSV(hue + s*0.02f, 0.55f, bright, 255);
float twist = DemoTime*0.4f;
for(j = 0; j <= SIDES; j++){
float a = (float)j/SIDES*2.0f*3.14159265f + twist;
V3d p = add(c, add(scale(nn, rad*cosf(a)), scale(bb, rad*sinf(a))));
RWDEVICE::Im3DVertex *vert = &tunnelVerts[v++];
vert->setX(p.x);
vert->setY(p.y);
vert->setZ(p.z);
vert->setU((float)j/SIDES*4.0f);
vert->setV(s*vscale - vbase);
vert->setColor(col.red, col.green, col.blue, col.alpha);
}
}
}
static void
TunnelRender(void)
{
SetRenderState(ZTESTENABLE, 1);
SetRenderState(ZWRITEENABLE, 1);
SetRenderState(SRCBLEND, BLENDSRCALPHA);
SetRenderState(DESTBLEND, BLENDINVSRCALPHA);
SetRenderState(CULLMODE, CULLNONE);
SetRenderState(TEXTUREFILTER, Texture::LINEAR);
SetRenderStatePtr(TEXTURERASTER, gridTex ? gridTex->raster : nil);
im3d::Transform(tunnelVerts, NUMVERTS, &identMat, im3d::VERTEXUV|im3d::ALLOPAQUE);
im3d::RenderIndexedPrimitive(PRIMTYPETRILIST, tunnelIndices, NUMINDICES);
im3d::End();
}
DemoScene TunnelScene = {
"Tunnel",
TunnelInit,
TunnelTerm,
TunnelUpdate,
TunnelRender
};