Prepare() public method

Prepare node and children (perform CPU tasks, may be background thread)
public Prepare ( ) : void
return void
Ejemplo n.º 1
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;
		}
Ejemplo n.º 2
0
		public bool Prepare( StreamSerializer stream )
		{
			FreeTemporaryResources();
			FreeCPUResources();

			CopyGlobalOptions();

			if ( stream.ReadChunkBegin( TERRAIN_CHUNK_ID, TERRAIN_CHUNK_VERSION ) == null )
			{
				return false;
			}

			byte align;
			stream.Read( out align );
			Alignment = (Alignment)align;
			stream.Read( out this.mSize );
			stream.Read( out this.mWorldSize );

			stream.Read( out this.mMaxBatchSize );
			stream.Read( out this.mMinBatchSize );
			stream.Read( out this.mPos );
			RootSceneNode.Position = this.mPos;
			UpdateBaseScale();
			DetermineLodLevels();

			int numVertices = this.mSize*this.mSize;
			this.mHeightData = new float[numVertices];
			stream.Read( out this.mHeightData );

			// layer declaration
			if ( !ReadLayerDeclaration( ref stream, ref this.mLayerDecl ) )
			{
				return false;
			}

			CheckDeclaration();

			// Layers
			if ( !ReadLayerInstanceList( ref stream, this.mLayerDecl.Elements.Count, ref this.mLayers ) )
			{
				return false;
			}

			DeriveUVMultipliers();

			// Packed layer blend data
			var numLayers = (byte)this.mLayers.Count;
			stream.Read( out this.mLayerBlendMapSize );
			this.mLayerBlendSizeActual = this.mLayerBlendMapSize; // for now, until we check
			//load packed CPU data
			var numBlendTex = GetBlendTextureCount( numLayers );
			for ( var i = 0; i < numBlendTex; ++i )
			{
				var fmt = GetBlendTextureFormat( (byte)i, numLayers );
				var channels = PixelUtil.GetNumElemBytes( fmt );
				var dataSz = channels*this.mLayerBlendMapSize*this.mLayerBlendMapSize;
				var data = new byte[dataSz];
				stream.Read( out data );
				this.mCpuBlendMapStorage.AddRange( data );
			}

			//derived data
			while ( !stream.IsEndOfChunk( TERRAIN_CHUNK_ID ) && stream.NextChunkId == TERRAINDERIVEDDATA_CHUNK_ID )
			{
				stream.ReadChunkBegin( TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION );
				//name
				var name = string.Empty;
				stream.Read( out name );
				ushort sz;
				stream.Read( out sz );
				if ( name == "normalmap" )
				{
					this.mNormalMapRequired = true;
					var data = new byte[sz*sz*3];
					stream.Read( out data );
					using ( var pDataF = BufferBase.Wrap( data ) )
					{
						this.mCpuTerrainNormalMap = new PixelBox( sz, sz, 1, PixelFormat.BYTE_RGB, pDataF );
					}
				}
				else if ( name == "colormap" )
				{
					IsGlobalColorMapEnabled = true;
					GlobalColorMapSize = sz;
					this.mCpuColorMapStorage = new byte[sz*sz*3];
					stream.Read( out this.mCpuColorMapStorage );
				}
				else if ( name == "lightmap" )
				{
					this.mLightMapRequired = true;
					LightMapSize = sz;
					this.mCpuLightmapStorage = new byte[sz*sz];
					stream.Read( out this.mCpuLightmapStorage );
				}
				else if ( name == "compositemap" )
				{
					this.mCompositeMapRequired = true;
					this.mCompositeMapSize = sz;
					this.mCpuCompositeMapStorage = new byte[sz*sz*4];
					stream.Read( out this.mCpuCompositeMapStorage );
				}

				stream.ReadChunkEnd( TERRAINDERIVEDDATA_CHUNK_ID );
			}

			//Load delta data
			var deltaData = new byte[ sizeof( float ) * numVertices ];
			stream.Read( out deltaData );
			this.mDeltaDataPtr = BufferBase.Wrap( deltaData );

			//Create and load quadtree
			QuadTree = new TerrainQuadTreeNode( this, null, 0, 0, this.mSize, (ushort)( NumLodLevels - 1 ), 0, 0 );
			QuadTree.Prepare();

			stream.ReadChunkEnd( TERRAIN_CHUNK_ID );

			DistributeVertexData();

			IsModified = false;
			IsHeightDataModified = false;

			return true;
		}