summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraap <aap@papnet.eu>2021-05-23 17:55:55 +0200
committerSergeanur <s.anureev@yandex.ua>2021-06-24 20:45:21 +0200
commite014bb5359ae464f14a413dd5ee98f0b5a385f67 (patch)
tree0a687f497f318c4a849e7054f05851a73f2f0c0c
parentUndef PS2_AUDIO_CHANNELS for SQUEEZE_PERFORMANCE and VANILLA_DEFINES (diff)
downloadre3-e014bb5359ae464f14a413dd5ee98f0b5a385f67.tar
re3-e014bb5359ae464f14a413dd5ee98f0b5a385f67.tar.gz
re3-e014bb5359ae464f14a413dd5ee98f0b5a385f67.tar.bz2
re3-e014bb5359ae464f14a413dd5ee98f0b5a385f67.tar.lz
re3-e014bb5359ae464f14a413dd5ee98f0b5a385f67.tar.xz
re3-e014bb5359ae464f14a413dd5ee98f0b5a385f67.tar.zst
re3-e014bb5359ae464f14a413dd5ee98f0b5a385f67.zip
-rw-r--r--src/core/Camera.cpp9
-rw-r--r--src/core/Camera.h6
-rw-r--r--src/core/References.cpp2
-rw-r--r--src/core/World.cpp47
-rw-r--r--src/core/World.h1
-rw-r--r--src/core/common.h6
-rw-r--r--src/entities/Entity.cpp130
-rw-r--r--src/entities/Entity.h21
-rw-r--r--src/entities/Physical.cpp8
-rw-r--r--src/math/VuVector.h2
-rw-r--r--src/modelinfo/ModelInfo.h3
-rw-r--r--src/objects/CutsceneObject.h1
-rw-r--r--src/peds/Population.cpp15
-rw-r--r--src/render/Coronas.cpp6
-rw-r--r--src/render/Occlusion.cpp4
-rw-r--r--src/render/Shadows.cpp2
-rw-r--r--src/rw/VisibilityPlugins.cpp60
-rw-r--r--src/rw/VisibilityPlugins.h15
18 files changed, 249 insertions, 89 deletions
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 373ede7d..35d4ea7d 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -4103,16 +4103,11 @@ CCamera::IsSphereVisible(const CVector &center, float radius, const CMatrix *mat
bool
CCamera::IsSphereVisible(const CVector &center, float radius)
{
- CMatrix mat = m_cameraMatrix;
- return IsSphereVisible(center, radius, &mat);
+ return IsSphereVisible(center, radius, &m_cameraMatrix);
}
bool
-#ifdef GTA_PS2
-CCamera::IsBoxVisible(CVuVector *box, const CMatrix *mat)
-#else
-CCamera::IsBoxVisible(CVector *box, const CMatrix *mat)
-#endif
+CCamera::IsBoxVisible(CVUVECTOR *box, const CMatrix *mat)
{
int i;
int frustumTests[6] = { 0 };
diff --git a/src/core/Camera.h b/src/core/Camera.h
index 9354e8ed..66a89f21 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -634,11 +634,7 @@ public:
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);
-#ifdef GTA_PS2
- bool IsBoxVisible(CVuVector *box, const CMatrix *mat);
-#else
- bool IsBoxVisible(CVector *box, const CMatrix *mat);
-#endif
+ bool IsBoxVisible(CVUVECTOR *box, const CMatrix *mat);
};
VALIDATE_SIZE(CCamera, 0xE9D8);
diff --git a/src/core/References.cpp b/src/core/References.cpp
index dc83d96d..09913817 100644
--- a/src/core/References.cpp
+++ b/src/core/References.cpp
@@ -39,9 +39,7 @@ CEntity::RegisterReference(CEntity **pent)
ref->pentity = pent;
ref->next = m_pFirstReference;
m_pFirstReference = ref;
- return;
}
- return;
}
// Clean up the reference from *pent -> 'this'
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 9e7a6fc4..9e2c4345 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -1906,16 +1906,7 @@ CWorld::Process(void)
for(int i = 0; i < NUMCUTSCENEOBJECTS; i++) {
CCutsceneObject *csObj = CCutsceneMgr::GetCutsceneObject(i);
if(csObj && csObj->m_entryInfoList.first) {
- if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP &&
- 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->UpdateAnim();
csObj->ProcessControl();
csObj->ProcessCollision();
csObj->GetMatrix().UpdateRW();
@@ -1927,26 +1918,40 @@ CWorld::Process(void)
} else {
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CEntity *movingEnt = (CEntity *)node->item;
- if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
- RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) {
- if (movingEnt->IsObject())
- RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepNonClippedInSeconds());
- else {
- if (!movingEnt->bOffscreen)
- movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
- RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepInSeconds(), !movingEnt->bOffscreen);
- }
- }
+ if(!movingEnt->bRemoveFromWorld)
+ movingEnt->UpdateAnim();
}
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CPhysical *movingEnt = (CPhysical *)node->item;
if(movingEnt->bRemoveFromWorld) {
RemoveEntityInsteadOfProcessingIt(movingEnt);
} else {
- movingEnt->ProcessControl();
+ if(!CCutsceneMgr::IsCutsceneProcessing() || movingEnt->UpdatesInCutscene())
+ movingEnt->ProcessControl();
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;
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CPhysical *movingEnt = (CPhysical *)node->item;
diff --git a/src/core/World.h b/src/core/World.h
index b75b6a6c..c90bb3a1 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -29,6 +29,7 @@ enum
{
ENTITYLIST_BUILDINGS,
ENTITYLIST_BUILDINGS_OVERLAP,
+ ENTITYLIST_UNKNOWN,
ENTITYLIST_OBJECTS,
ENTITYLIST_OBJECTS_OVERLAP,
ENTITYLIST_VEHICLES,
diff --git a/src/core/common.h b/src/core/common.h
index 268bc836..51170986 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -228,6 +228,12 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w)
#include "maths.h"
#include "Vector.h"
+#ifdef GTA_PS2
+#include "VuVector.h"
+#define CVUVECTOR CVuVector
+#else
+#define CVUVECTOR CVector
+#endif
#include "Vector2D.h"
#include "Matrix.h"
#include "Rect.h"
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 988649ef..d106898d 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -26,6 +26,12 @@
#include "Ped.h"
#include "Dummy.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;
@@ -71,13 +77,18 @@ CEntity::CEntity(void)
bDistanceFade = false;
m_flagE1 = false;
- m_flagE2 = false;
+ bDontCastShadowsOn = false;
bOffscreen = false;
bIsStaticWaitingForCollision = false;
bDontStream = false;
bUnderwater = false;
bHasPreRenderEffects = false;
+ bIsTreeModel = false;
+ m_flagG2 = false;
+ m_flagG4 = false;
+ m_flagG8 = false;
+
m_scanCode = 0;
m_modelIndex = -1;
m_rwObject = nil;
@@ -96,6 +107,8 @@ void
CEntity::SetModelIndex(uint32 id)
{
m_modelIndex = id;
+ bIsTreeModel = IsTreeModel(m_modelIndex);
+ bDrawLast |= bIsTreeModel;
bHasPreRenderEffects = HasPreRenderEffects();
CreateRwObject();
}
@@ -104,6 +117,8 @@ void
CEntity::SetModelIndexNoCreate(uint32 id)
{
m_modelIndex = id;
+ bIsTreeModel = IsTreeModel(m_modelIndex);
+ bDrawLast |= bIsTreeModel;
bHasPreRenderEffects = HasPreRenderEffects();
}
@@ -126,6 +141,7 @@ CEntity::CreateRwObject(void)
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
GetMatrix().AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump *)m_rwObject)), false);
+ // useless IsTextureLoaded();
mi->AddRef();
}
}
@@ -182,9 +198,11 @@ CEntity::DeleteRwObject(void)
if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC){
f = RpAtomicGetFrame((RpAtomic*)m_rwObject);
+ CStreaming::UnregisterInstance((RpAtomic*)m_rwObject, nil);
RpAtomicDestroy((RpAtomic*)m_rwObject);
RwFrameDestroy(f);
}else if(RwObjectGetType(m_rwObject) == rpCLUMP){
+ CStreaming::UnregisterInstance((RpClump*)m_rwObject);
if(IsClumpSkinned((RpClump*)m_rwObject))
RpClumpForAllAtomics((RpClump*)m_rwObject, AtomicRemoveAnimFromSkinCB, nil);
RpClumpDestroy((RpClump*)m_rwObject);
@@ -201,7 +219,7 @@ CEntity::GetBoundRect(void)
{
CRect rect;
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.max);
@@ -220,21 +238,27 @@ CEntity::GetBoundRect(void)
CVector
CEntity::GetBoundCentre(void)
{
- CVector v;
- GetBoundCentre(v);
- return v;
+ return GetMatrix() * CModelInfo::GetColModel(m_modelIndex)->boundingSphere.center;
}
+#ifdef GTA_PS2
+void
+CEntity::GetBoundCentre(CVuVector &out)
+{
+ TransformPoint(out, GetMatrix(), CModelInfo::GetColModel(m_modelIndex)->boundingSphere.center);
+}
+#else
void
CEntity::GetBoundCentre(CVector &out)
{
- out = GetMatrix() * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center;
+ out = GetMatrix() * CModelInfo::GetColModel(m_modelIndex)->boundingSphere.center;
}
+#endif
float
CEntity::GetBoundRadius(void)
{
- return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius;
+ return CModelInfo::GetColModel(m_modelIndex)->boundingSphere.radius;
}
void
@@ -244,9 +268,18 @@ CEntity::UpdateRwFrame(void)
RwFrameUpdateObjects((RwFrame*)rwObjectGetParent(m_rwObject));
}
+bool
+PauseEntityAnims(void)
+{
+ return CSpecialFX::bSnapShotActive;
+}
+
void
CEntity::UpdateRpHAnim(void)
{
+ if(PauseEntityAnims())
+ return;
+
if(IsClumpSkinned(GetClump())){
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
RpHAnimHierarchyUpdateMatrices(hier);
@@ -308,9 +341,10 @@ CEntity::PreRender(void)
if(!bHasPreRenderEffects)
return;
+ // separate function in LCS but we don't know the name
switch(m_type){
case ENTITY_TYPE_BUILDING:
- if(IsTreeModel(GetModelIndex())){
+ if(bIsTreeModel){
float dist = (TheCamera.GetPosition() - GetPosition()).Magnitude2D();
CObject::fDistToNearestTree = Min(CObject::fDistToNearestTree, dist);
ModifyMatrixForTreeInWind();
@@ -373,7 +407,7 @@ CEntity::PreRender(void)
CVector pos = GetPosition();
CShadows::StoreShadowToBeRendered(SHADOWTYPE_DARK,
gpShadowPedTex, &pos,
- 0.4f, 0.0f, 0.0f, -0.4f,
+ 0.4f, 0.0f, 0.0f, 0.4f,
CTimeCycle::GetShadowStrength(),
CTimeCycle::GetShadowStrength(),
CTimeCycle::GetShadowStrength(),
@@ -409,19 +443,65 @@ void
CEntity::Render(void)
{
if(m_rwObject){
- bImBeingRendered = true;
- if(RwObjectGetType(m_rwObject) == rpATOMIC)
- RpAtomicRender((RpAtomic*)m_rwObject);
- else
- RpClumpRender((RpClump*)m_rwObject);
- bImBeingRendered = false;
+ if(CVisibilityPlugins::GetObjectDistanceAlpha(m_rwObject) != 0){
+ // NB: LCS does not use bImBeingRendered here,
+ // but that may be due to the streamed world. better keep it for safety
+ bImBeingRendered = true;
+ if(RwObjectGetType(m_rwObject) == rpATOMIC)
+ 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
-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
@@ -439,8 +519,7 @@ CEntity::IsVisibleComplex(void)
bool
CEntity::GetIsOnScreen(void)
{
- return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(),
- &TheCamera.GetCameraMatrix());
+ return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius());
}
bool
@@ -456,7 +535,7 @@ CEntity::GetIsOnScreenComplex(void)
return true;
CRect rect = GetBoundRect();
- CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel();
+ CColModel *colmodel = CModelInfo::GetColModel(m_modelIndex);
float z = GetPosition().z;
float minz = z + colmodel->boundingBox.min.z;
float maxz = z + colmodel->boundingBox.max.z;
@@ -611,7 +690,7 @@ CEntity::Remove(void)
float
CEntity::GetDistanceFromCentreOfMassToBaseOfModel(void)
{
- return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z;
+ return -CModelInfo::GetColModel(m_modelIndex)->boundingBox.min.z;
}
void
@@ -737,11 +816,6 @@ CEntity::PreRenderForGlassWindow(void)
bIsVisible = false;
}
-/*
-0x487A10 - SetAtomicAlphaCB
-0x4879E0 - SetClumpAlphaCB
-*/
-
RpMaterial*
SetAtomicAlphaCB(RpMaterial *material, void *data)
{
@@ -840,7 +914,7 @@ CEntity::SaveEntityFlags(uint8*& buf)
if (bDistanceFade) tmp |= BIT(7);
if (m_flagE1) tmp |= BIT(8);
- if (m_flagE2) tmp |= BIT(9);
+ if (bDontCastShadowsOn) tmp |= BIT(9);
if (bOffscreen) tmp |= BIT(10);
if (bIsStaticWaitingForCollision) tmp |= BIT(11);
if (bDontStream) tmp |= BIT(12);
@@ -896,7 +970,7 @@ CEntity::LoadEntityFlags(uint8*& buf)
bDistanceFade = !!(tmp & BIT(7));
m_flagE1 = !!(tmp & BIT(8));
- m_flagE2 = !!(tmp & BIT(9));
+ bDontCastShadowsOn = !!(tmp & BIT(9));
bOffscreen = !!(tmp & BIT(10));
bIsStaticWaitingForCollision = !!(tmp & BIT(11));
bDontStream = !!(tmp & BIT(12));
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index c7a6f881..4db58eef 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -43,6 +43,7 @@ private:
uint32 m_status : 5;
public:
// flagsA
+ // LCS flagsB 02
uint32 bUsesCollision : 1; // does entity use collision
uint32 bCollisionProcessed : 1; // has object been processed by a ProcessEntityCollision function
uint32 bIsStatic : 1; // is entity static
@@ -50,6 +51,7 @@ public:
uint32 bPedPhysics : 1;
uint32 bIsStuck : 1; // is entity stuck
uint32 bIsInSafePosition : 1; // is entity in a collision free safe position
+ // LCS flagsC
uint32 bUseCollisionRecords : 1;
// flagsB
@@ -60,6 +62,7 @@ public:
uint32 bRenderScorched : 1;
uint32 bHasBlip : 1;
uint32 bIsBIGBuilding : 1; // Set if this entity is a big building
+ // LCS flagsD
uint32 bStreamBIGBuilding : 1; // set when draw dist <= 2000
// flagsC
@@ -70,6 +73,7 @@ public:
uint32 bMeleeProof : 1;
uint32 bOnlyDamagedByPlayer : 1;
uint32 bStreamingDontDelete : 1; // Dont let the streaming remove this
+ // LCS flagsE
uint32 bRemoveFromWorld : 1; // remove this entity next time it should be processed
// flagsD
@@ -80,17 +84,24 @@ public:
uint32 bDrawLast : 1; // draw object last
uint32 bNoBrightHeadLights : 1;
uint32 bDoNotRender : 1; //-- only applies to CObjects apparently
+ // LCS flagsF
uint32 bDistanceFade : 1; // Fade entity because it is far away
// flagsE
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 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 bUnderwater : 1; // this object is underwater change drawing order
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_randomSeed;
int16 m_modelIndex;
@@ -118,6 +129,7 @@ public:
virtual void Add(void);
virtual void Remove(void);
+ virtual bool UpdatesInCutscene(void) { return false; }
virtual void SetModelIndex(uint32 id);
virtual void SetModelIndexNoCreate(uint32 id);
virtual void CreateRwObject(void);
@@ -129,6 +141,7 @@ public:
virtual void Teleport(CVector v) {}
virtual void PreRender(void);
virtual void Render(void);
+ virtual void UpdateAnim(void);
virtual bool SetupLighting(void);
virtual void RemoveLighting(bool);
virtual void FlagToDestroyWhenNextProcessed(void) {}
@@ -148,11 +161,13 @@ public:
return (RpClump*)m_rwObject;
}
- void GetBoundCentre(CVector &out);
+ void UpdateDistanceFade(void);
+ void GetBoundCentre(CVUVECTOR &out);
CVector GetBoundCentre(void);
float GetBoundRadius(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 GetIsOnScreenComplex(void);
bool IsVisible(void);
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index 08516b75..2c554c8e 100644
--- a/src/entities/Physical.cpp
+++ b/src/entities/Physical.cpp
@@ -224,7 +224,7 @@ CPhysical::RemoveAndAdd(void)
CRect
CPhysical::GetBoundRect(void)
{
- CVector center;
+ CVUVECTOR center;
float radius;
GetBoundCentre(center);
radius = GetBoundRadius();
@@ -1282,7 +1282,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
CPhysical *A, *B;
CObject *Bobj;
bool canshift;
- CVector center;
+ CVUVECTOR center;
float radius;
int numCollisions;
@@ -1441,7 +1441,7 @@ CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists)
{
static CColPoint aColPoints[MAX_COLLISION_POINTS];
float radius;
- CVector center;
+ CVUVECTOR center;
int listtype;
CPhysical *A, *B;
int numCollisions;
@@ -1608,7 +1608,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
{
static CColPoint aColPoints[MAX_COLLISION_POINTS];
float radius;
- CVector center;
+ CVUVECTOR center;
CPtrList *list;
CPhysical *A, *B;
CObject *Aobj, *Bobj;
diff --git a/src/math/VuVector.h b/src/math/VuVector.h
index 026965d1..ccaa4cfb 100644
--- a/src/math/VuVector.h
+++ b/src/math/VuVector.h
@@ -22,6 +22,8 @@ public:
x = 1.0f;
}
*/
+
+ // TODO: operator-
};
void TransformPoint(CVuVector &out, const CMatrix &mat, const CVuVector &in);
diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h
index 30f4c015..f92a73ad 100644
--- a/src/modelinfo/ModelInfo.h
+++ b/src/modelinfo/ModelInfo.h
@@ -38,6 +38,9 @@ public:
return ms_modelInfoPtrs[id];
}
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 IsBikeModel(int32 id);
diff --git a/src/objects/CutsceneObject.h b/src/objects/CutsceneObject.h
index af24c0a6..b0659c08 100644
--- a/src/objects/CutsceneObject.h
+++ b/src/objects/CutsceneObject.h
@@ -14,6 +14,7 @@ public:
CCutsceneObject(void);
~CCutsceneObject(void);
+ bool UpdatesInCutscene(void) { return true; }
void SetModelIndex(uint32 id);
void CreateShadow(void);
void ProcessControl(void);
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index b8984165..f0e41231 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -979,27 +979,30 @@ CPopulation::TestSafeForRealObject(CDummyObject *dummy)
{
CPtrNode *ptrNode;
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;
- int minY = CWorld::GetSectorIndexY(dummy->GetPosition().y - colRadius);
+ int minY = CWorld::GetSectorIndexY(dummy->GetPosition().y - radius);
if (minY < 0) minY = 0;
- int maxX = CWorld::GetSectorIndexX(dummy->GetPosition().x + colRadius);
+ int maxX = CWorld::GetSectorIndexX(dummy->GetPosition().x + radius);
#ifdef FIX_BUGS
if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
#else
if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
#endif
- int maxY = CWorld::GetSectorIndexY(dummy->GetPosition().y + colRadius);
+ int maxY = CWorld::GetSectorIndexY(dummy->GetPosition().y + radius);
#ifdef FIX_BUGS
if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
#else
if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
#endif
+ float colRadius = dummy->GetBoundRadius();
+ CVUVECTOR colCentre;
+ dummy->GetBoundCentre(colCentre);
+
static CColPoint aTempColPoints[MAX_COLLISION_POINTS];
for (int curY = minY; curY <= maxY; curY++) {
diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp
index 8b137aad..1ac3263c 100644
--- a/src/render/Coronas.cpp
+++ b/src/render/Coronas.cpp
@@ -913,9 +913,9 @@ CEntity::ProcessLightsForEntity(void)
effect->light.shadowSize, 0.0f,
0.0f, -effect->light.shadowSize,
128,
- effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
- effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
- effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
+ effect->col.r,
+ effect->col.g,
+ effect->col.b,
15.0f, 1.0f, 40.0f, false, 0.0f);
}else if(lightFlickering){
CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,
diff --git a/src/render/Occlusion.cpp b/src/render/Occlusion.cpp
index 3ea5678c..ec7101a6 100644
--- a/src/render/Occlusion.cpp
+++ b/src/render/Occlusion.cpp
@@ -513,8 +513,8 @@ bool CEntity::IsEntityOccluded(void) {
}
if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) {
- CVector min = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.min;
- CVector max = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.max;
+ CVector min = m_matrix * CModelInfo::GetColModel(m_modelIndex)->boundingBox.min;
+ 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(CVector(max.x, max.y, min.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp
index 64b09395..ae4cf724 100644
--- a/src/render/Shadows.cpp
+++ b/src/render/Shadows.cpp
@@ -1406,7 +1406,7 @@ CShadows::CastShadowSectorList(CPtrList &PtrList, float fStartX, float fStartY,
{
pEntity->m_scanCode = CWorld::GetCurrentScanCode();
- if ( pEntity->bUsesCollision && !pEntity->m_flagE2 )
+ if ( pEntity->bUsesCollision && !pEntity->bDontCastShadowsOn)
{
if ( IsAreaVisible(pEntity->m_area) )
{
diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp
index eebbb93b..ffd7b18a 100644
--- a/src/rw/VisibilityPlugins.cpp
+++ b/src/rw/VisibilityPlugins.cpp
@@ -827,9 +827,9 @@ CVisibilityPlugins::PluginAttach(void)
return ms_atomicPluginOffset != -1 && ms_clumpPluginOffset != -1;
}
-#define ATOMICEXT(o) (RWPLUGINOFFSET(AtomicExt, o, ms_atomicPluginOffset))
-#define FRAMEEXT(o) (RWPLUGINOFFSET(FrameExt, o, ms_framePluginOffset))
-#define CLUMPEXT(o) (RWPLUGINOFFSET(ClumpExt, o, ms_clumpPluginOffset))
+#define ATOMICEXT(o) (RWPLUGINOFFSET(CVisibilityPlugins::AtomicExt, o, CVisibilityPlugins::ms_atomicPluginOffset))
+#define FRAMEEXT(o) (RWPLUGINOFFSET(CVisibilityPlugins::FrameExt, o, CVisibilityPlugins::ms_framePluginOffset))
+#define CLUMPEXT(o) (RWPLUGINOFFSET(CVisibilityPlugins::ClumpExt, o, CVisibilityPlugins::ms_clumpPluginOffset))
//
// Atomic
@@ -839,6 +839,7 @@ void*
CVisibilityPlugins::AtomicConstructor(void *object, int32, int32)
{
ATOMICEXT(object)->modelInfo = nil;
+ ATOMICEXT(object)->distanceAlpha = 255;
return object;
}
@@ -991,3 +992,56 @@ CVisibilityPlugins::GetClumpAlpha(RpClump *clump)
{
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);
+}
diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h
index f188096c..3a3e555b 100644
--- a/src/rw/VisibilityPlugins.h
+++ b/src/rw/VisibilityPlugins.h
@@ -97,10 +97,13 @@ public:
// RW Plugins
//
- union AtomicExt
+ struct AtomicExt
{
- CSimpleModelInfo *modelInfo; // used by SimpleModelInfo
- int flags; // used by ClumpModelInfo
+ union {
+ 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 CSimpleModelInfo *GetAtomicModelInfo(RpAtomic *atomic);
@@ -129,7 +132,6 @@ public:
int32 offset, int32 len);
static int32 ms_framePluginOffset;
- // Not actually used
struct ClumpExt
{
ClumpVisibilityCB visibilityCB;
@@ -138,6 +140,8 @@ public:
static void SetClumpModelInfo(RpClump*, CClumpModelInfo*);
static void SetClumpAlpha(RpClump*, int);
static int GetClumpAlpha(RpClump*);
+ static void SetClumpDistanceAlpha(RpClump*, int);
+ static int GetClumpDistanceAlpha(RpClump*);
static void *ClumpConstructor(void *object, int32 offset, int32 len);
static void *ClumpDestructor(void *object, int32 offset, int32 len);
@@ -145,6 +149,9 @@ public:
int32 offset, int32 len);
static int32 ms_clumpPluginOffset;
+ static void SetObjectDistanceAlpha(RwObject *object, int alpha);
+ static int GetObjectDistanceAlpha(RwObject *object);
+
static bool PluginAttach(void);
};