예제 #1
0
    // Start is called before the first frame update
    void Start()
    {
        DQuaternion.Test();


        SetParameters(StartingInertia, StartingOmega, ApplyAdjustment);
    }
예제 #2
0
파일: ELSovler.cs 프로젝트: MrHuggs/Poinsot
    public static double EnergyFromOrientation(DQuaternion o, DVector3 L, DVector3 I)
    {
        var ir = DQuaternion.Inverse(o);

        DVector3 body_l = ir * L;

        double e = body_l.x * body_l.x / I.x +
                   body_l.y * body_l.y / I.y +
                   body_l.z * body_l.z / I.z;

        e *= .5f;

        return(e);
    }
예제 #3
0
    void UpdateOrientation(targ_type dt)
    {
        DVector3 axis = Omega.normalized;
        // Omega is in radians/sec, but AngleAxis need degrees.
        targ_type w = (targ_type)(Omega.magnitude * (360 / (2 * Math.PI)));

        // Note that in Unity, a positive angle of rotation is clockwise around the
        // axis of rotation. This is unusual....

        var inc = DQuaternion.AngleAxis(w * dt, axis);

        PrevOrientation = Orientation;
        Orientation     = inc * Orientation;
    }
예제 #4
0
    void Update()
    {
        Quaternion q = new Quaternion();

        q.SetFromToRotation(Vector3.up, DVector3.ToUnity(Body.Omega));

        Omega.transform.localRotation = q;
        Omega.SetLength((float)Body.Omega.magnitude / MasterScale);

        AngularVelocityTrail.transform.localPosition = DVector3.ToUnity(Body.Omega / MasterScale);

        InertiaEllipsoid.transform.rotation = DQuaternion.ToUnity(Body.Orientation);

        AngularVelocityTrail.enabled = true;
    }
예제 #5
0
파일: ELSovler.cs 프로젝트: MrHuggs/Poinsot
    public DQuaternion AdjustOrientation(DQuaternion initial)
    {
        DQuaternion cur   = initial;
        int         niter = 0;

        double ecur_i = EnergyFromOrientation(cur);
        double del_i  = Energy - ecur_i;

        for (; ;)
        {
            double ecur = EnergyFromOrientation(cur);
            double del  = Energy - ecur;

            if (Math.Abs(del) < Energy * .0001f)
            {
                break;
            }

            var next = Iterate(initial);


            double ef   = EnergyFromOrientation(next);
            double delf = Energy - ef;
            Debug.Assert(delf <= del);

            cur = next;

            niter++;
            if (niter > 6)
            {
                Debug.Log("EL Sovler ran out of iterations.");
                break;
            }
        }

        if (niter > 0)
        {
            double ecur_f = EnergyFromOrientation(cur);
            double del_f  = Energy - ecur_f;

            //Debug.Log(string.Format("ELSolver changed del from {0} to {1} out of {2} in {3} iter.",
            //			del_i, del_f, Energy, niter));
        }



        return(cur);
    }
예제 #6
0
    public void SetParameters(Vector3 inertia, Vector3 omega, bool apply_adjustment)
    {
        ConditionParameters(ref inertia, ref omega);

        InitialOmega = DVector3.FromUnity(omega);

        BodyOmega = InitialOmega;         // Initial BTW is identity

        bool b = ExtentsFromInertia(DVector3.FromUnity(inertia), out Extents);

        if (b)
        {
            Debug.Assert((InertiaFromExtents(Extents) - DVector3.FromUnity(inertia)).magnitude < .001f);
        }
        else
        {
            Debug.Log(("Requested inertia values don't correspond to an ellipsoid object."));
        }

        ApplyAdjustment = apply_adjustment;

        transform.localScale = DVector3.ToUnity(Extents);

        Orientation     = DQuaternion.identity;
        PrevOrientation = DQuaternion.identity;

        I = DVector3.FromUnity(inertia);

        Debug.Log(string.Format("Inertia Values: ({0},{1},{2})", I.x, I.y, I.z));

        // Initially the body and world coordinates match:
        L.x = I.x * Omega.x;
        L.y = I.y * Omega.y;
        L.z = I.z * Omega.z;

        Energy = ELSolver.EnergyFromOrientation(Orientation, L, I);
        Debug.Assert(Energy == CurrentE());

        ELSolver    = new ELSolver(Energy, L, I);
        UpdateCount = 0;

        DumpParameters();

        BodyParmsChanged?.Invoke();
    }
예제 #7
0
    private void Normalize()
    {
        // Renormalize the orientation, and make sure angular momentum
        // and energy are being conserved.
        Orientation.Normalize();

        if (ApplyAdjustment)
        {
            Orientation = ELSolver.AdjustOrientation(Orientation);

            var ir     = DQuaternion.Inverse(Orientation);
            var body_l = ir * L;

            _BodyOmega.x = body_l.x / I.x;
            _BodyOmega.y = body_l.y / I.y;
            _BodyOmega.z = body_l.z / I.z;
        }
    }
예제 #8
0
    void UpdateOmega(targ_type dt)
    {
        var body_omega = BodyOmega;

        DVector3 body_omega_dt = new DVector3();

        // Euler's equations for torque free motion.
        // Even the the Unity coordinate system is left-handed, this still works.
        // Uses explicit Euler integration...
        body_omega_dt.x = (I.y - I.z) * body_omega.y * body_omega.z / I.x;
        body_omega_dt.y = (I.z - I.x) * body_omega.z * body_omega.x / I.y;
        body_omega_dt.z = (I.x - I.y) * body_omega.x * body_omega.y / I.z;

        body_omega += body_omega_dt * dt;

        BodyOmega = body_omega;

        Debug.Assert(DVector3.Distance(body_omega, DQuaternion.Inverse(Orientation) * Omega) < 1.0e10);
    }
예제 #9
0
파일: ELSovler.cs 프로젝트: MrHuggs/Poinsot
    // Perform a single iteration: Find the energy delta, measure the gradient WRT
    // each perturbation. Find the one with the largest effect and apply a scaled adjustment
    // to the orientation.
    //
    DQuaternion Iterate(DQuaternion cur_orientation)
    {
        double ecur = EnergyFromOrientation(cur_orientation);
        double del  = Energy - ecur;

        double dm      = 0;
        double delbest = 0;
        int    ibest   = 0;

        for (int im = 0; im < Adjustments.Length; im++)
        {
            var o  = Adjustments[im] * cur_orientation;
            var ep = EnergyFromOrientation(o);
            var cd = ep - ecur;
            if (Math.Abs(cd) > dm)
            {
                ibest   = im;
                delbest = cd;
                dm      = Math.Abs(cd);
            }
        }

        double factor = del / delbest;

        if (factor < -4)
        {
            factor = -4;                                        // There is no clamp for doubles.
        }
        else if (factor > 4)
        {
            factor = 4;
        }

        double angle = AdjustAngle * factor;

        var adjust = DQuaternion.AngleAxis(angle, AdjustmentDirs[ibest]);

        var next_orientation = adjust * cur_orientation;

        return(next_orientation);
    }
예제 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="gameTime"></param>
        void DrawInternal(GameTime gameTime)
        {
            var dev = Game.GraphicsDevice;

            viewMatrix = DMatrix.LookAtRH(cameraPosition, DVector3.Zero, DVector3.UnitY);

            DMatrix vvvM = viewMatrix;

            viewMatrix.TranslationVector = DVector3.Zero;

            var camPos = cameraPosition;

            if (Game.InputDevice.IsKeyDown(Keys.LeftShift))
            {
                DVector3 cameraUp    = cameraPosition / cameraPosition.Length();
                DVector3 lookAtPoint = cameraUp * Config.earthRadius;

                double length = Config.CameraDistance - Config.earthRadius;

                var quat = DQuaternion.RotationAxis(DVector3.UnitY, FreeCamYaw) * DQuaternion.RotationAxis(DVector3.UnitX, FreeCamPitch);

                var qRot = DMatrix.RotationQuaternion(quat);
                var mat  = DMatrix.Identity;

                var xAxis = DVector3.TransformNormal(DVector3.UnitX, DMatrix.RotationAxis(DVector3.UnitY, Yaw));
                xAxis.Normalize();

                mat.Up      = cameraUp;
                mat.Right   = xAxis;
                mat.Forward = DVector3.Cross(xAxis, cameraUp);
                mat.Forward.Normalize();

                var matrix = qRot * mat;

                var c = DVector3.Transform(new DVector3(0, 0, length), matrix);

                var camPoint = new DVector3(c.X, c.Y, c.Z) + lookAtPoint;

                camPos = camPoint;

                viewMatrix = DMatrix.LookAtRH(camPoint, lookAtPoint, cameraUp);
                vvvM       = viewMatrix;
                viewMatrix.TranslationVector = DVector3.Zero;
            }

            viewMatrixFloat = DMatrix.ToFloatMatrix(viewMatrix);
            projMatrixFloat = DMatrix.ToFloatMatrix(projMatrix);

            var viewDir = cameraPosition / cameraPosition.Length();

            constBuffer.Data.ViewProj      = viewMatrixFloat * projMatrixFloat;
            constBuffer.Data.ViewPositionX = camPos.X;
            constBuffer.Data.ViewPositionY = camPos.Y;
            constBuffer.Data.ViewPositionZ = camPos.Z;
            constBuffer.Data.Temp          = new Vector4(0.0f, (float)Config.earthRadius, 0, 0);
            constBuffer.Data.ViewDir       = new Vector4((float)viewDir.X, (float)viewDir.Y, (float)viewDir.Z, 0);
            constBuffer.UpdateCBuffer();

            Game.GraphicsDevice.VertexShaderConstants[0] = constBuffer;

            Game.GraphicsDevice.PixelShaderSamplers[0]  = SamplerState.LinearClamp;
            Game.GraphicsDevice.PixelShaderResources[1] = frame;

            if (gridVertexBuffer != null)
            {
                Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
                    GlobeFlags.DRAW_POLY | GlobeFlags.DRAW_VERTEX_POLY | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_TEXTURED | (Config.ShowFrames ? GlobeFlags.SHOW_FRAMES : GlobeFlags.NONE),
                    Primitive.TriangleList,
                    BlendState.AlphaBlend,
                    RasterizerState.CullCW,
                    DepthStencilState.Readonly);

                Game.GraphicsDevice.PixelShaderResources[0] = gridTex;

                Game.GraphicsDevice.SetupVertexInput(gridVertexBuffer, gridIndexBuffer);
                dev.DrawIndexed(/*Primitive.TriangleList,*/ gridIndexBuffer.Capacity, 0, 0);
            }

            var rastState = Game.InputDevice.IsKeyDown(Keys.Tab) ? RasterizerState.Wireframe : RasterizerState.CullCW;

            Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
                GlobeFlags.DRAW_POLY | GlobeFlags.DRAW_VERTEX_POLY | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_TEXTURED | (Config.ShowFrames ? GlobeFlags.SHOW_FRAMES : GlobeFlags.NONE),
                Primitive.TriangleList,
                BlendState.AlphaBlend,
                rastState,
                DepthStencilState.Default);

            foreach (var globeTile in tilesToRender)
            {
                var tex = Game.GetService <LayerService>().MapLayer.CurrentMapSource.GetTile(globeTile.Value.X, globeTile.Value.Y, globeTile.Value.Z).Tile;
                dev.PixelShaderResources[0] = tex;

                dev.SetupVertexInput(globeTile.Value.VertexBuf, globeTile.Value.IndexBuf);
                dev.DrawIndexed(globeTile.Value.IndexBuf.Capacity, 0, 0);
            }


            dotsBuf.Data.View = viewMatrixFloat;
            dotsBuf.Data.Proj = projMatrixFloat;
            dotsBuf.UpdateCBuffer();

            //// Draw simple railroads
            //if (simpleRailroadsVB != null && Config.ShowRailroads) {
            //	Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
            //		GlobeFlags.DRAW_VERTEX_LINES | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_SEGMENTED_LINES,
            //		Primitive.LineList,
            //		BlendState.AlphaBlend,
            //		RasterizerState.CullNone,
            //		DepthStencilState.None);
            //
            //	constBuffer.Data.Temp = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
            //	constBuffer.UpdateCBuffer();
            //
            //	Game.GraphicsDevice.VertexShaderConstants[1]	= dotsBuf;
            //	Game.GraphicsDevice.GeometryShaderConstants[1]	= dotsBuf;
            //	Game.GraphicsDevice.GeometryShaderConstants[0]	= constBuffer;
            //	Game.GraphicsDevice.VertexShaderConstants[0]	= constBuffer;
            //	Game.GraphicsDevice.PixelShaderConstants[0]		= constBuffer;
            //
            //	Game.GraphicsDevice.PixelShaderResources[0] = railRoadsTex;
            //	Game.GraphicsDevice.PixelShaderSamplers[0]	= SamplerState.LinearWrap;
            //
            //	dev.SetupVertexInput(simpleRailroadsVB, null);
            //	dev.Draw(simpleRailroadsVB.Capacity, 0);
            //}


            //// Draw buildings
            //if (contourBuildingsVB != null && Config.ShowBuildingsContours) {
            //
            //	Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
            //		GlobeFlags.DRAW_POLY | GlobeFlags.DRAW_VERTEX_POLY | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_COLOR,
            //		Primitive.LineList,
            //		BlendState.AlphaBlend,
            //		RasterizerState.CullNone,
            //		DepthStencilState.None);
            //
            //
            //	constBuffer.Data.Temp = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
            //	constBuffer.UpdateCBuffer();
            //
            //	Game.GraphicsDevice.VertexShaderConstants[0]	= constBuffer;
            //	Game.GraphicsDevice.PixelShaderConstants[0]		= constBuffer;
            //
            //	dev.SetupVertexInput(contourBuildingsVB, null);
            //	dev.Draw(contourBuildingsVB.Capacity, 0);
            //}

            // Draw Lines
            if (linesBatch.Count != 0 && Config.ShowRoads)
            {
                Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
                    GlobeFlags.DRAW_POLY | GlobeFlags.DRAW_VERTEX_POLY | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_COLOR,
                    Primitive.LineList,
                    BlendState.AlphaBlend,
                    RasterizerState.CullNone,
                    DepthStencilState.None);


                constBuffer.Data.Temp = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
                constBuffer.UpdateCBuffer();

                Game.GraphicsDevice.VertexShaderConstants[0] = constBuffer;
                Game.GraphicsDevice.PixelShaderConstants[0]  = constBuffer;

                foreach (var vb in linesBatch)
                {
                    dev.SetupVertexInput(vb, null);
                    dev.Draw(vb.Capacity, 0);
                }
            }



            // Draw simple railroads
            if (linesPolyBatch.Count != 0 && Config.ShowRoads)
            {
                Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
                    GlobeFlags.DRAW_VERTEX_LINES | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_LINES,
                    Primitive.LineList,
                    BlendState.AlphaBlend,
                    RasterizerState.CullNone,
                    DepthStencilState.None);

                constBuffer.Data.Temp = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
                constBuffer.UpdateCBuffer();

                Game.GraphicsDevice.VertexShaderConstants[1]   = dotsBuf;
                Game.GraphicsDevice.GeometryShaderConstants[1] = dotsBuf;
                Game.GraphicsDevice.GeometryShaderConstants[0] = constBuffer;
                Game.GraphicsDevice.VertexShaderConstants[0]   = constBuffer;
                Game.GraphicsDevice.PixelShaderConstants[0]    = constBuffer;


                foreach (var vb in linesPolyBatch)
                {
                    dev.SetupVertexInput(vb, null);
                    dev.Draw(vb.Capacity, 0);
                }
            }



            if (Config.ShowPOI)
            {
                dotsBuf.Data.TexWHST = new Vector4(geoObjects.Width, geoObjects.Height, 164.0f, 0.05f);
                dotsBuf.UpdateCBuffer();

                Game.GraphicsDevice.VertexShaderConstants[1]   = dotsBuf;
                Game.GraphicsDevice.GeometryShaderConstants[1] = dotsBuf;
                Game.GraphicsDevice.GeometryShaderConstants[0] = constBuffer;

                Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
                    GlobeFlags.DRAW_VERTEX_LINES | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_DOTS | GlobeFlags.DOTS_WORLDSPACE,
                    Primitive.PointList,
                    BlendState.AlphaBlend,
                    RasterizerState.CullNone,
                    DepthStencilState.None);

                Game.GraphicsDevice.PixelShaderResources[0] = geoObjects;
                Game.GraphicsDevice.PixelShaderSamplers[0]  = SamplerState.LinearClamp;

                dev.SetupVertexInput(dotsVB, null);
                dev.Draw(dotsVB.Capacity - geoObjectStart, geoObjectStart);
            }



            // Draw people
            if (Config.ShowPeople)
            {
                dotsBuf.Data.TexWHST = new Vector4(socioClasses.Width, socioClasses.Height, 64.0f, 0.025f);
                dotsBuf.UpdateCBuffer();

                Game.GraphicsDevice.VertexShaderConstants[1]   = dotsBuf;
                Game.GraphicsDevice.GeometryShaderConstants[1] = dotsBuf;
                Game.GraphicsDevice.GeometryShaderConstants[0] = constBuffer;

                Game.GraphicsDevice.PixelShaderResources[0] = socioClasses;
                Game.GraphicsDevice.PixelShaderSamplers[0]  = SamplerState.LinearClamp;

                Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
                    GlobeFlags.DRAW_VERTEX_LINES | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_DOTS | GlobeFlags.DOTS_WORLDSPACE,
                    Primitive.PointList,
                    BlendState.AlphaBlend,
                    RasterizerState.CullNone,
                    DepthStencilState.None);

                dev.SetupVertexInput(dotsVB, null);
                dev.Draw(geoObjectStart - 1, 0);
            }



            //// Draw heatmap
            //if (Config.ShowHeatMap && heatVB != null) {
            //	constBuffer.Data.Temp = new Vector4((float)Config.MaxHeatMapLevel, Config.HeatMapTransparency, HeatMapDim, 0);
            //	constBuffer.UpdateCBuffer();
            //
            //	Game.GraphicsDevice.VertexShaderConstants[0]	= constBuffer;
            //	Game.GraphicsDevice.PixelShaderConstants[0]		= constBuffer;
            //
            //	Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
            //		GlobeFlags.DRAW_POLY | GlobeFlags.DRAW_VERTEX_POLY | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_HEAT,
            //		Primitive.TriangleList,
            //		BlendState.AlphaBlend,
            //		RasterizerState.CullNone,
            //		DepthStencilState.None);
            //
            //
            //	Game.GraphicsDevice.PixelShaderSamplers[0] = SamplerState.LinearClamp;
            //	Game.GraphicsDevice.PixelShaderSamplers[1] = SamplerState.AnisotropicClamp;
            //
            //	Game.GraphicsDevice.PixelShaderResources[0] = heatMap;
            //	Game.GraphicsDevice.PixelShaderResources[1] = heatMapPalette;
            //
            //	Game.GraphicsDevice.SetupVertexInput(heatVB, heatIB);
            //	Game.GraphicsDevice.DrawIndexed(heatIB.Capacity, 0, 0);
            //}

            //// Draw infection map
            //if (Config.ShowInfectHeatMap && heatVB != null) {
            //	constBuffer.Data.Temp = new Vector4((float)Config.MaxInfectLevel, 0.0f, HeatMapDim, 0);
            //	constBuffer.UpdateCBuffer();
            //
            //	Game.GraphicsDevice.VertexShaderConstants[0]	= constBuffer;
            //	Game.GraphicsDevice.PixelShaderConstants[0]		= constBuffer;
            //
            //	Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
            //		GlobeFlags.DRAW_POLY | GlobeFlags.DRAW_VERTEX_POLY | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_HEAT,
            //		Primitive.TriangleList,
            //		BlendState.AlphaBlend,
            //		RasterizerState.CullNone,
            //		DepthStencilState.None);
            //
            //	Game.GraphicsDevice.PixelShaderSamplers[0] = SamplerState.LinearClamp;
            //	Game.GraphicsDevice.PixelShaderSamplers[1] = SamplerState.AnisotropicClamp;
            //
            //	Game.GraphicsDevice.PixelShaderResources[0] = infectMap;
            //	Game.GraphicsDevice.PixelShaderResources[1] = heatMapPalette;
            //
            //	Game.GraphicsDevice.SetupVertexInput(heatVB, heatIB);
            //	Game.GraphicsDevice.DrawIndexed(/*Primitive.TriangleList,*/ heatIB.Capacity, 0, 0);
            //}


            ////Draw atmosphere
            //if (Config.ShowAtmosphere && atmosVB != null) {
            //	constBuffer.Data.Temp = new Vector4(atmosTime, Config.ArrowsScale, 0.0f, 0);
            //	constBuffer.UpdateCBuffer();
            //
            //	Game.GraphicsDevice.VertexShaderConstants[0]	= constBuffer;
            //	Game.GraphicsDevice.PixelShaderConstants[0]		= constBuffer;
            //
            //
            //	Game.GraphicsDevice.PixelShaderResources[0] = atmosTexture;
            //	Game.GraphicsDevice.PixelShaderResources[1] = heatMapPalette;
            //	Game.GraphicsDevice.PixelShaderResources[2] = atmosNextTexture;
            //	Game.GraphicsDevice.PixelShaderResources[3] = arrowTex;
            //
            //
            //	Game.GraphicsDevice.PixelShaderSamplers[0] = SamplerState.LinearClamp;
            //	Game.GraphicsDevice.PixelShaderSamplers[1] = SamplerState.AnisotropicClamp;
            //
            //	Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
            //		GlobeFlags.DRAW_VERTEX_POLY | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_ATMOSPHERE,
            //		Primitive.TriangleList,
            //		BlendState.AlphaBlend,
            //		RasterizerState.CullNone,
            //		DepthStencilState.None);
            //
            //	Game.GraphicsDevice.SetupVertexInput(atmosVB, atmosIB);
            //	Game.GraphicsDevice.DrawIndexed(atmosIB.Capacity, 0, 0);
            //}


            //Draw airlines
            if (airLinesVB != null && Config.ShowAirLines)
            {
                constBuffer.Data.Temp = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
                constBuffer.UpdateCBuffer();

                Game.GraphicsDevice.VertexShaderConstants[1]   = dotsBuf;
                Game.GraphicsDevice.GeometryShaderConstants[0] = constBuffer;
                Game.GraphicsDevice.GeometryShaderConstants[1] = dotsBuf;

                Game.GraphicsDevice.PipelineState = myMiniFactory.ProducePipelineState(
                    GlobeFlags.DRAW_VERTEX_LINES | GlobeFlags.USE_GEOCOORDS | GlobeFlags.VERTEX_SHADER | GlobeFlags.DRAW_ARCS,
                    Primitive.LineList,
                    BlendState.Additive,
                    RasterizerState.CullNone,
                    DepthStencilState.Readonly);

                dev.SetupVertexInput(airLinesVB, null);
                dev.Draw(/*Primitive.LineList,*/ airLinesVB.Capacity, 0);
            }

            DrawDebugLines();

            //Game.GetService<DebugStrings>().Add("Cam pos     : " + Game.GetService<Camera>().CameraMatrix.TranslationVector, Color.Red);
            //Game.GetService<DebugStrings>().Add("Radius      : " + Config.earthRadius, Color.Red);
            //Game.GetService<DebugStrings>().Add("Level       : " + CurrentLevel, Color.Green);
            //Game.GetService<DebugStrings>().Add("CamDistance : " + Config.CameraDistance, Color.Green);
            //Game.GetService<DebugStrings>().Add("Pitch : " + Pitch, Color.Green);
            //Game.GetService<DebugStrings>().Add("Width : " + Game.GraphicsDevice.Viewport.Width, Color.Green);
            Game.GetService <DebugStrings>().Add("Height : " + (Config.CameraDistance - Config.earthRadius) * 1000.0, Color.Green);
        }
예제 #11
0
 public static float Angle(DQuaternion left, DQuaternion right)
 {
     return (float)Math.Acos(Dot(left, right));
 }
예제 #12
0
    //Spherically interpolates between from and to by t.
    public static DQuaternion Slerp(DQuaternion start, DQuaternion end, float amount)
    {
        float opposite;
        float inverse;
        float dot = Dot(start, end);                                            // Dot product
        DQuaternion result = Zero;

        if (Math.Abs(dot) > 1.0f)                                               // If abs is greater then 1
        {                                                                       // This simple logic helps with the
            inverse = 1.0f - amount;                                            // look between slerp and lerp
            opposite = amount * Math.Sign(dot);                                 // This is default for lerp
        }
        else                                                                    // else it will calculate a
        {                                                                       // better inverse and opposite using
            float acos = (float)Math.Acos(Math.Abs(dot));                       // acos and inverse sin
            float invSin = (float)(1.0 / Math.Sin(acos));

            inverse = (float)Math.Sin((1.0f - amount) * acos) * invSin;
            opposite = (float)Math.Sin(amount * acos) * invSin * Math.Sign(dot);
        }

        result.x = (inverse * start.x) + (opposite * end.x);
        result.y = (inverse * start.y) + (opposite * end.y);
        result.z = (inverse * start.z) + (opposite * end.z);
        result.w = (inverse * start.w) + (opposite * end.w);

        return result;
    }
예제 #13
0
 //Rotates a rotation from towards to.
 //The from quaternion is rotated towards to by an angular step of maxDegreesDelta (but note that the rotation will not overshoot).
 //Negative values of maxDegreesDelta will move away from to until the rotation is exactly the opposite direction.
 public static DQuaternion RotateTowards(DQuaternion from, DQuaternion to, float maxDegreesDelta)
 {
     float angle = Angle(from, to);
     if (angle < maxDegreesDelta)
         return to;
     else
         return Slerp(from, to, maxDegreesDelta / angle);
 }
예제 #14
0
    //Interpolates between from and to by t and normalizes the result afterwards.
    //This is faster than Slerp but looks worse if the rotations are far apart.
    //Similar to Slerp but normalizes at the end. Probably why for the terrible looks
    public static DQuaternion Lerp(DQuaternion start, DQuaternion end, float amount)
    {
        float inverse = 1.0f - amount;
        DQuaternion result = Zero;

        if (Dot(start, end) >= 0.0f)
            {
                result.x = (inverse * start.x) + (amount * end.x);
                result.y = (inverse * start.y) + (amount * end.y);
                result.z = (inverse * start.z) + (amount * end.z);
                result.w = (inverse * start.w) + (amount * end.w);
            }
        else
            {
                result.x = (inverse * start.x) - (amount * end.x);
                result.y = (inverse * start.y) - (amount * end.y);
                result.z = (inverse * start.z) - (amount * end.z);
                result.w = (inverse * start.w) - (amount * end.w);
            }

        result.Normalize();
        return result;
    }
예제 #15
0
파일: ELSovler.cs 프로젝트: MrHuggs/Poinsot
 double EnergyFromOrientation(DQuaternion o)
 {
     return(EnergyFromOrientation(o, AngularMomentum, Inertia));
 }
예제 #16
0
		void SetState(SurfaceCameraState state)
		{
			CameraPosition = FreeSurfacePosition = state.FreeSurfacePosition;
			CameraDistance = CameraPosition.Length();

			FreeSurfaceYaw		= state.FreeSurfaceYaw;
			FreeSurfacePitch	= state.FreeSurfacePitch;
			freeSurfaceRotation = state.FreeRotation;

			var newLonLat = GetCameraLonLat();
			Yaw		= newLonLat.X;
			Pitch	= -newLonLat.Y;
		}
예제 #17
0
		public void Update(GameTime gameTime)
		{
			UpdateProjectionMatrix();

			CameraPosition	= DVector3.Transform(new DVector3(0, 0, CameraDistance), Rotation);
			ViewMatrix		= DMatrix.LookAtRH(CameraPosition, DVector3.Zero, DVector3.UnitY);

			ViewMatrixWithTranslation		= ViewMatrix;
			ViewMatrix.TranslationVector	= DVector3.Zero;
			FinalCamPosition				= CameraPosition;


			if (CameraState == CameraStates.ViewToPoint) {
				var mat = CalculateBasisOnSurface();

				DVector3	lookAtPoint = mat.Up * EarthRadius;
				double		length		= CameraDistance - EarthRadius;

				var quat	= DQuaternion.RotationAxis(DVector3.UnitY, ViewToPointYaw) * DQuaternion.RotationAxis(DVector3.UnitX, ViewToPointPitch);
				var qRot	= DMatrix.RotationQuaternion(quat);
				var matrix	= qRot * mat;

				var pointOffset = DVector3.Transform(new DVector3(0, 0, length), matrix);
				var camPoint	= new DVector3(pointOffset.X, pointOffset.Y, pointOffset.Z) + lookAtPoint;

				FinalCamPosition = camPoint;

				ViewMatrix					= DMatrix.LookAtRH(camPoint, lookAtPoint, mat.Up);
				ViewMatrixWithTranslation	= ViewMatrix;

				ViewMatrix.TranslationVector = DVector3.Zero;
			} else if (CameraState == CameraStates.FreeSurface) {
				var mat = CalculateBasisOnSurface();
				
				#region Input
					// Update surface camera yaw and pitch
					//if (input.IsKeyDown(Keys.RightButton)) {
					//	FreeSurfaceYaw		+= input.RelativeMouseOffset.X*0.0003;
					//	FreeSurfacePitch	-= input.RelativeMouseOffset.Y*0.0003;
					//
					//	input.IsMouseCentered	= false;
					//	input.IsMouseHidden		= true;
					//}
					//else {
					//	input.IsMouseCentered	= false;
					//	input.IsMouseHidden		= false;
					//}


					//if (Game.Keyboard.IsKeyDown(Input.Keys.Left))		FreeSurfaceYaw		-= gameTime.ElapsedSec * 0.7;
					//if (Game.Keyboard.IsKeyDown(Input.Keys.Right))	FreeSurfaceYaw		+= gameTime.ElapsedSec * 0.7;
					//if (Game.Keyboard.IsKeyDown(Input.Keys.Up))		FreeSurfacePitch	-= gameTime.ElapsedSec * 0.7;
					//if (Game.Keyboard.IsKeyDown(Input.Keys.Down))		FreeSurfacePitch	+= gameTime.ElapsedSec * 0.7;


					//FreeSurfaceYaw = DMathUtil.Clamp(FreeSurfaceYaw, -DMathUtil.PiOverTwo, DMathUtil.PiOverTwo);
					if (FreeSurfaceYaw > DMathUtil.TwoPi)	FreeSurfaceYaw -= DMathUtil.TwoPi;
					if (FreeSurfaceYaw < -DMathUtil.TwoPi)	FreeSurfaceYaw += DMathUtil.TwoPi;

					// Calculate free cam rotation matrix

					if (!freezeFreeCamRotation)
						freeSurfaceRotation = DQuaternion.RotationAxis(DVector3.UnitY, FreeSurfaceYaw) * DQuaternion.RotationAxis(DVector3.UnitX, FreeSurfacePitch);

					var quat	= freeSurfaceRotation;
					var qRot	= DMatrix.RotationQuaternion(quat);
					var matrix	= qRot * mat;

					var velDir = matrix.Forward * velocityDirection.X + mat.Up * velocityDirection.Y + matrix.Right * velocityDirection.Z;

					if (velDir.Length() != 0) {
						velDir.Normalize();
					}
				
				#endregion

				double fac = ((CameraDistance - EarthRadius) - Parameters.MinDistVelocityThreshold) / (Parameters.MaxDistVelocityThreshold - Parameters.MinDistVelocityThreshold);
				fac = DMathUtil.Clamp(fac, 0.0, 1.0);

				FreeSurfaceVelocityMagnitude = DMathUtil.Lerp(Parameters.MinVelocityFreeSurfCam, Parameters.MaxVelocityFreeSurfCam, fac);

				// Update camera position
				FinalCamPosition	= FreeSurfacePosition = FreeSurfacePosition + velDir * FreeSurfaceVelocityMagnitude * gameTime.ElapsedSec;
				CameraPosition		= FinalCamPosition;


				velocityDirection = DVector3.Zero;


				//Calculate view matrix
				ViewMatrix = DMatrix.LookAtRH(FinalCamPosition, FinalCamPosition + matrix.Forward, matrix.Up);
				ViewMatrixWithTranslation		= ViewMatrix;
				ViewMatrix.TranslationVector	= DVector3.Zero;

				// Calculate new yaw and pitch
				CameraDistance = CameraPosition.Length();

				var newLonLat = GetCameraLonLat();
				Yaw		= newLonLat.X;
				Pitch	= -newLonLat.Y;
			}

			ViewMatrixFloat = DMatrix.ToFloatMatrix(ViewMatrix);
			ProjMatrixFloat = DMatrix.ToFloatMatrix(ProjMatrix);

			//var viewDir = CameraPosition / CameraPosition.Length();
		}
예제 #18
0
 // Update is called once per frame
 void Update()
 {
     transform.rotation = DQuaternion.ToUnity(Orientation);
 }
예제 #19
0
		public void PlayAnimation(GameTime gameTime)
		{
			if(cameraAnimTrackStates == null) return;

			freezeFreeCamRotation = true;

			var state = cameraAnimTrackStates[curStateInd];


			curTime += 0.016f; //gameTime.ElapsedSec;
			
			if (curTime < state.WaitTime || curStateInd >= cameraAnimTrackStates.Count - 1) {
				SetState(state);

				if (curStateInd >= cameraAnimTrackStates.Count - 1)
					StopAnimation();

				return;
			}

			float time		= curTime - state.WaitTime;
			float amount	= time/state.TransitionTime;

			float	factor = MathUtil.SmoothStep(amount);
					factor = MathUtil.Clamp(factor, 0.0f, 1.0f);

			var nextState = cameraAnimTrackStates[curStateInd+1];

			var curPos		= DVector3.Lerp(state.FreeSurfacePosition, nextState.FreeSurfacePosition, factor);
			var curFreeRot	= DQuaternion.Slerp(state.FreeRotation, nextState.FreeRotation, factor);

			freeSurfaceRotation = curFreeRot;

			CameraPosition = FreeSurfacePosition = curPos;

			var newLonLat = GetCameraLonLat();
			Yaw		= newLonLat.X;
			Pitch	= -newLonLat.Y;
			
			if (curTime > state.WaitTime + state.TransitionTime) {
				curStateInd++;
				curTime = 0;
			}
		}
예제 #20
0
 public static DQuaternion QuaternionFromTwoDirs(DVector3 UnitFrom, DVector3 UnitTo)
 {
     UnitFrom.Normalize();
     UnitTo.Normalize();
     DQuaternion quat;
     double CosA = DVector3.Dot(UnitFrom, UnitTo);
     if (CosA < -0.999999d)
     {  // angle close to PI    ( can replaced by Bisect.lensquared() < 0.000001f ) ;
         DVector3 CrossVec = new DVector3(0d, UnitFrom.X, -UnitFrom.Y); // cross with (1, 0, 0)
         if ((UnitFrom.Z * UnitFrom.Z) > (UnitFrom.Y * UnitFrom.Y))
         {
             // if (0, 1, 0) Cross > (1, 0, 0) Cross
             CrossVec = new DVector3(-UnitFrom.Z, 0, UnitFrom.X); // cross with (0 ,1, 0)
         }
         CrossVec.Normalize();
         quat = new DQuaternion(CrossVec.X, CrossVec.Y, CrossVec.Z, 0.0d);
     }
     else
     {
         DVector3 Bisect = DVector3.Add(UnitFrom, UnitTo);
         Bisect.Normalize();
         DVector3 BCross = DVector3.Cross(UnitFrom, Bisect);
         quat = new DQuaternion(BCross.X, BCross.Y, BCross.Z, DVector3.Dot(UnitFrom, Bisect));
     }
     return quat;
 }
예제 #21
0
		void GetEulerAngles(DQuaternion q, out double yaw, out double pitch, out double roll)
		{
		    double w2 = q.W*q.W;
		    double x2 = q.X*q.X;
		    double y2 = q.Y*q.Y;
		    double z2 = q.Z*q.Z;
		    double unitLength = w2 + x2 + y2 + z2;    // Normalised == 1, otherwise correction divisor.
		    double abcd = q.W*q.X + q.Y*q.Z;
		    double eps = 1e-7;    // TODO: pick from your math lib instead of hardcoding.
		    double pi = 3.14159265358979323846;   // TODO: pick from your math lib instead of hardcoding.
		    
			if (abcd > (0.5-eps)*unitLength) {
		        yaw		= 2 * Math.Atan2(q.Y, q.W);
		        pitch	= pi;
		        roll	= 0;
		    }
		    else if (abcd < (-0.5+eps)*unitLength) {
		        yaw		= -2 * Math.Atan2(q.Y, q.W);
		        pitch	= -pi;
		        roll	= 0;
		    }
		    else {
		        double adbc = q.W*q.Z - q.X*q.Y;
		        double acbd = q.W*q.Y - q.X*q.Z;
		        yaw		= Math.Atan2(2*adbc, 1 - 2*(z2+x2));
		        pitch	= Math.Asin(2*abcd/unitLength);
				roll	= Math.Atan2(2 * acbd, 1 - 2 * (y2 + x2));
		    }
		}
예제 #22
0
 //The dot product between two rotations.
 public static float Dot(DQuaternion left, DQuaternion right)
 {
     return (left.x * right.x) + (left.y * right.y) + (left.z * right.z) + (left.w * right.w);
 }