void GuiSplitContainer::solvePanelConstraints( Point2I newDragPos, GuiContainer * firstPanel, GuiContainer * secondPanel, RectI clientRect )
{
   if( !firstPanel || !secondPanel )
      return;

   if ( mOrientation == Horizontal )
   {
      // Constrain based on Y axis (Horizontal Splitter)

      // This accounts for the splitter width 
      S32 splitterSize = (S32)(mSplitRect.extent.y * 0.5);

      // Collapsed fixed panel
      if ( mFixedPanel == SecondPanel && !secondPanel->isVisible() )
      {
         newDragPos = Point2I(mSplitPoint.x, getExtent().y - splitterSize );
      }
      else if( mFixedPanel == SecondPanel && !firstPanel->isVisible() )
      {
         newDragPos = Point2I(mSplitPoint.x, splitterSize );
      }
      else // Normal constraints
      {
         //newDragPos.y -= splitterSize;
         S32 newPosition = mClamp( newDragPos.y, 
                                   firstPanel->getMinExtent().y + splitterSize,
                                   getExtent().y - secondPanel->getMinExtent().y - splitterSize );
         newDragPos = Point2I( mSplitPoint.x, newPosition );
      }
   }
   else
   {
      // Constrain based on X axis (Vertical Splitter)

      // This accounts for the splitter width 
      S32 splitterSize = (S32)(mSplitRect.extent.x * 0.5);

      // Collapsed fixed panel
      if ( mFixedPanel == SecondPanel && !secondPanel->isVisible() )
      {
         newDragPos = Point2I(getExtent().x - splitterSize, mSplitPoint.y  );
      }
      else if ( mFixedPanel == FirstPanel && !firstPanel->isVisible() )
      {
         newDragPos = Point2I( splitterSize, mSplitPoint.x );
      }
      else // Normal constraints
      {
         S32 newPosition = mClamp( newDragPos.x, firstPanel->getMinExtent().x + splitterSize,
            getExtent().x - secondPanel->getMinExtent().x - splitterSize );
         newDragPos = Point2I( newPosition, mSplitPoint.y );
      }
   }

   // Just in case, clamp to bounds of controls
   newDragPos.x = mClamp( newDragPos.x, clientRect.point.x, clientRect.point.x + clientRect.extent.x );
   newDragPos.y = mClamp( newDragPos.y, clientRect.point.y, clientRect.point.y + clientRect.extent.y );

   mSplitPoint = newDragPos;
}
Esempio n. 2
0
   virtual void sampleChannels(int x, int y, unsigned char *out)
   {
      const U32 off = (x * mSourceSize + y) * mNumberOfChannels;

      for(S32 i=0; i<getNumberChannels(); i++)
         out[i] = mClamp(mSourceBuffer[off + i] * mScale, 0x0, 0xFF);
   }
Esempio n. 3
0
//-----------------------------------------------------------------------------
// 
// VEvent::setTriggerTime( pTime );
// 
// Apply the given trigger time to the object.
// 
// If the project was built using the VT_EDITOR preprocessor argument, then
// the validity of the passed value is verified. It also cannot be changed
// while the controller is playing.
// 
//-----------------------------------------------------------------------------
void VEvent::setTriggerTime( const S32 &pTime )
{
#ifdef VT_EDITOR

    VTrack *track = getTrack();
    if ( !track )
    {
        // Apply Time.
        mTriggerTime = pTime;

        return;
    }

    if ( track->isControllerPlaying() )
    {
        // Don't Change While Playing.
        return;
    }

    /*
    // Check For Overlap.
    for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode )
    {
        VEvent *event = ( VEvent* )node;
        if ( event == this )
        {
            // Skip.
            continue;
        }

        const U32 startTime  = getStartTime();
        const U32 finishTime = getFinishTime();

        if ( ( pTime > startTime && pTime < finishTime )
             || ( ( pTime + mDuration ) > startTime && ( pTime + mDuration ) < finishTime )
             || ( pTime < startTime && ( pTime + mDuration ) > finishTime ) )
        {
            // Overlap!
            return;
        }
    }
    */

    // Apply Time.
    mTriggerTime = mClamp( pTime, 0, getControllerDuration() );

    // Sort Events.
    track->sort();

    // Reset Track.
    track->onControllerReset( getControllerTime(), isControllerPlayingForward() );

#else

    // Apply Time.
    mTriggerTime = pTime;

#endif
}
void StdMoveList::clearMoves(U32 count)
{
   if (!mConnection->isConnectionToServer())
   {
      count = mClamp(count,0,mMoveCredit);
      mMoveCredit -= count;
   }

   Parent::clearMoves(count);
}
Esempio n. 5
0
bool AtlasClipMapImageSource::isDataAvailable( const U32 mipLevel, const RectI& inRegion ) const
{
   // We need to convert from a mip level to a level in our TOC, potentially scaling.
   U32 baseMips = getBinLog2(mTOC->getTextureChunkSize());
   U32 tocLevel = -1;
   if(mipLevel >= baseMips)
   {
      // In an inner or leaf tile.
      tocLevel = mipLevel - baseMips;
   }
   else
   {
      // It's in our base tile.
      tocLevel = 0;
   }
   
   // We don't scale beyond the depth of the TOC, so simply assert in that
   // case.
   AssertFatal(tocLevel < mTOC->getTreeDepth(), "AtlasClipMapImageSource::isDataAvailable - went beyond depth of tree.");

   // Check all the chunks of all the stubs in the appropriate region...
   RectI r;
   convertToTOCRect(tocLevel, inRegion, r);

   const S32 xStart = mClamp(r.point.x,               0, BIT(tocLevel));
   const S32 xEnd   = mClamp(r.point.x + r.extent.x,  0, BIT(tocLevel));

   const S32 yStart = mClamp(r.point.y,               0, BIT(tocLevel));
   const S32 yEnd   = mClamp(r.point.y + r.extent.y,  0, BIT(tocLevel));

   for(S32 x=xStart; x<xEnd; x++)
   {
      for(S32 y=yStart; y<yEnd; y++)
      {
         AtlasResourceTexStub *arts = mTOC->getResourceStub(mTOC->getStub(tocLevel, Point2I(x,y)));

         if(!arts->hasResource())
            return false;
      }
   }

   return true;
}
Esempio n. 6
0
   virtual void getColor(int x, int y, unsigned char &r, unsigned char &b, unsigned char &g, unsigned char &a)
   {
      const U32 off = (y * mSourceSize + x) * mNumberOfChannels;

      r = mClamp(U32(mSourceBuffer[off + 0])  *mScale, 0, 0xFF);

      if(mNumberOfChannels >= 2)
         b = mClamp(U32(mSourceBuffer[off + 1]) * mScale, 0, 0xFF);
      else
         b = 0;

      if(mNumberOfChannels >= 3)
         g = mClamp(U32(mSourceBuffer[off + 2]) * mScale, 0, 0xFF);
      else
         g = 0;

      if(mNumberOfChannels >= 4)
         a = mClamp(U32(mSourceBuffer[off + 3]) * mScale, 0, 0xFF);
      else
         a = 0;
   }
Esempio n. 7
0
/// Helper for converting floating point linear volume
/// to a logrithmic integer volume for dsound.
LONG SFXDSVoice::_linearToLogVolume( F32 linVolume )
{
   LONG logVolume;

   if ( linVolume <= 0.0f )
      logVolume = DSBVOLUME_MIN;
   else
   {
      logVolume = -2000.0 * mLog( 1.0f / linVolume );
      logVolume = mClamp( logVolume, DSBVOLUME_MIN, DSBVOLUME_MAX );
   }

   return logVolume;
}
Esempio n. 8
0
void mkFluid::setReflectionSize(U32 size)
{
   mReflectionSize = getNextPow2(mClamp(size, 1, getGlobalReflectionSize()));
   if(mReflectionRT && mReflectionRT->getWidth() != mReflectionSize)
   {
      RenderTextureManager->deleteRenderTexture(mReflectionRT);
      mReflectionRT = NULL;
   }
   if(!mReflectionRT && mReflectionSize > 1)
   {
      RenderTextureFormat testFormat(RGBA8, Depth24, None, Stencil0, 0, false, false);
      RenderTextureFormat bestFit;
      RenderTextureManager->getClosestMatch(testFormat, bestFit);
      
      mReflectionRT = RenderTextureManager->createRenderTexture(mReflectionSize, mReflectionSize, bestFit);
   }
}
Esempio n. 9
0
void TSShapeInstance::setCurrentDetail( S32 dl, F32 intraDL )
{
   PROFILE_SCOPE( TSShapeInstance_setCurrentDetail );

   mCurrentDetailLevel = mClamp( dl, -1, mShape->mSmallestVisibleDL );
   mCurrentIntraDetailLevel = intraDL > 1.0f ? 1.0f : (intraDL < 0.0f ? 0.0f : intraDL);

   // Restrict the chosen detail level by cutoff value.
   if ( smNumSkipRenderDetails > 0 && mCurrentDetailLevel >= 0 )
   {
      S32 cutoff = getMin( smNumSkipRenderDetails, mShape->mSmallestVisibleDL );
      if ( mCurrentDetailLevel < cutoff )
      {
         mCurrentDetailLevel = cutoff;
         mCurrentIntraDetailLevel = 1.0f;
      }
   }
}
void GuiGameListMenuCtrl::setSelected(S32 index)
{
   if (index == NO_ROW)
   {
      // deselection
      mSelected = NO_ROW;
      return;
   }

   if (! isValidRowIndex(index))
   {
      return;
   }

   if (! isRowEnabled(index))
   {
      // row is disabled, it can't be selected
      return;
   }

   mSelected = mClamp(index, 0, mRows.size() - 1);
}
Esempio n. 11
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);
        }
    }
}
Esempio n. 12
0
void ClipMap::calculateClipMapLevels(const F32 near, const F32 far, 
                                          const RectF &texBounds, 
                                          S32 &outStartLevel, S32 &outEndLevel)
{
   PROFILE_START(ClipMap_calculateClipMapLevels);

   // We also have to deal w/ the available data. So let's figure out if our
   // desired TCs are in the loaded textureset.

   // Adjust the specified TC range into a texel range.
   F32 ftexsize = F32(mTextureSize);
   RectF tcR(Point2F(texBounds.point.y * ftexsize, texBounds.point.x * ftexsize), ftexsize * texBounds.extent);

   // If we're tiling, make sure we're only insetting away from the clipmap bounds.
   // This avoids making bad LOD selections at clipmap boundaries.
   // Note: compress several compares into one since a*b=0 iff a==0 or b==0
   bool doInset = true;//mTile || (tcR.point.x * tcR.point.y * (tcR.extent.x+tcR.point.x-mTextureSize) * (tcR.extent.y+tcR.point.y-mTextureSize) != 0); 

   if(doInset)
      tcR.inset(-1, -1);

   // Put some safe defaults in for starters.
   outEndLevel   = mClipStackDepth-1;
   outStartLevel = getMax(outEndLevel-3, S32(0));

   // Now iterate over every clipstack entry and find the smallest that contains
   // the relevant TCs.
   S32 minLevelOverlap = mClipStackDepth - 1;
   S32 maxLevelOverlap = mClipStackDepth - 1;

   for(S32 i=mClipStackDepth-2; i>=0; i--)
   {
      // Find region for entry at this level.
      RectF r;
      F32 biti = F32(BIT(i));
      F32 biticms = F32(BIT(i) * mClipMapSize);
      r.point = Point2F(
         biti * mLevels[i].mToroidalOffset.x, 
         biti * mLevels[i].mToroidalOffset.y);
      r.extent.set(biticms,biticms);

      // Is our tex region fully contained?
      if(r.contains(tcR))
      {
         // If we're fully contained, then this is our new max.
         maxLevelOverlap = i;
         minLevelOverlap = i;
         continue;
      }

      // Or else maybe we've got overlap?
      if (!r.overlaps(tcR))
         break;

      // If we're overlapping then this is our new min...
      minLevelOverlap = getMin(minLevelOverlap, i);
   }

   // Given our level range, do a best fit. We ALWAYS have to have
   // enough for the minimum detail, so we fit that constraint then
   // do our best to give additional detail on top of that.

   // bias the minimum detail to allow smooth transitions to work properly,
   // this avoids a LOT of texture popping.
   maxLevelOverlap++;

   outEndLevel   = mClamp(maxLevelOverlap, 0, mClipStackDepth-1);
   outStartLevel = mClamp(minLevelOverlap, outEndLevel - 3, outEndLevel - 1);

   // Make sure we're not exceeding our max delta.
   const S32 delta = outEndLevel - outStartLevel;
   AssertFatal(delta >= 1 && delta <= 4, 
      "ClipMap::calculateClipMapLevels - range in levels outside of 2..4 range!");

   PROFILE_END();
}
void ColladaShapeLoader::enumerateScene()
{
   // Get animation clips
   Vector<const domAnimation_clip*> animationClips;
   for (S32 iClipLib = 0; iClipLib < root->getLibrary_animation_clips_array().getCount(); iClipLib++) {
      const domLibrary_animation_clips* libraryClips = root->getLibrary_animation_clips_array()[iClipLib];
      for (S32 iClip = 0; iClip < libraryClips->getAnimation_clip_array().getCount(); iClip++)
         appSequences.push_back(new ColladaAppSequence(libraryClips->getAnimation_clip_array()[iClip]));
   }

   // Process all animations => this attaches animation channels to the targeted
   // Collada elements, and determines the length of the sequence if it is not
   // already specified in the Collada <animation_clip> element
   for (S32 iSeq = 0; iSeq < appSequences.size(); iSeq++) {
      ColladaAppSequence* appSeq = dynamic_cast<ColladaAppSequence*>(appSequences[iSeq]);
      F32 maxEndTime = 0;
      F32 minFrameTime = 1000.0f;
      for (S32 iAnim = 0; iAnim < appSeq->getClip()->getInstance_animation_array().getCount(); iAnim++) {
         domAnimation* anim = daeSafeCast<domAnimation>(appSeq->getClip()->getInstance_animation_array()[iAnim]->getUrl().getElement());
         if (anim)
            processAnimation(anim, maxEndTime, minFrameTime);
      }
      if (appSeq->getEnd() == 0)
         appSeq->setEnd(maxEndTime);

      // Collada animations can be stored as sampled frames or true keyframes. For
      // sampled frames, use the same frame rate as the DAE file. For true keyframes,
      // resample at a fixed frame rate.
      appSeq->fps = mClamp(1.0f / minFrameTime + 0.5f, TSShapeLoader::MinFrameRate, TSShapeLoader::MaxFrameRate);
   }

   // First grab all of the top-level nodes
   Vector<domNode*> sceneNodes;
   for (S32 iSceneLib = 0; iSceneLib < root->getLibrary_visual_scenes_array().getCount(); iSceneLib++) {
      const domLibrary_visual_scenes* libScenes = root->getLibrary_visual_scenes_array()[iSceneLib];
      for (S32 iScene = 0; iScene < libScenes->getVisual_scene_array().getCount(); iScene++) {
         const domVisual_scene* visualScene = libScenes->getVisual_scene_array()[iScene];
         for (S32 iNode = 0; iNode < visualScene->getNode_array().getCount(); iNode++)
            sceneNodes.push_back(visualScene->getNode_array()[iNode]);
      }
   }

   // Set LOD option
   bool singleDetail = true;
   switch (ColladaUtils::getOptions().lodType)
   {
      case ColladaUtils::ImportOptions::DetectDTS:
         // Check for a baseXX->startXX hierarchy at the top-level, if we find
         // one, use trailing numbers for LOD, otherwise use a single size
         for (S32 iNode = 0; singleDetail && (iNode < sceneNodes.size()); iNode++) {
            domNode* node = sceneNodes[iNode];
            if (dStrStartsWith(_GetNameOrId(node), "base")) {
               for (S32 iChild = 0; iChild < node->getNode_array().getCount(); iChild++) {
                  domNode* child = node->getNode_array()[iChild];
                  if (dStrStartsWith(_GetNameOrId(child), "start")) {
                     singleDetail = false;
                     break;
                  }
               }
            }
         }
         break;

      case ColladaUtils::ImportOptions::SingleSize:
         singleDetail = true;
         break;

      case ColladaUtils::ImportOptions::TrailingNumber:
         singleDetail = false;
         break;
         
      default:
         break;
   }

   ColladaAppMesh::fixDetailSize( singleDetail, ColladaUtils::getOptions().singleDetailSize );

   // Process the top level nodes
   for (S32 iNode = 0; iNode < sceneNodes.size(); iNode++) {
      ColladaAppNode* node = new ColladaAppNode(sceneNodes[iNode], 0);
      if (!processNode(node))
         delete node;
   }

   // Make sure that the scene has a bounds node (for getting the root scene transform)
   if (!boundsNode)
   {
      domVisual_scene* visualScene = root->getLibrary_visual_scenes_array()[0]->getVisual_scene_array()[0];
      domNode* dombounds = daeSafeCast<domNode>( visualScene->createAndPlace( "node" ) );
      dombounds->setName( "bounds" );
      ColladaAppNode *appBounds = new ColladaAppNode(dombounds, 0);
      if (!processNode(appBounds))
         delete appBounds;
   }
}
Esempio n. 14
0
void ArrayObject::insert( const String &key, const String &value, S32 index )
{
   index = mClamp( index, 0, mArray.size() );
   mArray.insert( index, Element( key, value ) );
}
Esempio n. 15
0
{
   AssertFatal( terrain, "TerrainSmoothAction::smooth() - Got null object!" );

   // Store our input parameters.
   mTerrainId = terrain->getId();
   mSteps = steps;
   mFactor = factor;

   // The redo can do the rest.
   redo();
}

DefineConsoleMethod( TerrainSmoothAction, smooth, void, ( TerrainBlock *terrain, F32 factor, U32 steps ), , "( TerrainBlock obj, F32 factor, U32 steps )")
{
	if (terrain)
   	object->smooth( terrain, factor, mClamp( steps, 1, 13 ) );
}

void TerrainSmoothAction::undo()
{
   // First find the terrain from the id.
   TerrainBlock *terrain;
   if ( !Sim::findObject( mTerrainId, terrain ) || !terrain )
      return;

   // Get the terrain file.
   TerrainFile *terrFile = terrain->getFile();

   // Copy our stored heightmap to the file.
   terrFile->setHeightMap( mUnsmoothedHeights, false );
Esempio n. 16
0
void AtlasClipMapImageSource::setInterestCenter( const Point2I& origin, const U32 radius )
{
   // Walk the quadtree, topmost unloaded stuff has highest priority.
   // We also need to issue unloads for stuff around the old origin...
   // So let's iterate over everything within the bounds of our radius of BOTH
   // origins. If it's within the originRect, keep it, otherwise cancel it.

   RectI oldOriginTexelRect, newOriginTexelRect;
   RectI oldOriginTOCRect, newOriginTOCRect;
   RectI unionRect;

   for(S32 i=mTOC->getTreeDepth()-1; i>=0; i--)
   {
      const U32 shift = mTOC->getTreeDepth() - i - 1;

      oldOriginTexelRect.point = mCacheOrigin;
      oldOriginTexelRect.point.x >>= shift;
      oldOriginTexelRect.point.y >>= shift;
      oldOriginTexelRect.extent.set(0,0);
      S32 rad = (S32)radius;
      oldOriginTexelRect.inset(-rad, -rad);

      newOriginTexelRect.point = origin;
      newOriginTexelRect.point.x >>= shift;
      newOriginTexelRect.point.y >>= shift;
      newOriginTexelRect.extent.set(0,0);
      newOriginTexelRect.inset(-rad, -rad);

      convertToTOCRect(i, oldOriginTexelRect, oldOriginTOCRect);
      convertToTOCRect(i, newOriginTexelRect, newOriginTOCRect);

      unionRect = oldOriginTOCRect;
      unionRect.unionRects(newOriginTOCRect);

      // Clamp our update region so we're not walking stuff that is out of range.
      const S32 xStart = mClamp(unionRect.point.x, 0, BIT(i));
      const S32 xEnd   = mClamp(unionRect.point.x + unionRect.extent.x, 0, BIT(i));

      const S32 yStart = mClamp(unionRect.point.y, 0, BIT(i));
      const S32 yEnd   = mClamp(unionRect.point.y + unionRect.extent.y, 0, BIT(i));

      for(S32 x=xStart; x<xEnd; x++)
      {
         for(S32 y=yStart; y<yEnd; y++)
         {
            const Point2I pos(x, y);
            AtlasInstanceTexStub *aits = mTOC->getStub(i, pos);

            // Note we weight our loads by depth - the closest to the root
            // goes first.
            if(newOriginTOCRect.pointInRect(pos))
               mTOC->requestLoad(aits, AtlasTOC::NormalPriority, 
                  F32(shift + 1) / F32(mTOC->getTreeDepth() + 1));
            else
            {
               mTOC->cancelLoadRequest(aits, AtlasTOC::NormalPriority);
            }
         }
      }
   }

   // Now we can update the cache origin.
   mCacheOrigin = origin;
}
Esempio n. 17
0
void mkFluid::enableRefraction(bool refract)
{
   mDoRefraction = mClamp((U32)refract, 0, (U32)isGlobalRefractive());
}
Esempio n. 18
0
   void terrTexGen( vertexType vtype, Point4F *clipmapMapping, const MatrixF &blockTransform, const Point3F &cameraPosition, LightInfo *light, SceneState * state)
   {
      PROFILE_SCOPE(Terrain_TexGen);
      SceneManager * sceneManager = state->getSceneManager();
      Point3F relative;
      const F32 blockTexCoordScale = 1.0f / (TerrainRender::mCurrentBlock->getSquareSize() * TerrainBlock::BlockSize);
      // Apply texgen to the new verts...
      if (vtype == vertexTypeFullClipMapping)
      {
         for(U32 i=0; i<mCurVertex; i++)
         {
            mVertexStore[i].texCoord.x = mVertexStore[i].point.x * blockTexCoordScale;
            mVertexStore[i].texCoord.y = mVertexStore[i].point.y * blockTexCoordScale;
         }
      }
      else if (vtype == vertexTypeSingleTextureClipMapping)
      {
         // Compute the fixedfunction vert stuff now
         AssertFatal(clipmapMapping != NULL, "TerrBatch::end - vertexTypeSingleTextureClipMapping requires clipmapMapping variable!");
         const F32 fadeConstant = 3.0f;
         const F32 blockTexCoordScale2 = blockTexCoordScale * clipmapMapping->z;
         for(U32 i=0; i<mCurVertex; i++)
         {
            mVertexStorePCNT[i].point = mVertexStore[i].point;
            mVertexStorePCNT[i].normal = mVertexStore[i].normal;
            mVertexStorePCNT[i].texCoord.x = mVertexStore[i].point.x * blockTexCoordScale2;
            mVertexStorePCNT[i].texCoord.y = mVertexStore[i].point.y * blockTexCoordScale2;
            relative.x = mVertexStorePCNT[i].texCoord.x - clipmapMapping->x;
            relative.y = mVertexStorePCNT[i].texCoord.y - clipmapMapping->y;
            relative.z = 0;
            // note: this uses 128.0f - instead of 255.0f - to hide some
            // transition artifacts at the edges (which are not visible
            // in the shader path due to its use of /2 in the vertex
            // shader and saturate(fade*2) in the pixel shader, which
            // allows sharp transitions to be interpolated more cleanly)
            mVertexStorePCNT[i].color.set(255, 255, 255, (U8)mClampF(128.0f - (relative.len() * (2.0f * fadeConstant) - (fadeConstant - 1.0f)) * 255.0f, 0.0f, 255.0f));
         }
      }
      else if (vtype == vertexTypeDLight)
      {
         // Compute the fixedfunction vert stuff now
         AssertFatal(clipmapMapping != NULL, "TerrBatch::end - vertexTypeDLight requires clipmapMapping variable!");
         AssertFatal(light != NULL, "TerrBatch::end - vertexTypeDLight requires light variable!");
         AssertFatal(light->mRadius > 0, "TerrBatch::end - vertexTypeDLight requires light->mRadius > 0!");
         const F32 blockTexCoordScale2 = blockTexCoordScale * clipmapMapping->z;
         const F32 heightOffset = sceneManager->getFogHeightOffset();
         const F32 inverseHeightRange = sceneManager->getFogInvHeightRange();
         const F32 inverseVisibleDistanceMod = 1.0f / sceneManager->getVisibleDistanceMod();
         Point3F worldPoint;
         const F32 lightRadius = light->mRadius;
         const Point3F lightPosition = light->mPos;
         F32 intensity;
         const F32 inverseLightRadius = 1.0f / lightRadius;
         // note: this imitates sgLightingModel only very loosely for
         // performance reasons, it does look very similar to the shader path
         for(U32 i=0; i<mCurVertex; i++)
         {
            mVertexStorePCNTT[i].point = mVertexStore[i].point;
            mVertexStorePCNTT[i].normal = mVertexStore[i].normal;
            mVertexStorePCNTT[i].texCoord[0].x = mVertexStore[i].point.x * blockTexCoordScale2;
            mVertexStorePCNTT[i].texCoord[0].y = mVertexStore[i].point.y * blockTexCoordScale2;
            blockTransform.mulP(mVertexStore[i].point, &worldPoint);
            relative = worldPoint - cameraPosition;
            mVertexStorePCNTT[i].texCoord[1].x = 1.0 - (relative.len() * inverseVisibleDistanceMod);
            mVertexStorePCNTT[i].texCoord[1].y = (worldPoint.z - heightOffset) * inverseHeightRange;
            relative = worldPoint - lightPosition;
            intensity = getMax(1.0f - relative.len() * inverseLightRadius, 0.0f);
            intensity = 512.0f * intensity;
            if (intensity > 0)
               mVertexStorePCNTT[i].color.set((U8)getMin(light->mColor.red * intensity, 255.0f), (U8)getMin(light->mColor.green * intensity, 255.0f), (U8)getMin(light->mColor.blue * intensity, 255.0f), 255);
            else
               mVertexStorePCNTT[i].color.set(0, 0, 0, 255);
         }
      }
      else if (vtype == vertexTypeFog)
      {
         const F32 heightOffset = sceneManager->getFogHeightOffset();
         const F32 inverseHeightRange = sceneManager->getFogInvHeightRange();
         const F32 inverseVisibleDistanceMod = 1.0f / sceneManager->getVisibleDistanceMod();
         Point3F worldPoint;
         for(U32 i=0; i<mCurVertex; i++)
         {
            mVertexStorePCNT[i].point = mVertexStore[i].point;
            mVertexStorePCNT[i].normal = mVertexStore[i].normal;
            blockTransform.mulP(mVertexStore[i].point, &worldPoint);
            relative = worldPoint - cameraPosition;
            mVertexStorePCNT[i].texCoord.x = 1.0 - (relative.len() * inverseVisibleDistanceMod);
            mVertexStorePCNT[i].texCoord.y = (worldPoint.z - heightOffset) * inverseHeightRange;
            mVertexStorePCNT[i].color.set(255, 255, 255, 255);
         }
      }
      // The only time 'vertexTypeDetail' is used is during a fixed-function detail pass.
      else if( vtype == vertexTypeDetail )
      {
         // Get detail distance squared to save us from sqrt
         const F32 detailDistanceSquared = TerrainRender::mCurrentBlock->mDetailDistance * TerrainRender::mCurrentBlock->mDetailDistance;

         // Detail Brightness done via assignment of color values
         const U8 colorByte = mClamp( 255 * TerrainRender::mCurrentBlock->mDetailBrightness, 0, 255 );

         Point3F worldPoint;
         for( U32 i = 0; i < mCurVertex; i++ )
         {
            mVertexStorePCNT[i].point = mVertexStore[i].point;
            mVertexStorePCNT[i].normal = mVertexStore[i].normal;
            mVertexStorePCNT[i].texCoord.x = mVertexStore[i].point.x * blockTexCoordScale;
            mVertexStorePCNT[i].texCoord.y = mVertexStore[i].point.y * blockTexCoordScale;

            // Transform vertex into world space
            blockTransform.mulP( mVertexStore[i].point, &worldPoint );
            relative = worldPoint - cameraPosition;

            // Alpha
            const F32 alpha = TerrainRender::mCurrentBlock->mDetailBrightness * ( 1.0f - ( relative.lenSquared() / detailDistanceSquared ) );

            // Assign alpha value to vert so the detail texture blend fades
            mVertexStorePCNT[i].color.set( colorByte, colorByte, colorByte, mClamp( alpha * 255, 0, 255 ) );
         }
      }
      else
      {
         for(U32 i=0; i<mCurVertex; i++)
         {
            mVertexStorePCNT[i].point = mVertexStore[i].point;
            mVertexStorePCNT[i].normal = mVertexStore[i].normal;
            mVertexStorePCNT[i].texCoord.x = mVertexStore[i].point.x * blockTexCoordScale;
            mVertexStorePCNT[i].texCoord.y = mVertexStore[i].point.y * blockTexCoordScale;
            mVertexStorePCNT[i].color.set(255, 255, 255, 255);
         }
      }
   }
Esempio n. 19
0
bool StandardMainLoop::doMainLoop()
{
   #ifdef TORQUE_DEBUG
   if( gStartupTimer )
   {
      Con::printf( "Started up in %.2f seconds...",
         F32( gStartupTimer->getElapsedMs() ) / 1000.f );
      SAFE_DELETE( gStartupTimer );
   }
   #endif
   
   bool keepRunning = true;
//   while(keepRunning)
   {
      tm->setBackgroundThreshold(mClamp(sgBackgroundProcessSleepTime, 1, 200));
      tm->setForegroundThreshold(mClamp(sgTimeManagerProcessInterval, 1, 200));
      // update foreground/background status
      if(WindowManager->getFirstWindow())
      {
         static bool lastFocus = false;
         bool newFocus = ( WindowManager->getFocusedWindow() != NULL );
         if(lastFocus != newFocus)
         {
#ifndef TORQUE_SHIPPING
            Con::printf("Window focus status changed: focus: %d", newFocus);
            if (!newFocus)
               Con::printf("  Using background sleep time: %u", Platform::getBackgroundSleepTime());
#endif

#ifdef TORQUE_OS_MAC
            if (newFocus)
               WindowManager->getFirstWindow()->show();
               
#endif
            lastFocus = newFocus;
         }
         
#ifndef TORQUE_OS_MAC         
         // under the web plugin do not sleep the process when the child window loses focus as this will cripple the browser perfomance
         if (!Platform::getWebDeployment())
            tm->setBackground(!newFocus);
         else
            tm->setBackground(false);
#else
         tm->setBackground(false);
#endif
      }
      else
      {
         tm->setBackground(false);
      }
      
      PROFILE_START(MainLoop);
      Sampler::beginFrame();

      if(!Process::processEvents())
         keepRunning = false;

      ThreadPool::processMainThreadWorkItems();
      Sampler::endFrame();
      PROFILE_END_NAMED(MainLoop);
   }
   
   return keepRunning;
}
Esempio n. 20
0
void TerrCell::_updateVertexBuffer()
{
   PROFILE_SCOPE( TerrCell_UpdateVertexBuffer );

   // Start off with no empty squares
   mHasEmpty = false;
   mEmptyVertexList.clear();

   mVertexBuffer.set( GFX, smVBSize, GFXBufferTypeStatic );

   const F32 squareSize = mTerrain->getSquareSize();
   const U32 blockSize = mTerrain->getBlockSize();
   const U32 stepSize = mSize / smMinCellSize;

   U32 vbcounter = 0;

   TerrVertex *vert = mVertexBuffer.lock();

   Point2I gridPt;
   Point2F point;
   F32 height;
   Point3F normal;   
   
   const TerrainFile *file = mTerrain->getFile();

   for ( U32 y = 0; y < smVBStride; y++ )
   {
      for ( U32 x = 0; x < smVBStride; x++ )
      {
         // We clamp here to keep the geometry from reading across
         // one side of the height map to the other causing walls
         // around the edges of the terrain.
         gridPt.x = mClamp( mPoint.x + x * stepSize, 0, blockSize - 1 );
         gridPt.y = mClamp( mPoint.y + y * stepSize, 0, blockSize - 1 );

         // Setup this point.
         point.x = (F32)gridPt.x * squareSize;
         point.y = (F32)gridPt.y * squareSize;
         height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
         vert->point.x = point.x;
         vert->point.y = point.y;
         vert->point.z = height;

         // Get the normal.
         mTerrain->getSmoothNormal( point, &normal, true, false );
         vert->normal = normal;

         // Get the tangent z.
         vert->tangentZ = fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) ) - height;

         // Test the empty state for this vert.
         if ( file->isEmptyAt( gridPt.x, gridPt.y ) )
         {
            mHasEmpty = true;
            mEmptyVertexList.push_back( vbcounter );
         }

         vbcounter++;
         ++vert;
      }
   }

   // Add verts for 'skirts' around/beneath the edge verts of this cell.
   // This could probably be reduced to a loop...
   
   const F32 skirtDepth = mSize / smMinCellSize * mTerrain->getSquareSize();

   // Top edge skirt
   for ( U32 i = 0; i < smVBStride; i++ )
   {      
      gridPt.x = mClamp( mPoint.x + i * stepSize, 0, blockSize - 1 );
      gridPt.y = mClamp( mPoint.y, 0, blockSize - 1 );
      
      point.x = (F32)gridPt.x * squareSize;
      point.y = (F32)gridPt.y * squareSize;
      height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
      vert->point.x = point.x;
      vert->point.y = point.y;
      vert->point.z = height - skirtDepth;

      // Get the normal.
      mTerrain->getNormal( point, &normal, true, false );
      vert->normal = normal;

      // Get the tangent.
      vert->tangentZ = height - fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) );

      vbcounter++;
      ++vert;      
   }

   // Bottom edge skirt
   for ( U32 i = 0; i < smVBStride; i++ )
   {      
      gridPt.x = mClamp( mPoint.x + i * stepSize, 0, blockSize - 1 );
      gridPt.y = mClamp( mPoint.y + smMinCellSize * stepSize, 0, blockSize - 1 );

      point.x = (F32)gridPt.x * squareSize;
      point.y = (F32)gridPt.y * squareSize;
      height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
      vert->point.x = point.x;
      vert->point.y = point.y;
      vert->point.z = height - skirtDepth;

      // Get the normal.
      mTerrain->getNormal( point, &normal, true, false );
      vert->normal = normal;

      // Get the tangent.
      vert->tangentZ = height - fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) );

      vbcounter++;
      ++vert;      
   }

   // Left edge skirt
   for ( U32 i = 0; i < smVBStride; i++ )
   {      
      gridPt.x = mClamp( mPoint.x, 0, blockSize - 1 );
      gridPt.y = mClamp( mPoint.y + i * stepSize, 0, blockSize - 1 );

      point.x = (F32)gridPt.x * squareSize;
      point.y = (F32)gridPt.y * squareSize;
      height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
      vert->point.x = point.x;
      vert->point.y = point.y;
      vert->point.z = height - skirtDepth;

      // Get the normal.
      mTerrain->getNormal( point, &normal, true, false );
      vert->normal = normal;

      // Get the tangent.
      vert->tangentZ = height - fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) );

      vbcounter++;
      ++vert;      
   }

   // Right edge skirt
   for ( U32 i = 0; i < smVBStride; i++ )
   {      
      gridPt.x = mClamp( mPoint.x + smMinCellSize * stepSize, 0, blockSize - 1 );
      gridPt.y = mClamp( mPoint.y + i * stepSize, 0, blockSize - 1 );

      point.x = (F32)gridPt.x * squareSize;
      point.y = (F32)gridPt.y * squareSize;
      height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
      vert->point.x = point.x;
      vert->point.y = point.y;
      vert->point.z = height - skirtDepth;

      // Get the normal.
      mTerrain->getNormal( point, &normal, true, false );
      vert->normal = normal;

      // Get the tangent.
      vert->tangentZ = height - fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) );

      vbcounter++;
      ++vert;      
   }

   AssertFatal( vbcounter == smVBSize, "bad" );
   mVertexBuffer.unlock();
}