The definition of the information each layer will contain in this terrain. All layers must contain the same structure of information, although the input textures can be different per layer instance.
示例#1
0
 /// <summary>
 /// Whether this generator can generate a material for a given declaration.
 ///	By default this only returns true if the declaration is equal to the
 ///	standard one returned from getLayerDeclaration, but if a subclass wants
 ///	to be flexible to generate materials for other declarations too, it
 ///	can specify here.
 /// </summary>
 /// <param name="decl"></param>
 /// <returns></returns>
 public virtual bool CanGenerateUsingDeclaration(TerrainLayerDeclaration decl)
 {
     return(decl == this.mLayerDecl);
 }
		/// <summary>
		/// Whether this generator can generate a material for a given declaration. 
		///	By default this only returns true if the declaration is equal to the 
		///	standard one returned from getLayerDeclaration, but if a subclass wants
		///	to be flexible to generate materials for other declarations too, it 
		///	can specify here. 
		/// </summary>
		/// <param name="decl"></param>
		/// <returns></returns>
		public virtual bool CanGenerateUsingDeclaration( TerrainLayerDeclaration decl )
		{
			return decl == this.mLayerDecl;
		}
示例#3
0
		protected void CheckDeclaration()
		{
			if ( this.mMaterialGenerator == null )
			{
				this.mMaterialGenerator = TerrainGlobalOptions.DefaultMaterialGenerator;
			}

			if ( this.mLayerDecl.Elements == null || this.mLayerDecl.Elements.Count == 0 )
			{
				//default the declaration
				this.mLayerDecl = this.mMaterialGenerator.LayerDeclaration;
			}
		}
示例#4
0
		public bool Prepare( ImportData importData )
		{
			FreeTemporaryResources();
			FreeCPUResources();

			CopyGlobalOptions();

			//validate
			if (
				!( Bitwise.IsPow2( importData.TerrainSize - 1 ) && Bitwise.IsPow2( importData.MinBatchSize - 1 ) &&
				   Bitwise.IsPow2( importData.MaxBatchSize - 1 ) ) )
			{
				throw new AxiomException( "terrainSize, minBatchSize and maxBatchSize must all be n^2 + 1. Terrain.Prepare" );
			}

			if ( importData.MinBatchSize > importData.MaxBatchSize )
			{
				throw new AxiomException( "MinBatchSize must be less then or equal to MaxBatchSize. Terrain.Prepare" );
			}

			if ( importData.MaxBatchSize > TERRAIN_MAX_BATCH_SIZE )
			{
				throw new AxiomException( "MaxBatchSize must be not larger then {0} . Terrain.Prepare", TERRAIN_MAX_BATCH_SIZE );
			}

			Alignment = importData.TerrainAlign;
			this.mSize = importData.TerrainSize;
			this.mWorldSize = importData.WorldSize;
			this.mLayerDecl = importData.LayerDeclaration;
			CheckDeclaration();
			this.mLayers = importData.LayerList;
			CheckLayers( false );
			DeriveUVMultipliers();
			this.mMaxBatchSize = importData.MaxBatchSize;
			this.mMinBatchSize = importData.MinBatchSize;
			this.mPos = importData.Pos;
			UpdateBaseScale();
			DetermineLodLevels();

			int numVertices = this.mSize*this.mSize;
			this.mHeightData = new float[numVertices];

			if ( importData.InputFloat != null )
			{
				if ( Utility.RealEqual( importData.InputBias, 0.0f ) && Utility.RealEqual( importData.InputScale, 1.0f ) )
				{
					//straigt copy
					this.mHeightData = new float[numVertices];
					Array.Copy( importData.InputFloat, this.mHeightData, this.mHeightData.Length );
				}
				else
				{
					// scale & bias, lets do it unsafe, should be faster :)
					var src = importData.InputFloat;
					for ( var i = 0; i < numVertices; ++i )
					{
						this.mHeightData[ i ] = ( src[ i ]*importData.InputScale ) + importData.InputBias;
					}
				}
			}
			else if ( importData.InputImage != null )
			{
				var img = importData.InputImage;
				if ( img.Width != this.mSize || img.Height != this.mSize )
				{
					img.Resize( this.mSize, this.mSize );
				}

				// convert image data to floats
				// Do this on a row-by-row basis, because we describe the terrain in
				// a bottom-up fashion (ie ascending world coords), while Image is top-down
				var pSrcBaseF = BufferBase.Wrap( img.Data );
				var pHeightDataF = BufferBase.Wrap( this.mHeightData, mHeightData.Length * sizeof(float) );
				for ( var i = 0; i < this.mSize; ++i )
				{
					var srcy = this.mSize - i - 1;
					using ( var pSrc = pSrcBaseF + srcy*img.RowSpan )
					{
						using ( var pDest = pHeightDataF + i*this.mSize*sizeof ( float ) )
						{
							PixelConverter.BulkPixelConversion( pSrc, img.Format, pDest, PixelFormat.FLOAT32_R, this.mSize );
						}
					}
				}

				pSrcBaseF.Dispose();
				pHeightDataF.Dispose();

				if ( !Utility.RealEqual( importData.InputBias, 0.0f ) || !Utility.RealEqual( importData.InputScale, 1.0f ) )
				{
					for ( int i = 0; i < numVertices; ++i )
					{
						this.mHeightData[ i ] = ( this.mHeightData[ i ]*importData.InputScale ) + importData.InputBias;
					}
				}
			}
			else
			{
				// start with flat terrain
				this.mHeightData = new float[this.mSize*this.mSize];
			}

			var deltaData = new float[numVertices];

			this.mHeightDataPtr = BufferBase.Wrap( this.mHeightData,mHeightData.Length * sizeof(float) );
			this.mDeltaDataPtr = BufferBase.Wrap( deltaData, deltaData.Length * sizeof(float) );

			var numLevel = (ushort)(int)( NumLodLevels - 1 );
			QuadTree = new TerrainQuadTreeNode( this, null, 0, 0, this.mSize, (ushort)( NumLodLevels - 1 ), 0, 0 );
			QuadTree.Prepare();

			//calculate entire terrain
			var rect = new Rectangle();
			rect.Top = 0;
			rect.Bottom = this.mSize;
			rect.Left = 0;
			rect.Right = this.mSize;
			CalculateHeightDeltas( rect );
			FinalizeHeightDeltas( rect, true );

			DistributeVertexData();

			// Imported data is treated as modified because it's not saved
			IsModified = true;
			IsHeightDataModified = true;

			return true;
		}
示例#5
0
		public static bool ReadLayerDeclaration( ref StreamSerializer stream, ref TerrainLayerDeclaration targetDecl )
		{
			if ( stream.ReadChunkBegin( TERRAINLAYERDECLARATION_CHUNK_ID, TERRAINLAYERDECLARATION_CHUNK_VERSION ) == null )
			{
				return false;
			}

			//  samplers
			byte numSamplers;
			stream.Read( out numSamplers );
			targetDecl.Samplers = new List<TerrainLayerSampler>( numSamplers );
			for ( var s = 0; s < numSamplers; ++s )
			{
				if ( stream.ReadChunkBegin( TERRAINLAYERSAMPLER_CHUNK_ID, TERRAINLAYERSAMPLER_CHUNK_VERSION ) == null )
				{
					return false;
				}

				var sampler = new TerrainLayerSampler();
				stream.Read( out sampler.Alias );
				byte pixFmt;
				stream.Read( out pixFmt );
				sampler.Format = (PixelFormat)pixFmt;
				stream.ReadChunkEnd( TERRAINLAYERSAMPLER_CHUNK_ID );
				targetDecl.Samplers.Add( sampler );
			}

			//  elements
			byte numElems;
			stream.Read( out numElems );
			targetDecl.Elements = new List<TerrainLayerSamplerElement>( numElems );
			for ( var e = 0; e < numElems; ++e )
			{
				if ( stream.ReadChunkBegin( TERRAINLAYERSAMPLERELEMENT_CHUNK_ID, TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION ) == null )
				{
					return false;
				}

				var samplerElem = new TerrainLayerSamplerElement();

				stream.Read( out samplerElem.Source );
				byte sem;
				stream.Read( out sem );
				samplerElem.Semantic = (TerrainLayerSamplerSemantic)sem;
				stream.Read( out samplerElem.ElementStart );
				stream.Read( out samplerElem.ElementCount );
				stream.ReadChunkEnd( TERRAINLAYERSAMPLERELEMENT_CHUNK_ID );
				targetDecl.Elements.Add( samplerElem );
			}
			stream.ReadChunkEnd( TERRAINLAYERDECLARATION_CHUNK_ID );

			return true;
		}
示例#6
0
		public static void WriteLayerDeclaration( TerrainLayerDeclaration decl, ref StreamSerializer stream )
		{
			// Layer declaration
			stream.WriteChunkBegin( TERRAINLAYERDECLARATION_CHUNK_ID, TERRAINLAYERDECLARATION_CHUNK_VERSION );

			//  samplers
			var numSamplers = (byte)decl.Samplers.Count;
			stream.Write( numSamplers );
			foreach ( var sampler in decl.Samplers )
			{
				stream.WriteChunkBegin( TERRAINLAYERSAMPLER_CHUNK_ID, TERRAINLAYERSAMPLER_CHUNK_VERSION );
				stream.Write( sampler.Alias );
				var pixFmt = (byte)sampler.Format;
				stream.Write( pixFmt );
				stream.WriteChunkEnd( TERRAINLAYERSAMPLER_CHUNK_ID );
			}

			//  elements
			var numElems = (byte)decl.Elements.Count;
			stream.Write( numElems );
			foreach ( var elem in decl.Elements )
			{
				stream.WriteChunkBegin( TERRAINLAYERSAMPLERELEMENT_CHUNK_ID, TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION );
				stream.Write( elem.Source );
				var sem = (byte)elem.Semantic;
				stream.Write( sem );
				stream.Write( elem.ElementStart );
				stream.Write( elem.ElementCount );
				stream.WriteChunkEnd( TERRAINLAYERSAMPLERELEMENT_CHUNK_ID );
			}
			stream.WriteChunkEnd( TERRAINLAYERDECLARATION_CHUNK_ID );
		}