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));
        }
        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);
        }
Beispiel #3
0
        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);
        }