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(); }
U32 GFXGLDevice::getNumSamplers() const { return getMin((U32)TEXTURE_STAGE_COUNT,mPixelShaderVersion > 0.001f ? mMaxShaderTextures : mMaxFFTextures); }
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 ); }
// --------------------------------------------------------------------------- // 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; }
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; }
KeyType getMin() { return getMin(root); }
//----------------------------------------------------------------------------- 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; }
Cube Cube::boundingBox() { return Cube(getMin(),getMax(),getCenter()); }
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; } } }
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]); } }
int isMin(byte *g) { byte buf[W*H]; getMin(g,buf); return(compare(g,buf)==0); }//isMin
/** * 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; }
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); }
/// 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(); }
bool Chunk::contains( const BSONObj& obj ){ return _manager->getShardKey().compare( getMin() , obj ) <= 0 && _manager->getShardKey().compare( obj , getMax() ) < 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() ); }
//----------------------------------------------------------------------------- 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); }
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; } }
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); }
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"); } }
//------------------------------------------------------------------------ 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; }
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(); } } }
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); }
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 ); }
void PlaneReflector::updateReflection( const ReflectParams ¶ms ) { 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; }
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); } } }
/// 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 ); }