Example #1
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;
		}