private ProceduralShape AddSkirt(ref VertexPositionColorTextureNormal[] vertices, ref List <int> topEdges, ProceduralShape spherePatch, bool insideOut) { ProceduralShapeBuilder builder = new ProceduralShapeBuilder(); float skirtSize = 10f; float offset = 0; for (int i = 0; i < topEdges.Count - 1; i++) { Vector3 point = vertices[topEdges[i]].Position; Vector3 toCenter = Vector3.Normalize(-point); Vector3 lowPoint = point + toCenter * skirtSize; point += toCenter * offset; lowPoint += toCenter * offset; Vector3 point2 = vertices[topEdges[i + 1]].Position; Vector3 toCenter2 = Vector3.Normalize(-point2); Vector3 lowPoint2 = point2 + toCenter2 * skirtSize; point2 += toCenter2 * offset; lowPoint2 += toCenter2 * offset; builder.AddFaceWithColor(vertices[topEdges[i]].Color, point, point2, lowPoint2, lowPoint); } var skirt = builder.BakeShape(); if (insideOut) { skirt.InsideOut(); } spherePatch = ProceduralShape.Combine(spherePatch, skirt); return(spherePatch); }
/// <summary> /// Builds a composite shape composed of a cylinder and two spheres. /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="width"></param> /// <returns></returns> public static ProceduralShape Capsule(Vector3 start, Vector3 end, float width) { ProceduralSphereTwo s = new ProceduralSphereTwo(20); ProceduralSphereTwo e = new ProceduralSphereTwo(20); s.Scale(width); e.Scale(width); Vector3 translation = Vector3.Zero - ((start + end) / 2); //untranslated cylinder will have a centroid at zero, a bottom point at (0,-length/2,0) and a top point at (0,length/2,0). // we want to find the transform that takes these points to our desired start + end. Vector3 length = start - end; float l = length.Length(); Vector3 oldBottom = new Vector3(0, -l / 2, 0); Vector3 oldTop = new Vector3(0, l / 2, 0); s.Translate(oldBottom); e.Translate(oldTop); Vector3 oldLength = oldBottom - oldTop; Vector3 crossAxis = Vector3.Cross(Vector3.Normalize(oldLength), Vector3.Normalize(length)); ProceduralCylinder cylinder = new ProceduralCylinder(width, width, l, 20, 2); var finalShape = ProceduralShape.Combine(cylinder, s, e); if (crossAxis != Vector3.Zero) { float angleOfRotation = (float)MonoMathHelper.GetSignedAngleBetween2DVectors(oldLength, length); Matrix rotation = Matrix.CreateFromAxisAngle(Vector3.Normalize(crossAxis), angleOfRotation); finalShape.Transform(rotation); } finalShape.Translate(-translation); return(finalShape); }
public static ProceduralShape CapsuleCube() { var cube = new ProceduralCube(); var cyl1 = Capsule(new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(0.5f, 0.5f, 0.5f), 0.01f); var cyl2 = Capsule(new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(0.5f, 0.5f, -0.5f), 0.01f); var cyl3 = Capsule(new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, -0.5f), 0.01f); var cyl4 = Capsule(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(0.5f, 0.5f, -0.5f), 0.01f); var cyl5 = Capsule(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f), 0.01f); var cyl6 = Capsule(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(0.5f, -0.5f, -0.5f), 0.01f); var cyl7 = Capsule(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(-0.5f, -0.5f, -0.5f), 0.01f); var cyl8 = Capsule(new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, -0.5f), 0.01f); var cyl9 = Capsule(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f), 0.01f); var cyl10 = Capsule(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(-0.5f, 0.5f, -0.5f), 0.01f); var cyl11 = Capsule(new Vector3(0.5f, -0.5f, -0.5f), new Vector3(0.5f, 0.5f, -0.5f), 0.01f); var cyl12 = Capsule(new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, 0.5f, 0.5f), 0.01f); var finalShape = ProceduralShape.Combine(cube, cyl1, cyl2, cyl3, cyl4, cyl5, cyl6, cyl7, cyl8, cyl9, cyl10, cyl11, cyl12); return(finalShape); }