|
|
|
|
@@ -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)
|
|
|
|
|
|