Example #1
0
 public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture)
 {
     var solid = new Solid(generator.GetNextObjectID()) { Colour = Colour.GetRandomBrushColour() };
     // The lower Z plane will be base, the x planes will be triangles
     var c1 = new Coordinate(box.Start.X, box.Start.Y, box.Start.Z);
     var c2 = new Coordinate(box.End.X, box.Start.Y, box.Start.Z);
     var c3 = new Coordinate(box.End.X, box.End.Y, box.Start.Z);
     var c4 = new Coordinate(box.Start.X, box.End.Y, box.Start.Z);
     var c5 = new Coordinate(box.Center.X, box.Start.Y, box.End.Z);
     var c6 = new Coordinate(box.Center.X, box.End.Y, box.End.Z);
     var faces = new[]
                     {
                         new[] { c1, c2, c3, c4 },
                         new[] { c2, c1, c5 },
                         new[] { c5, c6, c3, c2 },
                         new[] { c4, c3, c6 },
                         new[] { c6, c5, c1, c4 }
                     };
     foreach (var arr in faces)
     {
         var face = new Face(generator.GetNextFaceID())
                        {
                            Parent = solid,
                            Plane = new Plane(arr[0], arr[1], arr[2]),
                            Colour = solid.Colour,
                            Texture = { Texture = texture }
                        };
         face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
         face.UpdateBoundingBox();
         face.AlignTextureToFace();
         solid.Faces.Add(face);
     }
     solid.UpdateBoundingBox();
     yield return solid;
 }
Example #2
0
 public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
 {
     var solid = new Solid(generator.GetNextObjectID()) { Colour = Colour.GetRandomBrushColour() };
     // The higher Z plane will be triangle, with the lower X value getting the two corners
     var c1 = new Coordinate(box.Start.X, box.Start.Y, box.End.Z).Round(roundDecimals);
     var c2 = new Coordinate(box.End.X, box.Start.Y, box.End.Z).Round(roundDecimals);
     var c3 = new Coordinate(box.Center.X, box.End.Y, box.End.Z).Round(roundDecimals);
     var c4 = new Coordinate(box.Center.X, box.Center.Y, box.Start.Z).Round(roundDecimals);
     var faces = new[]
                     {
                         new[] { c3, c2, c1 },
                         new[] { c3, c1, c4 },
                         new[] { c2, c3, c4 },
                         new[] { c1, c2, c4 }
                     };
     foreach (var arr in faces)
     {
         var face = new Face(generator.GetNextFaceID())
                        {
                            Parent = solid,
                            Plane = new Plane(arr[0], arr[1], arr[2]),
                            Colour = solid.Colour,
                            Texture = { Texture = texture }
                        };
         face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
         face.UpdateBoundingBox();
         face.AlignTextureToFace();
         solid.Faces.Add(face);
     }
     solid.UpdateBoundingBox();
     yield return solid;
 }
Example #3
0
        public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture)
        {
            var numsides = (int) _numSides.GetValue();
            if (numsides < 3) yield break;

            // This is all very similar to the cylinder brush.
            var width = box.Width;
            var length = box.Length;
            var major = width / 2;
            var minor = length / 2;
            var angle = 2 * DMath.PI / numsides;

            var points = new Coordinate[numsides];
            for (var i = 0; i < numsides; i++)
            {
                var a = i * angle;
                var xval = box.Center.X + major * DMath.Cos(a);
                var yval = box.Center.Y + minor * DMath.Sin(a);
                var zval = box.Start.Z;
                points[i] = new Coordinate(xval, yval, zval).Round(0);
            }

            var faces = new List<Coordinate[]>();

            var point = new Coordinate(box.Center.X, box.Center.Y, box.End.Z);
            for (var i = 0; i < numsides; i++)
            {
                var next = (i + 1) % numsides;
                faces.Add(new[] {points[i], point, points[next]});
            }
            faces.Add(points.ToArray());

            var solid = new Solid(generator.GetNextObjectID()) { Colour = Colour.GetRandomBrushColour() };
            foreach (var arr in faces)
            {
                var face = new Face(generator.GetNextFaceID())
                {
                    Parent = solid,
                    Plane = new Plane(arr[0], arr[1], arr[2]),
                    Colour = solid.Colour,
                    Texture = { Texture = texture }
                };
                face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
                face.UpdateBoundingBox();
                face.AlignTextureToFace();
                solid.Faces.Add(face);
            }
            solid.UpdateBoundingBox();
            yield return solid;
        }
Example #4
0
 public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
 {
     var solid = new Solid(generator.GetNextObjectID()) { Colour = Colour.GetRandomBrushColour() };
     foreach (var arr in box.GetBoxFaces())
     {
         var face = new Face(generator.GetNextFaceID())
         {
             Parent = solid,
             Plane = new Plane(arr[0], arr[1], arr[2]),
             Colour = solid.Colour,
             Texture = { Texture = texture }
         };
         face.Vertices.AddRange(arr.Select(x => new Vertex(x.Round(roundDecimals), face)));
         face.UpdateBoundingBox();
         face.AlignTextureToFace();
         solid.Faces.Add(face);
     }
     solid.UpdateBoundingBox();
     yield return solid;
 }
Example #5
0
        public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
        {
            var numsides = (int) _numSides.GetValue();
            if (numsides < 3) yield break;

            // Cylinders can be elliptical so use both major and minor rather than just the radius
            // NOTE: when a low number (< 10ish) of faces are selected this will cause the cylinder to not touch all the edges of the box.
            var width = box.Width;
            var length = box.Length;
            var height = box.Height;
            var major = width / 2;
            var minor = length / 2;
            var angle = 2 * DMath.PI / numsides;

            // Calculate the X and Y points for the ellipse
            var points = new Coordinate[numsides];
            for (var i = 0; i < numsides; i++)
            {
                var a = i * angle;
                var xval = box.Center.X + major * DMath.Cos(a);
                var yval = box.Center.Y + minor * DMath.Sin(a);
                var zval = box.Start.Z;
                points[i] = new Coordinate(xval, yval, zval).Round(roundDecimals);
            }

            var faces = new List<Coordinate[]>();

            // Add the vertical faces
            var z = new Coordinate(0, 0, height).Round(roundDecimals);
            for (var i = 0; i < numsides; i++)
            {
                var next = (i + 1) % numsides;
                faces.Add(new[] {points[i], points[i] + z, points[next] + z, points[next]});
            }
            // Add the elliptical top and bottom faces
            faces.Add(points.ToArray());
            faces.Add(points.Select(x => x + z).Reverse().ToArray());

            // Nothing new here, move along
            var solid = new Solid(generator.GetNextObjectID()) { Colour = Colour.GetRandomBrushColour() };
            foreach (var arr in faces)
            {
                var face = new Face(generator.GetNextFaceID())
                {
                    Parent = solid,
                    Plane = new Plane(arr[0], arr[1], arr[2]),
                    Colour = solid.Colour,
                    Texture = { Texture = texture }
                };
                face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
                face.UpdateBoundingBox();
                face.AlignTextureToFace();
                solid.Faces.Add(face);
            }
            solid.UpdateBoundingBox();
            yield return solid;
        }
Example #6
0
 private Solid MakeSolid(IDGenerator generator, IEnumerable<Coordinate[]> faces, ITexture texture, Color col)
 {
     var solid = new Solid(generator.GetNextObjectID()) { Colour = col };
     foreach (var arr in faces)
     {
         var face = new Face(generator.GetNextFaceID())
         {
             Parent = solid,
             Plane = new Plane(arr[0], arr[1], arr[2]),
             Colour = solid.Colour,
             Texture = { Texture = texture }
         };
         face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
         face.UpdateBoundingBox();
         face.AlignTextureToFace();
         solid.Faces.Add(face);
     }
     solid.UpdateBoundingBox();
     return solid;
 }
Example #7
0
        public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
        {
            var width = box.Width;
            var length = Math.Max(1, Math.Abs((int) box.Length));
            var height = box.Height;
            var flatten = (float) _flattenFactor.Value;
            var text = _text.GetValue();

            var family = _fontChooser.GetFontFamily();
            var style = Enum.GetValues(typeof (FontStyle)).OfType<FontStyle>().FirstOrDefault(fs => family.IsStyleAvailable(fs));
            if (!family.IsStyleAvailable(style)) family = FontFamily.GenericSansSerif;

            var set = new PolygonSet();

            var sizes = new List<RectangleF>();
            using (var bmp = new Bitmap(1,1))
            {
                using (var g = System.Drawing.Graphics.FromImage(bmp))
                {
                    using (var font = new Font(family, length, style, GraphicsUnit.Pixel))
                    {
                        for (var i = 0; i < text.Length; i += 32)
                        {
                            using (var sf = new StringFormat(StringFormat.GenericTypographic))
                            {
                                var rem = Math.Min(text.Length, i + 32) - i;
                                var range = Enumerable.Range(0, rem).Select(x => new CharacterRange(x, 1)).ToArray();
                                sf.SetMeasurableCharacterRanges(range);
                                var reg = g.MeasureCharacterRanges(text.Substring(i, rem), font, new RectangleF(0, 0, float.MaxValue, float.MaxValue), sf);
                                sizes.AddRange(reg.Select(x => x.GetBounds(g)));
                            }
                        }
                    }
                }
            }

            var xOffset = box.Start.DX;
            var yOffset = box.End.DY;

            for (var ci = 0; ci < text.Length; ci++)
            {
                var c = text[ci];
                var size = sizes[ci];

                var gp = new GraphicsPath();
                gp.AddString(c.ToString(CultureInfo.InvariantCulture), family, (int)style, length, new PointF(0, 0), StringFormat.GenericTypographic);
                gp.Flatten(new System.Drawing.Drawing2D.Matrix(), flatten);

                var polygons = new List<Polygon>();
                var poly = new List<PolygonPoint>();

                for (var i = 0; i < gp.PointCount; i++)
                {
                    var type = gp.PathTypes[i];
                    var point = gp.PathPoints[i];

                    poly.Add(new PolygonPoint(point.X + xOffset, -point.Y + yOffset));

                    if ((type & 0x80) == 0x80)
                    {
                        polygons.Add(new Polygon(poly));
                        poly.Clear();
                    }
                }

                var tri = new List<Polygon>();
                Polygon polygon = null;
                foreach (var p in polygons)
                {
                    if (polygon == null)
                    {
                        polygon = p;
                        tri.Add(p);
                    }
                    else if (p.CalculateWindingOrder() != polygon.CalculateWindingOrder())
                    {
                        polygon.AddHole(p);
                    }
                    else
                    {
                        polygon = null;
                        tri.Add(p);
                    }
                }

                foreach (var pp in tri)
                {
                    try
                    {
                        P2T.Triangulate(pp);
                        set.Add(pp);
                    }
                    catch
                    {
                        // Ignore
                    }
                }

                xOffset += size.Width;
            }

            var zOffset = box.Start.Z;

            foreach (var polygon in set.Polygons)
            {
                foreach (var t in polygon.Triangles)
                {
                    var points = t.Points.Select(x => new Coordinate((decimal) x.X, (decimal) x.Y, zOffset).Round(roundDecimals)).ToList();

                    var faces = new List<Coordinate[]>();

                    // Add the vertical faces
                    var z = new Coordinate(0, 0, height).Round(roundDecimals);
                    for (var j = 0; j < points.Count; j++)
                    {
                        var next = (j + 1) % points.Count;
                        faces.Add(new[] {points[j], points[j] + z, points[next] + z, points[next]});
                    }
                    // Add the top and bottom faces
                    faces.Add(points.ToArray());
                    faces.Add(points.Select(x => x + z).Reverse().ToArray());

                    // Nothing new here, move along
                    var solid = new Solid(generator.GetNextObjectID()) {Colour = Colour.GetRandomBrushColour()};
                    foreach (var arr in faces)
                    {
                        var face = new Face(generator.GetNextFaceID())
                        {
                            Parent = solid,
                            Plane = new Plane(arr[0], arr[1], arr[2]),
                            Colour = solid.Colour,
                            Texture = {Texture = texture}
                        };
                        face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
                        face.UpdateBoundingBox();
                        face.AlignTextureToFace();
                        solid.Faces.Add(face);
                    }
                    solid.UpdateBoundingBox();
                    yield return solid;
                }
            }
        }
Example #8
0
        private Face ReadFace(string line, IDGenerator generator)
        {
            const NumberStyles ns = NumberStyles.Float;

            var parts = line.Split(' ').Where(x => !String.IsNullOrWhiteSpace(x)).ToList();

            Assert(parts[0] == "(");
            Assert(parts[4] == ")");
            Assert(parts[5] == "(");
            Assert(parts[9] == ")");
            Assert(parts[10] == "(");
            Assert(parts[14] == ")");

            var face = new Face(generator.GetNextFaceID())
            {
                Plane = new Plane(Coordinate.Parse(parts[1], parts[2], parts[3]),
                    Coordinate.Parse(parts[6], parts[7], parts[8]),
                    Coordinate.Parse(parts[11], parts[12], parts[13])),
                Texture = {Name = parts[15]}
            };

            // Cater for older-style map formats
            if (parts.Count == 21)
            {
                face.AlignTextureToFace();
                face.Texture.XShift = decimal.Parse(parts[16], ns, CultureInfo.InvariantCulture);
                face.Texture.YShift = decimal.Parse(parts[17], ns, CultureInfo.InvariantCulture);
                face.Texture.Rotation = decimal.Parse(parts[18], ns, CultureInfo.InvariantCulture);
                face.Texture.XScale = decimal.Parse(parts[19], ns, CultureInfo.InvariantCulture);
                face.Texture.YScale = decimal.Parse(parts[20], ns, CultureInfo.InvariantCulture);
            }
            else
            {
                Assert(parts[16] == "[");
                Assert(parts[21] == "]");
                Assert(parts[22] == "[");
                Assert(parts[27] == "]");

                face.Texture.UAxis = Coordinate.Parse(parts[17], parts[18], parts[19]);
                face.Texture.XShift = decimal.Parse(parts[20], ns, CultureInfo.InvariantCulture);
                face.Texture.VAxis = Coordinate.Parse(parts[23], parts[24], parts[25]);
                face.Texture.YShift = decimal.Parse(parts[26], ns, CultureInfo.InvariantCulture);
                face.Texture.Rotation = decimal.Parse(parts[28], ns, CultureInfo.InvariantCulture);
                face.Texture.XScale = decimal.Parse(parts[29], ns, CultureInfo.InvariantCulture);
                face.Texture.YScale = decimal.Parse(parts[30], ns, CultureInfo.InvariantCulture);
            }

            return face;
        }
Example #9
0
        private void PokeFace(Face face, int num)
        {
            var solid = face.Parent;
            // Remove the face
            solid.Faces.Remove(face);
            face.Parent = null;
            _selection.Remove(face);

            var center = face.BoundingBox.Center + face.Plane.Normal * num;
            foreach (var edge in face.GetEdges())
            {
                var v1 = face.Vertices.First(x => x.Location == edge.Start);
                var v2 = face.Vertices.First(x => x.Location == edge.End);
                var verts = new[] { v1.Location, v2.Location, center };
                var f = new Face(Document.Map.IDGenerator.GetNextFaceID())
                {
                    Parent = solid,
                    Plane = new Plane(verts[0], verts[1], verts[2]),
                    Colour = solid.Colour,
                    Texture = face.Texture.Clone()
                };
                f.Vertices.AddRange(verts.Select(x => new Vertex(x, face)));
                f.UpdateBoundingBox();
                f.AlignTextureToFace();
                solid.Faces.Add(f);
                _selection.Add(f);
            }
            solid.UpdateBoundingBox();
            UpdateSelection();

            MainTool.SetDirty(true, true);
        }
Example #10
0
        private void BevelFace(Face face, int num)
        {
            var solid = face.Parent;
            var vertexCoordinates = face.Vertices.ToDictionary(x => x, x => x.Location);
            // Scale the face a bit and move it away by the bevel distance
            face.Transform(new UnitScale(Coordinate.One * 0.9m, face.BoundingBox.Center), TransformFlags.TextureLock);
            face.Transform(new UnitTranslate(face.Plane.Normal * num), TransformFlags.TextureLock);
            foreach (var edge in face.GetEdges())
            {
                var v1 = face.Vertices.First(x => x.Location == edge.Start);
                var v2 = face.Vertices.First(x => x.Location == edge.End);
                var verts = new[] { vertexCoordinates[v1], vertexCoordinates[v2], v2.Location, v1.Location };
                var f = new Face(Document.Map.IDGenerator.GetNextFaceID())
                            {
                                Parent = solid,
                                Plane = new Plane(verts[0], verts[1], verts[2]),
                                Colour = solid.Colour,
                                Texture = face.Texture.Clone()
                            };
                f.Vertices.AddRange(verts.Select(x => new Vertex(x, face)));
                f.UpdateBoundingBox();
                f.AlignTextureToFace();
                solid.Faces.Add(f);
                _selection.Add(f);
            }
            solid.UpdateBoundingBox();
            UpdateSelection();

            MainTool.SetDirty(true, true);
        }