|
#region File Description
//-----------------------------------------------------------------------------
// CylinderPrimitive.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace Primitives3D
{
/// <summary>
/// Geometric primitive class for drawing cylinders.
/// </summary>
public class CylinderPrimitive : GeometricPrimitive
{
/// <summary>
/// Constructs a new cylinder primitive, using default settings.
/// </summary>
public CylinderPrimitive(GraphicsDevice graphicsDevice)
: this(graphicsDevice, 1, 1, 32)
{
}
/// <summary>
/// Constructs a new cylinder primitive,
/// with the specified size and tessellation level.
/// </summary>
public CylinderPrimitive(GraphicsDevice graphicsDevice,
float height, float diameter, int tessellation)
{
if (tessellation < 3)
throw new ArgumentOutOfRangeException("tessellation");
height /= 2;
float radius = diameter / 2;
// Create a ring of triangles around the outside of the cylinder.
for (int i = 0; i < tessellation; i++)
{
Vector3 normal = GetCircleVector(i, tessellation);
AddVertex(normal * radius + Vector3.Up * height, normal);
AddVertex(normal * radius + Vector3.Down * height, normal);
AddIndex(i * 2);
AddIndex(i * 2 + 1);
AddIndex((i * 2 + 2) % (tessellation * 2));
AddIndex(i * 2 + 1);
AddIndex((i * 2 + 3) % (tessellation * 2));
AddIndex((i * 2 + 2) % (tessellation * 2));
}
// Create flat triangle fan caps to seal the top and bottom.
CreateCap(tessellation, height, radius, Vector3.Up);
CreateCap(tessellation, height, radius, Vector3.Down);
InitializePrimitive(graphicsDevice);
}
/// <summary>
/// Helper method creates a triangle fan to close the ends of the cylinder.
/// </summary>
void CreateCap(int tessellation, float height, float radius, Vector3 normal)
{
// Create cap indices.
for (int i = 0; i < tessellation - 2; i++)
{
if (normal.Y > 0)
{
AddIndex(CurrentVertex);
AddIndex(CurrentVertex + (i + 1) % tessellation);
AddIndex(CurrentVertex + (i + 2) % tessellation);
}
else
{
AddIndex(CurrentVertex);
AddIndex(CurrentVertex + (i + 2) % tessellation);
AddIndex(CurrentVertex + (i + 1) % tessellation);
}
}
// Create cap vertices.
for (int i = 0; i < tessellation; i++)
{
Vector3 position = GetCircleVector(i, tessellation) * radius +
normal * height;
AddVertex(position, normal);
}
}
/// <summary>
/// Helper method computes a point on a circle.
/// </summary>
static Vector3 GetCircleVector(int i, int tessellation)
{
float angle = i * MathHelper.TwoPi / tessellation;
float dx = (float)Math.Cos(angle);
float dz = (float)Math.Sin(angle);
return new Vector3(dx, 0, dz);
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Started programming on the mainframe in 1985.
Have been programming in Visual Basic since VB 2.0
and been using Visual Studio since it appeared on the market.
Currently prefered language when working with Windows Phone is C#.
For the time being main interest is "Augmented Reality" types of apps..
I am employed at EVRY a Norwegian based very successful DP company with offices in Norway, Sweden, Denmark, Finland, U.K., India and Ukraine.