6 using SiliconStudio.Paradox.Effects.Data;
7 using SiliconStudio.Paradox.Graphics;
8 using SiliconStudio.Core;
9 using SiliconStudio.Core.Mathematics;
10 using SiliconStudio.Core.Serialization;
11 using SiliconStudio.Core.Serialization.Serializers;
12 using SiliconStudio.Paradox.Graphics.Data;
14 namespace SiliconStudio.
Paradox.Extensions
28 if (!meshData.IsSimple())
29 throw new ArgumentException(
"meshData is not simple.");
33 throw new NotImplementedException();
35 var vertexBufferBinding = meshData.VertexBuffers[0];
36 var indexBufferBinding = meshData.IndexBuffer;
37 var indexData = indexBufferBinding != null ? indexBufferBinding.Buffer.Value.Content : null;
39 var oldVertexStride = vertexBufferBinding.Declaration.VertexStride;
40 var bufferData = vertexBufferBinding.Buffer.Value.Content;
43 var offsetMapping = vertexBufferBinding.Declaration
44 .EnumerateWithOffsets()
45 .ToDictionary(x => x.VertexElement.SemanticAsText, x => x.Offset);
47 var positionOffset = offsetMapping[
"POSITION"];
49 var normalOffset = offsetMapping[VertexElementUsage.Normal];
52 var vertexElements = vertexBufferBinding.Declaration.VertexElements.ToList();
55 vertexBufferBinding.Declaration =
new VertexDeclaration(vertexElements.ToArray());
56 var newVertexStride = vertexBufferBinding.Declaration.VertexStride;
59 offsetMapping = vertexBufferBinding.Declaration
60 .EnumerateWithOffsets()
61 .ToDictionary(x => x.VertexElement.SemanticAsText, x => x.Offset);
63 var tangentOffset = offsetMapping[VertexElementUsage.Tangent];
65 var newBufferData =
new byte[vertexBufferBinding.Count * newVertexStride];
67 var tangents =
new Vector3[vertexBufferBinding.Count];
68 var bitangents =
new Vector3[vertexBufferBinding.Count];
70 fixed (byte* indexBufferStart = indexData)
71 fixed (byte* oldBuffer = &bufferData[vertexBufferBinding.Offset])
72 fixed (byte* newBuffer = &newBufferData[0])
74 var indexBuffer32 = indexBufferBinding != null && indexBufferBinding.Is32Bit ? (
int*)indexBufferStart : null;
75 var indexBuffer16 = indexBufferBinding != null && !indexBufferBinding.Is32Bit ? (
short*)indexBufferStart : null;
77 var indexCount = indexBufferBinding != null ? indexBufferBinding.Count : vertexBufferBinding.Count;
79 for (
int i = 0; i < indexCount; i += 3)
86 if (indexBuffer32 != null)
88 index1 = indexBuffer32[index1];
89 index2 = indexBuffer32[index2];
90 index3 = indexBuffer32[index3];
92 else if (indexBuffer16 != null)
94 index1 = indexBuffer16[index1];
95 index2 = indexBuffer16[index2];
96 index3 = indexBuffer16[index3];
99 int vertexOffset1 = index1 * oldVertexStride;
100 int vertexOffset2 = index2 * oldVertexStride;
101 int vertexOffset3 = index3 * oldVertexStride;
104 var position1 = (
Vector3*)&oldBuffer[vertexOffset1 + positionOffset];
105 var position2 = (
Vector3*)&oldBuffer[vertexOffset2 + positionOffset];
106 var position3 = (
Vector3*)&oldBuffer[vertexOffset3 + positionOffset];
109 var uv1 = (
Vector3*)&oldBuffer[vertexOffset1 + uvOffset];
110 var uv2 = (
Vector3*)&oldBuffer[vertexOffset2 + uvOffset];
111 var uv3 = (
Vector3*)&oldBuffer[vertexOffset3 + uvOffset];
114 var edge1 = *position2 - *position1;
115 var edge2 = *position3 - *position1;
116 var uvEdge1 = *uv2 - *uv1;
117 var uvEdge2 = *uv3 - *uv1;
119 var t = Vector3.Normalize(uvEdge2.Y * edge1 - uvEdge1.Y * edge2);
120 var
b = Vector3.Normalize(uvEdge1.X * edge2 - uvEdge2.X * edge1);
123 tangents[index1] += t;
124 tangents[index2] += t;
125 tangents[index3] += t;
127 bitangents[index1] +=
b;
128 bitangents[index2] +=
b;
129 bitangents[index3] +=
b;
132 var oldVertexOffset = 0;
133 var newVertexOffset = 0;
134 for (
int i = 0; i < vertexBufferBinding.Count; ++i)
136 Utilities.CopyMemory(
new IntPtr(&newBuffer[newVertexOffset]),
new IntPtr(&oldBuffer[oldVertexOffset]), oldVertexStride);
138 var normal = *(
Vector3*)&oldBuffer[oldVertexOffset + normalOffset];
139 var target = ((
float*)(&newBuffer[newVertexOffset + tangentOffset]));
141 var tangent = -tangents[i];
142 var bitangent = bitangents[i];
145 *((
Vector3*)target) = Vector3.Normalize(tangent - normal * Vector3.Dot(normal, tangent));
148 target[3] = Vector3.Dot(Vector3.Cross(normal, tangent), bitangent) < 0.0f ? -1.0f : 1.0f;
150 oldVertexOffset += oldVertexStride;
151 newVertexOffset += newVertexStride;
155 vertexBufferBinding.Offset = 0;
The layout of a vertex buffer with a set of VertexElement.
static VertexElement Tangent(PixelFormat format, int offsetInBytes=AppendAligned)
Declares a VertexElement with the semantic "TANGENT".
static readonly string Tangent
Vertex tangent data.
SiliconStudio.Paradox.Graphics.PrimitiveType PrimitiveType
Data field for SiliconStudio.Paradox.Effects.MeshDraw.PrimitiveType.
Represents a three dimensional mathematical vector.
TextureCoordinate
The texture coordinate.
Represents a four dimensional mathematical vector.
static unsafe void GenerateTangentBinormal(this MeshDrawData meshData)
Generates the tangents and binormals for this mesh data. Tangents and bitangents will be encoded as f...
Data type for SiliconStudio.Paradox.Effects.MeshDraw.
PrimitiveType
Defines how vertex data is ordered.
Content of a GPU buffer (vertex buffer, index buffer, etc...).
A description of a single element for the input-assembler stage. This structure is related to Direct3...