Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
GeometricPrimitive.Cylinder.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 //
4 // Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 // THE SOFTWARE.
23 // -----------------------------------------------------------------------------
24 // The following code is a port of DirectXTk http://directxtk.codeplex.com
25 // -----------------------------------------------------------------------------
26 // Microsoft Public License (Ms-PL)
27 //
28 // This license governs use of the accompanying software. If you use the
29 // software, you accept this license. If you do not accept the license, do not
30 // use the software.
31 //
32 // 1. Definitions
33 // The terms "reproduce," "reproduction," "derivative works," and
34 // "distribution" have the same meaning here as under U.S. copyright law.
35 // A "contribution" is the original software, or any additions or changes to
36 // the software.
37 // A "contributor" is any person that distributes its contribution under this
38 // license.
39 // "Licensed patents" are a contributor's patent claims that read directly on
40 // its contribution.
41 //
42 // 2. Grant of Rights
43 // (A) Copyright Grant- Subject to the terms of this license, including the
44 // license conditions and limitations in section 3, each contributor grants
45 // you a non-exclusive, worldwide, royalty-free copyright license to reproduce
46 // its contribution, prepare derivative works of its contribution, and
47 // distribute its contribution or any derivative works that you create.
48 // (B) Patent Grant- Subject to the terms of this license, including the license
49 // conditions and limitations in section 3, each contributor grants you a
50 // non-exclusive, worldwide, royalty-free license under its licensed patents to
51 // make, have made, use, sell, offer for sale, import, and/or otherwise dispose
52 // of its contribution in the software or derivative works of the contribution
53 // in the software.
54 //
55 // 3. Conditions and Limitations
56 // (A) No Trademark License- This license does not grant you rights to use any
57 // contributors' name, logo, or trademarks.
58 // (B) If you bring a patent claim against any contributor over patents that
59 // you claim are infringed by the software, your patent license from such
60 // contributor to the software ends automatically.
61 // (C) If you distribute any portion of the software, you must retain all
62 // copyright, patent, trademark, and attribution notices that are present in the
63 // software.
64 // (D) If you distribute any portion of the software in source code form, you
65 // may do so only under this license by including a complete copy of this
66 // license with your distribution. If you distribute any portion of the software
67 // in compiled or object code form, you may only do so under a license that
68 // complies with this license.
69 // (E) The software is licensed "as-is." You bear the risk of using it. The
70 // contributors give no express warranties, guarantees or conditions. You may
71 // have additional consumer rights under your local laws which this license
72 // cannot change. To the extent permitted under your local laws, the
73 // contributors exclude the implied warranties of merchantability, fitness for a
74 // particular purpose and non-infringement.
75 
76 using System;
77 using System.Collections.Generic;
78 using SiliconStudio.Core;
79 using SiliconStudio.Core.Mathematics;
80 
81 namespace SiliconStudio.Paradox.Graphics
82 {
83  public partial class GeometricPrimitive
84  {
85  /// <summary>
86  /// A Cylinder primitive.
87  /// </summary>
88  public struct Cylinder
89  {
90  // Helper computes a point on a unit circle, aligned to the x/z plane and centered on the origin.
91  private static Vector3 GetCircleVector(int i, int tessellation)
92  {
93  var angle = (float) (i*2.0*Math.PI/tessellation);
94  var dx = (float) Math.Sin(angle);
95  var dz = (float) Math.Cos(angle);
96 
97  return new Vector3(dx, 0, dz);
98  }
99 
100  // Helper creates a triangle fan to close the end of a cylinder.
101  private static void CreateCylinderCap(List<VertexPositionNormalTexture> vertices, List<int> indices, int tessellation, float height, float radius, float textureTiling, bool isTop)
102  {
103  // Create cap indices.
104  for (int i = 0; i < tessellation - 2; i++)
105  {
106  int i1 = (i + 1)%tessellation;
107  int i2 = (i + 2)%tessellation;
108 
109  if (isTop)
110  {
111  Utilities.Swap(ref i1, ref i2);
112  }
113 
114  int vbase = vertices.Count;
115  indices.Add(vbase);
116  indices.Add(vbase + i1);
117  indices.Add(vbase + i2);
118  }
119 
120  // Which end of the cylinder is this?
121  var normal = Vector3.UnitY;
122  var textureScale = new Vector2(-0.5f);
123 
124  if (!isTop)
125  {
126  normal = -normal;
127  textureScale.X = -textureScale.X;
128  }
129 
130  // Create cap vertices.
131  for (int i = 0; i < tessellation; i++)
132  {
133  var circleVector = GetCircleVector(i, tessellation);
134  var position = (circleVector*radius) + (normal*height);
135  var textureCoordinate = new Vector2(textureTiling * (circleVector.X * textureScale.X + 0.5f), textureTiling * (circleVector.Z * textureScale.Y + 0.5f));
136 
137  vertices.Add(new VertexPositionNormalTexture(position, normal, textureCoordinate));
138  }
139  }
140 
141  /// <summary>
142  /// Creates a cylinder primitive.
143  /// </summary>
144  /// <param name="device">The device.</param>
145  /// <param name="height">The height.</param>
146  /// <param name="diameter">The diameter.</param>
147  /// <param name="tessellation">The tessellation.</param>
148  /// <param name="textureTiling">The texture tiling.</param>
149  /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param>
150  /// <returns>A cylinder primitive.</returns>
151  /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be &gt;= 3</exception>
152  public static GeometricPrimitive New(GraphicsDevice device, float height = 1.0f, float diameter = 1.0f, int tessellation = 32, float textureTiling = 1, bool toLeftHanded = false)
153  {
154  // Create the primitive object.
155  return new GeometricPrimitive(device, New(height, diameter, tessellation, textureTiling, toLeftHanded));
156  }
157 
158  /// <summary>
159  /// Creates a cylinder primitive.
160  /// </summary>
161  /// <param name="height">The height.</param>
162  /// <param name="diameter">The diameter.</param>
163  /// <param name="tessellation">The tessellation.</param>
164  /// <param name="textureTiling">The texture tiling.</param>
165  /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param>
166  /// <returns>A cylinder primitive.</returns>
167  /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be &gt;= 3</exception>
168  public static GeometricMeshData<VertexPositionNormalTexture> New(float height = 1.0f, float diameter = 1.0f, int tessellation = 32, float textureTiling = 1, bool toLeftHanded = false)
169  {
170  if (tessellation < 3)
171  throw new ArgumentOutOfRangeException("tessellation", "tessellation must be >= 3");
172 
173  var vertices = new List<VertexPositionNormalTexture>();
174  var indices = new List<int>();
175 
176  height /= 2;
177 
178  var topOffset = Vector3.UnitY*height;
179 
180  float radius = diameter/2;
181  int stride = tessellation + 1;
182 
183  // Create a ring of triangles around the outside of the cylinder.
184  for (int i = 0; i <= tessellation; i++)
185  {
186  var normal = GetCircleVector(i, tessellation);
187 
188  var sideOffset = normal*radius;
189 
190  var textureCoordinate = new Vector2(textureTiling * (float) i/tessellation, 0);
191 
192  vertices.Add(new VertexPositionNormalTexture(sideOffset + topOffset, normal, textureCoordinate));
193  vertices.Add(new VertexPositionNormalTexture(sideOffset - topOffset, normal, textureCoordinate + Vector2.UnitY));
194 
195  indices.Add(i*2);
196  indices.Add((i*2 + 2)%(stride*2));
197  indices.Add(i*2 + 1);
198 
199  indices.Add(i*2 + 1);
200  indices.Add((i*2 + 2)%(stride*2));
201  indices.Add((i*2 + 3)%(stride*2));
202  }
203 
204  // Create flat triangle fan caps to seal the top and bottom.
205  CreateCylinderCap(vertices, indices, tessellation, height, radius, textureTiling, true);
206  CreateCylinderCap(vertices, indices, tessellation, height, radius, textureTiling, false);
207 
208  // Create the primitive object.
209  return new GeometricMeshData<VertexPositionNormalTexture>(vertices.ToArray(), indices.ToArray(), toLeftHanded) {Name = "Cylinder"};
210  }
211  }
212  }
213 }
SiliconStudio.Paradox.Games.Mathematics.Vector2 Vector2
Represents a two dimensional mathematical vector.
Definition: Vector2.cs:42
static GeometricMeshData< VertexPositionNormalTexture > New(float height=1.0f, float diameter=1.0f, int tessellation=32, float textureTiling=1, bool toLeftHanded=false)
Creates a cylinder primitive.
static readonly Vector2 UnitY
The Y unit SiliconStudio.Core.Mathematics.Vector2 (0, 1).
Definition: Vector2.cs:62
A geometric primitive. Use Cube, Cylinder, GeoSphere, Plane, Sphere, Teapot, Torus. See Draw+vertices to learn how to use it.
Describes a custom vertex format structure that contains position, normal and texture information...
static GeometricPrimitive New(GraphicsDevice device, float height=1.0f, float diameter=1.0f, int tessellation=32, float textureTiling=1, bool toLeftHanded=false)
Creates a cylinder primitive.
Represents a three dimensional mathematical vector.
Definition: Vector3.cs:42
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.
SiliconStudio.Core.Mathematics.Vector3 Vector3