public void Transform()
        {
            if (_document.Selection.IsEmpty() || _document.Selection.InFaceSelection)
            {
                return;
            }
            var box = _document.Selection.GetSelectionBoundingBox();

            using (var td = new TransformDialog(box))
            {
                if (td.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                var value = td.TransformValue;
                IUnitTransformation transform = null;
                switch (td.TransformType)
                {
                case TransformType.Rotate:
                    var mov = Matrix.Translation(-box.Center);                                 // Move to zero
                    var rot = Matrix.Rotation(Quaternion.EulerAngles(value * DMath.PI / 180)); // Do rotation
                    var fin = Matrix.Translation(box.Center);                                  // Move to final origin
                    transform = new UnitMatrixMult(fin * rot * mov);
                    break;

                case TransformType.Translate:
                    transform = new UnitTranslate(value);
                    break;

                case TransformType.Scale:
                    transform = new UnitScale(value, box.Center);
                    break;
                }

                if (transform == null)
                {
                    return;
                }

                var selected = _document.Selection.GetSelectedParents();
                _document.PerformAction("Transform selection", new Edit(selected, new TransformEditOperation(transform, _document.Map.GetTransformFlags())));
            }
        }
Example #2
0
 public static Matrix Rotation(Quaternion quaternion)
 {
     var aa = quaternion.GetAxisAngle();
     return Rotation(aa.Item1, aa.Item2);
 }
Example #3
0
 public Coordinate Rotate(Coordinate coord)
 {
     // http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation
     var q = new Quaternion(coord.Normalise(), 0);
     var temp = q * Conjugate();
     return (this * temp).Vector;
 }
Example #4
0
        public void Draw3D(ViewportBase context, Matrix4 viewport, Matrix4 camera, Matrix4 modelView)
        {
            var type = ((Viewport3D)context).Type;
            var opts = new Viewport3DRenderOptions
            {
                Viewport    = viewport,
                Camera      = camera,
                ModelView   = modelView,
                ShowGrid    = Document.Map.Show3DGrid,
                GridSpacing = Document.Map.GridSpacing,
                Shaded      = type == Viewport3D.ViewType.Shaded || type == Viewport3D.ViewType.Textured,
                Textured    = type == Viewport3D.ViewType.Textured,
                Wireframe   = type == Viewport3D.ViewType.Wireframe
            };

            var cam      = ((Viewport3D)context).Camera.Location;
            var location = new Coordinate((decimal)cam.X, (decimal)cam.Y, (decimal)cam.Z);

            if (!opts.Wireframe)
            {
                _mapObject3DShader.Bind(opts);
                _mapObject3DShader.SelectionTransform        = _selectionTransform;
                _mapObject3DShader.SelectionColourMultiplier = Document.Map.HideFaceMask &&
                                                               Document.Selection.InFaceSelection
                                                                   ? new Vector4(1, 1, 1, 1)
                                                                   : new Vector4(1, 0.5f, 0.5f, 1);

                // Render textured polygons
                _array.RenderTextured(context.Context);

                // Render textured models
                if (!Sledge.Settings.View.DisableModelRendering)
                {
                    foreach (var tuple in _models)
                    {
                        var arr    = _modelArrays[tuple.Item2];
                        var origin = tuple.Item1.Origin;
                        if (tuple.Item1.HideDistance() <= (location - origin).VectorMagnitude())
                        {
                            continue;
                        }

                        var angles = tuple.Item1.EntityData.GetPropertyCoordinate("angles", Coordinate.Zero);
                        angles = new Coordinate(-DMath.DegreesToRadians(angles.Z), DMath.DegreesToRadians(angles.X),
                                                -DMath.DegreesToRadians(angles.Y));
                        if (tuple.Item1.IsSelected)
                        {
                            origin *= _selectionTransformMat;
                            // TODO: rotation/angles
                        }
                        var tform = Matrix.Rotation(Quaternion.EulerAngles(angles)).Translate(origin);
                        _mapObject3DShader.Transformation = tform.ToGLSLMatrix4();
                        arr.RenderTextured(context.Context);
                    }
                    _mapObject3DShader.Transformation = Matrix4.Identity;
                }

                // Render untextured polygons
                _mapObject3DShader.IsTextured = false;
                _array.RenderUntextured(context.Context, location);

                // todo Render sprites

                _mapObject3DShader.Unbind();
            }

            // Render wireframe
            _mapObject2DShader.Bind(opts);
            _mapObject2DShader.SelectedColour = new Vector4(1, 1, 0, 1);

            if (opts.Wireframe)
            {
                _mapObject2DShader.SelectedOnly       = false;
                _mapObject2DShader.SelectionTransform = _selectionTransform;
                _array.RenderWireframe(context.Context);
                _decalArray.RenderWireframe(context.Context);
            }

            if (!Document.Selection.InFaceSelection || !Document.Map.HideFaceMask)
            {
                _mapObject2DShader.SelectedOnly       = true;
                _mapObject2DShader.SelectionTransform = Matrix4.Identity;
                _array.RenderWireframe(context.Context);
                _decalArray.RenderWireframe(context.Context);
            }

            _mapObject2DShader.Unbind();

            if (!opts.Wireframe)
            {
                // Render transparent
                _mapObject3DShader.Bind(opts);
                _decalArray.RenderTransparent(context.Context, location);
                _array.RenderTransparent(context.Context, x => _mapObject3DShader.IsTextured = x && opts.Textured, location);
                _mapObject3DShader.Unbind();
            }
        }
Example #5
0
 public bool Equals(Quaternion other)
 {
     if (ReferenceEquals(null, other)) return false;
     if (ReferenceEquals(this, other)) return true;
     return Equals(other.Vector, Vector) && other.Scalar == Scalar;
 }
Example #6
0
 public decimal Dot(Quaternion c)
 {
     return Vector.Dot(c.Vector) + Scalar * c.Scalar;
 }
Example #7
0
        public static Quaternion Slerp(Quaternion start, Quaternion end, decimal blend)
        {
            // Clone to avoid modifying the parameters
            var q1 = start.Clone();
            var q2 = end.Clone();

            // if either input is zero, return the other.
            if (q1.Magnitude() == 0) return q2.Magnitude() == 0 ? Identity : q2;
            if (q2.Magnitude() == 0) return q1;

            var cosHalfAngle = q1.Dot(q2);

            if (cosHalfAngle >= 1 || cosHalfAngle <= -1) return q1;

            if (cosHalfAngle < 0)
            {
                q2.Vector = -q2.Vector;
                q2.Scalar = -q2.Scalar;
                cosHalfAngle = -cosHalfAngle;
            }

            decimal blendA;
            decimal blendB;
            if (cosHalfAngle < 0.99m)
            {
                // do proper slerp for big angles
                var halfAngle = DMath.Acos(cosHalfAngle);
                var sinHalfAngle = DMath.Sin(halfAngle);
                var oneOverSinHalfAngle = 1 / sinHalfAngle;
                blendA = DMath.Sin(halfAngle * (1 - blend)) * oneOverSinHalfAngle;
                blendB = DMath.Sin(halfAngle * blend) * oneOverSinHalfAngle;
            }
            else
            {
                // do lerp if angle is really small.
                blendA = 1 - blend;
                blendB = blend;
            }

            var result = new Quaternion(blendA * q1.Vector + blendB * q2.Vector, blendA * q1.W + blendB * q2.W);
            return result.Magnitude() > 0 ? result.Normalise() : Identity;
        }
Example #8
0
        public static Quaternion Lerp(Quaternion start, Quaternion end, decimal blend)
        {
            // Clone to avoid modifying the parameters
            var q1 = start.Clone();
            var q2 = end.Clone();

            // if either input is zero, return the other.
            if (q1.Magnitude() == 0) return q2.Magnitude() == 0 ? Identity : q2;
            if (q2.Magnitude() == 0) return q1;

            var blendA = 1 - blend;
            var blendB = blend;

            var result = new Quaternion(blendA * q1.Vector + blendB * q2.Vector, blendA * q1.W + blendB * q2.W);
            return result.Magnitude() > 0 ? result.Normalise() : Identity;
        }
Example #9
0
        public void Draw3D(ViewportBase context, Matrix4 viewport, Matrix4 camera, Matrix4 modelView)
        {
            var type     = ((Viewport3D)context).Type;
            var cam      = ((Viewport3D)context).Camera.Location;
            var location = new Coordinate((decimal)cam.X, (decimal)cam.Y, (decimal)cam.Z);

            UpdateCache();

            Matrix4 current;

            GL.GetFloat(GetPName.ModelviewMatrix, out current);
            GL.MatrixMode(MatrixMode.Modelview);

            bool shaded    = type == Viewport3D.ViewType.Shaded || type == Viewport3D.ViewType.Textured,
                 textured  = type == Viewport3D.ViewType.Textured,
                 wireframe = type == Viewport3D.ViewType.Wireframe;

            if (shaded)
            {
                MapObjectRenderer.EnableLighting();
            }
            if (!textured)
            {
                GL.Disable(EnableCap.Texture2D);
            }
            else
            {
                GL.Enable(EnableCap.Texture2D);
            }

            if (!wireframe)
            {
                GL.CallList(textured ? _listUntransformed3DTextured : _listUntransformed3DFlat);
                GL.CallList(_listUntransformed3D);

                // Render models
                if (!View.DisableModelRendering)
                {
                    foreach (var tuple in _models)
                    {
                        var arr    = _modelLists[tuple.Item2];
                        var origin = tuple.Item1.Origin;
                        if (tuple.Item1.HideDistance() <= (location - origin).VectorMagnitude())
                        {
                            MapObjectRenderer.DrawFilled(tuple.Item1.GetBoxFaces(), Color.Empty, textured);
                        }
                        else
                        {
                            var angles = tuple.Item1.EntityData.GetPropertyCoordinate("angles", Coordinate.Zero);
                            angles = new Coordinate(DMath.DegreesToRadians(angles.Z), DMath.DegreesToRadians(angles.X), DMath.DegreesToRadians(angles.Y));
                            if (tuple.Item1.IsSelected)
                            {
                                origin *= _selectionTransformMat;
                            }
                            var tform = Matrix.Rotation(Quaternion.EulerAngles(angles)).Translate(origin).ToOpenTKMatrix4();
                            GL.MultMatrix(ref tform);

                            GL.CallList(arr);
                            GL.LoadMatrix(ref current);
                        }
                    }
                }
            }
            else
            {
                GL.CallList(_listUntransformed2D);
            }

            GL.MultMatrix(ref _selectionTransform);
            if (!wireframe)
            {
                GL.CallList(textured ? _listTransformed3DTextured : _listTransformed3DFlat);
            }
            else
            {
                GL.CallList(_listTransformed2D);
            }
            GL.LoadMatrix(ref current);

            if (!wireframe)
            {
                foreach (var face in _transparentFaces.OrderByDescending(x => (location - x.BoundingBox.Center).LengthSquared()))
                {
                    var sel = (!Document.Map.HideFaceMask || !Document.Selection.InFaceSelection) && (face.IsSelected || (face.Parent != null && face.Parent.IsSelected));
                    if (sel)
                    {
                        GL.MultMatrix(ref _selectionTransform);
                    }
                    MapObjectRenderer.DrawFilled(new[] { face }, sel ? Color.FromArgb(255, 255, 128, 128) : Color.Empty, true);
                    GL.LoadMatrix(ref current);
                }
            }
            else
            {
                if (Document.Map.HideFaceMask && Document.Selection.InFaceSelection)
                {
                    MapObjectRenderer.DrawWireframe(_transparentFaces, false, true);
                }
                else
                {
                    MapObjectRenderer.DrawWireframe(_transparentFaces.Where(x => !x.IsSelected && (x.Parent == null || !x.Parent.IsSelected)), false, true);
                    GL.Color4(Color.Red);
                    MapObjectRenderer.DrawWireframe(_transparentFaces.Where(x => x.IsSelected || (x.Parent != null && x.Parent.IsSelected)), true, true);
                }
            }

            MapObjectRenderer.DisableLighting();
        }