4 using System.Collections.Generic;
6 using SiliconStudio.Core;
7 using SiliconStudio.Paradox.Effects.Data;
8 using SiliconStudio.Paradox.Graphics;
9 using SiliconStudio.Paradox.Graphics.Data;
11 namespace SiliconStudio.
Paradox.Extensions
15 public static List<MeshData>
SplitMeshes(List<MeshData> meshes,
bool can32bitIndex)
17 var finalList =
new List<MeshData>();
18 foreach (var mesh
in meshes)
20 var drawDatas = SplitMesh(mesh.Draw, can32bitIndex);
21 if (drawDatas.Count <= 1)
27 foreach (var draw
in drawDatas)
31 Material = mesh.Material,
32 Parameters = mesh.Parameters,
35 NodeIndex = mesh.NodeIndex,
36 Skinning = mesh.Skinning,
38 finalList.Add(newMeshData);
55 return new List<MeshDrawData> { meshDrawData };
58 return new List<MeshDrawData> { meshDrawData };
60 var verticesCount = meshDrawData.VertexBuffers[0].Count;
61 if (verticesCount <= ushort.MaxValue)
63 meshDrawData.CompactIndexBuffer();
64 return new List<MeshDrawData> { meshDrawData };
70 return new List<MeshDrawData> { meshDrawData };
74 return new List<MeshDrawData> { meshDrawData };
77 var finalList =
new List<MeshDrawData>();
80 var indicesUint = (uint*)indicesByte;
82 var splitInfos =
new List<SplitInformation>();
83 var currentSplit =
new SplitInformation();
84 currentSplit.StartTriangleIndex = 0;
85 var currentIndexUintPtr = indicesUint;
86 for (
int triangleIndex = 0; triangleIndex < meshDrawData.IndexBuffer.Count / 3; ++triangleIndex)
88 var verticesToAdd = 0;
89 var index0 = *currentIndexUintPtr++;
90 var index1 = *currentIndexUintPtr++;
91 var index2 = *currentIndexUintPtr++;
92 if (!currentSplit.UsedIndices.Contains(index0)) ++verticesToAdd;
93 if (!currentSplit.UsedIndices.Contains(index1)) ++verticesToAdd;
94 if (!currentSplit.UsedIndices.Contains(index2)) ++verticesToAdd;
96 if (currentSplit.UsedIndices.Count + verticesToAdd > 65535)
98 splitInfos.Add(currentSplit);
99 currentSplit =
new SplitInformation();
100 currentSplit.StartTriangleIndex = triangleIndex;
102 AddTriangle(currentSplit, index0, index1, index2, triangleIndex);
105 if (currentSplit.UsedIndices.Count > 0)
106 splitInfos.Add(currentSplit);
108 foreach (var splitInfo
in splitInfos)
110 var triangleCount = splitInfo.LastTriangleIndex - splitInfo.StartTriangleIndex + 1;
114 DrawCount = 3 * triangleCount,
119 for (
int vbIndex = 0; vbIndex < meshDrawData.VertexBuffers.Length; ++ vbIndex)
121 var stride = meshDrawData.VertexBuffers[vbIndex].Stride;
123 stride = meshDrawData.VertexBuffers[vbIndex].Declaration.VertexStride;
124 var newVertexBuffer =
new byte[splitInfo.UsedIndices.Count * stride];
126 fixed (byte* vertexBufferPtr = &meshDrawData.
VertexBuffers[vbIndex].
Buffer.Value.Content[0])
127 fixed (byte* newVertexBufferPtr = &newVertexBuffer[vbIndex])
130 foreach (var index
in splitInfo.UsedIndices)
131 Utilities.CopyMemory((IntPtr)(newVertexBufferPtr + stride * splitInfo.IndexRemapping[index]), (IntPtr)(vertexBufferPtr + stride * index), stride);
137 Count = splitInfo.UsedIndices.Count,
139 Declaration = meshDrawData.VertexBuffers[vbIndex].Declaration,
145 var newIndexBuffer =
new byte[
sizeof(ushort) * 3 * triangleCount];
146 fixed (byte* newIndexBufferPtr = &newIndexBuffer[0])
148 var newIndexBufferUshortPtr = (ushort*)newIndexBufferPtr;
149 var currentIndexPtr = &indicesUint[3 * splitInfo.StartTriangleIndex];
150 for (
int triangleIndex = 0; triangleIndex < triangleCount; ++triangleIndex)
152 var index0 = *currentIndexPtr++;
153 var index1 = *currentIndexPtr++;
154 var index2 = *currentIndexPtr++;
156 var newIndex0 = splitInfo.IndexRemapping[index0];
157 var newIndex1 = splitInfo.IndexRemapping[index1];
158 var newIndex2 = splitInfo.IndexRemapping[index2];
160 *newIndexBufferUshortPtr++ = newIndex0;
161 *newIndexBufferUshortPtr++ = newIndex1;
162 *newIndexBufferUshortPtr++ = newIndex2;
169 Count = triangleCount * 3,
174 finalList.Add(newMeshDrawData);
188 private static void AddTriangle(SplitInformation currentSplit, uint index0, uint index1, uint index2,
int triangleIndex)
190 if (currentSplit.UsedIndices.Add(index0)) currentSplit.IndexRemapping.Add(index0, (ushort)(currentSplit.UsedIndices.Count - 1));
191 if (currentSplit.UsedIndices.Add(index1)) currentSplit.IndexRemapping.Add(index1, (ushort)(currentSplit.UsedIndices.Count - 1));
192 if (currentSplit.UsedIndices.Add(index2)) currentSplit.IndexRemapping.Add(index2, (ushort)(currentSplit.UsedIndices.Count - 1));
193 currentSplit.LastTriangleIndex = triangleIndex;
196 private class SplitInformation
198 public readonly Dictionary<uint, ushort> IndexRemapping;
200 public readonly HashSet<uint> UsedIndices;
202 public int StartTriangleIndex;
204 public int LastTriangleIndex;
206 public SplitInformation()
208 IndexRemapping =
new Dictionary<uint, ushort>();
209 UsedIndices =
new HashSet<uint>();
static unsafe List< MeshDrawData > SplitMesh(MeshDrawData meshDrawData, bool can32bitIndex)
Split the mesh if it has strictly more than 65535 vertices (max index = 65534) on a plaftorm that doe...
static List< MeshData > SplitMeshes(List< MeshData > meshes, bool can32bitIndex)
SiliconStudio.Paradox.Graphics.Data.VertexBufferBindingData[] VertexBuffers
Data field for SiliconStudio.Paradox.Effects.MeshDraw.VertexBuffers.
SiliconStudio.Paradox.Graphics.PrimitiveType PrimitiveType
Data field for SiliconStudio.Paradox.Effects.MeshDraw.PrimitiveType.
SiliconStudio.Paradox.Graphics.Data.IndexBufferBindingData IndexBuffer
Data field for SiliconStudio.Paradox.Effects.MeshDraw.IndexBuffer.
SiliconStudio.Core.Serialization.ContentReference< SiliconStudio.Paradox.Graphics.Data.BufferData > Buffer
Data field for SiliconStudio.Paradox.Graphics.VertexBufferBinding.Buffer.
All-in-One Buffer class linked SharpDX.Direct3D11.Buffer.
Data type for SiliconStudio.Paradox.Graphics.IndexBufferBinding.
SiliconStudio.Core.Serialization.ContentReference< SiliconStudio.Paradox.Graphics.Data.BufferData > Buffer
Data field for SiliconStudio.Paradox.Graphics.IndexBufferBinding.Buffer.
Data type for SiliconStudio.Paradox.Graphics.VertexBufferBinding.
Data type for SiliconStudio.Paradox.Effects.Mesh.
Data type for SiliconStudio.Paradox.Effects.MeshDraw.
PrimitiveType
Defines how vertex data is ordered.
System.Boolean Is32Bit
Data field for SiliconStudio.Paradox.Graphics.IndexBufferBinding.Is32Bit.
Content of a GPU buffer (vertex buffer, index buffer, etc...).