Beispiel #1
0
        public SectorSelection?ClampToRoom(Room r, Direction?excludeBorderWallsDirection = Direction.None)
        {
            int[] c = new int[2] {
                0, 0
            };                             // How many blocks to cut from compared area zone perimeter
            bool excludeAll = !excludeBorderWallsDirection.HasValue;

            if (excludeAll || excludeBorderWallsDirection.Value == Direction.NegativeX || excludeBorderWallsDirection.Value == Direction.PositiveX)
            {
                if ((Start.Y == 0 || Start.Y == r.NumZSectors - 1) && Area.Size.Y == 0)
                {
                    return(null);
                }
                c[0] = 1;
            }
            if (excludeAll || excludeBorderWallsDirection.Value == Direction.NegativeZ || excludeBorderWallsDirection.Value == Direction.PositiveZ)
            {
                if ((Start.X == 0 || Start.X == r.NumXSectors - 1) && Area.Size.X == 0)
                {
                    return(null);
                }
                c[1] = 1;
            }

            return(new SectorSelection()
            {
                Start = new VectorInt2(MathC.Clamp(Start.X, c[1], r.NumXSectors - (1 + c[1])), MathC.Clamp(Start.Y, c[0], r.NumZSectors - (1 + c[0]))),
                End = new VectorInt2(MathC.Clamp(End.X, c[1], r.NumXSectors - (1 + c[1])), MathC.Clamp(End.Y, c[0], r.NumZSectors - (1 + c[0])))
            });
        }
Beispiel #2
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()));
 }
        private void ChangeColorByMouse(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Focus();
                _selectedColorCoord = new Point((int)MathC.Clamp((e.X / _paletteCellWidth), 0, PaletteSize.Width - 1),
                                                (int)MathC.Clamp((e.Y / _paletteCellHeight), 0, PaletteSize.Height - 1));

                if (_editor.SelectedObject is LightInstance)
                {
                    var light = _editor.SelectedObject as LightInstance;
                    if (!(_editor.Level.Settings.GameVersion.Legacy() <= TRVersion.Game.TR4 && light.Type == LightType.FogBulb))
                    {
                        light.Color = SelectedColor.ToFloat3Color() * 2.0f;
                        light.Room.RebuildLighting(_editor.Configuration.Rendering3D_HighQualityLightPreview);
                        _editor.ObjectChange(light, ObjectChangeType.Change);
                    }
                }
                else if (_editor.SelectedObject is StaticInstance)
                {
                    var instance = _editor.SelectedObject as StaticInstance;
                    instance.Color = SelectedColor.ToFloat3Color() * 2.0f;
                    _editor.ObjectChange(instance, ObjectChangeType.Change);
                }
                else if (_editor.Level.Settings.GameVersion == TRVersion.Game.TR5Main && _editor.SelectedObject is MoveableInstance)
                {
                    var instance = _editor.SelectedObject as MoveableInstance;
                    instance.Color = SelectedColor.ToFloat3Color() * 2.0f;
                    _editor.ObjectChange(instance, ObjectChangeType.Change);
                }

                _editor.LastUsedPaletteColourChange(SelectedColor);
                Invalidate();
            }
        }
Beispiel #4
0
        private void GizmoRotate(GizmoMode mode, float newAngle)
        {
            if (_control != null)
            {
                var model     = _control.Model;
                var animation = _editor.CurrentAnim;
                if (animation == null || _control.SelectedMesh == null)
                {
                    return;
                }

                var meshIndex      = model.Meshes.IndexOf(_control.SelectedMesh);
                var rotationVector = _editor.CurrentKeyFrame.Rotations[meshIndex];
                var delta          = 0f;
                var axis           = Vector3.Zero;

                switch (mode)
                {
                case GizmoMode.RotateX: delta = newAngle - rotationVector.X; axis = Vector3.UnitX; break;

                case GizmoMode.RotateY: delta = newAngle - rotationVector.Y; axis = Vector3.UnitY; break;

                case GizmoMode.RotateZ: delta = newAngle - rotationVector.Z; axis = Vector3.UnitZ; break;
                }

                var quat = _editor.CurrentKeyFrame.Quaternions[meshIndex] * Quaternion.CreateFromAxisAngle(axis, delta);
                _editor.UpdateTransform(meshIndex, MathC.QuaternionToEuler(quat), _editor.CurrentKeyFrame.Translations[0]);

                _control.Model.BuildAnimationPose(_editor.CurrentKeyFrame);
                _control.Invalidate();
            }
        }
Beispiel #5
0
        private void UpdateTimer(object sender, EventArgs e)
        {
            if (Mode == AnimationMode.Spin)
            {
                if (MoveMultiplier < 1.0f)
                {
                    MoveMultiplier += _moveAcceleration;
                }
                else
                {
                    MoveMultiplier = 1.0f;
                }
            }
            else if (Mode != AnimationMode.Idle)
            {
                _autoMoveCurrent += _autoMoveStep;

                // Allow timer to overflow for 2 subsequent frames, so we
                // get finalizing 1.0 value at all times

                if (_autoMoveCurrent >= 1.0f + (_autoMoveStep * 2))
                {
                    Stop(true);
                }
                else
                {
                    var newMultiplier = MathC.SmoothStep(0.0, 1.0, _autoMoveCurrent);
                    MoveMultiplier = (float)MathC.Clamp(newMultiplier, 0.0, 1.0);
                }
            }
            else
            {
                Stop(true);
            }
        }
Beispiel #6
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();
        }
Beispiel #7
0
        public UndoManager(int undoDepth)
        {
            undoDepth = MathC.Clamp(undoDepth, 1, MaxUndoDepth);

            _undoStack = new UndoRedoStack(undoDepth);
            _redoStack = new UndoRedoStack(undoDepth);
        }
Beispiel #8
0
        public override Vector3 GetDirection()
        {
            Matrix4x4 rotation = GetRotationMatrix();
            Vector3   look     = MathC.HomogenousTransform(Vector3.UnitZ, rotation);

            return(Vector3.Normalize(look));
        }
Beispiel #9
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);
        }
Beispiel #10
0
 public static Color ToWinFormsColor(this Vector4 color, float?alpha = null)
 {
     return(Color.FromArgb(
                (int)Math.Max(0, Math.Min(255, Math.Round((alpha.HasValue ? MathC.Clamp(alpha.Value, 0.0, 1.0) : color.W) * 255.0f))),
                (int)Math.Max(0, Math.Min(255, Math.Round(color.X * 255.0f))),
                (int)Math.Max(0, Math.Min(255, Math.Round(color.Y * 255.0f))),
                (int)Math.Max(0, Math.Min(255, Math.Round(color.Z * 255.0f)))));
 }
Beispiel #11
0
        public void TestPositiveAbs()
        {
            var x = 15;

            var actual   = MathC.Abs(x);
            var expected = System.Math.Abs(x);

            Assert.AreEqual(expected, actual);
        }
Beispiel #12
0
        public void Emboss(int xStart, int yStart, int width, int height, int weight, int size)
        {
            size          = MathC.Clamp(size, 2, 8);
            int[,] kernel = new int[size, size];
            kernel[0, 0]  = -1;
            kernel[size - 1, size - 1] = 1;

            ApplyKernel(xStart, yStart, width, height, weight, kernel);
        }
Beispiel #13
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;
        }
Beispiel #14
0
 public void Resize(int newSize)
 {
     if (newSize == _undoStack.Count)
     {
         return;
     }
     newSize = MathC.Clamp(newSize, 1, MaxUndoDepth);
     _undoStack.Resize(newSize);
     _redoStack.Resize(newSize);
     UndoStackChanged?.Invoke(this, new EventArgs());
 }
Beispiel #15
0
        protected Vector4 ApplyColorTransform(Vector4 color)
        {
            // Clamp each value separately to prevent overflows which are possible because TE doesn't internally
            // clamp its vertex lighting to 2.0f.

            color.X = MathC.Clamp(color.X, 0.0f, 2.0f);
            color.Y = MathC.Clamp(color.Y, 0.0f, 2.0f);
            color.Z = MathC.Clamp(color.Z, 0.0f, 2.0f);
            color.W = MathC.Clamp(color.W, 0.0f, 1.0f);
            return(new Vector4(color.X / 2.0f, color.Y / 2.0f, color.Z / 2.0f, color.W));
        }
Beispiel #16
0
        static void Main(string[] args)
        {
            if (!File.Exists("File.csv"))
            {
                File.Create("File.csv");
            }
            StreamWriter sw = new StreamWriter("File.csv");

            Console.Write("Нужная функция(sin,cos,log,ln,sqrt,expression:");
            string func = Console.ReadLine();

            Console.WriteLine("Введите стартовое значение");
            double start = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Введите шаг функции");
            double step = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Введите конечное значение");
            double end = Convert.ToDouble(Console.ReadLine());

            using var csv = new CsvWriter(sw, new CsvConfiguration(CultureInfo.InvariantCulture)
            {
                Delimiter = ";"
            });
            for (double i = start; i < end; i += step)
            {
                double result = 0;
                if (func == "sin")
                {
                    result = new MathC().Sin(i);
                }
                if (func == "cos")
                {
                    result = new MathC().Cos(i);
                }
                if (func == "ln")
                {
                    result = new MathC().Ln(i);
                }
                if (func == "sqrt")
                {
                    result = MathC.Sqrt(i);
                }
                if (func == "expression")
                {
                    result = new Expression().Calc(i);
                }
                csv.WriteRecord(new { X = func + $"({i})", Result = result });

                csv.NextRecord();
            }
            Console.WriteLine($"Результаты вычисления функции {func} сохранены в File.csv");
        }
Beispiel #17
0
        private static bool ConstructPlaneIntersection(Vector3 Position, Matrix4x4 viewProjection, Ray ray, Vector3 perpendicularVector0, Vector3 perpendicularVector1, out Vector3 intersection)
        {
            // Choose the perpendicular plane that is more parallel to the camera plane to
            // maximize the available accuracy in the view space.
            Vector3 viewDirection           = new Vector3(viewProjection.M31, viewProjection.M32, viewProjection.M33);
            float   perpendicularVector0Dot = Math.Abs(Vector3.Dot(viewDirection, perpendicularVector0));
            float   perpendicularVector1Dot = Math.Abs(Vector3.Dot(viewDirection, perpendicularVector1));
            Plane   plane = MathC.CreatePlaneAtPoint(Position, perpendicularVector0Dot > perpendicularVector1Dot ? perpendicularVector0 : perpendicularVector1);

            // Construct intersection
            return(Collision.RayIntersectsPlane(ray, plane, out intersection));
        }
Beispiel #18
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);
        }
Beispiel #19
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);
            }
        }
Beispiel #20
0
        public void ApplyKernel(int xStart, int yStart, int width, int height, int weight, int[,] kernel)
        {
            ImageC oldImage = new ImageC(width, height, new byte[width * height * 4]);

            oldImage.CopyFrom(0, 0, this, xStart, yStart, width, height);

            int kernel_width  = kernel.GetUpperBound(0) + 1;
            int kernel_height = kernel.GetUpperBound(1) + 1;

            for (int x = 0, xReal = xStart; x < width; x++, xReal++)
            {
                for (int y = 0, yReal = yStart; y < height; y++, yReal++)
                {
                    int r = 0, g = 0, b = 0;
                    for (int dx = 0; dx < kernel_width; dx++)
                    {
                        for (int dy = 0; dy < kernel_height; dy++)
                        {
                            int    sourceX = MathC.Clamp(x + dx, 0, width - 1);
                            int    sourceY = MathC.Clamp(y + dy, 0, height - 1);
                            ColorC clr     = oldImage.GetPixel(sourceX, sourceY);
                            r += (int)clr.R * kernel[dx, dy];
                            g += (int)clr.G * kernel[dx, dy];
                            b += (int)clr.B * kernel[dx, dy];
                        }
                    }
                    r = MathC.Clamp((int)(127 + r / weight), 0, 255);
                    g = MathC.Clamp((int)(127 + g / weight), 0, 255);
                    b = MathC.Clamp((int)(127 + b / weight), 0, 255);
                    SetPixel(xReal, yReal, new ColorC((byte)r, (byte)g, (byte)b));
                }
            }

            // Restore alpha
            for (int x = 0, xReal = xStart; x < width; x++, xReal++)
            {
                for (int y = 0, yReal = yStart; y < height; y++, yReal++)
                {
                    var alpha = oldImage.GetPixel(xReal, yReal).A;
                    var color = GetPixel(xReal, yReal);
                    color.A = alpha;
                    SetPixel(xReal, yReal, color);
                }
            }
        }
Beispiel #21
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);
        }
Beispiel #22
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)));
        }
Beispiel #23
0
        void AddMessage(float?progress, string message, bool isWarning)
        {
            if (!(bool)Invoke((Func <bool>) delegate
            {
                if (progress.HasValue)
                {
                    pbStato.Value = (int)Math.Round(MathC.Clamp(progress.Value, 0, 100), 0);
                    TaskbarProgress.SetValue(Application.OpenForms[0].Handle, progress.Value, 100);
                }

                if (!string.IsNullOrEmpty(message))
                {
                    lstLog.SelectionBackColor = isWarning ? Color.Yellow.Multiply(Colors.Brightness) : Color.Empty;
                    lstLog.AppendText(message + "\n");
                    lstLog.ScrollToCaret();
                }

                return(!_threadShouldAbort);
            }))
            {
                throw new OperationCanceledException();
            }
        }
Beispiel #24
0
        public override void MoveCameraPlane(Vector3 movementVec)
        {
            float distanceMultiplier = (float)Math.Pow(Distance / DefaultDistance, 2 / (float)3);

            Target += MathC.HomogenousTransform(movementVec * distanceMultiplier, GetRotationMatrix());
        }
Beispiel #25
0
 public void InitTest()
 {
     mathFunc   = new MathC();
     expression = new Expression();
 }
Beispiel #26
0
        private static byte[] PackTextureMap32To16BitDithered(byte[] textureData, int pageSize)
        {
            // Stucki dithering matrix, it produces better result than Floyd-Steinberg
            // with gradients
            var ditherMatrix = new byte[, ]
            {
                { 0, 0, 0, 8, 4 },
                { 2, 4, 8, 4, 2 },
                { 1, 2, 4, 2, 1 }
            };

            var seed       = new Random(31459);
            int pixelCount = textureData.Length / 4;
            var height     = pixelCount / pageSize;

            byte[] newTextureData = new byte[pixelCount * 2];

            for (int i = 0; i < pixelCount; i++)
            {
                int r1 = textureData[i * 4 + 2];
                int g1 = textureData[i * 4 + 1];
                int b1 = textureData[i * 4 + 0];
                int r2 = (byte)(r1 >> 3) << 3;
                int g2 = (byte)(g1 >> 3) << 3;
                int b2 = (byte)(b1 >> 3) << 3;
                int rE = r1 - r2;
                int bE = g1 - g2;
                int gE = b1 - b2;

                for (int row = 0; row < 3; row++)
                {
                    int offsetY = (i / pageSize) + row;

                    for (int col = 0; col < 5; col++)
                    {
                        int coefficient = ditherMatrix[row, col];
                        int offsetX     = (i % pageSize) + (col - 4);

                        if (coefficient != 0 && offsetX >= 0 && offsetX < pageSize && offsetY >= 0 && offsetY < height)
                        {
                            // Add some noise to coefficient to reduce banding
                            float finalCoeff = 42 - (seed.Next(0, 15));

                            int offsetIndex = (offsetY * pageSize + offsetX) * 4;
                            int newR        = (int)((rE * coefficient) / finalCoeff);
                            int newG        = (int)((gE * coefficient) / finalCoeff);
                            int newB        = (int)((bE * coefficient) / finalCoeff);

                            byte a = (byte)MathC.Clamp((textureData[offsetIndex + 3]), 0, 255);
                            byte r = (byte)MathC.Clamp((textureData[offsetIndex + 2] + newR), 0, 255);
                            byte g = (byte)MathC.Clamp((textureData[offsetIndex + 1] + newG), 0, 255);
                            byte b = (byte)MathC.Clamp((textureData[offsetIndex + 0] + newB), 0, 255);

                            if (r < 8 || a == 0)
                            {
                                r = 0;
                            }
                            if (g < 8 || a == 0)
                            {
                                g = 0;
                            }
                            if (b < 8 || a == 0)
                            {
                                b = 0;
                            }

                            if (a > 0 && a < 255)
                            {
                                // Convert true alpha to brightness with slight noise to prevent banding
                                a -= (byte)seed.Next(0, MathC.Clamp((255 - a) / 20, 0, a));
                                r  = (byte)(r * (a / 255.0f));
                                g  = (byte)(g * (a / 255.0f));
                                b  = (byte)(b * (a / 255.0f));
                            }

                            r /= 8;
                            g /= 8;
                            b /= 8;

                            ushort tmp = 0;

                            if (r == 255 && g == 255 && b == 255)
                            {
                                tmp = 0xffff;
                            }
                            else
                            {
                                tmp |= (ushort)(a == 0 ? 0 : 0x8000);
                                tmp |= (ushort)(r << 10);
                                tmp |= (ushort)(g << 5);
                                tmp |= (ushort)b;
                            }

                            newTextureData[offsetIndex / 2]     = (byte)((tmp & 0x00ff));
                            newTextureData[offsetIndex / 2 + 1] = (byte)((tmp & 0xff00) >> 8);
                        }
                    }
                }
            }
            return(newTextureData);
        }
Beispiel #27
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);
            }
        }
    void Start()
    {
        //origin = origin + new Vector2(attack.offset.x * direction, attack.offset.y);
        attackPath = attack.attackPath;

        if (attack.targetType == Attack.TargetType.TargetStraight)
        {
            RaycastHit2D hitInfo;
            hitInfo = Physics2D.Raycast(transform.position, Vector2.right, attack.offset.x);

            if (hitInfo.collider.gameObject.tag == "Enemy")
            {
                //transform.position = hitInfo.collider.gameObject.transform.position;
            }
            else
            {
                //transform.position = origin;
            }
        }
        else
        {
            print(origin);
            //transform.position = origin;
        }


        gameObject.tag = "Attack";

        rb              = gameObject.AddComponent <Rigidbody2D>();
        rb.constraints  = RigidbodyConstraints2D.FreezeRotation;
        rb.gravityScale = 0;

        sr = attack.spriteAnimation.GetComponent <SpriteRenderer>();

        velocityDiv = attack.velocityDiv;
        lifetime    = attack.lifetime;
        xSpeed      = attack.speed;

        if (attack.attackType == Attack.AttackType.Melee)
        {
            //mht = sprite
        }

        if (attack.bounces)
        {
            lifetime *= attack.bounceCount + 1;
        }


        if (boxCol = GetComponentInChildren <BoxCollider2D>())
        {
            print("Box Collider Present");
        }

        if (attack.spriteAnimation != null)
        {
            GameObject sprite = Instantiate(attack.spriteAnimation, transform.position, Quaternion.identity, this.gameObject.transform);
            if (direction < 0)
            {
                // facing left
                sprite.transform.localScale = MathC.MultiplyVector(sprite.transform.localScale, MathC.NegaVectorX);
            }

            if (attack.attackBase != null)
            {
                // Checks for a 2D Collider in the attack base prefab
                if (sprite.GetComponent <Collider2D>())
                {
                    // Adds the attack collision script and links the attack script to it
                    AttackCollision _ac = sprite.AddComponent <AttackCollision>();
                    _ac._as = this;
                }
            }

            if (attack.attackPath == Attack.AttackPath.Meteor)
            {
                sprite.transform.Rotate(new Vector3(0, 0, -45));
                ySpeed = xSpeed;
            }
            else if (attack.attackPath == Attack.AttackPath.CrashDown)
            {
                sprite.transform.Rotate(new Vector3(0, 0, -90));
                ySpeed = xSpeed;
            }
        }



        if (col != null)
        {
            col.isTrigger = true;
        }

        if (attack.attackType == Attack.AttackType.Beam)
        {
            if (boxCol == null)
            {
                boxCol = attack.spriteAnimation.GetComponent <BoxCollider2D>();
            }

            if (boxCol != null)
            {
                boxCol.isTrigger = true;
                sr.tileMode      = SpriteTileMode.Continuous;
            }
            else
            {
                Debug.LogError("No Box Collider Present on Beam");
            }
        }
    }
Beispiel #29
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);
        }
Beispiel #30
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);
        }