public static SurfaceComponentGeometry CreateDiamondCenterOctaSplitSquareGeometry( float sizeX, float sizeZ, int segmentX, int segmentZ, float diamondRatio = 0.6f, int surfaceGroup = 0, RenderGeometry.FaceType faceType = RenderGeometry.FaceType.Polygonal) { SurfaceComponentGeometry planeGeometry = SurfaceComponentGeometries.CreatePlaneGeometry(sizeX, sizeZ, segmentX, segmentZ); List <Vertex> corners = planeGeometry.corners; var structure = new StructureGeometry(planeGeometry); var edgesToMerge = new List <Halfedge>(); structure.faces.ForEach(f => { var component = CreateSingleDiamondCenterOctaSplitSquareGeometry(1, 1, diamondRatio, surfaceGroup, faceType); edgesToMerge.AddRange(component.boundaries.SelectMany(b => b).Select(e => e.opposite)); structure.SetFaceComponent(f, component, true); }); var geometry = new SurfaceComponentGeometry(structure.Build()); foreach (Halfedge edge in edgesToMerge) { if (edge.index >= 0 && !edge.opposite.isBoundary) { geometry.MergeFaces(edge); } } geometry.DefineBoundaries(corners.Select(structure.GetBuiltVertex).ToArray()); return(geometry); }
public static SurfaceComponentGeometry CreateExtrudedPolygonCapGeometry( float radius, float height, int segmentP, int segmentH, float topRatio = 1, int surfaceGroup = 0, RenderGeometry.FaceType faceType = RenderGeometry.FaceType.Smooth, bool splitBoundary = false) { if (topRatio == 0) { return(CreateConeCapGeometry(radius, height, segmentP, segmentH, 0, surfaceGroup, faceType, splitBoundary)); } if (topRatio == 1 && height == 0) { return(CreateRegularPolygonGeometry(radius, segmentP, surfaceGroup, RenderGeometry.FaceType.Polygonal, true)); } StructureGeometry structure = new StructureGeometry(); SurfaceComponentGeometry upperCap = CreateRegularPolygonGeometry(radius * topRatio, segmentP, surfaceGroup + 1); SurfaceComponentGeometry side = CreateConeSideGeometry(radius, radius * topRatio, height, segmentP, segmentH, 0, false, surfaceGroup, faceType); side.ApplyOffset(Vector3.up * (height / 2)); Vertex cornerUp = structure.CreateVertex(new Vector3(radius * topRatio, height, 0)); Vertex cornerDown = structure.CreateVertex(new Vector3(radius, 0, 0)); structure.CreateFace(side, false, cornerUp, cornerUp, cornerDown, cornerDown); structure.CreateFace(upperCap, true, cornerUp); SurfaceComponentGeometry geometry = new SurfaceComponentGeometry(structure.Build()); geometry.DefineBoundaries(structure.GetBuiltVertex(cornerDown)); if (splitBoundary) { geometry.SplitBoundaries(); } return(geometry); }
private RenderGeometry ReplaceAllFace(RenderGeometry original, Func <Face, SurfaceComponentGeometry> surfaceProvider) { var structure = new StructureGeometry(original); structure.faces.ForEach(f => structure.SetFaceComponent(f, surfaceProvider(f), true)); return(structure.Build()); }
public static RenderGeometry CreateTurningRampGeometry( float width, float height, float angle, float extraRadius, int segmentWidth, int segmentLength, bool smoothWidth, bool smoothLength, RampType rampType = RampType.Right, float curvature = 0, float baseHeight = 0, float highSideWidth = 0, float lowSideWidth = 0) { StructureGeometry structure = new StructureGeometry(); RenderGeometry.FaceType rampFaceType = GetFaceType(smoothWidth, smoothLength); RenderGeometry.FaceType sideFaceType = GetFaceType(false, smoothLength); return(structure.Build()); }
public static RenderGeometry CreateSphereGeometry(float radius, int segmentP, int segmentH, bool smoothH, bool smoothV, float cutTop = 0, float cutBottom = 0) { if (cutTop + cutBottom > 1) { return(new RenderGeometry()); } RenderGeometry.FaceType faceType = GetFaceType(smoothH, smoothV); StructureGeometry structure = new StructureGeometry(); SurfaceComponentGeometry upperPart, lowerPart, middlePart; if (cutTop != 0) { upperPart = SurfaceComponentGeometries.CreateRegularPolygonGeometry(radius * Mathf.Sqrt(4 * cutTop * (1 - cutTop)), segmentP, 2); upperPart.ApplyOffset(radius * (1 - 2 * cutTop) * Vector3.up); } else { float angle = cutBottom != 0 ? Mathf.Acos(-1 + cutBottom * 2) : Mathf.PI * (segmentH / 2) / segmentH; upperPart = SurfaceComponentGeometries.CreateSphereCapGeometry(radius, segmentP, cutBottom != 0 ? segmentH : segmentH / 2, 2 * angle, 0, 1, faceType); } if (cutBottom != 0) { lowerPart = SurfaceComponentGeometries.CreateRegularPolygonGeometry(radius * Mathf.Sqrt(4 * cutBottom * (1 - cutBottom)), segmentP, 2); lowerPart.ApplyOffset(radius * (1 - 2 * cutBottom) * Vector3.up); lowerPart.ApplyRotation(Quaternion.AngleAxis(180, Vector3.right)); } else { float angle = cutTop != 0 ? Mathf.Acos(-1 + cutTop * 2) : Mathf.PI * ((segmentH + 1) / 2) / segmentH; lowerPart = SurfaceComponentGeometries.CreateSphereCapGeometry(radius, segmentP, cutTop != 0 ? segmentH : (segmentH + 1) / 2, 2 * angle, 0, 1, faceType); lowerPart.ApplyRotation(Quaternion.AngleAxis(180, Vector3.right)); } if (cutTop != 0 && cutBottom != 0) { float angle1 = Mathf.Acos(1 - cutTop * 2); float angle2 = Mathf.Acos(-1 + cutBottom * 2); middlePart = SurfaceComponentGeometries.CreateSphereSideGeometry(radius, angle1, angle2, segmentP, segmentH, 0, 1, faceType); Vertex cornerUp = structure.CreateVertex(); Vertex cornerDown = structure.CreateVertex(); structure.CreateFace(middlePart, false, cornerUp, cornerUp, cornerDown, cornerDown); structure.CreateFace(upperPart, false, cornerUp); structure.CreateFace(lowerPart, false, cornerDown); } else { Vertex corner = structure.CreateVertex(); structure.CreateFace(upperPart, false, corner); structure.CreateFace(lowerPart, false, corner); } return(structure.Build()); }
public static SurfaceComponentGeometry CreateSplitTriangleGeometry( float sizeBase, float sizeHeight, float offsetTop, int segment, int surfaceGroup = 0, RenderGeometry.FaceType faceType = RenderGeometry.FaceType.Polygonal) { SurfaceComponentGeometry triangleGeometry = SurfaceComponentGeometries.CreateTriangleGeometry(sizeBase, sizeHeight, offsetTop, segment, false); List <Vertex> corners = triangleGeometry.corners; var structure = new StructureGeometry(triangleGeometry); structure.faces.ForEach(f => structure.SetFaceComponent(f, CreateSingleSplitTriangleGeometry(1, 1, 0, surfaceGroup, faceType), true)); var geometry = new SurfaceComponentGeometry(structure.Build()); geometry.DefineBoundaries(corners.Select(structure.GetBuiltVertex).ToArray()); return(geometry); }
public static SurfaceComponentGeometry CreateDiamondCenterCrossSplitSquareGeometry( float sizeX, float sizeZ, int segmentX, int segmentZ, float diamondRatio = 0.6f, int surfaceGroup = 0, RenderGeometry.FaceType faceType = RenderGeometry.FaceType.Polygonal) { SurfaceComponentGeometry planeGeometry = SurfaceComponentGeometries.CreatePlaneGeometry(sizeX, sizeZ, segmentX, segmentZ); List <Vertex> corners = planeGeometry.corners; var structure = new StructureGeometry(planeGeometry); structure.faces.ForEach(f => structure.SetFaceComponent(f, CreateSingleDiamondCenterCrossSplitSquareGeometry(1, 1, diamondRatio, surfaceGroup, faceType), true)); var geometry = new SurfaceComponentGeometry(structure.Build()); geometry.DefineBoundaries(corners.Select(structure.GetBuiltVertex).ToArray()); return(geometry); }
private static RenderGeometry CreateTetrahedronGeometryInternal(float size, Func <SurfaceComponentGeometry> surfaceGenerator) { StructureGeometry structure = new StructureGeometry(); Vertex v1 = structure.CreateVertex(new Vector3(-1, -1, 1) * (size / 2)); Vertex v2 = structure.CreateVertex(new Vector3(-1, 1, -1) * (size / 2)); Vertex v3 = structure.CreateVertex(new Vector3(1, -1, -1) * (size / 2)); Vertex v4 = structure.CreateVertex(new Vector3(1, 1, 1) * (size / 2)); structure.CreateFace(surfaceGenerator.Invoke(), true, v1, v2, v3); structure.CreateFace(surfaceGenerator.Invoke(), true, v1, v4, v2); structure.CreateFace(surfaceGenerator.Invoke(), true, v2, v4, v3); structure.CreateFace(surfaceGenerator.Invoke(), true, v3, v4, v1); return(structure.Build()); }
public static SurfaceComponentGeometry CreateTrianglesCombinedRegularPolygonGeometry(float radius, int segmentP, Func <SurfaceComponentGeometry> triangleSurfaceComponentProvider) { SurfaceComponentGeometry polygonGeometry = SurfaceComponentGeometries.CreateFanCapGeometry(radius, segmentP, 1); polygonGeometry.SplitBoundaries(); List <Vertex> corners = polygonGeometry.corners; var structure = new StructureGeometry(polygonGeometry); structure.faces.ForEach(f => structure.SetFaceComponent(f, triangleSurfaceComponentProvider(), true)); var geometry = new SurfaceComponentGeometry(structure.Build()); geometry.DefineBoundaries(corners.Select(structure.GetBuiltVertex).ToArray()); return(geometry); }
private static RenderGeometry CreateOctahedronGeometryInternal(float size, Func <SurfaceComponentGeometry> surfaceGenerator) { StructureGeometry structure = new StructureGeometry(); var corners = new Dictionary <IntVector3, Vertex>(); foreach (var keyAndPosition in VertexSymmetryGroup("100", Key(1, 0, 0), Vector3.right * (size / 2))) { corners[keyAndPosition.Key] = structure.CreateVertex(keyAndPosition.Value); } foreach (IntVector3[] keys in FaceSymmetryGroup("111", Key(1, 0, 0), Key(0, 1, 0), Key(0, 0, 1))) { structure.CreateFace(surfaceGenerator.Invoke(), true, keys.Select(key => corners[key]).ToArray()); } return(structure.Build()); }
public static RenderGeometry CreateConeGeometry(float radius, float height, int segmentP, int segmentH, bool smoothH, bool smoothV, float cutTop = 0, float cutAngle = 0) { if (cutTop == 0) { StructureGeometry structure = new StructureGeometry(); RenderGeometry.FaceType faceType = GetFaceType(smoothH, smoothV); SurfaceComponentGeometry coneCap = SurfaceComponentGeometries.CreateConeCapGeometry(radius, height, segmentP, segmentH, cutAngle, 1, faceType); if (cutAngle == 0) { SurfaceComponentGeometry bottom = SurfaceComponentGeometries.CreateRegularPolygonGeometry(radius, segmentP, 2); bottom.ApplyRotation(Quaternion.AngleAxis(180, Vector3.right)); Vertex corner = structure.CreateVertex(); structure.CreateFace(coneCap, false, corner); structure.CreateFace(bottom, false, corner); } else { SurfaceComponentGeometry bottom = SurfaceComponentGeometries.CreateFanCapGeometry(radius, segmentP, 1, cutAngle, 2); SurfaceComponentGeometry wall1 = SurfaceComponentGeometries.CreateTriangleGeometry(1, 1, 0, segmentH, true, 3); SurfaceComponentGeometry wall2 = SurfaceComponentGeometries.CreateTriangleGeometry(1, 1, 0, segmentH, true, 4); Vertex cornerUp = structure.CreateVertex(new Vector3(0, height, 0)); Vertex cornerDownC = structure.CreateVertex(Vector3.zero); Vertex cornerDown1 = structure.CreateVertex(new Vector3(radius * Mathf.Cos(cutAngle), 0, -radius * Mathf.Sin(cutAngle))); Vertex cornerDown2 = structure.CreateVertex(new Vector3(radius, 0, 0)); structure.CreateFace(coneCap, true, cornerDown1, cornerDown2, cornerUp); structure.CreateFace(bottom, true, cornerDown2, cornerDown1, cornerDownC); structure.CreateFace(wall1, true, cornerDown1, cornerUp, cornerDownC); structure.CreateFace(wall2, true, cornerDownC, cornerUp, cornerDown2); } return(structure.Build()); } else { RenderGeometry geometry = CreateCylinderGeometry(radius, height, segmentP, segmentH, smoothH, smoothV, cutAngle); geometry.ApplyOffset(Vector3.up * (height / 2)); float shrinkCoeff = (1 - cutTop) / height; SpaceWarp warp = new SpaceWarp($"x*(1-y*{shrinkCoeff})", "y", $"z*(1-y*{shrinkCoeff})"); geometry.ApplySpaceWarp(warp); return(geometry); } }
private static RenderGeometry CreateCubeGeometryInternal(Vector3 size, Func <int, SurfaceComponentGeometry> surfaceGenerator) { StructureGeometry structure = new StructureGeometry(); var corners = new Dictionary <IntVector3, Vertex>(); foreach (var keyAndPosition in VertexSymmetryGroup("111", Key(1, 1, 1), Vector3.one)) { corners[keyAndPosition.Key] = structure.CreateVertex(keyAndPosition.Value.Times(size / 2)); } foreach (Symmetry symmetry in Symmetry.SymmetryGroup("100")) { Vertex[] verts = symmetry.Apply(Key(1, -1, -1), Key(1, 1, -1), Key(1, 1, 1), Key(1, -1, 1)).Select(key => corners[key]).ToArray(); structure.CreateFace(surfaceGenerator.Invoke(symmetry.rotation), true, verts); } return(structure.Build()); }
public static RenderGeometry CreateSpringGeometry(float ringRadius, float barRadius, float heightPerCycle, int segmentPerCycle, int segmentBar, bool smoothH, bool smoothV, float angle = 0, float deltaAngle = 0) { StructureGeometry structure = new StructureGeometry(); RenderGeometry.FaceType faceType = GetFaceType(smoothH, smoothV); float heightPerRad = heightPerCycle / (2 * Mathf.PI); float slope = heightPerRad / ringRadius; float scaleH = Mathf.Sqrt(1 + slope * slope); int segmentRing = Mathf.CeilToInt(segmentPerCycle * angle / (2 * Mathf.PI) - 1e-6f); SurfaceComponentGeometry face = SurfaceComponentGeometries.CreatePlaneGeometry(1, 1, segmentBar, segmentRing, 1, faceType); var warp = new SpaceWarp( $" a1=(z+0.5)*{angle}", $" a2={deltaAngle}-x*(2*PI)", $" r={ringRadius}+{barRadius}*cos(a2)", $" X=r*cos(a1)", $" Y={scaleH}*{barRadius}*sin(a2)+a1*{heightPerRad}", $" Z=r*sin(a1)" ); face.ApplySpaceWarp(warp); SurfaceComponentGeometry cap1 = SurfaceComponentGeometries.CreateRegularPolygonGeometry(barRadius, segmentBar, 2); SurfaceComponentGeometry cap2 = SurfaceComponentGeometries.CreateRegularPolygonGeometry(barRadius, segmentBar, 2); cap1.ApplyLinearTransform( Matrix4x4.Translate(Vector3.right * ringRadius) * Matrix4x4.Scale(new Vector3(1, scaleH, 1)) * Matrix4x4.Rotate(Quaternion.LookRotation(Vector3.down, Vector3.back) * Quaternion.AngleAxis(-deltaAngle * Mathf.Rad2Deg, Vector3.up))); cap2.ApplyLinearTransform( Matrix4x4.Translate(new Vector3(ringRadius * Mathf.Cos(angle), heightPerRad * angle, ringRadius * Mathf.Sin(angle))) * Matrix4x4.Scale(new Vector3(1, scaleH, 1)) * Matrix4x4.Rotate(Quaternion.LookRotation(Vector3.up, Quaternion.AngleAxis(angle * Mathf.Rad2Deg, Vector3.down) * Vector3.forward) * Quaternion.AngleAxis(deltaAngle * Mathf.Rad2Deg, Vector3.up))); Vertex corner1 = structure.CreateVertex(); Vertex corner2 = structure.CreateVertex(); structure.CreateFace(face, false, corner1, corner2, corner2, corner1); structure.CreateFace(cap1, false, corner1); structure.CreateFace(cap2, false, corner2); return(structure.Build()); }
public static SurfaceComponentGeometry CreateXSplitSquareGeometry( float sizeX, float sizeZ, int segmentX, int segmentZ, float spikeHeight = 0, int surfaceGroup = 0, RenderGeometry.FaceType faceType = RenderGeometry.FaceType.Polygonal) { var planeGeometry = SurfaceComponentGeometries.CreatePlaneGeometry(sizeX, sizeZ, segmentX, segmentZ); List <Vertex> corners = planeGeometry.corners; var structure = new StructureGeometry(planeGeometry); var coneHeight = spikeHeight / (sizeZ / segmentZ) * Mathf.Sqrt(2); structure.faces.ForEach(f => { var component = SurfaceComponentGeometries.CreateConeCapGeometry(1, coneHeight, 4, 1, 0, surfaceGroup, faceType); component.SplitBoundaries(); structure.SetFaceComponent(f, component, true); }); var geometry = new SurfaceComponentGeometry(structure.Build()); geometry.DefineBoundaries(corners.Select(structure.GetBuiltVertex).ToArray()); return(geometry); }
public static RenderGeometry CreateTorusGeometry(float ringRadius, float barRadius, int segmentRing, int segmentBar, bool smoothH, bool smoothV, float cutAngle = 0, float deltaAngle = 0) { StructureGeometry structure = new StructureGeometry(); RenderGeometry.FaceType faceType = GetFaceType(smoothH, smoothV); SurfaceComponentGeometry face = SurfaceComponentGeometries.CreatePlaneGeometry(1, 1, segmentBar, segmentRing, 1, faceType); var warp = new SpaceWarp( $" a1=(z+0.5)*(2*PI-{cutAngle})", $" a2={deltaAngle}-x*(2*PI)", $" r={ringRadius}+{barRadius}*cos(a2)", $" X=r*cos(a1)", $" Y={barRadius}*sin(a2)", $" Z=r*sin(a1)" ); face.ApplySpaceWarp(warp); if (cutAngle == 0) { Vertex corner = structure.CreateVertex(); structure.CreateFace(face, false, corner, corner, corner, corner); } else { SurfaceComponentGeometry cap1 = SurfaceComponentGeometries.CreateRegularPolygonGeometry(barRadius, segmentBar, 2); SurfaceComponentGeometry cap2 = SurfaceComponentGeometries.CreateRegularPolygonGeometry(barRadius, segmentBar, 2); cap1.ApplyRotation(Quaternion.LookRotation(Vector3.down, Vector3.back) * Quaternion.AngleAxis(-deltaAngle, Vector3.up)); cap1.ApplyOffset(Vector3.right * ringRadius); cap2.ApplyRotation(Quaternion.LookRotation(Vector3.up, Quaternion.AngleAxis(cutAngle * Mathf.Rad2Deg, Vector3.up) * Vector3.forward) * Quaternion.AngleAxis(deltaAngle * Mathf.Rad2Deg, Vector3.up)); cap2.ApplyOffset(new Vector3(ringRadius * Mathf.Cos(cutAngle), 0, -ringRadius * Mathf.Sin(cutAngle))); Vertex corner1 = structure.CreateVertex(); Vertex corner2 = structure.CreateVertex(); structure.CreateFace(face, false, corner1, corner2, corner2, corner1); structure.CreateFace(cap1, false, corner1); structure.CreateFace(cap2, false, corner2); } return(structure.Build()); }
public static RenderGeometry CreateCapsuleGeometry(float radius, float height, int segmentP, int segmentH1, int segmentH2, bool smoothH, bool smoothV) { StructureGeometry structure = new StructureGeometry(); RenderGeometry.FaceType faceType = GetFaceType(smoothH, smoothV); SurfaceComponentGeometry side = SurfaceComponentGeometries.CreateCylinderSideGeometry(radius, height, segmentP, segmentH1, faceType: faceType); SurfaceComponentGeometry upperCap = SurfaceComponentGeometries.CreateSphereCapGeometry(radius, segmentP, segmentH2, faceType: faceType); SurfaceComponentGeometry lowerCap = SurfaceComponentGeometries.CreateSphereCapGeometry(radius, segmentP, segmentH2, faceType: faceType); lowerCap.ApplyRotation(Quaternion.AngleAxis(180, Vector3.right)); Vertex cornerUp = structure.CreateVertex(new Vector3(radius, height / 2, 0)); Vertex cornerDown = structure.CreateVertex(new Vector3(radius, -height / 2, 0)); structure.CreateFace(side, false, cornerUp, cornerUp, cornerDown, cornerDown); structure.CreateFace(upperCap, true, cornerUp); structure.CreateFace(lowerCap, true, cornerDown); return(structure.Build()); }
private static RenderGeometry CreateIcosahedronGeometryInternal(float size, Func <SurfaceComponentGeometry> surfaceGenerator) { StructureGeometry structure = new StructureGeometry(); float goldenRatio = (1 + Mathf.Sqrt(5)) / 2; float dL = size / 2; float dS = dL / goldenRatio; var corners = new Dictionary <IntVector3, Vertex>(); foreach (var keyAndPosition in VertexSymmetryGroup("110", Key(1, 1, 0), Vec(dL, dS, 0))) { corners[keyAndPosition.Key] = structure.CreateVertex(keyAndPosition.Value); } foreach (IntVector3[] keys in Combine( FaceSymmetryGroup("101", Key(1, 1, 0), Key(1, 0, 1), Key(1, -1, 0)), FaceSymmetryGroup("111", Key(1, 1, 0), Key(0, 1, 1), Key(1, 0, 1)))) { structure.CreateFace(surfaceGenerator.Invoke(), true, keys.Select(key => corners[key]).ToArray()); } return(structure.Build()); }
public static RenderGeometry CreateCylinderGeometry(float radius, float height, int segmentP, int segmentH, bool smoothH, bool smoothV, float cutAngle = 0, float hollowRatio = 0) { StructureGeometry structure = new StructureGeometry(); RenderGeometry.FaceType faceType = GetFaceType(smoothH, smoothV); float hollowRadius = hollowRatio * radius; SurfaceComponentGeometry side = SurfaceComponentGeometries.CreateCylinderSideGeometry(radius, height, segmentP, segmentH, cutAngle, false, 1, faceType); SurfaceComponentGeometry sideInner = null; if (hollowRatio > 0) { sideInner = SurfaceComponentGeometries.CreateCylinderSideGeometry(hollowRadius, height, segmentP, segmentH, cutAngle, true, 1, faceType); } SurfaceComponentGeometry upperCap, lowerCap; if (hollowRatio > 0) { upperCap = SurfaceComponentGeometries.CreateRingCapGeometry(radius, hollowRadius, segmentP, 1, cutAngle, 2); lowerCap = SurfaceComponentGeometries.CreateRingCapGeometry(radius, hollowRadius, segmentP, 1, cutAngle, 2); } else if (cutAngle == 0) { upperCap = SurfaceComponentGeometries.CreateRegularPolygonGeometry(radius, segmentP, 2); lowerCap = SurfaceComponentGeometries.CreateRegularPolygonGeometry(radius, segmentP, 2); } else { upperCap = SurfaceComponentGeometries.CreateFanCapGeometry(radius, segmentP, 1, cutAngle, 2); lowerCap = SurfaceComponentGeometries.CreateFanCapGeometry(radius, segmentP, 1, cutAngle, 2); } lowerCap.ApplyRotation(Quaternion.AngleAxis(cutAngle * Mathf.Rad2Deg, Vector3.up) * Quaternion.AngleAxis(180, Vector3.right)); if (cutAngle == 0) { Vertex cornerUp = structure.CreateVertex(new Vector3(radius, height / 2, 0)); Vertex cornerDown = structure.CreateVertex(new Vector3(radius, -height / 2, 0)); if (hollowRatio == 0) { structure.CreateFace(side, false, cornerUp, cornerUp, cornerDown, cornerDown); structure.CreateFace(upperCap, true, cornerUp); structure.CreateFace(lowerCap, true, cornerDown); } else { Vertex cornerUpInner = structure.CreateVertex(new Vector3(hollowRadius, height / 2, 0)); Vertex cornerDownInner = structure.CreateVertex(new Vector3(hollowRadius, -height / 2, 0)); structure.CreateFace(side, false, cornerUp, cornerUp, cornerDown, cornerDown); structure.CreateFace(sideInner, false, cornerDownInner, cornerDownInner, cornerUpInner, cornerUpInner); structure.CreateFace(upperCap, true, cornerUpInner, cornerUpInner, cornerUp, cornerUp); structure.CreateFace(lowerCap, true, cornerDownInner, cornerDownInner, cornerDown, cornerDown); } } else { SurfaceComponentGeometry wall1 = SurfaceComponentGeometries.CreatePlaneGeometry(1, 1, 1, segmentH, 3); SurfaceComponentGeometry wall2 = SurfaceComponentGeometries.CreatePlaneGeometry(1, 1, 1, segmentH, 4); Vertex cornerUp1 = structure.CreateVertex(new Vector3(radius * Mathf.Cos(cutAngle), height / 2, -radius * Mathf.Sin(cutAngle))); Vertex cornerUp2 = structure.CreateVertex(new Vector3(radius, height / 2, 0)); Vertex cornerDown1 = structure.CreateVertex(new Vector3(radius * Mathf.Cos(cutAngle), -height / 2, -radius * Mathf.Sin(cutAngle))); Vertex cornerDown2 = structure.CreateVertex(new Vector3(radius, -height / 2, 0)); if (hollowRatio == 0) { Vertex cornerUpC = structure.CreateVertex(new Vector3(0, height / 2, 0)); Vertex cornerDownC = structure.CreateVertex(new Vector3(0, -height / 2, 0)); structure.CreateFace(side, false, cornerUp2, cornerUp1, cornerDown1, cornerDown2); structure.CreateFace(upperCap, true, cornerUp1, cornerUp2, cornerUpC); structure.CreateFace(lowerCap, true, cornerDown2, cornerDown1, cornerDownC); structure.CreateFace(wall1, true, cornerUpC, cornerDownC, cornerDown1, cornerUp1); structure.CreateFace(wall2, true, cornerDownC, cornerUpC, cornerUp2, cornerDown2); } else { Vertex cornerUp1Inner = structure.CreateVertex(new Vector3(hollowRadius * Mathf.Cos(cutAngle), height / 2, -hollowRadius * Mathf.Sin(cutAngle))); Vertex cornerUp2Inner = structure.CreateVertex(new Vector3(hollowRadius, height / 2, 0)); Vertex cornerDown1Inner = structure.CreateVertex(new Vector3(hollowRadius * Mathf.Cos(cutAngle), -height / 2, -hollowRadius * Mathf.Sin(cutAngle))); Vertex cornerDown2Inner = structure.CreateVertex(new Vector3(hollowRadius, -height / 2, 0)); structure.CreateFace(side, false, cornerUp2, cornerUp1, cornerDown1, cornerDown2); structure.CreateFace(sideInner, false, cornerDown2Inner, cornerDown1Inner, cornerUp1Inner, cornerUp2Inner); structure.CreateFace(upperCap, true, cornerUp2Inner, cornerUp1Inner, cornerUp1, cornerUp2); structure.CreateFace(lowerCap, true, cornerDown1Inner, cornerDown2Inner, cornerDown2, cornerDown1); structure.CreateFace(wall1, true, cornerUp1Inner, cornerDown1Inner, cornerDown1, cornerUp1); structure.CreateFace(wall2, true, cornerDown2Inner, cornerUp2Inner, cornerUp2, cornerDown2); } } return(structure.Build()); }
public static RenderGeometry CreateStraightRampGeometry( float width, float height, float length, int segmentWidth, int segmentLength, bool smoothWidth, bool smoothLength, RampType rampType = RampType.Right, float curvature = 0, float baseHeight = 0, float highPlatformWidth = 0, float lowPlatformWidth = 0) { StructureGeometry structure = new StructureGeometry(); RenderGeometry.FaceType rampFaceType = GetFaceType(smoothWidth, smoothLength); RenderGeometry.FaceType sideFaceType = GetFaceType(false, smoothLength); float leftPlatformHeight = (rampType == RampType.Left || rampType == RampType.Peak ? 0 : height) + baseHeight; float rightPlatformHeight = (rampType == RampType.Right || rampType == RampType.Peak ? 0 : height) + baseHeight; float middlePlatformHeight = (rampType == RampType.Valley ? 0 : height) + baseHeight; float leftPlatformWidth = ((rampType == RampType.Left || rampType == RampType.Peak) ? lowPlatformWidth : highPlatformWidth); float rightPlatformWidth = ((rampType == RampType.Right || rampType == RampType.Peak) ? lowPlatformWidth : highPlatformWidth); float middlePlatformWidth = (rampType == RampType.Valley ? lowPlatformWidth : (rampType == RampType.Peak ? highPlatformWidth : 0)); float leftX = -width / 2 - middlePlatformWidth / 2; float rightX = width / 2 + middlePlatformWidth / 2; bool isLeftTopAndBottomSameVertex = (rampType == RampType.Left || rampType == RampType.Peak) && baseHeight == 0; bool isRightTopAndBottomSameVertex = (rampType == RampType.Right || rampType == RampType.Peak) && baseHeight == 0; Vertex cornerBottomLeft1 = structure.CreateVertex(new Vector3(leftX, 0, -length / 2)); Vertex cornerBottomLeft2 = structure.CreateVertex(new Vector3(leftX, 0, length / 2)); Vertex cornerBottomRight1 = structure.CreateVertex(new Vector3(rightX, 0, -length / 2)); Vertex cornerBottomRight2 = structure.CreateVertex(new Vector3(rightX, 0, length / 2)); Vertex cornerTopLeft1 = isLeftTopAndBottomSameVertex ? cornerBottomLeft1 : structure.CreateVertex(new Vector3(leftX, leftPlatformHeight, -length / 2)); Vertex cornerTopLeft2 = isLeftTopAndBottomSameVertex ? cornerBottomLeft2 : structure.CreateVertex(new Vector3(leftX, leftPlatformHeight, length / 2)); Vertex cornerTopRight1 = isRightTopAndBottomSameVertex ? cornerBottomRight1 : structure.CreateVertex(new Vector3(rightX, rightPlatformHeight, -length / 2)); Vertex cornerTopRight2 = isRightTopAndBottomSameVertex ? cornerBottomRight2 : structure.CreateVertex(new Vector3(rightX, rightPlatformHeight, length / 2)); if (rampType == RampType.Left || rampType == RampType.Right) { CreateStraightRampPart( structure, rampType == RampType.Left, cornerTopLeft1, cornerTopLeft2, cornerTopRight1, cornerTopRight2, cornerBottomLeft1, cornerBottomLeft2, cornerBottomRight1, cornerBottomRight2, leftPlatformWidth == 0, rightPlatformWidth == 0, segmentWidth, segmentLength, curvature, rampFaceType, sideFaceType); } else { bool isMiddleTopAndBottomSameVertex = rampType == RampType.Valley && baseHeight == 0; bool isMiddleLeftAndRightSameVertex = middlePlatformWidth == 0 && !isMiddleTopAndBottomSameVertex; Vertex cornerBottomMiddleLeft1 = structure.CreateVertex(new Vector3(-middlePlatformWidth / 2, 0, -length / 2)); Vertex cornerBottomMiddleLeft2 = structure.CreateVertex(new Vector3(-middlePlatformWidth / 2, 0, length / 2)); Vertex cornerBottomMiddleRight1 = isMiddleLeftAndRightSameVertex ? cornerBottomMiddleLeft1 : structure.CreateVertex(new Vector3(middlePlatformWidth / 2, 0, -length / 2)); Vertex cornerBottomMiddleRight2 = isMiddleLeftAndRightSameVertex ? cornerBottomMiddleLeft2 : structure.CreateVertex(new Vector3(middlePlatformWidth / 2, 0, length / 2)); Vertex cornerTopMiddleLeft1 = isMiddleTopAndBottomSameVertex ? cornerBottomMiddleLeft1 : structure.CreateVertex(new Vector3(-middlePlatformWidth / 2, middlePlatformHeight, -length / 2)); Vertex cornerTopMiddleLeft2 = isMiddleTopAndBottomSameVertex ? cornerBottomMiddleLeft2 : structure.CreateVertex(new Vector3(-middlePlatformWidth / 2, middlePlatformHeight, length / 2)); Vertex cornerTopMiddleRight1 = isMiddleTopAndBottomSameVertex ? cornerBottomMiddleRight1 : structure.CreateVertex(new Vector3(middlePlatformWidth / 2, middlePlatformHeight, -length / 2)); Vertex cornerTopMiddleRight2 = isMiddleTopAndBottomSameVertex ? cornerBottomMiddleRight2 : structure.CreateVertex(new Vector3(middlePlatformWidth / 2, middlePlatformHeight, length / 2)); CreateStraightRampPart( structure, rampType == RampType.Peak, cornerTopLeft1, cornerTopLeft2, cornerTopMiddleLeft1, cornerTopMiddleLeft2, cornerBottomLeft1, cornerBottomLeft2, cornerBottomMiddleLeft1, cornerBottomMiddleLeft2, leftPlatformWidth == 0, false, segmentWidth, segmentLength, curvature, rampFaceType, sideFaceType); CreateStraightRampPart( structure, rampType == RampType.Valley, cornerTopMiddleRight1, cornerTopMiddleRight2, cornerTopRight1, cornerTopRight2, cornerBottomMiddleRight1, cornerBottomMiddleRight2, cornerBottomRight1, cornerBottomRight2, false, rightPlatformWidth == 0, segmentWidth, segmentLength, curvature, rampFaceType, sideFaceType); if (middlePlatformWidth > 0) { CreateStraightPlatformPart( structure, cornerTopMiddleLeft1, cornerTopMiddleLeft2, cornerTopMiddleRight1, cornerTopMiddleRight2, cornerBottomMiddleLeft1, cornerBottomMiddleLeft2, cornerBottomMiddleRight1, cornerBottomMiddleRight2, false, false, segmentLength, sideFaceType); } } if (leftPlatformWidth > 0) { Vertex cornerBottomFarLeft1 = structure.CreateVertex(cornerBottomLeft1.p + leftPlatformWidth * Vector3.left); Vertex cornerBottomFarLeft2 = structure.CreateVertex(cornerBottomLeft2.p + leftPlatformWidth * Vector3.left); Vertex cornerTopFarLeft1 = cornerTopLeft1 == cornerBottomLeft1 ? cornerBottomFarLeft1 : structure.CreateVertex(cornerTopLeft1.p + leftPlatformWidth * Vector3.left); Vertex cornerTopFarLeft2 = cornerTopLeft2 == cornerBottomLeft2 ? cornerBottomFarLeft2 : structure.CreateVertex(cornerTopLeft2.p + leftPlatformWidth * Vector3.left); CreateStraightPlatformPart( structure, cornerTopFarLeft1, cornerTopFarLeft2, cornerTopLeft1, cornerTopLeft2, cornerBottomFarLeft1, cornerBottomFarLeft2, cornerBottomLeft1, cornerBottomLeft2, true, false, segmentLength, sideFaceType); } if (rightPlatformWidth > 0) { Vertex cornerBottomFarRight1 = structure.CreateVertex(cornerBottomRight1.p + rightPlatformWidth * Vector3.right); Vertex cornerBottomFarRight2 = structure.CreateVertex(cornerBottomRight2.p + rightPlatformWidth * Vector3.right); Vertex cornerTopFarRight1 = cornerTopRight1 == cornerBottomRight1 ? cornerBottomFarRight1 : structure.CreateVertex(cornerTopRight1.p + rightPlatformWidth * Vector3.right); Vertex cornerTopFarRight2 = cornerTopRight2 == cornerBottomRight2 ? cornerBottomFarRight2 : structure.CreateVertex(cornerTopRight2.p + rightPlatformWidth * Vector3.right); CreateStraightPlatformPart( structure, cornerTopRight1, cornerTopRight2, cornerTopFarRight1, cornerTopFarRight2, cornerBottomRight1, cornerBottomRight2, cornerBottomFarRight1, cornerBottomFarRight2, false, true, segmentLength, sideFaceType); } return(structure.Build()); }