Пример #1
0
        private void butSaveChanges_Click(object sender, EventArgs e)
        {
            // Check if we need to transform mesh
            var transform = panelRendering.GizmoTransform;

            if (transform != Matrix4x4.Identity)
            {
                for (int i = 0; i < _workingStatic.Mesh.VerticesPositions.Count; i++)
                {
                    var position = MathC.HomogenousTransform(_workingStatic.Mesh.VerticesPositions[i], transform);
                    _workingStatic.Mesh.VerticesPositions[i] = new Vector3(position.X, position.Y, position.Z);
                }

                for (int i = 0; i < _workingStatic.Mesh.VerticesNormals.Count; i++)
                {
                    var normal = MathC.HomogenousTransform(_workingStatic.Mesh.VerticesNormals[i], transform);
                    _workingStatic.Mesh.VerticesNormals[i] = new Vector3(normal.X, normal.Y, normal.Z);
                }
            }

            // Assign the edited mesh to original static mesh
            _wad.Statics.Remove(_workingStatic.Id);
            _wad.Statics.Add(_workingStatic.Id, _workingStatic);

            _workingStatic.Version = DataVersion.GetNext();

            _tool.ToggleUnsavedChanges();

            DialogResult = DialogResult.OK;
            Close();
        }
Пример #2
0
        public BoundingBox CalculateBoundingBox(AnimatedModel model, AnimatedModel skin, List <int> meshesToUse = null)
        {
            Vector3 min = new Vector3(float.MaxValue);
            Vector3 max = new Vector3(float.MinValue);

            for (int i = 0; i < skin.Meshes.Count; i++)
            {
                if (meshesToUse != null && !meshesToUse.Contains(i))
                {
                    continue;
                }

                foreach (var vertex in skin.Meshes[i].Vertices)
                {
                    var transformedPosition = MathC.HomogenousTransform(vertex.Position, model.AnimationTransforms[i]);
                    min = Vector3.Min(transformedPosition, min);
                    max = Vector3.Max(transformedPosition, max);
                }
            }

            BoundingBox = new BoundingBox(new Vector3((int)min.X, (int)max.Y, (int)min.Z),
                                          new Vector3((int)max.X, (int)min.Y, (int)max.Z));

            return(BoundingBox);
        }
Пример #3
0
        public override Vector3 GetDirection()
        {
            Matrix4x4 rotation = GetRotationMatrix();
            Vector3   look     = MathC.HomogenousTransform(Vector3.UnitZ, rotation);

            return(Vector3.Normalize(look));
        }
Пример #4
0
 public override Vector3 GetDirection()
 {
     // Translate down the Z axis by the desired distance
     // between the camera and object, then rotate that
     // vector to find the camera offset from the target
     return(MathC.HomogenousTransform(new Vector3(0, 0, Distance), GetRotationMatrix()));
 }
Пример #5
0
        public override void MoveCameraPlane(Vector3 movementVec)
        {
            Matrix4x4 rotation = GetRotationMatrix();

            Vector3 look  = MathC.HomogenousTransform(Vector3.UnitZ, rotation);
            Vector3 right = MathC.HomogenousTransform(Vector3.UnitX, rotation);
            Vector3 up    = Vector3.Cross(look, right);

            Position -= movementVec.Z * look;
            Position -= movementVec.X * right;
        }
Пример #6
0
        public override Matrix4x4 GetViewProjectionMatrix(float width, float height)
        {
            // Calculate up vector
            Matrix4x4 rotation = Matrix4x4.CreateFromYawPitchRoll(RotationY, -RotationX, 0);
            Vector3   up       = MathC.HomogenousTransform(Vector3.UnitY, rotation);

            //new Vector3(0, 150, 0), Vector3.Up);
            Matrix4x4 View        = MathC.Matrix4x4CreateLookAtLH(GetPosition(), Target, up);
            float     aspectRatio = width / height;
            Matrix4x4 Projection  = MathC.Matrix4x4CreatePerspectiveFieldOfViewLH(FieldOfView, aspectRatio, 20.0f, 1000000.0f);
            Matrix4x4 result      = View * Projection;

            return(result);
        }
Пример #7
0
        private bool DoMeshPicking(Ray ray, int meshIndex, out float meshDistance)
        {
            meshDistance = 0;

            // Transform view ray to object space space
            Matrix4x4 inverseObjectMatrix;

            if (!Matrix4x4.Invert((_editor.CurrentAnim != null ? _model.AnimationTransforms[meshIndex] : _model.BindPoseTransforms[meshIndex]), out inverseObjectMatrix))
            {
                return(false);
            }
            Vector3 transformedRayPos         = MathC.HomogenousTransform(ray.Position, inverseObjectMatrix);
            Vector3 transformedRayDestination = MathC.HomogenousTransform(ray.Position + ray.Direction, inverseObjectMatrix);
            Ray     transformedRay            = new Ray(transformedRayPos, transformedRayDestination - transformedRayPos);

            transformedRay.Direction = Vector3.Normalize(transformedRay.Direction);

            // Now do a ray - triangle intersection test
            bool  hit         = false;
            float minDistance = float.PositiveInfinity;
            var   mesh        = _skinModel.Meshes[meshIndex];

            foreach (var submesh in mesh.Submeshes)
            {
                for (int k = 0; k < submesh.Value.Indices.Count; k += 3)
                {
                    Vector3 p1 = mesh.Vertices[submesh.Value.Indices[k]].Position;
                    Vector3 p2 = mesh.Vertices[submesh.Value.Indices[k + 1]].Position;
                    Vector3 p3 = mesh.Vertices[submesh.Value.Indices[k + 2]].Position;

                    float distance;
                    if (Collision.RayIntersectsTriangle(transformedRay, p1, p2, p3, out distance) && distance < minDistance)
                    {
                        minDistance = distance;
                        hit         = true;
                    }
                }
            }

            if (hit)
            {
                meshDistance = minDistance;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #8
0
        public override Matrix4x4 GetViewProjectionMatrix(float width, float height)
        {
            Matrix4x4 rotation = GetRotationMatrix();

            Vector3 look  = MathC.HomogenousTransform(Vector3.UnitZ, rotation);
            Vector3 right = MathC.HomogenousTransform(Vector3.UnitX, rotation);
            Vector3 up    = Vector3.Cross(look, right);

            Target = Position + 1024.0f * look;

            Matrix4x4 View = MathC.Matrix4x4CreateLookAtLH(Position, Target, up);

            float     aspectRatio = width / height;
            Matrix4x4 Projection  = MathC.Matrix4x4CreatePerspectiveFieldOfViewLH(FieldOfView, aspectRatio, 20.0f, 1000000.0f);
            Matrix4x4 result      = View * Projection;

            return(result);
        }
Пример #9
0
        public BoundingBox CalculateBoundingBox(Matrix4x4 transform)
        {
            float minX = float.MaxValue;
            float minY = float.MaxValue;
            float minZ = float.MaxValue;
            float maxX = float.MinValue;
            float maxY = float.MinValue;
            float maxZ = float.MinValue;

            foreach (Vector3 oldVertex in VerticesPositions)
            {
                var transformedVertex = MathC.HomogenousTransform(oldVertex, transform);

                minX = (float)Math.Min(transformedVertex.X, minX);
                minY = (float)Math.Min(transformedVertex.Y, minY);
                minZ = (float)Math.Min(transformedVertex.Z, minZ);
                maxX = (float)Math.Max(transformedVertex.X, maxX);
                maxY = (float)Math.Max(transformedVertex.Y, maxY);
                maxZ = (float)Math.Max(transformedVertex.Z, maxZ);
            }

            return(new BoundingBox(new Vector3(minX, maxY, minZ), new Vector3(maxX, minY, maxZ)));
        }
Пример #10
0
        private bool DoNodePicking(Ray ray, WadMeshBoneNode node, out float nodeDistance)
        {
            nodeDistance = 0;

            // Transform view ray to object space space
            Matrix4x4 inverseObjectMatrix;

            if (!Matrix4x4.Invert(node.GlobalTransform, out inverseObjectMatrix))
            {
                return(false);
            }
            Vector3 transformedRayPos         = MathC.HomogenousTransform(ray.Position, inverseObjectMatrix);
            Vector3 transformedRayDestination = MathC.HomogenousTransform(ray.Position + ray.Direction, inverseObjectMatrix);
            Ray     transformedRay            = new Ray(transformedRayPos, transformedRayDestination - transformedRayPos);

            transformedRay.Direction = Vector3.Normalize(transformedRay.Direction);

            // Now do a ray - triangle intersection test
            bool  hit         = false;
            float minDistance = float.PositiveInfinity;
            var   mesh        = node.WadMesh;

            foreach (var poly in mesh.Polys)
            {
                if (poly.Shape == WadPolygonShape.Quad)
                {
                    Vector3 p1 = mesh.VerticesPositions[poly.Index0];
                    Vector3 p2 = mesh.VerticesPositions[poly.Index1];
                    Vector3 p3 = mesh.VerticesPositions[poly.Index2];
                    Vector3 p4 = mesh.VerticesPositions[poly.Index3];

                    float distance;
                    if (Collision.RayIntersectsTriangle(transformedRay, p1, p2, p3, out distance) && distance < minDistance)
                    {
                        minDistance = distance;
                        hit         = true;
                    }

                    if (Collision.RayIntersectsTriangle(transformedRay, p1, p3, p4, out distance) && distance < minDistance)
                    {
                        minDistance = distance;
                        hit         = true;
                    }
                }
                else
                {
                    Vector3 p1 = mesh.VerticesPositions[poly.Index0];
                    Vector3 p2 = mesh.VerticesPositions[poly.Index1];
                    Vector3 p3 = mesh.VerticesPositions[poly.Index2];

                    float distance;
                    if (Collision.RayIntersectsTriangle(transformedRay, p1, p2, p3, out distance) && distance < minDistance)
                    {
                        minDistance = distance;
                        hit         = true;
                    }
                }
            }

            /*
             * _wadRenderer.Dispose();
             * foreach (var submesh in node.Bone.Children.Select(bone => bone.Mesh))
             * for (int k = 0; k < submesh.Value.Indices.Count; k += 3)
             * {
             *  var mesh = _wadRenderer.GetStatic(new WadStatic(new WadStaticId(0)) { Mesh = node.WadMesh });
             *
             *  Vector3 p1 = mesh.Vertices[submesh.Value.Indices[k]].Position;
             *  Vector3 p2 = mesh.Vertices[submesh.Value.Indices[k + 1]].Position;
             *  Vector3 p3 = mesh.Vertices[submesh.Value.Indices[k + 2]].Position;
             *
             *  float distance;
             *  if (Collision.RayIntersectsTriangle(transformedRay, p1, p2, p3, out distance) && distance < minDistance)
             *  {
             *      minDistance = distance;
             *      hit = true;
             *  }
             * }*/
            // TODO Avoid using the renderer for pickingData transforms need to be available in wad mesh without rendering.
            int TODO_DoNodePicking;

            if (hit)
            {
                nodeDistance = minDistance;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #11
0
        public PickingResultGizmo DoPicking(Ray ray)
        {
            if (!DrawGizmo)
            {
                return(null);
            }

            bool upside = Orientation == GizmoOrientation.UpsideDown;

            // Check for translation
            if (SupportTranslateX)
            {
                float          unused;
                BoundingSphere sphereX = new BoundingSphere(Position + Vector3.UnitX * (upside ? -Size : Size) * _arrowHeadOffsetMultiplier, TranslationConeSize / 1.5f);
                if (Collision.RayIntersectsSphere(ray, sphereX, out unused))
                {
                    return(new PickingResultGizmo(GizmoMode.TranslateX));
                }
            }
            if (SupportTranslateY)
            {
                float          unused;
                BoundingSphere sphereY = new BoundingSphere(Position + Vector3.UnitY * (upside ? -Size : Size) * _arrowHeadOffsetMultiplier, TranslationConeSize / 1.5f);
                if (Collision.RayIntersectsSphere(ray, sphereY, out unused))
                {
                    return(new PickingResultGizmo(GizmoMode.TranslateY));
                }
            }
            if (SupportTranslateZ)
            {
                float          unused;
                BoundingSphere sphereZ = new BoundingSphere(Position - Vector3.UnitZ * (upside ? -Size : Size) * _arrowHeadOffsetMultiplier, TranslationConeSize / 1.5f);
                if (Collision.RayIntersectsSphere(ray, sphereZ, out unused))
                {
                    return(new PickingResultGizmo(GizmoMode.TranslateZ));
                }
            }

            // Check for scale
            if (SupportScale)
            {
                float       unused;
                BoundingBox scaleX = new BoundingBox(Position + Vector3.UnitX * (upside ? -Size : Size) / 2.0f - new Vector3(ScaleCubeSize / 2.0f),
                                                     Position + Vector3.UnitX * (upside ? -Size : Size) / 2.0f + new Vector3(ScaleCubeSize / 2.0f));
                if (Collision.RayIntersectsBox(ray, scaleX, out unused))
                {
                    return(new PickingResultGizmo(GizmoMode.ScaleX));
                }

                BoundingBox scaleY = new BoundingBox(Position + Vector3.UnitY * (upside ? -Size : Size) / 2.0f - new Vector3(ScaleCubeSize / 2.0f),
                                                     Position + Vector3.UnitY * (upside ? -Size : Size) / 2.0f + new Vector3(ScaleCubeSize / 2.0f));
                if (Collision.RayIntersectsBox(ray, scaleY, out unused))
                {
                    return(new PickingResultGizmo(GizmoMode.ScaleY));
                }

                BoundingBox scaleZ = new BoundingBox(Position - Vector3.UnitZ * (upside ? -Size : Size) / 2.0f - new Vector3(ScaleCubeSize / 2.0f),
                                                     Position - Vector3.UnitZ * (upside ? -Size : Size) / 2.0f + new Vector3(ScaleCubeSize / 2.0f));
                if (Collision.RayIntersectsBox(ray, scaleZ, out unused))
                {
                    return(new PickingResultGizmo(GizmoMode.ScaleZ));
                }
            }

            // Check for rotation
            float pickRadius = LineThickness / 2 + (Size * 0.045f);

            if (SupportRotationZ)
            {
                Plane   planeZ = MathC.CreatePlaneAtPoint(Position, MathC.HomogenousTransform(Vector3.UnitZ, RotateMatrixZ));
                Vector3 intersectionPoint;
                if (Collision.RayIntersectsPlane(ray, planeZ, out intersectionPoint))
                {
                    var distance = (intersectionPoint - Position).Length();
                    if (distance >= Size - pickRadius && distance <= Size + pickRadius)
                    {
                        Vector3 startDirection = Vector3.Normalize(intersectionPoint - Position);

                        float sin = Vector3.Dot(Vector3.UnitY, startDirection);
                        float cos = Vector3.Dot(planeZ.Normal, Vector3.Cross(Vector3.UnitY, startDirection));
                        return(new PickingResultGizmo(GizmoMode.RotateZ, (float)Math.Atan2(-sin, cos), distance));
                    }
                }
            }

            if (SupportRotationX)
            {
                Plane   planeX = MathC.CreatePlaneAtPoint(Position, MathC.HomogenousTransform(Vector3.UnitX, RotateMatrixX));
                Vector3 intersectionPoint;
                if (Collision.RayIntersectsPlane(ray, planeX, out intersectionPoint))
                {
                    var distance = (intersectionPoint - Position).Length();
                    if (distance >= Size - pickRadius && distance <= Size + pickRadius)
                    {
                        Vector3 startDirection = Vector3.Normalize(intersectionPoint - Position);

                        float sin = Vector3.Dot(Vector3.UnitY, startDirection);
                        float cos = Vector3.Dot(planeX.Normal, Vector3.Cross(Vector3.UnitY, startDirection));
                        return(new PickingResultGizmo(GizmoMode.RotateX, (float)Math.Atan2(-sin, cos), distance));
                    }
                }
            }

            if (SupportRotationY)
            {
                Plane   planeY = MathC.CreatePlaneAtPoint(Position, MathC.HomogenousTransform(Vector3.UnitY, RotateMatrixY));
                Vector3 intersectionPoint;
                if (Collision.RayIntersectsPlane(ray, planeY, out intersectionPoint))
                {
                    var distance = (intersectionPoint - Position).Length();
                    if (distance >= Size - pickRadius && distance <= Size + pickRadius)
                    {
                        Vector3 startDirection = Vector3.Normalize(intersectionPoint - Position);

                        float sin = Vector3.Dot(Vector3.UnitZ, startDirection);
                        float cos = Vector3.Dot(planeY.Normal, Vector3.Cross(Vector3.UnitZ, startDirection));
                        return(new PickingResultGizmo(GizmoMode.RotateY, (float)Math.Atan2(-sin, cos), distance));
                    }
                }
            }

            return(null);
        }
Пример #12
0
        /// <returns>true, if an iteraction with the gizmo is happening</returns>
        public bool MouseMoved(Matrix4x4 viewProjection, Ray ray)
        {
            if (!DrawGizmo || _mode == GizmoMode.None)
            {
                return(false);
            }

            bool upside       = Orientation == GizmoOrientation.UpsideDown;
            bool flippedScale = false;

            // Flip sizing dimensions if object is rotateable on Y axis
            if ((_mode == GizmoMode.ScaleX || _mode == GizmoMode.ScaleZ) && SupportRotationY)
            {
                flippedScale = MathC.RadToDeg(RotationY) % 180.0f >= 45.0f;
            }

            // First get the ray in 3D space from X, Y mouse coordinates
            switch (_mode)
            {
            case GizmoMode.TranslateX:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitY, Vector3.UnitZ, out intersection))
                {
                    GizmoMove(new Vector3(intersection.X - (upside ? -Size : Size) * _arrowHeadOffsetMultiplier, Position.Y, Position.Z));
                    GizmoMoveDelta(new Vector3(intersection.X - (upside ? -Size : Size) * _arrowHeadOffsetMultiplier - Position.X, 0.0f, 0.0f));
                }
            }
            break;

            case GizmoMode.TranslateY:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitX, Vector3.UnitZ, out intersection))
                {
                    GizmoMove(new Vector3(Position.X, intersection.Y - (upside ? -Size : Size) * _arrowHeadOffsetMultiplier, Position.Z));
                    GizmoMoveDelta(new Vector3(0.0f, intersection.Y - (upside ? -Size : Size) * _arrowHeadOffsetMultiplier - Position.Y, 0.0f));
                }
            }
            break;

            case GizmoMode.TranslateZ:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitX, Vector3.UnitY, out intersection))
                {
                    GizmoMove(new Vector3(Position.X, Position.Y, intersection.Z + (upside ? -Size : Size) * _arrowHeadOffsetMultiplier));
                    GizmoMoveDelta(new Vector3(0.0f, 0.0f, intersection.Z + (upside ? -Size : Size) * _arrowHeadOffsetMultiplier - Position.Z));
                }
            }
            break;

            case GizmoMode.ScaleX:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitY, Vector3.UnitZ, out intersection))
                {
                    if (flippedScale)
                    {
                        GizmoScaleZ(_scaleBase.Z * (float)Math.Exp(_scaleSpeed * (intersection.X - Position.X)));
                    }
                    else
                    {
                        GizmoScaleX(_scaleBase.X * (float)Math.Exp(_scaleSpeed * (intersection.X - Position.X)));
                    }
                }
            }
            break;

            case GizmoMode.ScaleY:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitX, Vector3.UnitZ, out intersection))
                {
                    GizmoScaleY(_scaleBase.Y * (float)Math.Exp(_scaleSpeed * (intersection.Y - Position.Y)));
                }
            }
            break;

            case GizmoMode.ScaleZ:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitX, Vector3.UnitY, out intersection))
                {
                    if (flippedScale)
                    {
                        GizmoScaleX(_scaleBase.X * (float)Math.Exp(_scaleSpeed * -(intersection.Z - Position.Z)));
                    }
                    else
                    {
                        GizmoScaleZ(_scaleBase.Z * (float)Math.Exp(_scaleSpeed * -(intersection.Z - Position.Z)));
                    }
                }
            }
            break;

            case GizmoMode.RotateY:
            {
                Plane   rotationPlane = MathC.CreatePlaneAtPoint(Position, MathC.HomogenousTransform(Vector3.UnitY, RotateMatrixY));
                Vector3 rotationIntersection;
                if (Collision.RayIntersectsPlane(ray, rotationPlane, out rotationIntersection))
                {
                    Vector3 direction = rotationIntersection - Position;
                    _rotationLastMouseRadius = direction.Length();
                    direction = Vector3.Normalize(direction);

                    float sin = Vector3.Dot(Vector3.UnitZ, direction);
                    float cos = Vector3.Dot(rotationPlane.Normal, Vector3.Cross(Vector3.UnitZ, direction));
                    _rotationLastMouseAngle = (float)Math.Atan2(-sin, cos);
                    GizmoRotateY(SimplifyAngle(_rotationPickAngleOffset + _rotationLastMouseAngle));
                }
            }
            break;

            case GizmoMode.RotateX:
            {
                Plane   rotationPlane = MathC.CreatePlaneAtPoint(Position, MathC.HomogenousTransform(Vector3.UnitX, RotateMatrixX));
                Vector3 rotationIntersection;
                if (Collision.RayIntersectsPlane(ray, rotationPlane, out rotationIntersection))
                {
                    Vector3 direction = rotationIntersection - Position;
                    _rotationLastMouseRadius = direction.Length();
                    direction = Vector3.Normalize(direction);

                    float sin = Vector3.Dot(Vector3.UnitY, direction);
                    float cos = Vector3.Dot(rotationPlane.Normal, Vector3.Cross(Vector3.UnitY, direction));
                    _rotationLastMouseAngle = (float)Math.Atan2(-sin, cos);
                    GizmoRotateX(SimplifyAngle(_rotationPickAngleOffset + _rotationLastMouseAngle));
                }
            }
            break;

            case GizmoMode.RotateZ:
            {
                Plane   rotationPlane = MathC.CreatePlaneAtPoint(Position, MathC.HomogenousTransform(Vector3.UnitZ, RotateMatrixZ));
                Vector3 rotationIntersection;
                if (Collision.RayIntersectsPlane(ray, rotationPlane, out rotationIntersection))
                {
                    Vector3 direction = rotationIntersection - Position;
                    _rotationLastMouseRadius = direction.Length();
                    direction = Vector3.Normalize(direction);

                    float sin = Vector3.Dot(Vector3.UnitY, direction);
                    float cos = Vector3.Dot(rotationPlane.Normal, Vector3.Cross(Vector3.UnitY, direction));
                    _rotationLastMouseAngle = (float)Math.Atan2(-sin, cos);
                    GizmoRotateZ(SimplifyAngle(_rotationPickAngleOffset + _rotationLastMouseAngle));
                }
            }
            break;
            }

            return(true);
        }
Пример #13
0
        public override void MoveCameraPlane(Vector3 movementVec)
        {
            float distanceMultiplier = (float)Math.Pow(Distance / DefaultDistance, 2 / (float)3);

            Target += MathC.HomogenousTransform(movementVec * distanceMultiplier, GetRotationMatrix());
        }