public static WW3DModel GenerateCuboid(Size3D wdh, Vector3D offset, NormalDirection nd) { var points = new List<Point3D>(); points.Add(new Point3D(-wdh.X / 2 + offset.X, -wdh.Y / 2 + offset.Y, wdh.Z / 2 + offset.Z)); points.Add(new Point3D(-wdh.X / 2 + offset.X, -wdh.Y / 2 + offset.Y, -wdh.Z / 2 + offset.Z)); points.Add(new Point3D(wdh.X / 2 + offset.X, -wdh.Y / 2 + offset.Y, -wdh.Z / 2 + offset.Z)); points.Add(new Point3D(wdh.X / 2 + offset.X, -wdh.Y / 2 + offset.Y, wdh.Z / 2 + offset.Z)); points.Add(new Point3D(-wdh.X / 2 + offset.X, wdh.Y / 2 + offset.Y, wdh.Z / 2 + offset.Z)); points.Add(new Point3D(-wdh.X / 2 + offset.X, wdh.Y / 2 + offset.Y, -wdh.Z / 2 + offset.Z)); points.Add(new Point3D(wdh.X / 2 + offset.X, wdh.Y / 2 + offset.Y, -wdh.Z / 2 + offset.Z)); points.Add(new Point3D(wdh.X / 2 + offset.X, wdh.Y / 2 + offset.Y, wdh.Z / 2 + offset.Z)); int[] indices = null; switch (nd) { case NormalDirection.Outward: indices = new int[] { 5, 1, 0, 6, 2, 1, 7, 3, 2, 4, 0, 3, 1, 2, 3, 6, 5, 4, 4, 5, 0, 5, 6, 1, 6, 7, 2, 7, 4, 3, 0, 1, 3, 7, 6, 4 }; break; case NormalDirection.Inward: indices = new int[] { 0,1,5,1,2,6,2,3,7,3,0,4, 3,2,1,4,5,6,0,5,4,1,6,5, 2,7,6,3,4,7,3,1,0,4,6,7}; break; } return new WW3DModel(points.ToArray(), indices); }
public static WW3DModel GenerateCuboid(Size3D wdh, Vector3D offset, NormalDirection nd) { var points = new List <Point3D>(); points.Add(new Point3D(-wdh.X / 2 + offset.X, -wdh.Y / 2 + offset.Y, wdh.Z / 2 + offset.Z)); points.Add(new Point3D(-wdh.X / 2 + offset.X, -wdh.Y / 2 + offset.Y, -wdh.Z / 2 + offset.Z)); points.Add(new Point3D(wdh.X / 2 + offset.X, -wdh.Y / 2 + offset.Y, -wdh.Z / 2 + offset.Z)); points.Add(new Point3D(wdh.X / 2 + offset.X, -wdh.Y / 2 + offset.Y, wdh.Z / 2 + offset.Z)); points.Add(new Point3D(-wdh.X / 2 + offset.X, wdh.Y / 2 + offset.Y, wdh.Z / 2 + offset.Z)); points.Add(new Point3D(-wdh.X / 2 + offset.X, wdh.Y / 2 + offset.Y, -wdh.Z / 2 + offset.Z)); points.Add(new Point3D(wdh.X / 2 + offset.X, wdh.Y / 2 + offset.Y, -wdh.Z / 2 + offset.Z)); points.Add(new Point3D(wdh.X / 2 + offset.X, wdh.Y / 2 + offset.Y, wdh.Z / 2 + offset.Z)); int[] indices = null; switch (nd) { case NormalDirection.Outward: indices = new int[] { 5, 1, 0, 6, 2, 1, 7, 3, 2, 4, 0, 3, 1, 2, 3, 6, 5, 4, 4, 5, 0, 5, 6, 1, 6, 7, 2, 7, 4, 3, 0, 1, 3, 7, 6, 4 }; break; case NormalDirection.Inward: indices = new int[] { 0, 1, 5, 1, 2, 6, 2, 3, 7, 3, 0, 4, 3, 2, 1, 4, 5, 6, 0, 5, 4, 1, 6, 5, 2, 7, 6, 3, 4, 7, 3, 1, 0, 4, 6, 7 }; break; } return(new WW3DModel(points.ToArray(), indices)); }
/// <summary> /// For each edge, return the plane containing the edge whose normal direction points toward the interior side /// of the edge. /// </summary> public IEnumerable <Plane> GetEdgesAsInwardPointingPlanes() => Edges.Select(edge => new Plane(NormalDirection.CrossProduct(edge.Direction), edge.BasePoint));
/// <summary> /// Creates a Plane primitive on the X/Y plane with a normal equal to -<see cref="Vector3.UnitZ"/>. /// </summary> /// <param name="sizeX">The size X.</param> /// <param name="sizeY">The size Y.</param> /// <param name="tessellationX">The tessellation, as the number of quads per X axis.</param> /// <param name="tessellationY">The tessellation, as the number of quads per Y axis.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <param name="uFactor">Scale U coordinates between 0 and the values of this parameter.</param> /// <param name="vFactor">Scale V coordinates 0 and the values of this parameter.</param> /// <param name="generateBackFace">Add a back face to the plane</param> /// <param name="normalDirection">The direction of the plane normal</param> /// <returns>A Plane primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be > 0</exception> public static GeometricMeshData <VertexPositionNormalTexture> New(float sizeX = 1.0f, float sizeY = 1.0f, int tessellationX = 1, int tessellationY = 1, float uFactor = 1f, float vFactor = 1f, bool generateBackFace = false, bool toLeftHanded = false, NormalDirection normalDirection = 0) { if (tessellationX < 1) { tessellationX = 1; } if (tessellationY < 1) { tessellationY = 1; } var lineWidth = tessellationX + 1; var lineHeight = tessellationY + 1; var vertices = new VertexPositionNormalTexture[lineWidth * lineHeight * (generateBackFace? 2: 1)]; var indices = new int[tessellationX * tessellationY * 6 * (generateBackFace? 2: 1)]; var deltaX = sizeX / tessellationX; var deltaY = sizeY / tessellationY; sizeX /= 2.0f; sizeY /= 2.0f; int vertexCount = 0; int indexCount = 0; Vector3 normal; switch (normalDirection) { default: case NormalDirection.UpZ: normal = Vector3.UnitZ; break; case NormalDirection.UpY: normal = Vector3.UnitY; break; case NormalDirection.UpX: normal = Vector3.UnitX; break; } var uv = new Vector2(uFactor, vFactor); // Create vertices for (int y = 0; y < (tessellationY + 1); y++) { for (int x = 0; x < (tessellationX + 1); x++) { Vector3 position; switch (normalDirection) { default: case NormalDirection.UpZ: position = new Vector3(-sizeX + deltaX * x, sizeY - deltaY * y, 0); break; case NormalDirection.UpY: position = new Vector3(-sizeX + deltaX * x, 0, -sizeY + deltaY * y); break; case NormalDirection.UpX: position = new Vector3(0, sizeY - deltaY * y, sizeX - deltaX * x); break; } var texCoord = new Vector2(uv.X * x / tessellationX, uv.Y * y / tessellationY); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, texCoord); } } // Create indices for (int y = 0; y < tessellationY; y++) { for (int x = 0; x < tessellationX; x++) { // Six indices (two triangles) per face. int vbase = lineWidth * y + x; indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + 1 + lineWidth); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase); } } if (generateBackFace) { var numVertices = lineWidth * lineHeight; normal = -normal; for (int y = 0; y < (tessellationY + 1); y++) { for (int x = 0; x < (tessellationX + 1); x++) { var baseVertex = vertices[vertexCount - numVertices]; var position = new Vector3(baseVertex.Position.X, baseVertex.Position.Y, baseVertex.Position.Z); var texCoord = new Vector2(uv.X * x / tessellationX, uv.Y * y / tessellationY); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, texCoord); } } // Create indices for (int y = 0; y < tessellationY; y++) { for (int x = 0; x < tessellationX; x++) { // Six indices (two triangles) per face. int vbase = lineWidth * (y + tessellationY + 1) + x; indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase + 1 + lineWidth); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase); indices[indexCount++] = (vbase + lineWidth); } } } // Create the primitive object. return(new GeometricMeshData <VertexPositionNormalTexture>(vertices, indices, toLeftHanded) { Name = "Plane" }); }
/// <summary> /// Creates a Plane primitive on the X/Y plane with a normal equal to -<see cref="Vector3.UnitZ"/>. /// </summary> /// <param name="device">The device.</param> /// <param name="sizeX">The size X.</param> /// <param name="sizeY">The size Y.</param> /// <param name="tessellationX">The tessellation, as the number of quads per X axis.</param> /// <param name="tessellationY">The tessellation, as the number of quads per Y axis.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <param name="uFactor">Scale U coordinates between 0 and the values of this parameter.</param> /// <param name="vFactor">Scale V coordinates 0 and the values of this parameter.</param> /// <param name="generateBackFace">Add a back face to the plane</param> /// <param name="normalDirection">The direction of the plane normal</param> /// <returns>A Plane primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be > 0</exception> public static GeometricPrimitive New(GraphicsDevice device, float sizeX = 1.0f, float sizeY = 1.0f, int tessellationX = 1, int tessellationY = 1, float uFactor = 1f, float vFactor = 1f, bool generateBackFace = false, bool toLeftHanded = false, NormalDirection normalDirection = NormalDirection.UpZ) { return(new GeometricPrimitive(device, New(sizeX, sizeY, tessellationX, tessellationY, uFactor, vFactor, generateBackFace, toLeftHanded, normalDirection))); }
/// <summary> /// Creates a Plane primitive on the X/Y plane with a normal equal to -<see cref="Vector3.UnitZ"/>. /// </summary> /// <param name="sizeX">The size X.</param> /// <param name="sizeY">The size Y.</param> /// <param name="tessellationX">The tessellation, as the number of quads per X axis.</param> /// <param name="tessellationY">The tessellation, as the number of quads per Y axis.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <param name="uFactor">Scale U coordinates between 0 and the values of this parameter.</param> /// <param name="vFactor">Scale V coordinates 0 and the values of this parameter.</param> /// <param name="generateBackFace">Add a back face to the plane</param> /// <param name="normalDirection">The direction of the plane normal</param> /// <returns>A Plane primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be > 0</exception> public static GeometricMeshData<VertexPositionNormalTexture> New(float sizeX = 1.0f, float sizeY = 1.0f, int tessellationX = 1, int tessellationY = 1, float uFactor = 1f, float vFactor = 1f, bool generateBackFace = false, bool toLeftHanded = false, NormalDirection normalDirection = 0) { if (tessellationX < 1) tessellationX = 1; if (tessellationY < 1) tessellationY = 1; var lineWidth = tessellationX + 1; var lineHeight = tessellationY + 1; var vertices = new VertexPositionNormalTexture[lineWidth * lineHeight * (generateBackFace? 2: 1)]; var indices = new int[tessellationX * tessellationY * 6 * (generateBackFace? 2: 1)]; var deltaX = sizeX / tessellationX; var deltaY = sizeY / tessellationY; sizeX /= 2.0f; sizeY /= 2.0f; int vertexCount = 0; int indexCount = 0; Vector3 normal; switch (normalDirection) { default: case NormalDirection.UpZ: normal = Vector3.UnitZ; break; case NormalDirection.UpY: normal = Vector3.UnitY; break; case NormalDirection.UpX: normal = Vector3.UnitX; break; } var uv = new Vector2(uFactor, vFactor); // Create vertices for (int y = 0; y < (tessellationY + 1); y++) { for (int x = 0; x < (tessellationX + 1); x++) { Vector3 position; switch (normalDirection) { default: case NormalDirection.UpZ: position = new Vector3(-sizeX + deltaX * x, sizeY - deltaY * y, 0); break; case NormalDirection.UpY: position = new Vector3(-sizeX + deltaX * x, 0, -sizeY + deltaY * y); break; case NormalDirection.UpX: position = new Vector3(0, sizeY - deltaY * y, sizeX - deltaX * x); break; } var texCoord = new Vector2(uv.X * x / tessellationX, uv.Y * y / tessellationY); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, texCoord); } } // Create indices for (int y = 0; y < tessellationY; y++) { for (int x = 0; x < tessellationX; x++) { // Six indices (two triangles) per face. int vbase = lineWidth * y + x; indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + 1 + lineWidth); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase); } } if(generateBackFace) { var numVertices = lineWidth * lineHeight; normal = -normal; for (int y = 0; y < (tessellationY + 1); y++) { for (int x = 0; x < (tessellationX + 1); x++) { var baseVertex = vertices[vertexCount - numVertices]; var position = new Vector3(baseVertex.Position.X, baseVertex.Position.Y, baseVertex.Position.Z); var texCoord = new Vector2(uv.X * x / tessellationX, uv.Y * y / tessellationY); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, texCoord); } } // Create indices for (int y = 0; y < tessellationY; y++) { for (int x = 0; x < tessellationX; x++) { // Six indices (two triangles) per face. int vbase = lineWidth * (y + tessellationY + 1) + x; indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase + 1 + lineWidth); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase); indices[indexCount++] = (vbase + lineWidth); } } } // Create the primitive object. return new GeometricMeshData<VertexPositionNormalTexture>(vertices, indices, toLeftHanded) { Name = "Plane" }; }
/// <summary> /// Creates a Plane primitive on the X/Y plane with a normal equal to -<see cref="Vector3.UnitZ"/>. /// </summary> /// <param name="device">The device.</param> /// <param name="sizeX">The size X.</param> /// <param name="sizeY">The size Y.</param> /// <param name="tessellationX">The tessellation, as the number of quads per X axis.</param> /// <param name="tessellationY">The tessellation, as the number of quads per Y axis.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <param name="uFactor">Scale U coordinates between 0 and the values of this parameter.</param> /// <param name="vFactor">Scale V coordinates 0 and the values of this parameter.</param> /// <param name="generateBackFace">Add a back face to the plane</param> /// <param name="normalDirection">The direction of the plane normal</param> /// <returns>A Plane primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be > 0</exception> public static GeometricPrimitive New(GraphicsDevice device, float sizeX = 1.0f, float sizeY = 1.0f, int tessellationX = 1, int tessellationY = 1, float uFactor = 1f, float vFactor = 1f, bool generateBackFace = false, bool toLeftHanded = false, NormalDirection normalDirection = NormalDirection.UpZ) { return new GeometricPrimitive(device, New(sizeX, sizeY, tessellationX, tessellationY, uFactor, vFactor, generateBackFace, toLeftHanded, normalDirection)); }