Beispiel #1
0
        public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
        {
            var numSides = (int)_numSides.GetValue();
            if (numSides < 3) yield break;

            var width = box.Width;
            var length = box.Length;
            var height = box.Height;
            var major = width / 2;
            var minor = length / 2;
            var heightRadius = height / 2;

            var angleV = DMath.DegreesToRadians(180) / numSides;
            var angleH = DMath.DegreesToRadians(360) / numSides;

            var faces = new List<Coordinate[]>();
            var bottom = new Coordinate(box.Center.X, box.Center.Y, box.Start.Z).Round(roundDecimals);
            var top = new Coordinate(box.Center.X, box.Center.Y, box.End.Z).Round(roundDecimals);

            for (var i = 0; i < numSides; i++)
            {
                // Top -> bottom
                var zAngleStart = angleV * i;
                var zAngleEnd = angleV * (i + 1);
                var zStart = heightRadius * DMath.Cos(zAngleStart);
                var zEnd = heightRadius * DMath.Cos(zAngleEnd);
                var zMultStart = DMath.Sin(zAngleStart);
                var zMultEnd = DMath.Sin(zAngleEnd);
                for (var j = 0; j < numSides; j++)
                {
                    // Go around the circle in X/Y
                    var xyAngleStart = angleH * j;
                    var xyAngleEnd = angleH * ((j + 1) % numSides);
                    var xyStartX = major * DMath.Cos(xyAngleStart);
                    var xyStartY = minor * DMath.Sin(xyAngleStart);
                    var xyEndX = major * DMath.Cos(xyAngleEnd);
                    var xyEndY = minor * DMath.Sin(xyAngleEnd);
                    var one = (new Coordinate(xyStartX * zMultStart, xyStartY * zMultStart, zStart) + box.Center).Round(roundDecimals);
                    var two = (new Coordinate(xyEndX * zMultStart, xyEndY * zMultStart, zStart) + box.Center).Round(roundDecimals);
                    var three = (new Coordinate(xyEndX * zMultEnd, xyEndY * zMultEnd, zEnd) + box.Center).Round(roundDecimals);
                    var four = (new Coordinate(xyStartX * zMultEnd, xyStartY * zMultEnd, zEnd) + box.Center).Round(roundDecimals);
                    if (i == 0)
                    {
                        // Top faces are triangles
                        faces.Add(new[] { top, three, four });
                    }
                    else if (i == numSides - 1)
                    {
                        // Bottom faces are also triangles
                        faces.Add(new[] { bottom, one, two });
                    }
                    else
                    {
                        // Inner faces are quads
                        faces.Add(new[] { one, two, three, four });
                    }
                }
            }
            yield return MakeSolid(generator, faces, texture, Colour.GetRandomBrushColour());
        }
Beispiel #2
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;
 }
Beispiel #3
0
        public PasteSpecialDialog(Box source)
        {
            _source = source;
            InitializeComponent();
            EntityPrefix.Enabled = PrefixEntityNamesCheckbox.Checked;

            ZeroOffsetXButton.Click += (sender, e) => OffsetX.Value = 0;
            ZeroOffsetYButton.Click += (sender, e) => OffsetY.Value = 0;
            ZeroOffsetZButton.Click += (sender, e) => OffsetZ.Value = 0;

            SourceOffsetXButton.Click += (sender, e) => OffsetX.Value = _source.Width;
            SourceOffsetYButton.Click += (sender, e) => OffsetY.Value = _source.Length;
            SourceOffsetZButton.Click += (sender, e) => OffsetZ.Value = _source.Height;

            ZeroRotationXButton.Click += (sender, e) => RotationX.Value = 0;
            ZeroRotationYButton.Click += (sender, e) => RotationY.Value = 0;
            ZeroRotationZButton.Click += (sender, e) => RotationZ.Value = 0;

            PrefixEntityNamesCheckbox.CheckedChanged += (sender, e) => EntityPrefix.Enabled = PrefixEntityNamesCheckbox.Checked;

            NumCopies.Value = _lastNumCopies;
            OffsetX.Value = _lastXOffset;
            OffsetY.Value = _lastYOffset;
            OffsetZ.Value = _lastZOffset;
            RotationX.Value = _lastXRotation;
            RotationY.Value = _lastYRotation;
            RotationZ.Value = _lastZRotation;
        }
Beispiel #4
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;
 }
 private decimal Extractor(Box box)
 {
     Coordinate coord;
     switch (_direction)
     {
         case AlignDirection.Min:
             coord = box.Start;
             break;
         case AlignDirection.Max:
             coord = box.End;
             break;
         default:
             throw new ArgumentOutOfRangeException();
     }
     switch (_axis)
     {
         case AlignAxis.X:
             return coord.X;
         case AlignAxis.Y:
             return coord.Y;
         case AlignAxis.Z:
             return coord.Z;
         default:
             throw new ArgumentOutOfRangeException();
     }
 }
 public AlignObjectsEditOperation(Box alignBox, AlignAxis axis, AlignDirection direction, TransformFlags transformFlags)
 {
     _alignBox = alignBox;
     _axis = axis;
     _direction = direction;
     _transformFlags = transformFlags;
 }
Beispiel #7
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;
        }
Beispiel #8
0
        public Map()
        {
            Version = 1;
            Visgroups = new List<Visgroup>();
            Cameras = new List<Camera>();
            ActiveCamera = null;
            IDGenerator = new IDGenerator();
            WorldSpawn = new World(IDGenerator.GetNextObjectID());

            Show2DGrid = SnapToGrid = true;
            TextureLock = true;
            HideDisplacementSolids = true;
            CordonBounds = new Box(Coordinate.One * -1024, Coordinate.One * 1024);
        }
Beispiel #9
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;
        }
Beispiel #10
0
        public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture)
        {
            var wallWidth = (int) _width.GetValue();
            if (wallWidth < 1) yield break;
            var numsides = (int) _numSides.GetValue();
            if (numsides < 3) yield break;

            // Very similar to the cylinder, except we have multiple solids this time
            var width = box.Width;
            var length = box.Length;
            var height = box.Height;
            var majorOut = width / 2;
            var majorIn = majorOut - wallWidth;
            var minorOut = length / 2;
            var minorIn = minorOut - wallWidth;
            var angle = 2 * DMath.PI / numsides;

            var colour = Colour.GetRandomBrushColour();

            // Calculate the X and Y points for the inner and outer ellipses
            var outer = new Coordinate[numsides];
            var inner = new Coordinate[numsides];
            for (var i = 0; i < numsides; i++)
            {
                var a = i * angle;
                var xval = box.Center.X + majorOut * DMath.Cos(a);
                var yval = box.Center.Y + minorOut * DMath.Sin(a);
                var zval = box.Start.Z;
                outer[i] = new Coordinate(xval, yval, zval).Round(0);
                xval = box.Center.X + majorIn * DMath.Cos(a);
                yval = box.Center.Y + minorIn * DMath.Sin(a);
                inner[i] = new Coordinate(xval, yval, zval).Round(0);
            }

            // Create the solids
            var z = new Coordinate(0, 0, height);
            for (var i = 0; i < numsides; i++)
            {
                var faces = new List<Coordinate[]>();
                var next = (i + 1) % numsides;
                faces.Add(new[] { outer[i], outer[i] + z, outer[next] + z, outer[next] });
                faces.Add(new[] { inner[next], inner[next] + z, inner[i] + z, inner[i] });
                faces.Add(new[] { outer[next], outer[next] + z, inner[next] + z, inner[next] });
                faces.Add(new[] { inner[i], inner[i] + z, outer[i] + z, outer[i] });
                faces.Add(new[] { inner[next] + z, outer[next] + z, outer[i] + z, inner[i] + z });
                faces.Add(new[] { inner[i], outer[i], outer[next], inner[next] });
                yield return MakeSolid(generator, faces, texture, colour);
            }
        }
Beispiel #11
0
        public TransformDialog(Box source)
        {
            _source = source;
            InitializeComponent();

            ZeroValueXButton.Click += (sender, e) => ValueX.Value = zeroValue;
            ZeroValueYButton.Click += (sender, e) => ValueY.Value = zeroValue;
            ZeroValueZButton.Click += (sender, e) => ValueZ.Value = zeroValue;

            SourceValueXButton.Click += (sender, e) => ValueX.Value = _source.Width;
            SourceValueYButton.Click += (sender, e) => ValueY.Value = _source.Length;
            SourceValueZButton.Click += (sender, e) => ValueZ.Value = _source.Height;

            TypeChanged(null, null);
        }
Beispiel #12
0
 public Cloud(IEnumerable<Coordinate> points)
 {
     Points = new List<Coordinate>(points);
     BoundingBox = new Box(points);
     MinX = MinY = MinZ = MaxX = MaxY = MaxZ = null;
     foreach (var p in points)
     {
         if (MinX == null || p.X < MinX.X) MinX = p;
         if (MinY == null || p.Y < MinY.Y) MinY = p;
         if (MinZ == null || p.Z < MinZ.Z) MinZ = p;
         if (MaxX == null || p.X > MaxX.X) MaxX = p;
         if (MaxY == null || p.Y > MaxY.Y) MaxY = p;
         if (MaxZ == null || p.Z > MaxZ.Z) MaxZ = p;
     }
 }
Beispiel #13
0
        public void CopyEntityTest()
        {
            var idGen = new IDGenerator();
            var box = new Box(Coordinate.One * -100, Coordinate.One * 100);

            // Create an entity with children
            var ent = new Entity(idGen.GetNextObjectID());
            ent.EntityData.Name = "Test";
            ent.EntityData.Properties.Add(new Property { Key = "key1", Value = "value1"});
            ent.EntityData.Properties.Add(new Property { Key = "key2", Value = "value2"});
            ent.EntityData.Flags = 12345;

            var solids = new BlockBrush().Create(idGen, box, null, 0);
            foreach (var mo in solids) mo.SetParent(ent);

            // Copy and reconstruct
            var gs = VmfProvider.CreateCopyStream(new List<MapObject> {ent});
            var pasted = VmfProvider.ExtractCopyStream(gs, idGen).ToList();

            // Test object
            Assert.AreEqual(1, pasted.Count);
            Assert.IsInstanceOfType(pasted[0], typeof(Entity));

            // Test entity
            var pastedEnt = (Entity) pasted[0];
            Assert.AreEqual("Test", pastedEnt.EntityData.Name);
            Assert.AreEqual(12345, pastedEnt.EntityData.Flags);

            // Test properties
            Assert.AreEqual(2, pastedEnt.EntityData.Properties.Count);
            var k1 = pastedEnt.EntityData.Properties.FirstOrDefault(x => x.Key == "key1");
            var k2 = pastedEnt.EntityData.Properties.FirstOrDefault(x => x.Key == "key1");
            Assert.IsNotNull(k1);
            Assert.IsNotNull(k2);
            Assert.AreEqual(k1.Value, "value1");
            Assert.AreEqual(k2.Value, "value1");

            // Test child
            Assert.AreEqual(1, pastedEnt.ChildCount);
            Assert.IsInstanceOfType(pastedEnt.GetChildren().ToList()[0], typeof(Solid));

            // Check number of sides, values of sides not so important
            var pastedSolid = (Solid) pastedEnt.GetChildren().ToList()[0];
            Assert.AreEqual(6, pastedSolid.Faces.Count);
        }
Beispiel #14
0
 public override void BoxDrawnConfirm(ViewportBase viewport)
 {
     var box = new Box(State.BoxStart, State.BoxEnd);
     if (box.Start.X != box.End.X && box.Start.Y != box.End.Y && box.Start.Z != box.End.Z)
     {
         CreateBrush(box);
         _lastBox = box;
     }
     _preview = null;
     base.BoxDrawnConfirm(viewport);
     if (Select.SwitchToSelectAfterCreation)
     {
         Mediator.Publish(HotkeysMediator.SwitchTool, HotkeyTool.Selection);
     }
     if (Select.ResetBrushTypeOnCreation)
     {
         Mediator.Publish(EditorMediator.ResetSelectedBrushType);
     }
 }
Beispiel #15
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;
 }
Beispiel #16
0
 public void BenchmarkSolidConstruction()
 {
     var idg = new IDGenerator();
     var box = new Box(Coordinate.One * -100, Coordinate.One * 100);
     var planes = new CylinderBrush().Create(idg, box, null, 2).OfType<Solid>().SelectMany(x => x.Faces).Select(x => x.Plane).ToList();
     var stopwatch = new Stopwatch();
     stopwatch.Start();
     for (var b = 0; b < 1000; b++)
     {
         Solid.CreateFromIntersectingPlanes(planes, idg);
     }
     stopwatch.Stop();
     Debug.WriteLine(stopwatch.Elapsed);
     stopwatch.Restart();
     for (var b = 0; b < 1000; b++)
     {
         var polys = new List<Polygon>();
         for (var i = 0; i < planes.Count; i++)
         {
             var poly = new Polygon(planes[i]);
             for (var j = 0; j < planes.Count; j++)
             {
                 if (i != j) poly.Split(planes[j]);
             }
             polys.Add(poly);
         }
         var solid = new Solid(idg.GetNextObjectID());
         foreach (var polygon in polys)
         {
             var face = new Face(idg.GetNextFaceID()) {Plane = polygon.Plane};
             face.Vertices.AddRange(polygon.Vertices.Select(x => new Vertex(x, face)));
             face.UpdateBoundingBox();
             face.AlignTextureToWorld();
             solid.Faces.Add(face);
         }
         solid.UpdateBoundingBox();
     }
     stopwatch.Stop();
     Debug.WriteLine(stopwatch.Elapsed);
 }
Beispiel #17
0
        public override void MouseMove(ViewportBase viewport, ViewportEvent e)
        {
            var vp = viewport as Viewport3D;
            if (vp == null) return;

            UpdateCurrentFace(vp, e);

            switch (_state)
            {
                case SketchState.None:
                case SketchState.Ready:
                    // face detect
                    break;
                case SketchState.DrawingBase:
                    _drawing = new Box(_drawing.Start, _intersection);
                    break;
                case SketchState.DrawingVolume:
                    _drawing = new Box(_drawing.Start, _intersection);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
Beispiel #18
0
 public override void BoxDrawnCancel(ViewportBase viewport)
 {
     _lastBox = new Box(State.BoxStart, State.BoxEnd);
     _preview = null;
     base.BoxDrawnCancel(viewport);
 }
Beispiel #19
0
 private MapObject GetBrush(Box bounds, IDGenerator idg)
 {
     var brush = BrushManager.CurrentBrush;
     var ti = Document.TextureCollection.SelectedTexture;
     var texture = ti != null ? ti.GetTexture() : null;
     var created = brush.Create(idg, bounds, texture, BrushManager.RoundCreatedVertices ? 0 : 2).ToList();
     if (created.Count > 1)
     {
         var g = new Group(idg.GetNextObjectID());
         created.ForEach(x => x.SetParent(g));
         g.UpdateBoundingBox();
         return g;
     }
     return created.FirstOrDefault();
 }
Beispiel #20
0
        private void CreateBrush(Box bounds)
        {
            var brush = GetBrush(bounds, Document.Map.IDGenerator);
            if (brush == null) return;

            brush.IsSelected = Select.SelectCreatedBrush;
            IAction action = new Create(Document.Map.WorldSpawn.ID, brush);
            if (Select.SelectCreatedBrush && Select.DeselectOthersWhenSelectingCreation)
            {
                action = new ActionCollection(new ChangeSelection(new MapObject[0], Document.Selection.GetSelectedObjects()), action);
            }

            Document.PerformAction("Create " + BrushManager.CurrentBrush.Name.ToLower(), action);
        }
Beispiel #21
0
 public override void UpdateFrame(ViewportBase viewport, FrameInfo frame)
 {
     if (_updatePreview && ShouldDrawBox(viewport))
     {
         var box = new Box(State.BoxStart, State.BoxEnd);
         var brush = GetBrush(box, new IDGenerator());
         _preview = new List<Face>();
         CollectFaces(_preview, new[] { brush });
         var color = GetRenderBoxColour();
         _preview.ForEach(x => { x.Colour = color; });
     }
     _updatePreview = false;
 }
Beispiel #22
0
 public override void ToolSelected(bool preventHistory)
 {
     BrushManager.ValuesChanged += ValuesChanged;
     var sel = Document.Selection.GetSelectedObjects().OfType<Solid>().ToList();
     if (sel.Any())
     {
         _lastBox = new Box(sel.Select(x => x.BoundingBox));
     }
     else if (_lastBox == null)
     {
         var gs = Document.Map.GridSpacing;
         _lastBox = new Box(Coordinate.Zero, new Coordinate(gs, gs, gs));
     }
     _updatePreview = true;
 }
Beispiel #23
0
 public override void UpdateBoundingBox()
 {
     var list = new List<Coordinate>();
     // LINQ doesn't seem to like multi-dimensional arrays
     foreach (var p in Points) list.Add(p.CurrentPosition.Location);
     BoundingBox = new Box(list);
 }
Beispiel #24
0
        private MapObject SelectionTest(Viewport2D viewport, ViewportEvent e)
        {
            // Create a box to represent the click, with a tolerance level
            var unused = viewport.GetUnusedCoordinate(new Coordinate(100000, 100000, 100000));
            var tolerance = 4 / viewport.Zoom; // Selection tolerance of four pixels
            var used = viewport.Expand(new Coordinate(tolerance, tolerance, 0));
            var add = used + unused;
            var click = viewport.Expand(viewport.ScreenToWorld(e.X, viewport.Height - e.Y));
            var box = new Box(click - add, click + add);

            var centerHandles = Sledge.Settings.Select.DrawCenterHandles;
            var centerOnly = Sledge.Settings.Select.ClickSelectByCenterHandlesOnly;
            // Get the first element that intersects with the box, selecting or deselecting as needed
            return Document.Map.WorldSpawn.GetAllNodesIntersecting2DLineTest(box, centerHandles, centerOnly).FirstOrDefault();
        }
Beispiel #25
0
        private void RenderTransformBox(Viewport2D viewport)
        {
            if (!CurrentTransform.HasValue) return;

            var box = new Box(State.PreTransformBoxStart, State.PreTransformBoxEnd);
            var trans = CreateMatrixMultTransformation(CurrentTransform.Value);
            box = box.Transform(trans);
            var s = viewport.Flatten(box.Start);
            var e = viewport.Flatten(box.End);

            GL.Enable(EnableCap.LineStipple);
            GL.LineStipple(10, 0xAAAA);
            GL.Begin(PrimitiveType.Lines);
            GL.Color4(Color.FromArgb(64, BoxColour));

            Coord(s.DX, s.DY, e.DZ);
            Coord(e.DX, s.DY, e.DZ);

            Coord(s.DX, e.DY, e.DZ);
            Coord(e.DX, e.DY, e.DZ);

            Coord(s.DX, s.DY, e.DZ);
            Coord(s.DX, e.DY, e.DZ);

            Coord(e.DX, s.DY, e.DZ);
            Coord(e.DX, e.DY, e.DZ);

            GL.End();
            GL.Disable(EnableCap.LineStipple);

            RenderBoxText(viewport, s, e);
        }
Beispiel #26
0
        protected override void MouseDraggingToResize(Viewport2D viewport, ViewportEvent e)
        {
            if (_currentTool == null)
            {
                base.MouseDraggingToResize(viewport, e);
                return;
            }

            State.Action = BoxAction.Resizing;
            CurrentTransform = GetTransformMatrix(viewport, e);
            if (CurrentTransform.HasValue)
            {
                Document.SetSelectListTransform(CurrentTransform.Value);
                var box = new Box(State.PreTransformBoxStart, State.PreTransformBoxEnd);
                var trans = CreateMatrixMultTransformation(CurrentTransform.Value);
                Mediator.Publish(EditorMediator.SelectionBoxChanged, box.Transform(trans));
            }
            else
            {
                //OnBoxChanged();
            }
        }
Beispiel #27
0
        public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
        {
            var numSides = (int)_numSides.GetValue();
            if (numSides < 3) yield break;
            var wallWidth = _wallWidth.GetValue();
            if (wallWidth < 1) yield break;
            var arc = _arc.GetValue();
            if (arc < 1) yield break;
            var startAngle = _startAngle.GetValue();
            if (startAngle < 0 || startAngle > 359) yield break;
            var addHeight = _addHeight.GetValue();
            var curvedRamp = _curvedRamp.GetValue();
            var tiltAngle = curvedRamp ? _tiltAngle.GetValue() : 0;
            if (DMath.Abs(tiltAngle % 180) == 90) yield break;
            var tiltInterp = curvedRamp && _tiltInterp.GetValue();

            // Very similar to the pipe brush, except with options for start angle, arc, height and tilt
            var width = box.Width;
            var length = box.Length;
            var height = box.Height;

            var majorOut = width / 2;
            var majorIn = majorOut - wallWidth;
            var minorOut = length / 2;
            var minorIn = minorOut - wallWidth;

            var start = DMath.DegreesToRadians(startAngle);
            var tilt = DMath.DegreesToRadians(tiltAngle);
            var angle = DMath.DegreesToRadians(arc) / numSides;

            var colour = Colour.GetRandomBrushColour();

            // Calculate the coordinates of the inner and outer ellipses' points
            var outer = new Coordinate[numSides + 1];
            var inner = new Coordinate[numSides + 1];
            for (var i = 0; i < numSides + 1; i++)
            {
                var a = start + i * angle;
                var h = i * addHeight;
                var interp = tiltInterp ? DMath.Cos(DMath.PI / numSides * (i - numSides / 2M)) : 1;
                var tiltHeight = wallWidth / 2 * interp * DMath.Tan(tilt);

                var xval = box.Center.X + majorOut * DMath.Cos(a);
                var yval = box.Center.Y + minorOut * DMath.Sin(a);
                var zval = box.Start.Z + (curvedRamp ? h + tiltHeight : 0);
                outer[i] = new Coordinate(xval, yval, zval).Round(roundDecimals);

                xval = box.Center.X + majorIn * DMath.Cos(a);
                yval = box.Center.Y + minorIn * DMath.Sin(a);
                zval = box.Start.Z + (curvedRamp ? h - tiltHeight : 0);
                inner[i] = new Coordinate(xval, yval, zval).Round(roundDecimals);
            }

            // Create the solids
            for (var i = 0; i < numSides; i++)
            {
                var faces = new List<Coordinate[]>();
                var z = new Coordinate(0, 0, height).Round(roundDecimals);

                // Since we are triangulating/splitting each arch segment, we need to generate 2 brushes per side
                if (curvedRamp)
                {
                    // The splitting orientation depends on the curving direction of the arch
                    if (addHeight >= 0)
                    {
                        faces.Add(new[] { outer[i],       outer[i] + z,   outer[i+1] + z, outer[i+1] });
                        faces.Add(new[] { outer[i+1],     outer[i+1] + z, inner[i] + z,   inner[i]   });
                        faces.Add(new[] { inner[i],       inner[i] + z,   outer[i] + z,   outer[i]   });
                        faces.Add(new[] { outer[i] + z,   inner[i] + z,   outer[i+1] + z  });
                        faces.Add(new[] { outer[i+1],     inner[i],       outer[i]        });
                    }
                    else
                    {
                        faces.Add(new[] { inner[i+1],     inner[i+1] + z, inner[i] + z,   inner[i]   });
                        faces.Add(new[] { outer[i],       outer[i] + z,   inner[i+1] + z, inner[i+1] });
                        faces.Add(new[] { inner[i],       inner[i] + z,   outer[i] + z,   outer[i]   });
                        faces.Add(new[] { inner[i+1] + z, outer[i] + z,   inner[i] + z    });
                        faces.Add(new[] { inner[i],       outer[i],       inner[i+1]      });
                    }
                    yield return MakeSolid(generator, faces, texture, colour);

                    faces.Clear();

                    if (addHeight >= 0)
                    {
                        faces.Add(new[] { inner[i+1],     inner[i+1] + z, inner[i] + z,   inner[i]   });
                        faces.Add(new[] { inner[i],       inner[i] + z,   outer[i+1] + z, outer[i+1] });
                        faces.Add(new[] { outer[i+1],     outer[i+1] + z, inner[i+1] + z, inner[i+1] });
                        faces.Add(new[] { inner[i+1] + z, outer[i+1] + z, inner[i] + z    });
                        faces.Add(new[] { inner[i],       outer[i+1],     inner[i+1]      });
                    }
                    else
                    {
                        faces.Add(new[] { outer[i],       outer[i] + z,   outer[i+1] + z, outer[i+1] });
                        faces.Add(new[] { inner[i+1],     inner[i+1] + z, outer[i] + z,   outer[i]   });
                        faces.Add(new[] { outer[i+1],     outer[i+1] + z, inner[i+1] + z, inner[i+1] });
                        faces.Add(new[] { outer[i] + z,   inner[i+1] + z, outer[i+1] + z  });
                        faces.Add(new[] { outer[i+1],     inner[i+1],     outer[i]        });
                    }
                    yield return MakeSolid(generator, faces, texture, colour);
                }
                else
                {
                    var h = i * addHeight * Coordinate.UnitZ;
                    faces.Add(new[] { outer[i],       outer[i] + z,   outer[i+1] + z, outer[i+1]   }.Select(x => x + h).ToArray());
                    faces.Add(new[] { inner[i+1],     inner[i+1] + z, inner[i] + z,   inner[i]     }.Select(x => x + h).ToArray());
                    faces.Add(new[] { outer[i+1],     outer[i+1] + z, inner[i+1] + z, inner[i+1]   }.Select(x => x + h).ToArray());
                    faces.Add(new[] { inner[i],       inner[i] + z,   outer[i] + z,   outer[i]     }.Select(x => x + h).ToArray());
                    faces.Add(new[] { inner[i+1] + z, outer[i+1] + z, outer[i] + z,   inner[i] + z }.Select(x => x + h).ToArray());
                    faces.Add(new[] { inner[i],       outer[i],       outer[i+1],     inner[i+1]   }.Select(x => x + h).ToArray());
                    yield return MakeSolid(generator, faces, texture, colour);
                }
            }
        }
Beispiel #28
0
 public override void UpdateBoundingBox(bool cascadeToParent = true)
 {
     BoundingBox = new Box(Faces.Select(x => x.BoundingBox));
     base.UpdateBoundingBox(cascadeToParent);
 }
Beispiel #29
0
 public override void ToolSelected(bool preventHistory)
 {
     _state = SketchState.None;
     _currentFace = _cloneFace = null;
     _intersection = null;
     _drawing = null;
     _volumePlane = null;
 }
Beispiel #30
0
 public override void MouseDown(ViewportBase viewport, ViewportEvent e)
 {
     //
     switch (_state)
     {
         case SketchState.None:
             // nothin
             break;
         case SketchState.Ready:
             if (e.Button != MouseButtons.Left) break;
             _drawing = new Box(_intersection, _intersection);
             _state = SketchState.DrawingBase;
             break;
         case SketchState.DrawingBase:
             if (e.Button == MouseButtons.Right)
             {
                 // Cancel
                 _state = SketchState.None;
                 _drawing = null;
             }
             else if (e.Button == MouseButtons.Left)
             {
                 _drawing = new Box(_drawing.Start, _intersection);
                 _volumePlane = new Plane(new Coordinate(_drawing.End.X, _drawing.Start.Y, _drawing.Start.Z), _drawing.End, _drawing.End + _currentFace.Plane.Normal);
                 _state = SketchState.DrawingVolume;
             }
             break;
         case SketchState.DrawingVolume:
             if (e.Button == MouseButtons.Right)
             {
                 _state = SketchState.DrawingBase;
                 _volumePlane = null;
             }
             else if (e.Button == MouseButtons.Left)
             {
                 CreateBrush(new Box(new[] {_drawing.Start, _drawing.End}));
                 _drawing = null;
                 _volumePlane = null;
                 _state = SketchState.None;
             }
             break;
         default:
             throw new ArgumentOutOfRangeException();
     }
 }