private static MeshDraft Bracket(Vector3 origin, Vector3 width, Vector3 length,
                                  Vector3 innerOrigin, Vector3 innerWidth, Vector3 innerLength)
 {
     return(MeshDraft.TriangleStrip(new List <Vector3>
     {
         innerOrigin,
         origin,
         innerOrigin + innerLength,
         origin + length,
         innerOrigin + innerLength + innerWidth,
         origin + length + width,
         innerOrigin + innerWidth,
         origin + width
     }));
 }
        protected static MeshDraft Balcony(
            Vector3 origin,
            float width,
            float height,
            Color wallColor,
            Color frameColor,
            Color glassColor)
        {
            Vector3 widthVector  = Vector3.right * width;
            Vector3 heightVector = Vector3.up * height;

            var draft = Balcony(origin, width, wallColor);

            Vector3 innerHeightOffset = Vector3.up * BalconyThickness;

            Vector3 windowHeightOffset = Vector3.up * WindowBottomOffset;
            Vector3 windowWidth        = Vector3.right * (width - WindowWidthOffset * 2);
            Vector3 windowHeight       = Vector3.up * (height - WindowBottomOffset - WindowTopOffset);
            Vector3 windowDepth        = Vector3.forward * WindowDepth;

            int     rodCount   = Mathf.FloorToInt(windowWidth.magnitude / WindowSegmentMinWidth);
            Vector3 doorWidth  = Vector3.right * windowWidth.magnitude / (rodCount + 1);
            Vector3 doorHeight = windowHeightOffset + windowHeight;

            Vector3        outerFrameOrigin = origin + Vector3.right * WindowWidthOffset;
            List <Vector3> outerFrame       = new List <Vector3>
            {
                outerFrameOrigin + innerHeightOffset,
                outerFrameOrigin + doorHeight,
                outerFrameOrigin + windowWidth + doorHeight,
                outerFrameOrigin + windowWidth + windowHeightOffset,
                outerFrameOrigin + doorWidth + windowHeightOffset,
                outerFrameOrigin + doorWidth + innerHeightOffset
            };

            var panel = MeshDraft.TriangleStrip(new List <Vector3>
            {
                outerFrame[0],
                origin,
                outerFrame[1],
                origin + heightVector,
                outerFrame[2],
                origin + widthVector + heightVector,
                outerFrame[3],
                origin + widthVector,
                outerFrame[4],
                origin + widthVector,
                outerFrame[5]
            });

            panel.Paint(wallColor);

            draft.Add(panel);

            List <Vector3> innerFrame = new List <Vector3>();

            foreach (Vector3 vertex in outerFrame)
            {
                innerFrame.Add(vertex - windowDepth);
            }
            var frame = MeshDraft.FlatBand(innerFrame, outerFrame);

            frame.Paint(wallColor);
            draft.Add(frame);

            Vector3 windowpaneMin1 = outerFrame[0] - windowDepth;
            Vector3 windowpaneMin2 = outerFrame[4] - windowDepth;

            draft.Add(Windowpane(windowpaneMin1, windowpaneMin1 + doorWidth + doorHeight - innerHeightOffset,
                                 frameColor, glassColor));
            draft.Add(Windowpane(windowpaneMin2, windowpaneMin2 + windowWidth - doorWidth + windowHeight,
                                 frameColor, glassColor));

            return(draft);
        }
        public static MeshDraft Balcony(Vector3 origin, Vector3 width, Vector3 height)
        {
            Vector3 right         = width.normalized;
            Vector3 normal        = Vector3.Cross(height, width).normalized;
            Vector3 balconyWidth  = width;
            Vector3 balconyHeight = Vector3.up * BalconyHeight;
            Vector3 balconyDepth  = normal * BalconyDepth;

            var draft        = new MeshDraft();
            var balconyOuter = MeshDraft.Hexahedron(balconyWidth, balconyDepth, balconyHeight,
                                                    Directions.All & ~Directions.Up & ~Directions.Back);

            balconyOuter.FlipFaces();
            Vector3 balconyCenter = origin + width / 2 + balconyDepth / 2 + balconyHeight / 2;

            balconyOuter.Move(balconyCenter);
            balconyOuter.Paint(Khrushchyovka.wallColor);

            Vector3 innerWidthOffset  = right * BalconyThickness;
            Vector3 innerWidth        = balconyWidth - innerWidthOffset * 2;
            Vector3 innerHeightOffset = Vector3.up * BalconyThickness;
            Vector3 innerHeight       = balconyHeight - innerHeightOffset;
            Vector3 innerDepthOffset  = normal * BalconyThickness;
            Vector3 innerDepth        = balconyDepth - innerDepthOffset;
            var     balconyInner      = MeshDraft.Hexahedron(innerWidth, innerDepth, innerHeight,
                                                             Directions.All & ~Directions.Up & ~Directions.Back);

            balconyInner.Move(balconyCenter - innerDepthOffset / 2 + innerHeightOffset / 2);

            Vector3 borderOrigin      = origin + balconyWidth + balconyHeight;
            Vector3 borderInnerOrigin = borderOrigin - innerWidthOffset;
            var     balconyBorder     = Bracket(borderOrigin, -balconyWidth, balconyDepth,
                                                borderInnerOrigin, -innerWidth, innerDepth);

            draft.Add(balconyOuter);
            draft.Add(balconyInner);
            draft.Add(balconyBorder);

            Vector3 windowWidthOffset  = right * WindowWidthOffset;
            Vector3 windowHeightOffset = Vector3.up * WindowHeightOffset;
            Vector3 windowWidth        = right * (width.magnitude - WindowWidthOffset * 2);
            Vector3 windowHeight       = Vector3.up * WindowHeight;
            Vector3 windowDepth        = normal * WindowDepth;

            int     rodCount   = Mathf.FloorToInt(windowWidth.magnitude / WindowSegmentMinWidth);
            Vector3 doorWidth  = right * windowWidth.magnitude / (rodCount + 1);
            Vector3 doorHeight = windowHeightOffset + windowHeight;

            List <Vector3> outerFrame = new List <Vector3>
            {
                origin + windowWidthOffset + innerHeightOffset,
                origin + windowWidthOffset + doorHeight,
                origin + windowWidthOffset + windowWidth + doorHeight,
                origin + windowWidthOffset + windowWidth + windowHeightOffset,
                origin + windowWidthOffset + doorWidth + windowHeightOffset,
                origin + windowWidthOffset + doorWidth + innerHeightOffset
            };

            var panel = MeshDraft.TriangleStrip(new List <Vector3>
            {
                outerFrame[0],
                origin,
                outerFrame[1],
                origin + height,
                outerFrame[2],
                origin + width + height,
                outerFrame[3],
                origin + width,
                outerFrame[4],
                origin + width,
                outerFrame[5]
            });

            draft.Add(panel);

            List <Vector3> innerFrame = new List <Vector3>();

            foreach (Vector3 vertex in outerFrame)
            {
                innerFrame.Add(vertex - windowDepth);
            }
            var frame = MeshDraft.FlatBand(innerFrame, outerFrame);

            draft.Add(frame);

            draft.Paint(Khrushchyovka.wallColor);

            draft.Add(Windowpane(outerFrame[0] - windowDepth, doorWidth, doorHeight - innerHeightOffset));
            draft.Add(Windowpane(outerFrame[4] - windowDepth, windowWidth - doorWidth, windowHeight));

            return(draft);
        }