77 using System.Collections.Generic;
78 using SiliconStudio.Core.Mathematics;
80 namespace SiliconStudio.
Paradox.Graphics
82 public partial class GeometricPrimitive
94 private struct TeapotPatch
96 public TeapotPatch(
bool mirrorZ, params
int[] indices)
98 this.mirrorZ = mirrorZ;
99 this.indices = indices;
103 public int[] indices;
107 private static readonly TeapotPatch[] TeapotPatches =
new TeapotPatch[]
110 new TeapotPatch(
true,
new[] {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}),
113 new TeapotPatch(
true,
new[] {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}),
114 new TeapotPatch(
true,
new[] {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}),
117 new TeapotPatch(
true,
new[] {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3}),
118 new TeapotPatch(
true,
new[] {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117}),
121 new TeapotPatch(
false,
new[] {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56}),
122 new TeapotPatch(
false,
new[] {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67}),
125 new TeapotPatch(
false,
new[] {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83}),
126 new TeapotPatch(
false,
new[] {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}),
129 new TeapotPatch(
true,
new[] {118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37}),
134 private static readonly
Vector3[] TeapotControlPoints =
new Vector3[]
136 new Vector3(0, 0.345f, -0.05f),
137 new Vector3(-0.028f, 0.345f, -0.05f),
138 new Vector3(-0.05f, 0.345f, -0.028f),
139 new Vector3(-0.05f, 0.345f, -0),
140 new Vector3(0, 0.3028125f, -0.334375f),
141 new Vector3(-0.18725f, 0.3028125f, -0.334375f),
142 new Vector3(-0.334375f, 0.3028125f, -0.18725f),
143 new Vector3(-0.334375f, 0.3028125f, -0),
144 new Vector3(0, 0.3028125f, -0.359375f),
145 new Vector3(-0.20125f, 0.3028125f, -0.359375f),
146 new Vector3(-0.359375f, 0.3028125f, -0.20125f),
147 new Vector3(-0.359375f, 0.3028125f, -0),
148 new Vector3(0, 0.27f, -0.375f),
149 new Vector3(-0.21f, 0.27f, -0.375f),
150 new Vector3(-0.375f, 0.27f, -0.21f),
151 new Vector3(-0.375f, 0.27f, -0),
152 new Vector3(0, 0.13875f, -0.4375f),
153 new Vector3(-0.245f, 0.13875f, -0.4375f),
154 new Vector3(-0.4375f, 0.13875f, -0.245f),
155 new Vector3(-0.4375f, 0.13875f, -0),
156 new Vector3(0, 0.007499993f, -0.5f),
157 new Vector3(-0.28f, 0.007499993f, -0.5f),
158 new Vector3(-0.5f, 0.007499993f, -0.28f),
159 new Vector3(-0.5f, 0.007499993f, -0),
160 new Vector3(0, -0.105f, -0.5f),
161 new Vector3(-0.28f, -0.105f, -0.5f),
162 new Vector3(-0.5f, -0.105f, -0.28f),
163 new Vector3(-0.5f, -0.105f, -0),
165 new Vector3(0, -0.2175f, -0.5f),
166 new Vector3(-0.28f, -0.2175f, -0.5f),
167 new Vector3(-0.5f, -0.2175f, -0.28f),
168 new Vector3(-0.5f, -0.2175f, -0),
169 new Vector3(0, -0.27375f, -0.375f),
170 new Vector3(-0.21f, -0.27375f, -0.375f),
171 new Vector3(-0.375f, -0.27375f, -0.21f),
172 new Vector3(-0.375f, -0.27375f, -0),
173 new Vector3(0, -0.2925f, -0.375f),
174 new Vector3(-0.21f, -0.2925f, -0.375f),
175 new Vector3(-0.375f, -0.2925f, -0.21f),
176 new Vector3(-0.375f, -0.2925f, -0),
177 new Vector3(0, 0.17625f, 0.4f),
178 new Vector3(-0.075f, 0.17625f, 0.4f),
179 new Vector3(-0.075f, 0.2325f, 0.375f),
180 new Vector3(0, 0.2325f, 0.375f),
181 new Vector3(0, 0.17625f, 0.575f),
182 new Vector3(-0.075f, 0.17625f, 0.575f),
183 new Vector3(-0.075f, 0.2325f, 0.625f),
184 new Vector3(0, 0.2325f, 0.625f),
185 new Vector3(0, 0.17625f, 0.675f),
186 new Vector3(-0.075f, 0.17625f, 0.675f),
187 new Vector3(-0.075f, 0.2325f, 0.75f),
188 new Vector3(0, 0.2325f, 0.75f),
190 new Vector3(-0.075f, 0.12f, 0.675f),
191 new Vector3(-0.075f, 0.12f, 0.75f),
193 new Vector3(0, 0.06375f, 0.675f),
194 new Vector3(-0.075f, 0.06375f, 0.675f),
195 new Vector3(-0.075f, 0.007499993f, 0.75f),
196 new Vector3(0, 0.007499993f, 0.75f),
197 new Vector3(0, -0.04875001f, 0.625f),
198 new Vector3(-0.075f, -0.04875001f, 0.625f),
199 new Vector3(-0.075f, -0.09562501f, 0.6625f),
200 new Vector3(0, -0.09562501f, 0.6625f),
201 new Vector3(-0.075f, -0.105f, 0.5f),
202 new Vector3(-0.075f, -0.18f, 0.475f),
203 new Vector3(0, -0.18f, 0.475f),
204 new Vector3(0, 0.02624997f, -0.425f),
205 new Vector3(-0.165f, 0.02624997f, -0.425f),
206 new Vector3(-0.165f, -0.18f, -0.425f),
207 new Vector3(0, -0.18f, -0.425f),
208 new Vector3(0, 0.02624997f, -0.65f),
209 new Vector3(-0.165f, 0.02624997f, -0.65f),
210 new Vector3(-0.165f, -0.12375f, -0.775f),
211 new Vector3(0, -0.12375f, -0.775f),
212 new Vector3(0, 0.195f, -0.575f),
213 new Vector3(-0.0625f, 0.195f, -0.575f),
214 new Vector3(-0.0625f, 0.17625f, -0.6f),
215 new Vector3(0, 0.17625f, -0.6f),
216 new Vector3(0, 0.27f, -0.675f),
217 new Vector3(-0.0625f, 0.27f, -0.675f),
218 new Vector3(-0.0625f, 0.27f, -0.825f),
219 new Vector3(0, 0.27f, -0.825f),
220 new Vector3(0, 0.28875f, -0.7f),
221 new Vector3(-0.0625f, 0.28875f, -0.7f),
222 new Vector3(-0.0625f, 0.2934375f, -0.88125f),
223 new Vector3(0, 0.2934375f, -0.88125f),
224 new Vector3(0, 0.28875f, -0.725f),
225 new Vector3(-0.0375f, 0.28875f, -0.725f),
226 new Vector3(-0.0375f, 0.298125f, -0.8625f),
227 new Vector3(0, 0.298125f, -0.8625f),
229 new Vector3(-0.0375f, 0.27f, -0.7f),
230 new Vector3(-0.0375f, 0.27f, -0.8f),
233 new Vector3(0, 0.4575f, -0.2f),
234 new Vector3(-0.1125f, 0.4575f, -0.2f),
235 new Vector3(-0.2f, 0.4575f, -0.1125f),
236 new Vector3(-0.2f, 0.4575f, -0),
239 new Vector3(-0.196f, 0.27f, -0.35f),
240 new Vector3(-0.35f, 0.27f, -0.196f),
241 new Vector3(-0.35f, 0.27f, -0),
242 new Vector3(0, 0.3075f, -0.1f),
243 new Vector3(-0.056f, 0.3075f, -0.1f),
244 new Vector3(-0.1f, 0.3075f, -0.056f),
245 new Vector3(-0.1f, 0.3075f, -0),
246 new Vector3(0, 0.3075f, -0.325f),
247 new Vector3(-0.182f, 0.3075f, -0.325f),
248 new Vector3(-0.325f, 0.3075f, -0.182f),
249 new Vector3(-0.325f, 0.3075f, -0),
250 new Vector3(0, 0.27f, -0.325f),
251 new Vector3(-0.182f, 0.27f, -0.325f),
252 new Vector3(-0.325f, 0.27f, -0.182f),
253 new Vector3(-0.325f, 0.27f, -0),
255 new Vector3(-0.1995f, -0.33f, -0.35625f),
256 new Vector3(0, -0.31125f, -0.375f),
257 new Vector3(0, -0.33f, -0.35625f),
258 new Vector3(-0.35625f, -0.33f, -0.1995f),
259 new Vector3(-0.375f, -0.31125f, -0),
260 new Vector3(-0.35625f, -0.33f, -0),
261 new Vector3(-0.21f, -0.31125f, -0.375f),
262 new Vector3(-0.375f, -0.31125f, -0.21f),
289 public static GeometricMeshData<VertexPositionNormalTexture>
New(
float size = 1.0f,
int tessellation = 8,
bool toLeftHanded =
false)
291 var vertices =
new List<VertexPositionNormalTexture>();
292 var indices =
new List<int>();
294 if (tessellation < 1)
295 throw new ArgumentOutOfRangeException(
"tessellation",
"tessellation must be > 0");
298 var scaleNegateX = scaleVector;
299 scaleNegateX.X = -scaleNegateX.X;
300 var scaleNegateZ = scaleVector;
301 scaleNegateZ.Z = -scaleNegateZ.Z;
304 for (
int i = 0; i < TeapotPatches.Length; i++)
306 var patch = TeapotPatches[i];
310 TessellatePatch(vertices, indices, ref patch, tessellation, scaleVector,
false);
311 TessellatePatch(vertices, indices, ref patch, tessellation, scaleNegateX,
true);
318 TessellatePatch(vertices, indices, ref patch, tessellation, scaleNegateZ,
true);
319 TessellatePatch(vertices, indices, ref patch, tessellation, scaleNegateXZ,
false);
323 return new GeometricMeshData<VertexPositionNormalTexture>(vertices.ToArray(), indices.ToArray(), toLeftHanded) { Name =
"Teapot" };
333 var onet2 = (1 - t) * (1 - t);
334 return p1*(1 - t)*onet2 +
346 return p1*(-1 + 2*t - t2) +
347 p2*(1 - 4*t + 3*t2) +
355 private static void CreatePatchVertices(
Vector3[] patch,
int tessellation,
bool isMirrored, List<VertexPositionNormalTexture> outputList)
357 for (
int i = 0; i <= tessellation; i++)
359 float u = (float) i/tessellation;
361 for (
int j = 0; j <= tessellation; j++)
363 float v = (float) j/tessellation;
367 var p1 = CubicInterpolate(ref patch[0], ref patch[1], ref patch[2], ref patch[3], u);
368 var p2 = CubicInterpolate(ref patch[4], ref patch[5], ref patch[6], ref patch[7], u);
369 var p3 = CubicInterpolate(ref patch[8], ref patch[9], ref patch[10], ref patch[11], u);
370 var p4 = CubicInterpolate(ref patch[12], ref patch[13], ref patch[14], ref patch[15], u);
374 var position = CubicInterpolate(ref p1, ref p2, ref p3, ref p4, v);
378 var q1 = CubicInterpolate(ref patch[0], ref patch[4], ref patch[8], ref patch[12], v);
379 var q2 = CubicInterpolate(ref patch[1], ref patch[5], ref patch[9], ref patch[13], v);
380 var q3 = CubicInterpolate(ref patch[2], ref patch[6], ref patch[10], ref patch[14], v);
381 var q4 = CubicInterpolate(ref patch[3], ref patch[7], ref patch[11], ref patch[15], v);
384 var tangent1 = CubicTangent(ref p1, ref p2, ref p3, ref p4, v);
385 var tangent2 = CubicTangent(ref q1, ref q2, ref q3, ref q4, u);
388 var normal = Vector3.Cross(tangent1, tangent2);
414 normal.Y = position.Y < 0.0f ? -1.0f : 1.0f;
419 float mirroredU = isMirrored ? 1 - u : u;
421 var textureCoordinate =
new Vector2(mirroredU, v);
424 outputList.Add(
new VertexPositionNormalTexture(position, normal, textureCoordinate));
431 private static IEnumerable<int> CreatePatchIndices(
int tessellation,
bool isMirrored,
int baseIndex)
433 int stride = tessellation + 1;
435 var indices =
new int[6];
437 for (
int i = 0; i < tessellation; i++)
439 for (
int j = 0; j < tessellation; j++)
441 indices[0] = baseIndex + i*stride + j;
442 indices[1] = baseIndex + (i + 1)*stride + j;
443 indices[2] = baseIndex + (i + 1)*stride + j + 1;
444 indices[3] = baseIndex + i*stride + j;
445 indices[4] = baseIndex + (i + 1)*stride + j + 1;
446 indices[5] = baseIndex + i*stride + j + 1;
451 Array.Reverse(indices);
454 foreach (var index
in indices)
463 private static void TessellatePatch(List<VertexPositionNormalTexture> vertices, List<int> indices, ref TeapotPatch patch,
int tessellation,
Vector3 scale,
467 var controlPoints =
new Vector3[16];
469 for (
int i = 0; i < 16; i++)
471 controlPoints[i] = TeapotControlPoints[patch.indices[i]] * scale;
475 int vbase = vertices.Count;
476 indices.AddRange(CreatePatchIndices(tessellation, isMirrored, vbase));
477 CreatePatchVertices(controlPoints, tessellation, isMirrored, vertices);
static GeometricMeshData< VertexPositionNormalTexture > New(float size=1.0f, int tessellation=8, bool toLeftHanded=false)
Creates a teapot primitive.
SiliconStudio.Paradox.Games.Mathematics.Vector2 Vector2
A geometric primitive. Use Cube, Cylinder, GeoSphere, Plane, Sphere, Teapot, Torus. See Draw+vertices to learn how to use it.
Represents a three dimensional mathematical vector.
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
static readonly Vector3 Zero
A SiliconStudio.Core.Mathematics.Vector3 with all of its components set to zero.
static bool NearEqual(Vector3 left, Vector3 right, Vector3 epsilon)
Tests whether one 3D vector is near another 3D vector.
SiliconStudio.Core.Mathematics.Vector3 Vector3
static Vector3 CubicInterpolate(ref Vector3 p1, ref Vector3 p2, ref Vector3 p3, ref Vector3 p4, float t)
_In_ size_t _In_ size_t size
static GeometricPrimitive New(GraphicsDevice device, float size=1.0f, int tessellation=8, bool toLeftHanded=false)
Creates a teapot primitive.