void TerrainFile::smooth( F32 factor, U32 steps, bool updateCollision )
{
   const U32 blockSize = mSize * mSize;

   // Grab some temp buffers for our smoothing results.
   Vector<F32> h1, h2;
   h1.setSize( blockSize );
   h2.setSize( blockSize );

   // Fill the first buffer with the current heights.   
   for ( U32 i=0; i < blockSize; i++ )
      h1[i] = (F32)mHeightMap[i];

   // factor of 0.0 = NO Smoothing
   // factor of 1.0 = MAX Smoothing
   const F32 matrixM = 1.0f - getMax(0.0f, getMin(1.0f, factor));
   const F32 matrixE = (1.0f-matrixM) * (1.0f/12.0f) * 2.0f;
   const F32 matrixC = matrixE * 0.5f;

   // Now loop for our interations.
   F32 *src = h1.address();
   F32 *dst = h2.address();
   for ( U32 s=0; s < steps; s++ )
   {
      for ( S32 y=0; y < mSize; y++ )
      {
         for ( S32 x=0; x < mSize; x++ )
         {
            F32 samples[9];

            S32 c = 0;
            for (S32 i = y-1; i < y+2; i++)
               for (S32 j = x-1; j < x+2; j++)
               {
                  if ( i < 0 || j < 0 || i >= mSize || j >= mSize )
                     samples[c++] = src[ x + ( y * mSize ) ];
                  else
                     samples[c++] = src[ j + ( i * mSize ) ];
               }

            //  0  1  2
            //  3 x,y 5
            //  6  7  8

            dst[ x + ( y * mSize ) ] =
               ((samples[0]+samples[2]+samples[6]+samples[8]) * matrixC) +
               ((samples[1]+samples[3]+samples[5]+samples[7]) * matrixE) +
               (samples[4] * matrixM);
         }
      }

      // Swap!
      F32 *tmp = dst;
      dst = src;
      src = tmp;
   }

   // Copy the results back to the height map.
   for ( U32 i=0; i < blockSize; i++ )
      mHeightMap[i] = (U16)mCeil( (F32)src[i] );

   if ( updateCollision )
      _buildGridMap();
}
示例#2
0
U32 GFXGLDevice::getNumSamplers() const
{
   return getMin((U32)TEXTURE_STAGE_COUNT,mPixelShaderVersion > 0.001f ? mMaxShaderTextures : mMaxFFTextures);
}
示例#3
0
void LightFlareData::prepRender( SceneRenderState *state, LightFlareState *flareState )
{
   PROFILE_SCOPE( LightFlareData_prepRender );

   const LightInfo *lightInfo = flareState->lightInfo;

   if (  mIsZero( flareState->fullBrightness ) ||
         mIsZero( lightInfo->getBrightness() ) )
      return;

   // Figure out the element count to render.
   U32 elementCount = mElementCount;
   const bool isReflectPass = state->isReflectPass();
   if ( isReflectPass )
   {
      // Then we don't render anything this pass.
      if ( !mRenderReflectPass )
         return;

      // Find the zero distance elements which make 
      // up the corona of the light flare.
      elementCount = 0.0f;
      for ( U32 i=0; i < mElementCount; i++ )
         if ( mIsZero( mElementDist[i] ) )
            elementCount++;
   }

   // Better have something to render.
   if ( elementCount == 0 )
      return;
  
   U32 visDelta = U32_MAX;
   F32 occlusionFade = 1.0f;
   Point3F lightPosSS;
   bool lightVisible = _testVisibility( state, flareState, &visDelta, &occlusionFade, &lightPosSS );
   
   // We can only skip rendering if the light is not 
   // visible, and it has elapsed the fade out time.
   if (  mIsZero( occlusionFade ) ||
         !lightVisible && visDelta > FadeOutTime )
      return;

   const RectI &viewport = GFX->getViewport();
   Point3F oneOverViewportExtent( 1.0f / (F32)viewport.extent.x, 1.0f / (F32)viewport.extent.y, 0.0f );

   // Really convert it to screen space.
   lightPosSS.x -= viewport.point.x;
   lightPosSS.y -= viewport.point.y;
   lightPosSS *= oneOverViewportExtent;
   lightPosSS = ( lightPosSS * 2.0f ) - Point3F::One;
   lightPosSS.y = -lightPosSS.y;
   lightPosSS.z = 0.0f;

   // Take any projection offset into account so that the point where the flare's
   // elements converge is at the 'eye' point rather than the center of the viewport.
   const Point2F& projOffset = state->getFrustum().getProjectionOffset();
   Point3F flareVec( -lightPosSS + Point3F(projOffset.x, projOffset.y, 0.0f) );
   const F32 flareLength = flareVec.len();
   if ( flareLength > 0.0f )
      flareVec *= 1.0f / flareLength;

   // Setup the flare quad points.
   Point3F rotatedBasePoints[4];
   dMemcpy(rotatedBasePoints, sBasePoints, sizeof( sBasePoints ));

   // Rotate the flare quad.
   F32 rot = mAcos( -1.0f * flareVec.x );
   rot *= flareVec.y > 0.0f ? -1.0f : 1.0f;
   MathUtils::vectorRotateZAxis( rot, rotatedBasePoints, 4 );

   // Here we calculate a the light source's influence on 
   // the effect's size and brightness.

   // Scale based on the current light brightness compared to its normal output.
   F32 lightSourceBrightnessScale = lightInfo->getBrightness() / flareState->fullBrightness;

   const Point3F &camPos = state->getCameraPosition();
   const Point3F &lightPos = flareState->lightMat.getPosition();   
   const bool isVectorLight = lightInfo->getType() == LightInfo::Vector;

   // Scale based on world space distance from camera to light source.
   F32 distToCamera = ( camPos - lightPos ).len();
   F32 lightSourceWSDistanceScale = isVectorLight && distToCamera > 0.0f ? 1.0f : getMin( 10.0f / distToCamera, 10.0f );

   // Scale based on screen space distance from screen position of light source to the screen center.
   F32 lightSourceSSDistanceScale = getMax( ( 1.5f - flareLength ) / 1.5f, 0.0f );

   // Scale based on recent visibility changes, fading in or out.
   F32 fadeInOutScale = 1.0f;   
   if (  lightVisible &&
         visDelta < FadeInTime && 
         flareState->occlusion > 0.0f )
      fadeInOutScale = (F32)visDelta / (F32)FadeInTime;
   else if (   !lightVisible && 
               visDelta < FadeOutTime )
      fadeInOutScale = 1.0f - (F32)visDelta / (F32)FadeOutTime;

   // This combined scale influences the size of all elements this effect renders.
   // Note we also add in a scale that is user specified in the Light.
   F32 lightSourceIntensityScale = lightSourceBrightnessScale * 
                                   lightSourceWSDistanceScale * 
                                   lightSourceSSDistanceScale * 
                                   fadeInOutScale * 
                                   flareState->scale *
                                   occlusionFade;

   if ( mIsZero( lightSourceIntensityScale ) )
      return;

   // The baseColor which modulates the color of all elements.
   //
   // These are the factors which affect the "alpha" of the flare effect.
   // Modulate more in as appropriate.
   ColorF baseColor = ColorF::WHITE * lightSourceBrightnessScale * occlusionFade;

   // Setup the vertex buffer for the maximum flare elements.
   const U32 vertCount = 4 * mElementCount;
   if (  flareState->vertBuffer.isNull() || 
         flareState->vertBuffer->mNumVerts != vertCount )
         flareState->vertBuffer.set( GFX, vertCount, GFXBufferTypeDynamic );

   GFXVertexPCT *vert = flareState->vertBuffer.lock();

   const Point2F oneOverTexSize( 1.0f / (F32)mFlareTexture.getWidth(), 1.0f / (F32)mFlareTexture.getHeight() );

   for ( U32 i = 0; i < mElementCount; i++ )
   {      
      // Skip non-zero elements for reflections.
      if ( isReflectPass && mElementDist[i] > 0.0f )
         continue;

      Point3F *basePos = mElementRotate[i] ? rotatedBasePoints : sBasePoints;

      ColorF color( baseColor * mElementTint[i] );
      if ( mElementUseLightColor[i] )
         color *= lightInfo->getColor();
      color.clamp();

      Point3F pos( lightPosSS + flareVec * mElementDist[i] * flareLength );

      const RectF &rect = mElementRect[i];
      Point3F size( rect.extent.x, rect.extent.y, 1.0f );
      size *= mElementScale[i] * mScale * lightSourceIntensityScale;

      AssertFatal( size.x >= 0.0f, "LightFlareData::prepRender - Got a negative element size?" );

      if ( size.x < 100.0f )
      {
         F32 alphaScale = mPow( size.x / 100.0f, 2 );
         color *= alphaScale;
      }

      Point2F texCoordMin, texCoordMax;
      texCoordMin = rect.point * oneOverTexSize;
      texCoordMax = ( rect.point + rect.extent ) * oneOverTexSize;          

      size.x = getMax( size.x, 1.0f );
      size.y = getMax( size.y, 1.0f );
      size *= oneOverViewportExtent;

      vert->color = color;
      vert->point = ( basePos[0] * size ) + pos;      
      vert->texCoord.set( texCoordMin.x, texCoordMax.y );
      vert++;

      vert->color = color;
      vert->point = ( basePos[1] * size ) + pos;
      vert->texCoord.set( texCoordMax.x, texCoordMax.y );
      vert++;

      vert->color = color;
      vert->point = ( basePos[2] * size ) + pos;
      vert->texCoord.set( texCoordMax.x, texCoordMin.y );
      vert++;

      vert->color = color;
      vert->point = ( basePos[3] * size ) + pos;
      vert->texCoord.set( texCoordMin.x, texCoordMin.y );
      vert++;
   }   

   flareState->vertBuffer.unlock();   

   RenderPassManager *rpm = state->getRenderPass();

   // Create and submit the render instance.   
   ParticleRenderInst *ri = rpm->allocInst<ParticleRenderInst>();
   ri->type = RenderPassManager::RIT_Particle;
   ri->vertBuff = &flareState->vertBuffer;
   ri->primBuff = &mFlarePrimBuffer;
   ri->translucentSort = true;
   ri->sortDistSq = ( lightPos - camPos ).lenSquared();
   ri->modelViewProj = &MatrixF::Identity;
   ri->bbModelViewProj = &MatrixF::Identity;
   ri->count = elementCount;
   ri->blendStyle = ParticleRenderInst::BlendGreyscale;
   ri->diffuseTex = mFlareTexture;
   ri->softnessDistance = 1.0f; 
   ri->defaultKey = ri->diffuseTex ? (U32)ri->diffuseTex : (U32)ri->vertBuff; // Sort by texture too.

   // NOTE: Offscreen partical code is currently disabled.
   ri->systemState = PSS_AwaitingHighResDraw;

   rpm->addInst( ri );
}
示例#4
0
文件: Token.cpp 项目: js422/PERL
// ---------------------------------------------------------------------------
//  Token: Getter mthods
// ---------------------------------------------------------------------------
int Token::getMinLength() const {

	switch (fTokenType) {

	case T_CONCAT:
        {
            int sum = 0;
            unsigned int childSize = size();

            for (unsigned int i=0; i<childSize; i++) {
                sum += getChild(i)->getMinLength();
            }
            return sum;
        }
	case T_CONDITION:
	case T_UNION:
        {
			unsigned int childSize = size();

            if (childSize == 0) {
                return 0;
            }
			int ret = getChild(0)->getMinLength();

            for (unsigned int i=1; i < childSize; i++) {

                int min = getChild(i)->getMinLength();
                if (min < ret)
                    ret = min;
            }
			return ret;
        }
	case T_CLOSURE:
	case T_NONGREEDYCLOSURE:
        if (getMin() >= 0)
            return getMin() * getChild(0)->getMinLength();

		return 0;
	case T_EMPTY:
	case T_ANCHOR:
		return 0;
	case T_DOT:
	case T_CHAR:
	case T_RANGE:
	case T_NRANGE:
		return 1;
	case T_INDEPENDENT:
	case T_PAREN:
	case T_MODIFIERGROUP:
		return getChild(0)->getMinLength();
	case T_BACKREFERENCE:
		return 0; // *****  - REVISIT
	case T_STRING:
		return XMLString::stringLen(getString());
	case T_LOOKAHEAD:
	case T_NEGATIVELOOKAHEAD:
	case T_LOOKBEHIND:
	case T_NEGATIVELOOKBEHIND:
		return 0; // *****  - REVIST
//	default:
//		throw;
	}

	// We should not get here, but we have it to make some compilers happy
	return -1;
}
示例#5
0
bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials, 
                                       Pass *pass, 
                                       bool firstPass,
                                       bool prePassMat,
                                       bool reflectMat,
                                       bool baseOnly )
{
   if ( GFX->getPixelShaderVersion() < 3.0f )
      baseOnly = true;

   // NOTE: At maximum we only try to combine sgMaxTerrainMaterialsPerPass materials 
   // into a single pass.  This is sub-optimal for the simplest
   // cases, but the most common case results in much fewer
   // shader generation failures and permutations leading to
   // faster load time and less hiccups during gameplay.
   U32 matCount = getMin( sgMaxTerrainMaterialsPerPass, materials->size() );

   Vector<GFXTexHandle> normalMaps;

   // See if we're currently running under the
   // basic lighting manager.
   //
   // TODO: This seems ugly... we should trigger
   // features like this differently in the future.
   //
   bool useBLM = dStrcmp( LIGHTMGR->getId(), "BLM" ) == 0;

   // Do we need to disable normal mapping?
   const bool disableNormalMaps = MATMGR->getExclusionFeatures().hasFeature( MFT_NormalMap ) || useBLM;

   // How about parallax?
   const bool disableParallaxMaps = GFX->getPixelShaderVersion() < 3.0f || 
                                    MATMGR->getExclusionFeatures().hasFeature( MFT_Parallax );

   // Has advanced lightmap support been enabled for prepass.
   bool advancedLightmapSupport = false;
   if ( prePassMat )
   {
      // This sucks... but it works.
      AdvancedLightBinManager *lightBin;
      if ( Sim::findObject( "AL_LightBinMgr", lightBin ) )
         advancedLightmapSupport = lightBin->MRTLightmapsDuringPrePass();
   }

   // Loop till we create a valid shader!
   while( true )
   {
      FeatureSet features;
      features.addFeature( MFT_VertTransform );

      if ( prePassMat )
      {
         features.addFeature( MFT_EyeSpaceDepthOut );
         features.addFeature( MFT_PrePassConditioner );
         features.addFeature( MFT_DeferredTerrainBaseMap );
         features.addFeature(MFT_isDeferred);

         if ( advancedLightmapSupport )
            features.addFeature( MFT_RenderTarget3_Zero );
      }
      else
      {
         features.addFeature( MFT_TerrainBaseMap );
         features.addFeature( MFT_RTLighting );

         // The HDR feature is always added... it will compile out
         // if HDR is not enabled in the engine.
         features.addFeature( MFT_HDROut );
      }
      features.addFeature(MFT_DeferredTerrainBlankInfoMap);

      // Enable lightmaps and fogging if we're in BL.
      if ( reflectMat || useBLM )
      {
         features.addFeature( MFT_Fog );
         features.addFeature( MFT_ForwardShading );
      }
      if ( useBLM )
         features.addFeature( MFT_TerrainLightMap );

      // The additional passes need to be lerp blended into the
      // target to maintain the results of the previous passes.
      if ( !firstPass )
         features.addFeature( MFT_TerrainAdditive );

      normalMaps.clear();
      pass->materials.clear();

      // Now add all the material layer features.

      for ( U32 i=0; i < matCount && !baseOnly; i++ )
      {
         TerrainMaterial *mat = (*materials)[i]->mat;

         if ( mat == NULL )
            continue;

         // We only include materials that 
         // have more than a base texture.
         if (  mat->getDetailSize() <= 0 ||
               mat->getDetailDistance() <= 0 ||
               mat->getDetailMap().isEmpty() )
            continue;         

         S32 featureIndex = pass->materials.size();

		 // check for macro detail texture
         if (  !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
         {
            if(prePassMat)
               features.addFeature( MFT_DeferredTerrainMacroMap, featureIndex );
            else
	         features.addFeature( MFT_TerrainMacroMap, featureIndex );
         }

         if(prePassMat)
             features.addFeature( MFT_DeferredTerrainDetailMap, featureIndex );
         else
         features.addFeature( MFT_TerrainDetailMap, featureIndex );

         pass->materials.push_back( (*materials)[i] );
         normalMaps.increment();

         // Skip normal maps if we need to.
         if ( !disableNormalMaps && mat->getNormalMap().isNotEmpty() )
         {
            features.addFeature( MFT_TerrainNormalMap, featureIndex );

            normalMaps.last().set( mat->getNormalMap(), 
               &GFXDefaultStaticNormalMapProfile, "TerrainCellMaterial::_createPass() - NormalMap" );

            if ( normalMaps.last().getFormat() == GFXFormatDXT5 )
               features.addFeature( MFT_IsDXTnm, featureIndex );

            // Do we need and can we do parallax mapping?
            if (  !disableParallaxMaps &&
                  mat->getParallaxScale() > 0.0f &&
                  !mat->useSideProjection() )
               features.addFeature( MFT_TerrainParallaxMap, featureIndex );
         }

         // Is this layer got side projection?
         if ( mat->useSideProjection() )
            features.addFeature( MFT_TerrainSideProject, featureIndex );
      }

      MaterialFeatureData featureData;
      featureData.features = features;
      featureData.materialFeatures = features;

      // Check to see how many vertex shader output 
      // registers we're gonna need.
      U32 numTex = 0;
      U32 numTexReg = 0;
      for ( U32 i=0; i < features.getCount(); i++ )
      {
         S32 index;
         const FeatureType &type = features.getAt( i, &index );
         ShaderFeature* sf = FEATUREMGR->getByType( type );
         if ( !sf ) 
            continue;

         sf->setProcessIndex( index );
         ShaderFeature::Resources res = sf->getResources( featureData );

         numTex += res.numTex;
         numTexReg += res.numTexReg;
      }

      // Can we build the shader?
      //
      // NOTE: The 10 is sort of an abitrary SM 3.0 
      // limit.  Its really supposed to be 11, but that
      // always fails to compile so far.
      //
      if (  numTex < GFX->getNumSamplers() &&
            numTexReg <= 10 )
      {         
         // NOTE: We really shouldn't be getting errors building the shaders,
         // but we can generate more instructions than the ps_2_x will allow.
         //
         // There is no way to deal with this case that i know of other than
         // letting the compile fail then recovering by trying to build it
         // with fewer materials.
         //
         // We normally disable the shader error logging so that the user 
         // isn't fooled into thinking there is a real bug.  That is until
         // we get down to a single material.  If a single material case
         // fails it means it cannot generate any passes at all!
         const bool logErrors = matCount == 1;
         GFXShader::setLogging( logErrors, true );

         pass->shader = SHADERGEN->getShader( featureData, getGFXVertexFormat<TerrVertex>(), NULL, mSamplerNames );
      }

      // If we got a shader then we can continue.
      if ( pass->shader )
         break;

      // If the material count is already 1 then this
      // is a real shader error... give up!
      if ( matCount <= 1 )
         return false;

      // If we failed we next try half the input materials
      // so that we can more quickly arrive at a valid shader.
      matCount -= matCount / 2;
   }

   // Setup the constant buffer.
   pass->consts = pass->shader->allocConstBuffer();

   // Prepare the basic constants.
   pass->modelViewProjConst = pass->shader->getShaderConstHandle( "$modelview" );
   pass->worldViewOnly = pass->shader->getShaderConstHandle( "$worldViewOnly" );
   pass->viewToObj = pass->shader->getShaderConstHandle( "$viewToObj" );
   pass->eyePosWorldConst = pass->shader->getShaderConstHandle( "$eyePosWorld" );
   pass->eyePosConst = pass->shader->getShaderConstHandle( "$eyePos" );
   pass->vEyeConst = pass->shader->getShaderConstHandle( "$vEye" );
   pass->layerSizeConst = pass->shader->getShaderConstHandle( "$layerSize" );
   pass->objTransConst = pass->shader->getShaderConstHandle( "$objTrans" );
   pass->worldToObjConst = pass->shader->getShaderConstHandle( "$worldToObj" );  
   pass->lightInfoBufferConst = pass->shader->getShaderConstHandle( "$lightInfoBuffer" );   
   pass->baseTexMapConst = pass->shader->getShaderConstHandle( "$baseTexMap" );
   pass->layerTexConst = pass->shader->getShaderConstHandle( "$layerTex" );
   pass->fogDataConst = pass->shader->getShaderConstHandle( "$fogData" );
   pass->fogColorConst = pass->shader->getShaderConstHandle( "$fogColor" );
   pass->lightMapTexConst = pass->shader->getShaderConstHandle( "$lightMapTex" );
   pass->oneOverTerrainSize = pass->shader->getShaderConstHandle( "$oneOverTerrainSize" );
   pass->squareSize = pass->shader->getShaderConstHandle( "$squareSize" );

   pass->lightParamsConst = pass->shader->getShaderConstHandle( "$rtParamslightInfoBuffer" );

   // Now prepare the basic stateblock.
   GFXStateBlockDesc desc;
   if ( !firstPass )
   {
      desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha );

      // If this is the prepass then we don't want to
      // write to the last two color channels (where
      // depth is usually encoded).
      //
      // This trick works in combination with the 
      // MFT_TerrainAdditive feature to lerp the
      // output normal with the previous pass.
      //
      if ( prePassMat )
         desc.setColorWrites( true, true, true, false );
   }

   // We write to the zbuffer if this is a prepass
   // material or if the prepass is disabled.
   desc.setZReadWrite( true,  !MATMGR->getPrePassEnabled() || 
                              prePassMat ||
                              reflectMat );

   desc.samplersDefined = true;
   if ( pass->baseTexMapConst->isValid() )
      desc.samplers[pass->baseTexMapConst->getSamplerRegister()] = GFXSamplerStateDesc::getWrapLinear();

   if ( pass->layerTexConst->isValid() )
      desc.samplers[pass->layerTexConst->getSamplerRegister()] = GFXSamplerStateDesc::getClampPoint();

   if ( pass->lightInfoBufferConst->isValid() )
      desc.samplers[pass->lightInfoBufferConst->getSamplerRegister()] = GFXSamplerStateDesc::getClampPoint();

   if ( pass->lightMapTexConst->isValid() )
      desc.samplers[pass->lightMapTexConst->getSamplerRegister()] = GFXSamplerStateDesc::getWrapLinear();

   const U32 maxAnisotropy = MATMGR->getDefaultAnisotropy();

   // Finally setup the material specific shader 
   // constants and stateblock state.
   //
   // NOTE: If this changes be sure to check TerrainCellMaterial::_updateDefaultAnisotropy
   // to see if it needs the same changes.
   //
   for ( U32 i=0; i < pass->materials.size(); i++ )
   {
      MaterialInfo *matInfo = pass->materials[i];

      matInfo->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) );
      matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%d", i ) );

      matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) );
      if ( matInfo->detailTexConst->isValid() )
      {
         const S32 sampler = matInfo->detailTexConst->getSamplerRegister();

         desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
         desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
         desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;

         if ( maxAnisotropy > 1 )
         {
            desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
            desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
         }
         else
            desc.samplers[sampler].minFilter = GFXTextureFilterLinear;

         matInfo->detailTex.set( matInfo->mat->getDetailMap(), 
            &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - DetailMap" );
      }

      matInfo->macroInfoVConst = pass->shader->getShaderConstHandle( avar( "$macroScaleAndFade%d", i ) );
      matInfo->macroInfoPConst = pass->shader->getShaderConstHandle( avar( "$macroIdStrengthParallax%d", i ) );

      matInfo->macroTexConst = pass->shader->getShaderConstHandle( avar( "$macroMap%d", i ) );
      if ( matInfo->macroTexConst->isValid() )
      {
         const S32 sampler = matInfo->macroTexConst->getSamplerRegister();

         desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
         desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
         desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;

         if ( maxAnisotropy > 1 )
         {
            desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
            desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
         }
         else
            desc.samplers[sampler].minFilter = GFXTextureFilterLinear;

         matInfo->macroTex.set( matInfo->mat->getMacroMap(), 
            &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - MacroMap" );
      }
	  //end macro texture

      matInfo->normalTexConst = pass->shader->getShaderConstHandle( avar( "$normalMap%d", i ) );
      if ( matInfo->normalTexConst->isValid() )
      {
         const S32 sampler = matInfo->normalTexConst->getSamplerRegister();

         desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
         desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
         desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;

         if ( maxAnisotropy > 1 )
         {
            desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
            desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
         }
         else
            desc.samplers[sampler].minFilter = GFXTextureFilterLinear;

         matInfo->normalTex = normalMaps[i];
      }
   }

   // Remove the materials we processed and leave the
   // ones that remain for the next pass.
   for ( U32 i=0; i < matCount; i++ )
   {
      MaterialInfo *matInfo = materials->first();
      if ( baseOnly || pass->materials.find_next( matInfo ) == -1 )
         delete matInfo;     
      materials->pop_front();
   }

   // If we're doing prepass it requires some 
   // special stencil settings for it to work.
   if ( prePassMat )
      desc.addDesc( RenderPrePassMgr::getOpaqueStenciWriteDesc( false ) );

   desc.setCullMode( GFXCullCCW );
   pass->stateBlock = GFX->createStateBlock(desc);

   //reflection stateblock
   desc.setCullMode( GFXCullCW );
   pass->reflectionStateBlock = GFX->createStateBlock(desc);

   // Create the wireframe state blocks.
   GFXStateBlockDesc wireframe( desc );
   wireframe.fillMode = GFXFillWireframe;
   wireframe.setCullMode( GFXCullCCW );
   pass->wireframeStateBlock = GFX->createStateBlock( wireframe );

   return true;
}
示例#6
0
    KeyType getMin() {

      return getMin(root); 

    } 
示例#7
0
//-----------------------------------------------------------------------------
bool FileStream::_write(const U32 i_numBytes, const void *i_pBuffer)
{
   AssertFatal(0 != mStreamCaps, "FileStream::_write: the stream isn't open");
   AssertFatal(NULL != i_pBuffer || i_numBytes == 0, "FileStream::_write: NULL source buffer pointer on non-zero write request");

   if (!hasCapability(Stream::StreamWrite))
   {
      AssertFatal(false, "FileStream::_write: file stream lacks capability");
      Stream::setStatus(IllegalCall);
      return(false);
   }

   // exit on pre-existing errors
   if (Ok != getStatus() && EOS != getStatus())
      return(false);

   // if a request of non-zero length was made
   if (0 != i_numBytes)
   {
      U8 *pSrc = (U8 *)i_pBuffer;
      U32 writeSize;
      U32 remaining = i_numBytes;
      U32 bytesWrit;
      U32 blockHead;
      U32 blockTail;

      // check if the buffer is valid
      if (BUFFER_INVALID != mBuffHead)
      {
         // copy as much as possible from the source to the buffer
         calcBlockBounds(mBuffHead, &blockHead, &blockTail);
         writeSize = (mBuffPos > blockTail) ? 0 : blockTail - mBuffPos + 1;
         writeSize = getMin(writeSize, remaining);

         AssertFatal(0 == writeSize || (mBuffPos - blockHead) < BUFFER_SIZE, "FileStream::_write: out of bounds buffer position");
         dMemcpy(mBuffer + (mBuffPos - blockHead), pSrc, writeSize);
         // reduce the remaining amount to be written
         remaining -= writeSize;
         // advance the buffer pointers
         mBuffPos += writeSize;
         mBuffTail = getMax(mBuffTail, mBuffPos - 1);
         pSrc += writeSize;
         // mark the buffer dirty
         if (0 < writeSize)
            mDirty = true;
      }

      // if the request wasn't satisfied by the buffer
      if (0 < remaining)
      {
         // flush the buffer if its dirty, since we now need to go to disk
         if (mDirty)
            flush();

         // make sure we know the current write location in the underlying file
         mBuffPos = mFile->getPosition();
         calcBlockBounds(mBuffPos, &blockHead, &blockTail);

         // check if the data to be written falls within a single block
         if ((mBuffPos + remaining) <= blockTail)
         {
            // write the data to the buffer
            dMemcpy(mBuffer + (mBuffPos - blockHead), pSrc, remaining);
            // update the buffer pointers
            mBuffHead = mBuffPos;
            mBuffPos += remaining;
            mBuffTail = mBuffPos - 1;
            // mark the buffer dirty
            mDirty = true;
         }
         // otherwise the remaining spans multiple blocks
         else
         {
            clearBuffer();
            // write to disk directly from the source
            bytesWrit = mFile->write((char *)pSrc, remaining);
            setStatus();
            return(Ok == getStatus() || EOS == getStatus());
         }
      }
   }
   return(true);
}
int  main()
{
	int width;
	char* bayer[] = {"RG","BG","GR","GB"};
	char* controls[MAX_CONTROL] = {"Exposure", "Gain", "Gamma", "WB_R", "WB_B", "Brightness", "USB Traffic"};

	int height;
	int i;
	char c;
	bool bresult;

	int time1,time2;
	int count=0;

	char buf[128]={0};

	int CamNum=0;
	
	///long exposure, exp_min, exp_max, exp_step, exp_flag, exp_default;
	//long gain, gain_min, gain_max,gain_step, gain_flag, gain_default;

	IplImage *pRgb;


	int numDevices = getNumberOfConnectedCameras();
	if(numDevices <= 0)
	{
		printf("no camera connected, press any key to exit\n");
		getchar();
		return -1;
	}
	else
		printf("attached cameras:\n");

	for(i = 0; i < numDevices; i++)
		printf("%d %s\n",i, getCameraModel(i));

	printf("\nselect one to privew\n");
	scanf("%d", &CamNum);


	bresult = openCamera(CamNum);
	if(!bresult)
	{
		printf("OpenCamera error,are you root?,press any key to exit\n");
		getchar();
		return -1;
	}

	printf("%s information\n",getCameraModel(CamNum));
	int iMaxWidth, iMaxHeight;
	iMaxWidth = getMaxWidth();
	iMaxHeight =  getMaxHeight();
	printf("resolution:%dX%d\n", iMaxWidth, iMaxHeight);
	if(isColorCam())
		printf("Color Camera: bayer pattern:%s\n",bayer[getColorBayer()]);
	else
		printf("Mono camera\n");
	
	for( i = 0; i < MAX_CONTROL; i++)
	{
			if(isAvailable((Control_TYPE)i))
				printf("%s support:Yes\n", controls[i]);
			else
				printf("%s support:No\n", controls[i]);
	}

	printf("\nPlease input the <width height bin image_type> with one space, ie. 640 480 2 0. use max resolution if input is 0. Press ESC when video window is focused to quit capture\n");
	int bin = 1, Image_type;
	scanf("%d %d %d %d", &width, &height, &bin, &Image_type);
	if(width == 0 || height == 0)
	{
		width = iMaxWidth;
		height = iMaxHeight;
	}

	initCamera(); //this must be called before camera operation. and it only need init once
	printf("sensor temperature:%02f\n", getSensorTemp());

//	IMG_TYPE image_type;
	
	while(!setImageFormat(width, height, bin, (IMG_TYPE)Image_type))//IMG_RAW8
	{
		printf("Set format error, please check the width and height\n ASI120's data size(width*height) must be integer multiple of 1024\n");
		printf("Please input the width and height again£¬ie. 640 480\n");
		scanf("%d %d %d %d", &width, &height, &bin, &Image_type);
	}
	printf("\nset image format %d %d %d %d success, start privew, press ESC to stop \n", width, height, bin, Image_type);

	
	if(Image_type == IMG_RAW16)
		pRgb=cvCreateImage(cvSize(getWidth(),getHeight()), IPL_DEPTH_16U, 1);
	else if(Image_type == IMG_RGB24)
		pRgb=cvCreateImage(cvSize(getWidth(),getHeight()), IPL_DEPTH_8U, 3);
	else
		pRgb=cvCreateImage(cvSize(getWidth(),getHeight()), IPL_DEPTH_8U, 1);

	setValue(CONTROL_EXPOSURE, 100*1000, false); //ms//auto
	setValue(CONTROL_GAIN,getMin(CONTROL_GAIN), false); 
	setValue(CONTROL_BANDWIDTHOVERLOAD, getMin(CONTROL_BANDWIDTHOVERLOAD), false); //low transfer speed

	setValue(CONTROL_WB_B, 90, false);
 	setValue(CONTROL_WB_R, 48, false);
  	setAutoPara(getMax(CONTROL_GAIN)/2,10,150); //max auto gain and exposure and target brightness
//	EnableDarkSubtract("dark.bmp"); //dark subtract will be disabled when exposure set auto and exposure below 500ms
	startCapture(); //start privew


	

	bDisplay = 1;
#ifdef _LIN
	pthread_t thread_display;
	pthread_create(&thread_display, NULL, Display, (void*)pRgb);
#elif defined _WINDOWS
	HANDLE thread_setgainexp;
	thread_setgainexp = (HANDLE)_beginthread(Display,  NULL, (void*)pRgb);
#endif

	time1 = GetTickCount();
	int iStrLen = 0, iTextX = 40, iTextY = 60;
	void* retval;
//	int time0, iWaitMs = -1;
//	bool bGetImg;
	while(bMain)
	{

//		time0 = GetTickCount();
		getImageData((unsigned char*)pRgb->imageData, pRgb->imageSize, 200);

//		bGetImg = getImageData((unsigned char*)pRgb->imageData, pRgb->imageSize, iWaitMs);
		time2 = GetTickCount();
//		printf("waitMs%d, deltaMs%d, %d\n", iWaitMs, time2 - time0, bGetImg);
		count++;
		
		if(time2-time1 > 1000 )
		{
			sprintf(buf, "fps:%d dropped frames:%lu ImageType:%d",count, getDroppedFrames(), (int)getImgType());

			count = 0;
			time1=GetTickCount();	
			printf(buf);
			printf("\n");

		}
		if(Image_type != IMG_RGB24 && Image_type != IMG_RAW16)
		{
			iStrLen = strlen(buf);
			CvRect rect = cvRect(iTextX, iTextY - 15, iStrLen* 11, 20);
			cvSetImageROI(pRgb , rect);
			cvSet(pRgb, CV_RGB(180, 180, 180)); 
			cvResetImageROI(pRgb);
		}
		cvText(pRgb, buf, iTextX,iTextY );

		if(bChangeFormat)
		{
			bChangeFormat = 0;
			bDisplay = false;
			pthread_join(thread_display, &retval);
			cvReleaseImage(&pRgb);
			stopCapture();
			
			switch(change)
			{
				 case change_imagetype:
					Image_type++;
					if(Image_type > 3)
						Image_type = 0;
					
					break;
				case change_bin:
					if(bin == 1)
					{
						bin = 2;
						width/=2;
						height/=2;
					}
					else 
					{
						bin = 1;
						width*=2;
						height*=2;
					}
					break;
				case change_size_smaller:
					if(width > 320 && height > 240)
					{
						width/= 2;
						height/= 2;
					}
					break;
				
				case change_size_bigger:
				
					if(width*2*bin <= iMaxWidth && height*2*bin <= iMaxHeight)
					{
						width*= 2;
						height*= 2;
					}
					break;
			}
			setImageFormat(width, height, bin, (IMG_TYPE)Image_type);
			if(Image_type == IMG_RAW16)
				pRgb=cvCreateImage(cvSize(getWidth(),getHeight()), IPL_DEPTH_16U, 1);
			else if(Image_type == IMG_RGB24)
				pRgb=cvCreateImage(cvSize(getWidth(),getHeight()), IPL_DEPTH_8U, 3);
			else
				pRgb=cvCreateImage(cvSize(getWidth(),getHeight()), IPL_DEPTH_8U, 1);
			bDisplay = 1;
			pthread_create(&thread_display, NULL, Display, (void*)pRgb);
			startCapture(); //start privew
		}
	}
END:
	
	if(bDisplay)
	{
		bDisplay = 0;
#ifdef _LIN
   		pthread_join(thread_display, &retval);
#elif defined _WINDOWS
		Sleep(50);
#endif
	}
	
	stopCapture();
	closeCamera();
	cvReleaseImage(&pRgb);
	printf("main function over\n");
	return 1;
}
示例#9
0
Cube Cube::boundingBox()
{

    return Cube(getMin(),getMax(),getCenter());
}
示例#10
0
bool VolumetricFog::LoadShape()
{
    GFXPrimitiveType GFXdrawTypes[] = { GFXTriangleList, GFXTriangleStrip };
    if (!mShapeName || mShapeName[0] == '\0')
    {
        Con::errorf("VolumetricFog::LoadShape() - No shape name! Volumetric Fog will not be rendered!");
        return false;
    }

    // Load shape, server side only reads bounds and radius

    Resource<TSShape> mShape;
    mShape = ResourceManager::get().load(mShapeName);
    if (bool(mShape) == false)
    {
        Con::errorf("VolumetricFog::LoadShape() - Unable to load shape: %s", mShapeName);
        return false;
    }

    mObjBox = mShape->bounds;
    mRadius = mShape->radius;
    resetWorldBox();

    if (!isClientObject())
        return false;

    TSShapeInstance *mShapeInstance = new TSShapeInstance(mShape, false);
    meshes mesh_detail;

    for (S32 i = 0; i < det_size.size(); i++)
    {
        if (det_size[i].indices != NULL)
            delete(det_size[i].indices);
        if (det_size[i].piArray != NULL)
            delete(det_size[i].piArray);
        if (det_size[i].verts != NULL)
            delete(det_size[i].verts);
    }
    det_size.clear();

    // browsing model for detail levels

    for (U32 i = 0; i < mShape->details.size(); i++)
    {
        const TSDetail *detail = &mShape->details[i];
        mesh_detail.det_size = detail->size;
        mesh_detail.sub_shape = detail->subShapeNum;
        mesh_detail.obj_det = detail->objectDetailNum;
        mesh_detail.verts = NULL;
        mesh_detail.piArray = NULL;
        mesh_detail.indices = NULL;
        if (detail->size >= 0.0f && detail->subShapeNum >= 0)
            det_size.push_back(mesh_detail);
    }

    for (U32 i = 0; i < det_size.size(); i++)
    {
        const S32 ss = det_size[i].sub_shape;
        if (ss >= 0)
        {
            const S32 start = mShape->subShapeFirstObject[ss];
            const S32 end = start + mShape->subShapeNumObjects[ss];
            for (S32 j = start; j < end; j++)
            {
                // Loading shape, only the first mesh for each detail will be used!
                TSShapeInstance::MeshObjectInstance *meshObj = &mShapeInstance->mMeshObjects[j];
                if (!meshObj)
                    continue;
                TSMesh *mesh = meshObj->getMesh(det_size[i].obj_det);
                if (mesh != NULL)
                {
                    const U32 numNrms = mesh->mNumVerts;
                    GFXVertexPNTT *tmpVerts = NULL;
                    tmpVerts = new GFXVertexPNTT[numNrms];
                    mIsVBDirty = true;
                    for (U32 k = 0; k < numNrms; k++)
                    {
                        Point3F norm = mesh->mVertexData[k].normal();
                        Point3F vert = mesh->mVertexData[k].vert();
                        Point2F uv = mesh->mVertexData[k].tvert();
                        tmpVerts[k].point = vert;
                        tmpVerts[k].texCoord = uv;
                        tmpVerts[k].normal = norm;
                    }
                    det_size[i].verts = tmpVerts;
                    det_size[i].num_verts = numNrms;

                    det_size[i].piArray = new Vector<GFXPrimitive>();
                    GFXPrimitive pInfo;

                    det_size[i].indices = new Vector<U32>();

                    for (U32 k = 0; k < mesh->indices.size(); k++)
                        det_size[i].indices->push_back(mesh->indices[k]);

                    U32 primitivesSize = mesh->primitives.size();
                    for (U32 k = 0; k < primitivesSize; k++)
                    {
                        const TSDrawPrimitive & draw = mesh->primitives[k];
                        GFXPrimitiveType drawType = GFXdrawTypes[draw.matIndex >> 30];
                        switch (drawType)
                        {
                        case GFXTriangleList:
                            pInfo.type = drawType;
                            pInfo.numPrimitives = draw.numElements / 3;
                            pInfo.startIndex = draw.start;
                            // Use the first index to determine which 16-bit address space we are operating in
                            pInfo.startVertex = mesh->indices[draw.start] & 0xFFFF0000;
                            pInfo.minIndex = pInfo.startVertex;
                            pInfo.numVertices = getMin((U32)0x10000, mesh->mNumVerts - pInfo.startVertex);
                            break;
                        case GFXTriangleStrip:
                            pInfo.type = drawType;
                            pInfo.numPrimitives = draw.numElements - 2;
                            pInfo.startIndex = draw.start;
                            // Use the first index to determine which 16-bit address space we are operating in
                            pInfo.startVertex = mesh->indices[draw.start] & 0xFFFF0000;
                            pInfo.minIndex = pInfo.startVertex;
                            pInfo.numVertices = getMin((U32)0x10000, mesh->mNumVerts - pInfo.startVertex);
                            break;
                        default:
                            Con::errorf("VolumetricFog::LoadShape Unknown drawtype!?!");
                            return false;
                            break;
                        }
                        det_size[i].piArray->push_back(pInfo);
                        j = end;
                    }
                }
                else
                {
                    Con::errorf("VolumetricFog::LoadShape Error loading mesh from shape!");
                    delete mShapeInstance;
                    return false;
                }
                mIsVBDirty = true;
                mIsPBDirty = true;
            }
        }
    }
示例#11
0
void TSShapeInstance::animateNodes(S32 ss)
{
   PROFILE_SCOPE( TSShapeInstance_animateNodes );

   if (!mShape->nodes.size())
      return;

   // @todo: When a node is added, we need to make sure to resize the nodeTransforms array as well
   mNodeTransforms.setSize(mShape->nodes.size());

   // temporary storage for node transforms
   mCurrentRenderState->smNodeCurrentRotations.setSize(mShape->nodes.size());
   mCurrentRenderState->smNodeCurrentTranslations.setSize(mShape->nodes.size());
   mCurrentRenderState->smNodeLocalTransforms.setSize(mShape->nodes.size());
   mCurrentRenderState->smRotationThreads.setSize(mShape->nodes.size());
   mCurrentRenderState->smTranslationThreads.setSize(mShape->nodes.size());

   TSIntegerSet rotBeenSet;
   TSIntegerSet tranBeenSet;
   TSIntegerSet scaleBeenSet;
   rotBeenSet.setAll(mShape->nodes.size());
   tranBeenSet.setAll(mShape->nodes.size());
   scaleBeenSet.setAll(mShape->nodes.size());
   mCurrentRenderState->smNodeLocalTransformDirty.clearAll();

   S32 i,j,nodeIndex,a,b,start,end,firstBlend = mThreadList.size();
   for (i=0; i<mThreadList.size(); i++)
   {
      TSThread * th = mThreadList[i];

      if (th->getSequence()->isBlend())
      {
         // blend sequences need default (if not set by other sequence)
         // break rather than continue because the rest will be blends too
         firstBlend = i;
         break;
      }
      rotBeenSet.takeAway(th->getSequence()->rotationMatters);
      tranBeenSet.takeAway(th->getSequence()->translationMatters);
      scaleBeenSet.takeAway(th->getSequence()->scaleMatters);
   }
   rotBeenSet.takeAway(mCallbackNodes);
   rotBeenSet.takeAway(mHandsOffNodes);
   rotBeenSet.overlap(mMaskRotationNodes);

   TSIntegerSet maskPosNodes=mMaskPosXNodes;
   maskPosNodes.overlap(mMaskPosYNodes);
   maskPosNodes.overlap(mMaskPosZNodes);
   tranBeenSet.overlap(maskPosNodes);

   tranBeenSet.takeAway(mCallbackNodes);
   tranBeenSet.takeAway(mHandsOffNodes);
   // can't add masked nodes since x, y, & z masked separately...
   // we'll set default regardless of mask status

   // all the nodes marked above need to have the default transform
   a = mShape->subShapeFirstNode[ss];
   b = a + mShape->subShapeNumNodes[ss];
   for (i=a; i<b; i++)
   {
      if (rotBeenSet.test(i))
      {
         mShape->defaultRotations[i].getQuatF(&mCurrentRenderState->smNodeCurrentRotations[i]);
         mCurrentRenderState->smRotationThreads[i] = NULL;
      }
      if (tranBeenSet.test(i))
      {
         mCurrentRenderState->smNodeCurrentTranslations[i] = mShape->defaultTranslations[i];
         mCurrentRenderState->smTranslationThreads[i] = NULL;
      }
   }

   // don't want a transform in these cases...
   rotBeenSet.overlap(mHandsOffNodes);
   rotBeenSet.overlap(mCallbackNodes);
   tranBeenSet.takeAway(maskPosNodes);
   tranBeenSet.overlap(mHandsOffNodes);
   tranBeenSet.overlap(mCallbackNodes);

   // default scale
   if (scaleCurrentlyAnimated())
      handleDefaultScale(a,b,scaleBeenSet);

   // handle non-blend sequences
   for (i=0; i<firstBlend; i++)
   {
      TSThread * th = mThreadList[i];

      j=0;
      start = th->getSequence()->rotationMatters.start();
      end   = b;
      for (nodeIndex=start; nodeIndex<end; th->getSequence()->rotationMatters.next(nodeIndex), j++)
      {
         // skip nodes outside of this detail
         if (nodeIndex<a)
            continue;
         if (!rotBeenSet.test(nodeIndex))
         {
            QuatF q1,q2;
            mShape->getRotation(*th->getSequence(),th->keyNum1,j,&q1);
            mShape->getRotation(*th->getSequence(),th->keyNum2,j,&q2);
            TSTransform::interpolate(q1,q2,th->keyPos,&mCurrentRenderState->smNodeCurrentRotations[nodeIndex]);
            rotBeenSet.set(nodeIndex);
            mCurrentRenderState->smRotationThreads[nodeIndex] = th;
         }
      }

      j=0;
      start = th->getSequence()->translationMatters.start();
      end   = b;
      for (nodeIndex=start; nodeIndex<end; th->getSequence()->translationMatters.next(nodeIndex), j++)
      {
         if (nodeIndex<a)
            continue;
         if (!tranBeenSet.test(nodeIndex))
         {
            if (maskPosNodes.test(nodeIndex))
               handleMaskedPositionNode(th,nodeIndex,j);
            else
            {
               const Point3F & p1 = mShape->getTranslation(*th->getSequence(),th->keyNum1,j);
               const Point3F & p2 = mShape->getTranslation(*th->getSequence(),th->keyNum2,j);
               TSTransform::interpolate(p1,p2,th->keyPos,&mCurrentRenderState->smNodeCurrentTranslations[nodeIndex]);
               mCurrentRenderState->smTranslationThreads[nodeIndex] = th;
            }
            tranBeenSet.set(nodeIndex);
         }
      }

      if (scaleCurrentlyAnimated())
         handleAnimatedScale(th,a,b,scaleBeenSet);
   }

   // compute transforms
   for (i=a; i<b; i++)
   {
      if (!mHandsOffNodes.test(i))
         TSTransform::setMatrix(mCurrentRenderState->smNodeCurrentRotations[i],mCurrentRenderState->smNodeCurrentTranslations[i],&mCurrentRenderState->smNodeLocalTransforms[i]);
      else
         mCurrentRenderState->smNodeLocalTransforms[i] = mNodeTransforms[i];     // in case mNodeTransform was changed externally
   }

   // add scale onto transforms
   if (scaleCurrentlyAnimated())
      handleNodeScale(a,b);

   // get callbacks...
   start = getMax(mCallbackNodes.start(),a);
   end = getMin(mCallbackNodes.end(),b);
   for (i=0; i<mNodeCallbacks.size(); i++)
   {
      AssertFatal(mNodeCallbacks[i].callback, "No callback method defined");
      S32 nodeIndex = mNodeCallbacks[i].nodeIndex;
      if (nodeIndex>=start && nodeIndex<end)
      {
         mNodeCallbacks[i].callback->setNodeTransform(this, nodeIndex, mCurrentRenderState->smNodeLocalTransforms[nodeIndex]);
         mCurrentRenderState->smNodeLocalTransformDirty.set(nodeIndex);
      }
   }

   // handle blend sequences
   for (i=firstBlend; i<mThreadList.size(); i++)
   {
      TSThread * th = mThreadList[i];
      if (th->blendDisabled)
         continue;

      handleBlendSequence(th,a,b);
   }

   // transitions...
   if (inTransition())
      handleTransitionNodes(a,b);

   // multiply transforms...
   for (i=a; i<b; i++)
   {
      S32 parentIdx = mShape->nodes[i].parentIndex;
      if (parentIdx < 0)
         mNodeTransforms[i] = mCurrentRenderState->smNodeLocalTransforms[i];
      else
         mNodeTransforms[i].mul(mNodeTransforms[parentIdx],mCurrentRenderState->smNodeLocalTransforms[i]);
   }
}
示例#12
0
int isMin(byte *g) {
  byte buf[W*H];

  getMin(g,buf);
  return(compare(g,buf)==0);
}//isMin
示例#13
0
/**
 * Sets the speed at which this AI moves
 *
 * @param speed Speed to move, default player was 10
 */
void AIPlayer::setMoveSpeed( F32 speed )
{
   mMoveSpeed = getMax(0.0f, getMin( 1.0f, speed ));
}
bool SceneCullingState::isOccludedByTerrain( SceneObject* object ) const
{
   PROFILE_SCOPE( SceneCullingState_isOccludedByTerrain );

   // Don't try to occlude globally bounded objects.
   if( object->isGlobalBounds() )
      return false;

   const Vector< SceneObject* >& terrains = getSceneManager()->getContainer()->getTerrains();
   const U32 numTerrains = terrains.size();

   for( U32 terrainIdx = 0; terrainIdx < numTerrains; ++ terrainIdx )
   {
      TerrainBlock* terrain = dynamic_cast< TerrainBlock* >( terrains[ terrainIdx ] );
      if( !terrain )
         continue;

      Point3F localCamPos = getCameraState().getViewPosition();
      terrain->getWorldTransform().mulP( localCamPos );
      F32 height;
      terrain->getHeight( Point2F( localCamPos.x, localCamPos.y ), &height );
      bool aboveTerrain = ( height <= localCamPos.z );

      // Don't occlude if we're below the terrain.  This prevents problems when
      //  looking out from underground bases...
      if( !aboveTerrain )
         continue;

      const Box3F& oBox = object->getObjBox();
      F32 minSide = getMin(oBox.len_x(), oBox.len_y());
      if (minSide > 85.0f)
         continue;

      const Box3F& rBox = object->getWorldBox();
      Point3F ul(rBox.minExtents.x, rBox.minExtents.y, rBox.maxExtents.z);
      Point3F ur(rBox.minExtents.x, rBox.maxExtents.y, rBox.maxExtents.z);
      Point3F ll(rBox.maxExtents.x, rBox.minExtents.y, rBox.maxExtents.z);
      Point3F lr(rBox.maxExtents.x, rBox.maxExtents.y, rBox.maxExtents.z);

      terrain->getWorldTransform().mulP(ul);
      terrain->getWorldTransform().mulP(ur);
      terrain->getWorldTransform().mulP(ll);
      terrain->getWorldTransform().mulP(lr);

      Point3F xBaseL0_s = ul - localCamPos;
      Point3F xBaseL0_e = lr - localCamPos;
      Point3F xBaseL1_s = ur - localCamPos;
      Point3F xBaseL1_e = ll - localCamPos;

      static F32 checkPoints[3] = {0.75, 0.5, 0.25};
      RayInfo rinfo;
      for( U32 i = 0; i < 3; i ++ )
      {
         Point3F start = (xBaseL0_s * checkPoints[i]) + localCamPos;
         Point3F end   = (xBaseL0_e * checkPoints[i]) + localCamPos;

         if (terrain->castRay(start, end, &rinfo))
            continue;

         terrain->getHeight(Point2F(start.x, start.y), &height);
         if ((height <= start.z) == aboveTerrain)
            continue;

         start = (xBaseL1_s * checkPoints[i]) + localCamPos;
         end   = (xBaseL1_e * checkPoints[i]) + localCamPos;

         if (terrain->castRay(start, end, &rinfo))
            continue;

         Point3F test = (start + end) * 0.5;
         if (terrain->castRay(localCamPos, test, &rinfo) == false)
            continue;

         return true;
      }
   }

   return false;
}
示例#15
0
for ( ; n>0; n--) {
        insert(F, getMin(F)+1);
        insert(F, getMin(F)-1);
        insert(F, getMin(F)-2);
        deleteMin(F);
        x = min(F).childs[0]; // immer das größte Kind des Minimums
        decreaseKey(x, getMin(F)-2);
        deleteMin(F);
}
示例#16
0
 /// Clamp the value between the minimum and maximum
 inline void clamp(double &val) const
 {
   if(val<min)         val=getMin();
   if(val>(min+width)) val=getMax();
 }
示例#17
0
文件: chunk.cpp 项目: catap/mongo
 bool Chunk::contains( const BSONObj& obj ){
     return
         _manager->getShardKey().compare( getMin() , obj ) <= 0 &&
         _manager->getShardKey().compare( obj , getMax() ) < 0;
 }
示例#18
0
//-----------------------------------------------------------------------------
//
// VActorPhysicsController::postTickUpdate( pDelta );
//
// ...
//
//-----------------------------------------------------------------------------
void VActorPhysicsController::postTickUpdate( const F32 &pDelta )
{
    switch( mControlState )
    {
    case k_PathControlState :
        {
            AssertFatal( isPathing(), "VActorPhysicsController::postTickUpdate() - Invalid Path State." );

            // Fetch Mount Transform.
            MatrixF transform;
            mMountedPath->getMountTransform( mObject->getMountNode(), getTransform(), &transform );
            // Fetch Mount Position.
            const Point3F &mountPosition = transform.getPosition();

            // Update X & Y Position.
            Point3F position = getPosition();
            position.x = mountPosition.x;
            position.y = mountPosition.y;

            // In Water?
            bool underWater = false;
            if ( isInWater() )
            {
                // Fetch Body of Water.
                WaterObject *waterBody = getWaterObject();

                // Fetch Surface Position.
                const F32 &waterSurfacePosition = waterBody->getSurfaceHeight( Point2F( position.x, position.y ) );
                // Fetch Submersion Position.
                const F32 sumbersionPosition = waterSurfacePosition - ( mObject->getWorldBox().len_z() * mObject->getDataBlock()->getSumbergeCoverage() );

                // Choose a Z Value.
                // Note: This is done so that the Actor will either path under the
                //       water, or it will swim along the water's surface.
                position.z = getMin( mountPosition.z, sumbersionPosition );

                // Under Water?
                underWater = ( position.z < sumbersionPosition );
            }

            // Under Water?
            if ( !underWater )
            {
                // Fetch Y Column.
                VectorF forwardVector;
                transform.getColumn( 1, &forwardVector );

                // Determine Angle.
                const F32 &angle = -mAtan2( -forwardVector.x, forwardVector.y );

                // Reset Transform.
                transform.set( EulerF( 0.f, 0.f, angle ) );

                // In the air?
                if ( !isOnGround() )
                {
                    // Apply z-axis force.
                    position.z += ( getVelocity().z * pDelta );
                }
            }

            // Update Transform.
            transform.setPosition( position );

            // Apply Update.
            setTransform( transform );

        } break;

    default :
        {
            // Fetch Transform.
            MatrixF transform = getTransform();

            // Determine the Post-Tick Position.
            Point3F postTickPosition = getPosition() + ( getVelocity() * pDelta );
            // Set the Post Tick Position.
            transform.setPosition( postTickPosition );

            // Apply the Transform.
            setTransform( transform );

        } break;
    }

    // Push Delta.
    mInterpController.pushDelta( getTransform() );
}
示例#19
0
//-----------------------------------------------------------------------------
bool FileStream::_read(const U32 i_numBytes, void *o_pBuffer)
{
   AssertFatal(0 != mStreamCaps, "FileStream::_read: the stream isn't open");
   AssertFatal(NULL != o_pBuffer || i_numBytes == 0, "FileStream::_read: NULL destination pointer with non-zero read request");

   if (!hasCapability(Stream::StreamRead))
   {
      AssertFatal(false, "FileStream::_read: file stream lacks capability");
      Stream::setStatus(IllegalCall);
      return(false);
   }

   // exit on pre-existing errors
   if (Ok != getStatus())
      return(false);

   // if a request of non-zero length was made
   if (0 != i_numBytes)
   {
      U8 *pDst = (U8 *)o_pBuffer;
      U32 readSize;
      U32 remaining = i_numBytes;
      U32 bytesRead;
      U32 blockHead;
      U32 blockTail;

      // check if the buffer has some data in it
      if (BUFFER_INVALID != mBuffHead)
      {
         // copy as much as possible from the buffer into the destination
         readSize = ((mBuffTail + 1) >= mBuffPos) ? (mBuffTail + 1 - mBuffPos) : 0;
         readSize = getMin(readSize, remaining);
         calcBlockHead(mBuffPos, &blockHead);
         dMemcpy(pDst, mBuffer + (mBuffPos - blockHead), readSize);
         // reduce the remaining amount to read
         remaining -= readSize;
         // advance the buffer pointers
         mBuffPos += readSize;
         pDst += readSize;

         if (mBuffPos > mBuffTail && remaining != 0)
         {
            flush();
            mBuffHead = BUFFER_INVALID;
            if (mEOF == true)
               Stream::setStatus(EOS);
         }
      }

      // if the request wasn't satisfied by the buffer and the file has more data
      if (false == mEOF && 0 < remaining)
      {
         // flush the buffer if its dirty, since we now need to go to disk
         if (true == mDirty)
            flush();

         // make sure we know the current read location in the underlying file
         mBuffPos = mFile->getPosition();
         calcBlockBounds(mBuffPos, &blockHead, &blockTail);

         // check if the data to be read falls within a single block
         if ((mBuffPos + remaining) <= blockTail)
         {
            // fill the buffer from disk
            if (true == fillBuffer(mBuffPos))
            {
               // copy as much as possible from the buffer to the destination
               remaining = getMin(remaining, mBuffTail - mBuffPos + 1);
               dMemcpy(pDst, mBuffer + (mBuffPos - blockHead), remaining);
               // advance the buffer pointer
               mBuffPos += remaining;
            }
            else
               return(false);
         }
         // otherwise the remaining spans multiple blocks
         else
         {
            clearBuffer();
            // read from disk directly into the destination
            bytesRead = mFile->read((char *)pDst, remaining);
            setStatus();
            // check to make sure we read as much as expected
            if (Ok == getStatus() || EOS == getStatus())
            {
               // if not, update the end-of-file status
               if (0 != bytesRead && EOS == getStatus())
               {
                  Stream::setStatus(Ok);
                  mEOF = true;
               }
            }
            else
               return(false);
         }
      }
   }
   return(true);
}
示例#20
0
void  detect(IplImage* img_8uc1,IplImage* img_8uc3) 
{  
	clock_t inicio, fin;
	inicio = clock();

	CvMemStorage* storage = cvCreateMemStorage();
	CvSeq* first_contour = NULL;
	CvSeq* maxitem=NULL;
	char resultado [] = " ";
	double area=0,areamax=0;
	double longitudExt = 0;
	double radio = 0;
	int maxn=0;
	int Nc = cvFindContours(
		img_8uc1,
		storage,
		&first_contour,
		sizeof(CvContour),
		CV_RETR_LIST 
		);
	int n=0;
	//printf( "Contornos detectados: %d\n", Nc );

	if(Nc>0)
	{
		for( CvSeq* c=first_contour; c!=NULL; c=c->h_next ) 
		{     
			area=cvContourArea(c,CV_WHOLE_SEQ );

			if(area>areamax)
			{
				areamax=area;
				maxitem=c;
				maxn=n;
			}
			n++;
		}

		CvMemStorage* storage3 = cvCreateMemStorage(0);

		if(areamax>5000)
		{
			maxitem = cvApproxPoly( maxitem, sizeof(CvContour), storage3, CV_POLY_APPROX_DP, 10, 1 );
			CvPoint pt0;

			CvMemStorage* storage1 = cvCreateMemStorage(0);
			CvMemStorage* storage2 = cvCreateMemStorage(0);
			CvSeq* ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvContour), sizeof(CvPoint), storage1 );
			CvSeq* hull;
			CvSeq* defects;

			CvPoint minDefectPos;;
			minDefectPos.x = 1000000;
			minDefectPos.y = 1000000;

			CvPoint maxDefectPos;
			maxDefectPos.x = 0;
			maxDefectPos.y = 0;			


			for(int i = 0; i < maxitem->total; i++ )
			{   
				CvPoint* p = CV_GET_SEQ_ELEM( CvPoint, maxitem, i );
				pt0.x = p->x;
				pt0.y = p->y;
				cvSeqPush( ptseq, &pt0 );
			}
			hull = cvConvexHull2( ptseq, 0, CV_CLOCKWISE, 0 );
			int hullcount = hull->total;

			defects= cvConvexityDefects(ptseq,hull,storage2  );

			//printf(" Numero de defectos %d \n",defects->total);
			CvConvexityDefect* defectArray;  

			int j=0;  

			// This cycle marks all defects of convexity of current contours.  

			longitudExt = 0;

			for(;defects;defects = defects->h_next)  
			{  
				int nomdef = defects->total; // defect amount  
				//outlet_float( m_nomdef, nomdef );  
				//printf(" defect no %d \n",nomdef);

				if(nomdef == 0)  
					continue;  

				// Alloc memory for defect set.     
				//fprintf(stderr,"malloc\n");  
				defectArray = (CvConvexityDefect*)malloc(sizeof(CvConvexityDefect)*nomdef);  

				// Get defect set.  
				//fprintf(stderr,"cvCvtSeqToArray\n");  
				cvCvtSeqToArray(defects,defectArray, CV_WHOLE_SEQ); 






				// Draw marks for all defects.  
				for(int i=0; i<nomdef; i++)  
				{  					

					CvPoint startP;
					startP.x = defectArray[i].start->x;
					startP.y = defectArray[i].start->y;

					CvPoint depthP;
					depthP.x = defectArray[i].depth_point->x;
					depthP.y = defectArray[i].depth_point->y;

					CvPoint endP;
					endP.x = defectArray[i].end->x;
					endP.y = defectArray[i].end->y;





					//obtener minimo y maximo

					minDefectPos.x = getMin (startP.x, depthP.x, endP.x, minDefectPos.x);
					minDefectPos.y = getMin (startP.y, depthP.y, endP.y, minDefectPos.y);

					maxDefectPos.x = getMax (startP.x, depthP.x, endP.x, maxDefectPos.x);
					maxDefectPos.y = getMax (startP.y, depthP.y, endP.y, maxDefectPos.y);					

					//fin obtener minimo y maximo
					if (saveLength)
					{
						longitudExt += longBtwnPoints(startP, depthP);
						longitudExt += longBtwnPoints(depthP, endP);


					}
					//printf(" defect depth for defect %d %f \n",i,defectArray[i].depth);
					cvLine(img_8uc3, startP, depthP, CV_RGB(255,255,0),1, CV_AA, 0 ); 


					cvCircle( img_8uc3, depthP, 5, CV_RGB(0,0,164), 2, 8,0);  
					cvCircle( img_8uc3, startP, 5, CV_RGB(255,0,0), 2, 8,0);  
					cvCircle( img_8uc3, endP, 5, CV_RGB(0,255,0), 2, 8,0);  

					cvLine(img_8uc3, depthP, endP,CV_RGB(0,0,0),1, CV_AA, 0 );   
				} 

				/*if (nomdef>0)
				{
				resultado [0] = identificaGesto (longitudExt, nomdef, radio);
				if (resultado[0] !=' ')
				printf ("Gesto identificado (%c) \n", resultado[0]);
				}*/

				if (saveLength)
				{
					radio = (double)maxDefectPos.x / (double)maxDefectPos.y;
					if (nomdef>0)
					{
						printf ("_______________________\n");

						
 
						
						

						resultado [0] = identificaGesto (longitudExt, nomdef, radio);
						
						fin = clock();
						fin = fin - inicio;

						if (resultado[0] !=' ')
							printf ("Gesto identificado (%c) \n", resultado[0]);
						else
							printf ("No se identifico ningun gesto\n");

						printf("Tiempo de ejecucion: %f\nLongitud %g \nNomDef %i \nradio %g \n",(((float)fin)/CLOCKS_PER_SEC ), longitudExt, nomdef, radio);
						FILE *fp;
						fp=fopen("archivo.txt", "a");
						if (nomdef == 6)
							fprintf(fp, "\n>>>>>>>5<<<<<<\n%g\n%i\n%g\n",longitudExt, nomdef, radio);
						else
							fprintf(fp, "\n%g\n%i\n%g\n",longitudExt, nomdef, radio);
						fclose (fp);
					}
					else
						printf("No hay defectos");
					printf ("_______________________\n");
				}
				/*
				char txt[]="0";
				txt[0]='0'+nomdef-1;
				CvFont font;
				cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 5, CV_AA);
				cvPutText(img_8uc3, txt, cvPoint(50, 50), &font, cvScalar(0, 0, 255, 0)); */

				CvFont font;
				cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 5, CV_AA);
				if (resultado!= NULL)
					cvPutText(img_8uc3, resultado, cvPoint(50, 50), &font, cvScalar(0, 0, 255, 0));

				j++;  

				// Free memory.   
				free(defectArray);  
			} 

			pt0 = **CV_GET_SEQ_ELEM( CvPoint*, hull, hullcount - 1 );

			for(int i = 0; i < hullcount; i++ )
			{

				CvPoint pt = **CV_GET_SEQ_ELEM( CvPoint*, hull, i );
				cvLine( img_8uc3, pt0, pt, CV_RGB( 0, 255, 0 ), 1, CV_AA, 0 );
				pt0 = pt;
			}



			cvLine( img_8uc3, minDefectPos, cvPoint( (maxDefectPos.x), (minDefectPos.y)), CV_RGB( 2500, 0, 0 ), 1, CV_AA, 0 );
			cvLine( img_8uc3,  cvPoint( (maxDefectPos.x), (minDefectPos.y)), maxDefectPos, CV_RGB( 2500, 0, 0 ), 1, CV_AA, 0 );
			cvLine( img_8uc3, maxDefectPos, cvPoint( (minDefectPos.x), (maxDefectPos.y)), CV_RGB( 2500, 0, 0 ), 1, CV_AA, 0 );
			cvLine( img_8uc3, cvPoint( (minDefectPos.x), (maxDefectPos.y)), minDefectPos, CV_RGB( 2500, 0, 0 ), 1, CV_AA, 0 );

			cvReleaseMemStorage( &storage );
			cvReleaseMemStorage( &storage1 );
			cvReleaseMemStorage( &storage2 );
			cvReleaseMemStorage( &storage3 );
			//return 0;
		}
	}
示例#21
0
void ColladaShapeLoader::processAnimation(const domAnimation* anim, F32& maxEndTime, F32& minFrameTime)
{
   const char* sRGBANames[] =   { ".R", ".G", ".B", ".A", "" };
   const char* sXYZNames[] =    { ".X", ".Y", ".Z", "" };
   const char* sXYZANames[] =   { ".X", ".Y", ".Z", ".ANGLE" };
   const char* sLOOKATNames[] = { ".POSITIONX", ".POSITIONY", ".POSITIONZ", ".TARGETX", ".TARGETY", ".TARGETZ", ".UPX", ".UPY", ".UPZ", "" };
   const char* sSKEWNames[] =   { ".ROTATEX", ".ROTATEY", ".ROTATEZ", ".AROUNDX", ".AROUNDY", ".AROUNDZ", ".ANGLE", "" };
   const char* sNullNames[] =   { "" };

   for (int iChannel = 0; iChannel < anim->getChannel_array().getCount(); iChannel++) {

      // Get the animation elements: <channel>, <sampler>
      domChannel* channel = anim->getChannel_array()[iChannel];
      domSampler* sampler = daeSafeCast<domSampler>(channel->getSource().getElement());
      if (!sampler)
         continue;

      // Find the animation channel target
      daeSIDResolver resolver(channel, channel->getTarget());
      daeElement* target = resolver.getElement();
      if (!target) {
         daeErrorHandler::get()->handleWarning(avar("Failed to resolve animation "
            "target: %s", channel->getTarget()));
         continue;
      }
/*
      // If the target is a <source>, point it at the array instead
      // @todo:Only support targeting float arrays for now...
      if (target->getElementType() == COLLADA_TYPE::SOURCE)
      {
         domSource* source = daeSafeCast<domSource>(target);
         if (source->getFloat_array())
            target = source->getFloat_array();
      }
*/
      // Get the target's animation channels (create them if not already)
      if (!AnimData::getAnimChannels(target)) {
         animations.push_back(new AnimChannels(target));
      }
      AnimChannels* targetChannels = AnimData::getAnimChannels(target);

      // Add a new animation channel to the target
      targetChannels->push_back(new AnimData());
      channel->setUserData(targetChannels->last());
      AnimData& data = *targetChannels->last();

      for (int iInput = 0; iInput < sampler->getInput_array().getCount(); iInput++) {

         const domInputLocal* input = sampler->getInput_array()[iInput];
         const domSource* source = daeSafeCast<domSource>(input->getSource().getElement());
         if (!source)
            continue;

         // @todo:don't care about the input param names for now. Could
         // validate against the target type....
         if (dStrEqual(input->getSemantic(), "INPUT")) {
            data.input.initFromSource(source);
            // Adjust the maximum sequence end time
            maxEndTime = getMax(maxEndTime, data.input.getFloatValue((S32)data.input.size()-1));

            // Detect the frame rate (minimum time between keyframes)
            for (S32 iFrame = 1; iFrame < data.input.size(); iFrame++)
            {
               F32 delta = data.input.getFloatValue( iFrame ) - data.input.getFloatValue( iFrame-1 );
               if ( delta < 0 )
               {
                  daeErrorHandler::get()->handleError(avar("<animation> INPUT '%s' "
                     "has non-monotonic keys. Animation is unlikely to be imported correctly.", source->getID()));
                  break;
               }
               minFrameTime = getMin( minFrameTime, delta );
            }
         }
         else if (dStrEqual(input->getSemantic(), "OUTPUT"))
            data.output.initFromSource(source);
         else if (dStrEqual(input->getSemantic(), "IN_TANGENT"))
            data.inTangent.initFromSource(source);
         else if (dStrEqual(input->getSemantic(), "OUT_TANGENT"))
            data.outTangent.initFromSource(source);
         else if (dStrEqual(input->getSemantic(), "INTERPOLATION"))
            data.interpolation.initFromSource(source);
      }

      // Set initial value for visibility targets that were added automatically (in colladaUtils.cpp
      if (dStrEqual(target->getElementName(), "visibility"))
      {
         domAny* visTarget = daeSafeCast<domAny>(target);
         if (visTarget && dStrEqual(visTarget->getValue(), ""))
            visTarget->setValue(avar("%g", data.output.getFloatValue(0)));
      }

      // Ignore empty animations
      if (data.input.size() == 0) {
         channel->setUserData(0);
         delete targetChannels->last();
         targetChannels->pop_back();
         continue;
      }

      // Determine the number and offset the elements of the target value
      // targeted by this animation
      switch (target->getElementType()) {
         case COLLADA_TYPE::COLOR:        data.parseTargetString(channel->getTarget(), 4, sRGBANames);   break;
         case COLLADA_TYPE::TRANSLATE:    data.parseTargetString(channel->getTarget(), 3, sXYZNames);    break;
         case COLLADA_TYPE::ROTATE:       data.parseTargetString(channel->getTarget(), 4, sXYZANames);   break;
         case COLLADA_TYPE::SCALE:        data.parseTargetString(channel->getTarget(), 3, sXYZNames);    break;
         case COLLADA_TYPE::LOOKAT:       data.parseTargetString(channel->getTarget(), 3, sLOOKATNames); break;
         case COLLADA_TYPE::SKEW:         data.parseTargetString(channel->getTarget(), 3, sSKEWNames);   break;
         case COLLADA_TYPE::MATRIX:       data.parseTargetString(channel->getTarget(), 16, sNullNames);  break;
         case COLLADA_TYPE::FLOAT_ARRAY:  data.parseTargetString(channel->getTarget(), daeSafeCast<domFloat_array>(target)->getCount(), sNullNames); break;
         default:                         data.parseTargetString(channel->getTarget(), 1, sNullNames);   break;
      }
   }

   // Process child animations
   for (int iAnim = 0; iAnim < anim->getAnimation_array().getCount(); iAnim++)
      processAnimation(anim->getAnimation_array()[iAnim], maxEndTime, minFrameTime);
}
示例#22
0
文件: makePlots2.C 项目: dcraik/lhcb
void makePlots2() {
	gROOT->ProcessLine(".x lhcbStyle.C");
	gStyle->SetOptStat(0);

	Double_t ignore, eff, massfit1, massfit2, bias1, bias2;

	Double_t value[6][19], stat[6][19], syst[6][19];
	Int_t ng(4);

	TH1D pull("pull","",15,-3.0,3.0);

	std::ifstream fin("errs.dat");
	fin.ignore(256,'\n');
	for(Int_t q=0; q<19; ++q) {
		for(Int_t g=1; g<ng+1; ++g) {	
			fin >> ignore >> ignore >> value[g+1][q] >> stat[g+1][q] >> eff >> massfit1 >> massfit2 >> bias1 >> bias2;
			syst[g+1][q] = TMath::Sqrt(stat[g+1][q]*stat[g+1][q] + eff*eff + massfit1*massfit1 + massfit2*massfit2 + bias1*bias1 + bias2*bias2);
			//plot syst errors on top of stats

			if(q<17) pull.Fill(value[g+1][q]/syst[g+1][q]);
		}
		value[0][q] = value[2][q];
		stat[0][q]  = stat[2][q];
		syst[0][q]  = syst[2][q];

		value[1][q] = 2*value[3][q]+1;
		stat[1][q]  = 2*stat[3][q];
		syst[1][q]  = 2*syst[3][q];
	}

	fin.close();

	Double_t  xs[19] = { 0.54, 1.55, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 11.375, 12.125, 15.5, 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 3.55, 18.5};
	Double_t exs[19] = { 0.44, 0.45, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,  0.375,  0.375,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5, 2.45,  3.5};

	TCanvas c;

	TF1 gaus("gaus","gaus(0)",-3.,3.);
	gaus.SetParameter(0,68);
	gaus.SetParameter(1,pull.GetBinCenter(pull.GetMaximumBin()));
	gaus.SetParameter(2,pull.GetStdDev());
	gaus.SetParLimits(1,-2.0,2.0);
	gaus.SetParLimits(2,0.3,3.0);
	pull.Fit(&gaus,"S");
	pull.Draw();
	c.SaveAs("gPulls.pdf");

	for(Int_t i=0; i<ng+2; ++i) {
            TString varName("");
            TString varName2("");

	    switch(i) {
		    case 0:
			    varName="A_{FB}";
			    varName2="AFB";
			    break;
		    case 1:
			    varName="F_{H}";
			    varName2="FH";
			    break;
		    default:
			    varName="G^{("; varName+=(i-1); varName+=")}";
			    varName2="G"; varName2+=(i-1);
	    }
	    
	    Double_t yMin = getMin(19,value[i])-getMax(19,syst[i]);
	    Double_t yMax = getMax(19,value[i])+getMax(19,syst[i]);

	    if(yMax-yMin == 0) continue;

	    TH2D h("h","",1,0.0,22.,1,yMin,yMax);

	    TLine l(0.0,0.0,22.0,0.0);
	    l.SetLineStyle(kDashed);
	    l.SetLineColor(kRed);
	    
	    h.GetYaxis()->SetTitle(varName);
	    h.GetXaxis()->SetTitle("q^{2} [GeV^{2}/c^{4}]");

	    TGraphErrors g1(17,xs,   value[i],   exs,   stat[i]   );
	    TGraphErrors g2( 2,xs+17,value[i]+17,exs+17,stat[i]+17);
	    TGraphErrors g3(17,xs,   value[i],   exs,   syst[i]   );
	    TGraphErrors g4( 2,xs+17,value[i]+17,exs+17,syst[i]+17);

	    g2.SetLineColor(kBlue);
	    g2.SetMarkerColor(kBlue);
	    g3.SetLineColor(kRed);
	    g4.SetLineColor(kRed);
	    g2.SetFillColor(kBlue);
	    g4.SetFillColor(kRed);
	    g2.SetFillStyle(3001);
	    g4.SetFillStyle(3002);

	    h.Draw();
	    l.Draw();
	    g4.Draw("E2same");
	    g2.Draw("E2same");
	    g3.Draw("PEsame");
	    g1.Draw("PEsame");
	    c.SaveAs("plots/fromPatrickNew/"+varName2+".pdf");
	    c.SaveAs("plots/fromPatrickNew/"+varName2+".png");
	}

}
示例#23
0
//------------------------------------------------------------------------
CMouseEventResult CSlider::onMouseMoved (CPoint& where, const CButtonState& _buttons)
{
	if (isEditing ())
	{
		CButtonState buttons (_buttons);
		if (kAlwaysUseZoomFactor)
			buttons |= kZoomModifier;
		if (buttons & kLButton)
		{
			if (kAlwaysUseZoomFactor)
			{
				CCoord distance = fabs ((style & kHorizontal) ? where.y - mouseStartPoint.y : where.x - mouseStartPoint.x);
				float newZoomFactor = 1.f;
				if (distance > ((style & kHorizontal) ? getHeight () : getWidth ()))
				{
					newZoomFactor = (float)(distance / ((style & kHorizontal) ? getHeight () : getWidth ()));
					newZoomFactor = static_cast<int32_t>(newZoomFactor * 10.f) / 10.f;
				}
				if (zoomFactor != newZoomFactor)
				{
					zoomFactor = newZoomFactor;
					oldVal = (value - getMin ()) / getRange ();
					delta = calculateDelta (where);
				}
			}
			
			if (oldVal == getMin () - 1)
				oldVal = (value - getMin ()) / getRange ();
				
			if ((oldButton != buttons) && (buttons & kZoomModifier))
			{
				oldVal = (value - getMin ()) / getRange ();
				oldButton = buttons;
			}
			else if (!(buttons & kZoomModifier))
				oldVal = (value - getMin ()) / getRange ();

			float normValue;
			if (style & kHorizontal)
				normValue = (float)(where.x - delta) / (float)rangeHandle;
			else
				normValue = (float)(where.y - delta) / (float)rangeHandle;

			if (style & kRight || style & kBottom)
				normValue = 1.f - normValue;

			if (buttons & kZoomModifier)
				normValue = oldVal + ((normValue - oldVal) / zoomFactor);

			setValueNormalized (normValue);
				
			if (isDirty ())
			{
				valueChanged ();
				invalid ();
			}
		}
		return kMouseEventHandled;
	}
	return kMouseEventNotHandled;
}
示例#24
0
void SFXSource::play( F32 fadeInTime )
{
   // Update our status once.
   _updateStatus();

   if( mStatus == SFXStatusPlaying )
      return;

   if( mStatus != SFXStatusPaused )
      mPlayStartTick = Platform::getVirtualMilliseconds();
         
   // Add fade-out, if requested.
   
   U32 fadeOutStartsAt = getDuration();
   if( mFadeOutTime )
   {
      fadeOutStartsAt = getMax( getPosition(), getDuration() - U32( mFadeOutTime * 1000 ) );
      mEffects.pushBack( new SFXFadeEffect( this,
                                            getMin( mFadeOutTime,
                                                    F32( getDuration() - getPosition() ) / 1000.f ),
                                            0.0f,
                                            fadeOutStartsAt,
                                            SFXFadeEffect::ON_END_Stop,
                                            true ) );
   }
   
   // Add fade-in, if requested.
   
   if( fadeInTime != 0.0f && ( fadeInTime > 0.0f || mFadeInTime > 0.0f ) )
   {
      // Don't fade from full 0.0f to avoid virtualization on this source.
      
      if( fadeInTime == -1.0f )
         fadeInTime = mFadeInTime;
         
      fadeInTime = getMin( fadeInTime, F32( fadeOutStartsAt ) * 1000.f );
      
      mEffects.pushFront( new SFXFadeEffect( this, 
                                             fadeInTime,
                                             mVolume,
                                             getPosition(),
                                             SFXFadeEffect::ON_END_Nop,
                                             true ) );
      setVolume( 0.01f );
   }

   // Start playback.

   _setStatus( SFXStatusPlaying );
   if( mVoice )
   {
      #ifdef DEBUG_SPEW
      Platform::outputDebugString( "[SFXSource] playing source '%i'", getId() );
      #endif
      
      mVoice->play( mIsLooping );
   }
   else
   {
      // To ensure the fastest possible reaction 
      // to this playback let the system reassign
      // voices immediately.
      SFX->_assignVoices();

      // If we did not get assigned a voice, start the
      // playback timer for virtualized playback.

      if( !mVoice )
      {
         #ifdef DEBUG_SPEW
         Platform::outputDebugString( "[SFXSource] virtualizing playback of source '%i'", getId() );
         #endif
         
         mVirtualPlayTimer.start();
      }
   }
}
示例#25
0
void GFXGLDevice::initGLState()
{  
   // We don't currently need to sync device state with a known good place because we are
   // going to set everything in GFXGLStateBlock, but if we change our GFXGLStateBlock strategy, this may
   // need to happen.
   
   // Deal with the card profiler here when we know we have a valid context.
   mCardProfiler = new GFXGLCardProfiler();
   mCardProfiler->init(); 
   glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (GLint*)&mMaxShaderTextures);
   // JTH: Needs removed, ffp
   //glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&mMaxFFTextures);
   glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, (GLint*)&mMaxTRColors);
   mMaxTRColors = getMin( mMaxTRColors, (U32)(GFXTextureTarget::MaxRenderSlotId-1) );
   
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   
   // [JTH 5/6/2016] GLSL 1.50 is really SM 4.0
   // Setting mPixelShaderVersion to 3.0 will allow Advanced Lighting to run.   
   mPixelShaderVersion = 3.0;

	// Set capability extensions.
   mCapabilities.anisotropicFiltering = mCardProfiler->queryProfile("GL_EXT_texture_filter_anisotropic");
   mCapabilities.bufferStorage = mCardProfiler->queryProfile("GL_ARB_buffer_storage");
   mCapabilities.shaderModel5 = mCardProfiler->queryProfile("GL_ARB_gpu_shader5");
   mCapabilities.textureStorage = mCardProfiler->queryProfile("GL_ARB_texture_storage");
   mCapabilities.samplerObjects = mCardProfiler->queryProfile("GL_ARB_sampler_objects");
   mCapabilities.copyImage = mCardProfiler->queryProfile("GL_ARB_copy_image");
   mCapabilities.vertexAttributeBinding = mCardProfiler->queryProfile("GL_ARB_vertex_attrib_binding");

   String vendorStr = (const char*)glGetString( GL_VENDOR );
   if( vendorStr.find("NVIDIA", 0, String::NoCase | String::Left) != String::NPos)
      mUseGlMap = false;
   
   // Workaround for all Mac's, has a problem using glMap* with volatile buffers
#ifdef TORQUE_OS_MAC
   mUseGlMap = false;
#endif

#if TORQUE_DEBUG
   if( gglHasExtension(ARB_debug_output) )
   {
      glEnable(GL_DEBUG_OUTPUT);
      glDebugMessageCallbackARB(glDebugCallback, NULL);
      glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
      GLuint unusedIds = 0;
      glDebugMessageControlARB(GL_DONT_CARE,
            GL_DONT_CARE,
            GL_DONT_CARE,
            0,
            &unusedIds,
            GL_TRUE);
   }
   else if(gglHasExtension(AMD_debug_output))
   {
      glEnable(GL_DEBUG_OUTPUT);
      glDebugMessageCallbackAMD(glAmdDebugCallback, NULL);      
      //glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
      GLuint unusedIds = 0;
      glDebugMessageEnableAMD(GL_DONT_CARE, GL_DONT_CARE, 0,&unusedIds, GL_TRUE);
   }
#endif

   PlatformGL::setVSync(smDisableVSync ? 0 : 1);

   //install vsync callback
   Con::NotifyDelegate clbk(this, &GFXGLDevice::vsyncCallback);
   Con::addVariableNotify("$pref::Video::disableVerticalSync", clbk);

   //OpenGL 3 need a binded VAO for render
   GLuint vao;
   glGenVertexArrays(1, &vao);
   glBindVertexArray(vao);
}
示例#26
0
bool GuiTextEditCtrl::onKeyDown(const GuiEvent &event)
{
   if ( !isActive() || !isAwake() )
      return false;

   S32 stringLen = mTextBuffer.length();
   setUpdate();

   // Ugly, but now I'm cool like MarkF.
   if(event.keyCode == KEY_BACKSPACE)
      goto dealWithBackspace;
   
   if ( event.modifier & SI_SHIFT )
   {

      // Added support for word jump selection.

      if ( event.modifier & SI_CTRL )
      {
         switch ( event.keyCode )
         {
            case KEY_LEFT:
            {
               S32 newpos = findPrevWord();               

               if ( mBlockStart == mBlockEnd )
               {
                  // There was not already a selection so start a new one.
                  mBlockStart = newpos;
                  mBlockEnd = mCursorPos;
               }
               else
               {
                  // There was a selection already...
                  // In this case the cursor MUST be at either the
                  // start or end of that selection.

                  if ( mCursorPos == mBlockStart )
                  {
                     // We are at the start block and traveling left so
                     // just extend the start block farther left.                     
                     mBlockStart = newpos;
                  }
                  else
                  {
                     // We are at the end block BUT traveling left
                     // back towards the start block...

                     if ( newpos > mBlockStart )
                     {
                        // We haven't overpassed the existing start block
                        // so just trim back the end block.
                        mBlockEnd = newpos;
                     }
                     else if ( newpos == mBlockStart )
                     {
                        // We are back at the start, so no more selection.
                        mBlockEnd = mBlockStart = 0;
                     }
                     else
                     {
                        // Only other option, we just backtracked PAST
                        // our original start block.
                        // So the new position becomes the start block
                        // and the old start block becomes the end block.
                        mBlockEnd = mBlockStart;
                        mBlockStart = newpos;
                     }
                  }
               }
                              
               mCursorPos = newpos;

               return true;
            }

            case KEY_RIGHT:
            {
               S32 newpos = findNextWord();               

               if ( mBlockStart == mBlockEnd )
               {
                  // There was not already a selection so start a new one.
                  mBlockStart = mCursorPos;
                  mBlockEnd = newpos;
               }
               else
               {
                  // There was a selection already...
                  // In this case the cursor MUST be at either the
                  // start or end of that selection.

                  if ( mCursorPos == mBlockEnd )
                  {
                     // We are at the end block and traveling right so
                     // just extend the end block farther right.                     
                     mBlockEnd = newpos;
                  }
                  else
                  {
                     // We are at the start block BUT traveling right
                     // back towards the end block...

                     if ( newpos < mBlockEnd )
                     {
                        // We haven't overpassed the existing end block
                        // so just trim back the start block.
                        mBlockStart = newpos;
                     }
                     else if ( newpos == mBlockEnd )
                     {
                        // We are back at the end, so no more selection.
                        mBlockEnd = mBlockStart = 0;
                     }
                     else
                     {
                        // Only other option, we just backtracked PAST
                        // our original end block.
                        // So the new position becomes the end block
                        // and the old end block becomes the start block.
                        mBlockStart = mBlockEnd;
                        mBlockEnd = newpos;
                     }
                  }
               }

               mCursorPos = newpos;

               return true;
            }
            
            default:
               break;
         }
      }

      // End support for word jump selection.


        switch ( event.keyCode )
        {
            case KEY_TAB:
               if ( mTabComplete )
               {
				  onTabComplete_callback("1");
                  return true;
               }
			   break; // We don't want to fall through if we don't handle the TAB here.

            case KEY_HOME:
               mBlockStart = 0;
               mBlockEnd = mCursorPos;
               mCursorPos = 0;
               return true;

            case KEY_END:
                mBlockStart = mCursorPos;
                mBlockEnd = stringLen;
                mCursorPos = stringLen;
                return true;

            case KEY_LEFT:
                if ((mCursorPos > 0) & (stringLen > 0))
                {
                    //if we already have a selected block
                    if (mCursorPos == mBlockEnd)
                    {
                        mCursorPos--;
                        mBlockEnd--;
                        if (mBlockEnd == mBlockStart)
                        {
                            mBlockStart = 0;
                            mBlockEnd = 0;
                        }
                    }
                    else {
                        mCursorPos--;
                        mBlockStart = mCursorPos;

                        if (mBlockEnd == 0)
                        {
                            mBlockEnd = mCursorPos + 1;
                        }
                    }
                }
                return true;

            case KEY_RIGHT:
                if (mCursorPos < stringLen)
                {
                    if ((mCursorPos == mBlockStart) && (mBlockEnd > 0))
                    {
                        mCursorPos++;
                        mBlockStart++;
                        if (mBlockStart == mBlockEnd)
                        {
                            mBlockStart = 0;
                            mBlockEnd = 0;
                        }
                    }
                    else
                    {
                        if (mBlockEnd == 0)
                        {
                            mBlockStart = mCursorPos;
                            mBlockEnd = mCursorPos;
                        }
                        mCursorPos++;
                        mBlockEnd++;
                    }
                }
                return true;

				case KEY_RETURN:
				case KEY_NUMPADENTER:
           
					return dealWithEnter(false);

            default:
               break;
        }
    }
   else if (event.modifier & SI_CTRL)
   {
      switch(event.keyCode)
      {
#if defined(TORQUE_OS_MAC)
         // Added UNIX emacs key bindings - just a little hack here...

         // Ctrl-B - move one character back
         case KEY_B:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_LEFT;
            return(onKeyDown(new_event));
         }

         // Ctrl-F - move one character forward
         case KEY_F:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_RIGHT;
            return(onKeyDown(new_event));
         }

         // Ctrl-A - move to the beginning of the line
         case KEY_A:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_HOME;
            return(onKeyDown(new_event));
         }

         // Ctrl-E - move to the end of the line
         case KEY_E:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_END;
            return(onKeyDown(new_event));
         }

         // Ctrl-P - move backward in history
         case KEY_P:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_UP;
            return(onKeyDown(new_event));
         }

         // Ctrl-N - move forward in history
         case KEY_N:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_DOWN;
            return(onKeyDown(new_event));
         }

         // Ctrl-D - delete under cursor
         case KEY_D:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_DELETE;
            return(onKeyDown(new_event));
         }

         case KEY_U:
         { 
            GuiEvent new_event;
            new_event.modifier = SI_CTRL;
            new_event.keyCode = KEY_DELETE;
            return(onKeyDown(new_event));
         }

         // End added UNIX emacs key bindings
#endif

         // Adding word jump navigation.

         case KEY_LEFT:
         {

            mCursorPos = findPrevWord();
            mBlockStart = 0;
            mBlockEnd = 0;
            return true;
         }

         case KEY_RIGHT:
         {
            mCursorPos = findNextWord();
            mBlockStart = 0;
            mBlockEnd = 0;
            return true;
         }         
         
#if !defined(TORQUE_OS_MAC)
         // Select all
         case KEY_A:
         {
            selectAllText();
            return true;
         }

         // windows style cut / copy / paste / undo keybinds
         case KEY_C:
         case KEY_X:
         {
            // copy, and cut the text if we hit ctrl-x
            onCopy( event.keyCode==KEY_X );
            return true;
         }
         case KEY_V:
         {
            onPaste();

            // Execute the console command!
            execConsoleCallback();
            return true;
         }

         case KEY_Z:
            if (! mDragHit)
            {
               onUndo();
               return true;
            }
#endif

         case KEY_DELETE:
         case KEY_BACKSPACE:
            //save the current state
            saveUndoState();

            //delete everything in the field
            mTextBuffer.set("");
            mCursorPos  = 0;
            mBlockStart = 0;
            mBlockEnd   = 0;

            execConsoleCallback();

            return true;
         default:
            break;
      }
   }
#if defined(TORQUE_OS_MAC)
   // mac style cut / copy / paste / undo keybinds
   else if (event.modifier & SI_ALT)
   {
      // Mac command key maps to alt in torque.

      // Added Mac cut/copy/paste/undo keys
      switch(event.keyCode)
      {
         // Select all
         case KEY_A:
         {
            selectAllText();
            return true;
         }
         case KEY_C:
         case KEY_X:
         {
            // copy, and cut the text if we hit cmd-x
            onCopy( event.keyCode==KEY_X );
            return true;
         }
         case KEY_V:
         {
            onPaste();

            // Execute the console command!
            execConsoleCallback();

            return true;
         }
            
         case KEY_Z:
            if (! mDragHit)
            {
               onUndo();
               return true;
            }
            
         default:
            break;
      }
   }
#endif
   else
   {
      switch(event.keyCode)
      {
         case KEY_ESCAPE:
            if( mEscapeCommand.isNotEmpty() )
            {
               evaluate( mEscapeCommand );
               return( true );
            }
            return( Parent::onKeyDown( event ) );

         case KEY_RETURN:
         case KEY_NUMPADENTER:
           
				return dealWithEnter(true);

         case KEY_UP:
         {
            if( mHistorySize > 0 )
            {
               if(mHistoryDirty)
               {
                  updateHistory(&mTextBuffer, false);
                  mHistoryDirty = false;
               }

               mHistoryIndex--;
               
               if(mHistoryIndex >= 0 && mHistoryIndex <= mHistoryLast)
                  setText(mHistoryBuf[mHistoryIndex]);
               else if(mHistoryIndex < 0)
                  mHistoryIndex = 0;
            }
               
            return true;
         }

         case KEY_DOWN:
         {
            if( mHistorySize > 0 )
            {
               if(mHistoryDirty)
               {
                  updateHistory(&mTextBuffer, false);
                  mHistoryDirty = false;
               }
               mHistoryIndex++;
               if(mHistoryIndex > mHistoryLast)
               {
                  mHistoryIndex = mHistoryLast + 1;
                  setText("");
               }
               else
                  setText(mHistoryBuf[mHistoryIndex]);
            }
            return true;
         }

         case KEY_LEFT:
            
            // If we have a selection put the cursor to the left side of it.
            if ( mBlockStart != mBlockEnd )
            {
               mCursorPos = mBlockStart;
               mBlockStart = mBlockEnd = 0;
            }
            else
            {
               mBlockStart = mBlockEnd = 0;
               mCursorPos = getMax( mCursorPos - 1, 0 );               
            }

            return true;

         case KEY_RIGHT:

            // If we have a selection put the cursor to the right side of it.            
            if ( mBlockStart != mBlockEnd )
            {
               mCursorPos = mBlockEnd;
               mBlockStart = mBlockEnd = 0;
            }
            else
            {
               mBlockStart = mBlockEnd = 0;
               mCursorPos = getMin( mCursorPos + 1, stringLen );               
            }

            return true;

         case KEY_BACKSPACE:
dealWithBackspace:
            //save the current state
            saveUndoState();

            if (mBlockEnd > 0)
            {
               mTextBuffer.cut(mBlockStart, mBlockEnd-mBlockStart);
               mCursorPos  = mBlockStart;
               mBlockStart = 0;
               mBlockEnd   = 0;
               mHistoryDirty = true;

               // Execute the console command!
               execConsoleCallback();

            }
            else if (mCursorPos > 0)
            {
               mTextBuffer.cut(mCursorPos-1, 1);
               mCursorPos--;
               mHistoryDirty = true;

               // Execute the console command!
               execConsoleCallback();
            }
            return true;

         case KEY_DELETE:
            //save the current state
            saveUndoState();

            if (mBlockEnd > 0)
            {
               mHistoryDirty = true;
               mTextBuffer.cut(mBlockStart, mBlockEnd-mBlockStart);

               mCursorPos = mBlockStart;
               mBlockStart = 0;
               mBlockEnd = 0;

               // Execute the console command!
               execConsoleCallback();
            }
            else if (mCursorPos < stringLen)
            {
               mHistoryDirty = true;
               mTextBuffer.cut(mCursorPos, 1);

               // Execute the console command!
               execConsoleCallback();
            }
            return true;

         case KEY_INSERT:
            mInsertOn = !mInsertOn;
            return true;

         case KEY_HOME:
            mBlockStart = 0;
            mBlockEnd   = 0;
            mCursorPos  = 0;
            return true;

         case KEY_END:
            mBlockStart = 0;
            mBlockEnd   = 0;
            mCursorPos  = stringLen;
            return true;
      
         default:
            break;

         }
   }

   switch ( event.keyCode )
   {
      case KEY_TAB:
         if ( mTabComplete )
         {
			onTabComplete_callback("0");
            return( true );
         }
      case KEY_UP:
      case KEY_DOWN:
      case KEY_ESCAPE:
         return Parent::onKeyDown( event );
      default:
         break;
   }
         
   // Handle character input events.

   if( mProfile->mFont->isValidChar( event.ascii ) )
   {
      handleCharInput( event.ascii );
      return true;
   }

   // Or eat it if that's appropriate.
   if( mSinkAllKeyEvents )
      return true;

   // Not handled - pass the event to it's parent.
   return Parent::onKeyDown( event );
}
示例#27
0
void PlaneReflector::updateReflection( const ReflectParams &params )
{
   PROFILE_SCOPE(PlaneReflector_updateReflection);   
   GFXDEBUGEVENT_SCOPE( PlaneReflector_updateReflection, ColorI::WHITE );

   mIsRendering = true;

   S32 texDim = mDesc->texSize;
   texDim = getMax( texDim, 32 );

   // Protect against the reflection texture being bigger
   // than the current game back buffer.
   texDim = getMin( texDim, params.viewportExtent.x );
   texDim = getMin( texDim, params.viewportExtent.y );

   bool texResize = ( texDim != mLastTexSize );  
   mLastTexSize = texDim;

   const Point2I texSize( texDim, texDim );

   if (  texResize || 
         reflectTex.isNull() ||
         reflectTex->getFormat() != REFLECTMGR->getReflectFormat() )
   {
      reflectTex = REFLECTMGR->allocRenderTarget( texSize );
      depthBuff = LightShadowMap::_getDepthTarget( texSize.x, texSize.y );
   }

   // store current matrices
   GFXTransformSaver saver;
   
   Point2I viewport(params.viewportExtent);
   if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
   {
      viewport.x *= 0.5f;
   }
   F32 aspectRatio = F32( viewport.x ) / F32( viewport.y );

   Frustum frustum;
   frustum.set(false, params.query->fov, aspectRatio, params.query->nearPlane, params.query->farPlane);

   // Manipulate the frustum for tiled screenshots
   const bool screenShotMode = gScreenShot && gScreenShot->isPending();
   if ( screenShotMode )
      gScreenShot->tileFrustum( frustum );

   GFX->setFrustum( frustum );
      
   // Store the last view info for scoring.
   mLastDir = params.query->cameraMatrix.getForwardVector();
   mLastPos = params.query->cameraMatrix.getPosition();

   setGFXMatrices( params.query->cameraMatrix );

   // Adjust the detail amount
   F32 detailAdjustBackup = TSShapeInstance::smDetailAdjust;
   TSShapeInstance::smDetailAdjust *= mDesc->detailAdjust;


   if(reflectTarget.isNull())
      reflectTarget = GFX->allocRenderToTextureTarget();
   reflectTarget->attachTexture( GFXTextureTarget::Color0, reflectTex );
   reflectTarget->attachTexture( GFXTextureTarget::DepthStencil, depthBuff );
   GFX->pushActiveRenderTarget();
   GFX->setActiveRenderTarget( reflectTarget );   

   U32 objTypeFlag = -1;
   SceneCameraState reflectCameraState = SceneCameraState::fromGFX();
   LIGHTMGR->registerGlobalLights( &reflectCameraState.getFrustum(), false );

   // Since we can sometime be rendering a reflection for 1 or 2 frames before
   // it gets updated do to the lag associated with getting the results from
   // a HOQ we can sometimes see into parts of the reflection texture that
   // have nothing but clear color ( eg. under the water ).
   // To make this look less crappy use the ambient color of the sun.
   //
   // In the future we may want to fix this instead by having the scatterSky
   // render a skirt or something in its lower half.
   //
   ColorF clearColor = gClientSceneGraph->getAmbientLightColor();
   GFX->clear( GFXClearZBuffer | GFXClearStencil | GFXClearTarget, clearColor, 1.0f, 0 );

   if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
   {
      // Store previous values
      RectI originalVP = GFX->getViewport();

      Point2F projOffset = GFX->getCurrentProjectionOffset();
      Point3F eyeOffset = GFX->getStereoEyeOffset();

      // Render left half of display
      RectI leftVP = originalVP;
      leftVP.extent.x *= 0.5;
      GFX->setViewport(leftVP);

      MatrixF leftWorldTrans(true);
      leftWorldTrans.setPosition(Point3F(eyeOffset.x, eyeOffset.y, eyeOffset.z));
      MatrixF leftWorld(params.query->cameraMatrix);
      leftWorld.mulL(leftWorldTrans);

      Frustum gfxFrustum = GFX->getFrustum();
      gfxFrustum.setProjectionOffset(Point2F(projOffset.x, projOffset.y));
      GFX->setFrustum(gfxFrustum);

      setGFXMatrices( leftWorld );

      SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
      SceneRenderState renderStateLeft( gClientSceneGraph, SPT_Reflect, cameraStateLeft );
      renderStateLeft.setSceneRenderStyle(SRS_SideBySide);
      renderStateLeft.setSceneRenderField(0);
      renderStateLeft.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
      renderStateLeft.setDiffuseCameraTransform( params.query->cameraMatrix );
      renderStateLeft.disableAdvancedLightingBins(true);

      gClientSceneGraph->renderSceneNoLights( &renderStateLeft, objTypeFlag );

      // Render right half of display
      RectI rightVP = originalVP;
      rightVP.extent.x *= 0.5;
      rightVP.point.x += rightVP.extent.x;
      GFX->setViewport(rightVP);

      MatrixF rightWorldTrans(true);
      rightWorldTrans.setPosition(Point3F(-eyeOffset.x, eyeOffset.y, eyeOffset.z));
      MatrixF rightWorld(params.query->cameraMatrix);
      rightWorld.mulL(rightWorldTrans);

      gfxFrustum = GFX->getFrustum();
      gfxFrustum.setProjectionOffset(Point2F(-projOffset.x, projOffset.y));
      GFX->setFrustum(gfxFrustum);

      setGFXMatrices( rightWorld );

      SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
      SceneRenderState renderStateRight( gClientSceneGraph, SPT_Reflect, cameraStateRight );
      renderStateRight.setSceneRenderStyle(SRS_SideBySide);
      renderStateRight.setSceneRenderField(1);
      renderStateRight.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
      renderStateRight.setDiffuseCameraTransform( params.query->cameraMatrix );
      renderStateRight.disableAdvancedLightingBins(true);

      gClientSceneGraph->renderSceneNoLights( &renderStateRight, objTypeFlag );

      // Restore previous values
      gfxFrustum.clearProjectionOffset();
      GFX->setFrustum(gfxFrustum);
      GFX->setViewport(originalVP);
   }
   else
   {
      SceneRenderState reflectRenderState
      (
         gClientSceneGraph,
         SPT_Reflect,
         SceneCameraState::fromGFX()
      );

      reflectRenderState.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
      reflectRenderState.setDiffuseCameraTransform( params.query->cameraMatrix );
      reflectRenderState.disableAdvancedLightingBins(true);

      gClientSceneGraph->renderSceneNoLights( &reflectRenderState, objTypeFlag );
   }

   LIGHTMGR->unregisterAllLights();

   // Clean up.
   reflectTarget->resolve();
   GFX->popActiveRenderTarget();

   // Restore detail adjust amount.
   TSShapeInstance::smDetailAdjust = detailAdjustBackup;

   mIsRendering = false;
}
示例#28
0
void updateChunkWriteStatsAndSplitIfNeeded(OperationContext* opCtx,
                                           ChunkManager* manager,
                                           Chunk* chunk,
                                           long dataWritten) {
    // Disable lastError tracking so that any errors, which occur during auto-split do not get
    // bubbled up on the client connection doing a write
    LastError::Disabled disableLastError(&LastError::get(opCtx->getClient()));

    const auto balancerConfig = Grid::get(opCtx)->getBalancerConfiguration();

    const bool minIsInf =
        (0 == manager->getShardKeyPattern().getKeyPattern().globalMin().woCompare(chunk->getMin()));
    const bool maxIsInf =
        (0 == manager->getShardKeyPattern().getKeyPattern().globalMax().woCompare(chunk->getMax()));

    const uint64_t chunkBytesWritten = chunk->addBytesWritten(dataWritten);

    const uint64_t desiredChunkSize =
        calculateDesiredChunkSize(balancerConfig->getMaxChunkSizeBytes(), manager->numChunks());

    if (!chunk->shouldSplit(desiredChunkSize, minIsInf, maxIsInf)) {
        return;
    }

    const NamespaceString nss(manager->getns());

    if (!manager->_autoSplitThrottle._splitTickets.tryAcquire()) {
        LOG(1) << "won't auto split because not enough tickets: " << nss;
        return;
    }

    TicketHolderReleaser releaser(&(manager->_autoSplitThrottle._splitTickets));

    const ChunkRange chunkRange(chunk->getMin(), chunk->getMax());

    try {
        // Ensure we have the most up-to-date balancer configuration
        uassertStatusOK(balancerConfig->refreshAndCheck(opCtx));

        if (!balancerConfig->getShouldAutoSplit()) {
            return;
        }

        LOG(1) << "about to initiate autosplit: " << redact(chunk->toString())
               << " dataWritten: " << chunkBytesWritten
               << " desiredChunkSize: " << desiredChunkSize;

        const uint64_t chunkSizeToUse = [&]() {
            const uint64_t estNumSplitPoints = chunkBytesWritten / desiredChunkSize * 2;

            if (estNumSplitPoints >= kTooManySplitPoints) {
                // The current desired chunk size will split the chunk into lots of small chunk and
                // at the worst case this can result into thousands of chunks. So check and see if a
                // bigger value can be used.
                return std::min(chunkBytesWritten, balancerConfig->getMaxChunkSizeBytes());
            } else {
                return desiredChunkSize;
            }
        }();

        auto splitPoints =
            uassertStatusOK(shardutil::selectChunkSplitPoints(opCtx,
                                                              chunk->getShardId(),
                                                              nss,
                                                              manager->getShardKeyPattern(),
                                                              chunkRange,
                                                              chunkSizeToUse,
                                                              boost::none));

        if (splitPoints.size() <= 1) {
            // No split points means there isn't enough data to split on; 1 split point means we
            // have
            // between half the chunk size to full chunk size so there is no need to split yet
            chunk->clearBytesWritten();
            return;
        }

        if (minIsInf || maxIsInf) {
            // We don't want to reset _dataWritten since we want to check the other side right away
        } else {
            // We're splitting, so should wait a bit
            chunk->clearBytesWritten();
        }

        // We assume that if the chunk being split is the first (or last) one on the collection,
        // this chunk is likely to see more insertions. Instead of splitting mid-chunk, we use the
        // very first (or last) key as a split point.
        //
        // This heuristic is skipped for "special" shard key patterns that are not likely to produce
        // monotonically increasing or decreasing values (e.g. hashed shard keys).
        if (KeyPattern::isOrderedKeyPattern(manager->getShardKeyPattern().toBSON())) {
            if (minIsInf) {
                BSONObj key = findExtremeKeyForShard(
                    opCtx, nss, chunk->getShardId(), manager->getShardKeyPattern(), true);
                if (!key.isEmpty()) {
                    splitPoints.front() = key.getOwned();
                }
            } else if (maxIsInf) {
                BSONObj key = findExtremeKeyForShard(
                    opCtx, nss, chunk->getShardId(), manager->getShardKeyPattern(), false);
                if (!key.isEmpty()) {
                    splitPoints.back() = key.getOwned();
                }
            }
        }

        const auto suggestedMigrateChunk =
            uassertStatusOK(shardutil::splitChunkAtMultiplePoints(opCtx,
                                                                  chunk->getShardId(),
                                                                  nss,
                                                                  manager->getShardKeyPattern(),
                                                                  manager->getVersion(),
                                                                  chunkRange,
                                                                  splitPoints));

        // Balance the resulting chunks if the option is enabled and if the shard suggested a chunk
        // to balance
        const bool shouldBalance = [&]() {
            if (!balancerConfig->shouldBalanceForAutoSplit())
                return false;

            auto collStatus =
                Grid::get(opCtx)->catalogClient()->getCollection(opCtx, manager->getns());
            if (!collStatus.isOK()) {
                log() << "Auto-split for " << nss << " failed to load collection metadata"
                      << causedBy(redact(collStatus.getStatus()));
                return false;
            }

            return collStatus.getValue().value.getAllowBalance();
        }();

        log() << "autosplitted " << nss << " chunk: " << redact(chunk->toString()) << " into "
              << (splitPoints.size() + 1) << " parts (desiredChunkSize " << desiredChunkSize << ")"
              << (suggestedMigrateChunk ? "" : (std::string) " (migrate suggested" +
                          (shouldBalance ? ")" : ", but no migrations allowed)"));

        // Reload the chunk manager after the split
        auto routingInfo = uassertStatusOK(
            Grid::get(opCtx)->catalogCache()->getShardedCollectionRoutingInfoWithRefresh(opCtx,
                                                                                         nss));

        if (!shouldBalance || !suggestedMigrateChunk) {
            return;
        }

        // Top chunk optimization - try to move the top chunk out of this shard to prevent the hot
        // spot from staying on a single shard. This is based on the assumption that succeeding
        // inserts will fall on the top chunk.

        // We need to use the latest chunk manager (after the split) in order to have the most
        // up-to-date view of the chunk we are about to move
        auto suggestedChunk = routingInfo.cm()->findIntersectingChunkWithSimpleCollation(
            suggestedMigrateChunk->getMin());

        ChunkType chunkToMove;
        chunkToMove.setNS(nss.ns());
        chunkToMove.setShard(suggestedChunk->getShardId());
        chunkToMove.setMin(suggestedChunk->getMin());
        chunkToMove.setMax(suggestedChunk->getMax());
        chunkToMove.setVersion(suggestedChunk->getLastmod());

        uassertStatusOK(configsvr_client::rebalanceChunk(opCtx, chunkToMove));

        // Ensure the collection gets reloaded because of the move
        Grid::get(opCtx)->catalogCache()->invalidateShardedCollection(nss);
    } catch (const DBException& ex) {
        chunk->clearBytesWritten();

        if (ErrorCodes::isStaleShardingError(ErrorCodes::Error(ex.getCode()))) {
            log() << "Unable to auto-split chunk " << redact(chunkRange.toString()) << causedBy(ex)
                  << ", going to invalidate routing table entry for " << nss;
            Grid::get(opCtx)->catalogCache()->invalidateShardedCollection(nss);
        }
    }
}
示例#29
0
/// Called by OpenGL device to active this state block.
/// @param oldState  The current state, used to make sure we don't set redundant states on the device.  Pass NULL to reset all states.
void GFXGLStateBlock::activate(const GFXGLStateBlock* oldState)
{
   // Big scary warning copied from Apple docs 
   // http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_performance/chapter_13_section_2.html#//apple_ref/doc/uid/TP40001987-CH213-SW12
   // Don't set a state that's already set. Once a feature is enabled, it does not need to be enabled again.
   // Calling an enable function more than once does nothing except waste time because OpenGL does not check 
   // the state of a feature when you call glEnable or glDisable. For instance, if you call glEnable(GL_LIGHTING) 
   // more than once, OpenGL does not check to see if the lighting state is already enabled. It simply updates 
   // the state value even if that value is identical to the current value.

#define STATE_CHANGE(state) (!oldState || oldState->mDesc.state != mDesc.state)
#define TOGGLE_STATE(state, enum) if(mDesc.state) glEnable(enum); else glDisable(enum)
#define CHECK_TOGGLE_STATE(state, enum) if(!oldState || oldState->mDesc.state != mDesc.state) if(mDesc.state) glEnable(enum); else glDisable(enum)

   // Blending
   CHECK_TOGGLE_STATE(blendEnable, GL_BLEND);
   if(STATE_CHANGE(blendSrc) || STATE_CHANGE(blendDest))
      glBlendFunc(GFXGLBlend[mDesc.blendSrc], GFXGLBlend[mDesc.blendDest]);
   if(STATE_CHANGE(blendOp))
      glBlendEquation(GFXGLBlendOp[mDesc.blendOp]);

   // Color write masks
   if(STATE_CHANGE(colorWriteRed) || STATE_CHANGE(colorWriteBlue) || STATE_CHANGE(colorWriteGreen) || STATE_CHANGE(colorWriteAlpha))
      glColorMask(mDesc.colorWriteRed, mDesc.colorWriteBlue, mDesc.colorWriteGreen, mDesc.colorWriteAlpha);
   
   // Culling
   if(STATE_CHANGE(cullMode))
   {
      TOGGLE_STATE(cullMode, GL_CULL_FACE);
      glCullFace(GFXGLCullMode[mDesc.cullMode]);
   }

   // Depth
   CHECK_TOGGLE_STATE(zEnable, GL_DEPTH_TEST);
   
   if(STATE_CHANGE(zFunc))
      glDepthFunc(GFXGLCmpFunc[mDesc.zFunc]);
   
   if(STATE_CHANGE(zBias))
   {
      if (mDesc.zBias == 0)
      {
         glDisable(GL_POLYGON_OFFSET_FILL);
      } else {
         F32 bias = mDesc.zBias * 10000.0f;
         glEnable(GL_POLYGON_OFFSET_FILL);
         glPolygonOffset(bias, bias);
      } 
   }
   
   if(STATE_CHANGE(zWriteEnable))
      glDepthMask(mDesc.zWriteEnable);

   // Stencil
   CHECK_TOGGLE_STATE(stencilEnable, GL_STENCIL_TEST);
   if(STATE_CHANGE(stencilFunc) || STATE_CHANGE(stencilRef) || STATE_CHANGE(stencilMask))
      glStencilFunc(GFXGLCmpFunc[mDesc.stencilFunc], mDesc.stencilRef, mDesc.stencilMask);
   if(STATE_CHANGE(stencilFailOp) || STATE_CHANGE(stencilZFailOp) || STATE_CHANGE(stencilPassOp))
      glStencilOp(GFXGLStencilOp[mDesc.stencilFailOp], GFXGLStencilOp[mDesc.stencilZFailOp], GFXGLStencilOp[mDesc.stencilPassOp]);
   if(STATE_CHANGE(stencilWriteMask))
      glStencilMask(mDesc.stencilWriteMask);
   

   if(STATE_CHANGE(fillMode))
      glPolygonMode(GL_FRONT_AND_BACK, GFXGLFillMode[mDesc.fillMode]);

#undef CHECK_STATE
#undef TOGGLE_STATE
#undef CHECK_TOGGLE_STATE

   //sampler objects
   if( gglHasExtension(ARB_sampler_objects) )
   {
      for (U32 i = 0; i < getMin(getOwningDevice()->getNumSamplers(), (U32) TEXTURE_STAGE_COUNT); i++)
      {
         if(!oldState || oldState->mSamplerObjects[i] != mSamplerObjects[i])
		      glBindSampler(i, mSamplerObjects[i] );
      }
   }	  

   // TODO: states added for detail blend   
}
void TerrainFile::_loadLegacy(  FileStream &stream )
{
   // Some legacy constants.
   enum 
   {
      MaterialGroups = 8,
      BlockSquareWidth = 256,
   };

   const U32 sampleCount = BlockSquareWidth * BlockSquareWidth;
   mSize = BlockSquareWidth;

   // Load the heightmap.
   mHeightMap.setSize( sampleCount );
   for ( U32 i=0; i < mHeightMap.size(); i++ )
      stream.read( &mHeightMap[i] );

   // Prior to version 7 we stored this weird material struct.
   const U32 MATERIAL_GROUP_MASK = 0x7;
   struct Material 
   {
      enum Flags 
      {
         Plain          = 0,
         Rotate         = 1,
         FlipX          = 2,
         FlipXRotate    = 3,
         FlipY          = 4,
         FlipYRotate    = 5,
         FlipXY         = 6,
         FlipXYRotate   = 7,
         RotateMask     = 7,
         Empty          = 8,
         Modified       = BIT(7),

         // must not clobber TerrainFile::MATERIAL_GROUP_MASK bits!
         PersistMask       = BIT(7)
      };

      U8 flags;
      U8 index;
   };

   // Temp locals for loading before we convert to the new
   // version 7+ format.
   U8 baseMaterialMap[sampleCount] = { 0 };
   U8 *materialAlphaMap[MaterialGroups] = { 0 };
   Material materialMap[BlockSquareWidth * BlockSquareWidth];

   // read the material group map and flags...
   dMemset(materialMap, 0, sizeof(materialMap));

   AssertFatal(!(Material::PersistMask & MATERIAL_GROUP_MASK),
      "Doh! We have flag clobberage...");

   for (S32 j=0; j < sampleCount; j++)
   {
      U8 val;
      stream.read(&val);

      //
      baseMaterialMap[j] = val & MATERIAL_GROUP_MASK;
      materialMap[j].flags = val & Material::PersistMask;
   }

   // Load the material names.
   Vector<String> materials;
   for ( U32 i=0; i < MaterialGroups; i++ )
   {
      String matName;
      stream.read( &matName );
      if ( matName.isEmpty() )
         continue;

      if ( mFileVersion > 3 && mFileVersion < 6 )
      {
         // Between version 3 and 5 we store the texture file names 
         // relative to the terrain file.  We restore the full path
         // here so that we can create a TerrainMaterial from it.
         materials.push_back( Torque::Path::CompressPath( mFilePath.getRoot() + mFilePath.getPath() + '/' + matName ) );
      }
      else
         materials.push_back( matName );
   }

   if ( mFileVersion <= 3 )
   {
      GFXTexHandle terrainMat;
      Torque::Path matRelPath;

      // Try to automatically fix up our material file names
      for (U32 i = 0; i < materials.size(); i++)
      {
         if ( materials[i].isEmpty() )
            continue;
            
         terrainMat.set( materials[i], &GFXDefaultPersistentProfile, avar( "%s() - (line %d)", __FUNCTION__, __LINE__ ) );
         if ( terrainMat )
            continue;

         matRelPath = materials[i];

         String path = matRelPath.getPath();

         String::SizeType n = path.find( '/', 0, String::NoCase );
         if ( n != String::NPos )
         {
            matRelPath.setPath( String(Con::getVariable( "$defaultGame" )) + path.substr( n, path.length() - n ) );

            terrainMat.set( matRelPath, &GFXDefaultPersistentProfile, avar( "%s() - (line %d)", __FUNCTION__, __LINE__ ) );
            if ( terrainMat )
            {
               materials[i] = matRelPath.getFullPath();
               mNeedsResaving = true;
            }
         }
         
      } // for (U32 i = 0; i < TerrainBlock::MaterialGroups; i++)
      
   } // if ( mFileVersion <= 3 )

   if ( mFileVersion == 1 )
   {
      for( S32 j = 0; j < sampleCount; j++ )
      {
         if ( materialAlphaMap[baseMaterialMap[j]] == NULL )
         {
            materialAlphaMap[baseMaterialMap[j]] = new U8[sampleCount];
            dMemset(materialAlphaMap[baseMaterialMap[j]], 0, sampleCount);
         }

         materialAlphaMap[baseMaterialMap[j]][j] = 255;
      }
   }
   else
   {
      for( S32 k=0; k < materials.size(); k++ )
      {
         AssertFatal(materialAlphaMap[k] == NULL, "Bad assumption.  There should be no alpha map at this point...");
         materialAlphaMap[k] = new U8[sampleCount];
         stream.read(sampleCount, materialAlphaMap[k]);
      }
   }

   // Throw away the old texture and heightfield scripts.
   if ( mFileVersion >= 3 )
   {
      U32 len;
      stream.read(&len);
      char *textureScript = (char *)dMalloc(len + 1);
      stream.read(len, textureScript);
      dFree( textureScript );

      stream.read(&len);
      char *heightfieldScript = (char *)dMalloc(len + 1);
      stream.read(len, heightfieldScript);
      dFree( heightfieldScript );
   }

   // Load and throw away the old edge terrain paths.
   if ( mFileVersion >= 5 )
   {
      stream.readSTString(true);
      stream.readSTString(true);
   }

   U32 layerCount = materials.size() - 1;

   // Ok... time to convert all this mess to the layer index map!
   for ( U32 i=0; i < sampleCount; i++ )
   {
      // Find the greatest layer.
      U32 layer = 0;
      U32 lastValue = 0;
      for ( U32 k=0; k < MaterialGroups; k++ )
      {
         if ( materialAlphaMap[k] && materialAlphaMap[k][i] > lastValue )
         {
            layer = k;
            lastValue = materialAlphaMap[k][i];
         }
      }

      // Set the layer index.   
      mLayerMap[i] = getMin( layer, layerCount );
   }
   
   // Cleanup.
   for ( U32 i=0; i < MaterialGroups; i++ )
      delete [] materialAlphaMap[i];

   // Force resaving on these old file versions.
   //mNeedsResaving = false;

   // Resolve the TerrainMaterial objects from the names.
   _resolveMaterials( materials );
}