Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        public bool Generate(ref ChiselBrushContainer brushContainer)
        {
            if (!IsValid)
            {
                return(false);
            }

            brushContainer.EnsureSize(1);

            brushContainer.brushMeshes[0] = new BrushMesh(brushOutline);

            brushContainer.brushMeshes[0].CalculatePlanes();

            // Detect if outline is inside-out and if so, just invert all polygons.
            isInsideOut = brushContainer.brushMeshes[0].IsInsideOut();
            if (isInsideOut)
            {
                brushContainer.brushMeshes[0].Invert();
            }

            // Split non planar polygons into convex pieces
            brushContainer.brushMeshes[0].SplitNonPlanarPolygons();

            return(brushContainer.brushMeshes[0].Validate());
        }
        public static bool GenerateHemisphere(ref ChiselBrushContainer brushContainer, ref ChiselHemisphereDefinition definition)
        {
            definition.Validate();

            brushContainer.EnsureSize(1);

            var transform = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(definition.rotation, Vector3.up), Vector3.one);
            return GenerateHemisphereSubMesh(ref brushContainer.brushMeshes[0], definition.diameterXYZ, transform, definition.horizontalSegments, definition.verticalSegments, definition.surfaceDefinition);
        }
Exemplo n.º 4
0
        public static bool GenerateSphere(ref ChiselBrushContainer brushContainer, ref ChiselSphereDefinition definition)
        {
            definition.Validate();

            brushContainer.EnsureSize(1);

            var transform = float4x4.TRS(Vector3.zero, quaternion.AxisAngle(new Vector3(0, 1, 0), definition.rotation), Vector3.one);

            return(BrushMeshFactory.GenerateSphere(ref brushContainer.brushMeshes[0], definition.diameterXYZ, definition.offsetY, definition.generateFromCenter, transform, definition.horizontalSegments, definition.verticalSegments, definition.surfaceDefinition));
        }
        public bool Generate(ref ChiselBrushContainer brushContainer)
        {
            Profiler.BeginSample("GenerateBrush");
            try
            {
                if (!IsValid)
                {
                    return(false);
                }

                Profiler.BeginSample("EnsureSize");
                brushContainer.EnsureSize(1);
                Profiler.EndSample();

                Profiler.BeginSample("new BrushMesh");
                BrushMesh brushMesh;
                if (brushContainer.brushMeshes[0] == null)
                {
                    brushMesh = new BrushMesh(brushOutline);
                    brushContainer.brushMeshes[0] = brushMesh;
                }
                else
                {
                    brushContainer.brushMeshes[0].CopyFrom(brushOutline);
                    brushMesh = brushContainer.brushMeshes[0];
                }
                Profiler.EndSample();

                Profiler.BeginSample("Definition.Validate");
                Validate();
                Profiler.EndSample();

                Profiler.BeginSample("Assign Materials");
                for (int p = 0; p < brushMesh.polygons.Length; p++)
                {
                    brushMesh.polygons[p].surface = surfaceDefinition.surfaces[p];
                }
                Profiler.EndSample();

                Profiler.BeginSample("BrushMesh.Validate");
                var valid = brushMesh.Validate();
                Profiler.EndSample();
                return(valid);
            }
            finally
            {
                Profiler.EndSample();
            }
        }
        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));
        }
Exemplo n.º 7
0
        public static bool GenerateBox(ref ChiselBrushContainer brushContainer, ref ChiselBoxDefinition definition)
        {
            definition.Validate();

            var min = definition.min;
            var max = definition.max;

            if (!BoundsExtensions.IsValid(min, max))
            {
                return(false);
            }

            brushContainer.EnsureSize(1);

            return(GenerateBox(ref brushContainer.brushMeshes[0], definition.min, definition.max, definition.surfaceDefinition));
        }
Exemplo n.º 8
0
        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));
        }
Exemplo n.º 9
0
        public static bool GenerateCylinder(ref ChiselBrushContainer brushContainer, ref ChiselCylinderDefinition definition)
        {
            definition.Validate();

            var tempTop    = definition.top;
            var tempBottom = definition.bottom;

            if (!definition.isEllipsoid)
            {
                tempTop.diameterZ    = tempTop.diameterX;
                tempBottom.diameterZ = tempBottom.diameterX;
            }

            brushContainer.EnsureSize(1);

            bool result = false;

            switch (definition.type)
            {
            case CylinderShapeType.Cylinder:       result = BrushMeshFactory.GenerateCylinder(ref brushContainer.brushMeshes[0], tempBottom, tempTop.height, definition.rotation, definition.sides, in definition.surfaceDefinition); break;
        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);
        }
Exemplo n.º 11
0
        public static bool GenerateTorus(ref ChiselBrushContainer brushContainer, ref ChiselTorusDefinition definition)
        {
            definition.Validate();
            Vector3[] vertices = null;
            if (!GenerateTorusVertices(definition, ref vertices))
            {
                return(false);
            }

            var tubeRadiusX = (definition.tubeWidth * 0.5f);
            var tubeRadiusY = (definition.tubeHeight * 0.5f);
            var torusRadius = (definition.outerDiameter * 0.5f) - tubeRadiusX;


            var horzSegments = definition.horizontalSegments;
            var vertSegments = definition.verticalSegments;

            brushContainer.EnsureSize(horzSegments);


            var horzDegreePerSegment = (definition.totalAngle / horzSegments);
            var vertDegreePerSegment = math.radians(360.0f / vertSegments);
            var descriptionIndex     = new int[2 + vertSegments];

            descriptionIndex[0] = 0;
            descriptionIndex[1] = 1;

            var circleVertices = new Vector3[vertSegments];

            var min             = new float2(float.PositiveInfinity, float.PositiveInfinity);
            var max             = new float2(float.NegativeInfinity, float.NegativeInfinity);
            var tubeAngleOffset = math.radians((((vertSegments & 1) == 1) ? 0.0f : ((360.0f / vertSegments) * 0.5f)) + definition.tubeRotation);

            for (int v = 0; v < vertSegments; v++)
            {
                var vRad = tubeAngleOffset + (v * vertDegreePerSegment);
                circleVertices[v] = new Vector3((math.cos(vRad) * tubeRadiusX) - torusRadius,
                                                (math.sin(vRad) * tubeRadiusY), 0);
                min.x = math.min(min.x, circleVertices[v].x);
                min.y = math.min(min.y, circleVertices[v].y);
                max.x = math.max(max.x, circleVertices[v].x);
                max.y = math.max(max.y, circleVertices[v].y);
                descriptionIndex[v + 2] = 2;
            }

            if (definition.fitCircle)
            {
                var center = (max + min) * 0.5f;
                var size   = (max - min) * 0.5f;
                size.x = tubeRadiusX / size.x;
                size.y = tubeRadiusY / size.y;
                for (int v = 0; v < vertSegments; v++)
                {
                    circleVertices[v].x  = (circleVertices[v].x - center.x) * size.x;
                    circleVertices[v].y  = (circleVertices[v].y - center.y) * size.y;
                    circleVertices[v].x -= torusRadius;
                }
            }

            var horzOffset = definition.startAngle;

            for (int h = 1, p = 0; h < horzSegments + 1; p = h, h++)
            {
                var hDegree0        = (p * horzDegreePerSegment) + horzOffset;
                var hDegree1        = (h * horzDegreePerSegment) + horzOffset;
                var rotation0       = quaternion.AxisAngle(new Vector3(0, 1, 0), hDegree0);
                var rotation1       = quaternion.AxisAngle(new Vector3(0, 1, 0), hDegree1);
                var subMeshVertices = new Vector3[vertSegments * 2];
                for (int v = 0; v < vertSegments; v++)
                {
                    subMeshVertices[v + vertSegments] = math.mul(rotation0, circleVertices[v]);
                    subMeshVertices[v] = math.mul(rotation1, circleVertices[v]);
                }

                var brushMesh = new BrushMesh();
                BrushMeshFactory.CreateExtrudedSubMesh(ref brushMesh, vertSegments, descriptionIndex, 0, 1, subMeshVertices, in definition.surfaceDefinition);
                if (!brushMesh.Validate())
                {
                    return(false);
                }

                brushContainer.brushMeshes[h - 1] = brushMesh;
            }
            return(true);
        }