예제 #1
0
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;

}
예제 #2
0
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;
    }
}
예제 #3
0
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;
}
예제 #4
0
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;
}