CVisibilityPlugins

This commit is contained in:
aap 2020-05-11 22:21:18 +02:00
parent d4250fc2c7
commit 6e4710b717
6 changed files with 169 additions and 143 deletions

View File

@ -51,7 +51,9 @@ enum Config {
// Link list lengths // Link list lengths
NUMALPHALIST = 20, NUMALPHALIST = 20,
NUMALPHAENTITYLIST = 150, NUMBOATALPHALIST = 20,
NUMALPHAENTITYLIST = 200,
NUMALPHAUNTERWATERENTITYLIST = 30,
NUMCOLCACHELINKS = 200, NUMCOLCACHELINKS = 200,
NUMREFERENCES = 800, NUMREFERENCES = 800,

View File

@ -77,7 +77,7 @@ CEntity::CEntity(void)
bOffscreen = false; bOffscreen = false;
bIsStaticWaitingForCollision = false; bIsStaticWaitingForCollision = false;
m_flagE10 = false; m_flagE10 = false;
m_flagE20 = false; bUnderwater = false;
m_flagE40 = false; m_flagE40 = false;
m_scanCode = 0; m_scanCode = 0;

View File

@ -86,8 +86,8 @@ public:
uint32 m_flagE2 : 1; uint32 m_flagE2 : 1;
uint32 bOffscreen : 1; // offscreen flag. This can only be trusted when it is set to true uint32 bOffscreen : 1; // offscreen flag. This can only be trusted when it is set to true
uint32 bIsStaticWaitingForCollision : 1; // this is used by script created entities - they are static until the collision is loaded below them uint32 bIsStaticWaitingForCollision : 1; // this is used by script created entities - they are static until the collision is loaded below them
uint32 m_flagE10 : 1; uint32 m_flagE10 : 1; // probably bDontStream
uint32 m_flagE20 : 1; uint32 bUnderwater : 1; // this object is underwater change drawing order
uint32 m_flagE40 : 1; uint32 m_flagE40 : 1;
uint16 m_scanCode; uint16 m_scanCode;

View File

@ -35,7 +35,7 @@ enum eVehicleType {
}; };
enum { enum {
NUM_VEHICLE_POSITIONS = 10 NUM_VEHICLE_POSITIONS = 5
}; };
class CVehicleModelInfo : public CClumpModelInfo class CVehicleModelInfo : public CClumpModelInfo

View File

@ -4,15 +4,20 @@
#include "Entity.h" #include "Entity.h"
#include "ModelInfo.h" #include "ModelInfo.h"
#include "Lights.h" #include "Lights.h"
#include "RwHelper.h"
#include "Renderer.h" #include "Renderer.h"
#include "Camera.h" #include "Camera.h"
#include "VisibilityPlugins.h" #include "VisibilityPlugins.h"
#include "World.h" #include "World.h"
//--MIAMI: file done
#define FADE_DISTANCE 20.0f #define FADE_DISTANCE 20.0f
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaList; CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaList;
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaBoatAtomicList;
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaEntityList; CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaEntityList;
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaUnderwaterEntityList;
int32 CVisibilityPlugins::ms_atomicPluginOffset = -1; int32 CVisibilityPlugins::ms_atomicPluginOffset = -1;
int32 CVisibilityPlugins::ms_framePluginOffset = -1; int32 CVisibilityPlugins::ms_framePluginOffset = -1;
@ -26,7 +31,6 @@ float CVisibilityPlugins::ms_vehicleLod1Dist;
float CVisibilityPlugins::ms_vehicleFadeDist; float CVisibilityPlugins::ms_vehicleFadeDist;
float CVisibilityPlugins::ms_bigVehicleLod0Dist; float CVisibilityPlugins::ms_bigVehicleLod0Dist;
float CVisibilityPlugins::ms_bigVehicleLod1Dist; float CVisibilityPlugins::ms_bigVehicleLod1Dist;
float CVisibilityPlugins::ms_pedLod0Dist;
float CVisibilityPlugins::ms_pedLod1Dist; float CVisibilityPlugins::ms_pedLod1Dist;
float CVisibilityPlugins::ms_pedFadeDist; float CVisibilityPlugins::ms_pedFadeDist;
@ -36,6 +40,11 @@ CVisibilityPlugins::Initialise(void)
m_alphaList.Init(NUMALPHALIST); m_alphaList.Init(NUMALPHALIST);
m_alphaList.head.item.sort = 0.0f; m_alphaList.head.item.sort = 0.0f;
m_alphaList.tail.item.sort = 100000000.0f; m_alphaList.tail.item.sort = 100000000.0f;
m_alphaBoatAtomicList.Init(NUMBOATALPHALIST);
m_alphaBoatAtomicList.head.item.sort = 0.0f;
m_alphaBoatAtomicList.tail.item.sort = 100000000.0f;
#ifdef ASPECT_RATIO_SCALE #ifdef ASPECT_RATIO_SCALE
// default 150 if not enough for bigger FOVs // default 150 if not enough for bigger FOVs
m_alphaEntityList.Init(NUMALPHAENTITYLIST * 3); m_alphaEntityList.Init(NUMALPHAENTITYLIST * 3);
@ -44,19 +53,28 @@ CVisibilityPlugins::Initialise(void)
#endif // ASPECT_RATIO_SCALE #endif // ASPECT_RATIO_SCALE
m_alphaEntityList.head.item.sort = 0.0f; m_alphaEntityList.head.item.sort = 0.0f;
m_alphaEntityList.tail.item.sort = 100000000.0f; m_alphaEntityList.tail.item.sort = 100000000.0f;
m_alphaUnderwaterEntityList.Init(NUMALPHAUNTERWATERENTITYLIST);
m_alphaUnderwaterEntityList.head.item.sort = 0.0f;
m_alphaUnderwaterEntityList.tail.item.sort = 100000000.0f;
} }
void void
CVisibilityPlugins::Shutdown(void) CVisibilityPlugins::Shutdown(void)
{ {
m_alphaList.Shutdown(); m_alphaList.Shutdown();
m_alphaBoatAtomicList.Shutdown();
m_alphaEntityList.Shutdown(); m_alphaEntityList.Shutdown();
m_alphaUnderwaterEntityList.Shutdown();
} }
void void
CVisibilityPlugins::InitAlphaEntityList(void) CVisibilityPlugins::InitAlphaEntityList(void)
{ {
m_alphaEntityList.Clear(); m_alphaEntityList.Clear();
m_alphaBoatAtomicList.Clear();
m_alphaUnderwaterEntityList.Clear();
} }
bool bool
@ -65,10 +83,9 @@ CVisibilityPlugins::InsertEntityIntoSortedList(CEntity *e, float dist)
AlphaObjectInfo item; AlphaObjectInfo item;
item.entity = e; item.entity = e;
item.sort = dist; item.sort = dist;
bool ret = !!m_alphaEntityList.InsertSorted(item); if(e->bUnderwater && m_alphaUnderwaterEntityList.InsertSorted(item))
// if(!ret) return true;
// printf("list full %d\n", m_alphaEntityList.Count()); return !!m_alphaEntityList.InsertSorted(item);
return ret;
} }
void void
@ -83,10 +100,16 @@ CVisibilityPlugins::InsertAtomicIntoSortedList(RpAtomic *a, float dist)
AlphaObjectInfo item; AlphaObjectInfo item;
item.atomic = a; item.atomic = a;
item.sort = dist; item.sort = dist;
bool ret = !!m_alphaList.InsertSorted(item); return !!m_alphaList.InsertSorted(item);
// if(!ret) }
// printf("list full %d\n", m_alphaList.Count());
return ret; bool
CVisibilityPlugins::InsertAtomicIntoBoatSortedList(RpAtomic *a, float dist)
{
AlphaObjectInfo item;
item.atomic = a;
item.sort = dist;
return !!m_alphaBoatAtomicList.InsertSorted(item);
} }
void void
@ -106,14 +129,21 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera)
ms_vehicleFadeDist = sq(100.0f * TheCamera.GenerationDistMultiplier); ms_vehicleFadeDist = sq(100.0f * TheCamera.GenerationDistMultiplier);
ms_bigVehicleLod0Dist = sq(60.0f * TheCamera.GenerationDistMultiplier); ms_bigVehicleLod0Dist = sq(60.0f * TheCamera.GenerationDistMultiplier);
ms_bigVehicleLod1Dist = sq(150.0f * TheCamera.GenerationDistMultiplier); ms_bigVehicleLod1Dist = sq(150.0f * TheCamera.GenerationDistMultiplier);
ms_pedLod0Dist = sq(25.0f * TheCamera.LODDistMultiplier);
ms_pedLod1Dist = sq(60.0f * TheCamera.LODDistMultiplier); ms_pedLod1Dist = sq(60.0f * TheCamera.LODDistMultiplier);
ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier); ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier);
} }
static float DistToCameraSq;
static float PitchToCamera;
void void
CVisibilityPlugins::SetupVehicleVariables(RpClump *vehicle) CVisibilityPlugins::SetupVehicleVariables(RpClump *vehicle)
{ {
DistToCameraSq = GetDistanceSquaredFromCamera(RpClumpGetFrame(vehicle));
RwV3d distToCam;
RwV3dSub(&distToCam, ms_pCameraPosn, &RwFrameGetMatrix(RpClumpGetFrame(vehicle))->pos);
float dist2d = Sqrt(SQR(distToCam.x) + SQR(distToCam.y));
PitchToCamera = Atan2(distToCam.z, dist2d);
} }
RpMaterial* RpMaterial*
@ -131,23 +161,33 @@ SetTextureCB(RpMaterial *material, void *data)
} }
void void
CVisibilityPlugins::RenderAlphaAtomics(void) CVisibilityPlugins::RenderAtomicList(CLinkList<AlphaObjectInfo> &list)
{ {
CLink<AlphaObjectInfo> *node; CLink<AlphaObjectInfo> *node;
for(node = m_alphaList.tail.prev; for(node = list.tail.prev; node != &list.head; node = node->prev)
node != &m_alphaList.head;
node = node->prev)
AtomicDefaultRenderCallBack(node->item.atomic); AtomicDefaultRenderCallBack(node->item.atomic);
} }
void void
CVisibilityPlugins::RenderFadingEntities(void) CVisibilityPlugins::RenderAlphaAtomics(void)
{
RenderAtomicList(m_alphaList);
}
void
CVisibilityPlugins::RenderBoatAlphaAtomics(void)
{
SetCullMode(rwCULLMODECULLNONE);
RenderAtomicList(m_alphaBoatAtomicList);
SetCullMode(rwCULLMODECULLBACK);
}
void
CVisibilityPlugins::RenderFadingEntities(CLinkList<AlphaObjectInfo> &list)
{ {
CLink<AlphaObjectInfo> *node; CLink<AlphaObjectInfo> *node;
CSimpleModelInfo *mi; CSimpleModelInfo *mi;
for(node = m_alphaEntityList.tail.prev; for(node = list.tail.prev; node != &list.head; node = node->prev){
node != &m_alphaEntityList.head;
node = node->prev){
CEntity *e = node->item.entity; CEntity *e = node->item.entity;
if(e->m_rwObject == nil) if(e->m_rwObject == nil)
continue; continue;
@ -169,25 +209,29 @@ CVisibilityPlugins::RenderFadingEntities(void)
} }
} }
void
CVisibilityPlugins::RenderFadingEntities(void)
{
RenderFadingEntities(m_alphaEntityList);
RenderBoatAlphaAtomics();
}
void void
CVisibilityPlugins::RenderFadingUnderwaterEntities(void) CVisibilityPlugins::RenderFadingUnderwaterEntities(void)
{ {
RenderFadingEntities(m_alphaUnderwaterEntityList);
} }
RpAtomic* RpAtomic*
CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic) CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic)
{ {
RpAtomic *lodatm; RpAtomic *lodatm;
RwMatrix *m;
RwV3d view;
float len; float len;
CSimpleModelInfo *mi; CSimpleModelInfo *mi;
mi = GetAtomicModelInfo(atomic); mi = GetAtomicModelInfo(atomic);
m = RwFrameGetLTM(RpAtomicGetFrame(atomic)); len = Sqrt(DistToCameraSq);
RwV3dSub(&view, RwMatrixGetPos(m), ms_pCameraPosn); lodatm = mi->GetAtomicFromDistance(len * TheCamera.LODDistMultiplier / TheCamera.GenerationDistMultiplier);
len = RwV3dLength(&view);
lodatm = mi->GetAtomicFromDistance(len);
if(lodatm){ if(lodatm){
if(RpAtomicGetGeometry(lodatm) != RpAtomicGetGeometry(atomic)) if(RpAtomicGetGeometry(lodatm) != RpAtomicGetGeometry(atomic))
RpAtomicSetGeometry(atomic, RpAtomicGetGeometry(lodatm), rpATOMICSAMEBOUNDINGSPHERE); RpAtomicSetGeometry(atomic, RpAtomicGetGeometry(lodatm), rpATOMICSAMEBOUNDINGSPHERE);
@ -228,7 +272,6 @@ CVisibilityPlugins::RenderAlphaAtomic(RpAtomic *atomic, int alpha)
return atomic; return atomic;
} }
//--MIAMI: done
RpAtomic* RpAtomic*
CVisibilityPlugins::RenderWeaponCB(RpAtomic *atomic) CVisibilityPlugins::RenderWeaponCB(RpAtomic *atomic)
{ {
@ -247,7 +290,6 @@ CVisibilityPlugins::RenderWeaponCB(RpAtomic *atomic)
return atomic; return atomic;
} }
//--MIAMI: done
RpAtomic* RpAtomic*
CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist) CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist)
{ {
@ -291,17 +333,16 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleHiDetailCB(RpAtomic *atomic)
{ {
RwFrame *clumpframe; RwFrame *clumpframe;
float distsq, dot; float dot;
uint32 flags; uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe); if(DistToCameraSq < ms_vehicleLod0Dist){
if(distsq < ms_vehicleLod0Dist){
flags = GetAtomicId(atomic); flags = GetAtomicId(atomic);
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f){
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags); RwFrameGetLTM(clumpframe), flags);
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot)) if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic; return atomic;
} }
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
@ -313,25 +354,24 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailAlphaCB(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleHiDetailAlphaCB(RpAtomic *atomic)
{ {
RwFrame *clumpframe; RwFrame *clumpframe;
float distsq, dot; float dot;
uint32 flags; uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe); if(DistToCameraSq < ms_vehicleLod0Dist){
if(distsq < ms_vehicleLod0Dist){
flags = GetAtomicId(atomic); flags = GetAtomicId(atomic);
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags); RwFrameGetLTM(clumpframe), flags);
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0) if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f)
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot)) if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic; return atomic;
if(flags & ATOMIC_FLAG_DRAWLAST){ if(flags & ATOMIC_FLAG_DRAWLAST){
// sort before clump // sort before clump
if(!InsertAtomicIntoSortedList(atomic, distsq - 0.0001f)) if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - 0.0001f))
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
}else{ }else{
if(!InsertAtomicIntoSortedList(atomic, distsq + dot)) if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
} }
} }
@ -342,14 +382,13 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic)
{ {
RwFrame *clumpframe; RwFrame *clumpframe;
float distsq, dot; float dot;
uint32 flags; uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe); if(DistToCameraSq < ms_bigVehicleLod0Dist){
if(distsq < ms_bigVehicleLod0Dist){
flags = GetAtomicId(atomic); flags = GetAtomicId(atomic);
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f){
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags); RwFrameGetLTM(clumpframe), flags);
if(dot > 0.0f) if(dot > 0.0f)
@ -364,20 +403,19 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic)
{ {
RwFrame *clumpframe; RwFrame *clumpframe;
float distsq, dot; float dot;
uint32 flags; uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe); if(DistToCameraSq < ms_bigVehicleLod0Dist){
if(distsq < ms_bigVehicleLod0Dist){
flags = GetAtomicId(atomic); flags = GetAtomicId(atomic);
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags); RwFrameGetLTM(clumpframe), flags);
if(dot > 0.0f) if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f)
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0) if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic; return atomic;
if(!InsertAtomicIntoSortedList(atomic, distsq + dot)) if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
} }
return atomic; return atomic;
@ -386,29 +424,36 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic)
RpAtomic* RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic)
{ {
RwFrame *clumpframe; if(DistToCameraSq < ms_bigVehicleLod1Dist)
float distsq;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe);
if(distsq < ms_bigVehicleLod1Dist)
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
return atomic; return atomic;
} }
RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic)
{
if(DistToCameraSq < ms_vehicleLod0Dist){
if(GetAtomicId(atomic) & ATOMIC_FLAG_DRAWLAST){
if(!InsertAtomicIntoBoatSortedList(atomic, DistToCameraSq))
AtomicDefaultRenderCallBack(atomic);
}else
AtomicDefaultRenderCallBack(atomic);
}
return atomic;
}
RpAtomic* RpAtomic*
CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic)
{ {
RwFrame *clumpframe; RwFrame *clumpframe;
float distsq, dot; float dot;
uint32 flags; uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe); if(DistToCameraSq >= ms_bigVehicleLod0Dist &&
if(distsq >= ms_bigVehicleLod0Dist && DistToCameraSq < ms_bigVehicleLod1Dist){
distsq < ms_bigVehicleLod1Dist){
flags = GetAtomicId(atomic); flags = GetAtomicId(atomic);
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f){
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags); RwFrameGetLTM(clumpframe), flags);
if(dot > 0.0f) if(dot > 0.0f)
@ -423,21 +468,20 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic)
{ {
RwFrame *clumpframe; RwFrame *clumpframe;
float distsq, dot; float dot;
uint32 flags; uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe); if(DistToCameraSq >= ms_bigVehicleLod0Dist &&
if(distsq >= ms_bigVehicleLod0Dist && DistToCameraSq < ms_bigVehicleLod1Dist){
distsq < ms_bigVehicleLod1Dist){
flags = GetAtomicId(atomic); flags = GetAtomicId(atomic);
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags); RwFrameGetLTM(clumpframe), flags);
if(dot > 0.0f) if(dot > 0.0f)
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0) if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f)
return atomic; return atomic;
if(!InsertAtomicIntoSortedList(atomic, distsq + dot)) if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
} }
return atomic; return atomic;
@ -447,12 +491,10 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic)
{ {
RpClump *clump; RpClump *clump;
float dist;
int32 alpha; int32 alpha;
clump = RpAtomicGetClump(atomic); clump = RpAtomicGetClump(atomic);
dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)); if(DistToCameraSq >= ms_vehicleLod0Dist){
if(dist >= ms_vehicleLod0Dist){
alpha = GetClumpAlpha(clump); alpha = GetClumpAlpha(clump);
if(alpha == 255) if(alpha == 255)
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
@ -466,12 +508,7 @@ CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic)
RpAtomic* RpAtomic*
CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic)
{ {
RwFrame *clumpframe; if(DistToCameraSq >= ms_bigVehicleLod1Dist)
float distsq;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe);
if(distsq >= ms_bigVehicleLod1Dist)
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
return atomic; return atomic;
} }
@ -480,17 +517,16 @@ RpAtomic*
CVisibilityPlugins::RenderTrainHiDetailCB(RpAtomic *atomic) CVisibilityPlugins::RenderTrainHiDetailCB(RpAtomic *atomic)
{ {
RwFrame *clumpframe; RwFrame *clumpframe;
float distsq, dot; float dot;
uint32 flags; uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe); if(DistToCameraSq < ms_bigVehicleLod1Dist){
if(distsq < ms_bigVehicleLod1Dist){
flags = GetAtomicId(atomic); flags = GetAtomicId(atomic);
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f){
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags); RwFrameGetLTM(clumpframe), flags);
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot)) if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic; return atomic;
} }
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
@ -502,25 +538,24 @@ RpAtomic*
CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic) CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
{ {
RwFrame *clumpframe; RwFrame *clumpframe;
float distsq, dot; float dot;
uint32 flags; uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe); if(DistToCameraSq < ms_bigVehicleLod1Dist){
if(distsq < ms_bigVehicleLod1Dist){
flags = GetAtomicId(atomic); flags = GetAtomicId(atomic);
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags); RwFrameGetLTM(clumpframe), flags);
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0) if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f)
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot)) if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic; return atomic;
if(flags & ATOMIC_FLAG_DRAWLAST){ if(flags & ATOMIC_FLAG_DRAWLAST){
// sort before clump // sort before clump
if(!InsertAtomicIntoSortedList(atomic, distsq - 0.0001f)) if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - 0.0001f))
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
}else{ }else{
if(!InsertAtomicIntoSortedList(atomic, distsq + dot)) if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
} }
} }
@ -530,15 +565,36 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
RpAtomic* RpAtomic*
CVisibilityPlugins::RenderVehicleRotorAlphaCB(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleRotorAlphaCB(RpAtomic *atomic)
{ {
// TODO(MIAMI): RwFrame *clumpframe;
return AtomicDefaultRenderCallBack(atomic); float dot;
RwV3d cam2atm;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
if(DistToCameraSq < ms_bigVehicleLod1Dist){
RwV3dSub(&cam2atm, &RwFrameGetLTM(RpAtomicGetFrame(atomic))->pos, ms_pCameraPosn);
dot = RwV3dDotProduct(&cam2atm, &RwFrameGetLTM(clumpframe)->at);
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot*20.0f))
AtomicDefaultRenderCallBack(atomic);
}
return atomic;
} }
RpAtomic* RpAtomic*
CVisibilityPlugins::RenderVehicleTailRotorAlphaCB(RpAtomic *atomic) CVisibilityPlugins::RenderVehicleTailRotorAlphaCB(RpAtomic *atomic)
{ {
// TODO(MIAMI): RwMatrix *clumpMat, *atmMat;
return AtomicDefaultRenderCallBack(atomic); float dot;
RwV3d cam2atm;
if(DistToCameraSq < ms_bigVehicleLod0Dist){
atmMat = RwFrameGetLTM(RpAtomicGetFrame(atomic));
clumpMat = RwFrameGetLTM(RpClumpGetFrame(RpAtomicGetClump(atomic)));
RwV3dSub(&cam2atm, &atmMat->pos, ms_pCameraPosn);
dot = RwV3dDotProduct(&cam2atm, &clumpMat->up) + RwV3dDotProduct(&cam2atm, &clumpMat->right);
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - dot))
AtomicDefaultRenderCallBack(atomic);
}
return atomic;
} }
RpAtomic* RpAtomic*
@ -550,56 +606,20 @@ CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic)
return atomic; return atomic;
} }
RpAtomic*
CVisibilityPlugins::RenderPedLowDetailCB(RpAtomic *atomic)
{
RpClump *clump;
float dist;
int32 alpha;
clump = RpAtomicGetClump(atomic);
dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
if(dist >= ms_pedLod0Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
AtomicDefaultRenderCallBack(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
return atomic;
}
RpAtomic*
CVisibilityPlugins::RenderPedHiDetailCB(RpAtomic *atomic)
{
RpClump *clump;
float dist;
int32 alpha;
clump = RpAtomicGetClump(atomic);
dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
if(dist < ms_pedLod0Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
AtomicDefaultRenderCallBack(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
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* RpAtomic*
CVisibilityPlugins::RenderPedCB(RpAtomic *atomic) CVisibilityPlugins::RenderPedCB(RpAtomic *atomic)
{ {
int32 alpha; int32 alpha;
RwV3d cam2atm;
RwV3dSub(&cam2atm, &RwFrameGetLTM(RpAtomicGetFrame(atomic))->pos, ms_pCameraPosn);
if(RwV3dDotProduct(&cam2atm, &cam2atm) < ms_pedLod1Dist){
alpha = GetClumpAlpha(RpAtomicGetClump(atomic)); alpha = GetClumpAlpha(RpAtomicGetClump(atomic));
if(alpha == 255) if(alpha == 255)
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
else else
RenderAlphaAtomic(atomic, alpha); RenderAlphaAtomic(atomic, alpha);
}
return atomic; return atomic;
} }

View File

@ -21,7 +21,9 @@ public:
}; };
static CLinkList<AlphaObjectInfo> m_alphaList; static CLinkList<AlphaObjectInfo> m_alphaList;
static CLinkList<AlphaObjectInfo> m_alphaBoatAtomicList;
static CLinkList<AlphaObjectInfo> m_alphaEntityList; static CLinkList<AlphaObjectInfo> m_alphaEntityList;
static CLinkList<AlphaObjectInfo> m_alphaUnderwaterEntityList;
static RwCamera *ms_pCamera; static RwCamera *ms_pCamera;
static RwV3d *ms_pCameraPosn; static RwV3d *ms_pCameraPosn;
static float ms_cullCompsDist; static float ms_cullCompsDist;
@ -30,7 +32,6 @@ public:
static float ms_vehicleFadeDist; static float ms_vehicleFadeDist;
static float ms_bigVehicleLod0Dist; static float ms_bigVehicleLod0Dist;
static float ms_bigVehicleLod1Dist; static float ms_bigVehicleLod1Dist;
static float ms_pedLod0Dist;
static float ms_pedLod1Dist; static float ms_pedLod1Dist;
static float ms_pedFadeDist; static float ms_pedFadeDist;
@ -40,6 +41,7 @@ public:
static bool InsertEntityIntoSortedList(CEntity *e, float dist); static bool InsertEntityIntoSortedList(CEntity *e, float dist);
static void InitAlphaAtomicList(void); static void InitAlphaAtomicList(void);
static bool InsertAtomicIntoSortedList(RpAtomic *a, float dist); static bool InsertAtomicIntoSortedList(RpAtomic *a, float dist);
static bool InsertAtomicIntoBoatSortedList(RpAtomic *a, float dist);
static void SetRenderWareCamera(RwCamera *camera); static void SetRenderWareCamera(RwCamera *camera);
static void SetupVehicleVariables(RpClump *vehicle); static void SetupVehicleVariables(RpClump *vehicle);
@ -55,6 +57,7 @@ public:
static RpAtomic *RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic); static RpAtomic *RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic); static RpAtomic *RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailCB_Boat(RpAtomic *atomic); static RpAtomic *RenderVehicleHiDetailCB_Boat(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic);
static RpAtomic *RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic); static RpAtomic *RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic); static RpAtomic *RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleReallyLowDetailCB(RpAtomic *atomic); static RpAtomic *RenderVehicleReallyLowDetailCB(RpAtomic *atomic);
@ -65,11 +68,12 @@ public:
static RpAtomic *RenderVehicleTailRotorAlphaCB(RpAtomic *atomic); static RpAtomic *RenderVehicleTailRotorAlphaCB(RpAtomic *atomic);
static RpAtomic *RenderPlayerCB(RpAtomic *atomic); 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 RpAtomic *RenderPedCB(RpAtomic *atomic); // for skinned models with only one clump
static void RenderAtomicList(CLinkList<AlphaObjectInfo> &list);
static void RenderAlphaAtomics(void); static void RenderAlphaAtomics(void);
static void RenderBoatAlphaAtomics(void);
static void RenderFadingEntities(CLinkList<AlphaObjectInfo> &list);
static void RenderFadingEntities(void); static void RenderFadingEntities(void);
static void RenderFadingUnderwaterEntities(void); static void RenderFadingUnderwaterEntities(void);