From e014bb5359ae464f14a413dd5ee98f0b5a385f67 Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 23 May 2021 17:55:55 +0200 Subject: CEntity done; C(Vu)Vector fixes and cleanup --- src/core/Camera.cpp | 9 +-- src/core/Camera.h | 6 +- src/core/References.cpp | 2 - src/core/World.cpp | 47 +++++++++------- src/core/World.h | 1 + src/core/common.h | 6 ++ src/entities/Entity.cpp | 130 +++++++++++++++++++++++++++++++++---------- src/entities/Entity.h | 21 ++++++- src/entities/Physical.cpp | 8 +-- src/math/VuVector.h | 2 + src/modelinfo/ModelInfo.h | 3 + src/objects/CutsceneObject.h | 1 + src/peds/Population.cpp | 15 +++-- src/render/Coronas.cpp | 6 +- src/render/Occlusion.cpp | 4 +- src/render/Shadows.cpp | 2 +- src/rw/VisibilityPlugins.cpp | 60 +++++++++++++++++++- src/rw/VisibilityPlugins.h | 15 +++-- 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 ¢er, float radius, const CMatrix *mat bool CCamera::IsSphereVisible(const CVector ¢er, 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 ¢er, const CMatrix *mat); bool IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat); bool IsSphereVisible(const CVector ¢er, 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 ¢er, float radius) +{ + CVUVECTOR boundCenter; + GetBoundCentre(boundCenter); + return sq(GetBoundRadius()+radius) > (boundCenter-center).MagnitudeSqr(); +} + bool -CEntity::GetIsTouching(CVector const ¢er, 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 ¢er, float r); + bool GetIsTouching(CVUVECTOR const ¢er, 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); }; -- cgit v1.2.3