implemented skinned peds, no cutscene hands yet

This commit is contained in:
aap 2020-04-23 22:25:18 +02:00
parent 6467e2003a
commit f03b4eec4c
49 changed files with 1869 additions and 301 deletions

View file

@ -3,16 +3,15 @@
#include "Timecycle.h"
#include "skeleton.h"
#if defined(RWLIBS) && !defined(FINAL)
#include "Debug.h"
#ifndef FINAL
#include "rtcharse.h"
#pragma comment( lib, "rtcharse.lib" )
RtCharset *debugCharset;
#endif
void CreateDebugFont()
{
#if defined(RWLIBS) && !defined(FINAL)
#ifndef FINAL
RwRGBA color = { 255, 255, 128, 255 };
RwRGBA colorbg = { 0, 0, 0, 0 };
RtCharsetOpen();
@ -22,7 +21,7 @@ void CreateDebugFont()
void DestroyDebugFont()
{
#if defined(RWLIBS) && !defined(FINAL)
#ifndef FINAL
RtCharsetDestroy(debugCharset);
RtCharsetClose();
#endif
@ -30,14 +29,14 @@ void DestroyDebugFont()
void ObrsPrintfString(const char *str, short x, short y)
{
#if defined(RWLIBS) && !defined(FINAL)
RtCharsetPrintBuffered(debugCharset, str, x, y, true);
#ifndef FINAL
RtCharsetPrintBuffered(debugCharset, str, x*8, y*16, true);
#endif
}
void FlushObrsPrintfs()
{
#if defined(RWLIBS) && !defined(FINAL)
#ifndef FINAL
RtCharsetBufferFlush();
#endif
}
@ -168,6 +167,170 @@ GetFirstTexture(RwTexDictionary *txd)
return tex;
}
#ifdef PED_SKIN
static RpAtomic*
isSkinnedCb(RpAtomic *atomic, void *data)
{
RpAtomic **pAtomic = (RpAtomic**)data;
if(*pAtomic)
return nil; // already found one
if(RpSkinGeometryGetSkin(atomic->geometry))
*pAtomic = atomic; // we could just return nil here directly...
return atomic;
}
RpAtomic*
IsClumpSkinned(RpClump *clump)
{
RpAtomic *atomic = nil;
RpClumpForAllAtomics(clump, isSkinnedCb, &atomic);
return atomic;
}
static RpAtomic*
GetAnimHierarchyCallback(RpAtomic *atomic, void *data)
{
*(RpHAnimHierarchy**)data = RpSkinAtomicGetHAnimHierarchy(atomic);
return nil;
}
RpHAnimHierarchy*
GetAnimHierarchyFromSkinClump(RpClump *clump)
{
RpHAnimHierarchy *hier = nil;
RpClumpForAllAtomics(clump, GetAnimHierarchyCallback, &hier);
return hier;
}
static RwFrame*
GetAnimHierarchyFromClumpCB(RwFrame *frame, void *data)
{
RpHAnimHierarchy *hier = RpHAnimFrameGetHierarchy(frame);
if(hier){
*(RpHAnimHierarchy**)data = hier;
return nil;
}
RwFrameForAllChildren(frame, GetAnimHierarchyFromClumpCB, data);
return frame;
}
RpHAnimHierarchy*
GetAnimHierarchyFromClump(RpClump *clump)
{
RpHAnimHierarchy *hier = nil;
RwFrameForAllChildren(RpClumpGetFrame(clump), GetAnimHierarchyFromClumpCB, &hier);
return hier;
}
RwFrame*
GetHierarchyFromChildNodesCB(RwFrame *frame, void *data)
{
RpHAnimHierarchy **pHier = (RpHAnimHierarchy**)data;
RpHAnimHierarchy *hier = RpHAnimFrameGetHierarchy(frame);
if(hier == nil)
RwFrameForAllChildren(frame, GetHierarchyFromChildNodesCB, &hier);
*pHier = hier;
return nil;
}
void
SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable)
{
int i, parent;
RpAtomic *atomic;
RpSkin *skin;
RpHAnimHierarchy *hier;
int numBones;
RwMatrix m, invmat;
int stack[32];
int sp;
if(boneTable == nil)
return;
// atomic = GetFirstAtomic(clump); // mobile, also VC
atomic = IsClumpSkinned(clump); // xbox, seems safer
assert(atomic);
skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
assert(skin);
hier = GetAnimHierarchyFromSkinClump(clump);
assert(hier);
boneTable[0].x = 0.0f;
boneTable[0].y = 0.0f;
boneTable[0].z = 0.0f;
numBones = RpSkinGetNumBones(skin);
parent = 0;
sp = 0;
#ifdef FIX_BUGS
stack[0] = 0; // i think this is ok
#endif
for(i = 1; i < numBones; i++){
RwMatrixCopy(&m, &RpSkinGetSkinToBoneMatrices(skin)[i]);
RwMatrixInvert(&invmat, &m);
const RwMatrix *x = RpSkinGetSkinToBoneMatrices(skin);
RwV3dTransformPoints(&boneTable[i], &invmat.pos, 1, &x[parent]);
if(HIERNODEINFO(hier)[i].flags & rpHANIMPUSHPARENTMATRIX)
stack[++sp] = parent;
if(HIERNODEINFO(hier)[i].flags & rpHANIMPOPPARENTMATRIX)
parent = stack[sp--];
else
parent = i;
assert(parent >= 0 && parent < numBones);
}
}
RpHAnimAnimation*
HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier)
{
int i;
#ifdef FIX_BUGS
int numNodes = hier->numNodes*2; // you're supposed to have at least two KFs per node
#else
int numNodes = hier->numNodes;
#endif
RpHAnimAnimation *anim = RpHAnimAnimationCreate(rpHANIMSTDKEYFRAMETYPEID, numNodes, 0, 0.0f);
if(anim == nil)
return nil;
RpHAnimStdKeyFrame *frame = (RpHAnimStdKeyFrame*)HANIMFRAMES(anim);
for(i = 0; i < numNodes; i++){
frame->q.real = 1.0f;
frame->q.imag.x = frame->q.imag.y = frame->q.imag.z = 0.0f;
frame->t.x = frame->t.y = frame->t.z = 0.0f;
frame->time = 0.0f;
frame->prevFrame = nil;
frame++;
}
return anim;
}
void
RenderSkeleton(RpHAnimHierarchy *hier)
{
int i;
int sp;
int stack[32];
int par;
CVector p1, p2;
int numNodes = hier->numNodes;
RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
p1 = mats[0].pos;
par = 0;
sp = 0;
stack[sp++] = par;
for(i = 1; i < numNodes; i++){
p1 = mats[par].pos;
p2 = mats[i].pos;
CDebug::AddLine(p1, p2, 0xFFFFFFFF, 0xFFFFFFFF);
if(HIERNODEINFO(hier)[i].flags & rpHANIMPUSHPARENTMATRIX)
stack[sp++] = par;
par = i;
if(HIERNODEINFO(hier)[i].flags & rpHANIMPOPPARENTMATRIX)
par = stack[--sp];
}
}
#endif
void
CameraSize(RwCamera * camera, RwRect * rect,
RwReal viewWindow, RwReal aspectRatio)