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; }