summaryrefslogtreecommitdiffstats
path: root/src/rw
diff options
context:
space:
mode:
Diffstat (limited to 'src/rw')
-rw-r--r--src/rw/RwHelper.cpp179
-rw-r--r--src/rw/RwHelper.h9
-rw-r--r--src/rw/VisibilityPlugins.cpp15
-rw-r--r--src/rw/VisibilityPlugins.h3
4 files changed, 198 insertions, 8 deletions
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index acf811ad..5aa4475f 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -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)
diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h
index 5b47cb6f..9f178ec2 100644
--- a/src/rw/RwHelper.h
+++ b/src/rw/RwHelper.h
@@ -13,6 +13,15 @@ RwObject *GetFirstObject(RwFrame *frame);
RpAtomic *GetFirstAtomic(RpClump *clump);
RwTexture *GetFirstTexture(RwTexDictionary *txd);
+#ifdef PED_SKIN
+RpAtomic *IsClumpSkinned(RpClump *clump);
+RpHAnimHierarchy *GetAnimHierarchyFromSkinClump(RpClump *clump); // get from atomic
+RpHAnimHierarchy *GetAnimHierarchyFromClump(RpClump *clump); // get from frame
+RwFrame *GetHierarchyFromChildNodesCB(RwFrame *frame, void *data);
+void SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable);
+RpHAnimAnimation *HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier);
+#endif
+
RwTexDictionary *RwTexDictionaryGtaStreamRead(RwStream *stream);
RwTexDictionary *RwTexDictionaryGtaStreamRead1(RwStream *stream);
RwTexDictionary *RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict);
diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp
index 89bd13a6..7dc27f48 100644
--- a/src/rw/VisibilityPlugins.cpp
+++ b/src/rw/VisibilityPlugins.cpp
@@ -543,6 +543,21 @@ CVisibilityPlugins::RenderPedHiDetailCB(RpAtomic *atomic)
return atomic;
}
+// This is needed for peds with only one clump, i.e. skinned models
+// strangely even the xbox version has no such thing
+RpAtomic*
+CVisibilityPlugins::RenderPedCB(RpAtomic *atomic)
+{
+ int32 alpha;
+
+ alpha = GetClumpAlpha(RpAtomicGetClump(atomic));
+ if(alpha == 255)
+ AtomicDefaultRenderCallBack(atomic);
+ else
+ RenderAlphaAtomic(atomic, alpha);
+ return atomic;
+}
+
float
CVisibilityPlugins::GetDistanceSquaredFromCamera(RwFrame *frame)
{
diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h
index 63bc95e4..b367d7ee 100644
--- a/src/rw/VisibilityPlugins.h
+++ b/src/rw/VisibilityPlugins.h
@@ -63,6 +63,7 @@ public:
static RpAtomic *RenderPlayerCB(RpAtomic *atomic);
static RpAtomic *RenderPedLowDetailCB(RpAtomic *atomic);
static RpAtomic *RenderPedHiDetailCB(RpAtomic *atomic);
+ static RpAtomic *RenderPedCB(RpAtomic *atomic); // for skinned models with only one clump
static void RenderAlphaAtomics(void);
static void RenderFadingEntities(void);
@@ -131,3 +132,5 @@ public:
static bool PluginAttach(void);
};
+
+RpMaterial *SetAlphaCB(RpMaterial *material, void *data);