public bool GenerateNodes(ChiselBlobAssetReference <NativeChiselSurfaceDefinition> surfaceDefinitionBlob, NativeList <GeneratedNode> nodes, Allocator allocator) { var generatedBrushMeshes = new NativeList <ChiselBlobAssetReference <BrushMeshBlob> >(nodes.Length, Allocator.Temp); try { generatedBrushMeshes.Resize(nodes.Length, NativeArrayOptions.ClearMemory); if (!BrushMeshFactory.GenerateSpiralStairs(generatedBrushMeshes, ref this, in surfaceDefinitionBlob, allocator)) { for (int i = 0; i < generatedBrushMeshes.Length; i++) { if (generatedBrushMeshes[i].IsCreated) { generatedBrushMeshes[i].Dispose(); } generatedBrushMeshes[i] = default; } return(false); } for (int i = 0; i < generatedBrushMeshes.Length; i++) { nodes[i] = GeneratedNode.GenerateBrush(generatedBrushMeshes[i]); } // TODO: clean this up { var subMeshIndex = TreadStart - CylinderSubMeshCount; var node = nodes[subMeshIndex]; node.operation = CSGOperationType.Intersecting; nodes[subMeshIndex] = node; subMeshIndex = RequiredSubMeshCount - CylinderSubMeshCount; node = nodes[subMeshIndex]; node.operation = CSGOperationType.Intersecting; nodes[subMeshIndex] = node; } if (HaveInnerCylinder) { var subMeshIndex = TreadStart - 1; var node = nodes[subMeshIndex]; node.operation = CSGOperationType.Subtractive; nodes[subMeshIndex] = node; subMeshIndex = RequiredSubMeshCount - 1; node = nodes[subMeshIndex]; node.operation = CSGOperationType.Subtractive; nodes[subMeshIndex] = node; } return(true); } finally { generatedBrushMeshes.Dispose(); } }
public static bool GenerateCapsule(ref ChiselBrushContainer brushContainer, ref ChiselCapsuleDefinition definition) { definition.Validate(); Vector3[] vertices = null; if (!BrushMeshFactory.GenerateCapsuleVertices(ref definition, ref vertices)) { return(false); } // TODO: share this with GenerateCapsuleVertices var bottomCap = !definition.haveRoundedBottom; var topCap = !definition.haveRoundedTop; var sides = definition.sides; var segments = definition.segments; var bottomVertex = definition.bottomVertex; var topVertex = definition.topVertex; brushContainer.EnsureSize(1); return(BrushMeshFactory.GenerateSegmentedSubMesh(ref brushContainer.brushMeshes[0], sides, segments, vertices, topCap, bottomCap, topVertex, bottomVertex, definition.surfaceDefinition)); }
public static bool GenerateCapsule(ref BrushMesh brushMesh, ref ChiselCapsuleDefinition definition) { Vector3[] vertices = null; if (!BrushMeshFactory.GenerateCapsuleVertices(ref definition, ref vertices)) { brushMesh.Clear(); return(false); } // TODO: share this with GenerateCapsuleVertices var bottomCap = !definition.haveRoundedBottom; var topCap = !definition.haveRoundedTop; var sides = definition.sides; var segments = definition.segments; var bottomVertex = definition.bottomVertex; var topVertex = definition.topVertex; if (!BrushMeshFactory.GenerateSegmentedSubMesh(ref brushMesh, sides, segments, vertices, topCap, bottomCap, topVertex, bottomVertex, definition.surfaceDefinition)) { brushMesh.Clear(); return(false); } return(true); }
public static bool GenerateSphere(ref BrushMesh brushMesh, ref ChiselSphereDefinition definition) { definition.Validate(); var transform = float4x4.TRS(Vector3.zero, quaternion.AxisAngle(new Vector3(0, 1, 0), definition.rotation), Vector3.one); return(BrushMeshFactory.GenerateSphere(ref brushMesh, definition.diameterXYZ, definition.offsetY, definition.generateFromCenter, transform, definition.horizontalSegments, definition.verticalSegments, definition.surfaceDefinition)); }
public override void OnEdit(IChiselHandles handles) { var normal = Vector3.up; float3[] vertices = null; if (BrushMeshFactory.GenerateTorusVertices(this, ref vertices)) { var baseColor = handles.color; handles.color = handles.GetStateColor(baseColor, false, false); DrawOutline(handles, this, vertices, lineMode: LineMode.ZTest); handles.color = handles.GetStateColor(baseColor, false, true); DrawOutline(handles, this, vertices, lineMode: LineMode.NoZTest); handles.color = baseColor; } var outerRadius = settings.outerDiameter * 0.5f; var innerRadius = settings.InnerDiameter * 0.5f; var topPoint = normal * (settings.tubeHeight * 0.5f); var bottomPoint = normal * (-settings.tubeHeight * 0.5f); handles.DoRadiusHandle(ref outerRadius, normal, float3.zero); handles.DoRadiusHandle(ref innerRadius, normal, float3.zero); handles.DoDirectionHandle(ref bottomPoint, -normal); handles.DoDirectionHandle(ref topPoint, normal); if (handles.modified) { settings.outerDiameter = outerRadius * 2.0f; settings.InnerDiameter = innerRadius * 2.0f; settings.tubeHeight = (topPoint.y - bottomPoint.y); // TODO: handle sizing down } }
public ChiselBlobAssetReference <BrushMeshBlob> GenerateMesh(ChiselBlobAssetReference <NativeChiselSurfaceDefinition> surfaceDefinitionBlob, Allocator allocator) { if (!BrushMeshFactory.CreateBox(bounds.Min, bounds.Max, in surfaceDefinitionBlob, out var newBrushMesh, allocator)) { return(default);
public static bool GenerateSphere(ref ChiselBrushContainer brushContainer, ref ChiselSphereDefinition definition) { definition.Validate(); brushContainer.EnsureSize(1); var transform = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(definition.rotation, Vector3.up), Vector3.one); return(BrushMeshFactory.GenerateSphere(ref brushContainer.brushMeshes[0], definition.diameterXYZ, definition.offsetY, definition.generateFromCenter, transform, definition.horizontalSegments, definition.verticalSegments, definition.surfaceDefinition)); }
public static bool GenerateStadium(ref ChiselBrushContainer brushContainer, ref ChiselStadiumDefinition definition) { definition.Validate(); Vector3[] vertices = null; if (!GenerateStadiumVertices(definition, ref vertices)) { return(false); } brushContainer.EnsureSize(1); var surfaceIndices = new int[vertices.Length + 2]; return(BrushMeshFactory.CreateExtrudedSubMesh(ref brushContainer.brushMeshes[0], definition.sides, surfaceIndices, 0, 1, vertices, definition.surfaceDefinition)); }
static Vector3[] vertices = null; // TODO: store this per instance? or just allocate every frame? public void OnEdit(IChiselHandles handles) { var baseColor = handles.color; var normal = Vector3.up; if (BrushMeshFactory.GenerateHemisphereVertices(ref this, ref vertices)) { handles.color = handles.GetStateColor(baseColor, false, false); DrawOutline(handles, this, vertices, lineMode: LineMode.ZTest); handles.color = handles.GetStateColor(baseColor, false, true); DrawOutline(handles, this, vertices, lineMode: LineMode.NoZTest); handles.color = baseColor; } var topPoint = normal * this.diameterXYZ.y; var radius2D = new Vector2(this.diameterXYZ.x, this.diameterXYZ.z) * 0.5f; if (this.diameterXYZ.y < 0) { normal = -normal; } bool previousModified; previousModified = handles.modified; { handles.color = baseColor; // TODO: make it possible to (optionally) size differently in x & z handles.DoRadiusHandle(ref radius2D.x, normal, Vector3.zero); { var isTopBackfaced = false; // TODO: how to do this? handles.backfaced = isTopBackfaced; handles.DoDirectionHandle(ref topPoint, normal); handles.backfaced = false; } } if (previousModified != handles.modified) { var diameter = this.diameterXYZ; diameter.y = topPoint.y; diameter.x = radius2D.x * 2.0f; diameter.z = radius2D.x * 2.0f; this.diameterXYZ = diameter; } }
public bool GenerateNodes(ChiselBlobAssetReference <NativeChiselSurfaceDefinition> surfaceDefinitionBlob, NativeList <GeneratedNode> nodes, Allocator allocator) { var generatedBrushMeshes = new NativeList <ChiselBlobAssetReference <BrushMeshBlob> >(nodes.Length, Allocator.Temp); try { generatedBrushMeshes.Resize(nodes.Length, NativeArrayOptions.ClearMemory); using var vertices = BrushMeshFactory.GenerateTorusVertices(outerDiameter, tubeWidth, tubeHeight, tubeRotation, startAngle, totalAngle, verticalSegments, horizontalSegments, fitCircle, Allocator.Temp); if (!BrushMeshFactory.GenerateTorus(generatedBrushMeshes, in vertices, verticalSegments, horizontalSegments, in surfaceDefinitionBlob, allocator)) { for (int i = 0; i < generatedBrushMeshes.Length; i++) { if (generatedBrushMeshes[i].IsCreated) { generatedBrushMeshes[i].Dispose(); } generatedBrushMeshes[i] = default; } return(false); } for (int i = 0; i < generatedBrushMeshes.Length; i++) { nodes[i] = GeneratedNode.GenerateBrush(generatedBrushMeshes[i]); } return(true); } finally { generatedBrushMeshes.Dispose(); } }
public static bool GenerateLinearStairs(ref ChiselBrushContainer brushContainer, ref ChiselLinearStairsDefinition definition) { definition.Validate(); int requiredSubMeshCount = BrushMeshFactory.GetLinearStairsSubMeshCount(definition, definition.leftSide, definition.rightSide); if (requiredSubMeshCount == 0) { return(false); } int subMeshOffset = 0; brushContainer.EnsureSize(requiredSubMeshCount); return(GenerateLinearStairsSubMeshes(ref brushContainer, definition, definition.leftSide, definition.rightSide, subMeshOffset)); }
public static bool GenerateStadium(ref BrushMesh brushMesh, ref ChiselStadiumDefinition definition) { definition.Validate(); Vector3[] vertices = null; if (!GenerateStadiumVertices(definition, ref vertices)) { brushMesh.Clear(); return(false); } var surfaceIndices = new int[vertices.Length + 2]; if (!BrushMeshFactory.CreateExtrudedSubMesh(ref brushMesh, definition.sides, surfaceIndices, 0, 1, vertices, definition.surfaceDefinition)) { brushMesh.Clear(); return(false); } return(true); }
public bool Generate(ref ChiselBrushContainer brushContainer) { return(BrushMeshFactory.GenerateCapsule(ref brushContainer, ref this)); }
public bool Generate(ref ChiselBrushContainer brushContainer) { return(BrushMeshFactory.GenerateSpiralStairs(ref brushContainer, ref this)); }
public void OnEdit(IChiselHandles handles) { var baseColor = handles.color; var upVector = Vector3.up; var rightVector = Vector3.right; var forwardVector = Vector3.forward; Vector3[] vertices = null; if (BrushMeshFactory.GenerateStadiumVertices(this, ref vertices)) { handles.color = handles.GetStateColor(baseColor, false, false); DrawOutline(handles, this, vertices, lineMode: LineMode.ZTest); handles.color = handles.GetStateColor(baseColor, false, true); DrawOutline(handles, this, vertices, lineMode: LineMode.NoZTest); handles.color = baseColor; } var height = this.height; var length = this.length; var diameter = this.diameter; var sides = this.sides; var firstTopSide = this.firstTopSide; var lastTopSide = this.lastTopSide; var firstBottomSide = this.firstBottomSide; var lastBottomSide = this.lastBottomSide; var haveRoundedTop = this.haveRoundedTop; var haveRoundedBottom = this.haveRoundedBottom; var haveCenter = this.haveCenter; var topLength = this.topLength; var bottomLength = this.bottomLength; var midY = height * 0.5f; var halfLength = length * 0.5f; var midZ = ((halfLength - (haveRoundedTop ? topLength : 0)) - (halfLength - (haveRoundedBottom ? bottomLength : 0))) * -0.5f; // haveCenter ? ((vertices[firstTopSide].z + vertices[firstBottomSide].z) * 0.5f) : 0; var topPoint = new Vector3(0, height, midZ); var bottomPoint = new Vector3(0, 0, midZ); var frontPoint = new Vector3(0, midY, halfLength); var backPoint = new Vector3(0, midY, -halfLength); var leftPoint = new Vector3(diameter * 0.5f, midY, midZ); var rightPoint = new Vector3(diameter * -0.5f, midY, midZ); { { var isTopBackfaced = handles.IsSufaceBackFaced(topPoint, upVector); handles.backfaced = isTopBackfaced; handles.DoDirectionHandle(ref topPoint, upVector); var topHasFocus = handles.lastHandleHadFocus; handles.backfaced = false; //if (this.haveRoundedTop) { var thickness = topHasFocus ? kCapLineThicknessSelected : kCapLineThickness; handles.color = handles.GetStateColor(handles.color, topHasFocus, true); handles.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.NoZTest, thickness: thickness); if (haveRoundedTop) { handles.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { handles.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } handles.color = handles.GetStateColor(handles.color, topHasFocus, false); handles.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.ZTest, thickness: thickness); if (haveRoundedTop) { handles.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { handles.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } } } { var isBottomBackfaced = handles.IsSufaceBackFaced(bottomPoint, -upVector); handles.backfaced = isBottomBackfaced; handles.DoDirectionHandle(ref bottomPoint, -upVector); var bottomHasFocus = handles.lastHandleHadFocus; handles.backfaced = false; //if (this.haveRoundedBottom) { var thickness = bottomHasFocus ? kCapLineThicknessSelected : kCapLineThickness; handles.color = handles.GetStateColor(baseColor, bottomHasFocus, true); handles.DrawLineLoop(vertices, 0, sides, lineMode: LineMode.NoZTest, thickness: thickness); if (haveRoundedTop) { handles.DrawLine(vertices[firstTopSide], vertices[lastTopSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { handles.DrawLine(vertices[firstBottomSide], vertices[lastBottomSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } handles.color = handles.GetStateColor(baseColor, bottomHasFocus, false); handles.DrawLineLoop(vertices, 0, sides, lineMode: LineMode.ZTest, thickness: thickness); if (haveRoundedTop) { handles.DrawLine(vertices[firstTopSide], vertices[lastTopSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { handles.DrawLine(vertices[firstBottomSide], vertices[lastBottomSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } } } { var isTopBackfaced = handles.IsSufaceBackFaced(frontPoint, forwardVector); handles.backfaced = isTopBackfaced; handles.DoDirectionHandle(ref frontPoint, forwardVector); handles.backfaced = false; } { var isBottomBackfaced = handles.IsSufaceBackFaced(backPoint, -forwardVector); handles.backfaced = isBottomBackfaced; handles.DoDirectionHandle(ref backPoint, -forwardVector); handles.backfaced = false; } { var isTopBackfaced = handles.IsSufaceBackFaced(leftPoint, rightVector); handles.backfaced = isTopBackfaced; handles.DoDirectionHandle(ref leftPoint, rightVector); handles.backfaced = false; } { var isBottomBackfaced = handles.IsSufaceBackFaced(rightPoint, -rightVector); handles.backfaced = isBottomBackfaced; handles.DoDirectionHandle(ref rightPoint, -rightVector); handles.backfaced = false; } } if (handles.modified) { this.height = topPoint.y - bottomPoint.y; this.length = Mathf.Max(0, frontPoint.z - backPoint.z); this.diameter = leftPoint.x - rightPoint.x; // TODO: handle sizing in some directions (needs to modify transformation?) } }
static Vector3[] vertices = null; // TODO: store this per instance? or just allocate every frame? public void OnEdit(IChiselHandles handles) { var baseColor = handles.color; var normal = Vector3.up; if (BrushMeshFactory.GenerateSphereVertices(this, ref vertices)) { handles.color = handles.GetStateColor(baseColor, false, false); DrawOutline(handles, this, vertices, lineMode: LineMode.ZTest); handles.color = handles.GetStateColor(baseColor, false, true); DrawOutline(handles, this, vertices, lineMode: LineMode.NoZTest); handles.color = baseColor; } Vector3 center, topPoint, bottomPoint; if (!this.generateFromCenter) { center = normal * (this.offsetY + (this.diameterXYZ.y * 0.5f)); topPoint = normal * (this.offsetY + this.diameterXYZ.y); bottomPoint = normal * (this.offsetY); } else { center = normal * (this.offsetY); topPoint = normal * (this.offsetY + (this.diameterXYZ.y * 0.5f)); bottomPoint = normal * (this.offsetY + (this.diameterXYZ.y * -0.5f)); } if (this.diameterXYZ.y < 0) { normal = -normal; } var radius2D = new Vector2(this.diameterXYZ.x, this.diameterXYZ.z) * 0.5f; { // TODO: make it possible to (optionally) size differently in x & z var radiusX = radius2D.x; handles.DoRadiusHandle(ref radiusX, normal, center); radius2D.x = radiusX; { var isBottomBackfaced = false; // TODO: how to do this? handles.backfaced = isBottomBackfaced; handles.DoDirectionHandle(ref bottomPoint, -normal); handles.backfaced = false; } { var isTopBackfaced = false; // TODO: how to do this? handles.backfaced = isTopBackfaced; handles.DoDirectionHandle(ref topPoint, normal); handles.backfaced = false; } } if (handles.modified) { var diameter = this.diameterXYZ; diameter.y = topPoint.y - bottomPoint.y; diameter.x = radius2D.x * 2.0f; diameter.z = radius2D.x * 2.0f; this.offsetY = bottomPoint.y; this.diameterXYZ = diameter; // TODO: handle sizing down (needs to modify transformation?) } }
static Vector3[] vertices = null; // TODO: store this per instance? or just allocate every frame? public void OnEdit(IChiselHandles handles) { var baseColor = handles.color; var normal = Vector3.up; if (BrushMeshFactory.GenerateCapsuleVertices(ref this, ref vertices)) { handles.color = handles.GetStateColor(baseColor, false, false); DrawOutline(handles, this, vertices, lineMode: LineMode.ZTest); handles.color = handles.GetStateColor(baseColor, false, true); DrawOutline(handles, this, vertices, lineMode: LineMode.NoZTest); handles.color = baseColor; } var topPoint = normal * (this.offsetY + this.height); var bottomPoint = normal * (this.offsetY); var middlePoint = normal * (this.offsetY + (this.height * 0.5f)); var radius2D = new Vector2(this.diameterX, this.diameterZ) * 0.5f; var topHeight = this.topHeight; var bottomHeight = this.bottomHeight; var maxTopHeight = this.height - bottomHeight; var maxBottomHeight = this.height - topHeight; if (this.height < 0) { normal = -normal; } var prevModified = handles.modified; { handles.color = baseColor; // TODO: make it possible to (optionally) size differently in x & z var radius2Dx = radius2D.x; handles.DoRadiusHandle(ref radius2Dx, normal, middlePoint); radius2D.x = radius2Dx; { var isTopBackfaced = handles.IsSufaceBackFaced(topPoint, normal); var topLoopHasFocus = false; handles.backfaced = isTopBackfaced; for (int j = this.sides - 1, i = 0; i < this.sides; j = i, i++) { var from = vertices[j + this.topVertexOffset]; var to = vertices[i + this.topVertexOffset]; if (handles.DoEdgeHandle1DOffset(out var edgeOffset, UnitySceneExtensions.Axis.Y, from, to, renderLine: false)) { topHeight = Mathf.Clamp(topHeight - edgeOffset, 0, maxTopHeight); } topLoopHasFocus = topLoopHasFocus || handles.lastHandleHadFocus; } handles.color = baseColor; handles.DoDirectionHandle(ref topPoint, normal); var topHasFocus = handles.lastHandleHadFocus; handles.backfaced = false; topLoopHasFocus = topLoopHasFocus || (topHasFocus && !this.haveRoundedTop); var thickness = topLoopHasFocus ? kCapLineThicknessSelected : kCapLineThickness; handles.color = handles.GetStateColor(baseColor, topLoopHasFocus, true); handles.DrawLineLoop(vertices, this.topVertexOffset, this.sides, lineMode: LineMode.NoZTest, thickness: thickness); handles.color = handles.GetStateColor(baseColor, topLoopHasFocus, false); handles.DrawLineLoop(vertices, this.topVertexOffset, this.sides, lineMode: LineMode.ZTest, thickness: thickness); } { var isBottomBackfaced = handles.IsSufaceBackFaced(bottomPoint, -normal); var bottomLoopHasFocus = false; handles.backfaced = isBottomBackfaced; for (int j = this.sides - 1, i = 0; i < this.sides; j = i, i++) { var from = vertices[j + this.bottomVertexOffset]; var to = vertices[i + this.bottomVertexOffset]; if (handles.DoEdgeHandle1DOffset(out var edgeOffset, UnitySceneExtensions.Axis.Y, from, to, renderLine: false)) { bottomHeight = Mathf.Clamp(bottomHeight + edgeOffset, 0, maxBottomHeight); } bottomLoopHasFocus = bottomLoopHasFocus || handles.lastHandleHadFocus; } handles.color = baseColor; handles.DoDirectionHandle(ref bottomPoint, -normal); var bottomHasFocus = handles.lastHandleHadFocus; handles.backfaced = false; bottomLoopHasFocus = bottomLoopHasFocus || (bottomHasFocus && !this.haveRoundedBottom); var thickness = bottomLoopHasFocus ? kCapLineThicknessSelected : kCapLineThickness; handles.color = handles.GetStateColor(baseColor, bottomLoopHasFocus, true); handles.DrawLineLoop(vertices, this.bottomVertexOffset, this.sides, lineMode: LineMode.NoZTest, thickness: thickness); handles.color = handles.GetStateColor(baseColor, bottomLoopHasFocus, false); handles.DrawLineLoop(vertices, this.bottomVertexOffset, this.sides, lineMode: LineMode.ZTest, thickness: thickness); } } if (prevModified != handles.modified) { this.diameterX = radius2D.x * 2.0f; this.height = topPoint.y - bottomPoint.y; this.diameterZ = radius2D.x * 2.0f; this.offsetY = bottomPoint.y; this.topHeight = topHeight; this.bottomHeight = bottomHeight; // TODO: handle sizing down (needs to modify transformation?) } }
public override void OnEdit(IChiselHandles handles) { var normal = Vector3.up; var topDirection = Vector3.forward; var lowDirection = Vector3.forward; var originalOuterDiameter = settings.outerDiameter; var originalInnerDiameter = settings.innerDiameter; var originalStartAngle = settings.startAngle; var originalStepHeight = settings.stepHeight; var originalRotation = settings.rotation; var originalHeight = settings.height; var originalOrigin = settings.origin; var cylinderTop = new BrushMeshFactory.ChiselCircleDefinition { diameterX = 1, diameterZ = 1, height = originalOrigin.y + originalHeight }; var cylinderLow = new BrushMeshFactory.ChiselCircleDefinition { diameterX = 1, diameterZ = 1, height = originalOrigin.y }; var originalTopPoint = normal * cylinderTop.height; var originalLowPoint = normal * cylinderLow.height; var originalMidPoint = (originalTopPoint + originalLowPoint) * 0.5f; var outerDiameter = originalOuterDiameter; var innerDiameter = originalInnerDiameter; var topPoint = originalTopPoint; var lowPoint = originalLowPoint; var midPoint = originalMidPoint; var startAngle = originalStartAngle; var rotation = originalRotation; { var currRotation = startAngle + rotation; handles.DoRotatableLineHandle(ref startAngle, lowPoint, outerDiameter * 0.5f, normal, lowDirection, Vector3.Cross(normal, lowDirection)); handles.DoRotatableLineHandle(ref currRotation, topPoint, outerDiameter * 0.5f, normal, topDirection, Vector3.Cross(normal, topDirection)); if (handles.modified) { rotation = currRotation - startAngle; } // TODO: properly show things as backfaced // TODO: temporarily show inner or outer diameter as disabled when resizing one or the other // TODO: FIXME: why aren't there any arrows? handles.DoDirectionHandle(ref topPoint, normal, snappingStep: originalStepHeight); topPoint.y = math.max(lowPoint.y + originalStepHeight, topPoint.y); handles.DoDirectionHandle(ref lowPoint, -normal, snappingStep: originalStepHeight); lowPoint.y = math.min(topPoint.y - originalStepHeight, lowPoint.y); float minOuterDiameter = innerDiameter + ChiselSpiralStairs.kMinStairsDepth; { var outerRadius = outerDiameter * 0.5f; handles.DoRadiusHandle(ref outerRadius, Vector3.up, topPoint, renderDisc: false); handles.DoRadiusHandle(ref outerRadius, Vector3.up, lowPoint, renderDisc: false); outerDiameter = math.max(minOuterDiameter, outerRadius * 2.0f); } float maxInnerDiameter = outerDiameter - ChiselSpiralStairs.kMinStairsDepth; { var innerRadius = innerDiameter * 0.5f; handles.DoRadiusHandle(ref innerRadius, Vector3.up, midPoint, renderDisc: false); innerDiameter = math.min(maxInnerDiameter, innerRadius * 2.0f); } // TODO: somehow put this into a separate renderer cylinderTop.diameterZ = cylinderTop.diameterX = cylinderLow.diameterZ = cylinderLow.diameterX = originalInnerDiameter; BrushMeshFactory.GetConicalFrustumVertices(cylinderLow, cylinderTop, 0, settings.innerSegments, ref s_InnerVertices); cylinderTop.diameterZ = cylinderTop.diameterX = cylinderLow.diameterZ = cylinderLow.diameterX = originalOuterDiameter; BrushMeshFactory.GetConicalFrustumVertices(cylinderLow, cylinderTop, 0, settings.outerSegments, ref s_OuterVertices); var originalColor = handles.color; var color = handles.color; var outlineColor = Color.black; outlineColor.a = color.a; handles.color = outlineColor; { var sides = settings.outerSegments; for (int i = 0, j = sides - 1; i < sides; j = i, i++) { var t0 = s_OuterVertices[i]; var t1 = s_OuterVertices[j]; var b0 = s_OuterVertices[i + sides]; var b1 = s_OuterVertices[j + sides]; handles.DrawLine(t0, b0, thickness: 1.0f); handles.DrawLine(t0, t1, thickness: 1.0f); handles.DrawLine(b0, b1, thickness: 1.0f); } } { var sides = settings.innerSegments; for (int i = 0, j = sides - 1; i < sides; j = i, i++) { var t0 = s_InnerVertices[i]; var t1 = s_InnerVertices[j]; var b0 = s_InnerVertices[i + sides]; var b1 = s_InnerVertices[j + sides]; handles.DrawLine(t0, b0, thickness: 1.0f); handles.DrawLine(t0, t1, thickness: 1.0f); handles.DrawLine(b0, b1, thickness: 1.0f); } } handles.color = originalColor; { var sides = settings.outerSegments; for (int i = 0, j = sides - 1; i < sides; j = i, i++) { var t0 = s_OuterVertices[i]; var t1 = s_OuterVertices[j]; var b0 = s_OuterVertices[i + sides]; var b1 = s_OuterVertices[j + sides]; handles.DrawLine(t0, b0, thickness: 1.0f); handles.DrawLine(t0, t1, thickness: 1.0f); handles.DrawLine(b0, b1, thickness: 1.0f); } } { var sides = settings.innerSegments; for (int i = 0, j = sides - 1; i < sides; j = i, i++) { var t0 = s_InnerVertices[i]; var t1 = s_InnerVertices[j]; var b0 = s_InnerVertices[i + sides]; var b1 = s_InnerVertices[j + sides]; handles.DrawLine(t0, b0, thickness: 1.0f); handles.DrawLine(t0, t1, thickness: 1.0f); handles.DrawLine(b0, b1, thickness: 1.0f); var m0 = (t0 + b0) * 0.5f; var m1 = (t1 + b1) * 0.5f; handles.DrawLine(m0, m1, thickness: 2.0f); } } } if (handles.modified) { settings.outerDiameter = outerDiameter; settings.innerDiameter = innerDiameter; settings.startAngle = startAngle; settings.rotation = rotation; if (topPoint != originalTopPoint) { settings.height = topPoint.y - lowPoint.y; } if (lowPoint != originalLowPoint) { settings.height = topPoint.y - lowPoint.y; var newOrigin = originalOrigin; newOrigin.y += lowPoint.y - originalLowPoint.y; settings.origin = newOrigin; } } }
public static bool GenerateRevolvedShape(ref ChiselBrushContainer brushContainer, ref ChiselRevolvedShapeDefinition definition) { definition.Validate(); var shapeVertices = new List <Vector2>(); var shapeSegmentIndices = new List <int>(); BrushMeshFactory.GetPathVertices(definition.shape, definition.curveSegments, shapeVertices, shapeSegmentIndices); Vector2[][] polygonVerticesArray; int[][] polygonIndicesArray; if (!Decomposition.ConvexPartition(shapeVertices, shapeSegmentIndices, out polygonVerticesArray, out polygonIndicesArray)) { return(false); } // TODO: splitting it before we do the composition would be better var polygonVerticesList = polygonVerticesArray.ToList(); for (int i = polygonVerticesList.Count - 1; i >= 0; i--) { SplitPolygon(polygonVerticesList, i); } var brushMeshesList = new List <BrushMesh>(); var horzSegments = definition.revolveSegments; //horizontalSegments; var horzDegreePerSegment = definition.totalAngle / horzSegments; // TODO: make this work when intersecting rotation axis // 1. split polygons along rotation axis // 2. if edge lies on rotation axis, make sure we don't create infinitely thin quad // collapse this quad, or prevent this from happening // TODO: share this code with torus generator for (int p = 0; p < polygonVerticesList.Count; p++) { var polygonVertices = polygonVerticesList[p]; // var segmentIndices = polygonIndicesArray[p]; var shapeSegments = polygonVertices.Length; var vertSegments = polygonVertices.Length; var descriptionIndex = new int[2 + vertSegments]; descriptionIndex[0] = 0; descriptionIndex[1] = 1; for (int v = 0; v < vertSegments; v++) { descriptionIndex[v + 2] = 2; } var horzOffset = definition.startAngle; for (int h = 1, pr = 0; h < horzSegments + 1; pr = h, h++) { var hDegree0 = (pr * horzDegreePerSegment) + horzOffset; var hDegree1 = (h * horzDegreePerSegment) + horzOffset; var rotation0 = quaternion.AxisAngle(Vector3.forward, hDegree0); var rotation1 = quaternion.AxisAngle(Vector3.forward, hDegree1); var subMeshVertices = new Vector3[vertSegments * 2]; for (int v = 0; v < vertSegments; v++) { subMeshVertices[v + vertSegments] = math.mul(rotation0, new Vector3(polygonVertices[v].x, 0, polygonVertices[v].y)); subMeshVertices[v] = math.mul(rotation1, new Vector3(polygonVertices[v].x, 0, polygonVertices[v].y)); } var brushMesh = new BrushMesh(); if (!BrushMeshFactory.CreateExtrudedSubMesh(ref brushMesh, vertSegments, descriptionIndex, 0, 1, subMeshVertices, in definition.surfaceDefinition)) { continue; } if (!brushMesh.Validate()) { return(false); } brushMeshesList.Add(brushMesh); } } brushContainer.CopyFrom(brushMeshesList); return(true); }
public static bool GeneratePathedStairs(ref ChiselBrushContainer brushContainer, ref ChiselPathedStairsDefinition definition) { definition.Validate(); var shapeVertices = new List <Vector2>(); var shapeSegmentIndices = new List <int>(); GetPathVertices(definition.shape, definition.curveSegments, shapeVertices, shapeSegmentIndices); var totalSubMeshCount = 0; for (int i = 0; i < shapeVertices.Count; i++) { if (i == 0 && !definition.shape.closed) { continue; } var leftSide = (!definition.shape.closed && i == 1) ? definition.stairs.leftSide : StairsSideType.None; var rightSide = (!definition.shape.closed && i == shapeVertices.Count - 1) ? definition.stairs.rightSide : StairsSideType.None; totalSubMeshCount += BrushMeshFactory.GetLinearStairsSubMeshCount(definition.stairs, leftSide, rightSide); } if (totalSubMeshCount == 0) { return(false); } // var stairDirections = definition.shape.closed ? shapeVertices.Count : (shapeVertices.Count - 1); brushContainer.EnsureSize(totalSubMeshCount); var depth = definition.stairs.depth; var height = definition.stairs.height; var halfDepth = depth * 0.5f; var halfHeight = height * 0.5f; int subMeshIndex = 0; for (int vi0 = shapeVertices.Count - 3, vi1 = shapeVertices.Count - 2, vi2 = shapeVertices.Count - 1, vi3 = 0; vi3 < shapeVertices.Count; vi0 = vi1, vi1 = vi2, vi2 = vi3, vi3++) { if (vi2 == 0 && !definition.shape.closed) { continue; } // TODO: optimize this, we're probably redoing a lot of stuff for every iteration var v0 = shapeVertices[vi0]; var v1 = shapeVertices[vi1]; var v2 = shapeVertices[vi2]; var v3 = shapeVertices[vi3]; var m0 = (v0 + v1) * 0.5f; var m1 = (v1 + v2) * 0.5f; var m2 = (v2 + v3) * 0.5f; var d0 = (v1 - v0); var d1 = (v2 - v1); var d2 = (v3 - v2); var maxWidth0 = d0.magnitude; var maxWidth1 = d1.magnitude; var maxWidth2 = d2.magnitude; var halfWidth1 = d1 * 0.5f; d0 /= maxWidth0; d1 /= maxWidth1; d2 /= maxWidth2; var depthVector = new Vector3(d1.y, 0, -d1.x); var lineCenter = new Vector3(m1.x, halfHeight, m1.y) - (depthVector * halfDepth); var depthVector0 = new Vector2(d0.y, -d0.x) * depth; var depthVector1 = new Vector2(d1.y, -d1.x) * depth; var depthVector2 = new Vector2(d2.y, -d2.x) * depth; m0 -= depthVector0; m1 -= depthVector1; m2 -= depthVector2; Vector2 output; var leftShear = Intersect(m1, d1, m0, d0, out output) ? Vector2.Dot(d1, (output - (m1 - halfWidth1))) : 0; var rightShear = Intersect(m1, d1, m2, d2, out output) ? -Vector2.Dot(d1, (output - (m1 + halfWidth1))) : 0; var transform = Matrix4x4.TRS(lineCenter, // move to center of line Quaternion.LookRotation(depthVector, Vector3.up), // rotate to align with line Vector3.one); // set the width to the width of the line definition.stairs.width = maxWidth1; definition.stairs.nosingWidth = 0; var leftSide = (!definition.shape.closed && vi2 == 1) ? definition.stairs.leftSide : StairsSideType.None; var rightSide = (!definition.shape.closed && vi2 == shapeVertices.Count - 1) ? definition.stairs.rightSide : StairsSideType.None; var subMeshCount = BrushMeshFactory.GetLinearStairsSubMeshCount(definition.stairs, leftSide, rightSide); if (subMeshCount == 0) { continue; } if (!BrushMeshFactory.GenerateLinearStairsSubMeshes(ref brushContainer, definition.stairs, leftSide, rightSide, subMeshIndex)) { return(false); } var halfWidth = maxWidth1 * 0.5f; for (int m = 0; m < subMeshCount; m++) { var vertices = brushContainer.brushMeshes[subMeshIndex + m].vertices; for (int v = 0; v < vertices.Length; v++) { // TODO: is it possible to put all of this in a single matrix? // lerp the stairs to go from less wide to wider depending on the depth of the vertex var depthFactor = 1.0f - ((vertices[v].z / definition.stairs.depth) + 0.5f); var wideFactor = (vertices[v].x / halfWidth) + 0.5f; var scale = (vertices[v].x / halfWidth); // lerp the stairs width depending on if it's on the left or right side of the stairs vertices[v].x = Mathf.Lerp(scale * (halfWidth - (rightShear * depthFactor)), scale * (halfWidth - (leftShear * depthFactor)), wideFactor); vertices[v] = transform.MultiplyPoint(vertices[v]); } } subMeshIndex += subMeshCount; } return(false); }
public bool Generate(ref ChiselBrushContainer brushContainer) { return(BrushMeshFactory.GenerateRevolvedShape(ref brushContainer, ref this)); }
public static bool GenerateLinearStairsSubMeshes(ref ChiselBrushContainer brushContainer, ChiselLinearStairsDefinition definition, StairsSideType leftSideDefinition, StairsSideType rightSideDefinition, int subMeshOffset = 0) { // TODO: properly assign all materials if (definition.surfaceDefinition.surfaces.Length != (int)ChiselLinearStairsDefinition.SurfaceSides.TotalSides) { return(false); } // TODO: implement smooth riser-type const float kEpsilon = 0.001f; // TODO: put these values in a shared location since they need to match in multiple locations var treadHeight = (definition.treadHeight < kEpsilon) ? 0 : definition.treadHeight; var riserType = (treadHeight == 0 && definition.riserType == StairsRiserType.ThinRiser) ? StairsRiserType.ThickRiser : definition.riserType; var leftSideType = (riserType == StairsRiserType.None && definition.leftSide == StairsSideType.Up) ? StairsSideType.DownAndUp : leftSideDefinition; var rightSideType = (riserType == StairsRiserType.None && definition.rightSide == StairsSideType.Up) ? StairsSideType.DownAndUp : rightSideDefinition; if (riserType == StairsRiserType.Smooth) { switch (leftSideType) { case StairsSideType.Up: leftSideType = StairsSideType.DownAndUp; break; case StairsSideType.None: leftSideType = StairsSideType.Down; break; } switch (rightSideType) { case StairsSideType.Up: rightSideType = StairsSideType.DownAndUp; break; case StairsSideType.None: rightSideType = StairsSideType.Down; break; } } var boundsMin = definition.bounds.min; var boundsMax = definition.bounds.max; if (boundsMin.y > boundsMax.y) { var t = boundsMin.y; boundsMin.y = boundsMax.y; boundsMax.y = t; } if (boundsMin.x > boundsMax.x) { var t = boundsMin.x; boundsMin.x = boundsMax.x; boundsMax.x = t; } if (boundsMin.z > boundsMax.z) { var t = boundsMin.z; boundsMin.z = boundsMax.z; boundsMax.z = t; } var haveRiser = riserType != StairsRiserType.None; var haveLeftSideDown = riserType != StairsRiserType.FillDown && (leftSideType == StairsSideType.Down || leftSideType == StairsSideType.DownAndUp); var haveLeftSideUp = (leftSideType == StairsSideType.Up || leftSideType == StairsSideType.DownAndUp); var haveRightSideDown = riserType != StairsRiserType.FillDown && (rightSideType == StairsSideType.Down || rightSideType == StairsSideType.DownAndUp); var haveRightSideUp = (rightSideType == StairsSideType.Up || rightSideType == StairsSideType.DownAndUp); var sideWidth = definition.sideWidth; var sideHeight = definition.sideHeight; var leftSideDepth = (haveLeftSideDown) ? definition.sideDepth : 0; var rightSideDepth = (haveRightSideDown) ? definition.sideDepth : 0; var thickRiser = riserType == StairsRiserType.ThickRiser || riserType == StairsRiserType.Smooth; var riserDepth = (haveRiser && !thickRiser) ? definition.riserDepth : 0; var stepCount = definition.StepCount; var offsetZ = (definition.StepDepthOffset < kEpsilon) ? 0 : definition.StepDepthOffset; var offsetY = definition.plateauHeight; var nosingDepth = definition.nosingDepth; var haveTread = (treadHeight >= kEpsilon); var haveTopSide = (sideHeight > kEpsilon); var leftNosingWidth = haveLeftSideUp ? -sideWidth : definition.nosingWidth; var rightNosingWidth = haveRightSideUp ? -sideWidth : definition.nosingWidth; var leftTopNosingWidth = (haveLeftSideUp && (!haveTopSide)) ? definition.nosingWidth : leftNosingWidth; var rightTopNosingWidth = (haveRightSideUp && (!haveTopSide)) ? definition.nosingWidth : rightNosingWidth; var subMeshCount = 0; if (haveRiser) { subMeshCount = stepCount; } var startTread = subMeshCount; if (haveTread) { subMeshCount += stepCount; } var startLeftSideDown = subMeshCount; if (haveLeftSideDown) { subMeshCount += stepCount; } var startRightSideDown = subMeshCount; if (haveRightSideDown) { subMeshCount += stepCount; } var startLeftSideUp = subMeshCount; if (haveLeftSideUp) { subMeshCount += (stepCount - 1) + (haveTopSide ? 1 : 0) + 1; //(haveLeftSideDown ? 0 : 1); } var startRightSideUp = subMeshCount; if (haveRightSideUp) { subMeshCount += (stepCount - 1) + (haveTopSide ? 1 : 0) + 1; //(haveRightSideDown ? 0 : 1); } var stepOffset = new Vector3(0, -definition.stepHeight, definition.stepDepth); if (stepCount > 0) { if (haveRiser) { var min = boundsMin; var max = boundsMax; max.z = min.z + definition.StepDepthOffset + definition.stepDepth; if (riserType != StairsRiserType.FillDown) { if (riserType == StairsRiserType.ThinRiser) { min.z = max.z - riserDepth; } else { min.z = min.z + definition.StepDepthOffset; } if (thickRiser) { min.z -= offsetZ; } } min.y = max.y - definition.stepHeight; min.y -= treadHeight; max.y -= treadHeight; min.x += haveRightSideUp ? sideWidth : 0; max.x -= haveLeftSideUp ? sideWidth : 0; var extrusion = new Vector3(max.x - min.x, 0, 0); for (int i = 0; i < stepCount; i++) { if (i == 1 && thickRiser) { min.z += offsetZ; } if (i == stepCount - 1) { min.y += treadHeight - offsetY; } Vector3[] vertices; if (i == 0 || riserType != StairsRiserType.Smooth) { vertices = new[] { new Vector3(min.x, min.y, min.z), // 0 new Vector3(min.x, min.y, max.z), // 1 new Vector3(min.x, max.y, max.z), // 2 new Vector3(min.x, max.y, min.z), // 3 }; } else { vertices = new[] { new Vector3(min.x, min.y, min.z), // 0 new Vector3(min.x, min.y, max.z), // 1 new Vector3(min.x, max.y, max.z), // 2 new Vector3(min.x, max.y, min.z - definition.stepDepth), // 3 }; } BrushMeshFactory.CreateExtrudedSubMesh(ref brushContainer.brushMeshes[subMeshOffset + i], vertices, extrusion, new int[] { 0, 1, 2, 3, 3, 3 }, // TODO: fix this definition.surfaceDefinition); if (riserType != StairsRiserType.FillDown) { min.z += definition.stepDepth; } max.z += definition.stepDepth; min.y -= definition.stepHeight; max.y -= definition.stepHeight; } } if (haveTread) { var min = new Vector3(boundsMin.x + sideWidth, boundsMax.y - definition.treadHeight, boundsMin.z); var max = new Vector3(boundsMax.x - sideWidth, boundsMax.y, boundsMin.z + definition.StepDepthOffset + definition.stepDepth + nosingDepth); for (int i = 0; i < stepCount; i++) { min.x = boundsMin.x - ((i == 0) ? rightTopNosingWidth : rightNosingWidth); max.x = boundsMax.x + ((i == 0) ? leftTopNosingWidth : leftNosingWidth); if (i == 1) { min.z = max.z - (definition.stepDepth + nosingDepth); } var vertices = new[] { new Vector3(min.x, min.y, min.z), // 0 new Vector3(min.x, min.y, max.z), // 1 new Vector3(min.x, max.y, max.z), // 2 new Vector3(min.x, max.y, min.z), // 3 }; var extrusion = new Vector3(max.x - min.x, 0, 0); BrushMeshFactory.CreateExtrudedSubMesh(ref brushContainer.brushMeshes[subMeshOffset + startTread + i], vertices, extrusion, new int[] { 0, 1, 2, 2, 2, 2 }, // TODO: fix this definition.surfaceDefinition); min += stepOffset; max += stepOffset; } } if (haveLeftSideDown) { var min = new Vector3(boundsMax.x - sideWidth, boundsMax.y - definition.stepHeight - definition.treadHeight, boundsMin.z + definition.StepDepthOffset); var max = new Vector3(boundsMax.x, boundsMax.y - definition.treadHeight, boundsMin.z + definition.StepDepthOffset + definition.stepDepth); var extrusion = new Vector3(sideWidth, 0, 0); var extraDepth = (thickRiser ? definition.stepDepth : riserDepth) + leftSideDepth; var maxDepth = boundsMin.z; GenerateBottomRamp(ref brushContainer, subMeshOffset + startLeftSideDown, stepCount, min, max, extrusion, riserType, definition.stepDepth - riserDepth, extraDepth, maxDepth, definition, definition.surfaceDefinition); } if (haveRightSideDown) { var min = new Vector3(boundsMin.x, boundsMax.y - definition.stepHeight - definition.treadHeight, boundsMin.z + definition.StepDepthOffset); var max = new Vector3(boundsMin.x + sideWidth, boundsMax.y - definition.treadHeight, boundsMin.z + definition.StepDepthOffset + definition.stepDepth); var extrusion = new Vector3(sideWidth, 0, 0); var extraDepth = (thickRiser ? definition.stepDepth : riserDepth) + rightSideDepth; var maxDepth = boundsMin.z; GenerateBottomRamp(ref brushContainer, subMeshOffset + startRightSideDown, stepCount, min, max, extrusion, riserType, definition.stepDepth - riserDepth, extraDepth, maxDepth, definition, definition.surfaceDefinition); } if (haveLeftSideUp) { var min = new Vector3(boundsMax.x - sideWidth, boundsMax.y - definition.treadHeight - definition.stepHeight, boundsMin.z + definition.StepDepthOffset + definition.stepDepth); var max = new Vector3(boundsMax.x, boundsMax.y - definition.treadHeight, boundsMin.z + definition.StepDepthOffset + definition.stepDepth + definition.stepDepth); var extrusion = new Vector3(sideWidth, 0, 0); var extraDepth = (thickRiser ? definition.stepDepth : riserDepth) + leftSideDepth; var maxDepth = boundsMin.z; GenerateTopRamp(ref brushContainer, subMeshOffset + startLeftSideUp, stepCount - 1, min, max, extrusion, sideHeight, extraDepth, maxDepth, riserType, definition, definition.surfaceDefinition); if (haveTopSide) { var vertices = new[] { new Vector3(min.x, max.y + sideHeight + definition.treadHeight, min.z), // 0 new Vector3(min.x, max.y + sideHeight + definition.treadHeight, boundsMin.z), // 1 new Vector3(min.x, max.y, boundsMin.z), // 2 new Vector3(min.x, max.y, min.z), // 3 }; BrushMeshFactory.CreateExtrudedSubMesh(ref brushContainer.brushMeshes[subMeshOffset + startLeftSideUp + (stepCount - 1)], vertices, extrusion, new int[] { 0, 1, 2, 3, 3, 3 }, // TODO: fix this definition.surfaceDefinition); } //if (!haveLeftSideDown) { var stepHeight = definition.stepHeight; Vector3[] vertices; if (riserType == StairsRiserType.FillDown) { vertices = new[] { new Vector3(min.x, boundsMin.y + stepHeight, boundsMax.z), // 0 new Vector3(min.x, boundsMin.y + stepHeight, boundsMin.z), // 1 new Vector3(min.x, boundsMin.y, boundsMin.z), // 2 new Vector3(min.x, boundsMin.y, boundsMax.z), // 3 }; } else { vertices = new[] { new Vector3(min.x, boundsMin.y + stepHeight, boundsMax.z), // 0 new Vector3(min.x, boundsMin.y + stepHeight, boundsMax.z - extraDepth), // 1 new Vector3(min.x, boundsMin.y, boundsMax.z - extraDepth), // 2 new Vector3(min.x, boundsMin.y, boundsMax.z), // 3 }; } BrushMeshFactory.CreateExtrudedSubMesh(ref brushContainer.brushMeshes[subMeshOffset + startLeftSideUp + stepCount], vertices, extrusion, new int[] { 0, 1, 2, 3, 3, 3 }, // TODO: fix this definition.surfaceDefinition); } } if (haveRightSideUp) { var min = new Vector3(boundsMin.x, boundsMax.y - definition.treadHeight - definition.stepHeight, boundsMin.z + definition.StepDepthOffset + definition.stepDepth); var max = new Vector3(boundsMin.x + sideWidth, boundsMax.y - definition.treadHeight, boundsMin.z + definition.StepDepthOffset + definition.stepDepth + definition.stepDepth); var extrusion = new Vector3(sideWidth, 0, 0); var extraDepth = (thickRiser ? definition.stepDepth : riserDepth) + rightSideDepth; var maxDepth = boundsMin.z; GenerateTopRamp(ref brushContainer, subMeshOffset + startRightSideUp, stepCount - 1, min, max, extrusion, sideHeight, extraDepth, maxDepth, riserType, definition, definition.surfaceDefinition); if (haveTopSide) { var vertices = new[] { new Vector3(min.x, max.y + sideHeight + definition.treadHeight, min.z), // 0 new Vector3(min.x, max.y + sideHeight + definition.treadHeight, boundsMin.z), // 1 new Vector3(min.x, max.y, boundsMin.z), // 2 new Vector3(min.x, max.y, min.z), // 3 }; BrushMeshFactory.CreateExtrudedSubMesh(ref brushContainer.brushMeshes[subMeshOffset + startRightSideUp + (stepCount - 1)], vertices, extrusion, new int[] { 0, 1, 2, 3, 3, 3 }, // TODO: fix this definition.surfaceDefinition); } //if (!haveRightSideDown) { var stepHeight = definition.stepHeight; Vector3[] vertices; if (riserType == StairsRiserType.FillDown) { vertices = new[] { new Vector3(min.x, boundsMin.y + stepHeight, boundsMax.z), // 0 new Vector3(min.x, boundsMin.y + stepHeight, boundsMin.z), // 1 new Vector3(min.x, boundsMin.y, boundsMin.z), // 2 new Vector3(min.x, boundsMin.y, boundsMax.z), // 3 }; } else { vertices = new[] { new Vector3(min.x, boundsMin.y + stepHeight, boundsMax.z), // 0 new Vector3(min.x, boundsMin.y + stepHeight, boundsMax.z - extraDepth), // 1 new Vector3(min.x, boundsMin.y, boundsMax.z - extraDepth), // 2 new Vector3(min.x, boundsMin.y, boundsMax.z), // 3 }; } BrushMeshFactory.CreateExtrudedSubMesh(ref brushContainer.brushMeshes[subMeshOffset + startRightSideUp + stepCount], vertices, extrusion, new int[] { 0, 1, 2, 3, 3, 3 }, // TODO: fix this definition.surfaceDefinition); } } } return(true); }
public void OnEdit(IChiselHandles handles) { var baseColor = handles.color; var normal = Vector3.forward; var controlPoints = shape.controlPoints; var shapeVertices = new List <Vector2>(); var shapeSegmentIndices = new List <int>(); BrushMeshFactory.GetPathVertices(this.shape, this.curveSegments, shapeVertices, shapeSegmentIndices); var horzSegments = this.revolveSegments; var horzDegreePerSegment = this.totalAngle / horzSegments; var horzOffset = this.startAngle; var noZTestcolor = handles.GetStateColor(baseColor, false, true); var zTestcolor = handles.GetStateColor(baseColor, false, false); for (int h = 1, pr = 0; h < horzSegments + 1; pr = h, h++) { var hDegree0 = (pr * horzDegreePerSegment) + horzOffset; var hDegree1 = (h * horzDegreePerSegment) + horzOffset; var rotation0 = Quaternion.AngleAxis(hDegree0, normal); var rotation1 = Quaternion.AngleAxis(hDegree1, normal); for (int p0 = controlPoints.Length - 1, p1 = 0; p1 < controlPoints.Length; p0 = p1, p1++) { var point0 = controlPoints[p0].position; //var point1 = controlPoints[p1].position; var vertexA = rotation0 * new Vector3(point0.x, 0, point0.y); var vertexB = rotation1 * new Vector3(point0.x, 0, point0.y); //var vertexC = rotation0 * new Vector3(point1.x, 0, point1.y); handles.color = noZTestcolor; handles.DrawLine(vertexA, vertexB, lineMode: LineMode.NoZTest, thickness: kHorzLineThickness);//, dashSize: kLineDash); handles.color = zTestcolor; handles.DrawLine(vertexA, vertexB, lineMode: LineMode.ZTest, thickness: kHorzLineThickness); //, dashSize: kLineDash); } for (int v0 = shapeVertices.Count - 1, v1 = 0; v1 < shapeVertices.Count; v0 = v1, v1++) { var point0 = shapeVertices[v0]; var point1 = shapeVertices[v1]; var vertexA = rotation0 * new Vector3(point0.x, 0, point0.y); var vertexB = rotation0 * new Vector3(point1.x, 0, point1.y); handles.color = noZTestcolor; handles.DrawLine(vertexA, vertexB, lineMode: LineMode.NoZTest, thickness: kHorzLineThickness, dashSize: kLineDash); handles.color = zTestcolor; handles.DrawLine(vertexA, vertexB, lineMode: LineMode.ZTest, thickness: kHorzLineThickness, dashSize: kLineDash); } } handles.color = baseColor; { // TODO: make this work non grid aligned so we can place it upwards handles.DoShapeHandle(ref shape); handles.DrawLine(normal * 10, normal * -10, dashSize: 4.0f); } }