From b9e97ab79db84785838f1b995188c37328c26071 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Tue, 29 Dec 2020 13:55:26 +0200 Subject: Reorder CEntity functions into their original order --- src/entities/Entity.cpp | 1023 ++++++++++++++++------------------------------- src/entities/Entity.h | 14 +- 2 files changed, 344 insertions(+), 693 deletions(-) (limited to 'src/entities') diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 9db36bcf..9b6be5f6 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -4,35 +4,27 @@ #include "RwHelper.h" #include "ModelIndices.h" #include "Timer.h" -#include "Placeable.h" #include "Entity.h" #include "Object.h" -#include "ParticleObject.h" -#include "Lights.h" #include "World.h" #include "Camera.h" #include "Glass.h" -#include "Clock.h" #include "Weather.h" #include "Timecycle.h" -#include "Bridge.h" #include "TrafficLights.h" #include "Coronas.h" #include "PointLights.h" #include "Shadows.h" #include "Pickups.h" #include "SpecialFX.h" -#include "References.h" #include "TxdStore.h" #include "Zones.h" +#include "MemoryHeap.h" #include "Bones.h" #include "Debug.h" -#include "Renderer.h" #include "Ped.h" #include "Dummy.h" #include "WindModifiers.h" -#include "Occlusion.h" -#include "MemoryHeap.h" //--MIAMI: file done @@ -101,186 +93,6 @@ CEntity::~CEntity(void) ResolveReferences(); } -void -CEntity::GetBoundCentre(CVector &out) -{ - out = m_matrix * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center; -}; - -bool -CEntity::GetIsTouching(CVector const ¢er, float radius) -{ - return sq(GetBoundRadius()+radius) > (GetBoundCentre()-center).MagnitudeSqr(); -} - -bool -CEntity::GetIsOnScreen(void) -{ - return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(), - &TheCamera.GetCameraMatrix()); -} - -bool -CEntity::GetIsOnScreenComplex(void) -{ - RwV3d boundBox[8]; - - if(TheCamera.IsPointVisible(GetBoundCentre(), &TheCamera.GetCameraMatrix())) - return true; - - CRect rect = GetBoundRect(); - CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); - float z = GetPosition().z; - float minz = z + colmodel->boundingBox.min.z; - float maxz = z + colmodel->boundingBox.max.z; - boundBox[0].x = rect.left; - boundBox[0].y = rect.bottom; - boundBox[0].z = minz; - boundBox[1].x = rect.left; - boundBox[1].y = rect.top; - boundBox[1].z = minz; - boundBox[2].x = rect.right; - boundBox[2].y = rect.bottom; - boundBox[2].z = minz; - boundBox[3].x = rect.right; - boundBox[3].y = rect.top; - boundBox[3].z = minz; - boundBox[4].x = rect.left; - boundBox[4].y = rect.bottom; - boundBox[4].z = maxz; - boundBox[5].x = rect.left; - boundBox[5].y = rect.top; - boundBox[5].z = maxz; - boundBox[6].x = rect.right; - boundBox[6].y = rect.bottom; - boundBox[6].z = maxz; - boundBox[7].x = rect.right; - boundBox[7].y = rect.top; - boundBox[7].z = maxz; - - return TheCamera.IsBoxVisible(boundBox, &TheCamera.GetCameraMatrix()); -} - -void -CEntity::Add(void) -{ - int x, xstart, xmid, xend; - int y, ystart, ymid, yend; - CSector *s; - CPtrList *list; - - CRect bounds = GetBoundRect(); - xstart = CWorld::GetSectorIndexX(bounds.left); - xend = CWorld::GetSectorIndexX(bounds.right); - xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f); - ystart = CWorld::GetSectorIndexY(bounds.top); - yend = CWorld::GetSectorIndexY(bounds.bottom); - ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f); - assert(xstart >= 0); - assert(xend < NUMSECTORS_X); - assert(ystart >= 0); - assert(yend < NUMSECTORS_Y); - - for(y = ystart; y <= yend; y++) - for(x = xstart; x <= xend; x++){ - s = CWorld::GetSector(x, y); - if(x == xmid && y == ymid) switch(m_type){ - case ENTITY_TYPE_BUILDING: - list = &s->m_lists[ENTITYLIST_BUILDINGS]; - break; - case ENTITY_TYPE_VEHICLE: - list = &s->m_lists[ENTITYLIST_VEHICLES]; - break; - case ENTITY_TYPE_PED: - list = &s->m_lists[ENTITYLIST_PEDS]; - break; - case ENTITY_TYPE_OBJECT: - list = &s->m_lists[ENTITYLIST_OBJECTS]; - break; - case ENTITY_TYPE_DUMMY: - list = &s->m_lists[ENTITYLIST_DUMMIES]; - break; - }else switch(m_type){ - case ENTITY_TYPE_BUILDING: - list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]; - break; - case ENTITY_TYPE_VEHICLE: - list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP]; - break; - case ENTITY_TYPE_PED: - list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP]; - break; - case ENTITY_TYPE_OBJECT: - list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP]; - break; - case ENTITY_TYPE_DUMMY: - list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP]; - break; - } - list->InsertItem(this); - } -} - -void -CEntity::Remove(void) -{ - int x, xstart, xmid, xend; - int y, ystart, ymid, yend; - CSector *s; - CPtrList *list; - - CRect bounds = GetBoundRect(); - xstart = CWorld::GetSectorIndexX(bounds.left); - xend = CWorld::GetSectorIndexX(bounds.right); - xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f); - ystart = CWorld::GetSectorIndexY(bounds.top); - yend = CWorld::GetSectorIndexY(bounds.bottom); - ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f); - assert(xstart >= 0); - assert(xend < NUMSECTORS_X); - assert(ystart >= 0); - assert(yend < NUMSECTORS_Y); - - for(y = ystart; y <= yend; y++) - for(x = xstart; x <= xend; x++){ - s = CWorld::GetSector(x, y); - if(x == xmid && y == ymid) switch(m_type){ - case ENTITY_TYPE_BUILDING: - list = &s->m_lists[ENTITYLIST_BUILDINGS]; - break; - case ENTITY_TYPE_VEHICLE: - list = &s->m_lists[ENTITYLIST_VEHICLES]; - break; - case ENTITY_TYPE_PED: - list = &s->m_lists[ENTITYLIST_PEDS]; - break; - case ENTITY_TYPE_OBJECT: - list = &s->m_lists[ENTITYLIST_OBJECTS]; - break; - case ENTITY_TYPE_DUMMY: - list = &s->m_lists[ENTITYLIST_DUMMIES]; - break; - }else switch(m_type){ - case ENTITY_TYPE_BUILDING: - list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]; - break; - case ENTITY_TYPE_VEHICLE: - list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP]; - break; - case ENTITY_TYPE_PED: - list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP]; - break; - case ENTITY_TYPE_OBJECT: - list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP]; - break; - case ENTITY_TYPE_DUMMY: - list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP]; - break; - } - list->RemoveItem(this); - } -} - void CEntity::SetModelIndex(uint32 id) { @@ -318,6 +130,48 @@ CEntity::CreateRwObject(void) } } +void +CEntity::AttachToRwObject(RwObject *obj) +{ + m_rwObject = obj; + if(m_rwObject){ + if(RwObjectGetType(m_rwObject) == rpATOMIC) + m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false); + else if(RwObjectGetType(m_rwObject) == rpCLUMP) + m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false); + CModelInfo::GetModelInfo(m_modelIndex)->AddRef(); + } +} + +void +CEntity::DetachFromRwObject(void) +{ + if(m_rwObject) + CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef(); + m_rwObject = nil; + m_matrix.Detach(); +} + +RpAtomic* +AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data) +{ + if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic))){ + RpHAnimHierarchy *hier = RpSkinAtomicGetHAnimHierarchy(atomic); +#ifdef LIBRW + if(hier && hier->interpolator->currentAnim){ + RpHAnimAnimationDestroy(hier->interpolator->currentAnim); + hier->interpolator->currentAnim = nil; + } +#else + if(hier && hier->currentAnim){ + RpHAnimAnimationDestroy(hier->currentAnim->pCurrentAnim); + hier->currentAnim = nil; + } +#endif + } + return atomic; +} + void CEntity::DeleteRwObject(void) { @@ -341,35 +195,6 @@ CEntity::DeleteRwObject(void) } } -void -CEntity::UpdateRwFrame(void) -{ - if(m_rwObject){ - if(RwObjectGetType(m_rwObject) == rpATOMIC) - RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject)); - else if(RwObjectGetType(m_rwObject) == rpCLUMP) - RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject)); - } -} - -void -CEntity::SetupBigBuilding(void) -{ - CSimpleModelInfo *mi; - - mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); - bIsBIGBuilding = true; - bStreamingDontDelete = true; - bUsesCollision = false; - m_level = CTheZones::GetLevelFromPosition(&GetPosition()); - if(mi->m_lodDistances[0] <= 2000.0f) - bStreamBIGBuilding = true; - if(mi->m_lodDistances[0] > 2500.0f || mi->m_ignoreDrawDist) - m_level = LEVEL_GENERIC; - else if(m_level == LEVEL_GENERIC) - printf("%s isn't in a level\n", mi->GetName()); -} - CRect CEntity::GetBoundRect(void) { @@ -391,6 +216,74 @@ CEntity::GetBoundRect(void) return rect; } +CVector +CEntity::GetBoundCentre(void) +{ + CVector v; + GetBoundCentre(v); + return v; +} + +void +CEntity::GetBoundCentre(CVector &out) +{ + out = m_matrix * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center; +} + +float +CEntity::GetBoundRadius(void) +{ + return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; +} + +void +CEntity::UpdateRwFrame(void) +{ + if(m_rwObject){ + if(RwObjectGetType(m_rwObject) == rpATOMIC) + RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject)); + else if(RwObjectGetType(m_rwObject) == rpCLUMP) + RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject)); + } +} + +void +CEntity::UpdateRpHAnim(void) +{ + if(IsClumpSkinned(GetClump())){ + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); + RpHAnimHierarchyUpdateMatrices(hier); +#if 0 + int i; + char buf[256]; + if(this == (CEntity*)FindPlayerPed()) + for(i = 0; i < hier->numNodes; i++){ + RpHAnimStdInterpFrame *kf = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i); + sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s", + kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real, + kf->t.x, kf->t.y, kf->t.z, + HIERNODEID(hier, i), + ConvertBoneTag2BoneName(HIERNODEID(hier, i))); + CDebug::PrintAt(buf, 10, 1+i*3); + + RwMatrix *m = &RpHAnimHierarchyGetMatrixArray(hier)[i]; + sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", + m->right.x, m->up.x, m->at.x, m->pos.x); + CDebug::PrintAt(buf, 80, 1+i*3+0); + sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", + m->right.y, m->up.y, m->at.y, m->pos.y); + CDebug::PrintAt(buf, 80, 1+i*3+1); + sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", + m->right.z, m->up.z, m->at.z, m->pos.z); + CDebug::PrintAt(buf, 80, 1+i*3+2); + } + + void RenderSkeleton(RpHAnimHierarchy *hier); + RenderSkeleton(hier); +#endif + } +} + bool CEntity::HasPreRenderEffects(void) { @@ -515,15 +408,6 @@ CEntity::PreRender(void) } } -void -CEntity::PreRenderForGlassWindow(void) -{ - if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass) - return; - CGlass::AskForObjectToBeRenderedInGlass(this); - bIsVisible = false; -} - void CEntity::Render(void) { @@ -538,416 +422,213 @@ CEntity::Render(void) } bool -CEntity::SetupLighting(void) -{ - return false; -} - -void -CEntity::AttachToRwObject(RwObject *obj) -{ - m_rwObject = obj; - if(m_rwObject){ - if(RwObjectGetType(m_rwObject) == rpATOMIC) - m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false); - else if(RwObjectGetType(m_rwObject) == rpCLUMP) - m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false); - CModelInfo::GetModelInfo(m_modelIndex)->AddRef(); - } -} - -void -CEntity::DetachFromRwObject(void) -{ - if(m_rwObject) - CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef(); - m_rwObject = nil; - m_matrix.Detach(); -} - -void -CEntity::RegisterReference(CEntity **pent) +CEntity::GetIsTouching(CVector const ¢er, float radius) { - if(IsBuilding()) - return; - CReference *ref; - // check if already registered - for(ref = m_pFirstReference; ref; ref = ref->next) - if(ref->pentity == pent) - return; - // have to allocate new reference - ref = CReferences::pEmptyList; - if(ref){ - CReferences::pEmptyList = ref->next; - - ref->pentity = pent; - ref->next = m_pFirstReference; - m_pFirstReference = ref; - return; - } - return; + return sq(GetBoundRadius()+radius) > (GetBoundCentre()-center).MagnitudeSqr(); } -// Clear all references to this entity -void -CEntity::ResolveReferences(void) +bool +CEntity::IsVisible(void) { - CReference *ref; - // clear pointers to this entity - for(ref = m_pFirstReference; ref; ref = ref->next) - if(*ref->pentity == this) - *ref->pentity = nil; - // free list - if(m_pFirstReference){ - for(ref = m_pFirstReference; ref->next; ref = ref->next) - ; - ref->next = CReferences::pEmptyList; - CReferences::pEmptyList = m_pFirstReference; - m_pFirstReference = nil; - } + return m_rwObject && bIsVisible && GetIsOnScreen(); } -// Free all references that no longer point to this entity -void -CEntity::PruneReferences(void) +bool +CEntity::IsVisibleComplex(void) { - CReference *ref, *next, **lastnextp; - lastnextp = &m_pFirstReference; - for(ref = m_pFirstReference; ref; ref = next){ - next = ref->next; - if(*ref->pentity == this) - lastnextp = &ref->next; - else{ - *lastnextp = ref->next; - ref->next = CReferences::pEmptyList; - CReferences::pEmptyList = ref; - } - } + return m_rwObject && bIsVisible && GetIsOnScreenComplex(); } -// Clean up the reference from *pent -> 'this' -void -CEntity::CleanUpOldReference(CEntity **pent) +bool +CEntity::GetIsOnScreen(void) { - CReference* ref, ** lastnextp; - lastnextp = &m_pFirstReference; - for (ref = m_pFirstReference; ref; ref = ref->next) { - if (ref->pentity == pent) { - *lastnextp = ref->next; - ref->next = CReferences::pEmptyList; - CReferences::pEmptyList = ref; - break; - } - lastnextp = &ref->next; - } + return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(), + &TheCamera.GetCameraMatrix()); } -void -CEntity::UpdateRpHAnim(void) +bool +CEntity::GetIsOnScreenComplex(void) { - if(IsClumpSkinned(GetClump())){ - RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); - RpHAnimHierarchyUpdateMatrices(hier); -#if 0 - int i; - char buf[256]; - if(this == (CEntity*)FindPlayerPed()) - for(i = 0; i < hier->numNodes; i++){ - RpHAnimStdInterpFrame *kf = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i); - sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s", - kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real, - kf->t.x, kf->t.y, kf->t.z, - HIERNODEID(hier, i), - ConvertBoneTag2BoneName(HIERNODEID(hier, i))); - CDebug::PrintAt(buf, 10, 1+i*3); - - RwMatrix *m = &RpHAnimHierarchyGetMatrixArray(hier)[i]; - sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", - m->right.x, m->up.x, m->at.x, m->pos.x); - CDebug::PrintAt(buf, 80, 1+i*3+0); - sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", - m->right.y, m->up.y, m->at.y, m->pos.y); - CDebug::PrintAt(buf, 80, 1+i*3+1); - sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", - m->right.z, m->up.z, m->at.z, m->pos.z); - CDebug::PrintAt(buf, 80, 1+i*3+2); - } + RwV3d boundBox[8]; - void RenderSkeleton(RpHAnimHierarchy *hier); - RenderSkeleton(hier); -#endif - } -} + if(TheCamera.IsPointVisible(GetBoundCentre(), &TheCamera.GetCameraMatrix())) + return true; -void -CEntity::AddSteamsFromGround(CVector *unused) -{ - int i, n; - C2dEffect *effect; - CVector pos; - - n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects(); - for(i = 0; i < n; i++){ - effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i); - if(effect->type != EFFECT_PARTICLE) - continue; - - pos = GetMatrix() * effect->pos; - switch(effect->particle.particleType){ - case 0: - CParticleObject::AddObject(POBJECT_PAVEMENT_STEAM, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 1: - CParticleObject::AddObject(POBJECT_WALL_STEAM, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 2: - CParticleObject::AddObject(POBJECT_DRY_ICE, pos, effect->particle.scale, false); - break; - case 3: - CParticleObject::AddObject(POBJECT_SMALL_FIRE, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 4: - CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 5: - CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_VERT, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 6: - CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_HORIZ, pos, effect->particle.dir, effect->particle.scale, false); - break; - } - } + CRect rect = GetBoundRect(); + CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); + float z = GetPosition().z; + float minz = z + colmodel->boundingBox.min.z; + float maxz = z + colmodel->boundingBox.max.z; + boundBox[0].x = rect.left; + boundBox[0].y = rect.bottom; + boundBox[0].z = minz; + boundBox[1].x = rect.left; + boundBox[1].y = rect.top; + boundBox[1].z = minz; + boundBox[2].x = rect.right; + boundBox[2].y = rect.bottom; + boundBox[2].z = minz; + boundBox[3].x = rect.right; + boundBox[3].y = rect.top; + boundBox[3].z = minz; + boundBox[4].x = rect.left; + boundBox[4].y = rect.bottom; + boundBox[4].z = maxz; + boundBox[5].x = rect.left; + boundBox[5].y = rect.top; + boundBox[5].z = maxz; + boundBox[6].x = rect.right; + boundBox[6].y = rect.bottom; + boundBox[6].z = maxz; + boundBox[7].x = rect.right; + boundBox[7].y = rect.top; + boundBox[7].z = maxz; + + return TheCamera.IsBoxVisible(boundBox, &TheCamera.GetCameraMatrix()); } void -CEntity::ProcessLightsForEntity(void) +CEntity::Add(void) { - int i, n; - C2dEffect *effect; - CVector pos; - bool lightOn, lightFlickering; - uint32 flashTimer1, flashTimer2, flashTimer3; - - if(bRenderDamaged || !bIsVisible || GetUp().z < 0.96f) - return; - - flashTimer1 = 0; - flashTimer2 = 0; - flashTimer3 = 0; - - n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects(); - for(i = 0; i < n; i++, flashTimer1 += 0x80, flashTimer2 += 0x100, flashTimer3 += 0x200){ - effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i); + int x, xstart, xmid, xend; + int y, ystart, ymid, yend; + CSector *s; + CPtrList *list; - switch(effect->type){ - case EFFECT_LIGHT: - pos = GetMatrix() * effect->pos; + CRect bounds = GetBoundRect(); + xstart = CWorld::GetSectorIndexX(bounds.left); + xend = CWorld::GetSectorIndexX(bounds.right); + xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f); + ystart = CWorld::GetSectorIndexY(bounds.top); + yend = CWorld::GetSectorIndexY(bounds.bottom); + ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f); + assert(xstart >= 0); + assert(xend < NUMSECTORS_X); + assert(ystart >= 0); + assert(yend < NUMSECTORS_Y); - lightOn = false; - lightFlickering = false; - switch(effect->light.lightType){ - case LIGHT_ON: - lightOn = true; + for(y = ystart; y <= yend; y++) + for(x = xstart; x <= xend; x++){ + s = CWorld::GetSector(x, y); + if(x == xmid && y == ymid) switch(m_type){ + case ENTITY_TYPE_BUILDING: + list = &s->m_lists[ENTITYLIST_BUILDINGS]; + break; + case ENTITY_TYPE_VEHICLE: + list = &s->m_lists[ENTITYLIST_VEHICLES]; + break; + case ENTITY_TYPE_PED: + list = &s->m_lists[ENTITYLIST_PEDS]; + break; + case ENTITY_TYPE_OBJECT: + list = &s->m_lists[ENTITYLIST_OBJECTS]; + break; + case ENTITY_TYPE_DUMMY: + list = &s->m_lists[ENTITYLIST_DUMMIES]; break; - case LIGHT_ON_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) - lightOn = true; + }else switch(m_type){ + case ENTITY_TYPE_BUILDING: + list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]; + break; + case ENTITY_TYPE_VEHICLE: + list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP]; + break; + case ENTITY_TYPE_PED: + list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP]; break; - case LIGHT_FLICKER: - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) - lightOn = true; + case ENTITY_TYPE_OBJECT: + list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP]; break; - case LIGHT_FLICKER_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7 || CWeather::WetRoads > 0.5f){ - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) - lightOn = true; - } + case ENTITY_TYPE_DUMMY: + list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP]; break; - case LIGHT_FLASH1: - if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200) - lightOn = true; + } + list->InsertItem(this); + } +} + +void +CEntity::Remove(void) +{ + int x, xstart, xmid, xend; + int y, ystart, ymid, yend; + CSector *s; + CPtrList *list; + + CRect bounds = GetBoundRect(); + xstart = CWorld::GetSectorIndexX(bounds.left); + xend = CWorld::GetSectorIndexX(bounds.right); + xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f); + ystart = CWorld::GetSectorIndexY(bounds.top); + yend = CWorld::GetSectorIndexY(bounds.bottom); + ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f); + assert(xstart >= 0); + assert(xend < NUMSECTORS_X); + assert(ystart >= 0); + assert(yend < NUMSECTORS_Y); + + for(y = ystart; y <= yend; y++) + for(x = xstart; x <= xend; x++){ + s = CWorld::GetSector(x, y); + if(x == xmid && y == ymid) switch(m_type){ + case ENTITY_TYPE_BUILDING: + list = &s->m_lists[ENTITYLIST_BUILDINGS]; break; - case LIGHT_FLASH1_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) - if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200) - lightOn = true; + case ENTITY_TYPE_VEHICLE: + list = &s->m_lists[ENTITYLIST_VEHICLES]; break; - case LIGHT_FLASH2: - if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400) - lightOn = true; + case ENTITY_TYPE_PED: + list = &s->m_lists[ENTITYLIST_PEDS]; break; - case LIGHT_FLASH2_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) - if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400) - lightOn = true; + case ENTITY_TYPE_OBJECT: + list = &s->m_lists[ENTITYLIST_OBJECTS]; break; - case LIGHT_FLASH3: - if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800) - lightOn = true; + case ENTITY_TYPE_DUMMY: + list = &s->m_lists[ENTITYLIST_DUMMIES]; break; - case LIGHT_FLASH3_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) - if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800) - lightOn = true; + }else switch(m_type){ + case ENTITY_TYPE_BUILDING: + list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]; break; - case LIGHT_RANDOM_FLICKER: - if(m_randomSeed > 16) - lightOn = true; - else{ - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) - lightOn = true; - } + case ENTITY_TYPE_VEHICLE: + list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP]; break; - case LIGHT_RANDOM_FLICKER_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7){ - if(m_randomSeed > 16) - lightOn = true; - else{ - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) - lightOn = true; - } - } + case ENTITY_TYPE_PED: + list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP]; break; - case LIGHT_BRIDGE_FLASH1: - if(CBridge::ShouldLightsBeFlashing() && CTimer::GetTimeInMilliseconds() & 0x200) - lightOn = true; + case ENTITY_TYPE_OBJECT: + list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP]; break; - case LIGHT_BRIDGE_FLASH2: - if(CBridge::ShouldLightsBeFlashing() && (CTimer::GetTimeInMilliseconds() & 0x1FF) < 60) - lightOn = true; + case ENTITY_TYPE_DUMMY: + list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP]; break; } + list->RemoveItem(this); + } +} - if(effect->light.flags & LIGHTFLAG_HIDE_OBJECT){ - if(lightOn) - bDoNotRender = false; - else - bDoNotRender = true; - return; - } - - // Corona - if(lightOn) - CCoronas::RegisterCorona((uintptr)this + i, - effect->col.r, effect->col.g, effect->col.b, 255, - pos, effect->light.size, effect->light.dist, - effect->light.corona, effect->light.flareType, effect->light.roadReflection, - effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f, - !!(effect->light.flags&LIGHTFLAG_LONG_DIST)); - else if(lightFlickering) - CCoronas::RegisterCorona((uintptr)this + i, - 0, 0, 0, 255, - pos, effect->light.size, effect->light.dist, - effect->light.corona, effect->light.flareType, effect->light.roadReflection, - effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f, - !!(effect->light.flags&LIGHTFLAG_LONG_DIST)); - - // Pointlight - bool alreadyProcessedFog; - alreadyProcessedFog = false; - if(effect->light.range != 0.0f && lightOn){ - if(effect->col.r == 0 && effect->col.g == 0 && effect->col.b == 0){ - CPointLights::AddLight(CPointLights::LIGHT_POINT, - pos, CVector(0.0f, 0.0f, 0.0f), - effect->light.range, - 0.0f, 0.0f, 0.0f, - CPointLights::FOG_NONE, true); - }else{ - CPointLights::AddLight(CPointLights::LIGHT_POINT, - pos, CVector(0.0f, 0.0f, 0.0f), - effect->light.range, - effect->col.r*CTimeCycle::GetSpriteBrightness()/255.0f, - effect->col.g*CTimeCycle::GetSpriteBrightness()/255.0f, - effect->col.b*CTimeCycle::GetSpriteBrightness()/255.0f, - (effect->light.flags & LIGHTFLAG_FOG) >> 1, - true); - alreadyProcessedFog = true; - } - } - - if(!alreadyProcessedFog){ - if(effect->light.flags & LIGHTFLAG_FOG_ALWAYS){ - CPointLights::AddLight(CPointLights::LIGHT_FOGONLY_ALWAYS, - pos, CVector(0.0f, 0.0f, 0.0f), - 0.0f, - effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, - CPointLights::FOG_ALWAYS, true); - }else if(effect->light.flags & LIGHTFLAG_FOG_NORMAL && lightOn && effect->light.range == 0.0f){ - CPointLights::AddLight(CPointLights::LIGHT_FOGONLY, - pos, CVector(0.0f, 0.0f, 0.0f), - 0.0f, - effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, - CPointLights::FOG_NORMAL, true); - } - } +float +CEntity::GetDistanceFromCentreOfMassToBaseOfModel(void) +{ + return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z; +} - // Light shadow - if(effect->light.shadowSize != 0.0f){ - if(lightOn){ - CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, - effect->light.shadow, &pos, - 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, - 15.0f, 1.0f, 40.0f, false, 0.0f); - }else if(lightFlickering){ - CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, - effect->light.shadow, &pos, - effect->light.shadowSize, 0.0f, - 0.0f, -effect->light.shadowSize, - 0, 0.0f, 0.0f, 0.0f, - 15.0f, 1.0f, 40.0f, false, 0.0f); - } - } - break; +void +CEntity::SetupBigBuilding(void) +{ + CSimpleModelInfo *mi; - case EFFECT_SUNGLARE: - if(CWeather::SunGlare >= 0.0f){ - CVector pos = GetMatrix() * effect->pos; - CVector glareDir = pos - GetPosition(); - glareDir.Normalise(); - CVector camDir = TheCamera.GetPosition() - pos; - float dist = camDir.Magnitude(); - camDir *= 2.0f/dist; - glareDir += camDir; - glareDir.Normalise(); - float camAngle = -DotProduct(glareDir, CTimeCycle::GetSunDirection()); - if(camAngle > 0.0f){ - float intens = Sqrt(camAngle) * CWeather::SunGlare; - pos += camDir; - CCoronas::RegisterCorona((uintptr)this + 33 + i, - intens * (CTimeCycle::GetSunCoreRed() + 2*255)/3.0f, - intens * (CTimeCycle::GetSunCoreGreen() + 2*255)/3.0f, - intens * (CTimeCycle::GetSunCoreBlue() + 2*255)/3.0f, - 255, - pos, 0.5f*CWeather::SunGlare*Sqrt(dist), 120.0f, - CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, - CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, - CCoronas::STREAK_OFF, 0.0f); - } - } - break; - } - } + mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); + bIsBIGBuilding = true; + bStreamingDontDelete = true; + bUsesCollision = false; + m_level = CTheZones::GetLevelFromPosition(&GetPosition()); + if(mi->m_lodDistances[0] <= 2000.0f) + bStreamBIGBuilding = true; + if(mi->m_lodDistances[0] > 2500.0f || mi->m_ignoreDrawDist) + m_level = LEVEL_GENERIC; + else if(m_level == LEVEL_GENERIC) + printf("%s isn't in a level\n", mi->GetName()); } float WindTabel[] = { @@ -1041,14 +722,67 @@ CEntity::ModifyMatrixForBannerInWind(void) UpdateRwFrame(); } -void -CEntity::AddSteamsFromGround(CPtrList& list) +void +CEntity::PreRenderForGlassWindow(void) +{ + if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass) + return; + CGlass::AskForObjectToBeRenderedInGlass(this); + bIsVisible = false; +} + +/* +0x487A10 - SetAtomicAlphaCB +0x4879E0 - SetClumpAlphaCB +*/ + +RpMaterial* +SetAtomicAlphaCB(RpMaterial *material, void *data) +{ + ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data; + return material; +} + +RpAtomic* +SetClumpAlphaCB(RpAtomic *atomic, void *data) +{ + RpGeometry *geometry = RpAtomicGetGeometry(atomic); + RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)data); + return atomic; +} + +void +CEntity::SetRwObjectAlpha(int32 alpha) +{ + if (m_rwObject != nil) { + switch (RwObjectGetType(m_rwObject)) { + case rpATOMIC: { + RpGeometry *geometry = RpAtomicGetGeometry((RpAtomic*)m_rwObject); + RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)alpha); + break; + } + case rpCLUMP: + RpClumpForAllAtomics((RpClump*)m_rwObject, SetClumpAlphaCB, (void*)alpha); + break; + } + } +} + +bool IsEntityPointerValid(CEntity* pEntity) { - CPtrNode *pNode = list.first; - while (pNode) { - ((CEntity*)pNode->item)->AddSteamsFromGround(nil); - pNode = pNode->next; + if (!pEntity) + return false; + switch (pEntity->GetType()) { + case ENTITY_TYPE_NOTHING: return false; + case ENTITY_TYPE_BUILDING: return IsBuildingPointerValid((CBuilding*)pEntity); + case ENTITY_TYPE_VEHICLE: return IsVehiclePointerValid((CVehicle*)pEntity); + case ENTITY_TYPE_PED: return IsPedPointerValid((CPed*)pEntity); + case ENTITY_TYPE_OBJECT: return IsObjectPointerValid((CObject*)pEntity); + case ENTITY_TYPE_DUMMY: return IsDummyPointerValid((CDummy*)pEntity); } + return false; } #ifdef COMPATIBLE_SAVES @@ -1165,84 +899,3 @@ CEntity::LoadEntityFlags(uint8*& buf) } #endif - -bool IsEntityPointerValid(CEntity* pEntity) -{ - if (!pEntity) - return false; - switch (pEntity->GetType()) { - case ENTITY_TYPE_NOTHING: return false; - case ENTITY_TYPE_BUILDING: return IsBuildingPointerValid((CBuilding*)pEntity); - case ENTITY_TYPE_VEHICLE: return IsVehiclePointerValid((CVehicle*)pEntity); - case ENTITY_TYPE_PED: return IsPedPointerValid((CPed*)pEntity); - case ENTITY_TYPE_OBJECT: return IsObjectPointerValid((CObject*)pEntity); - case ENTITY_TYPE_DUMMY: return IsDummyPointerValid((CDummy*)pEntity); - } - return false; -} - -bool CEntity::IsEntityOccluded(void) { - - CVector coors; - float width, height; - - if (COcclusion::NumActiveOccluders == 0 || !CalcScreenCoors(GetBoundCentre(), &coors, &width, &height)) - return false; - - float area = Max(width, height) * GetBoundRadius() * 0.9f; - - for (int i = 0; i < COcclusion::NumActiveOccluders; i++) { - if (coors.z - (GetBoundRadius() * 0.85f) > COcclusion::aActiveOccluders[i].radius) { - if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, area)) { - return true; - } - - 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; - - 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, min.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; - if (CalcScreenCoors(CVector(min.x, max.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; - - return true; - } - } - } - - return false; -} - -/* -0x487A10 - SetAtomicAlphaCB -0x4879E0 - SetClumpAlphaCB -*/ - -RpMaterial* SetAtomicAlphaCB(RpMaterial *material, void *data) { - ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data; - return material; -} - -RpAtomic* SetClumpAlphaCB(RpAtomic *atomic, void *data) { - RpGeometry *geometry = RpAtomicGetGeometry(atomic); - RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); - RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)data); - return atomic; -} - -void CEntity::SetRwObjectAlpha(int32 alpha) { - if (m_rwObject != nil) { - switch (RwObjectGetType(m_rwObject)) { - case rpATOMIC: { - RpGeometry *geometry = RpAtomicGetGeometry((RpAtomic*)m_rwObject); - RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); - RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)alpha); - break; - } - case rpCLUMP: - RpClumpForAllAtomics((RpClump*)m_rwObject, SetClumpAlphaCB, (void*)alpha); - break; - } - } -} \ No newline at end of file diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 9129457c..2749e3f7 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -130,7 +130,7 @@ public: virtual void PreRender(void); virtual void Render(void); virtual bool SetupLighting(void); - virtual void RemoveLighting(bool) {} + virtual void RemoveLighting(bool); virtual void FlagToDestroyWhenNextProcessed(void) {} bool IsBuilding(void) { return m_type == ENTITY_TYPE_BUILDING; } @@ -149,14 +149,14 @@ public: } void GetBoundCentre(CVector &out); - CVector GetBoundCentre(void) { CVector v; GetBoundCentre(v); return v; } - float GetBoundRadius(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; } - float GetDistanceFromCentreOfMassToBaseOfModel(void) { return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z; } + CVector GetBoundCentre(void); + float GetBoundRadius(void); + float GetDistanceFromCentreOfMassToBaseOfModel(void); bool GetIsTouching(CVector const ¢er, float r); bool GetIsOnScreen(void); bool GetIsOnScreenComplex(void); - bool IsVisible(void) { return m_rwObject && bIsVisible && GetIsOnScreen(); } - bool IsVisibleComplex(void) { return m_rwObject && bIsVisible && GetIsOnScreenComplex(); } + bool IsVisible(void); + bool IsVisibleComplex(void); bool IsEntityOccluded(void); int16 GetModelIndex(void) const { return m_modelIndex; } void UpdateRwFrame(void); @@ -179,8 +179,6 @@ public: void ModifyMatrixForBannerInWind(void); void ProcessLightsForEntity(void); void SetRwObjectAlpha(int32 alpha); - - static void AddSteamsFromGround(CPtrList& list); }; bool IsEntityPointerValid(CEntity*); -- cgit v1.2.3