diff options
Diffstat (limited to 'src/rw/RwHelper.cpp')
-rw-r--r-- | src/rw/RwHelper.cpp | 183 |
1 files changed, 128 insertions, 55 deletions
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 35593722..25cd2eef 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -2,7 +2,6 @@ #include "common.h" #include <rpskin.h> -#include "RwHelper.h" #include "Timecycle.h" #include "skeleton.h" #include "Debug.h" @@ -77,7 +76,7 @@ DefinedState(void) RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RwRenderStateSet(rwRENDERSTATEALPHAPRIMITIVEBUFFER, (void*)FALSE); + //RwRenderStateSet(rwRENDERSTATEALPHAPRIMITIVEBUFFER, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEBORDERCOLOR, (void*)RWRGBALONG(0, 0, 0, 255)); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEFOGCOLOR, @@ -87,22 +86,13 @@ DefinedState(void) #ifdef LIBRW rw::SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL); + rw::SetRenderState(rw::ALPHATESTREF, 3); rw::SetRenderState(rw::GSALPHATEST, gPS2alphaTest); #else // D3D stuff RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); -#endif - SetAlphaRef(2); -} - -void -SetAlphaRef(int ref) -{ -#ifdef LIBRW - rw::SetRenderState(rw::ALPHATESTREF, ref+1); -#else - RwD3D8SetRenderState(D3DRS_ALPHAREF, ref); + RwD3D8SetRenderState(D3DRS_ALPHAREF, 2); #endif } @@ -213,24 +203,11 @@ 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(RpAtomicGetGeometry(atomic))) - *pAtomic = atomic; // we could just return nil here directly... - return atomic; -} - -RpAtomic* +bool IsClumpSkinned(RpClump *clump) { - RpAtomic *atomic = nil; - RpClumpForAllAtomics(clump, isSkinnedCb, &atomic); - return atomic; + RpAtomic *atomic = GetFirstAtomic(clump); + return atomic ? RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic)) : nil; } static RpAtomic* @@ -268,17 +245,6 @@ GetAnimHierarchyFromClump(RpClump *clump) 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) { @@ -294,8 +260,7 @@ SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable) if(boneTable == nil) return; -// atomic = GetFirstAtomic(clump); // mobile, also VC - atomic = IsClumpSkinned(clump); // xbox, seems safer + atomic = GetFirstAtomic(clump); // mobile, also VC assert(atomic); skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic)); assert(skin); @@ -382,7 +347,125 @@ RenderSkeleton(RpHAnimHierarchy *hier) par = stack[--sp]; } } -#endif + + +RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset) +{ + RwIm2DVertex vx[4]; + + /* + * Render an opaque white 2D quad at the given coordinates and + * spanning a whole texture. + */ + + RwIm2DVertexSetScreenX(&vx[0], x1); + RwIm2DVertexSetScreenY(&vx[0], y1); + RwIm2DVertexSetScreenZ(&vx[0], z); + RwIm2DVertexSetIntRGBA(&vx[0], 255, 255, 255, 255); + RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ); + RwIm2DVertexSetU(&vx[0], uvOffset, recipCamZ); + RwIm2DVertexSetV(&vx[0], uvOffset, recipCamZ); + + RwIm2DVertexSetScreenX(&vx[1], x1); + RwIm2DVertexSetScreenY(&vx[1], y2); + RwIm2DVertexSetScreenZ(&vx[1], z); + RwIm2DVertexSetIntRGBA(&vx[1], 255, 255, 255, 255); + RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ); + RwIm2DVertexSetU(&vx[1], uvOffset, recipCamZ); + RwIm2DVertexSetV(&vx[1], 1.0f + uvOffset, recipCamZ); + + RwIm2DVertexSetScreenX(&vx[2], x2); + RwIm2DVertexSetScreenY(&vx[2], y1); + RwIm2DVertexSetScreenZ(&vx[2], z); + RwIm2DVertexSetIntRGBA(&vx[2], 255, 255, 255, 255); + RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ); + RwIm2DVertexSetU(&vx[2], 1.0f + uvOffset, recipCamZ); + RwIm2DVertexSetV(&vx[2], uvOffset, recipCamZ); + + RwIm2DVertexSetScreenX(&vx[3], x2); + RwIm2DVertexSetScreenY(&vx[3], y2); + RwIm2DVertexSetScreenZ(&vx[3], z); + RwIm2DVertexSetIntRGBA(&vx[3], 255, 255, 255, 255); + RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ); + RwIm2DVertexSetU(&vx[3], 1.0f + uvOffset, recipCamZ); + RwIm2DVertexSetV(&vx[3], 1.0f + uvOffset, recipCamZ); + + RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4); + + return TRUE; +} + +bool b_cbsUseLTM = true; + +RpAtomic *cbsCalcMeanBSphereRadiusCB(RpAtomic *atomic, void *data) +{ + RwV3d atomicPos; + + if ( b_cbsUseLTM ) + RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump))); + else + RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump))); + + RwV3d temp; + RwV3dSub(&temp, &atomicPos, &((RwSphere *)data)->center); + RwReal radius = RwV3dLength(&temp) + RpAtomicGetBoundingSphere(atomic)->radius; + + if ( ((RwSphere *)data)->radius < radius ) + ((RwSphere *)data)->radius = radius; + + return atomic; +} + +RpAtomic *cbsCalcMeanBSphereCenterCB(RpAtomic *atomic, void *data) +{ + RwV3d atomicPos; + + if ( b_cbsUseLTM ) + RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump))); + else + RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump))); + + RwV3dAdd(&((RwSphere *)data)->center, &((RwSphere *)data)->center, &atomicPos); + + return atomic; +} + +RpClump *RpClumpGetBoundingSphere(RpClump *clump, RwSphere *sphere, bool useLTM) +{ + RwMatrix matrix; + RwSphere result = { 0.0f, 0.0f, 0.0f, 0.0f }; + + b_cbsUseLTM = useLTM; + + if ( clump == nil || sphere == nil ) + return nil; + + sphere->radius = 0.0f; + sphere->center.x = 0.0f; + sphere->center.y = 0.0f; + sphere->center.z = 0.0f; + + RwInt32 numAtomics = RpClumpGetNumAtomics(clump); + if ( numAtomics < 1.0f ) + return nil; + + RpClumpForAllAtomics(clump, cbsCalcMeanBSphereCenterCB, &result); + + RwV3dScale(&result.center, &result.center, 1.0f/numAtomics); + + RpClumpForAllAtomics(clump, cbsCalcMeanBSphereRadiusCB, &result); + + if ( b_cbsUseLTM ) + RwMatrixInvert(&matrix, RwFrameGetLTM(RpClumpGetFrame(clump))); + else + RwMatrixInvert(&matrix, RwFrameGetMatrix(RpClumpGetFrame(clump))); + + RwV3dTransformPoints(&result.center, &result.center, 1, &matrix); + + *sphere = result; + + return clump; +} void CameraSize(RwCamera * camera, RwRect * rect, @@ -495,7 +578,7 @@ CameraSize(RwCamera * camera, RwRect * rect, #else raster = RwCameraGetRaster(camera); zRaster = RwCameraGetZRaster(camera); - + raster->width = zRaster->width = rect->w; raster->height = zRaster->height = rect->h; #endif @@ -636,16 +719,6 @@ findPlatform(rw::Atomic *a) return 0; } -// in CVehicleModelInfo in VC -static RpMaterial* -GetMatFXEffectMaterialCB(RpMaterial *material, void *data) -{ - if(RpMatFXMaterialGetEffects(material) == rpMATFXEFFECTNULL) - return material; - *(int*)data = RpMatFXMaterialGetEffects(material); - return nil; -} - // Game doesn't read atomic extensions so we never get any other than the default pipe, // but we need it for uninstancing void @@ -655,7 +728,7 @@ attachPipe(rw::Atomic *atomic) atomic->pipeline = rw::skinGlobals.pipelines[rw::platform]; else{ int fx = rpMATFXEFFECTNULL; - RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), GetMatFXEffectMaterialCB, &fx); + RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), CVehicleModelInfo::GetMatFXEffectMaterialCB, &fx); if(fx != rpMATFXEFFECTNULL) RpMatFXAtomicEnableEffects(atomic); } |