//Merge identicle verticies in mesh public static Mesh WeldCopy(Mesh m) { var resultVerticies = new List<Vertex>(); var indexMap = new Dictionary<short, short>(); for (short i = 0; i < m.verticies.Length; i += 1) { var pos = m.verticies[i].Position; bool matchFound = false; for (int x = 0; x < resultVerticies.Count; ++x) { if (Gem.Math.Utility.AlmostZero((resultVerticies[x].Position - pos).LengthSquared())) { indexMap.Add(i, (short)x); matchFound = true; break; } } if (!matchFound) { indexMap.Add(i, (short)resultVerticies.Count); resultVerticies.Add(m.verticies[i]); } } var result = new Mesh(); result.verticies = resultVerticies.ToArray(); result.indicies = new short[m.indicies.Length]; for (int i = 0; i < result.indicies.Length; ++i) result.indicies[i] = indexMap[m.indicies[i]]; return result; }
public EdgeMesh(Mesh m) { this.Verticies = new List<Vector3>(); this.Faces = new List<EMFace>(); this.Edges = new List<EMEdge>(); foreach (var v in m.verticies) this.Verticies.Add(v.Position); for (int i = 0; i < m.indicies.Length; i += 3) { var face = new EMFace(m.indicies[i + 0], m.indicies[i + 1], m.indicies[i + 2]); foreach (var edge in face.edges) face.Centroid += this.Verticies[edge.Verticies[0]]; face.Centroid /= face.edges.Count; this.Faces.Add(face); for (int e = 0; e < face.edges.Count; ++e) { var foundEdge = FindEdge(face.edges[e].Verticies[0], face.edges[e].Verticies[1]); if (foundEdge != -1) { face.edges[e] = this.Edges[foundEdge]; face.edges[e].ParentFace.SetRecipricalNeighbor(face.edges[e], face); } else this.Edges.Add(face.edges[e]); } } }
public MeshNode(Mesh Mesh, Texture2D Texture, Euler Orientation = null) { this.Mesh = Mesh; this.Texture = Texture; this.Orientation = Orientation; if (this.Orientation == null) this.Orientation = new Euler(); }
public static Mesh CreateWedge(float Height) { var result = new Mesh(); result.verticies = new Vertex[6]; result.verticies[0].Position = new Vector3(-0.5f, -0.5f, -0.5f); result.verticies[1].Position = new Vector3(0.5f, -0.5f, -0.5f); result.verticies[2].Position = new Vector3(0.5f, 0.5f, -0.5f); result.verticies[3].Position = new Vector3(-0.5f, 0.5f, -0.5f); result.verticies[4].Position = new Vector3(0.5f, 0.5f, -0.5f + Height); result.verticies[5].Position = new Vector3(-0.5f, 0.5f, -0.5f + Height); result.indicies = new short[] { 0, 1, 2, // bottom 3, 0, 2, 4, 5, 2, // back 2, 5, 3, 0, 4, 1, // top 4, 0, 5, 0, 3, 5, // side 2, 1, 4, // side }; return result; }
public static void ProjectTextureFit(Mesh m) { var box = CalculateBoundingBox(m); ProjectTexture(m, box.Min, new Vector3(box.Max.X - box.Min.X, 0, 0), new Vector3(0, box.Max.Y - box.Min.Y, 0)); }
public Mesh CreatePatch(Vector3[] points, int tesselation) { var r = new Mesh(); r.indicies = CreatePatchIndices(tesselation, false); r.verticies = CreatePatchVertices(points, tesselation, false); return r; }
public static RealtimeCSG.Plane[] PlanesFromMesh(Mesh mesh) { var result = new List<RealtimeCSG.Plane>(); for (var i = 0; i < mesh.indicies.Length; i += 3) { var planeNormal = Gen.CalculateNormal(mesh, mesh.indicies[i], mesh.indicies[i + 1], mesh.indicies[i + 2]); var plane = new Plane(mesh.verticies[mesh.indicies[i]].Position, mesh.verticies[mesh.indicies[i + 1]].Position, mesh.verticies[mesh.indicies[i + 2]].Position); result.Add(new RealtimeCSG.Plane(new RealtimeCSG.Vector3(plane.Normal.X, plane.Normal.Y, plane.Normal.Z), plane.D)); } var final = new List<RealtimeCSG.Plane>(); foreach (var plane in result) { bool reject = false; foreach (var existingPlane in final) if (plane.EpsilonEquals(existingPlane)) reject = true; if (!reject) final.Add(plane); } return final.ToArray(); }
public static CoincidentEdge? FindCoincidentEdge(Mesh A, Mesh B) { foreach (var aEdge in A.EnumerateEdgesAsPosition()) foreach (var bEdge in B.EnumerateEdgesAsPosition()) if (CoincidentEdge.NearlyEqual(aEdge, bEdge)) return aEdge; return null; }
public static void ProjectTextureCube(Mesh m) { if (cubePlanes == null) { cubePlanes = new TexturePlane[6]; cubePlanes[0] = new TexturePlane { origin = Vector3.Zero, normal = new Vector3(0, 0, -1), uAxis = new Vector3(1, 0, 0), vAxis = new Vector3(0, 1, 0) }; cubePlanes[1] = new TexturePlane { origin = Vector3.Zero, normal = new Vector3(0, 0, 1), uAxis = new Vector3(1, 0, 0), vAxis = new Vector3(0, 1, 0) }; cubePlanes[2] = new TexturePlane { origin = Vector3.Zero, normal = new Vector3(-1, 0, 0), uAxis = new Vector3(0, 0, 1), vAxis = new Vector3(0, 1, 0) }; cubePlanes[3] = new TexturePlane { origin = Vector3.Zero, normal = new Vector3(1, 0, 0), uAxis = new Vector3(0, 0, 1), vAxis = new Vector3(0, 1, 0) }; cubePlanes[4] = new TexturePlane { origin = Vector3.Zero, normal = new Vector3(0, -1, 0), uAxis = new Vector3(0, 0, 1), vAxis = new Vector3(1, 0, 0) }; cubePlanes[5] = new TexturePlane { origin = Vector3.Zero, normal = new Vector3(0, 1, 0), uAxis = new Vector3(0, 0, 1), vAxis = new Vector3(1, 0, 0) }; } ProjectTexturePlanes(m, cubePlanes); }
public static Mesh MorphToSplineCopy( Mesh mesh, Vector3 axis, Gem.Math.Spline spline) { var result = Copy(mesh); MorphToSpline(result, axis, spline); return result; }
public static Mesh Copy(Mesh mesh) { var result = new Mesh(); result.verticies = new VertexPositionNormalTexture[mesh.verticies.Length]; for (int i = 0; i < mesh.verticies.Length; ++i) result.verticies[i] = mesh.verticies[i]; result.indicies = new short[mesh.indicies.Length]; CopyIndicies(result.indicies, 0, mesh.indicies); return result; }
public static Mesh AlignToSplineCopy( Mesh mesh, Vector3 axis, Vector3 splineRotationAxis, Gem.Math.Spline spline, float distance) { var result = Copy(mesh); AlignToSpline(result, axis, splineRotationAxis, spline, distance); return result; }
/// <summary> /// Scale mesh part so that it fits - and fills - the supplied bounding box. /// </summary> /// <param name="box"></param> /// <returns></returns> public static void FitToBox(Mesh mesh, BoundingBox box) { var partBox = Gen.CalculateBoundingBox(mesh); var partDims = partBox.Max - partBox.Min; var boxDims = box.Max - box.Min; Morph(mesh, (v) => { var rel = v - partBox.Min; return box.Min + ((rel / partDims) * boxDims); }); }
public static Mesh TextureAndFacetAsCube(Mesh In) { var result = FacetCopy(In); ProjectTextureCube(result); for (int i = 0; i < result.VertexCount; ++i) result.verticies[i].TextureCoordinate += new Vector2(0.5f, 0.5f); Gen.CalculateTangentsAndBiNormals(result); return result; }
public static void CalculateTangentsAndBiNormals(Mesh m) { for (short i = 0; i < m.verticies.Length; i += 3) { var normals = Gen.CalculateTangentAndBinormal(m, i, i + 1, i + 2); for (int j = 0; j < 3; ++j) { m.verticies[i + j].Tangent = normals.Item1; m.verticies[i + j].BiNormal = normals.Item2; } } }
public override void Project(Mesh onto, Matrix objectWorldTransformation) { var tPlane = Csg.TransformCopy(plane, objectWorldTransformation); var tHint = Vector3.Transform(upHint, objectWorldTransformation); var perpendicularAxis = new Vector3(tPlane.A, tPlane.B, tPlane.C); perpendicularAxis.Normalize(); var cross = Vector3.Cross(perpendicularAxis, tHint); Gen.ProjectTexture(onto, perpendicularAxis * plane.D, cross * Scale, Vector3.Cross(perpendicularAxis, cross) * Scale); }
public static CompiledModel CompileModel(Mesh model, GraphicsDevice device) { CompiledModel result = new CompiledModel(); result.indicies = new IndexBuffer(device, typeof(Int16), model.indicies.Length, BufferUsage.WriteOnly); result.indicies.SetData(model.indicies); result.verticies = new VertexBuffer(device, typeof(Vertex), model.verticies.Length, BufferUsage.WriteOnly); result.verticies.SetData(model.verticies); result.primitiveCount = model.indicies.Length / 3; return result; }
public GuiSceneNode(Geo.Mesh Mesh, GraphicsDevice device, int width, int height, Euler Euler = null) { this.Device = device; this.Mesh = Mesh; this.Orientation = Euler; if (this.Orientation == null) this.Orientation = new Euler(); uiCamera = new Render.OrthographicCamera(new Viewport(0, 0, width, height)); uiRoot = new UIItem("ROOT", new QuadShape(0, 0, width, height), null); uiCamera.focus = new Vector2(width / 2, height / 2); renderTarget = new RenderTarget2D(device, uiCamera.Viewport.Width, uiCamera.Viewport.Height); }
/// <summary> /// Align the object with the spline. Transforms object so that its origin is on the spline. /// </summary> /// <returns></returns> public static void AlignToSpline( Mesh mesh, Vector3 axis, Vector3 splineRotationAxis, Gem.Math.Spline spline, float distance) { Morph(mesh, (v) => { var splinePoint = spline.Point(distance); var splineTangent = spline.Tangent(distance); var m = Matrix.CreateFromAxisAngle(Vector3.Normalize(splineRotationAxis), Gem.Math.Vector.AngleBetweenVectors(axis, splineTangent)); return splinePoint + Vector3.Transform(v, m); }); }
public static BoundingBox CalculateBoundingBox(Mesh mesh) { Vector3 minimum = mesh.verticies[0].Position; Vector3 maximum = mesh.verticies[0].Position; foreach (var vert in mesh.verticies) { if (vert.Position.X < minimum.X) minimum.X = vert.Position.X; if (vert.Position.Y < minimum.Y) minimum.Y = vert.Position.Y; if (vert.Position.Z < minimum.Z) minimum.Z = vert.Position.Z; if (vert.Position.X > maximum.X) maximum.X = vert.Position.X; if (vert.Position.Y > maximum.Y) maximum.Y = vert.Position.Y; if (vert.Position.Z > maximum.Z) maximum.Z = vert.Position.Z; } return new BoundingBox(minimum, maximum); }
public static Mesh CreateLine(Vector3 v0, Vector3 v1, Vector3 normal, float width) { var lineV = v1 - v0; lineV.Normalize(); var lineP = Vector3.Cross(lineV, normal); var result = new Mesh(); result.verticies = new Vertex[4]; result.verticies[0].Position = v0 + (lineP * (width / 2.0f)); result.verticies[1].Position = v0 - (lineP * (width / 2.0f)); result.verticies[2].Position = v1 - (lineP * (width / 2.0f)); result.verticies[3].Position = v1 + (lineP * (width / 2.0f)); result.indicies = new short[] { 0, 1, 2, 3, 0, 2 }; return result; }
/// <summary> /// Morph the object onto a spline. Expects the object's origin to already be aligned with the spline. /// </summary> /// <returns></returns> public static void MorphToSpline( Mesh mesh, Vector3 axis, Gem.Math.Spline spline) { Morph(mesh, (v) => { var distance = Gem.Math.Vector.ProjectAOntoB(v, axis).Length() / axis.Length(); var splinePoint = spline.Point(distance); var splineTangent = spline.Tangent(distance); var rel = (axis * distance) - v; var m = Matrix.CreateFromAxisAngle(Vector3.Normalize(spline.RotationAxis),//splineRotationAxis), Gem.Math.Vector.AngleBetweenVectors(axis, splineTangent)); return splinePoint + Vector3.Transform(rel, m); }); }
public static Mesh InstanceMerge( IEnumerable<Mesh> Meshes, IEnumerable<Matrix> Transformation) { var r = new Mesh(); var totalVerticies = Meshes.Sum(m => m.VertexCount); var totalIndicies = Meshes.Sum(m => m.indicies.Length); r.verticies = new Vertex[totalVerticies]; r.indicies = new short[totalIndicies]; int vertexInsertLocation = 0; int indexInsertLocation = 0; foreach (var instance in Meshes.Zip(Transformation, (m, t) => Tuple.Create(m,t))) { var mesh = instance.Item1; var transform = instance.Item2; for (int i = 0; i < mesh.VertexCount; ++i) { r.verticies[i + vertexInsertLocation].Position = Vector3.Transform(mesh.verticies[i].Position, transform); r.verticies[i + vertexInsertLocation].TextureCoordinate = mesh.verticies[i].TextureCoordinate; } Vector3 scale; Vector3 trans; Quaternion rot; transform.Decompose(out scale, out rot, out trans); for (int i = 0; i < mesh.VertexCount; ++i) { r.verticies[i + vertexInsertLocation].Normal = Vector3.Transform(mesh.verticies[i].Normal, rot); r.verticies[i + vertexInsertLocation].Tangent = Vector3.Transform(mesh.verticies[i].Tangent, rot); r.verticies[i + vertexInsertLocation].BiNormal = Vector3.Transform(mesh.verticies[i].BiNormal, rot); } for (int i = 0; i < mesh.indicies.Length; ++i) r.indicies[i + indexInsertLocation] = (short)(vertexInsertLocation + mesh.indicies[i]); vertexInsertLocation += mesh.VertexCount; indexInsertLocation += mesh.indicies.Length; } return r; }
public static Mesh ConvertToMesh(RealtimeCSG.CSGMesh csg) { var result = new Mesh(); result.verticies = new VertexPositionNormalTexture[csg.Vertices.Count]; for (int i = 0; i < csg.Vertices.Count; ++i) result.verticies[i].Position = new Vector3(csg.Vertices[i].X, csg.Vertices[i].Y, csg.Vertices[i].Z); var indicies = new List<short>(); foreach (var polygon in csg.Polygons) { if (polygon.Visible && polygon.FirstIndex >= 0) { var indexList = new List<short>(); var start = csg.Edges[polygon.FirstIndex]; indexList.Add(start.VertexIndex); var current = csg.Edges[start.NextIndex]; while (current != start) { indexList.Add(current.VertexIndex); current = csg.Edges[current.NextIndex]; } for (var index = 0; index < indexList.Count - 2; ++index) { indicies.Add(indexList[0]); if (polygon.Category == RealtimeCSG.PolygonCategory.Aligned) { indicies.Add(indexList[index + 2]); indicies.Add(indexList[index + 1]); } else { indicies.Add(indexList[index + 1]); indicies.Add(indexList[index + 2]); } } } } result.indicies = indicies.ToArray(); return result; }
public static Mesh CreateSlantedCube(float Slant) { var result = new Mesh(); result.verticies = new Vertex[8]; result.verticies[0].Position = new Vector3(-0.5f, -0.5f, -0.5f); result.verticies[1].Position = new Vector3(0.5f, -0.5f, -0.5f); result.verticies[2].Position = new Vector3(0.5f, 0.5f, -0.5f); result.verticies[3].Position = new Vector3(-0.5f, 0.5f, -0.5f); result.verticies[4].Position = new Vector3(-0.5f, -0.5f, 0.5f); result.verticies[5].Position = new Vector3(0.5f, -0.5f, 0.5f); result.verticies[6].Position = new Vector3(0.5f, 0.5f, 0.5f + Slant); result.verticies[7].Position = new Vector3(-0.5f, 0.5f, 0.5f + Slant); result.indicies = CubeIndicies; return result; }
public static Mesh Merge(params Mesh[] parts) { var result = new Mesh(); result.verticies = new VertexPositionNormalTexture[parts.Sum((p) => p.verticies.Length)]; result.indicies = new short[parts.Sum((p) => p.indicies.Length)]; int vCount = 0; int iCount = 0; foreach (var part in parts) { for (int i = 0; i < part.verticies.Length; ++i) result.verticies[i + vCount] = part.verticies[i]; for (int i = 0; i < part.indicies.Length; ++i) result.indicies[i + iCount] = (short)(part.indicies[i] + vCount); vCount += part.verticies.Length; iCount += part.indicies.Length; } return result; }
//Explode mesh into unique triangles for facetted look. public static Mesh FacetCopy(Mesh m) { var result = new Mesh(); result.verticies = new Vertex[m.indicies.Length]; result.indicies = new short[m.indicies.Length]; for (short i = 0; i < m.indicies.Length; ++i) { result.verticies[i] = m.verticies[m.indicies[i]]; result.indicies[i] = i; } for (short i = 0; i < result.verticies.Length; i += 3) { var normal = Gen.CalculateNormal(result, i, i + 1, i + 2); for (int j = 0; j < 3; ++j) result.verticies[i + j].Normal = normal; } return result; }
public static Mesh CreateQuad() { var result = new Mesh(); result.verticies = new VertexPositionNormalTexture[4]; result.verticies[0].Position = new Vector3(-0.5f, -0.5f, 0); result.verticies[1].Position = new Vector3(0.5f, -0.5f, 0); result.verticies[2].Position = new Vector3(0.5f, 0.5f, 0); result.verticies[3].Position = new Vector3(-0.5f, 0.5f, 0); for (int i = 0; i < 4; ++i) { result.verticies[i].TextureCoordinate = new Vector2(result.verticies[i].Position.X + 0.5f, result.verticies[i].Position.Y + 0.5f); result.verticies[i].Normal = Vector3.UnitZ; } result.indicies = new short[] { 0, 1, 2, 3, 0, 2 }; return result; }
public static Mesh CreateSlantedQuad(float Slant) { var result = new Mesh(); result.verticies = new Vertex[4]; result.verticies[0].Position = new Vector3(-0.5f, -0.5f, 0); result.verticies[1].Position = new Vector3(0.5f, -0.5f, 0); result.verticies[2].Position = new Vector3(0.5f, 0.5f, Slant); result.verticies[3].Position = new Vector3(-0.5f, 0.5f, Slant); for (int i = 0; i < 4; ++i) { result.verticies[i].TextureCoordinate = new Vector2(result.verticies[i].Position.X + 0.5f, result.verticies[i].Position.Y + 0.5f); result.verticies[i].Normal = -Vector3.UnitZ; } result.indicies = new short[] { 0, 2, 1, 3, 2, 0 }; return result; }
public static Mesh Invert(Mesh m) { var result = new Mesh(); result.verticies = new Vertex[m.verticies.Length]; result.indicies = new short[m.indicies.Length]; for (short i = 0; i < m.verticies.Length; ++i) { result.verticies[i] = m.verticies[i]; result.verticies[i].Normal *= -1.0f; } for (short i = 0; i < m.indicies.Length; i += 3) { result.indicies[i] = m.indicies[i]; result.indicies[i + 1] = m.indicies[i + 2]; result.indicies[i + 2] = m.indicies[i + 1]; } return result; }