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::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];
}
Ejemplo n.º 3
0
void blInteriorProxy::addToShadowVolume(ShadowVolumeBSP * shadowVolume, LightInfo * light, S32 level)
{
    if(light->getType() != LightInfo::Vector)
        return;

    ColorF ambient = light->getAmbient();

    bool shadowedTree = true;

    InteriorInstance* interior = dynamic_cast<InteriorInstance*>(getObject());
    if (!interior)
        return;
    Resource<InteriorResource> mInteriorRes = interior->getResource();

    // check if just getting shadow detail
    if(level == SceneLighting::SHADOW_DETAIL)
    {
        shadowedTree = false;
        level = mInteriorRes->getNumDetailLevels() - 1;
    }

    Interior * detail = mInteriorRes->getDetailLevel(level);
    bool hasAlarm = detail->hasAlarmState();

    // make sure surfaces do not get processed more than once
    BitVector surfaceProcessed;
    surfaceProcessed.setSize(detail->mSurfaces.size());
    surfaceProcessed.clear();

    ColorI color = light->getAmbient();

    // go through the zones of the interior and grab outside visible surfaces
    for(U32 i = 0; i < detail->getNumZones(); i++)
    {
        Interior::Zone & zone = detail->mZones[i];
        for(U32 j = 0; j < zone.surfaceCount; j++)
        {
            U32 surfaceIndex = detail->mZoneSurfaces[zone.surfaceStart + j];

            // dont reprocess a surface
            if(surfaceProcessed.test(surfaceIndex))
                continue;
            surfaceProcessed.set(surfaceIndex);

            Interior::Surface & surface = detail->mSurfaces[surfaceIndex];

            // outside visible?
            if(!(surface.surfaceFlags & Interior::SurfaceOutsideVisible))
                continue;

            // good surface?
            PlaneF plane = detail->getPlane(surface.planeIndex);
            if(Interior::planeIsFlipped(surface.planeIndex))
                plane.neg();

            // project the plane
            PlaneF projPlane;
            mTransformPlane(interior->getTransform(), interior->getScale(), plane, &projPlane);

            // fill with ambient? (need to do here, because surface will not be
            // added to the SVBSP tree)
            F32 dot = mDot(projPlane, light->getDirection());
            if(dot > -gParellelVectorThresh)// && !(GFX->getPixelShaderVersion() > 0.0) )
            {
                if(shadowedTree)
                {
                    // alarm lighting
                    GFXTexHandle normHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getNormalLMapIndex(surfaceIndex));
                    GFXTexHandle alarmHandle;

                    GBitmap * normLightmap = normHandle->getBitmap();
                    GBitmap * alarmLightmap = 0;

                    // check if they share the lightmap
                    if(hasAlarm)
                    {
                        if(detail->getNormalLMapIndex(surfaceIndex) != detail->getAlarmLMapIndex(surfaceIndex))
                        {
                            alarmHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getAlarmLMapIndex(surfaceIndex));
                            alarmLightmap = alarmHandle->getBitmap();
                        }
                    }

                    //
                    // Support for interior light map border sizes.
                    //
                    U32 xlen, ylen, xoff, yoff;
                    U32 lmborder = detail->getLightMapBorderSize();
                    xlen = surface.mapSizeX + (lmborder * 2);
                    ylen = surface.mapSizeY + (lmborder * 2);
                    xoff = surface.mapOffsetX - lmborder;
                    yoff = surface.mapOffsetY - lmborder;

                    // attemp to light normal and alarm lighting
                    for(U32 c = 0; c < 2; c++)
                    {
                        GBitmap * lightmap = (c == 0) ? normLightmap : alarmLightmap;
                        if(!lightmap)
                            continue;

                        // fill it
                        for(U32 y = 0; y < ylen; y++)
                        {
                            for(U32 x = 0; x < xlen; x++)
                            {
                                ColorI outColor(255, 0, 0, 255);

#ifndef SET_COLORS
                                ColorI lmColor(0, 0, 0, 255);
                                lightmap->getColor(xoff + x, yoff + y, lmColor);

                                U32 _r = static_cast<U32>( color.red ) + static_cast<U32>( lmColor.red );
                                U32 _g = static_cast<U32>( color.green ) + static_cast<U32>( lmColor.green );
                                U32 _b = static_cast<U32>( color.blue ) + static_cast<U32>( lmColor.blue );

                                outColor.red   = mClamp(_r, 0, 255);
                                outColor.green = mClamp(_g, 0, 255);
                                outColor.blue  = mClamp(_b, 0, 255);
#endif

                                lightmap->setColor(xoff + x, yoff + y, outColor);
                            }
                        }
                    }
                }
                continue;
            }

            ShadowVolumeBSP::SVPoly * poly = buildInteriorPoly(shadowVolume, detail,
                                             surfaceIndex, light, shadowedTree);

            // insert it into the SVBSP tree
            shadowVolume->insertPoly(poly);
        }
    }
}