| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- //-----------------------------------------------------------------------------
- // SpherePrimitive.cs
- //
- // Microsoft XNA Community Game Platform
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- using System;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- namespace PerformanceMeasuring
- {
- /// <summary>
- /// Geometric primitive class for drawing spheres.
- ///
- /// This class is borrowed from the Primitives3D sample.
- /// </summary>
- public class SpherePrimitive : GeometricPrimitive
- {
- /// <summary>
- /// Constructs a new sphere primitive, using default settings.
- /// </summary>
- public SpherePrimitive(GraphicsDevice graphicsDevice)
- : this(graphicsDevice, 1, 16)
- {
- }
- /// <summary>
- /// Constructs a new sphere primitive,
- /// with the specified size and tessellation level.
- /// </summary>
- public SpherePrimitive(GraphicsDevice graphicsDevice, float diameter, int tessellation)
- {
- if (tessellation < 3)
- throw new ArgumentOutOfRangeException("tessellation");
- int verticalSegments = tessellation;
- int horizontalSegments = tessellation * 2;
- float radius = diameter / 2;
- // Start with a single vertex at the bottom of the sphere.
- AddVertex(Vector3.Down * radius, Vector3.Down);
- // Create rings of vertices at progressively higher latitudes.
- for (int i = 0; i < verticalSegments - 1; i++)
- {
- float latitude = ((i + 1) * MathHelper.Pi / verticalSegments) - MathHelper.PiOver2;
- float dy = (float)Math.Sin(latitude);
- float dxz = (float)Math.Cos(latitude);
- // Create a single ring of vertices at this latitude.
- for (int j = 0; j < horizontalSegments; j++)
- {
- float longitude = j * MathHelper.TwoPi / horizontalSegments;
- float dx = (float)Math.Cos(longitude) * dxz;
- float dz = (float)Math.Sin(longitude) * dxz;
- Vector3 normal = new Vector3(dx, dy, dz);
- AddVertex(normal * radius, normal);
- }
- }
- // Finish with a single vertex at the top of the sphere.
- AddVertex(Vector3.Up * radius, Vector3.Up);
- // Create a fan connecting the bottom vertex to the bottom latitude ring.
- for (int i = 0; i < horizontalSegments; i++)
- {
- AddIndex(0);
- AddIndex(1 + (i + 1) % horizontalSegments);
- AddIndex(1 + i);
- }
- // Fill the sphere body with triangles joining each pair of latitude rings.
- for (int i = 0; i < verticalSegments - 2; i++)
- {
- for (int j = 0; j < horizontalSegments; j++)
- {
- int nextI = i + 1;
- int nextJ = (j + 1) % horizontalSegments;
- AddIndex(1 + i * horizontalSegments + j);
- AddIndex(1 + i * horizontalSegments + nextJ);
- AddIndex(1 + nextI * horizontalSegments + j);
- AddIndex(1 + i * horizontalSegments + nextJ);
- AddIndex(1 + nextI * horizontalSegments + nextJ);
- AddIndex(1 + nextI * horizontalSegments + j);
- }
- }
- // Create a fan connecting the top vertex to the top latitude ring.
- for (int i = 0; i < horizontalSegments; i++)
- {
- AddIndex(CurrentVertex - 1);
- AddIndex(CurrentVertex - 2 - (i + 1) % horizontalSegments);
- AddIndex(CurrentVertex - 2 - i);
- }
- InitializePrimitive(graphicsDevice);
- }
- }
- }
|