public override void Tessellate() { // Create vertices. Vector3D normal = new Vector3D(0, 1, 0); for (int z = 0; z < _length; ++z) for (int x = 0; x < _width; ++x) AddVertex(new Point3D(x, 0, (_length - 1) - z), normal); // Invert z so that winding order is correct. // Create indices. for (int z = 0; z < _length - 1; ++z) for (int x = 0; x < _width; ++x) { // Create vertex for degenerate triangle. if (x == 0 && z > 0) AddIndex(((z + 0) * _width) + x); AddIndex(((z + 0) * _width) + x); AddIndex(((z + 1) * _width) + x); // Create vertex for degenerate triangle. if (x == _width - 1 && z < _length - 2) AddIndex(((z + 1) * _width) + x); } // It's easiest to define the plane in terms of a triangle strip, // and then convert it. Int32Collection newIndices = MeshUtility.ConvertTriangleStripToTriangleList(Indices); Indices.Clear(); Indices.AddRange(newIndices); }
/// <summary> /// Helper method creates a triangle fan to close the ends of the cylinder. /// </summary> private void CreateCap(Vector3D normal) { // Create cap indices. for (int i = 0; i < TessellationLevel - 2; i++) { if (normal.Y > 0) { AddIndex(CurrentVertex); AddIndex(CurrentVertex + (i + 1) % TessellationLevel); AddIndex(CurrentVertex + (i + 2) % TessellationLevel); } else { AddIndex(CurrentVertex); AddIndex(CurrentVertex + (i + 2) % TessellationLevel); AddIndex(CurrentVertex + (i + 1) % TessellationLevel); } } // Create cap vertices. for (int i = 0; i < TessellationLevel; i++) { Point3D position = (Point3D)GetCircleVector(i) * _radius + normal * _height; AddVertex(position, normal); } }
public Quaternion(Vector3D axis, float angle) { axis.Normalize(); float num2 = angle * 0.5f; float num = MathUtility.Sin(num2); float num3 = MathUtility.Cos(num2); X = axis.X * num; Y = axis.Y * num; Z = axis.Z * num; W = num3; }
private static void AccumulateTriangleNormals(Int32Collection indices, Point3DCollection positions, Vector3D[] vertexNormals) { for (int i = 0; i < indices.Count; i += 3) { Point3D vector4 = positions[indices[i]]; Point3D vector = positions[indices[i + 1]]; Point3D vector3 = positions[indices[i + 2]]; Vector3D vector2 = Vector3D.Normalize(Vector3D.Cross(vector3 - vector, vector - vector4)); for (int j = 0; j < 3; j++) vertexNormals[indices[i + j]] += vector2; } }
public static void CalculateNormals(Mesh mesh, bool overwriteExistingNormals) { if (mesh == null) throw new ArgumentNullException("mesh"); if (overwriteExistingNormals || !mesh.Normals.Any()) { Vector3D[] vertexNormals = new Vector3D[mesh.Positions.Count]; AccumulateTriangleNormals(mesh.Indices, mesh.Positions, vertexNormals); for (int i = 0; i < vertexNormals.Length; i++) vertexNormals[i] = Vector3D.Normalize(vertexNormals[i]); mesh.Normals.AddRange(vertexNormals); } }
public override void Tessellate() { // First we loop around the main ring of the torus. for (int i = 0; i < TessellationLevel; i++) { float outerAngle = i * MathUtility.TWO_PI / TessellationLevel; // Create a transform matrix that will align geometry to // slice perpendicularly though the current ring position. Matrix3D transform = Matrix3D.CreateTranslation(_radius, 0, 0) * Matrix3D.CreateRotationY(outerAngle); // Now we loop along the other axis, around the side of the tube. for (int j = 0; j < TessellationLevel; j++) { float innerAngle = j * MathUtility.TWO_PI / TessellationLevel; float dx = (float)Math.Cos(innerAngle); float dy = (float)Math.Sin(innerAngle); // Create a vertex. Vector3D normal = new Vector3D(dx, dy, 0); Point3D position = (Point3D)(normal * _thickness / 2); position = Point3D.Transform(position, transform); normal = Vector3D.TransformNormal(normal, transform); AddVertex(position, normal); // And create indices for two triangles. int nextI = (i + 1) % TessellationLevel; int nextJ = (j + 1) % TessellationLevel; AddIndex(i * TessellationLevel + j); AddIndex(i * TessellationLevel + nextJ); AddIndex(nextI * TessellationLevel + j); AddIndex(i * TessellationLevel + nextJ); AddIndex(nextI * TessellationLevel + nextJ); AddIndex(nextI * TessellationLevel + j); } } }
public override void Tessellate() { // A cube has six faces, each one pointing in a different direction. Vector3D[] normals = { new Vector3D(0, 0, 1), new Vector3D(0, 0, -1), new Vector3D(1, 0, 0), new Vector3D(-1, 0, 0), new Vector3D(0, 1, 0), new Vector3D(0, -1, 0), }; // Create each face in turn. foreach (Vector3D normal in normals) { // Get two vectors perpendicular to the face normal and to each other. Vector3D side1 = new Vector3D(normal.Y, normal.Z, normal.X); Vector3D side2 = Vector3D.Cross(normal, side1); // Six indices (two triangles) per face. AddIndex(CurrentVertex + 0); AddIndex(CurrentVertex + 1); AddIndex(CurrentVertex + 2); AddIndex(CurrentVertex + 0); AddIndex(CurrentVertex + 2); AddIndex(CurrentVertex + 3); // Four vertices per face. AddVertex((Point3D)((normal - side1 - side2) * _size / 2), normal); AddVertex((Point3D)((normal - side1 + side2) * _size / 2), normal); AddVertex((Point3D)((normal + side1 + side2) * _size / 2), normal); AddVertex((Point3D)((normal + side1 - side2) * _size / 2), normal); } }
private void OnMouseDown(object sender, MouseEventArgs e) { IoC.Get<IOutput>().Append("Mouse down"); Mouse.Capture(EventSource, CaptureMode.Element); _previousPosition2D = e.GetPosition(EventSource); _initialPosition3D = ProjectToTrackball( EventSource.ActualWidth, EventSource.ActualHeight, _previousPosition2D); _currentOrientation = _persistentOrientation; _mouseDown = true; }
public static Vector3D TransformNormal(Vector3D normal, Matrix3D matrix) { float num3 = ((normal.X * matrix.M11) + (normal.Y * matrix.M21)) + (normal.Z * matrix.M31); float num2 = ((normal.X * matrix.M12) + (normal.Y * matrix.M22)) + (normal.Z * matrix.M32); float num = ((normal.X * matrix.M13) + (normal.Y * matrix.M23)) + (normal.Z * matrix.M33); return new Vector3D(num3, num2, num); }
public static Vector3D Reflect(Vector3D vector, Vector3D normal) { Vector3D vector2; float num = ((vector.X * normal.X) + (vector.Y * normal.Y)) + (vector.Z * normal.Z); vector2.X = vector.X - ((2f * num) * normal.X); vector2.Y = vector.Y - ((2f * num) * normal.Y); vector2.Z = vector.Z - ((2f * num) * normal.Z); return vector2; }
public static Vector3D Normalize(Vector3D v) { return v / v.Length(); }
public static float AbsDot(Vector3D v1, Normal3D n2) { return System.Math.Abs(Dot(v1, n2)); }
public static float AbsDot(Vector3D v1, Vector3D v2) { return System.Math.Abs(Dot(v1, v2)); }
public static Vector3D Abs(Vector3D vector) { return new Vector3D(Math.Abs(vector.X), Math.Abs(vector.Y), Math.Abs(vector.Z)); }
private void ClearAccumulator() { _forceAccumulator = Vector3D.Zero; }
public static float Dot(Vector3D v1, Normal3D n2) { return (v1.X * n2.X) + (v1.Y * n2.Y) + (v1.Z * n2.Z); }
public static float Dot(Normal3D n1, Vector3D v2) { return (n1.X * v2.X) + (n1.Y * v2.Y) + (n1.Z * v2.Z); }
public static float AbsDot(Normal3D n1, Vector3D v2) { return System.Math.Abs(Dot(n1, v2)); }
public static Vector3D Parse(string source) { IFormatProvider cultureInfo = CultureInfo.InvariantCulture; TokenizerHelper helper = new TokenizerHelper(source, cultureInfo); string str = helper.NextTokenRequired(); Vector3D vectord = new Vector3D(Convert.ToSingle(str, cultureInfo), Convert.ToSingle(helper.NextTokenRequired(), cultureInfo), Convert.ToSingle(helper.NextTokenRequired(), cultureInfo)); helper.LastTokenRequired(); return vectord; }
public static float AngleBetween(Vector3D vector1, Vector3D vector2) { vector1.Normalize(); vector2.Normalize(); if (Dot(vector1, vector2) < 0.0f) { Vector3D vectord2 = -vector1 - vector2; return MathUtility.PI - (2.0f * MathUtility.Asin(vectord2.Length() / 2.0f)); } Vector3D vectord = vector1 - vector2; return 2.0f * MathUtility.Asin(vectord.Length() / 2.0f); }
public static Vector3D Transform(Vector3D position, Matrix3D matrix) { Vector3D vector; float num3 = (((position.X * matrix.M11) + (position.Y * matrix.M21)) + (position.Z * matrix.M31)) + matrix.M41; float num2 = (((position.X * matrix.M12) + (position.Y * matrix.M22)) + (position.Z * matrix.M32)) + matrix.M42; float num = (((position.X * matrix.M13) + (position.Y * matrix.M23)) + (position.Z * matrix.M33)) + matrix.M43; vector.X = num3; vector.Y = num2; vector.Z = num; return vector; }
public static void CoordinateSystem(Vector3D v1, out Vector3D v2, out Vector3D v3) { if (System.Math.Abs(v1.Y) > System.Math.Abs(v1.Y)) { float invLen = 1.0f / MathUtility.Sqrt(v1.X * v1.X + v1.Z * v1.Z); v2 = new Vector3D(-v1.Z * invLen, 0.0f, v1.X * invLen); } else { float invLen = 1.0f / MathUtility.Sqrt(v1.Y * v1.Y + v1.Z * v1.Z); v2 = new Vector3D(0.0f, v1.Z * invLen, -v1.Y * invLen); } v3 = Vector3D.Cross(v1, v2); }
/// <summary> /// Computes the tangent of a cubic bezier curve at the specified time, /// when given four Point3D control points. This is used for calculating /// normals (by crossing the horizontal and vertical tangent vectors). /// </summary> private static Vector3D BezierTangent(Point3D p1, Point3D p2, Point3D p3, Point3D p4, float t) { Vector3D result = new Vector3D(); result.X = BezierTangent(p1.X, p2.X, p3.X, p4.X, t); result.Y = BezierTangent(p1.Y, p2.Y, p3.Y, p4.Y, t); result.Z = BezierTangent(p1.Z, p2.Z, p3.Z, p4.Z, t); result.Normalize(); return result; }
public static void Cross(ref Vector3D v1, ref Vector3D v2, out Vector3D result) { result = new Vector3D((v1.Y * v2.Z) - (v1.Z * v2.Y), (v1.Z * v2.X) - (v1.X * v2.Z), (v1.X * v2.Y) - (v1.Y * v2.X)); }
public override void Tessellate() { int verticalSegments = TessellationLevel; int horizontalSegments = TessellationLevel * 2; // Start with a single vertex at the bottom of the sphere. AddVertex((Point3D)(Vector3D.Down * _radius), Vector3D.Down); // Create rings of vertices at progressively higher latitudes. for (int i = 0; i < verticalSegments - 1; i++) { float latitude = ((i + 1) * MathUtility.PI / verticalSegments) - MathUtility.PI_OVER_2; float dy = MathUtility.Sin(latitude); float dxz = MathUtility.Cos(latitude); // Create a single ring of vertices at this latitude. for (int j = 0; j < horizontalSegments; j++) { float longitude = j * MathUtility.TWO_PI / horizontalSegments; float dx = (float)Math.Cos(longitude) * dxz; float dz = (float)Math.Sin(longitude) * dxz; Vector3D normal = new Vector3D(dx, dy, dz); AddVertex((Point3D)(normal * _radius), normal); } } // Finish with a single vertex at the top of the sphere. AddVertex((Point3D)(Vector3D.Up * _radius), Vector3D.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); } }
public static Vector3D Cross(Normal3D v1, Vector3D v2) { return new Vector3D((v1.Y * v2.Z) - (v1.Z * v2.Y), (v1.Z * v2.X) - (v1.X * v2.Z), (v1.X * v2.Y) - (v1.Y * v2.X)); }
public VertexPositionColor(Point3D position, Vector3D color) { Position = position; Color = color; }
public static float Dot(Vector3D v1, Vector3D v2) { return (v1.X * v2.X) + (v1.Y * v2.Y) + (v1.Z * v2.Z); }
public ParticleGravity(Particle particle, Vector3D gravity) : base(particle) { _gravity = gravity; }
public static void Dot(ref Vector3D v1, ref Vector3D v2, out float result) { result = (v1.X * v2.X) + (v1.Y * v2.Y) + (v1.Z * v2.Z); }