4 using System.Collections.Generic;
6 using SiliconStudio.Paradox.Effects.Data;
7 using SiliconStudio.Paradox.Graphics;
8 using SiliconStudio.Core;
9 using SiliconStudio.Core.Mathematics;
10 using SiliconStudio.Paradox.Graphics.Data;
12 namespace SiliconStudio.
Paradox.Extensions
24 throw new NotImplementedException();
26 var oldVertexBuffer = meshData.VertexBuffers[0];
27 var vertexStride = oldVertexBuffer.Declaration.VertexStride;
28 var indexMapping = GenerateIndexMapping(oldVertexBuffer);
29 var vertices = indexMapping.Vertices;
32 var vertexBufferData =
new byte[oldVertexBuffer.Declaration.VertexStride * indexMapping.Vertices.Length];
33 fixed (byte* oldVertexBufferDataStart = &oldVertexBuffer.Buffer.Value.Content[oldVertexBuffer.Offset])
34 fixed (byte* vertexBufferDataStart = &vertexBufferData[0])
36 var vertexBufferDataCurrent = vertexBufferDataStart;
37 for (
int i = 0; i < vertices.Length; ++i)
39 Utilities.CopyMemory((IntPtr)vertexBufferDataCurrent,
new IntPtr(&oldVertexBufferDataStart[vertexStride * vertices[i]]), vertexStride);
40 vertexBufferDataCurrent += vertexStride;
46 var indexBufferData =
new byte[indexMapping.Indices.Length * Utilities.SizeOf<
int>()];
47 fixed (
int* indexDataStart = &indexMapping.Indices[0])
48 fixed (byte* indexBufferDataStart = &indexBufferData[0])
50 Utilities.CopyMemory((IntPtr)indexBufferDataStart, (IntPtr)indexDataStart, indexBufferData.Length);
69 throw new NotImplementedException();
71 var vertexBufferBinding = meshData.VertexBuffers[0];
72 var vertexCount = vertexBufferBinding.Count;
80 var indexCount = meshData.IndexBuffer.Count;
81 var indexBufferData =
new byte[indexCount * Utilities.SizeOf<ushort>()];
82 fixed (byte* oldIndexBufferDataStart = &meshData.
IndexBuffer.
Buffer.Value.Content[0])
83 fixed (byte* indexBufferDataStart = &indexBufferData[0])
85 var oldIndexBufferDataPtr = (
int*)oldIndexBufferDataStart;
86 var indexBufferDataPtr = (ushort*)indexBufferDataStart;
88 for (
int i = 0; i < indexCount; ++i)
91 *indexBufferDataPtr++ = (ushort)*oldIndexBufferDataPtr++;
110 throw new NotImplementedException();
114 var indexBuffer = meshData.IndexBuffer;
116 var triangleCount = indexBuffer.Count / 3;
117 var newIndices =
new int[triangleCount * 12];
119 var positionMapping = GenerateIndexMapping(meshData.
VertexBuffers[0],
"POSITION");
120 var dominantEdges =
new Dictionary<EdgeKeyAEN, EdgeAEN>();
121 var dominantVertices =
new Dictionary<int, int>();
123 fixed (byte* indexBufferStart = &indexBuffer.Buffer.Value.Content[indexBuffer.Offset])
125 var oldIndices = (
int*)indexBufferStart;
126 var triangleIndices = stackalloc
int[3];
127 var positionIndices = stackalloc
int[3];
130 for (
int i = 0; i < triangleCount; ++i)
132 triangleIndices[0] = oldIndices[i * 3 + 0];
133 triangleIndices[1] = oldIndices[i * 3 + 1];
134 triangleIndices[2] = oldIndices[i * 3 + 2];
136 positionIndices[0] = positionMapping.Indices[triangleIndices[0]];
137 positionIndices[1] = positionMapping.Indices[triangleIndices[1]];
138 positionIndices[2] = positionMapping.Indices[triangleIndices[2]];
140 newIndices[i * 12 + 0] = triangleIndices[0];
141 newIndices[i * 12 + 1] = triangleIndices[1];
142 newIndices[i * 12 + 2] = triangleIndices[2];
143 newIndices[i * 12 + 3] = triangleIndices[0];
144 newIndices[i * 12 + 4] = triangleIndices[1];
145 newIndices[i * 12 + 5] = triangleIndices[1];
146 newIndices[i * 12 + 6] = triangleIndices[2];
147 newIndices[i * 12 + 7] = triangleIndices[2];
148 newIndices[i * 12 + 8] = triangleIndices[0];
149 newIndices[i * 12 + 9] = triangleIndices[0];
150 newIndices[i * 12 + 10] = triangleIndices[1];
151 newIndices[i * 12 + 11] = triangleIndices[2];
154 for (
int j = 0; j < 3; ++j)
156 dominantVertices[positionIndices[j]] = triangleIndices[j];
158 var edge =
new EdgeAEN(
159 triangleIndices[((j + 0) % 3)],
160 triangleIndices[((j + 1) % 3)],
161 positionIndices[((j + 0) % 3)],
162 positionIndices[((j + 1) % 3)]);
164 dominantEdges[
new EdgeKeyAEN(edge)] = edge;
166 edge = edge.Reverse();
167 dominantEdges[
new EdgeKeyAEN(edge)] = edge;
172 for (
int i = 0; i < triangleCount; ++i)
174 triangleIndices[0] = oldIndices[i * 3 + 0];
175 triangleIndices[1] = oldIndices[i * 3 + 1];
176 triangleIndices[2] = oldIndices[i * 3 + 2];
178 positionIndices[0] = positionMapping.Indices[triangleIndices[0]];
179 positionIndices[1] = positionMapping.Indices[triangleIndices[1]];
180 positionIndices[2] = positionMapping.Indices[triangleIndices[2]];
182 for (
int j = 0; j < 3; ++j)
186 if (dominantVertices.TryGetValue(positionIndices[j], out vertexKey))
188 newIndices[i * 12 + 9 + j] = vertexKey;
193 var edgeKey =
new EdgeKeyAEN(positionIndices[((j + 0) % 3)], positionIndices[((j + 1) % 3)]);
194 if (dominantEdges.TryGetValue(edgeKey, out edge))
196 newIndices[i * 12 + 3 + j * 2 + 0] = edge.Index0;
197 newIndices[i * 12 + 3 + j * 2 + 1] = edge.Index1;
204 var indexBufferData =
new byte[triangleCount * 12 * Utilities.SizeOf<
int>()];
205 fixed (
int* indexDataStart = &newIndices[0])
206 fixed (byte* indexBufferDataStart = &indexBufferData[0])
208 Utilities.CopyMemory((IntPtr)indexBufferDataStart, (IntPtr)indexDataStart, indexBufferData.Length);
212 meshData.DrawCount = triangleCount * 12;
213 meshData.PrimitiveType = PrimitiveType.PatchList.ControlPointCount(12);
216 private struct EdgeKeyAEN
218 public readonly
int PositionIndex0;
219 public readonly
int PositionIndex1;
221 public EdgeKeyAEN(
int positionIndex0,
int positionIndex1)
223 PositionIndex0 = positionIndex0;
224 PositionIndex1 = positionIndex1;
227 public EdgeKeyAEN(EdgeAEN edge)
228 : this(edge.PositionIndex0, edge.PositionIndex1)
232 public override int GetHashCode()
236 return (PositionIndex0 * 397) ^ PositionIndex1;
241 private struct EdgeAEN
243 public readonly
int Index0;
244 public readonly
int Index1;
245 public readonly
int PositionIndex0;
246 public readonly
int PositionIndex1;
248 public EdgeAEN(
int index0,
int index1,
int positionIndex0,
int positionIndex1)
252 PositionIndex0 = positionIndex0;
253 PositionIndex1 = positionIndex1;
256 public EdgeAEN Reverse()
258 return new EdgeAEN(Index1, Index0, PositionIndex1, PositionIndex0);
271 var bufferData = vertexBufferBinding.Buffer.Value.Content;
272 var vertexStride = vertexBufferBinding.Declaration.VertexStride;
273 var vertexCount = vertexBufferBinding.Count;
274 var activeBytes = stackalloc byte[vertexStride];
276 var vertexMapping =
new List<int>();
277 var indexMapping =
new int[vertexCount];
279 var mapping =
new Dictionary<VertexKey, int>(
new VertexKeyEqualityComparer(activeBytes, vertexStride));
283 for (
int i = 0; i < vertexBufferBinding.Declaration.VertexStride; ++i)
285 activeBytes[i] = (byte)(usages.Length == 0 ? 1 : 0);
288 foreach (var vertexElement
in vertexBufferBinding.Declaration.EnumerateWithOffsets())
290 if (usages.Contains(vertexElement.VertexElement.SemanticAsText))
292 for (
int i = 0; i < vertexElement.Size; ++i)
294 activeBytes[vertexElement.Offset + i] = 1;
300 fixed (byte* bufferPointerStart = &bufferData[vertexBufferBinding.Offset])
302 var bufferPointer = bufferPointerStart;
304 for (
int i = 0; i < vertexCount; ++i)
307 var vertexKey =
new VertexKey(bufferPointer, activeBytes, vertexStride);
311 if (!mapping.TryGetValue(vertexKey, out currentIndex))
313 currentIndex = vertexMapping.Count;
314 mapping.Add(vertexKey, currentIndex);
315 vertexMapping.Add(i);
319 indexMapping[i] = currentIndex;
321 bufferPointer += vertexStride;
325 return new IndexMappingResult { Vertices = vertexMapping.ToArray(), Indices = indexMapping };
334 internal unsafe
struct VertexKey
339 public VertexKey(byte* vertex, byte* activeBytes,
int vertexStride)
345 for (
int i = 0; i < vertexStride; ++i)
347 if (*activeBytes++ != 0)
348 Hash = (Hash * 31) ^ *vertex;
355 internal unsafe
class VertexKeyEqualityComparer : EqualityComparer<VertexKey>
357 private byte* activeBytes;
358 private int vertexStride;
360 public VertexKeyEqualityComparer(byte* activeBytes,
int vertexStride)
362 this.activeBytes = activeBytes;
363 this.vertexStride = vertexStride;
366 public override bool Equals(VertexKey x, VertexKey
y)
368 var vertex1 = x.Vertex;
369 var vertex2 = y.Vertex;
371 var currentActiveBytes = activeBytes;
373 for (
int i = 0; i < vertexStride; ++i)
375 if (*currentActiveBytes++ != 0)
377 if (*vertex1 != *vertex2)
388 public override int GetHashCode(VertexKey obj)
SiliconStudio.Paradox.Graphics.Data.VertexBufferBindingData[] VertexBuffers
Data field for SiliconStudio.Paradox.Effects.MeshDraw.VertexBuffers.
static unsafe void GenerateIndexBufferAEN(this MeshDrawData meshData)
Generates the index buffer with dominant edge and vertex informations. Each triangle gets its indices...
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ float size_t y
SiliconStudio.Paradox.Graphics.Data.IndexBufferBindingData IndexBuffer
Data field for SiliconStudio.Paradox.Effects.MeshDraw.IndexBuffer.
static unsafe bool CompactIndexBuffer(this MeshDrawData meshData)
Compacts the index buffer from 32 bits to 16 bits per index, if possible.
static unsafe void GenerateIndexBuffer(this MeshDrawData meshData)
Generates an index buffer for this mesh data.
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.
static unsafe IndexMappingResult GenerateIndexMapping(this VertexBufferBindingData vertexBufferBinding, params string[] usages)
Generates an index mapping with the specified vertex elements. If no vertex elements are specified...
Data type for SiliconStudio.Paradox.Effects.MeshDraw.
System.Boolean Is32Bit
Data field for SiliconStudio.Paradox.Graphics.IndexBufferBinding.Is32Bit.
Content of a GPU buffer (vertex buffer, index buffer, etc...).