Ejemplo n.º 1
0
        private void UpdateSenzorToCamera()
        {
            // - translate by (-0.5, -aspectRatio * 0.5)
            // - scale by (width, height, 1)
            // - translate by (shiftX, shiftY, distanceZ)
            // - [tilt around X by tiltX, ...]
            var matrix = Matrix4d.CreateTranslation(-0.5, AspectRatio * -0.5, 0);

            matrix     = Matrix4d.Mult(matrix, Matrix4d.Scale(Width, Width, 1));
            matrix     = Matrix4d.Mult(matrix, Matrix4d.CreateTranslation(Shift));
            TiltMatrix = Matrix4d.Identity;
            if (Tilt.X != 0)
            {
                TiltMatrix = Matrix4d.CreateRotationX(Tilt.X);
            }
            if (Tilt.Y != 0)
            {
                TiltMatrix = Matrix4d.Mult(TiltMatrix, Matrix4d.CreateRotationY(Tilt.Y));
            }
            if (Tilt.Z != 0)
            {
                TiltMatrix = Matrix4d.Mult(TiltMatrix, Matrix4d.CreateRotationZ(Tilt.Z));
            }
            matrix         = Matrix4d.Mult(matrix, TiltMatrix);
            SenzorToCamera = matrix;
        }
Ejemplo n.º 2
0
        // we rotate around the centre point. hoff/voff allows you to place the bitmap to the side
        public static Vector3d[] GetVertices(Vector3d centre, Vector3 rotationdeg, float width, float height, float hoffset = 0, float voffset = 0)
        {
            Matrix4d rm = Matrix4d.Identity;

            if (rotationdeg.X != 0)
            {
                rm *= Matrix4d.CreateRotationX((float)(rotationdeg.X * Math.PI / 180.0f));
            }
            if (rotationdeg.Y != 0)
            {
                rm *= Matrix4d.CreateRotationY((float)(rotationdeg.Y * Math.PI / 180.0f));
            }
            if (rotationdeg.Z != 0)
            {
                rm *= Matrix4d.CreateRotationZ((float)(rotationdeg.Z * Math.PI / 180.0f));
            }

            width  /= 2;
            height /= 2;

            Vector3d[] points = new Vector3d[]                                                         // bitmap is placed on map, centred if hoff,voff=0.
            {
                Vector3d.Transform(new Vector3d(-width + hoffset, 0, height + voffset), rm) + centre,  // top left, rotate and transform
                Vector3d.Transform(new Vector3d(width + hoffset, 0, height + voffset), rm) + centre,   // top right
                Vector3d.Transform(new Vector3d(width + hoffset, 0, -height + voffset), rm) + centre,  // bot right
                Vector3d.Transform(new Vector3d(-width + hoffset, 0, -height + voffset), rm) + centre, // bot left
            };

            return(points);
        }
Ejemplo n.º 3
0
        public static CollisionResult CircleVsUnmovableLineSegment(
            // lineV1 and lineV2 are specified clockwise.
            Vector2d lineV1,
            Vector2d lineV2,
            Vector2d circlePosition,
            Vector2d circleVelocity,
            double circleRadius
            )
        {
            // Get the relative position of the circle centre to v1.
            Vector2d relativeCirclePosition = circlePosition - lineV1;

            // Rotate everything so that the line segment is lying flat along the X axis with v1 at the origin.
            // Figure out the angle to rotate by.
            Vector2d v2RelativePosition     = lineV2 - lineV1;
            double   angleToRotateByRadians = Math.Atan2(v2RelativePosition.Y, v2RelativePosition.X);
            // Produce a matrix to rotate everything by that amount.
            var rotationMatrix = Matrix4d.CreateRotationZ(angleToRotateByRadians).Inverted();

            double lineLength = v2RelativePosition.Length;

            // Perform the rotation.
            Vector3d rotatedCirclePosition = Vector3d.Transform(new Vector3d(relativeCirclePosition.X, relativeCirclePosition.Y, 0.0), rotationMatrix);
            Vector3d rotatedCircleVelocity = Vector3d.Transform(new Vector3d(circleVelocity.X, circleVelocity.Y, 0.0), rotationMatrix);

            // Determine whether the circle is intersecting.
            bool intersection =
                rotatedCirclePosition.X > 0 &&
                rotatedCirclePosition.X < lineLength &&
                rotatedCirclePosition.Y - circleRadius < 0 &&
                rotatedCirclePosition.Y + circleRadius > 0;

            if (!intersection)
            {
                // Return a negative collision result.
                return(new CollisionResult {
                    DidCollide = false,
                    NewCirclePosition = circlePosition,
                    // Use the original circle velocity.
                    NewCircleVelocity = circleVelocity
                });
            }
            else
            {
                // make the circle's Y velocity positive in this frame of reference,
                Vector3d postCollisionRotatedCircleVelocity = new Vector3d(rotatedCircleVelocity.X, Math.Abs(rotatedCircleVelocity.Y), 0);

                // Rotate the new velocity back.
                Vector3d postCollisionCircleVelocity = Vector3d.Transform(postCollisionRotatedCircleVelocity, rotationMatrix.Inverted());

                var newVelocity = postCollisionCircleVelocity.Xy * 1.005;

                // Return as a positive collision result.
                return(new CollisionResult {
                    DidCollide = true,
                    NewCirclePosition = circlePosition + newVelocity,
                    NewCircleVelocity = newVelocity
                });
            }
        }
Ejemplo n.º 4
0
        public void ActualModelRender()
        {
            Matrix4d mat = PreRot * Matrix4d.CreateRotationZ((Direction.Yaw * Utilities.PI180)) * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(GetPosition()));

            TheClient.MainWorldView.SetMatrix(2, mat);
            model.CustomAnimationAdjustments = new Dictionary <string, Matrix4>(SavedAdjustmentsOTK);
            model.Draw(aHTime, hAnim, aTTime, tAnim, aLTime, lAnim);
            // TODO: Render held item!
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Random direction around the [0,0,1] vector.
        /// Normal distribution is used, using required variance.
        /// </summary>
        /// <param name="rnd">Random generator to be used.</param>
        /// <param name="variance">Variance of the deviation angle in radians.</param>
        /// <returns></returns>
        public static Vector3d RandomDirectionNormal(RandomJames rnd, double variance)
        {
            // result: [0,0,1] * rotX(deviation) * rotZ(orientation)

            double   deviation   = rnd.Normal(0.0, variance);
            double   orientation = rnd.RandomDouble(0.0, Math.PI);
            Matrix4d mat         = Matrix4d.CreateRotationX(deviation) * Matrix4d.CreateRotationZ(orientation);

            return(new Vector3d(mat.Row2)); // [0,0,1] * mat
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Render a cylinder between two points.
        /// </summary>
        /// <param name="start">The initial point.</param>
        /// <param name="end">The ending point.</param>
        /// <param name="width">The width of the cylinder.</param>
        public void RenderCylinder(Location start, Location end, float width)
        {
            float    len    = (float)(end - start).Length();
            Location vecang = Utilities.VectorToAngles(start - end);
            Matrix4d mat    = Matrix4d.CreateRotationY((float)(90 * Utilities.PI180))
                              * Matrix4d.Scale(len, width, width)
                              * Matrix4d.CreateRotationY((float)(vecang.Y * Utilities.PI180))
                              * Matrix4d.CreateRotationZ((float)(vecang.Z * Utilities.PI180))
                              * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(start));

            Client.Central.MainWorldView.SetMatrix(2, mat);
            Client.Central.Models.Cylinder.Draw(); // TODO: Models reference in constructor - or client reference?
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Render a line between two points.
        /// </summary>
        /// <param name="start">The initial point.</param>
        /// <param name="end">The ending point.</param>
        public void RenderLine(Location start, Location end)
        {
            // TODO: Efficiency!
            float    len    = (float)(end - start).Length();
            Location vecang = Utilities.VectorToAngles(start - end);
            Matrix4d mat    = Matrix4d.Scale(len, 1, 1)
                              * Matrix4d.CreateRotationY((float)(vecang.Y * Utilities.PI180))
                              * Matrix4d.CreateRotationZ((float)(vecang.Z * Utilities.PI180))
                              * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(start));

            Client.Central.MainWorldView.SetMatrix(2, mat); // TODO: Client reference!
            GL.BindVertexArray(Line._VAO);
            GL.DrawElements(PrimitiveType.Lines, 2, DrawElementsType.UnsignedInt, IntPtr.Zero);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Render a cylinder between two points.
        /// </summary>
        /// <param name="start">The initial point.</param>
        /// <param name="end">The ending point.</param>
        /// <param name="width">The width of the cylinder.</param>
        /// <param name="view">The relevant view.</param>
        public void RenderCylinder(Location start, Location end, float width, View3D view)
        {
            float    len    = (float)(end - start).Length();
            Location vecang = Utilities.VectorToAngles(start - end);

            vecang.Yaw += 180;
            Matrix4d mat = Matrix4d.CreateRotationY((float)(90 * Utilities.PI180))
                           * Matrix4d.Scale(len, width, width)
                           * Matrix4d.CreateRotationY((float)(vecang.Y * Utilities.PI180))
                           * Matrix4d.CreateRotationZ((float)(vecang.Z * Utilities.PI180))
                           * Matrix4d.CreateTranslation(start.ToOpenTK3D());

            view.SetMatrix(2, mat);
            Models.Cylinder.Draw(); // TODO: Models reference in constructor - or client reference?
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Render a cylinder between two points.
        /// </summary>
        /// <param name="context">The sourcing render context.</param>
        /// <param name="start">The initial point.</param>
        /// <param name="end">The ending point.</param>
        /// <param name="width">The width of the cylinder.</param>
        /// <param name="view">The relevant view.</param>
        public void RenderCylinder(RenderContext context, Location start, Location end, float width, View3D view)
        {
            float    len    = (float)(end - start).Length();
            Location vecang = MathUtilities.VectorToAngles(start - end);

            vecang.Yaw += 180;
            Matrix4d mat = Matrix4d.CreateRotationY((float)(90 * MathUtilities.PI180))
                           * Matrix4d.Scale(len, width, width)
                           * Matrix4d.CreateRotationY((float)(vecang.Y * MathUtilities.PI180))
                           * Matrix4d.CreateRotationZ((float)(vecang.Z * MathUtilities.PI180))
                           * Matrix4d.CreateTranslation(start.ToOpenTK3D());

            view.SetMatrix(2, mat);
            Models.Cylinder.Draw(context);
        }
Ejemplo n.º 10
0
        public static CollisionResult CircleVsUnmovablePoint(
            double circleRadius,
            // Point position in game coords.
            // This is also the collision point.
            Vector2d pointPosition,
            // Circle position in game coords.
            Vector2d circlePosition,
            Vector2d circleVelocity
            )
        {
            Vector2d collisionPoint    = pointPosition;
            double   velocityMagnitude = circleVelocity.Length;

            if ((circlePosition - pointPosition).Length < circleRadius)
            {
                //var newVelocity = (circlePosition - pointPosition).Normalized() * velocityMagnitude;
                Vector2d relativeCirclePosition       = circlePosition - pointPosition;
                double   relativeAngleOfCircleRadians = Math.Atan2(relativeCirclePosition.Y, relativeCirclePosition.X) - Math.PI / 2;
                var      rotationMatrix = Matrix4d.CreateRotationZ(relativeAngleOfCircleRadians).Inverted();

                Vector3d rotatedCirclePosition = Vector3d.Transform(new Vector3d(relativeCirclePosition.X, relativeCirclePosition.Y, 0.0), rotationMatrix);
                Vector3d rotatedCircleVelocity = Vector3d.Transform(new Vector3d(circleVelocity.X, circleVelocity.Y, 0.0), rotationMatrix);

                // make the circle's Y velocity positive in this frame of reference,
                Vector3d postCollisionRotatedCircleVelocity = new Vector3d(rotatedCircleVelocity.X, Math.Abs(rotatedCircleVelocity.Y), 0);

                // Rotate the new velocity back.
                Vector3d postCollisionCircleVelocity = Vector3d.Transform(postCollisionRotatedCircleVelocity, rotationMatrix.Inverted());

                var newVelocity = postCollisionCircleVelocity.Xy * 1.005;

                // Return as a positive collision result.
                return(new CollisionResult {
                    DidCollide = true,
                    NewCirclePosition = circlePosition + newVelocity,
                    NewCircleVelocity = newVelocity
                });
            }
            else
            {
                // Return original velocity
                return(new CollisionResult {
                    DidCollide = false,
                    NewCirclePosition = circlePosition,
                    NewCircleVelocity = circleVelocity
                });
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Render a line between two points.
        /// </summary>
        /// <param name="start">The initial point.</param>
        /// <param name="end">The ending point.</param>
        /// <param name="view">The relevant view.</param>
        public void RenderLine(Location start, Location end, View3D view)
        {
            // TODO: Efficiency!
            float    len    = (float)(end - start).Length();
            Location vecang = Utilities.VectorToAngles(start - end);

            vecang.Yaw += 180;
            Matrix4d mat = Matrix4d.Scale(len, 1, 1)
                           * Matrix4d.CreateRotationY((float)(vecang.Y * Utilities.PI180))
                           * Matrix4d.CreateRotationZ((float)(vecang.Z * Utilities.PI180))
                           * Matrix4d.CreateTranslation(start.ToOpenTK3D());

            view.SetMatrix(2, mat);
            GL.BindVertexArray(Line._VAO);
            GL.DrawElements(PrimitiveType.Lines, 2, DrawElementsType.UnsignedInt, IntPtr.Zero);
        }
        /// <summary>Calculate the Projection matrix - projects the 3d model space to the 2D screen</summary>
        public void CalculateModelMatrix(Vector3d lookatd, Vector3d eyepositiond, double camerarotation)
        {
            LookAt      = new Vector3((float)lookatd.X, (float)lookatd.Y, (float)lookatd.Z); // record for shader use
            EyePosition = new Vector3((float)eyepositiond.X, (float)eyepositiond.Y, (float)eyepositiond.Z);
            EyeDistance = (float)((lookatd - eyepositiond).Length);

            //  System.Diagnostics.Debug.WriteLine($"CMM {lookat} {eyeposition} dist {EyeDistance} {cameradirection} {camerarotation}");

            Matrix4d mat;

            if (InPerspectiveMode)
            {
                Vector3d camnormal = new Vector3d(0, ModelAxisPositiveZAwayFromViewer ? -1 : 1, 0);

                if (camerarotation != 0)     // if we have camera rotation, then rotate the up vector
                {
                    Matrix4d rot = Matrix4d.CreateRotationZ((float)camerarotation.Radians());
                    camnormal = Vector3d.Transform(camnormal, rot);
                }

                mat = Matrix4d.LookAt(eyepositiond, lookatd, camnormal);   // from eye, look at target, with normal giving the rotation of the look
            }
            else
            {
                Size   scr         = ViewPort.Size;
                double orthoheight = (OrthographicDistance / 5.0f) * scr.Height / scr.Width;  // this comes from the projection calculation, and allows us to work out the scale factor the eye vs lookat has
                double scaler      = orthoheight / EyeDistance;

                // no create scale, do it manually.
                Matrix4d scale = new Matrix4d(new Vector4d(scaler, 0, 0, 0), new Vector4d(0, scaler, 0, 0), new Vector4d(0, 0, scaler, 0), new Vector4d(0, 0, 0, 1));

                mat = Matrix4d.CreateTranslation(-lookatd.X, 0, -lookatd.Z);         // we offset by the negative of the position to give the central look
                mat = Matrix4d.Mult(mat, scale);                                     // translation world->View = scale + offset

                Matrix4d rotcam = Matrix4d.CreateRotationX(90.0 * Math.PI / 180.0f); // flip 90 along the x axis to give the top down view
                mat = Matrix4d.Mult(mat, rotcam);
            }

            // and turn it to float model matrix
            ModelMatrix = new Matrix4((float)mat.M11, (float)mat.M12, (float)mat.M13, (float)mat.M14, (float)mat.M21, (float)mat.M22, (float)mat.M23, (float)mat.M24, (float)mat.M31, (float)mat.M32, (float)mat.M33, (float)mat.M34, (float)mat.M41, (float)mat.M42, (float)mat.M43, (float)mat.M44);

            //System.Diagnostics.Debug.WriteLine("MM\r\n{0}", ModelMatrix);

            ProjectionModelMatrix = Matrix4.Mult(ModelMatrix, ProjectionMatrix);        // order order order ! so important.
            CountMatrixCalcs++;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Random direction around the givent center vector.
        /// Normal distribution is used, using required variance.
        /// </summary>
        /// <param name="rnd">Random generator to be used.</param>
        /// <param name="dir">Central direction.</param>
        /// <param name="variance">Variance of the deviation angle in radians.</param>
        /// <returns></returns>
        public static Vector3d RandomDirectionNormal(RandomJames rnd, Vector3d dir, double variance)
        {
            // Matrix3d fromz: [0,0,1] -> dir
            // Vector4d delta: [0,0,1] * rotX(deviation) * rotZ(orientation)
            // result: delta * fromz

            dir.Normalize();
            Vector3d axis1, axis2;

            GetAxes(ref dir, out axis1, out axis2);
            Matrix4d fromz = new Matrix4d(new Vector4d(axis1), new Vector4d(axis2), new Vector4d(dir), Vector4d.UnitW);
            //fromz.Transpose();
            double   deviation   = rnd.Normal(0.0, variance);
            double   orientation = rnd.RandomDouble(0.0, Math.PI);
            Matrix4d mat         = Matrix4d.CreateRotationX(deviation) * Matrix4d.CreateRotationZ(orientation) * fromz;

            return(new Vector3d(mat.Row2)); // [0,0,1] * mat
        }
Ejemplo n.º 14
0
        private Vector3d MapMoveToSphere(double radius, Vector2 startPosition, Vector2 endPosition)
        {
            var deltaFromStartPixels = endPosition - startPosition;
            var deltaOnSurface       = new Vector2d(
                deltaFromStartPixels.X / radius,
                deltaFromStartPixels.Y / radius);

            var lengthOnSurfaceRadi = deltaOnSurface.Length;

            // get this rotation on the surface of the sphere about y
            var positionAboutY = Vector3d.Transform(Vector3d.UnitZ, Matrix4d.CreateRotationY(lengthOnSurfaceRadi));

            // get the angle that this distance travels around the sphere
            var angleToTravel = Math.Atan2(-deltaOnSurface.Y, deltaOnSurface.X);

            // now rotate that position about z in the direction of the screen vector
            return(Vector3d.Transform(positionAboutY, Matrix4d.CreateRotationZ(angleToTravel)));
        }
Ejemplo n.º 15
0
        public override void Render()
        {
            TheClient.SetEnts();
            TheClient.Rendering.SetColor(TheClient.Rendering.AdaptColor(ClientUtilities.Convert(GetPosition()), color));
            TheClient.Rendering.SetMinimumLight(0.0f);
            // TODO: Prevent model flipping (Possibly related to animation?)
            Matrix4d mat = PreRot * Matrix4d.CreateRotationZ((Direction.Yaw * Utilities.PI180)) * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(GetPosition()));

            TheClient.MainWorldView.SetMatrix(2, mat);
            model.CustomAnimationAdjustments = new Dictionary <string, Matrix4>(SavedAdjustmentsOTK);
            model.Draw(aHTime, hAnim, aTTime, tAnim, aLTime, lAnim);
            TheClient.Rendering.SetColor(Color4.White);
            // TODO: Render held item!
            if (IsTyping)
            {
                TheClient.Textures.GetTexture("ui/game/typing").Bind(); // TODO: store!
                TheClient.Rendering.RenderBillboard(GetPosition() + new Location(0, 0, 4), new Location(2), TheClient.MainWorldView.CameraPos);
            }
        }
Ejemplo n.º 16
0
        private void WriteNextMtx(int hnumber, sbyte bnumber, sbyte pnumber, Matrix4d testmtx, ref int ofs)
        {
            sbyte child   = Hierarchies[hnumber][bnumber].Child;
            sbyte sibling = Hierarchies[hnumber][bnumber].Sibling;

            Matrix4d localmtx = testmtx;

            localmtx = Matrix4d.Mult(Matrix4d.CreateTranslation(Hierarchies[hnumber][bnumber].Translation), testmtx);
            localmtx = Matrix4d.Mult(Matrix4d.CreateRotationZ(MathHelper.DegreesToRadians((float)Hierarchies[hnumber][bnumber].Rotation.Z / 182.0444444f)), localmtx);
            localmtx = Matrix4d.Mult(Matrix4d.CreateRotationY(MathHelper.DegreesToRadians((float)Hierarchies[hnumber][bnumber].Rotation.Y / 182.0444444f)), localmtx);
            localmtx = Matrix4d.Mult(Matrix4d.CreateRotationX(MathHelper.DegreesToRadians((float)Hierarchies[hnumber][bnumber].Rotation.X / 182.0444444f)), localmtx);

            if (Hierarchies[hnumber][bnumber].DisplayList != 0)
            {
                WriteMtxData(localmtx.M11, hnumber, ref ofs);
                WriteMtxData(localmtx.M12, hnumber, ref ofs);
                WriteMtxData(localmtx.M13, hnumber, ref ofs);
                WriteMtxData(localmtx.M14, hnumber, ref ofs);
                WriteMtxData(localmtx.M21, hnumber, ref ofs);
                WriteMtxData(localmtx.M22, hnumber, ref ofs);
                WriteMtxData(localmtx.M23, hnumber, ref ofs);
                WriteMtxData(localmtx.M24, hnumber, ref ofs);
                WriteMtxData(localmtx.M31, hnumber, ref ofs);
                WriteMtxData(localmtx.M32, hnumber, ref ofs);
                WriteMtxData(localmtx.M33, hnumber, ref ofs);
                WriteMtxData(localmtx.M34, hnumber, ref ofs);
                WriteMtxData(localmtx.M41, hnumber, ref ofs);
                WriteMtxData(localmtx.M42, hnumber, ref ofs);
                WriteMtxData(localmtx.M43, hnumber, ref ofs);
                WriteMtxData(localmtx.M44, hnumber, ref ofs);
                ofs += 0x20;
            }

            if (child > -1 && child != bnumber)
            {
                WriteNextMtx(hnumber, child, bnumber, localmtx, ref ofs);
            }
            if (sibling > -1 && sibling != bnumber)
            {
                WriteNextMtx(hnumber, sibling, pnumber, testmtx, ref ofs);
            }
        }
Ejemplo n.º 17
0
        public void RenderBillboard(Location pos, Location scale, Location facing)
        {
            // TODO: Quaternion magic?
            Location relang = Utilities.VectorToAngles(pos - facing);

            if (relang.IsInfinite() || relang.IsNaN())
            {
                throw new Exception("Unable to handle billboard: relang=" + relang);
            }
            Matrix4d mat =
                Matrix4d.Scale(ClientUtilities.ConvertD(scale))
                * Matrix4d.CreateTranslation(-0.5f, -0.5f, 0f)
                * Matrix4d.CreateRotationY((float)((relang.Y - 90) * Utilities.PI180))
                * Matrix4d.CreateRotationZ((float)(relang.Z * Utilities.PI180))
                * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(pos));

            Client.Central.MainWorldView.SetMatrix(2, mat); // TODO: Client reference!
            GL.BindVertexArray(Square._VAO);
            GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, IntPtr.Zero);
            GL.BindVertexArray(0);
        }
Ejemplo n.º 18
0
 private void ButtonViewIsometric_Click(object sender, EventArgs e)
 => glControlReciProGonio.WorldMatrix = Matrix4d.CreateRotationZ(-Math.PI / 4) * Matrix4d.CreateRotationX(-0.4 * Math.PI);
Ejemplo n.º 19
0
        public LensRayTransferFunction.Parameters ConvertSurfaceRayToParameters(
            Ray ray,
            Vector3d canonicalNormal, double surfaceSinTheta,
            Sphere sphericalSurface, ElementSurface surface)
        {
            //Console.WriteLine("ray->parameters");
            // - convert origin
            //   *- transform to hemispherical coordinates
            //     - find out if it is on the surface
            //   *- scale with respect to the spherical cap
            //   *- normalize
            Vector3d unitSpherePos = (ray.Origin - sphericalSurface.Center) * sphericalSurface.RadiusInv;

            unitSpherePos.Z *= canonicalNormal.Z;
            //Console.WriteLine("unit sphere position: {0}", unitSpherePos);
            Vector2d originParametric = Sampler.SampleSphereWithUniformSpacingInverse(
                unitSpherePos, surfaceSinTheta, 1);

            // - convert direction
            //   *- transform from camera space to local frame
            //     *- compute normal at origin

            //Console.WriteLine("ray origin: {0}", ray.Origin);
            Vector3d normalLocal = surface.SurfaceNormalField.GetNormal(ray.Origin);

            normalLocal.Normalize(); // TODO: check if it is unnecessary
            //Console.WriteLine("local normal: {0}", normalLocal);
            //     *- create rotation quaternion from canonical normal to local
            //       normal
            Vector3d direction = ray.Direction;

            //Console.WriteLine("local direction: {0}", direction);
            if (surface.Convex)
            {
                direction = -direction;
            }
            Vector3d rotationAxis = Vector3d.Cross(canonicalNormal, normalLocal);

            //Console.WriteLine("rotation axis: {0}", rotationAxis);
            if (rotationAxis.Length > 0)
            {
                double angle = Math.Acos(Vector3d.Dot(normalLocal, canonicalNormal));
                //Console.WriteLine("angle: {0}", angle);
                double positionPhi = originParametric.Y;
                // first transformed to the frame of the local normal
                //Console.WriteLine("position phi: {0}", positionPhi);
                Matrix4d rotMatrix = Matrix4d.CreateFromAxisAngle(rotationAxis, -angle);
                // then rotate the local direction around Z using the position phi
                rotMatrix = rotMatrix * Matrix4d.CreateRotationZ(2 * Math.PI * -positionPhi);
                direction = Vector3d.Transform(direction, rotMatrix);
            }
            //Console.WriteLine("abs. direction: {0}", direction);

            //   *- transform to hemispherical coordinates
            //     - find out if it is within the local hemisphere
            double sinTheta = direction.Z / canonicalNormal.Z;
            double dirTheta = Math.Asin(sinTheta);

            double cosTheta = Math.Sqrt(1 - sinTheta * sinTheta);
            double dirPhi   = Math.Atan2(direction.Y, direction.X);

            if (dirPhi < 0)
            {
                // map [-PI; PI] to [0; 2*PI]
                dirPhi += 2 * Math.PI;
            }
            //   *- normalize
            Vector2d directionParametric = new Vector2d(
                dirTheta / (0.5 * Math.PI),
                dirPhi / (2 * Math.PI));

            //Console.WriteLine("position parameters: {0}", new Vector2d(
            //    originParametric.X, originParametric.Y));

            return(new LensRayTransferFunction.Parameters(
                       originParametric.X, originParametric.Y,
                       directionParametric.X, directionParametric.Y));
        }
Ejemplo n.º 20
0
 public void RotateZ(double angle)
 {
     matrix          = Matrix4d.CreateRotationZ(angle) * matrix;
     inverse_matrix *= Matrix4d.CreateRotationZ(-angle);
 }
Ejemplo n.º 21
0
        public override Entity Create(Region tregion, byte[] data)
        {
            DataStream             ds  = new DataStream(data);
            DataReader             dr  = new DataReader(ds);
            GenericCharacterEntity ent = new GenericCharacterEntity(tregion);

            ent.SetPosition(Location.FromDoubleBytes(dr.ReadBytes(24), 0));
            ent.SetOrientation(new BEPUutilities.Quaternion(dr.ReadFloat(), dr.ReadFloat(), dr.ReadFloat(), dr.ReadFloat()));
            ent.SetMass(dr.ReadFloat());
            ent.CBAirForce         = dr.ReadFloat();
            ent.CBAirSpeed         = dr.ReadFloat();
            ent.CBCrouchSpeed      = dr.ReadFloat();
            ent.CBDownStepHeight   = dr.ReadFloat();
            ent.CBGlueForce        = dr.ReadFloat();
            ent.CBHHeight          = dr.ReadFloat();
            ent.CBJumpSpeed        = dr.ReadFloat();
            ent.CBMargin           = dr.ReadFloat();
            ent.CBMaxSupportSlope  = dr.ReadFloat();
            ent.CBMaxTractionSlope = dr.ReadFloat();
            ent.CBProneSpeed       = dr.ReadFloat();
            ent.CBRadius           = dr.ReadFloat();
            ent.CBSlideForce       = dr.ReadFloat();
            ent.CBSlideJumpSpeed   = dr.ReadFloat();
            ent.CBSlideSpeed       = dr.ReadFloat();
            ent.CBStandSpeed       = dr.ReadFloat();
            ent.CBStepHeight       = dr.ReadFloat();
            ent.CBTractionForce    = dr.ReadFloat();
            ent.PreRot            *= Matrix4d.CreateRotationX(dr.ReadFloat() * Utilities.PI180);
            ent.PreRot            *= Matrix4d.CreateRotationY(dr.ReadFloat() * Utilities.PI180);
            ent.PreRot            *= Matrix4d.CreateRotationZ(dr.ReadFloat() * Utilities.PI180);
            ent.mod_scale          = dr.ReadFloat();
            ent.PreRot             = Matrix4d.Scale(ent.mod_scale) * ent.PreRot;
            ent.color = System.Drawing.Color.FromArgb(dr.ReadInt());
            byte dtx = dr.ReadByte();

            ent.Visible     = (dtx & 1) == 1;
            ent.ShouldShine = (dtx & 32) == 32;
            int solidity = (dtx & (2 | 4 | 8 | 16));

            if (solidity == 2)
            {
                ent.CGroup = CollisionUtil.Solid;
            }
            else if (solidity == 4)
            {
                ent.CGroup = CollisionUtil.NonSolid;
            }
            else if (solidity == (2 | 4))
            {
                ent.CGroup = CollisionUtil.Item;
            }
            else if (solidity == 8)
            {
                ent.CGroup = CollisionUtil.Player;
            }
            else if (solidity == (2 | 8))
            {
                ent.CGroup = CollisionUtil.Water;
            }
            else if (solidity == (2 | 4 | 8))
            {
                ent.CGroup = CollisionUtil.WorldSolid;
            }
            else if (solidity == 16)
            {
                ent.CGroup = CollisionUtil.Character;
            }
            ent.model = tregion.TheClient.Models.GetModel(tregion.TheClient.Network.Strings.StringForIndex(dr.ReadInt()));
            dr.Close();
            return(ent);
        }
Ejemplo n.º 22
0
        public static void CalculateOrbit(ref LookAheadState lookAheadState, State state)
        {
            var mu = Constants.EarthGravitationalConstant;

            var radiusVector   = state.Position;
            var velocityVector = state.Velocity;

            var h = Vector3d.Cross(
                radiusVector,
                velocityVector
                );

            var r = radiusVector.Length;

            var eccentricityVector = (
                (velocityVector.LengthSquared - mu / r) * radiusVector - Vector3d.Dot(radiusVector, velocityVector) * velocityVector
                ) / mu;

            var eccentricity          = eccentricityVector.Length;
            var specificOrbitalEnergy = velocityVector.LengthSquared / 2 - mu / r;

            var semiMajorAxis = -mu / (2 * specificOrbitalEnergy);
            var semiMinorAxis = semiMajorAxis * Math.Sqrt(1 - eccentricity * eccentricity);

            var apoapsis  = (1 + eccentricity) * semiMajorAxis;
            var periapsis = (1 - eccentricity) * semiMajorAxis;

            var semiLatusRectum = periapsis * (1 + eccentricity);

            var thetaFromPeriapsis = Math.Acos(((semiLatusRectum - r) / (eccentricity * r)) % (Math.PI * 2));

            var actualRotation = Math.Atan2(radiusVector.Y, radiusVector.X) + Math.PI / 2;

            double argumentOfPeriapsis;

            if (h.Z < 0)
            {
                thetaFromPeriapsis  = Math.PI * 2 - thetaFromPeriapsis;
                argumentOfPeriapsis = actualRotation - thetaFromPeriapsis;
                //rotationMatrix = Matrix4d.Mult(rotationMatrix, Matrix4d.RotateY(Math.PI));
            }
            else
            {
                argumentOfPeriapsis = actualRotation - thetaFromPeriapsis;
            }
            var rotationMatrix = Matrix4d.CreateRotationZ(argumentOfPeriapsis);


            int    highAccuracyPoints = lookAheadState.FuturePositions.Length / 2;
            double highAccuracyAngle  = Math.PI / 20;

            if (SampleOrbit(ref lookAheadState.FuturePositions, ref rotationMatrix, semiLatusRectum, eccentricity, thetaFromPeriapsis, highAccuracyAngle, 0, highAccuracyPoints))
            {
                SampleOrbit(ref lookAheadState.FuturePositions, ref rotationMatrix, semiLatusRectum, eccentricity, thetaFromPeriapsis - highAccuracyAngle, Math.PI * 2 - highAccuracyAngle, highAccuracyPoints, lookAheadState.FuturePositions.Length - highAccuracyPoints);
            }
            //double approximatePerimeter = Math.PI * (3 * (semiMajorAxis + semiMinorAxis) - Math.Sqrt((3*semiMajorAxis + semiMinorAxis) * (semiMajorAxis + 3*semiMinorAxis)));

            lookAheadState.Apoapsis            = apoapsis - Constants.EarthRadius;
            lookAheadState.Periapsis           = periapsis - Constants.EarthRadius;
            lookAheadState.Eccentricity        = eccentricity;
            lookAheadState.SemiMajorAxis       = semiMajorAxis;
            lookAheadState.SemiMinorAxis       = semiMinorAxis;
            lookAheadState.SemiLatusRectum     = semiLatusRectum;
            lookAheadState.ArgumentOfPeriapsis = argumentOfPeriapsis;
            lookAheadState.Theta = thetaFromPeriapsis;

            //Title = string.Format("e{0,2:F}, {1,2:F} km {2,2:F} km, r {3,2:F}, v {4,2:F} {5,2:F} {6,2:F} {7,2:F}, a{8,2:F} b{9,2:F}", e, (apoapsis - Constants.EarthRadius)/1000, (periapsis - Constants.EarthRadius) / 1000, (radiusVector.Length - Constants.EarthRadius) /1000, velocityVector.Length / 1000, theta2, actualRotation, offset, (a - Constants.EarthRadius)/1000, (b - Constants.EarthRadius)/1000);

            /*
             *          GL.PushMatrix();
             *          //GL.Rotate(offset / Math.PI * 180, Vector3d.UnitZ);
             *          GL.LineWidth(2f);
             *          GL.Color3(1f, 0f, 0f);
             *          GL.Begin(PrimitiveType.LineLoop);
             *          for (var theta = 0.0; theta < Math.PI * 2.0; theta += 0.01)
             *          {
             *              GL.Vertex3(Math.Sin(theta) * b, Math.Cos(theta) * a + (apoapsis - a), 0);
             *          }
             *          GL.End();
             *          GL.PopMatrix();
             */
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Convert a ray with origin at the back or front lens surface from
        /// its parametric representation.
        /// </summary>
        /// <param name="position">Position on lens surface in parameteric
        /// representation (normalized hemispherical coordinates).</param>
        /// <param name="direction">Direction of the ray with respect to the
        /// local frame in parameteric representation (normalized hemispherical
        /// coordinates).
        /// </param>
        /// <param name="canonicalNormal">Normal of the lens surface
        /// hemisphere (typically (0,0,1) for the back surface or (0,0,-1) for
        /// the front surface).</param>
        /// <param name="surfaceSinTheta">Sine of the surface spherical cap
        /// theta angle.</param>
        /// <param name="sphericalSurface">Lens surface represented as a
        /// sphere.</param>
        /// <param name="surface">Lens surface with its normal field.</param>
        /// <returns>Ray corresponding to its parametric representation.
        /// </returns>
        public Ray ConvertParametersToSurfaceRay(
            LensRayTransferFunction.Parameters parameters,
            Vector3d canonicalNormal, double surfaceSinTheta,
            Sphere sphericalSurface, ElementSurface surface)
        {
            //Console.WriteLine("parameters->ray");

            //Console.WriteLine("position parameters: {0}", parameters.Position);
            // uniform spacing sampling for LRTF sampling
            Vector3d unitSpherePos = Sampler.SampleSphereWithUniformSpacing(
                parameters.Position, surfaceSinTheta, 1);

            //Console.WriteLine("unit sphere position: {0}", unitSpherePos);
            unitSpherePos.Z *= canonicalNormal.Z;

            Vector3d lensPos = sphericalSurface.Center + sphericalSurface.Radius * unitSpherePos;
            //Console.WriteLine("ray origin: {0}", lensPos);

            // - get normal N at P
            Vector3d normalLocal = surface.SurfaceNormalField.GetNormal(lensPos);
            // - compute direction D from spherical coordinates (wrt normal Z = (0,0,+/-1))
            double   theta      = 0.5 * Math.PI * parameters.DirectionTheta;
            double   phi        = 2 * Math.PI * parameters.DirectionPhi;
            double   cosTheta   = Math.Cos(theta);
            Vector3d directionZ = new Vector3d(
                Math.Cos(phi) * cosTheta,
                Math.Sin(phi) * cosTheta,
                Math.Sin(theta) * canonicalNormal.Z);

            // - rotate D from Z to N frame
            //   - using a (normalized) quaternion Q
            //   - N and Z should be assumed to be already normalized
            //   - more efficient method: Efficiently building a matrix to
            //     rotate one vector to another [moller1999]

            normalLocal.Normalize(); // TODO: check if it is unnecessary
            //Console.WriteLine("abs. direction: {0}", directionZ);
            //Console.WriteLine("local normal: {0}", normalLocal);
            Vector3d rotationAxis = Vector3d.Cross(canonicalNormal, normalLocal);
            //Console.WriteLine("rotation axis: {0}", rotationAxis);

            Vector3d rotatedDir = directionZ;

            if (rotationAxis.Length > 0)
            {
                double angle = Math.Acos(Vector3d.Dot(canonicalNormal, normalLocal));
                //Console.WriteLine("angle: {0}", angle);
                // first the local direction must be rotated around using the position phi!
                //Console.WriteLine("position phi: {0}", parameters.PositionPhi);
                Matrix4d rotMatrix = Matrix4d.CreateRotationZ(2 * Math.PI * parameters.PositionPhi);
                // only then can be transformed to the frame of the local normal
                rotMatrix  = rotMatrix * Matrix4d.CreateFromAxisAngle(rotationAxis, angle);
                rotatedDir = Vector3d.Transform(directionZ, rotMatrix);
            }
            if (surface.Convex)
            {
                rotatedDir = -rotatedDir;
            }
            //Console.WriteLine("local direction: {0}", rotatedDir);

            Ray result = new Ray(lensPos, rotatedDir);

            return(result);
        }
Ejemplo n.º 24
0
        /// <summary>
        /// 起動時
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormRotationMatrix_Load(object sender, EventArgs e)
        {
            #region glControlの追加 (デザイナが壊れるため)

            //
            // glControlReciProObjects
            //
            this.glControlReciProObjects = new GLControlAlpha
            {
                AllowMouseScaling     = false,
                AllowMouseTranslating = false,
                Anchor          = AnchorStyles.Top | AnchorStyles.Right,
                BorderStyle     = BorderStyle.Fixed3D,
                DisablingOpenGL = false,
                Location        = new Point(273, 248),
                Margin          = new Padding(0),
                Name            = "glControlReciProObjects",
                NodeCoefficient = 1,
                ProjWidth       = 1D,
                Size            = new Size(130, 130),
            };
            this.glControlReciProObjects.WorldMatrixChanged += new System.EventHandler(this.GlControlReciProAxes_WorldMatrixChanged);

            //
            // glControlReciProAxes
            //
            this.glControlReciProAxes = new GLControlAlpha
            {
                AllowMouseScaling     = false,
                AllowMouseTranslating = false,
                Anchor          = AnchorStyles.Top | AnchorStyles.Right,
                BorderStyle     = BorderStyle.Fixed3D,
                DisablingOpenGL = false,
                Location        = new Point(273, 114),
                Margin          = new Padding(0),
                Name            = "glControlReciProAxes",
                NodeCoefficient = 1,
                ProjWidth       = 2.8D,
                Size            = new Size(130, 130),
            };
            glControlReciProAxes.WorldMatrixChanged += new EventHandler(GlControlReciProAxes_WorldMatrixChanged);

            //
            // glControlReciProGonio
            //
            this.glControlReciProGonio = new GLControlAlpha
            {
                AllowMouseTranslating = false,
                Anchor          = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right,
                BorderStyle     = BorderStyle.Fixed3D,
                DisablingOpenGL = false,
                Location        = new Point(5, 114),
                Margin          = new Padding(0),
                Name            = "glControlReciProGonio",
                ProjWidth       = 5D,
                Size            = new Size(264, 264),
            };
            glControlReciProGonio.WorldMatrixChanged += new EventHandler(this.GlControlReciProAxes_WorldMatrixChanged);

            //
            // glControlExpObjects
            //
            this.glControlExpObjects = new GLControlAlpha
            {
                AllowMouseScaling     = false,
                AllowMouseTranslating = false,
                Anchor          = AnchorStyles.Top | AnchorStyles.Right,
                BorderStyle     = BorderStyle.Fixed3D,
                DisablingOpenGL = false,
                Location        = new Point(273, 248),
                Margin          = new Padding(0),
                Name            = "glControlExpObjects",
                ProjWidth       = 1D,
                Size            = new Size(130, 130),
            };
            this.glControlExpObjects.WorldMatrixChanged += new EventHandler(GlControlReciProAxes_WorldMatrixChanged);
            //
            // glControlExpAxes
            //
            this.glControlExpAxes = new GLControlAlpha
            {
                AllowMouseScaling     = false,
                AllowMouseTranslating = false,
                Anchor          = AnchorStyles.Top | AnchorStyles.Right,
                BorderStyle     = BorderStyle.Fixed3D,
                DisablingOpenGL = false,
                Location        = new Point(273, 114),
                Margin          = new System.Windows.Forms.Padding(0),
                Name            = "glControlExpAxes",
                ProjWidth       = 2.8D,
                Size            = new Size(130, 130),
            };
            this.glControlExpAxes.WorldMatrixChanged += new EventHandler(GlControlReciProAxes_WorldMatrixChanged);
            //
            // glControlExpGonio
            //
            this.glControlExpGonio = new GLControlAlpha
            {
                AllowMouseTranslating = false,
                Anchor          = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right,
                BorderStyle     = BorderStyle.Fixed3D,
                DisablingOpenGL = false,
                Location        = new Point(5, 114),
                Margin          = new Padding(0),
                Name            = "glControlExpGonio",
                ProjWidth       = 5D,
                Size            = new Size(264, 264),
            };
            this.glControlExpGonio.WorldMatrixChanged += new System.EventHandler(this.GlControlReciProAxes_WorldMatrixChanged);


            groupBox2.Controls.Add(glControlExpObjects);
            groupBox2.Controls.Add(glControlExpAxes);
            groupBox2.Controls.Add(glControlExpGonio);

            groupBox1.Controls.Add(glControlReciProObjects);
            groupBox1.Controls.Add(glControlReciProAxes);
            groupBox1.Controls.Add(glControlReciProGonio);

            #endregion
            glControlReciProGonio.WorldMatrix = Matrix4d.CreateRotationZ(-Math.PI / 4) * Matrix4d.CreateRotationX(-0.4 * Math.PI);
            SetRotation();

            numericBoxPhi.TextBoxBackColor   = numericBoxExp1.TextBoxBackColor = Color.FromArgb(255, 180, 180, 0);
            numericBoxTheta.TextBoxBackColor = numericBoxExp2.TextBoxBackColor = Color.FromArgb(255, 0, 180, 180);
            numericBoxPsi.TextBoxBackColor   = numericBoxExp3.TextBoxBackColor = Color.FromArgb(255, 180, 0, 180);

            numericBoxPhi.TextBoxForeColor         = numericBoxExp1.TextBoxForeColor =
                numericBoxTheta.TextBoxForeColor   = numericBoxExp2.TextBoxForeColor =
                    numericBoxPsi.TextBoxForeColor = numericBoxExp3.TextBoxForeColor = Color.FromArgb(255, 255, 255, 255);
        }