Exemple #1
0
        private void ProcessRotationDrag()
        {
            if (m_activeAxis == EGizmoAxis.None)
            {
                return;
            }

            if (m_activeAxisList.Count <= 0)
            {
                return;
            }

            Matrix viewProj = m_frameViewInfo.ViewMatrix * m_frameViewInfo.ProjectionMatrix;

            SharpDX.Vector2 mouseDelta = new SharpDX.Vector2(Input.GetNativeAxisValue(EInputAxis.MouseX), -Input.GetNativeAxisValue(EInputAxis.MouseY));
            SharpDX.Vector2 screenAxis = (SharpDX.Vector2)Vector3.TransformNormal(m_rotationDragAxis, viewProj);
            screenAxis.Normalize();

            float deltaMove = -SharpDX.Vector2.Dot(mouseDelta, screenAxis) * RotationSpeed;

            m_totalAngleDelta += deltaMove;

            float snappedAngle = m_totalAngleDelta;

            if (AngleSnap > 0.0f)
            {
                snappedAngle = m_totalAngleDelta - m_totalAngleDelta % AngleSnap;
            }

            Quaternion deltaRotation = Quaternion.RotationAxis(m_activeAxisList[0], snappedAngle);

            m_controlledTransform.SetWorldRotation(deltaRotation * m_originalRotation);
        }
        public static Vector3 FromQ2(Quaternion q1)
        {
            float   sqw  = q1.W * q1.W;
            float   sqx  = q1.X * q1.X;
            float   sqy  = q1.Y * q1.Y;
            float   sqz  = q1.Z * q1.Z;
            float   unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
            float   test = q1.X * q1.W - q1.Y * q1.Z;
            Vector3 v;

            if (test > 0.4995f * unit)
            { // singularity at north pole
                v.Y = _normalize_degrees((float)(2f * Math.Atan2(q1.Y, q1.X)) * (float)(180 / Math.PI));
                v.X = _normalize_degrees((float)(Math.PI / 2) * (float)(180 / Math.PI));
                v.Z = 0;
                return(v);// * (float)(180 / Math.PI);
            }
            if (test < -0.4995f * unit)
            { // singularity at south pole
                v.Y = _normalize_degrees((float)(-2f * Math.Atan2(q1.Y, q1.X)) * (float)(180 / Math.PI));
                v.X = _normalize_degrees((float)(-Math.PI / 2) * (float)(180 / Math.PI));
                v.Z = 0;
                return(v);
            }
            Quaternion q = new Quaternion(q1.W, q1.Z, q1.X, q1.Y);

            v.Y = _normalize_degrees((float)Math.Atan2(2f * q.X * q.W + 2f * q.Y * q.Z, 1 - 2f * (q.Z * q.Z + q.W * q.W)) * (float)(180 / Math.PI)); // Yaw
            v.X = _normalize_degrees((float)Math.Asin(2f * (q.X * q.Z - q.W * q.Y)) * (float)(180 / Math.PI));                                       // Pitch
            v.Z = _normalize_degrees((float)Math.Atan2(2f * q.X * q.Y + 2f * q.Z * q.W, 1 - 2f * (q.Y * q.Y + q.Z * q.Z)) * (float)(180 / Math.PI)); // Roll
            return(v);
            //return _normalize_degrees(v) * (float)(180 / Math.PI);
        }
        /// <summary>
        /// Sweeps a sphere against the physics world reporting the closest hit to the start location, beware convex sweeps can be very costly especially if they are long
        /// </summary>
        /// <param name="radius">Radius of the sphere</param>
        /// <param name="startPos">Location to start the sweep from</param>
        /// <param name="sweep">Direction in which to sweep, the length of the vector is the length of the sweep</param>
        /// <param name="group">Collision group to filter the sweep hits, anything above "Normal" is ignored</param>
        /// <param name="outSweepResult">Closest hit to the start location</param>
        /// <returns>True if any object was hit</returns>
        public bool SphereSweep(float radius, ref SharpDX.Vector3 startPos, ref SharpDX.Vector3 sweep, CollisionGroup group, ref SRaycastResult outSweepResult)
        {
            SphereShape sphereShape = new SphereShape(radius);
            Quaternion  rotation    = Quaternion.Identity;

            return(ConvexSweep(sphereShape, ref startPos, ref rotation, ref sweep, group, ref outSweepResult));
        }
        //https://csharp.hotexamples.com/examples/SharpDX/Matrix/-/php-matrix-class-examples.html
        public static Matrix rotationMatrix(Quaternion q)
        {
            SharpDX.Matrix matrix = new SharpDX.Matrix();
            // This is the arithmetical formula optimized to work with unit quaternions.
            // |1-2y²-2z²        2xy-2zw         2xz+2yw       0|
            // | 2xy+2zw        1-2x²-2z²        2yz-2xw       0|
            // | 2xz-2yw         2yz+2xw        1-2x²-2y²      0|
            // |    0               0               0          1|

            // And this is the code.
            // First Column
            matrix[0] = 1 - 2 * (q.Y * q.Y + q.Z * q.Z);
            matrix[1] = 2 * (q.X * q.Y + q.Z * q.W);
            matrix[2] = 2 * (q.X * q.Z - q.Y * q.W);
            matrix[3] = 0;

            // Second Column
            matrix[4] = 2 * (q.X * q.Y - q.Z * q.W);
            matrix[5] = 1 - 2 * (q.X * q.X + q.Z * q.Z);
            matrix[6] = 2 * (q.Y * q.Z + q.X * q.W);
            matrix[7] = 0;

            // Third Column
            matrix[8]  = 2 * (q.X * q.Z + q.Y * q.W);
            matrix[9]  = 2 * (q.Y * q.Z - q.X * q.W);
            matrix[10] = 1 - 2 * (q.X * q.X + q.Y * q.Y);
            matrix[11] = 0;

            // Fourth Column
            matrix[12] = 0;
            matrix[13] = 0;
            matrix[14] = 0;
            matrix[15] = 1;
            return(matrix);
        }
        /// <summary>
        /// Sweeps a sphere against the physics world reporting all hits on the path even if they ignore collisions, beware convex sweeps can be very costly especially if they are long
        /// </summary>
        /// <param name="radius">Radius of the sphere</param>
        /// <param name="startPos">Location to start the sweep from</param>
        /// <param name="sweep">Direction in which to sweep, the length of the vector is the length of the sweep</param>
        /// <param name="outSweepResults">All overlaps on the sweep path</param>
        /// <returns>True if any object was hit</returns>
        public bool SphereMultiSweep(float radius, ref SharpDX.Vector3 startPos, ref SharpDX.Vector3 sweep, List <SRaycastResult> outSweepResults)
        {
            SphereShape sphereShape = new SphereShape(radius);
            Quaternion  rotation    = Quaternion.Identity;

            return(MultiSweep(sphereShape, ref startPos, ref rotation, ref sweep, outSweepResults));
        }
Exemple #6
0
        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
#if DEBUG
            if (renderTimer.IsRunning)
            {
                renderTimer.Stop();
                Debug.WriteLine(string.Format("RENDER: {0} ellapsed for setting properties and rendering.", renderTimer.Elapsed));
                renderTimer.Reset();
            }
#endif
            if (directionalLight == null)
            {
                return;
            }

            var cf    = new Vector3((float)camera.LookDirection.X, (float)camera.LookDirection.Y, (float)camera.LookDirection.Z).Normalized();
            var cu    = new Vector3((float)camera.UpDirection.X, (float)camera.UpDirection.Y, (float)camera.UpDirection.Z).Normalized();
            var right = Vector3.Cross(cf, cu);

            var qel = Quaternion.RotationAxis(right, (float)((-LightElevationDegrees * Math.PI) / 180));
            var qaz = Quaternion.RotationAxis(cu, (float)((LightAzimuthDegrees * Math.PI) / 180));
            var v   = Vector3.Transform(cf, qaz * qel);
            directionalLightDirection = v;

            if (!directionalLight.Direction.Equals(directionalLightDirection))
            {
                directionalLight.Direction = v;
            }

            UpdateNearClipPlaneForSceneBounds();
        }
        public static Matrix RotationQuaternion(Quaternion rotation)
        {
            Matrix result;
            float  xx = rotation.X * rotation.X;
            float  yy = rotation.Y * rotation.Y;
            float  zz = rotation.Z * rotation.Z;
            float  xy = rotation.X * rotation.Y;
            float  zw = rotation.Z * rotation.W;
            float  zx = rotation.Z * rotation.X;
            float  yw = rotation.Y * rotation.W;
            float  yz = rotation.Y * rotation.Z;
            float  xw = rotation.X * rotation.W;

            result     = Matrix.Identity;
            result.M11 = 1.0f - (2.0f * (yy + zz));
            result.M12 = 2.0f * (xy + zw);
            result.M13 = 2.0f * (zx - yw);
            result.M21 = 2.0f * (xy - zw);
            result.M22 = 1.0f - (2.0f * (zz + xx));
            result.M23 = 2.0f * (yz + xw);
            result.M31 = 2.0f * (zx + yw);
            result.M32 = 2.0f * (yz - xw);
            result.M33 = 1.0f - (2.0f * (yy + xx));
            return(result);
        }
        public static Vector3 _newgetdirup(SharpDX.Quaternion rotation)
        {
            Vector3 dirup;

            //up vector
            dirup.X = 2 * (rotation.X * rotation.Y - rotation.W * rotation.Z);
            dirup.Y = 1 - 2 * (rotation.X * rotation.X + rotation.Z * rotation.Z);
            dirup.Z = 2 * (rotation.Y * rotation.Z + rotation.W * rotation.X);
            return(dirup);
        }
        public static Vector3 _newgetdirforward(SharpDX.Quaternion rotation)
        {
            Vector3 dirforward;

            //forward vector
            dirforward.X = 2 * (rotation.X * rotation.Z + rotation.W * rotation.Y);
            dirforward.Y = 2 * (rotation.Y * rotation.Z - rotation.W * rotation.X);
            dirforward.Z = 1 - 2 * (rotation.X * rotation.X + rotation.Y * rotation.Y);
            return(dirforward);
        }
        public static Vector3 _newgetdirleft(SharpDX.Quaternion rotation)
        {
            Vector3 dirleft;

            //left vector
            dirleft.X = 1 - 2 * (rotation.Y * rotation.Y + rotation.Z * rotation.Z);
            dirleft.Y = 2 * (rotation.X * rotation.Y + rotation.W * rotation.Z);
            dirleft.Z = 2 * (rotation.X * rotation.Z - rotation.W * rotation.Y);
            return(dirleft);
        }
        //https://www.gamedev.net/forums/topic/56471-extracting-direction-vectors-from-quaternion/
        public static void _newgetDirectiontotal(SharpDX.Quaternion rotation, out Vector3 forward, out Vector3 left, out Vector3 up)
        {
            //forward vector
            forward.X = 2 * (rotation.X * rotation.Z + rotation.W * rotation.Y);
            forward.Y = 2 * (rotation.Y * rotation.Z - rotation.W * rotation.X);
            forward.Z = 1 - 2 * (rotation.X * rotation.X + rotation.Y * rotation.Y);

            //up vector
            up.X = 2 * (rotation.X * rotation.Y - rotation.W * rotation.Z);
            up.Y = 1 - 2 * (rotation.X * rotation.X + rotation.Z * rotation.Z);
            up.Z = 2 * (rotation.Y * rotation.Z + rotation.W * rotation.X);

            //left vector
            left.X = 1 - 2 * (rotation.Y * rotation.Y + rotation.Z * rotation.Z);
            left.Y = 2 * (rotation.X * rotation.Y + rotation.W * rotation.Z);
            left.Z = 2 * (rotation.X * rotation.Z - rotation.W * rotation.Y);
        }
Exemple #12
0
        private Matrix MatrixConversionFromAssimp(Matrix4x4 assimpMatrix4x4)
        {
            Vector3D translation;
            Vector3D scaling;

            Assimp.Quaternion rotation;
            assimpMatrix4x4.Decompose(out scaling, out rotation, out translation);

            Vector3 transformedTranslation = new Vector3(translation.X, translation.Y, translation.Z);
            Vector3 transformedScaling     = new Vector3(scaling.X, scaling.Y, scaling.Z);

            SharpDX.Quaternion transformedRotation = new SharpDX.Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W);

            Matrix convertedMatrix = Matrix.Multiply(Matrix.Multiply(Matrix.Scaling(transformedScaling), Matrix.RotationQuaternion(transformedRotation)), Matrix.Translation(transformedTranslation));

            return(convertedMatrix);
        }
        private MeshGeometry3D CreateTube(Vector pos, out Vector3 endPoint, bool slim = false)
        {
            var m = pos.Length;

            if (double.IsNaN(m))
            {
                endPoint = default;
                return(new MeshGeometry3D());
            }

            float tubeLength = 100;
            float tubeRadius = 6;

            if (slim)
            {
                tubeRadius *= 0.98f;
            }

            float cableToCenter = 8;
            float wheelRadius   = 20;
            float cableDist     = (float)(m * Math.PI / 180 * wheelRadius);
            float curvature     = cableDist / (tubeLength * cableToCenter);

            var     r         = Quaternion.RotationAxis(Vector3.BackwardRH, (float)Math.Atan2(pos.Y, pos.X));
            var     points    = new List <Vector3>();
            int     divisions = 100;
            Vector3 p;

            points.Add(p = Vector3.Zero);
            for (int i = 1; i <= divisions; i++)
            {
                float a = curvature * tubeLength * i / divisions;
                var   t = new Vector3((float)Math.Sin(a), 0, (float)Math.Cos(a));
                p += t * tubeLength / divisions;
                points.Add(Vector3.Transform(p, r));
            }

            var mb = new MeshBuilder();

            mb.AddTube(points, tubeRadius * 2, 36, false, true, true);

            endPoint = points.Last();
            return(mb.ToMesh());
        }
        //https://stackoverflow.com/questions/12088610/conversion-between-euler-quaternion-like-in-unity3d-engine
        public static Vector3 QuaternionToEuler(Quaternion q)
        {
            Vector3 euler;

            // if the input quaternion is normalized, this is exactly one. Otherwise, this acts as a correction factor for the quaternion's not-normalizedness
            float unit = (q.X * q.X) + (q.Y * q.Y) + (q.Z * q.Z) + (q.W * q.W);

            // this will have a magnitude of 0.5 or greater if and only if this is a singularity case
            float test = q.X * q.W - q.Y * q.Z;

            if (test > 0.4995f * unit) // singularity at north pole
            {
                euler.X = (float)Math.PI / 2;
                euler.Y = (float)(2f * Math.Atan2(q.Y, q.X));
                euler.Z = 0;
            }
            else if (test < -0.4995f * unit) // singularity at south pole
            {
                euler.X = (float)-Math.PI / 2;
                euler.Y = (float)(-2f * Math.Atan2(q.Y, q.X));
                euler.Z = 0;
            }
            else // no singularity - this is the majority of cases
            {
                euler.X = (float)Math.Asin(2f * (q.W * q.X - q.Y * q.Z));
                euler.Y = (float)Math.Atan2(2f * q.W * q.Y + 2f * q.Z * q.X, 1 - 2f * (q.X * q.X + q.Y * q.Y));
                euler.Z = (float)Math.Atan2(2f * q.W * q.Z + 2f * q.X * q.Y, 1 - 2f * (q.Z * q.Z + q.X * q.X));
            }

            // all the math so far has been done in radians. Before returning, we convert to degrees...
            euler *= (float)(180 / Math.PI);

            //...and then ensure the degree values are between 0 and 360
            //euler.X %= 360;
            //euler.Y %= 360;
            //euler.Z %= 360;
            euler.X = RadianToDegree(_normalize_degrees(euler.X));
            euler.Y = RadianToDegree(_normalize_degrees(euler.Y));
            euler.Z = RadianToDegree(_normalize_degrees(euler.Z));

            return(euler);
        }
        /*
         * public float sc_check_distance_sebastian_lague_node_3d()
         * {
         *  if (dstX > dstZ)
         *  {
         *      if (dstX > dstY)
         *      {
         *          return 14 * dstY + 14 * dstZ + 10 * (dstX - dstZ) + 10 * (dstX - dstY);
         *      }
         *      else
         *      {
         *          return 14 * dstX + 14 * dstZ + 10 * (dstX - dstZ) + 10 * (dstY - dstX);
         *      }
         *  }
         *
         *  //calculating x
         *  if (dstX > dstY && dstX > dstZ)
         *  {
         *      var part_00 = 14 * dstY + 10 * (dstX - dstY);
         *      var part_01 = 14 * dstZ + 10 * (dstX - dstZ);
         *      return part_00 + part_01;
         *  }
         *  else if (dstX > dstY && dstX < dstZ)
         *  {
         *      var part_00 = 14 * dstY + 10 * (dstX - dstY);
         *      var part_01 = 14 * dstX + 10 * (dstZ - dstX);
         *      return part_00 + part_01;
         *  }
         *  else if (dstX < dstY && dstX < dstZ)
         *  {
         *      var part_00 = 14 * dstX + 10 * (dstY - dstX);
         *      var part_01 = 14 * dstX + 10 * (dstZ - dstX);
         *      return part_00 + part_01;
         *  }
         *  else if (dstX < dstY && dstX > dstZ)
         *  {
         *      var part_00 = 14 * dstX + 10 * (dstY - dstX);
         *      var part_01 = 14 * dstZ + 10 * (dstX - dstZ);
         *      return part_00 + part_01;
         *  }
         *  //calculating y
         *  else if (dstY > dstX && dstY > dstZ)
         *  {
         *      var part_00 = 14 * dstX + 10 * (dstY - dstX);
         *      var part_01 = 14 * dstZ + 10 * (dstY - dstZ);
         *      return part_00 + part_01;
         *  }
         *  else if (dstY > dstX && dstY < dstZ)
         *  {
         *      var part_00 = 14 * dstX + 10 * (dstY - dstX);
         *      var part_01 = 14 * dstY + 10 * (dstZ - dstY);
         *      return part_00 + part_01;
         *  }
         *  else if (dstY < dstX && dstY < dstZ)
         *  {
         *      var part_00 = 14 * dstY + 10 * (dstX - dstY);
         *      var part_01 = 14 * dstY + 10 * (dstZ - dstY);
         *      return part_00 + part_01;
         *  }
         *  else if (dstY < dstX && dstY > dstZ)
         *  {
         *      var part_00 = 14 * dstY + 10 * (dstX - dstY);
         *      var part_01 = 14 * dstZ + 10 * (dstY - dstZ);
         *      return part_00 + part_01;
         *  }
         *
         *  //calculating z
         *  else if (dstZ > dstX && dstZ > dstY)
         *  {
         *      var part_00 = 14 * dstX + 10 * (dstZ - dstX);
         *      var part_01 = 14 * dstY + 10 * (dstZ - dstY);
         *      return part_00 + part_01;
         *  }
         *  else if (dstZ > dstX && dstZ < dstY)
         *  {
         *      var part_00 = 14 * dstX + 10 * (dstZ - dstX);
         *      var part_01 = 14 * dstZ + 10 * (dstY - dstZ);
         *      return part_00 + part_01;
         *  }
         *  else if (dstZ < dstX && dstZ < dstY)
         *  {
         *      var part_00 = 14 * dstZ + 10 * (dstX - dstZ);
         *      var part_01 = 14 * dstZ + 10 * (dstY - dstZ);
         *      return part_00 + part_01;
         *  }
         *  else if (dstZ < dstX && dstZ > dstY)
         *  {
         *      var part_00 = 14 * dstZ + 10 * (dstX - dstZ);
         *      var part_01 = 14 * dstY + 10 * (dstZ - dstY);
         *      return part_00 + part_01;
         *  }*/
        //calculating diagonals ? not sure that covers them all. and it doesnt work

        /*else
         * {
         *  var part_00 = 10 * dstX; //14
         *  var part_01 = 10 * dstY; //14
         *  var part_02 = 10 * dstZ; //14
         *  return 10; //part_00 + part_01 + part_02
         * }
         * }*/


        //https://pastebin.com/fAFp6NnN // Also found on the unity3D forums.
        public static Vector3 _getDirection(Vector3 value, SharpDX.Quaternion rotation)
        {
            Vector3 vector;
            double  num12 = rotation.X + rotation.X;
            double  num2  = rotation.Y + rotation.Y;
            double  num   = rotation.Z + rotation.Z;
            double  num11 = rotation.W * num12;
            double  num10 = rotation.W * num2;
            double  num9  = rotation.W * num;
            double  num8  = rotation.X * num12;
            double  num7  = rotation.X * num2;
            double  num6  = rotation.X * num;
            double  num5  = rotation.Y * num2;
            double  num4  = rotation.Y * num;
            double  num3  = rotation.Z * num;
            double  num15 = ((value.X * ((1f - num5) - num3)) + (value.Y * (num7 - num9))) + (value.Z * (num6 + num10));
            double  num14 = ((value.X * (num7 + num9)) + (value.Y * ((1f - num8) - num3))) + (value.Z * (num4 - num11));
            double  num13 = ((value.X * (num6 - num10)) + (value.Y * (num4 + num11))) + (value.Z * ((1f - num8) - num5));

            vector.X = (float)num15;
            vector.Y = (float)num14;
            vector.Z = (float)num13;
            return(vector);
        }
 public void Rotate(Quaternion quaternion)
 {
     var center = new Vector3d();
     this *= CreateRotationMatrix(ref quaternion, ref center);
 }
Exemple #17
0
        public void Init(CInitializer initializer)
        {
            UpdateScheduler = new CUpdateScheduler();

            CreateLevel();
            GameConsole.Init();
            PhysicsWorld.Init(this);


            #region Sponza
            CModelAsset sponzaAsset = CImportManager.Instance.MeshImporter.LoadModelAsync("TestResources/SponzaAtrium/sponza.obj");
            m_sponzaEntity = SpawnEntity <CEntity>();
            CModelComponent modelComponent = m_sponzaEntity.AddComponent <CModelComponent>(true, true);
            m_sponzaEntity.SetWorldPosition(new Vector3(0, -5, -5));
            m_sponzaEntity.SetWorldRotation(Quaternion.RotationAxis(Axis.Up, MathUtil.DegreesToRadians(90)));
            m_sponzaEntity.SetWorldScale(new Vector3(0.03f));
            CStaticModelColliderComponent staticModelCollider = m_sponzaEntity.AddComponent <CStaticModelColliderComponent>(true, true);
            staticModelCollider.ModelAsset  = sponzaAsset;
            modelComponent.Model            = sponzaAsset;
            m_sponzaEntity.IsPhysicsStatic  = true;
            m_sponzaEntity.IsPhysicsEnabled = true;
            #endregion

            CMeshAsset cubeAsset = CImportManager.Instance.MeshImporter.LoadMeshAsync("EngineResources/DefaultMeshes/DefaultCube.obj");

            CEntity floorEntity = SpawnEntity <CEntity>();
            floorEntity.AddComponent <CSceneComponent>(true, true);
            CMeshComponent floorMesh = floorEntity.AddComponent <CMeshComponent>(true, true);
            floorMesh.Mesh       = cubeAsset;
            floorMesh.LocalScale = new Vector3(500, 1, 500);
            CBoxColliderComponent floorCollider = floorEntity.AddComponent <CBoxColliderComponent>(true, true);
            floorCollider.Height = 1;
            floorCollider.Width  = 500;
            floorCollider.Length = 500;
            floorEntity.SetLocalPosition(new Vector3(0, -15, 0));
            floorEntity.IsPhysicsStatic         = true;
            floorEntity.IsPhysicsEnabled        = true;
            floorEntity.PhysicalStatic.Material = new Material(1, 0.8f, 1f);

            #region LightSetup
            m_lightEntity = SpawnEntity <CEntity>();
            m_lightEntity.AddComponent <CSceneComponent>(true, true);

            CDirectionalLightComponent directionalLight = m_lightEntity.AddComponent <CDirectionalLightComponent>(true, true);
            directionalLight.LocalRotation = MathUtilities.CreateLookAtQuaternion(Vector3.Normalize(new Vector3(0.2f, -0.5f, 0.2f)), Axis.Up);
            directionalLight.LightColor    = Color4.White * 0.8f;

            CSpotLightComponent spotLight = m_lightEntity.AddComponent <CSpotLightComponent>(true, true);
            spotLight.ConstantAttenuation  = 0.01f;
            spotLight.LinearAttenuation    = 0.3f;
            spotLight.QuadraticAttenuation = 0.0f;
            spotLight.Enabled    = true;
            spotLight.SpotAngle  = MathUtil.DegreesToRadians(30.0f);
            spotLight.LightColor = new Color4(0.1f, 0.8f, 0.1f, 1.0f);
            spotLight.Range      = 100.0f;
            Quaternion deltaRotation = Quaternion.RotationAxis(Axis.Right, MathUtil.DegreesToRadians(10));
            spotLight.LocalRotation = deltaRotation;
            spotLight.LocalPosition = new Vector3(0, 1, -4);

            CPointLightComponent pointLight1 = m_lightEntity.AddComponent <CPointLightComponent>(true, true);
            pointLight1.ConstantAttenuation = 1;
            pointLight1.LinearAttenuation   = 0.2f;
            pointLight1.Enabled             = true;
            pointLight1.Range         = 100.0f;
            pointLight1.LightColor    = new Color4(0.8f, 0.1f, 0.1f, 1.0f);
            pointLight1.LocalPosition = new Vector3(0, 0, 3.0f);

            CPointLightComponent pointLight2 = m_lightEntity.AddComponent <CPointLightComponent>(true, true);
            pointLight2.ConstantAttenuation = 1;
            pointLight2.LinearAttenuation   = 0.4f;
            pointLight2.Enabled             = true;
            pointLight2.Range         = 100.0f;
            pointLight2.LightColor    = new Color4(0.1f, 0.1f, 0.8f, 1.0f);
            pointLight2.LocalPosition = new Vector3(0, -3, -8.0f);

            CAmbientLightComponent ambientLight = m_lightEntity.AddComponent <CAmbientLightComponent>(true, true);
            ambientLight.LightColor = Color4.White * 0.15f;
            #endregion
        }
Exemple #18
0
 public TransformData(Vector3 translation, Quaternion rotation, Vector3 scaling)
 {
     Translation = new Vector3DParameter(translation);
     Rotation    = new QuaternionParameter(rotation);
     Scaling     = new Vector3DParameter(scaling);
 }
 public void RotateAtPrepend(Quaternion quaternion, Vector3d center)
 {
     this = CreateRotationMatrix(ref quaternion, ref center) * this;
 }
Exemple #20
0
        override protected void Render()
        {
            Lock = true;

            int           mainRetry = 5;
            ClientContext context;

            do
            {
                context = new ClientContext("com.bivrost360.desktopplayer");
                Thread.Sleep(50);
            }while (context == null && mainRetry-- > 0);

            DisplayConfig displayConfig = null;

            for (int retry = 0; retry < 12; retry++)
            {
                if (abort)
                {
                    context.Dispose();
                    Lock = false;
                    return;
                }

                displayConfig = context.GetDisplayConfig();

                if (displayConfig != null)
                {
                    int contextRetry = 0;
                    do
                    {
                        context.update();
                        contextRetry++;
                        if (abort)
                        {
                            context.Dispose();
                            Lock = false;
                            return;
                        }
                        Thread.Sleep(1);
                    } while (!displayConfig.CheckDisplayStartup() || contextRetry < 300);
                    if (displayConfig.CheckDisplayStartup())
                    {
                        break;
                    }
                }
            }
            if (displayConfig == null)
            {
                context.Dispose();
                Lock = false;
                return;
            }

            var numDisplayInputs = displayConfig.GetNumDisplayInputs();

            if (numDisplayInputs != 1)
            {
                context.Dispose();
                Lock = false;
                return;
            }

            var displayDimensions = displayConfig.GetDisplayDimensions(0);
            var numViewers        = displayConfig.GetNumViewers();

            if (numViewers != 1)
            {
                context.Dispose();
                Lock = false;
                return;
            }


            var form = new RenderForm("BIVROST - OSVR");

            form.Width         = displayDimensions.Width;
            form.Height        = displayDimensions.Height;
            form.ShowInTaskbar = false;


            var desc = new SwapChainDescription()
            {
                BufferCount     = 1,
                ModeDescription =
                    new ModeDescription(displayDimensions.Width, displayDimensions.Height,
                                        new Rational(60, 1), Format.R8G8B8A8_UNorm),
                IsWindowed        = true,
                OutputHandle      = form.Handle,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect        = SwapEffect.Discard,
                Usage             = Usage.RenderTargetOutput
            };

            SwapChain swapChain;

            // Create DirectX drawing device.
            //SharpDX.Direct3D11.Device device = new Device(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.BgraSupport, new SharpDX.Direct3D.FeatureLevel[] { SharpDX.Direct3D.FeatureLevel.Level_10_0 });
            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.BgraSupport, desc, out _device, out swapChain);

            // Create DirectX Graphics Interface factory, used to create the swap chain.
            Factory factory = swapChain.GetParent <Factory>();

            factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll);
            form.FormBorderStyle = FormBorderStyle.None;
            form.TopMost         = true;

            DeviceContext immediateContext = _device.ImmediateContext;

            using (SharpDX.DXGI.Device2 dxgiDevice = _device.QueryInterface <SharpDX.DXGI.Device2>())
            {
                //var bounds = dxgiDevice.Adapter.Outputs[1].Description.DesktopBounds;
                //form.DesktopBounds = new System.Drawing.Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height);

                //dxgiDevice.Adapter.Outputs.ToList().ForEach(o =>
                //{
                //    if (o.Description.DeviceName.EndsWith("2"))
                //    {
                //        swapChain.SetFullscreenState(true, o);
                //    }
                //});

                Rectangle bounds;

                if (Features.IsDebug)
                {
                    log.Info("OSVR: available screens: " + string.Join("\n", dxgiDevice.Adapter.Outputs.ToList().ConvertAll(o => o.Description.DeviceName + " (" + o.Description.DesktopBounds + ")")));
                }

                if (Logic.Instance.settings.OSVRScreen == ScreenSelection.Autodetect)
                {
                    // start with last screen
                    Output output = dxgiDevice.Adapter.Outputs[dxgiDevice.Adapter.Outputs.Length - 1];

                    // but something resembling a HDK 1.4 (1920x1080) will be better
                    foreach (var o in dxgiDevice.Adapter.Outputs)
                    {
                        var b = o.Description.DesktopBounds;
                        if (b.Width == 1920 && b.Height == 1080)
                        {
                            log.Info("OSVR: found a 1920x1080 candidate for a HDK 1.4");
                            output = o;
                        }
                    }

                    // and something resembling a HDK 2.0 (2160x1200) will be even more better
                    foreach (var o in dxgiDevice.Adapter.Outputs)
                    {
                        var b = o.Description.DesktopBounds;
                        if (b.Width == 2160 && b.Height == 1200)
                        {
                            log.Info("OSVR: found a 2160x1200 candidate for a HDK 2.0");
                            output = o;
                        }
                    }

                    bounds = output.Description.DesktopBounds;
                    log.Info($"OSVR: guessed output ({bounds})");
                }
                else
                {
                    int osvrScreen = (int)Logic.Instance.settings.OSVRScreen;
                    if (osvrScreen >= dxgiDevice.Adapter.Outputs.Length)
                    {
                        osvrScreen = dxgiDevice.Adapter.Outputs.Length - 1;
                    }
                    bounds = dxgiDevice.Adapter.Outputs[osvrScreen].Description.DesktopBounds;
                    log.Info($"OSVR: selected output #{osvrScreen} ({bounds})");
                }

                form.DesktopBounds = new System.Drawing.Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height);

                if (dxgiDevice.Adapter.Outputs.Length <= 1)
                {
                    Logic.Notify("Only one screen is active. Press Control+S to stop the movie if needed.");
                }
            }

            // Create a depth buffer, using the same width and height as the back buffer.
            Texture2DDescription depthBufferDescription = new Texture2DDescription()
            {
                Format            = Format.D32_Float,
                ArraySize         = 1,
                MipLevels         = 1,
                Width             = displayDimensions.Width,
                Height            = displayDimensions.Height,
                SampleDescription = new SampleDescription(1, 0),
                Usage             = ResourceUsage.Default,
                BindFlags         = BindFlags.DepthStencil,
                CpuAccessFlags    = CpuAccessFlags.None,
                OptionFlags       = ResourceOptionFlags.None
            };



            // Retrieve the DXGI device, in order to set the maximum frame latency.
            using (SharpDX.DXGI.Device1 dxgiDevice = _device.QueryInterface <SharpDX.DXGI.Device1>())
                dxgiDevice.MaximumFrameLatency = 1;

            using (_gd = SharpDX.Toolkit.Graphics.GraphicsDevice.New(_device))
                using (customEffectL = GetCustomEffect(_gd))
                    using (customEffectR = GetCustomEffect(_gd))
                        //using (var primitive = GraphicTools.CreateGeometry(_projection, _gd))
                        using (vrui = new VRUI(_device, _gd))
                            using (Texture2D depthBuffer = new Texture2D(_device, depthBufferDescription))
                                using (DepthStencilView depthView = new DepthStencilView(_device, depthBuffer))
                                    using (Texture2D backBuffer = Texture2D.FromSwapChain <Texture2D>(swapChain, 0))
                                        using (RenderTargetView renderView = new RenderTargetView(_device, backBuffer))
                                        {
                                            //primitive = GraphicTools.CreateGeometry(Projection, _gd);

                                            DateTime startTime = DateTime.Now;
                                            Vector3  position  = new Vector3(0, 0, -1);

                                            #region Render loop

                                            DateTime lastTime  = DateTime.Now;
                                            float    deltaTime = 0;


                                            immediateContext.OutputMerger.SetTargets(depthView, renderView);


                                            form.GotFocus += (s, e) => OnGotFocus();
                                            bool first = true;

                                            RenderLoop.Run(form, () =>
                                            {
                                                if (abort)
                                                {
                                                    form.Close();
                                                    return;
                                                }

                                                if (first)
                                                {
                                                    // Start with default background
                                                    SetDefaultScene();

                                                    OnGotFocus();
                                                    first = false;
                                                }

                                                UpdateContentIfRequested();

                                                context.update();

                                                float timeSinceStart = (float)(DateTime.Now - startTime).TotalSeconds;
                                                deltaTime            = (float)(DateTime.Now - lastTime).TotalSeconds;
                                                lastTime             = DateTime.Now;

                                                immediateContext.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
                                                immediateContext.ClearRenderTargetView(renderView, Color.Black);

                                                uint viewer = 0;

                                                for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++)
                                                {
                                                    var numEyes    = displayConfig.GetNumEyesForViewer(viewer);
                                                    var viewerPose = displayConfig.GetViewerPose(viewer);



                                                    for (byte eye = 0; eye < numEyes; eye++)
                                                    {
                                                        uint numSurfaces           = displayConfig.GetNumSurfacesForViewerEye(viewer, eye);
                                                        Pose3 viewerEyePose        = displayConfig.GetViewerEyePose(viewer, eye);
                                                        Matrix44f viewerEyeMatrixf = displayConfig.GetViewerEyeViewMatrixf(viewer, eye, MatrixConventionsFlags.Default);
                                                        uint surface = 0;
                                                        OSVR.ClientKit.Viewport viewport = displayConfig.GetRelativeViewportForViewerEyeSurface(viewer, eye, surface);
                                                        Matrix44f projectionf            = displayConfig.GetProjectionMatrixForViewerEyeSurfacef(viewer, eye, surface, 0.001f, 1000.0f, MatrixConventionsFlags.Default);
                                                        ProjectionClippingPlanes projectionClippingPlanes = displayConfig.GetViewerEyeSurfaceProjectionClippingPlanes(viewer, eye, surface);

                                                        ViewportF vp = new ViewportF(viewport.Left, viewport.Bottom, viewport.Width, viewport.Height);
                                                        immediateContext.Rasterizer.SetViewport(vp);

                                                        Vector3 lookPosition = viewerEyePose.translation.ToVector3();

                                                        SharpDX.Quaternion lookRotation = viewerEyePose.rotation.ToQuaternion();
                                                        Matrix rotationMatrix           = Matrix.RotationQuaternion(lookRotation);
                                                        Vector3 lookUp    = Vector3.Transform(new Vector3(0, 1, 0), rotationMatrix).ToVector3();
                                                        Vector3 lookAt    = Vector3.Transform(new Vector3(0, 0, -1), rotationMatrix).ToVector3();
                                                        Matrix viewMatrix = Matrix.LookAtRH(lookPosition, lookPosition + lookAt, lookUp);

                                                        Matrix projectionMatrix = projectionf.ToMatrix();

                                                        Matrix worldMatrix = Matrix.Translation(lookPosition);

                                                        Matrix MVP = worldMatrix * viewMatrix * projectionMatrix;
                                                        customEffectL.Parameters["WorldViewProj"].SetValue(MVP);
                                                        customEffectR.Parameters["WorldViewProj"].SetValue(MVP);

                                                        lock (localCritical)
                                                        {
                                                            if (eye == 0)
                                                            {
                                                                primitive?.Draw(customEffectL);
                                                            }
                                                            if (eye == 1)
                                                            {
                                                                primitive?.Draw(customEffectR);
                                                            }
                                                        }

                                                        // reset UI position every frame if it is not visible
                                                        if (vrui.isUIHidden)
                                                        {
                                                            vrui.SetWorldPosition(viewMatrix.Forward, lookPosition, true);
                                                        }

                                                        if (eye == 0)
                                                        {
                                                            lookRotation.Invert();
                                                            ProvideLook?.Invoke(lookPosition, lookRotation, OSVRFOV);
                                                        }

                                                        vrui.Draw(Media, currentTime, Duration);
                                                        vrui.Render(deltaTime, viewMatrix, projectionMatrix, lookPosition, ShouldShowVRUI);
                                                    }
                                                }

                                                swapChain.Present(0, PresentFlags.None);
                                            });

                                            #endregion
                                            //debugWindow.Stop();

                                            waitForRendererStop.Set();

                                            //swapChain.SetFullscreenState(false, null);



                                            immediateContext.ClearState();
                                            immediateContext.Flush();
                                            immediateContext.Dispose();

                                            swapChain.Dispose();

                                            factory.Dispose();

                                            //swapChain.Dispose();

                                            // Disposing the device, before the hmd, will cause the hmd to fail when disposing.
                                            // Disposing the device, after the hmd, will cause the dispose of the device to fail.
                                            // It looks as if the hmd steals ownership of the device and destroys it, when it's shutting down.
                                            // device.Dispose();
                                            base._device.Dispose();

                                            //hmd.Dispose();
                                            //oculus.Dispose();

                                            displayConfig.Dispose();
                                            context.Dispose();
                                        }

            Lock = false;
        }
 public void RotatePrepend(Quaternion quaternion)
 {
     var center = new Vector3d();
     this = CreateRotationMatrix(ref quaternion, ref center) * this;
 }
 public static Matrix3d CreateRotationMatrix(ref Quaternion quaternion, ref Vector3d center)
 {
     var matrixd = s_identity;
     matrixd.IsDistinguishedIdentity = false;
     double num12 = quaternion.X + quaternion.X;
     double num2 = quaternion.Y + quaternion.Y;
     double num = quaternion.Z + quaternion.Z;
     var num11 = quaternion.X * num12;
     var num10 = quaternion.X * num2;
     var num9 = quaternion.X * num;
     var num8 = quaternion.Y * num2;
     var num7 = quaternion.Y * num;
     var num6 = quaternion.Z * num;
     var num5 = quaternion.W * num12;
     var num4 = quaternion.W * num2;
     var num3 = quaternion.W * num;
     matrixd._m11 = 1 - (num8 + num6);
     matrixd._m12 = num10 + num3;
     matrixd._m13 = num9 - num4;
     matrixd._m21 = num10 - num3;
     matrixd._m22 = 1 - (num11 + num6);
     matrixd._m23 = num7 + num5;
     matrixd._m31 = num9 + num4;
     matrixd._m32 = num7 - num5;
     matrixd._m33 = 1 - (num11 + num8);
     if (((center.X != 0) || (center.Y != 0)) || (center.Z != 0))
     {
         matrixd._offsetX = (((-center.X * matrixd._m11) - (center.Y * matrixd._m21)) - (center.Z * matrixd._m31)) + center.X;
         matrixd._offsetY = (((-center.X * matrixd._m12) - (center.Y * matrixd._m22)) - (center.Z * matrixd._m32)) + center.Y;
         matrixd._offsetZ = (((-center.X * matrixd._m13) - (center.Y * matrixd._m23)) - (center.Z * matrixd._m33)) + center.Z;
     }
     return matrixd;
 }
Exemple #23
0
        private void ProcessLeftMouse(EButtonEvent buttonEvent)
        {
            if (buttonEvent == EButtonEvent.Pressed && m_controlledTransform != null)
            {
                if (IsHovered)
                {
                    Plane axisPlane;
                    if (m_activeAxisList.Count > 1)
                    {
                        Vector3 planeNormal = Vector3.Cross(m_activeAxisList[0], m_activeAxisList[1]);
                        axisPlane = new Plane(m_gizmoLocation, planeNormal);
                    }
                    else
                    {
                        Vector3 planeNormal;
                        if (Mode == EGizmoMode.Rotation)
                        {
                            // Rotation
                            planeNormal = m_activeAxisList[0];
                        }
                        else
                        {
                            //Translation / Scale
                            Vector3 toCamera     = m_frameViewInfo.ViewLocation - m_gizmoLocation;
                            Vector3 planeTangent = Vector3.Cross(m_activeAxisList[0], toCamera);
                            planeNormal = Vector3.Cross(m_activeAxisList[0], planeTangent);
                        }

                        axisPlane = new Plane(m_gizmoLocation, planeNormal);
                    }

                    World.ViewManager.GetViewInfo(out SSceneViewInfo viewInfo);
                    Ray ray = CreateMouseRay(viewInfo);

                    if (ray.Intersects(ref axisPlane, out Vector3 intersectionPoint))
                    {
                        m_startLocation = intersectionPoint;

                        switch (Mode)
                        {
                        case EGizmoMode.Translation:
                            m_clickOffset      = intersectionPoint - m_gizmoLocation;
                            m_originalPosition = m_controlledTransform.WorldPosition;
                            break;

                        case EGizmoMode.Rotation:
                            Vector3 toStart = m_startLocation - m_gizmoLocation;
                            m_rotationDragAxis = Vector3.Cross(toStart, m_activeAxisList[0]);
                            m_rotationDragAxis.Normalize();
                            m_originalRotation = m_controlledTransform.WorldRotation;
                            break;

                        case EGizmoMode.Scale:
                            m_originalScale = m_controlledTransform.WorldScale;
                            m_scaleAxis     = Vector3.Zero;
                            foreach (Vector3 axis in m_activeAxisList)
                            {
                                m_scaleAxis += Vector3.Transform(axis, Quaternion.Invert(m_controlledTransform.WorldRotation));
                            }

                            m_scaleAxis.Normalize();
                            m_scaleSizeFactor = m_originalScale.Length();
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        IsClicked = true;
                    }
                }
            }
            else if (m_controlledTransform != null)
            {
                if (IsClicked)
                {
                    switch (Mode)
                    {
                    case EGizmoMode.Translation:
                        Vector3 newPosition = m_controlledTransform.WorldPosition;
                        if (newPosition != m_originalPosition)
                        {
                            OnTranslationChanged?.Invoke(m_controlledTransform, m_originalPosition, newPosition);
                        }
                        break;

                    case EGizmoMode.Rotation:
                        Quaternion newRotation = m_controlledTransform.WorldRotation;
                        if (newRotation != m_originalRotation)
                        {
                            OnRotationChanged?.Invoke(m_controlledTransform, m_originalRotation, newRotation);
                        }
                        break;

                    case EGizmoMode.Scale:
                        Vector3 newScale = m_controlledTransform.WorldScale;
                        if (newScale != m_originalScale)
                        {
                            OnScaleChanged?.Invoke(m_controlledTransform, m_originalScale, newScale);
                        }
                        break;
                    }
                }

                IsClicked         = false;
                m_totalAngleDelta = 0.0f;
                m_totalScaleDelta = 0.0f;
            }
        }
 public void RotateAt(Quaternion quaternion, Vector3d center)
 {
     this *= CreateRotationMatrix(ref quaternion, ref center);
 }
 public static void AffineTransformation(float scaling, ref Vector3 rotationCenter, ref Quaternion rotation, ref Vector3 translation, out Matrix result)
 {
     result = Scaling(scaling) * Translation(-rotationCenter) * RotationQuaternion(rotation) *
              Translation(rotationCenter) * Translation(translation);
 }