void ZFileSectorLoader::MakeTasks() { Long x,y,z; UByte Pri; // Sector Loading while (1) { if (RequestList[5].PullFromList(x,y,z)) {Pri = 4; } else if (RequestList[4].PullFromList(x,y,z)) {Pri = 4; } else if (RequestList[3].PullFromList(x,y,z)) {Pri = 3; } else if (RequestList[2].PullFromList(x,y,z)) {Pri = 2; } else if (RequestList[1].PullFromList(x,y,z)) {Pri = 1; } else if (RequestList[0].PullFromList(x,y,z)) {Pri = 0; } else break; if (LoadSector(x,y,z) /*&& Pri<4*/) break; } // Sector Unloading ZVoxelSector * Sector; while ( (Sector = EjectedSectorList->PullFromList()) ) { RequestTag.Remove(Sector->Pos_x, Sector->Pos_y, Sector->Pos_z); printf("Deleted : %lx, %lu L2 Start:%lu End:%lu nEntries:%lu\n", Sector,++debug_deletecount,EjectedSectorList->debug_getstart(),EjectedSectorList->debug_GetEnd(),EjectedSectorList->debug_GetnEntries() ); if (COMPILEOPTION_ALLOWSAVE) { #if COMPILEOPTION_SAVEONLYMODIFIED==1 if (Sector->IsMustBeSaved()) #endif { Sector->Save(UniverseNum); } } //delete Sector; Sector->ReinitSector(); SectorRecycling->PushToList(Sector); } return; }
void BgLoader::UpdatePosition(const csVector3& pos, const char* sectorName, bool force) { validPosition = true; if(GetLoadingCount() != 0) { ContinueLoading(false); } if(!force) { // Check if we've moved. if(csVector3(lastPos - pos).Norm() < loadRange/10) { return; } } csRef<Sector> sector; // Hack to work around the weird sector stuff we do. if(csString("SectorWhereWeKeepEntitiesResidingInUnloadedMaps").Compare(sectorName)) { sector = lastSector; } if(!sector.IsValid()) { sector = sectorHash.Get(sStringSet.Request(sectorName), csRef<Sector>()); } if(sector.IsValid()) { // Calc bbox. csBox3 loadBox; loadBox.AddBoundingVertex(pos.x+loadRange, pos.y+loadRange, pos.z+loadRange); loadBox.AddBoundingVertexSmart(pos.x-loadRange, pos.y-loadRange, pos.z-loadRange); csBox3 unloadBox; unloadBox.AddBoundingVertex(pos.x+loadRange*1.5, pos.y+loadRange*1.5, pos.z+loadRange*1.5); unloadBox.AddBoundingVertexSmart(pos.x-loadRange*1.5, pos.y-loadRange*1.5, pos.z-loadRange*1.5); // Check. LoadSector(loadBox, unloadBox, sector, 0, false, true); if(force) { // Make sure we start the loading now. engine->SyncEngineListsNow(tloader); for(size_t i=0; i<loadingMeshes.GetSize(); i++) { if(LoadMesh(loadingMeshes[i])) { FinishMeshLoad(loadingMeshes[i]); loadingMeshes.DeleteIndex(i); } } for(size_t i=0; i<loadingMeshGen.GetSize(); ++i) { if(LoadMeshGen(loadingMeshGen[i])) { loadingMeshGen.DeleteIndex(i); } } } if(lastSector != sector) { CleanDisconnectedSectors(sector); } lastPos = pos; lastSector = sector; } for(size_t i=0; i<sectors.GetSize(); i++) { sectors[i]->checked = false; } }
void BgLoader::LoadSector(const csBox3& loadBox, const csBox3& unloadBox, Sector* sector, uint depth, bool force, bool loadMeshes, bool portalsOnly) { sector->isLoading = true; if(!sector->object.IsValid()) { { csString msg; msg.AppendFmt("Attempting to load uninit sector %s!\n", sector->name.GetData()); CS_ASSERT_MSG(msg.GetData(), sector->init); if(!sector->init) return; } sector->object = engine->CreateSector(sector->name); sector->object->SetDynamicAmbientLight(sector->ambient); sector->object->SetVisibilityCullerPlugin(sector->culler); sector->object->QueryObject()->SetObjectParent(sector->parent); } if(!force && depth < maxPortalDepth) { // Check other sectors linked to by active portals. for(size_t i=0; i<sector->activePortals.GetSize(); i++) { if(!sector->activePortals[i]->targetSector->isLoading && !sector->activePortals[i]->targetSector->checked) { csBox3 wwLoadBox = loadBox; csBox3 wwUnloadBox = unloadBox; if(sector->activePortals[i]->warp) { csVector3& transform = sector->activePortals[i]->transform; wwLoadBox.SetMin(0, wwLoadBox.MinX()-transform.x); wwLoadBox.SetMin(1, wwLoadBox.MinY()-transform.y); wwLoadBox.SetMin(2, wwLoadBox.MinZ()-transform.z); wwLoadBox.SetMax(0, wwLoadBox.MaxX()-transform.x); wwLoadBox.SetMax(1, wwLoadBox.MaxY()-transform.y); wwLoadBox.SetMax(2, wwLoadBox.MaxZ()-transform.z); wwUnloadBox.SetMin(0, wwUnloadBox.MinX()-transform.x); wwUnloadBox.SetMin(1, wwUnloadBox.MinY()-transform.y); wwUnloadBox.SetMin(2, wwUnloadBox.MinZ()-transform.z); wwUnloadBox.SetMax(0, wwUnloadBox.MaxX()-transform.x); wwUnloadBox.SetMax(1, wwUnloadBox.MaxY()-transform.y); wwUnloadBox.SetMax(2, wwUnloadBox.MaxZ()-transform.z); } LoadSector(wwLoadBox, wwUnloadBox, sector->activePortals[i]->targetSector, depth+1, false, loadMeshes); } } } if(loadMeshes && !portalsOnly) { // Load all meshes which should always be loaded in this sector. for(size_t i=0; i<sector->alwaysLoaded.GetSize(); i++) { if(!sector->alwaysLoaded[i]->loading && !sector->alwaysLoaded[i]->object.IsValid()) { sector->alwaysLoaded[i]->loading = true; loadingMeshes.Push(sector->alwaysLoaded[i]); ++(sector->objectCount); } } // Check all meshes in this sector. for(size_t i=0; i<sector->meshes.GetSize(); i++) { if(!sector->meshes[i]->loading) { if(sector->meshes[i]->InRange(loadBox, force)) { sector->meshes[i]->loading = true; loadingMeshes.Push(sector->meshes[i]); ++(sector->objectCount); } else if(!force && sector->meshes[i]->OutOfRange(unloadBox)) { sector->meshes[i]->object->GetMovable()->ClearSectors(); sector->meshes[i]->object->GetMovable()->UpdateMove(); engine->GetMeshes()->Remove(sector->meshes[i]->object); sector->meshes[i]->object.Invalidate(); deleteQueue.Push(sector->meshes[i]); --(sector->objectCount); } } } // Check all meshgen in this sector. for(size_t i=0; i<sector->meshgen.GetSize(); i++) { if(!sector->meshgen[i]->loading) { if(sector->meshgen[i]->InRange(loadBox, force)) { sector->meshgen[i]->loading = true; loadingMeshGen.Push(sector->meshgen[i]); ++(sector->objectCount); } else if(!force && sector->meshgen[i]->OutOfRange(unloadBox)) { CleanMeshGen(sector->meshgen[i]); --(sector->objectCount); } } } } // Check all portals in this sector... and recurse into the sectors they lead to. for(size_t i=0; i<sector->portals.GetSize(); i++) { if(sector->portals[i]->InRange(loadBox, force)) { bool recurse = true; if(!force && depth >= maxPortalDepth) { // If we've reached the recursion limit then check if the // target sector is valid. If so then create a portal to it. if(sector->portals[i]->targetSector->object.IsValid()) { recurse = false; } else // Else check the next portal. { continue; } } if(force) { if(sector->portals[i]->mObject) { engine->GetMeshes()->Remove(sector->portals[i]->mObject); sector->portals[i]->pObject = NULL; sector->portals[i]->mObject.Invalidate(); sector->activePortals.Delete(sector->portals[i]); --(sector->objectCount); } if(!sector->portals[i]->targetSector->object.IsValid()) { { csString msg; msg.AppendFmt("Attempting to load uninit sector %s!\n", sector->portals[i]->targetSector->name.GetData()); CS_ASSERT_MSG(msg.GetData(), sector->portals[i]->targetSector->init); if(!sector->portals[i]->targetSector->init) return; } sector->portals[i]->targetSector->object = engine->CreateSector(sector->portals[i]->targetSector->name); sector->portals[i]->targetSector->object->SetDynamicAmbientLight(sector->portals[i]->targetSector->ambient); sector->portals[i]->targetSector->object->SetVisibilityCullerPlugin(sector->portals[i]->targetSector->culler); sector->portals[i]->targetSector->object->QueryObject()->SetObjectParent(sector->portals[i]->targetSector->parent); } } else if(!sector->portals[i]->targetSector->isLoading && !sector->portals[i]->targetSector->checked && recurse) { csBox3 wwLoadBox = loadBox; csBox3 wwUnloadBox = unloadBox; if(sector->portals[i]->warp) { csVector3& transform = sector->portals[i]->transform; wwLoadBox.SetMin(0, wwLoadBox.MinX()-transform.x); wwLoadBox.SetMin(1, wwLoadBox.MinY()-transform.y); wwLoadBox.SetMin(2, wwLoadBox.MinZ()-transform.z); wwLoadBox.SetMax(0, wwLoadBox.MaxX()-transform.x); wwLoadBox.SetMax(1, wwLoadBox.MaxY()-transform.y); wwLoadBox.SetMax(2, wwLoadBox.MaxZ()-transform.z); wwUnloadBox.SetMin(0, wwUnloadBox.MinX()-transform.x); wwUnloadBox.SetMin(1, wwUnloadBox.MinY()-transform.y); wwUnloadBox.SetMin(2, wwUnloadBox.MinZ()-transform.z); wwUnloadBox.SetMax(0, wwUnloadBox.MaxX()-transform.x); wwUnloadBox.SetMax(1, wwUnloadBox.MaxY()-transform.y); wwUnloadBox.SetMax(2, wwUnloadBox.MaxZ()-transform.z); } LoadSector(wwLoadBox, wwUnloadBox, sector->portals[i]->targetSector, depth+1, false, loadMeshes); } sector->portals[i]->mObject = engine->CreatePortal(sector->portals[i]->name, sector->object, csVector3(0), sector->portals[i]->targetSector->object, sector->portals[i]->poly.GetVertices(), (int)sector->portals[i]->poly.GetVertexCount(), sector->portals[i]->pObject); if(sector->portals[i]->warp) { sector->portals[i]->pObject->SetWarp(sector->portals[i]->matrix, sector->portals[i]->wv, sector->portals[i]->ww); } if(sector->portals[i]->pfloat) { sector->portals[i]->pObject->GetFlags().SetBool(CS_PORTAL_FLOAT, true); } if(sector->portals[i]->clip) { sector->portals[i]->pObject->GetFlags().SetBool(CS_PORTAL_CLIPDEST, true); } if(sector->portals[i]->zfill) { sector->portals[i]->pObject->GetFlags().SetBool(CS_PORTAL_ZFILL, true); } sector->activePortals.Push(sector->portals[i]); ++(sector->objectCount); } else if(!force && sector->portals[i]->OutOfRange(unloadBox)) { if(!sector->portals[i]->targetSector->isLoading) { csBox3 wwLoadBox = loadBox; csBox3 wwUnloadBox = unloadBox; if(sector->portals[i]->warp) { csVector3& transform = sector->portals[i]->transform; wwLoadBox.SetMin(0, wwLoadBox.MinX()-transform.x); wwLoadBox.SetMin(1, wwLoadBox.MinY()-transform.y); wwLoadBox.SetMin(2, wwLoadBox.MinZ()-transform.z); wwLoadBox.SetMax(0, wwLoadBox.MaxX()-transform.x); wwLoadBox.SetMax(1, wwLoadBox.MaxY()-transform.y); wwLoadBox.SetMax(2, wwLoadBox.MaxZ()-transform.z); wwUnloadBox.SetMin(0, wwUnloadBox.MinX()-transform.x); wwUnloadBox.SetMin(1, wwUnloadBox.MinY()-transform.y); wwUnloadBox.SetMin(2, wwUnloadBox.MinZ()-transform.z); wwUnloadBox.SetMax(0, wwUnloadBox.MaxX()-transform.x); wwUnloadBox.SetMax(1, wwUnloadBox.MaxY()-transform.y); wwUnloadBox.SetMax(2, wwUnloadBox.MaxZ()-transform.z); } LoadSector(wwLoadBox, wwUnloadBox, sector->portals[i]->targetSector, depth+1, false, loadMeshes); } engine->GetMeshes()->Remove(sector->portals[i]->mObject); sector->portals[i]->pObject = NULL; sector->portals[i]->mObject.Invalidate(); sector->activePortals.Delete(sector->portals[i]); --(sector->objectCount); } } if(loadMeshes && !portalsOnly) { // Check all sector lights. for(size_t i=0; i<sector->lights.GetSize(); i++) { if(sector->lights[i]->InRange(loadBox, force)) { sector->lights[i]->object = engine->CreateLight(sector->lights[i]->name, sector->lights[i]->pos, sector->lights[i]->radius, sector->lights[i]->colour, sector->lights[i]->dynamic); sector->lights[i]->object->SetAttenuationMode(sector->lights[i]->attenuation); sector->lights[i]->object->SetType(sector->lights[i]->type); sector->object->GetLights()->Add(sector->lights[i]->object); ++sector->objectCount; // Load all light sequences. for(size_t j=0; j<sector->lights[i]->sequences.GetSize(); ++j) { sector->lights[i]->sequences[j]->status = tloader->LoadNodeWait(vfs->GetCwd(), sector->lights[i]->sequences[j]->data); for(size_t k=0; k<sector->lights[i]->sequences[j]->triggers.GetSize(); ++k) { sector->lights[i]->sequences[j]->triggers[k]->status = tloader->LoadNode(vfs->GetCwd(), sector->lights[i]->sequences[j]->triggers[k]->data); } } } else if(!force && sector->lights[i]->OutOfRange(unloadBox)) { engine->RemoveLight(sector->lights[i]->object); sector->lights[i]->object.Invalidate(); --sector->objectCount; for(size_t j=0; j<sector->lights[i]->sequences.GetSize(); ++j) { if(sector->lights[i]->sequences[j]->status.IsValid()) { for(size_t k=0; k<sector->lights[i]->sequences[j]->triggers.GetSize(); ++k) { if(sector->lights[i]->sequences[j]->triggers[k]->status.IsValid()) { csRef<iSequenceTrigger> st = scfQueryInterface<iSequenceTrigger>(sector->lights[i]->sequences[j]->triggers[k]->status->GetResultRefPtr()); engseq->RemoveTrigger(st); sector->lights[i]->sequences[j]->triggers[k]->status.Invalidate(); } } csRef<iSequenceWrapper> sw = scfQueryInterface<iSequenceWrapper>(sector->lights[i]->sequences[j]->status->GetResultRefPtr()); engseq->RemoveSequence(sw); sector->lights[i]->sequences[j]->status.Invalidate(); } } } } if(loadMeshes && !portalsOnly) { // Load all sector sequences. for(size_t i=0; i<sector->sequences.GetSize(); i++) { if(!sector->sequences[i]->status.IsValid()) { sector->sequences[i]->status = tloader->LoadNode(vfs->GetCwd(), sector->sequences[i]->data); } } } // Check whether this sector is empty and should be unloaded. if(sector->objectCount == sector->alwaysLoaded.GetSize() && sector->object.IsValid()) { // Unload all 'always loaded' meshes before destroying sector. for(size_t i=0; i<sector->alwaysLoaded.GetSize(); i++) { sector->alwaysLoaded[i]->object->GetMovable()->ClearSectors(); sector->alwaysLoaded[i]->object->GetMovable()->UpdateMove(); engine->GetMeshes()->Remove(sector->alwaysLoaded[i]->object); sector->alwaysLoaded[i]->object.Invalidate(); deleteQueue.Push(sector->meshes[i]); --(sector->objectCount); } // Remove sequences. for(size_t i=0; i<sector->sequences.GetSize(); i++) { if(sector->sequences[i]->status.IsValid()) { csRef<iSequenceWrapper> sw = scfQueryInterface<iSequenceWrapper>(sector->sequences[i]->status->GetResultRefPtr()); engseq->RemoveSequence(sw); sector->sequences[i]->status.Invalidate(); } } // Remove the sector from the engine. sector->object->QueryObject()->SetObjectParent(0); engine->GetSectors()->Remove(sector->object); sector->object.Invalidate(); } } sector->checked = true; sector->isLoading = false; }
bool BgLoader::LoadZones(iStringArray* regions, bool loadMeshes) { // Firstly, get a list of all zones that should be loaded. csRefArray<Zone> newLoadedZones; for(size_t i=0; i<regions->GetSize(); ++i) { csRef<Zone> zone = zones.Get(zStringSet.Request(regions->Get(i)), csRef<Zone>()); if(zone.IsValid()) { newLoadedZones.Push(zone); } else { return false; } } // Next clean all sectors which shouldn't be loaded. for(size_t i=0; i<loadedZones.GetSize(); ++i) { bool found = false; for(size_t j=0; j<newLoadedZones.GetSize(); ++j) { if(loadedZones[i] == newLoadedZones[j]) { found = true; break; } } if(!found) { for(size_t j=0; j<loadedZones[i]->sectors.GetSize(); ++j) { CleanSector(loadedZones[i]->sectors[j]); } loadedZones.DeleteIndex(i); --i; } } // Now load all sectors which should be loaded. for(size_t i=0; i<newLoadedZones.GetSize(); ++i) { bool found = false; for(size_t j=0; j<loadedZones.GetSize(); ++j) { if(newLoadedZones[i] == loadedZones[j]) { found = true; break; } } if(!found) { loadedZones.Push(newLoadedZones[i]); for(size_t j=0; j<newLoadedZones[i]->sectors.GetSize(); ++j) { LoadSector(csBox3(), csBox3(), newLoadedZones[i]->sectors[j], (uint)-1, true, loadMeshes); } } else { for(size_t j=0; j<newLoadedZones[i]->sectors.GetSize(); ++j) { LoadSector(csBox3(), csBox3(), newLoadedZones[i]->sectors[j], (uint)-1, true, loadMeshes, true); } } } // Finally, clean up all sectors which were created but not checked for loading. for(size_t i=0; i<loadedZones.GetSize(); ++i) { for(size_t j=0; j<loadedZones[i]->sectors.GetSize(); ++j) { for(size_t k=0; k<loadedZones[i]->sectors[j]->activePortals.GetSize(); ++k) { if(!loadedZones[i]->sectors[j]->activePortals[k]->targetSector->checked) { CleanSector(loadedZones[i]->sectors[j]->activePortals[k]->targetSector); // TODO: improve this, it's a bit hacky. engine->GetMeshes()->Remove(loadedZones[i]->sectors[j]->activePortals[k]->mObject); loadedZones[i]->sectors[j]->activePortals[k]->pObject = NULL; loadedZones[i]->sectors[j]->activePortals[k]->mObject.Invalidate(); loadedZones[i]->sectors[j]->activePortals.Delete(loadedZones[i]->sectors[j]->activePortals[k]); --(loadedZones[i]->sectors[j]->objectCount); } } } } return true; }