CEntity done; C(Vu)Vector fixes and cleanup

This commit is contained in:
aap 2021-05-23 17:55:55 +02:00 committed by Sergeanur
parent fb03ee45b5
commit e014bb5359
18 changed files with 249 additions and 89 deletions

View file

@ -4103,16 +4103,11 @@ CCamera::IsSphereVisible(const CVector &center, float radius, const CMatrix *mat
bool bool
CCamera::IsSphereVisible(const CVector &center, float radius) CCamera::IsSphereVisible(const CVector &center, float radius)
{ {
CMatrix mat = m_cameraMatrix; return IsSphereVisible(center, radius, &m_cameraMatrix);
return IsSphereVisible(center, radius, &mat);
} }
bool bool
#ifdef GTA_PS2 CCamera::IsBoxVisible(CVUVECTOR *box, const CMatrix *mat)
CCamera::IsBoxVisible(CVuVector *box, const CMatrix *mat)
#else
CCamera::IsBoxVisible(CVector *box, const CMatrix *mat)
#endif
{ {
int i; int i;
int frustumTests[6] = { 0 }; int frustumTests[6] = { 0 };

View file

@ -634,11 +634,7 @@ public:
bool IsPointVisible(const CVector &center, const CMatrix *mat); bool IsPointVisible(const CVector &center, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius, const CMatrix *mat); bool IsSphereVisible(const CVector &center, float radius, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius); bool IsSphereVisible(const CVector &center, float radius);
#ifdef GTA_PS2 bool IsBoxVisible(CVUVECTOR *box, const CMatrix *mat);
bool IsBoxVisible(CVuVector *box, const CMatrix *mat);
#else
bool IsBoxVisible(CVector *box, const CMatrix *mat);
#endif
}; };
VALIDATE_SIZE(CCamera, 0xE9D8); VALIDATE_SIZE(CCamera, 0xE9D8);

View file

@ -39,9 +39,7 @@ CEntity::RegisterReference(CEntity **pent)
ref->pentity = pent; ref->pentity = pent;
ref->next = m_pFirstReference; ref->next = m_pFirstReference;
m_pFirstReference = ref; m_pFirstReference = ref;
return;
} }
return;
} }
// Clean up the reference from *pent -> 'this' // Clean up the reference from *pent -> 'this'

View file

@ -1906,16 +1906,7 @@ CWorld::Process(void)
for(int i = 0; i < NUMCUTSCENEOBJECTS; i++) { for(int i = 0; i < NUMCUTSCENEOBJECTS; i++) {
CCutsceneObject *csObj = CCutsceneMgr::GetCutsceneObject(i); CCutsceneObject *csObj = CCutsceneMgr::GetCutsceneObject(i);
if(csObj && csObj->m_entryInfoList.first) { if(csObj && csObj->m_entryInfoList.first) {
if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP && csObj->UpdateAnim();
RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) {
if (csObj->IsObject())
RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), CTimer::GetTimeStepNonClippedInSeconds());
else {
if (!csObj->bOffscreen)
csObj->bOffscreen = !csObj->GetIsOnScreen();
RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), CTimer::GetTimeStepInSeconds(), !csObj->bOffscreen);
}
}
csObj->ProcessControl(); csObj->ProcessControl();
csObj->ProcessCollision(); csObj->ProcessCollision();
csObj->GetMatrix().UpdateRW(); csObj->GetMatrix().UpdateRW();
@ -1927,26 +1918,40 @@ CWorld::Process(void)
} else { } else {
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) { for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CEntity *movingEnt = (CEntity *)node->item; CEntity *movingEnt = (CEntity *)node->item;
if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && if(!movingEnt->bRemoveFromWorld)
RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) { movingEnt->UpdateAnim();
if (movingEnt->IsObject())
RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepNonClippedInSeconds());
else {
if (!movingEnt->bOffscreen)
movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepInSeconds(), !movingEnt->bOffscreen);
}
}
} }
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) { for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CPhysical *movingEnt = (CPhysical *)node->item; CPhysical *movingEnt = (CPhysical *)node->item;
if(movingEnt->bRemoveFromWorld) { if(movingEnt->bRemoveFromWorld) {
RemoveEntityInsteadOfProcessingIt(movingEnt); RemoveEntityInsteadOfProcessingIt(movingEnt);
} else { } else {
movingEnt->ProcessControl(); if(!CCutsceneMgr::IsCutsceneProcessing() || movingEnt->UpdatesInCutscene())
movingEnt->ProcessControl();
if(movingEnt->GetIsStatic()) { movingEnt->RemoveFromMovingList(); } if(movingEnt->GetIsStatic()) { movingEnt->RemoveFromMovingList(); }
} }
} }
for(int y = 0; y < NUMSECTORS_Y; y++)
for(int x = 0; x < NUMSECTORS_X; x++){
CPtrNode *node;
CSector *sect = CWorld::GetSector(x, y);
for(node = sect->m_lists[ENTITYLIST_PEDS].first; node; node = node->next)
((CEntity*)node->item)->UpdateDistanceFade();
for(node = sect->m_lists[ENTITYLIST_PEDS_OVERLAP].first; node; node = node->next)
((CEntity*)node->item)->UpdateDistanceFade();
for(node = sect->m_lists[ENTITYLIST_VEHICLES].first; node; node = node->next)
((CEntity*)node->item)->UpdateDistanceFade();
for(node = sect->m_lists[ENTITYLIST_VEHICLES_OVERLAP].first; node; node = node->next)
((CEntity*)node->item)->UpdateDistanceFade();
for(node = sect->m_lists[ENTITYLIST_OBJECTS].first; node; node = node->next)
((CEntity*)node->item)->UpdateDistanceFade();
for(node = sect->m_lists[ENTITYLIST_OBJECTS_OVERLAP].first; node; node = node->next)
((CEntity*)node->item)->UpdateDistanceFade();
for(node = sect->m_lists[ENTITYLIST_DUMMIES].first; node; node = node->next)
((CEntity*)node->item)->UpdateDistanceFade();
for(node = sect->m_lists[ENTITYLIST_DUMMIES_OVERLAP].first; node; node = node->next)
((CEntity*)node->item)->UpdateDistanceFade();
}
bForceProcessControl = true; bForceProcessControl = true;
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) { for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CPhysical *movingEnt = (CPhysical *)node->item; CPhysical *movingEnt = (CPhysical *)node->item;

View file

@ -29,6 +29,7 @@ enum
{ {
ENTITYLIST_BUILDINGS, ENTITYLIST_BUILDINGS,
ENTITYLIST_BUILDINGS_OVERLAP, ENTITYLIST_BUILDINGS_OVERLAP,
ENTITYLIST_UNKNOWN,
ENTITYLIST_OBJECTS, ENTITYLIST_OBJECTS,
ENTITYLIST_OBJECTS_OVERLAP, ENTITYLIST_OBJECTS_OVERLAP,
ENTITYLIST_VEHICLES, ENTITYLIST_VEHICLES,

View file

@ -228,6 +228,12 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w)
#include "maths.h" #include "maths.h"
#include "Vector.h" #include "Vector.h"
#ifdef GTA_PS2
#include "VuVector.h"
#define CVUVECTOR CVuVector
#else
#define CVUVECTOR CVector
#endif
#include "Vector2D.h" #include "Vector2D.h"
#include "Matrix.h" #include "Matrix.h"
#include "Rect.h" #include "Rect.h"

View file

@ -26,6 +26,12 @@
#include "Ped.h" #include "Ped.h"
#include "Dummy.h" #include "Dummy.h"
#include "WindModifiers.h" #include "WindModifiers.h"
#include "SpecialFX.h"
#include "VisibilityPlugins.h"
#include "RpAnimBlend.h"
#include "CutsceneMgr.h"
//--LCS: file done except TODO for distance alpha
int gBuildings; int gBuildings;
@ -71,13 +77,18 @@ CEntity::CEntity(void)
bDistanceFade = false; bDistanceFade = false;
m_flagE1 = false; m_flagE1 = false;
m_flagE2 = false; bDontCastShadowsOn = false;
bOffscreen = false; bOffscreen = false;
bIsStaticWaitingForCollision = false; bIsStaticWaitingForCollision = false;
bDontStream = false; bDontStream = false;
bUnderwater = false; bUnderwater = false;
bHasPreRenderEffects = false; bHasPreRenderEffects = false;
bIsTreeModel = false;
m_flagG2 = false;
m_flagG4 = false;
m_flagG8 = false;
m_scanCode = 0; m_scanCode = 0;
m_modelIndex = -1; m_modelIndex = -1;
m_rwObject = nil; m_rwObject = nil;
@ -96,6 +107,8 @@ void
CEntity::SetModelIndex(uint32 id) CEntity::SetModelIndex(uint32 id)
{ {
m_modelIndex = id; m_modelIndex = id;
bIsTreeModel = IsTreeModel(m_modelIndex);
bDrawLast |= bIsTreeModel;
bHasPreRenderEffects = HasPreRenderEffects(); bHasPreRenderEffects = HasPreRenderEffects();
CreateRwObject(); CreateRwObject();
} }
@ -104,6 +117,8 @@ void
CEntity::SetModelIndexNoCreate(uint32 id) CEntity::SetModelIndexNoCreate(uint32 id)
{ {
m_modelIndex = id; m_modelIndex = id;
bIsTreeModel = IsTreeModel(m_modelIndex);
bDrawLast |= bIsTreeModel;
bHasPreRenderEffects = HasPreRenderEffects(); bHasPreRenderEffects = HasPreRenderEffects();
} }
@ -126,6 +141,7 @@ CEntity::CreateRwObject(void)
else if(RwObjectGetType(m_rwObject) == rpCLUMP) else if(RwObjectGetType(m_rwObject) == rpCLUMP)
GetMatrix().AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump *)m_rwObject)), false); GetMatrix().AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump *)m_rwObject)), false);
// useless IsTextureLoaded();
mi->AddRef(); mi->AddRef();
} }
} }
@ -182,9 +198,11 @@ CEntity::DeleteRwObject(void)
if(m_rwObject){ if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC){ if(RwObjectGetType(m_rwObject) == rpATOMIC){
f = RpAtomicGetFrame((RpAtomic*)m_rwObject); f = RpAtomicGetFrame((RpAtomic*)m_rwObject);
CStreaming::UnregisterInstance((RpAtomic*)m_rwObject, nil);
RpAtomicDestroy((RpAtomic*)m_rwObject); RpAtomicDestroy((RpAtomic*)m_rwObject);
RwFrameDestroy(f); RwFrameDestroy(f);
}else if(RwObjectGetType(m_rwObject) == rpCLUMP){ }else if(RwObjectGetType(m_rwObject) == rpCLUMP){
CStreaming::UnregisterInstance((RpClump*)m_rwObject);
if(IsClumpSkinned((RpClump*)m_rwObject)) if(IsClumpSkinned((RpClump*)m_rwObject))
RpClumpForAllAtomics((RpClump*)m_rwObject, AtomicRemoveAnimFromSkinCB, nil); RpClumpForAllAtomics((RpClump*)m_rwObject, AtomicRemoveAnimFromSkinCB, nil);
RpClumpDestroy((RpClump*)m_rwObject); RpClumpDestroy((RpClump*)m_rwObject);
@ -201,7 +219,7 @@ CEntity::GetBoundRect(void)
{ {
CRect rect; CRect rect;
CVector v; CVector v;
CColModel *col = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); CColModel *col = CModelInfo::GetColModel(m_modelIndex);
rect.ContainPoint(GetMatrix() * col->boundingBox.min); rect.ContainPoint(GetMatrix() * col->boundingBox.min);
rect.ContainPoint(GetMatrix() * col->boundingBox.max); rect.ContainPoint(GetMatrix() * col->boundingBox.max);
@ -220,21 +238,27 @@ CEntity::GetBoundRect(void)
CVector CVector
CEntity::GetBoundCentre(void) CEntity::GetBoundCentre(void)
{ {
CVector v; return GetMatrix() * CModelInfo::GetColModel(m_modelIndex)->boundingSphere.center;
GetBoundCentre(v);
return v;
} }
#ifdef GTA_PS2
void
CEntity::GetBoundCentre(CVuVector &out)
{
TransformPoint(out, GetMatrix(), CModelInfo::GetColModel(m_modelIndex)->boundingSphere.center);
}
#else
void void
CEntity::GetBoundCentre(CVector &out) CEntity::GetBoundCentre(CVector &out)
{ {
out = GetMatrix() * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center; out = GetMatrix() * CModelInfo::GetColModel(m_modelIndex)->boundingSphere.center;
} }
#endif
float float
CEntity::GetBoundRadius(void) CEntity::GetBoundRadius(void)
{ {
return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; return CModelInfo::GetColModel(m_modelIndex)->boundingSphere.radius;
} }
void void
@ -244,9 +268,18 @@ CEntity::UpdateRwFrame(void)
RwFrameUpdateObjects((RwFrame*)rwObjectGetParent(m_rwObject)); RwFrameUpdateObjects((RwFrame*)rwObjectGetParent(m_rwObject));
} }
bool
PauseEntityAnims(void)
{
return CSpecialFX::bSnapShotActive;
}
void void
CEntity::UpdateRpHAnim(void) CEntity::UpdateRpHAnim(void)
{ {
if(PauseEntityAnims())
return;
if(IsClumpSkinned(GetClump())){ if(IsClumpSkinned(GetClump())){
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
RpHAnimHierarchyUpdateMatrices(hier); RpHAnimHierarchyUpdateMatrices(hier);
@ -308,9 +341,10 @@ CEntity::PreRender(void)
if(!bHasPreRenderEffects) if(!bHasPreRenderEffects)
return; return;
// separate function in LCS but we don't know the name
switch(m_type){ switch(m_type){
case ENTITY_TYPE_BUILDING: case ENTITY_TYPE_BUILDING:
if(IsTreeModel(GetModelIndex())){ if(bIsTreeModel){
float dist = (TheCamera.GetPosition() - GetPosition()).Magnitude2D(); float dist = (TheCamera.GetPosition() - GetPosition()).Magnitude2D();
CObject::fDistToNearestTree = Min(CObject::fDistToNearestTree, dist); CObject::fDistToNearestTree = Min(CObject::fDistToNearestTree, dist);
ModifyMatrixForTreeInWind(); ModifyMatrixForTreeInWind();
@ -373,7 +407,7 @@ CEntity::PreRender(void)
CVector pos = GetPosition(); CVector pos = GetPosition();
CShadows::StoreShadowToBeRendered(SHADOWTYPE_DARK, CShadows::StoreShadowToBeRendered(SHADOWTYPE_DARK,
gpShadowPedTex, &pos, gpShadowPedTex, &pos,
0.4f, 0.0f, 0.0f, -0.4f, 0.4f, 0.0f, 0.0f, 0.4f,
CTimeCycle::GetShadowStrength(), CTimeCycle::GetShadowStrength(),
CTimeCycle::GetShadowStrength(), CTimeCycle::GetShadowStrength(),
CTimeCycle::GetShadowStrength(), CTimeCycle::GetShadowStrength(),
@ -409,19 +443,65 @@ void
CEntity::Render(void) CEntity::Render(void)
{ {
if(m_rwObject){ if(m_rwObject){
bImBeingRendered = true; if(CVisibilityPlugins::GetObjectDistanceAlpha(m_rwObject) != 0){
if(RwObjectGetType(m_rwObject) == rpATOMIC) // NB: LCS does not use bImBeingRendered here,
RpAtomicRender((RpAtomic*)m_rwObject); // but that may be due to the streamed world. better keep it for safety
else bImBeingRendered = true;
RpClumpRender((RpClump*)m_rwObject); if(RwObjectGetType(m_rwObject) == rpATOMIC)
bImBeingRendered = false; RpAtomicRender((RpAtomic*)m_rwObject);
else
RpClumpRender((RpClump*)m_rwObject);
bImBeingRendered = false;
}
} }
} }
void
CEntity::UpdateDistanceFade(void)
{
// TODO(LCS):
// increasing and decreasing alpha depending on bDistanceFade doesn't make any sense
// so disable this whole thing until it does.
return;
int alpha = CVisibilityPlugins::GetObjectDistanceAlpha(m_rwObject);
if(CCutsceneMgr::IsRunning() || TheCamera.WorldViewerBeingUsed)
alpha = 255;
else if(bDistanceFade)
alpha = Max(alpha-16, 0);
else if(alpha < 255)
alpha = Min(alpha+32, 255);
CVisibilityPlugins::SetObjectDistanceAlpha(m_rwObject, alpha);
}
void
CEntity::UpdateAnim(void)
{
if(PauseEntityAnims())
return;
if(m_rwObject && RwObjectGetType(m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(GetClump())) {
if (IsObject())
RpAnimBlendClumpUpdateAnimations(GetClump(), CTimer::GetTimeStepNonClippedInSeconds());
else {
if (!bOffscreen)
bOffscreen = !GetIsOnScreen();
RpAnimBlendClumpUpdateAnimations(GetClump(), CTimer::GetTimeStepInSeconds(), !bOffscreen);
}
}
}
bool
CEntity::GetIsTouching(CVUVECTOR const &center, float radius)
{
CVUVECTOR boundCenter;
GetBoundCentre(boundCenter);
return sq(GetBoundRadius()+radius) > (boundCenter-center).MagnitudeSqr();
}
bool bool
CEntity::GetIsTouching(CVector const &center, float radius) CEntity::GetIsTouching(CEntity *other)
{ {
return sq(GetBoundRadius()+radius) > (GetBoundCentre()-center).MagnitudeSqr(); return sq(GetBoundRadius()+other->GetBoundRadius()) > (GetBoundCentre()-other->GetBoundCentre()).MagnitudeSqr();
} }
bool bool
@ -439,8 +519,7 @@ CEntity::IsVisibleComplex(void)
bool bool
CEntity::GetIsOnScreen(void) CEntity::GetIsOnScreen(void)
{ {
return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(), return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius());
&TheCamera.GetCameraMatrix());
} }
bool bool
@ -456,7 +535,7 @@ CEntity::GetIsOnScreenComplex(void)
return true; return true;
CRect rect = GetBoundRect(); CRect rect = GetBoundRect();
CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); CColModel *colmodel = CModelInfo::GetColModel(m_modelIndex);
float z = GetPosition().z; float z = GetPosition().z;
float minz = z + colmodel->boundingBox.min.z; float minz = z + colmodel->boundingBox.min.z;
float maxz = z + colmodel->boundingBox.max.z; float maxz = z + colmodel->boundingBox.max.z;
@ -611,7 +690,7 @@ CEntity::Remove(void)
float float
CEntity::GetDistanceFromCentreOfMassToBaseOfModel(void) CEntity::GetDistanceFromCentreOfMassToBaseOfModel(void)
{ {
return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z; return -CModelInfo::GetColModel(m_modelIndex)->boundingBox.min.z;
} }
void void
@ -737,11 +816,6 @@ CEntity::PreRenderForGlassWindow(void)
bIsVisible = false; bIsVisible = false;
} }
/*
0x487A10 - SetAtomicAlphaCB
0x4879E0 - SetClumpAlphaCB
*/
RpMaterial* RpMaterial*
SetAtomicAlphaCB(RpMaterial *material, void *data) SetAtomicAlphaCB(RpMaterial *material, void *data)
{ {
@ -840,7 +914,7 @@ CEntity::SaveEntityFlags(uint8*& buf)
if (bDistanceFade) tmp |= BIT(7); if (bDistanceFade) tmp |= BIT(7);
if (m_flagE1) tmp |= BIT(8); if (m_flagE1) tmp |= BIT(8);
if (m_flagE2) tmp |= BIT(9); if (bDontCastShadowsOn) tmp |= BIT(9);
if (bOffscreen) tmp |= BIT(10); if (bOffscreen) tmp |= BIT(10);
if (bIsStaticWaitingForCollision) tmp |= BIT(11); if (bIsStaticWaitingForCollision) tmp |= BIT(11);
if (bDontStream) tmp |= BIT(12); if (bDontStream) tmp |= BIT(12);
@ -896,7 +970,7 @@ CEntity::LoadEntityFlags(uint8*& buf)
bDistanceFade = !!(tmp & BIT(7)); bDistanceFade = !!(tmp & BIT(7));
m_flagE1 = !!(tmp & BIT(8)); m_flagE1 = !!(tmp & BIT(8));
m_flagE2 = !!(tmp & BIT(9)); bDontCastShadowsOn = !!(tmp & BIT(9));
bOffscreen = !!(tmp & BIT(10)); bOffscreen = !!(tmp & BIT(10));
bIsStaticWaitingForCollision = !!(tmp & BIT(11)); bIsStaticWaitingForCollision = !!(tmp & BIT(11));
bDontStream = !!(tmp & BIT(12)); bDontStream = !!(tmp & BIT(12));

View file

@ -43,6 +43,7 @@ private:
uint32 m_status : 5; uint32 m_status : 5;
public: public:
// flagsA // flagsA
// LCS flagsB 02
uint32 bUsesCollision : 1; // does entity use collision uint32 bUsesCollision : 1; // does entity use collision
uint32 bCollisionProcessed : 1; // has object been processed by a ProcessEntityCollision function uint32 bCollisionProcessed : 1; // has object been processed by a ProcessEntityCollision function
uint32 bIsStatic : 1; // is entity static uint32 bIsStatic : 1; // is entity static
@ -50,6 +51,7 @@ public:
uint32 bPedPhysics : 1; uint32 bPedPhysics : 1;
uint32 bIsStuck : 1; // is entity stuck uint32 bIsStuck : 1; // is entity stuck
uint32 bIsInSafePosition : 1; // is entity in a collision free safe position uint32 bIsInSafePosition : 1; // is entity in a collision free safe position
// LCS flagsC
uint32 bUseCollisionRecords : 1; uint32 bUseCollisionRecords : 1;
// flagsB // flagsB
@ -60,6 +62,7 @@ public:
uint32 bRenderScorched : 1; uint32 bRenderScorched : 1;
uint32 bHasBlip : 1; uint32 bHasBlip : 1;
uint32 bIsBIGBuilding : 1; // Set if this entity is a big building uint32 bIsBIGBuilding : 1; // Set if this entity is a big building
// LCS flagsD
uint32 bStreamBIGBuilding : 1; // set when draw dist <= 2000 uint32 bStreamBIGBuilding : 1; // set when draw dist <= 2000
// flagsC // flagsC
@ -70,6 +73,7 @@ public:
uint32 bMeleeProof : 1; uint32 bMeleeProof : 1;
uint32 bOnlyDamagedByPlayer : 1; uint32 bOnlyDamagedByPlayer : 1;
uint32 bStreamingDontDelete : 1; // Dont let the streaming remove this uint32 bStreamingDontDelete : 1; // Dont let the streaming remove this
// LCS flagsE
uint32 bRemoveFromWorld : 1; // remove this entity next time it should be processed uint32 bRemoveFromWorld : 1; // remove this entity next time it should be processed
// flagsD // flagsD
@ -80,17 +84,24 @@ public:
uint32 bDrawLast : 1; // draw object last uint32 bDrawLast : 1; // draw object last
uint32 bNoBrightHeadLights : 1; uint32 bNoBrightHeadLights : 1;
uint32 bDoNotRender : 1; //-- only applies to CObjects apparently uint32 bDoNotRender : 1; //-- only applies to CObjects apparently
// LCS flagsF
uint32 bDistanceFade : 1; // Fade entity because it is far away uint32 bDistanceFade : 1; // Fade entity because it is far away
// flagsE // flagsE
uint32 m_flagE1 : 1; uint32 m_flagE1 : 1;
uint32 m_flagE2 : 1; uint32 bDontCastShadowsOn : 1; // Dont cast shadows on this object
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 bDontStream : 1; // tell the streaming not to stream me uint32 bDontStream : 1; // tell the streaming not to stream me
uint32 bUnderwater : 1; // this object is underwater change drawing order uint32 bUnderwater : 1; // this object is underwater change drawing order
uint32 bHasPreRenderEffects : 1; // Object has a prerender effects attached to it uint32 bHasPreRenderEffects : 1; // Object has a prerender effects attached to it
// LCS flagsG
uint32 bIsTreeModel : 1;
uint32 m_flagG2 : 1;
uint32 m_flagG4 : 1;
uint32 m_flagG8 : 1;
uint16 m_scanCode; uint16 m_scanCode;
uint16 m_randomSeed; uint16 m_randomSeed;
int16 m_modelIndex; int16 m_modelIndex;
@ -118,6 +129,7 @@ public:
virtual void Add(void); virtual void Add(void);
virtual void Remove(void); virtual void Remove(void);
virtual bool UpdatesInCutscene(void) { return false; }
virtual void SetModelIndex(uint32 id); virtual void SetModelIndex(uint32 id);
virtual void SetModelIndexNoCreate(uint32 id); virtual void SetModelIndexNoCreate(uint32 id);
virtual void CreateRwObject(void); virtual void CreateRwObject(void);
@ -129,6 +141,7 @@ public:
virtual void Teleport(CVector v) {} virtual void Teleport(CVector v) {}
virtual void PreRender(void); virtual void PreRender(void);
virtual void Render(void); virtual void Render(void);
virtual void UpdateAnim(void);
virtual bool SetupLighting(void); virtual bool SetupLighting(void);
virtual void RemoveLighting(bool); virtual void RemoveLighting(bool);
virtual void FlagToDestroyWhenNextProcessed(void) {} virtual void FlagToDestroyWhenNextProcessed(void) {}
@ -148,11 +161,13 @@ public:
return (RpClump*)m_rwObject; return (RpClump*)m_rwObject;
} }
void GetBoundCentre(CVector &out); void UpdateDistanceFade(void);
void GetBoundCentre(CVUVECTOR &out);
CVector GetBoundCentre(void); CVector GetBoundCentre(void);
float GetBoundRadius(void); float GetBoundRadius(void);
float GetDistanceFromCentreOfMassToBaseOfModel(void); float GetDistanceFromCentreOfMassToBaseOfModel(void);
bool GetIsTouching(CVector const &center, float r); bool GetIsTouching(CVUVECTOR const &center, float r);
bool GetIsTouching(CEntity *other);
bool GetIsOnScreen(void); bool GetIsOnScreen(void);
bool GetIsOnScreenComplex(void); bool GetIsOnScreenComplex(void);
bool IsVisible(void); bool IsVisible(void);

View file

@ -224,7 +224,7 @@ CPhysical::RemoveAndAdd(void)
CRect CRect
CPhysical::GetBoundRect(void) CPhysical::GetBoundRect(void)
{ {
CVector center; CVUVECTOR center;
float radius; float radius;
GetBoundCentre(center); GetBoundCentre(center);
radius = GetBoundRadius(); radius = GetBoundRadius();
@ -1282,7 +1282,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
CPhysical *A, *B; CPhysical *A, *B;
CObject *Bobj; CObject *Bobj;
bool canshift; bool canshift;
CVector center; CVUVECTOR center;
float radius; float radius;
int numCollisions; int numCollisions;
@ -1441,7 +1441,7 @@ CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists)
{ {
static CColPoint aColPoints[MAX_COLLISION_POINTS]; static CColPoint aColPoints[MAX_COLLISION_POINTS];
float radius; float radius;
CVector center; CVUVECTOR center;
int listtype; int listtype;
CPhysical *A, *B; CPhysical *A, *B;
int numCollisions; int numCollisions;
@ -1608,7 +1608,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
{ {
static CColPoint aColPoints[MAX_COLLISION_POINTS]; static CColPoint aColPoints[MAX_COLLISION_POINTS];
float radius; float radius;
CVector center; CVUVECTOR center;
CPtrList *list; CPtrList *list;
CPhysical *A, *B; CPhysical *A, *B;
CObject *Aobj, *Bobj; CObject *Aobj, *Bobj;

View file

@ -22,6 +22,8 @@ public:
x = 1.0f; x = 1.0f;
} }
*/ */
// TODO: operator-
}; };
void TransformPoint(CVuVector &out, const CMatrix &mat, const CVuVector &in); void TransformPoint(CVuVector &out, const CMatrix &mat, const CVuVector &in);

View file

@ -38,6 +38,9 @@ public:
return ms_modelInfoPtrs[id]; return ms_modelInfoPtrs[id];
} }
static CBaseModelInfo *GetModelInfo(const char *name, int minIndex, int maxIndex); static CBaseModelInfo *GetModelInfo(const char *name, int minIndex, int maxIndex);
static CColModel *GetColModel(int id){
return ms_modelInfoPtrs[id]->GetColModel();
}
static bool IsBoatModel(int32 id); static bool IsBoatModel(int32 id);
static bool IsBikeModel(int32 id); static bool IsBikeModel(int32 id);

View file

@ -14,6 +14,7 @@ public:
CCutsceneObject(void); CCutsceneObject(void);
~CCutsceneObject(void); ~CCutsceneObject(void);
bool UpdatesInCutscene(void) { return true; }
void SetModelIndex(uint32 id); void SetModelIndex(uint32 id);
void CreateShadow(void); void CreateShadow(void);
void ProcessControl(void); void ProcessControl(void);

View file

@ -979,27 +979,30 @@ CPopulation::TestSafeForRealObject(CDummyObject *dummy)
{ {
CPtrNode *ptrNode; CPtrNode *ptrNode;
CColModel *dummyCol = dummy->GetColModel(); CColModel *dummyCol = dummy->GetColModel();
float colRadius = dummy->GetBoundRadius();
CVector colCentre = dummy->GetBoundCentre();
int minX = CWorld::GetSectorIndexX(dummy->GetPosition().x - colRadius); float radius = dummyCol->boundingSphere.radius;
int minX = CWorld::GetSectorIndexX(dummy->GetPosition().x - radius);
if (minX < 0) minX = 0; if (minX < 0) minX = 0;
int minY = CWorld::GetSectorIndexY(dummy->GetPosition().y - colRadius); int minY = CWorld::GetSectorIndexY(dummy->GetPosition().y - radius);
if (minY < 0) minY = 0; if (minY < 0) minY = 0;
int maxX = CWorld::GetSectorIndexX(dummy->GetPosition().x + colRadius); int maxX = CWorld::GetSectorIndexX(dummy->GetPosition().x + radius);
#ifdef FIX_BUGS #ifdef FIX_BUGS
if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1; if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
#else #else
if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X; if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
#endif #endif
int maxY = CWorld::GetSectorIndexY(dummy->GetPosition().y + colRadius); int maxY = CWorld::GetSectorIndexY(dummy->GetPosition().y + radius);
#ifdef FIX_BUGS #ifdef FIX_BUGS
if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1; if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
#else #else
if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y; if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
#endif #endif
float colRadius = dummy->GetBoundRadius();
CVUVECTOR colCentre;
dummy->GetBoundCentre(colCentre);
static CColPoint aTempColPoints[MAX_COLLISION_POINTS]; static CColPoint aTempColPoints[MAX_COLLISION_POINTS];
for (int curY = minY; curY <= maxY; curY++) { for (int curY = minY; curY <= maxY; curY++) {

View file

@ -913,9 +913,9 @@ CEntity::ProcessLightsForEntity(void)
effect->light.shadowSize, 0.0f, effect->light.shadowSize, 0.0f,
0.0f, -effect->light.shadowSize, 0.0f, -effect->light.shadowSize,
128, 128,
effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, effect->col.r,
effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, effect->col.g,
effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, effect->col.b,
15.0f, 1.0f, 40.0f, false, 0.0f); 15.0f, 1.0f, 40.0f, false, 0.0f);
}else if(lightFlickering){ }else if(lightFlickering){
CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,

View file

@ -513,8 +513,8 @@ bool CEntity::IsEntityOccluded(void) {
} }
if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) { if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) {
CVector min = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.min; CVector min = m_matrix * CModelInfo::GetColModel(m_modelIndex)->boundingBox.min;
CVector max = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.max; CVector max = m_matrix * CModelInfo::GetColModel(m_modelIndex)->boundingBox.max;
if (CalcScreenCoors(min, &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; if (CalcScreenCoors(min, &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
if (CalcScreenCoors(CVector(max.x, max.y, min.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; if (CalcScreenCoors(CVector(max.x, max.y, min.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;

View file

@ -1406,7 +1406,7 @@ CShadows::CastShadowSectorList(CPtrList &PtrList, float fStartX, float fStartY,
{ {
pEntity->m_scanCode = CWorld::GetCurrentScanCode(); pEntity->m_scanCode = CWorld::GetCurrentScanCode();
if ( pEntity->bUsesCollision && !pEntity->m_flagE2 ) if ( pEntity->bUsesCollision && !pEntity->bDontCastShadowsOn)
{ {
if ( IsAreaVisible(pEntity->m_area) ) if ( IsAreaVisible(pEntity->m_area) )
{ {

View file

@ -827,9 +827,9 @@ CVisibilityPlugins::PluginAttach(void)
return ms_atomicPluginOffset != -1 && ms_clumpPluginOffset != -1; return ms_atomicPluginOffset != -1 && ms_clumpPluginOffset != -1;
} }
#define ATOMICEXT(o) (RWPLUGINOFFSET(AtomicExt, o, ms_atomicPluginOffset)) #define ATOMICEXT(o) (RWPLUGINOFFSET(CVisibilityPlugins::AtomicExt, o, CVisibilityPlugins::ms_atomicPluginOffset))
#define FRAMEEXT(o) (RWPLUGINOFFSET(FrameExt, o, ms_framePluginOffset)) #define FRAMEEXT(o) (RWPLUGINOFFSET(CVisibilityPlugins::FrameExt, o, CVisibilityPlugins::ms_framePluginOffset))
#define CLUMPEXT(o) (RWPLUGINOFFSET(ClumpExt, o, ms_clumpPluginOffset)) #define CLUMPEXT(o) (RWPLUGINOFFSET(CVisibilityPlugins::ClumpExt, o, CVisibilityPlugins::ms_clumpPluginOffset))
// //
// Atomic // Atomic
@ -839,6 +839,7 @@ void*
CVisibilityPlugins::AtomicConstructor(void *object, int32, int32) CVisibilityPlugins::AtomicConstructor(void *object, int32, int32)
{ {
ATOMICEXT(object)->modelInfo = nil; ATOMICEXT(object)->modelInfo = nil;
ATOMICEXT(object)->distanceAlpha = 255;
return object; return object;
} }
@ -991,3 +992,56 @@ CVisibilityPlugins::GetClumpAlpha(RpClump *clump)
{ {
return CLUMPEXT(clump)->alpha; return CLUMPEXT(clump)->alpha;
} }
// LCS walks the atomic list manually but we want to be compatible with both RW and librw,
// so this code isn't quite original and uses callbacks instead.
static RpAtomic*
SetAtomicDistanceAlphaCB(RpAtomic *atomic, void *data)
{
ATOMICEXT(atomic)->distanceAlpha = *(int*)data;
return atomic;
}
void
CVisibilityPlugins::SetClumpDistanceAlpha(RpClump *clump, int alpha)
{
RpClumpForAllAtomics(clump, SetAtomicDistanceAlphaCB, &alpha);
}
static RpAtomic*
GetAtomicDistanceAlphaCB(RpAtomic *atomic, void *data)
{
*(int*)data = ATOMICEXT(atomic)->distanceAlpha;
return atomic;
}
int
CVisibilityPlugins::GetClumpDistanceAlpha(RpClump *clump)
{
int alpha = 255;
RpClumpForAllAtomics(clump, GetAtomicDistanceAlphaCB, &alpha);
return alpha;
}
void
CVisibilityPlugins::SetObjectDistanceAlpha(RwObject *object, int alpha)
{
if(object == nil)
return;
if(RwObjectGetType(object) == rpATOMIC)
ATOMICEXT(object)->distanceAlpha = alpha;
else
SetClumpDistanceAlpha((RpClump*)object, alpha);
}
int
CVisibilityPlugins::GetObjectDistanceAlpha(RwObject *object)
{
if(object == nil)
return 255;
if(RwObjectGetType(object) == rpATOMIC)
return ATOMICEXT(object)->distanceAlpha;
else
return GetClumpDistanceAlpha((RpClump*)object);
}

View file

@ -97,10 +97,13 @@ public:
// RW Plugins // RW Plugins
// //
union AtomicExt struct AtomicExt
{ {
CSimpleModelInfo *modelInfo; // used by SimpleModelInfo union {
int flags; // used by ClumpModelInfo CSimpleModelInfo *modelInfo; // used by SimpleModelInfo
int flags; // used by ClumpModelInfo
};
int distanceAlpha; // not sure where this is in PS2/PSP LCS
}; };
static void SetAtomicModelInfo(RpAtomic*, CSimpleModelInfo*); static void SetAtomicModelInfo(RpAtomic*, CSimpleModelInfo*);
static CSimpleModelInfo *GetAtomicModelInfo(RpAtomic *atomic); static CSimpleModelInfo *GetAtomicModelInfo(RpAtomic *atomic);
@ -129,7 +132,6 @@ public:
int32 offset, int32 len); int32 offset, int32 len);
static int32 ms_framePluginOffset; static int32 ms_framePluginOffset;
// Not actually used
struct ClumpExt struct ClumpExt
{ {
ClumpVisibilityCB visibilityCB; ClumpVisibilityCB visibilityCB;
@ -138,6 +140,8 @@ public:
static void SetClumpModelInfo(RpClump*, CClumpModelInfo*); static void SetClumpModelInfo(RpClump*, CClumpModelInfo*);
static void SetClumpAlpha(RpClump*, int); static void SetClumpAlpha(RpClump*, int);
static int GetClumpAlpha(RpClump*); static int GetClumpAlpha(RpClump*);
static void SetClumpDistanceAlpha(RpClump*, int);
static int GetClumpDistanceAlpha(RpClump*);
static void *ClumpConstructor(void *object, int32 offset, int32 len); static void *ClumpConstructor(void *object, int32 offset, int32 len);
static void *ClumpDestructor(void *object, int32 offset, int32 len); static void *ClumpDestructor(void *object, int32 offset, int32 len);
@ -145,6 +149,9 @@ public:
int32 offset, int32 len); int32 offset, int32 len);
static int32 ms_clumpPluginOffset; static int32 ms_clumpPluginOffset;
static void SetObjectDistanceAlpha(RwObject *object, int alpha);
static int GetObjectDistanceAlpha(RwObject *object);
static bool PluginAttach(void); static bool PluginAttach(void);
}; };