| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "interior/interiorLMManager.h"
- #include "gfx/gfxTextureManager.h"
- #include "gfx/bitmap/gBitmap.h"
- #include "interior/interiorRes.h"
- #include "interior/interiorInstance.h"
- #include "interior/interior.h"
- //------------------------------------------------------------------------------
- // Globals
- InteriorLMManager gInteriorLMManager;
- //------------------------------------------------------------------------------
- InteriorLMManager::InteriorLMManager()
- {
- VECTOR_SET_ASSOCIATION( mInteriors );
- }
- InteriorLMManager::~InteriorLMManager()
- {
- for(U32 i = 0; i < mInteriors.size(); i++)
- removeInterior(LM_HANDLE(i));
- }
- //------------------------------------------------------------------------------
- void InteriorLMManager::addInterior(LM_HANDLE & interiorHandle, U32 numLightmaps, Interior * interior)
- {
- interiorHandle = mInteriors.size();
- mInteriors.increment();
- mInteriors.last() = new InteriorLMInfo;
- mInteriors.last()->mInterior = interior;
- mInteriors.last()->mHandlePtr = &interiorHandle;
- mInteriors.last()->mNumLightmaps = numLightmaps;
- // create base instance
- addInstance(interiorHandle, mInteriors.last()->mBaseInstanceHandle, 0);
- AssertFatal(mInteriors.last()->mBaseInstanceHandle == LM_HANDLE(0), "InteriorLMManager::addInterior: invalid base instance handle");
- // steal the lightmaps from the interior
- Vector<GFXTexHandle>& texHandles = getHandles(interiorHandle, 0);
- for(U32 i = 0; i < interior->mLightmaps.size(); i++)
- {
- AssertFatal(interior->mLightmaps[i], "InteriorLMManager::addInterior: interior missing lightmap");
- texHandles[i].set(interior->mLightmaps[i], &GFXDefaultPersistentProfile, true, String("Interior Lightmap"));
- }
- interior->mLightmaps.clear();
- }
- void InteriorLMManager::removeInterior(LM_HANDLE interiorHandle)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::removeInterior: invalid interior handle");
- AssertFatal(mInteriors[interiorHandle]->mInstances.size() == 1, "InteriorLMManager::removeInterior: cannot remove base interior");
- // remove base instance
- removeInstance(interiorHandle, 0);
- *mInteriors[interiorHandle]->mHandlePtr = LM_HANDLE(-1);
- delete mInteriors[interiorHandle];
- // last one? otherwise move it
- if((mInteriors.size()-1) != interiorHandle)
- {
- mInteriors[interiorHandle] = mInteriors.last();
- *(mInteriors[interiorHandle]->mHandlePtr) = interiorHandle;
- }
- mInteriors.decrement();
- }
- //------------------------------------------------------------------------------
- void InteriorLMManager::addInstance(LM_HANDLE interiorHandle, LM_HANDLE & instanceHandle, InteriorInstance * instance)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::addInstance: invalid interior handle");
- AssertFatal(interiorHandle == *(mInteriors[interiorHandle]->mHandlePtr), "InteriorLMManager::addInstance: invalid handle value");
- InteriorLMInfo * interiorInfo = mInteriors[interiorHandle];
- // create the instance info and fill
- InstanceLMInfo * instanceInfo = new InstanceLMInfo;
- instanceInfo->mInstance = instance;
- instanceInfo->mHandlePtr = &instanceHandle;
- instanceHandle = interiorInfo->mInstances.size();
- interiorInfo->mInstances.push_back(instanceInfo);
- // create/clear list
- instanceInfo->mLightmapHandles.setSize(interiorInfo->mNumLightmaps);
- for(U32 i = 0; i < instanceInfo->mLightmapHandles.size(); i++)
- instanceInfo->mLightmapHandles[i] = NULL;
- }
- void InteriorLMManager::removeInstance(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::removeInstance: invalid interior handle");
- AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::removeInstance: invalid instance handle");
- AssertFatal(!(instanceHandle == mInteriors[interiorHandle]->mBaseInstanceHandle &&
- mInteriors[interiorHandle]->mInstances.size() > 1), "InteriorLMManager::removeInstance: invalid base instance");
- InteriorLMInfo * itrInfo = mInteriors[interiorHandle];
- // kill it
- InstanceLMInfo * instInfo = itrInfo->mInstances[instanceHandle];
- for(U32 i = 0; i < instInfo->mLightmapHandles.size(); i++)
- instInfo->mLightmapHandles[i] = NULL;
- // reset on last instance removal only (multi detailed shapes share the same instance handle)
- if(itrInfo->mInstances.size() == 1)
- *instInfo->mHandlePtr = LM_HANDLE(-1);
- delete instInfo;
- // last one? otherwise move it
- if((itrInfo->mInstances.size()-1) != instanceHandle)
- {
- itrInfo->mInstances[instanceHandle] = itrInfo->mInstances.last();
- *(itrInfo->mInstances[instanceHandle]->mHandlePtr) = instanceHandle;
- }
- itrInfo->mInstances.decrement();
- }
- void InteriorLMManager::useBaseTextures(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::useBaseTextures: invalid interior handle");
- AssertFatal(interiorHandle == *(mInteriors[interiorHandle]->mHandlePtr), "InteriorLMManager::useBaseTextures: invalid handle value");
- // Make sure the base light maps are loaded
- loadBaseLightmaps(interiorHandle,instanceHandle);
- // Install base lightmaps for this instance...
- Vector<GFXTexHandle>& baseHandles = getHandles(interiorHandle, 0);
- Vector<GFXTexHandle>& texHandles = getHandles(interiorHandle, instanceHandle);
- for(U32 i = 0; i < baseHandles.size(); i++)
- texHandles[i] = baseHandles[i];
- }
- //------------------------------------------------------------------------------
- void InteriorLMManager::destroyBitmaps()
- {
- for(S32 i = mInteriors.size() - 1; i >= 0; i--)
- {
- InteriorLMInfo * interiorInfo = mInteriors[i];
- for(S32 j = interiorInfo->mInstances.size() - 1; j >= 0; j--)
- {
- InstanceLMInfo * instanceInfo = interiorInfo->mInstances[j];
- for(S32 k = instanceInfo->mLightmapHandles.size() - 1; k >= 0; k--)
- {
- if(!instanceInfo->mLightmapHandles[k])
- continue;
- GFXTextureObject * texObj = instanceInfo->mLightmapHandles[k];
- if(!texObj || !texObj->mBitmap)
- continue;
- // don't remove 'keep' bitmaps
- if(!interiorInfo->mInterior->mLightmapKeep[k])
- {
- // SAFE_DELETE(texObj->mBitmap);
- // texObj->bitmap = 0;
- }
- }
- }
- }
- }
- void InteriorLMManager::destroyTextures()
- {
- for(S32 i = mInteriors.size() - 1; i >= 0; i--)
- {
- InteriorLMInfo * interiorInfo = mInteriors[i];
- for(S32 j = interiorInfo->mInstances.size() - 1; j >= 0; j--)
- {
- InstanceLMInfo * instanceInfo = interiorInfo->mInstances[j];
- for(S32 k = interiorInfo->mNumLightmaps - 1; k >= 0; k--)
- {
- // will want to remove the vector here eventually... so dont clear
- instanceInfo->mLightmapHandles[k] = NULL;
- }
- }
- }
- }
- void InteriorLMManager::downloadGLTextures()
- {
- for(S32 i = mInteriors.size() - 1; i >= 0; i--)
- downloadGLTextures(i);
- }
- void InteriorLMManager::downloadGLTextures(LM_HANDLE interiorHandle)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::downloadGLTextures: invalid interior handle");
- InteriorLMInfo * interiorInfo = mInteriors[interiorHandle];
- // The bit vector is used to keep track of which lightmap sets need
- // to be loaded from the shared "base" instance. Every instance
- // can have it's own lightmap set due to mission lighting.
- BitVector needTexture;
- needTexture.setSize(interiorInfo->mNumLightmaps);
- needTexture.clear();
- for(S32 j = interiorInfo->mInstances.size() - 1; j >= 0; j--)
- {
- InstanceLMInfo * instanceInfo = interiorInfo->mInstances[j];
- for(S32 k = instanceInfo->mLightmapHandles.size() - 1; k >= 0; k--)
- {
- // All instances can share the base instances static lightmaps.
- // Test here to see if we need to load those lightmaps.
- if ((j == 0) && !needTexture.test(k))
- continue;
- if (!instanceInfo->mLightmapHandles[k])
- {
- needTexture.set(k);
- continue;
- }
- GFXTexHandle texObj = instanceInfo->mLightmapHandles[k];
- if (!texObj || !texObj->mBitmap)
- {
- needTexture.set(k);
- continue;
- }
- instanceInfo->mLightmapHandles[k].set( texObj->mBitmap, &GFXDefaultPersistentProfile, false, String("Interior Lightmap Handle") );
- }
- }
- }
- bool InteriorLMManager::loadBaseLightmaps(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::loadBaseLightmaps: invalid interior handle");
- AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::loadBaseLightmaps: invalid instance handle");
- // must use a valid instance handle
- if(!instanceHandle)
- return(false);
- InteriorLMInfo * interiorInfo = mInteriors[interiorHandle];
- if(!interiorInfo->mNumLightmaps)
- return(false);
- InstanceLMInfo * baseInstanceInfo = interiorInfo->mInstances[0];
- // already loaded? (if any bitmap is present, then assumed that all will be)
- GFXTexHandle texture (baseInstanceInfo->mLightmapHandles[0]);
- if(texture.isValid() && texture.getBitmap())
- return(true);
- InstanceLMInfo * instanceInfo = interiorInfo->mInstances[instanceHandle];
- Resource<InteriorResource> & interiorRes = instanceInfo->mInstance->getResource();
- if(!bool(interiorRes))
- return(false);
- GBitmap *** pBitmaps = 0;
- if(!instanceInfo->mInstance->readLightmaps(&pBitmaps))
- return(false);
- for(U32 i = 0; i < interiorRes->getNumDetailLevels(); i++)
- {
- Interior * interior = interiorRes->getDetailLevel(i);
- AssertFatal(interior, "InteriorLMManager::loadBaseLightmaps: invalid detail level in resource");
- AssertFatal(interior->getLMHandle() != LM_HANDLE(-1), "InteriorLMManager::loadBaseLightmaps: interior not added to manager");
- AssertFatal(interior->getLMHandle() < mInteriors.size(), "InteriorLMManager::loadBaseLightmaps: invalid interior");
- InteriorLMInfo * interiorInfo = mInteriors[interior->getLMHandle()];
- InstanceLMInfo * baseInstanceInfo = interiorInfo->mInstances[0];
- for(U32 j = 0; j < interiorInfo->mNumLightmaps; j++)
- {
- AssertFatal(pBitmaps[i][j], "InteriorLMManager::loadBaseLightmaps: invalid bitmap");
- if (baseInstanceInfo->mLightmapHandles[j])
- {
- GFXTextureObject * texObj = baseInstanceInfo->mLightmapHandles[j];
- texObj->mBitmap = pBitmaps[i][j];
- }
- else
- baseInstanceInfo->mLightmapHandles[j].set( pBitmaps[i][j], &GFXDefaultPersistentProfile, false, String("Interior Lightmap Handle") );
- }
- }
- delete [] pBitmaps;
- return(true);
- }
- //------------------------------------------------------------------------------
- GFXTexHandle &InteriorLMManager::getHandle(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle, U32 index)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::getHandle: invalid interior handle");
- AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::getHandle: invalid instance handle");
- AssertFatal(index < mInteriors[interiorHandle]->mNumLightmaps, "InteriorLMManager::getHandle: invalid texture index");
- // valid? if not, then get base lightmap handle
- if(!mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index])
- {
- AssertFatal(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index], "InteriorLMManager::getHandle: invalid base texture handle");
- return(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index]);
- }
- return(mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index]);
- }
- GBitmap * InteriorLMManager::getBitmap(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle, U32 index)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::getBitmap: invalid interior handle");
- AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::getBitmap: invalid instance handle");
- AssertFatal(index < mInteriors[interiorHandle]->mNumLightmaps, "InteriorLMManager::getBitmap: invalid texture index");
- if(!mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index])
- {
- AssertFatal(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index], "InteriorLMManager::getBitmap: invalid base texture handle");
- return(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index]->getBitmap());
- }
- return(mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index]->getBitmap());
- }
- Vector<GFXTexHandle> & InteriorLMManager::getHandles(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::getHandles: invalid interior handle");
- AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::getHandles: invalid instance handle");
- return(mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles);
- }
- //------------------------------------------------------------------------------
- void InteriorLMManager::clearLightmaps(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::clearLightmaps: invalid interior handle");
- AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::clearLightmaps: invalid instance handle");
- for(U32 i = 0; i < mInteriors[interiorHandle]->mNumLightmaps; i++)
- mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[i] = 0;
- }
- //------------------------------------------------------------------------------
- GFXTexHandle &InteriorLMManager::duplicateBaseLightmap(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle, U32 index)
- {
- AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::duplicateBaseLightmap: invalid interior handle");
- AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::duplicateBaseLightmap: invalid instance handle");
- AssertFatal(index < mInteriors[interiorHandle]->mNumLightmaps, "InteriorLMManager::duplicateBaseLightmap: invalid texture index");
- // already exists?
- GFXTexHandle texHandle = mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index];
- if(texHandle && texHandle->getBitmap() )
- return mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index];
- AssertFatal(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index], "InteriorLMManager::duplicateBaseLightmap: invalid base handle");
- // copy it
- GBitmap * src = mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index]->getBitmap();
- GBitmap * dest = new GBitmap(*src);
- // don't want this texture to be downloaded yet (SceneLighting will take care of that)
- GFXTexHandle tHandle( dest, &GFXDefaultPersistentProfile, true, String("Interior Lightmap Handle 2") );
- mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index] = tHandle;
- return mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index];
- }
|