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)); }
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); }
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); }
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 }
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; }
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; }
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); }