Clone() public méthode

Clones this vertex data, potentially including replicating any vertex buffers.
public Clone ( ) : VertexData
Résultat VertexData
        public GeometryBucket(MaterialBucket parent, string formatString, 
                              VertexData vData, IndexData iData)
        {
            // Clone the structure from the example
            this.parent = parent;
            this.formatString = formatString;
            vertexData = vData.Clone(false);
            indexData = iData.Clone(false);
            vertexData.vertexCount = 0;
            vertexData.vertexStart = 0;
            indexData.indexCount = 0;
            indexData.indexStart = 0;
            indexType = indexData.indexBuffer.Type;
            queuedGeometry = new List<QueuedGeometry>();
            // Derive the max vertices
            if (indexType == IndexType.Size32)
                maxVertexIndex = int.MaxValue;
            else
                maxVertexIndex = ushort.MaxValue;

            // Check to see if we have blend indices / blend weights
            // remove them if so, they can try to blend non-existent bones!
            VertexElement blendIndices =
                vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.BlendIndices);
            VertexElement blendWeights =
                vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.BlendWeights);
            if (blendIndices != null && blendWeights != null) {
                Debug.Assert(blendIndices.Source == blendWeights.Source,
                             "Blend indices and weights should be in the same buffer");
                // Get the source
                ushort source = blendIndices.Source;
                Debug.Assert(blendIndices.Size + blendWeights.Size ==
                    vertexData.vertexBufferBinding.GetBuffer(source).VertexSize,
                    "Blend indices and blend buffers should have buffer to themselves!");
                // Unset the buffer
                vertexData.vertexBufferBinding.UnsetBinding(source);
                // Remove the elements
                vertexData.vertexDeclaration.RemoveElement(VertexElementSemantic.BlendIndices);
                vertexData.vertexDeclaration.RemoveElement(VertexElementSemantic.BlendWeights);
            }
        }
Exemple #2
0
		/// <summary>
		///		Internal method to clone vertex data definitions but to remove blend buffers.
		/// </summary>
		/// <param name="source">Vertex data to clone.</param>
		/// <returns>A cloned instance of 'source' without blending information.</returns>
		protected internal VertexData CloneVertexDataRemoveBlendInfo( VertexData source )
		{
			// Clone without copying data
			var ret = source.Clone( false );
			var blendIndexElem = source.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.BlendIndices );
			var blendWeightElem = source.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.BlendWeights );

			// Remove blend index
			if ( blendIndexElem != null )
			{
				// Remove buffer reference
				ret.vertexBufferBinding.UnsetBinding( blendIndexElem.Source );
			}

			if ( blendWeightElem != null && blendWeightElem.Source != blendIndexElem.Source )
			{
				// Remove buffer reference
				ret.vertexBufferBinding.UnsetBinding( blendWeightElem.Source );
			}
			// remove elements from declaration
			ret.vertexDeclaration.RemoveElement( VertexElementSemantic.BlendIndices );
			ret.vertexDeclaration.RemoveElement( VertexElementSemantic.BlendWeights );

			// copy reference to w-coord buffer
			if ( source.hardwareShadowVolWBuffer != null )
			{
				ret.hardwareShadowVolWBuffer = source.hardwareShadowVolWBuffer;
			}

			return ret;
		}
		/// <summary>
		///   Split some shared geometry into dedicated geometry.
		/// </summary>
		/// <param name="vd"> </param>
		/// <param name="id"> </param>
		/// <param name="targetGeomLink"> </param>
		public void SplitGeometry( VertexData vd, IndexData id, ref SubMeshLodGeometryLink targetGeomLink )
		{
			// Firstly we need to scan to see how many vertices are being used
			// and while we're at it, build the remap we can use later
			bool use32bitIndexes = id.indexBuffer.Type == IndexType.Size32;

			var indexRemap = new Dictionary<int, int>();

			if ( use32bitIndexes )
			{
				var p32 = id.indexBuffer.Lock( id.indexStart, id.indexCount*id.indexBuffer.IndexSize, BufferLocking.ReadOnly );
				BuildIndexRemap( p32, id.indexCount, ref indexRemap );
				id.indexBuffer.Unlock();
			}
			else
			{
				var p16 = id.indexBuffer.Lock( id.indexStart, id.indexCount*id.indexBuffer.IndexSize, BufferLocking.ReadOnly );
				BuildIndexRemap( p16, id.indexCount, ref indexRemap );
				id.indexBuffer.Unlock();
			}

			if ( indexRemap.Count == vd.vertexCount )
			{
				// ha, complete usage after all
				targetGeomLink.vertexData = vd;
				targetGeomLink.indexData = id;
				return;
			}

			// Create the new vertex data records
			targetGeomLink.vertexData = vd.Clone( false );
			// Convenience
			VertexData newvd = targetGeomLink.vertexData;
			//IndexData* newid = targetGeomLink->indexData;
			// Update the vertex count
			newvd.vertexCount = indexRemap.Count;

			int numvbufs = vd.vertexBufferBinding.BindingCount;

			// Copy buffers from old to new
			for ( int b = 0; b < numvbufs; ++b )
			{
				// Lock old buffer
				HardwareVertexBuffer oldBuf = vd.vertexBufferBinding.GetBuffer( (short)b );
				// Create new buffer
				HardwareVertexBuffer newBuf =
					HardwareBufferManager.Instance.CreateVertexBuffer(
						oldBuf.VertexDeclaration,
						indexRemap.Count,
						BufferUsage.Static );
				// rebind
				newvd.vertexBufferBinding.SetBinding( (short)b, newBuf );

				// Copy all the elements of the buffer across, by iterating over
				// the IndexRemap which describes how to move the old vertices
				// to the new ones. By nature of the map the remap is in order of
				// indexes in the old buffer, but note that we're not guaranteed to
				// address every vertex (which is kinda why we're here)
				var pSrcBase = oldBuf.Lock( BufferLocking.ReadOnly );
				var pDstBase = newBuf.Lock( BufferLocking.Discard );
				int vertexSize = oldBuf.VertexSize;
				// Buffers should be the same size
				Debug.Assert( vertexSize == newBuf.VertexSize );

				foreach ( var r in indexRemap )
				{
					Debug.Assert( r.Key < oldBuf.VertexCount );
					Debug.Assert( r.Value < newBuf.VertexCount );

					var pSrc = pSrcBase + r.Key*vertexSize;
					var pDst = pDstBase + r.Value*vertexSize;
					var pSrcPtr = pSrc;
					var pDstPtr = pDst;
					Memory.Copy( pDstPtr, pSrcPtr, vertexSize );
				}
				// unlock
				oldBuf.Unlock();
				newBuf.Unlock();
			}

			// Now create a new index buffer
			HardwareIndexBuffer ibuf = HardwareBufferManager.Instance.CreateIndexBuffer( id.indexBuffer.Type, id.indexCount,
			                                                                             BufferUsage.Static );

			if ( use32bitIndexes )
			{
				uint* pSrc32, pDst32;
				pSrc32 = (uint*)id.indexBuffer.Lock(
					id.indexStart, id.indexCount*id.indexBuffer.IndexSize, BufferLocking.ReadOnly );
				pDst32 = (uint*)ibuf.Lock( BufferLocking.Discard );
				RemapIndexes( pSrc32, pDst32, ref indexRemap, id.indexCount );
				id.indexBuffer.Unlock();
				ibuf.Unlock();
			}
			else
			{
				ushort* pSrc16, pDst16;
				pSrc16 = (ushort*)id.indexBuffer.Lock(
					id.indexStart, id.indexCount*id.indexBuffer.IndexSize, BufferLocking.ReadOnly );
				pDst16 = (ushort*)ibuf.Lock( BufferLocking.Discard );
				RemapIndexes( pSrc16, pDst16, ref indexRemap, id.indexCount );
				id.indexBuffer.Unlock();
				ibuf.Unlock();
			}

			targetGeomLink.indexData = new IndexData();
			targetGeomLink.indexData.indexStart = 0;
			targetGeomLink.indexData.indexCount = id.indexCount;
			targetGeomLink.indexData.indexBuffer = ibuf;

			// Store optimised geometry for deallocation later
			var optGeom = new OptimisedSubMeshGeometry();
			optGeom.indexData = targetGeomLink.indexData;
			optGeom.vertexData = targetGeomLink.vertexData;
			mOptimisedSubMeshGeometryList.Add( optGeom );
		}
			public GeometryBucket( MaterialBucket parent,
			                       String formatString, VertexData vData,
			                       IndexData iData )
				: base()
			{
				mParent = parent;
				mFormatString = formatString;
				mVertexData = null;
				mIndexData = null;
				mBatch = mParent.Parent.Parent.Parent;
				if ( mBatch.BaseSkeleton != null )
				{
					SetCustomParameter( 0, new Vector4( mBatch.BaseSkeleton.BoneCount, 0, 0, 0 ) );
				}

				mVertexData = vData.Clone( false );

				renderOperation.useIndices = true;
				renderOperation.indexData = new IndexData();

				renderOperation.indexData.indexCount = 0;
				renderOperation.indexData.indexStart = 0;
				renderOperation.vertexData = new VertexData();
				renderOperation.vertexData.vertexCount = 0;

				renderOperation.vertexData.vertexDeclaration = (VertexDeclaration)vData.vertexDeclaration.Clone();
				mIndexType = iData.indexBuffer.Type;
				// Derive the max vertices
				if ( mIndexType == IndexType.Size32 )
				{
					mMaxVertexIndex = 0xFFFFFFFF;
				}
				else
				{
					mMaxVertexIndex = 0xFFFF;
				}

				int offset = 0, tcOffset = 0;
				short texCoordOffset = 0;
				short texCoordSource = 0;
				for ( int i = 0; i < renderOperation.vertexData.vertexDeclaration.ElementCount; i++ )
				{
					if ( renderOperation.vertexData.vertexDeclaration.GetElement( i ).Semantic == VertexElementSemantic.TexCoords )
					{
						texCoordOffset++;
						texCoordSource = renderOperation.vertexData.vertexDeclaration.GetElement( i ).Source;
						tcOffset = renderOperation.vertexData.vertexDeclaration.GetElement( i ).Offset + VertexElement.GetTypeSize(
							renderOperation.vertexData.vertexDeclaration.GetElement( i ).Type );
					}
					offset += VertexElement.GetTypeSize( renderOperation.vertexData.vertexDeclaration.GetElement( i ).Type );
				}

				renderOperation.vertexData.vertexDeclaration.AddElement( texCoordSource, tcOffset, VertexElementType.Float1,
				                                                         VertexElementSemantic.TexCoords, texCoordOffset );

				mTexCoordIndex = texCoordOffset;
			}
		protected void SplitGeometry( VertexData vd, IndexData id, SubMeshLodGeometryLink targetGeomLink )
		{
#if !AXIOM_SAFE_ONLY
			unsafe
#endif
			{
				if ( this.logLevel <= 1 )
				{
					LogManager.Instance.Write( "StaticGeometry.SplitGeometry called" );
				}
				// Firstly we need to scan to see how many vertices are being used
				// and while we're at it, build the remap we can use later
				var use32bitIndexes = id.indexBuffer.Type == IndexType.Size32;
				var indexRemap = new Dictionary<int, int>();
				var src = id.indexBuffer.Lock( BufferLocking.ReadOnly );
				indexRemap.Clear();
				if ( use32bitIndexes )
				{
					var p32 = src.ToIntPointer();
					for ( var i = 0; i < id.indexCount; ++i )
					{
						indexRemap[ p32[ i ] ] = indexRemap.Count;
					}
				}
				else
				{
					var p16 = src.ToShortPointer();
					for ( var i = 0; i < id.indexCount; ++i )
					{
						indexRemap[ p16[ i ] ] = indexRemap.Count;
					}
				}
				id.indexBuffer.Unlock();
				if ( indexRemap.Count == vd.vertexCount )
				{
					// ha, complete usage after all
					targetGeomLink.vertexData = vd;
					targetGeomLink.indexData = id;
					return;
				}

				// Create the new vertex data records
				targetGeomLink.vertexData = vd.Clone( false );
				// Convenience
				var newvd = targetGeomLink.vertexData;
				//IndexData newid = targetGeomLink.IndexData;
				// Update the vertex count
				newvd.vertexCount = indexRemap.Count;

				var numvbufs = vd.vertexBufferBinding.BindingCount;
				// Copy buffers from old to new
				for ( short b = 0; b < numvbufs; ++b )
				{
					// Lock old buffer
					var oldBuf = vd.vertexBufferBinding.GetBuffer( b );
					// Create new buffer
					var newBuf = HardwareBufferManager.Instance.CreateVertexBuffer( oldBuf.VertexDeclaration, indexRemap.Count,
					                                                                BufferUsage.Static );
					// rebind
					newvd.vertexBufferBinding.SetBinding( b, newBuf );

					// Copy all the elements of the buffer across, by iterating over
					// the IndexRemap which describes how to move the old vertices
					// to the new ones. By nature of the map the remap is in order of
					// indexes in the old buffer, but note that we're not guaranteed to
					// address every vertex (which is kinda why we're here)
					var vdSrc = oldBuf.Lock( BufferLocking.ReadOnly );
					var pSrcBase = vdSrc;
					var vdDest = newBuf.Lock( BufferLocking.Discard );
					var pDstBase = vdDest;
					var vertexSize = oldBuf.VertexSize;
					// Buffers should be the same size
					Debug.Assert( vertexSize == newBuf.VertexSize );

					foreach ( var pair in indexRemap )
					{
						Debug.Assert( pair.Key < oldBuf.VertexCount );
						Debug.Assert( pair.Value < newBuf.VertexCount );

						var pSrc = ( pSrcBase + pair.Key*vertexSize ).ToBytePointer();
						var pDst = ( pDstBase + pair.Value*vertexSize ).ToBytePointer();
						for ( var i = 0; i < vertexSize; i++ )
						{
							pDst[ i ] = pSrc[ i ];
						}
					}
					// unlock
					oldBuf.Unlock();
					newBuf.Unlock();
				}

				// Now create a new index buffer
				var ibuf = HardwareBufferManager.Instance.CreateIndexBuffer( id.indexBuffer.Type, id.indexCount, BufferUsage.Static );

				var idSrc = id.indexBuffer.Lock( BufferLocking.ReadOnly );
				var idDest = ibuf.Lock( BufferLocking.Discard );
				if ( use32bitIndexes )
				{
					var pSrc32 = idSrc.ToIntPointer();
					var pDst32 = idDest.ToIntPointer();
					for ( var i = 0; i < id.indexCount; ++i )
					{
						pDst32[ i ] = indexRemap[ pSrc32[ i ] ];
					}
				}
				else
				{
					var pSrc16 = idSrc.ToUShortPointer();
					var pDst16 = idDest.ToUShortPointer();
					for ( var i = 0; i < id.indexCount; ++i )
					{
						pDst16[ i ] = (ushort)indexRemap[ pSrc16[ i ] ];
					}
				}
				id.indexBuffer.Unlock();
				ibuf.Unlock();

				targetGeomLink.indexData = new IndexData();
				targetGeomLink.indexData.indexStart = 0;
				targetGeomLink.indexData.indexCount = id.indexCount;
				targetGeomLink.indexData.indexBuffer = ibuf;

				// Store optimised geometry for deallocation later
				var optGeom = new OptimisedSubMeshGeometry();
				optGeom.indexData = targetGeomLink.indexData;
				optGeom.vertexData = targetGeomLink.vertexData;
				this.optimisedSubMeshGeometryList.Add( optGeom );
			}
		}
        protected unsafe void SplitGeometry(VertexData vd, IndexData id, SubMeshLodGeometryLink targetGeomLink)
        {
            log.Info("StaticGeometry.SplitGeometry called");
            // Firstly we need to scan to see how many vertices are being used
            // and while we're at it, build the remap we can use later
            bool use32bitIndexes = id.indexBuffer.Type == IndexType.Size32;
            Dictionary<int, int> indexRemap = new Dictionary<int, int>();
            IntPtr src = id.indexBuffer.Lock(BufferLocking.ReadOnly);
            indexRemap.Clear();
            if (use32bitIndexes) {
                int *p32 = (int *)src.ToPointer();
                for (int i = 0; i<id.indexCount; ++i)
                    indexRemap[*p32++] = indexRemap.Count;
            }
            else {
                short *p16 = (short *)src.ToPointer();
                for (int i = 0; i<id.indexCount; ++i)
                    indexRemap[*p16++] = indexRemap.Count;
            }
            id.indexBuffer.Unlock();
            if (indexRemap.Count == vd.vertexCount)
            {
                // ha, complete usage after all
                targetGeomLink.vertexData = vd;
                targetGeomLink.indexData = id;
                return;
            }

            // Create the new vertex data records
            targetGeomLink.vertexData = vd.Clone(false);
            // Convenience
            VertexData newvd = targetGeomLink.vertexData;
            //IndexData newid = targetGeomLink.IndexData;
            // Update the vertex count
            newvd.vertexCount = indexRemap.Count;

            int numvbufs = vd.vertexBufferBinding.BindingCount;
            // Copy buffers from old to new
            for (ushort b = 0; b < numvbufs; ++b)
            {
                // Lock old buffer
                HardwareVertexBuffer oldBuf = vd.vertexBufferBinding.GetBuffer(b);
                // Create new buffer
                HardwareVertexBuffer newBuf =
                    HardwareBufferManager.Instance.CreateVertexBuffer(oldBuf.VertexSize, indexRemap.Count, BufferUsage.Static);
                // rebind
                newvd.vertexBufferBinding.SetBinding(b, newBuf);

                // Copy all the elements of the buffer across, by iterating over
                // the IndexRemap which describes how to move the old vertices
                // to the new ones. By nature of the map the remap is in order of
                // indexes in the old buffer, but note that we're not guaranteed to
                // address every vertex (which is kinda why we're here)
                IntPtr vdSrc = oldBuf.Lock(BufferLocking.ReadOnly);
                byte* pSrcBase = (byte *)vdSrc.ToPointer();
                IntPtr vdDest = newBuf.Lock(BufferLocking.Discard);
                byte* pDstBase = (byte *)vdDest.ToPointer();
                int vertexSize = oldBuf.VertexSize;
                // Buffers should be the same size
                Debug.Assert (vertexSize == newBuf.VertexSize);

                foreach(KeyValuePair<int, int> pair in indexRemap) {
                    Debug.Assert(pair.Key < oldBuf.VertexCount);
                    Debug.Assert(pair.Value < newBuf.VertexCount);

                    byte* pSrc = pSrcBase + pair.Key * vertexSize;
                    byte* pDst = pDstBase + pair.Value * vertexSize;
                    for (int i=0; i<vertexSize; i++)
                        *pDst++ = *pSrc++;
                }
                // unlock
                oldBuf.Unlock();
                newBuf.Unlock();

            }

            // Now create a new index buffer
            HardwareIndexBuffer ibuf =
                HardwareBufferManager.Instance.CreateIndexBuffer(id.indexBuffer.Type, id.indexCount, BufferUsage.Static);

            IntPtr idSrc = id.indexBuffer.Lock(BufferLocking.ReadOnly);
            IntPtr idDest = ibuf.Lock(BufferLocking.Discard);
            if (use32bitIndexes) {
                int *pSrc32 = (int *)idSrc.ToPointer();
                int *pDst32 = (int *)idDest.ToPointer();
                for (int i=0; i<id.indexCount; ++i)
                    *pDst32++ = (int)indexRemap[*pSrc32++];
            }
            else {
                ushort *pSrc16 = (ushort *)idSrc.ToPointer();
                ushort *pDst16 = (ushort *)idDest.ToPointer();
                for (int i=0; i<id.indexCount; ++i)
                    *pDst16++ = (ushort)indexRemap[*pSrc16++];
            }
            id.indexBuffer.Unlock();
            ibuf.Unlock();

            targetGeomLink.indexData = new IndexData();
            targetGeomLink.indexData.indexStart = 0;
            targetGeomLink.indexData.indexCount = id.indexCount;
            targetGeomLink.indexData.indexBuffer = ibuf;

            // Store optimised geometry for deallocation later
            OptimisedSubMeshGeometry optGeom = new OptimisedSubMeshGeometry();
            optGeom.indexData = targetGeomLink.indexData;
            optGeom.vertexData = targetGeomLink.vertexData;
            optimisedSubMeshGeometryList.Add(optGeom);
        }