protected override void DefaultValues() { base.DefaultValues(); this.collisions = new List <HitResult3D>(); this.resultZero = new HitResult3D(); }
/// <summary> /// Check cursor collision /// </summary> /// <param name="ray">ray cast</param> /// <param name="rayDistance">The ray distance to test</param> /// <returns>Cursor hit</returns> public CursorHit CheckCursorCollision(ref Ray ray, float rayDistance) { HitResult3D result = this.Owner.Scene.PhysicsManager.Simulation3D.RayCast(ref ray, rayDistance); CursorHit cursorHit = new CursorHit(); if (result.Succeeded) { cursorHit.Hit = true; cursorHit.Position = result.Point - (ray.Direction * this.SurfaceOffset); cursorHit.Target = result.Point + result.Normal; } return(cursorHit); }
private void CheckButtonInteraction(ref HitResult3D result) { ButtonComponentBase currentButton = null; if (result.Succeeded) { Entity entityHiting = (result.PhysicBody.UserData as PhysicBody3D).Owner; currentButton = entityHiting?.Parent?.FindComponent <ButtonComponentBase>(false); if (currentButton != null) { if (!currentButton.Hover) { currentButton.Hover = true; } if (this.TriggerValue > 0 && this.lastTriggerValue == 0) { currentButton?.Touch(); } if (currentButton != this.lastButton && this.lastButton != null) { this.lastButton.Hover = false; } } else { if (this.lastButton != null) { this.lastButton.Hover = false; } } } else { if (this.lastButton != null) { this.lastButton.Hover = false; } } this.lastButton = currentButton; }
//private void CheckNoesisInteraction(ref HitResult3D result, ref Ray ray) //{ // NoesisMouseSyncComponent noesisSyncComponent = null; // if (result.Succeeded) // { // Entity noesisEntity = (result.PhysicBody.UserData as PhysicBody3D).Owner; // var noesisPanel = noesisEntity?.FindComponent<NoesisPanel>(); // noesisSyncComponent = noesisEntity?.FindComponent<NoesisMouseSyncComponent>(); // if (noesisPanel != null && noesisSyncComponent != null) // { // int projectedX; // int projectedY; // float? rayDistance; // if (noesisPanel != null && noesisPanel.View != null && noesisPanel.ProjectRay(ray, out projectedX, out projectedY, out rayDistance)) // { // if (this.lastTriggerValue == 0 && this.TriggerValue > 0) // { // noesisSyncComponent.MouseDown(projectedX, projectedY, Noesis.MouseButton.Left); // } // else if (this.lastTriggerValue > 0 && this.TriggerValue == 0) // { // noesisSyncComponent.MouseUp(projectedX, projectedY, Noesis.MouseButton.Left); // } // else // { // noesisSyncComponent.MouseMove(projectedX, projectedY); // } // } // } // else // { // this.lastNoesisPanel?.MouseMove(-1, -1); // noesisSyncComponent = null; // } // } // else // { // this.lastNoesisPanel?.MouseMove(-1, -1); // noesisSyncComponent = null; // } // this.lastNoesisPanel = noesisSyncComponent; //} private HitResult3D NearestCollider(ref Vector3 startPosition, IList <HitResult3D> results) { float minDistance = float.MaxValue; HitResult3D nearest = this.resultZero; foreach (HitResult3D r in results) { if (!r.Succeeded) { continue; } if (minDistance > r.HitFraction) { nearest = r; minDistance = r.HitFraction; } } return(nearest); }
protected override void CalculateGazeProperties(ref Ray ray, out Vector3 gazePosition, out Vector3 gazeNormal) { gazePosition = ray.Position + ray.Direction * 50; gazeNormal = -ray.Direction; if (this.Owner.Scene.PhysicsManager.Simulation3D.InternalWorld == null) { return; } this.collisions.Clear(); this.Owner.Scene.PhysicsManager.Simulation3D.RayCastAll(ref ray, 10, this.collisions); if (this.collisions != null && this.collisions.Count > 0) { HitResult3D result = this.NearestCollider(ref ray.Position, this.collisions); if (result.Succeeded) { if (!this.gaze.IsVisible) { this.gaze.IsVisible = true; } gazePosition = result.Point + (result.Normal * 0.002f); gazeNormal = result.Normal; } // Noesis Panel //this.CheckNoesisInteraction(ref result, ref ray); // 3D Buttons this.CheckButtonInteraction(ref result); } else { if (gaze.IsVisible) { this.gaze.IsVisible = false; } } }
/// <inheritdoc/> protected override void Update(TimeSpan gameTime) { Ray?ray = null; var disableByPalmUp = false; if (this.Joint != null) { if (this.Joint.PoseIsValid) { this.Joint.TrackedDevice.TryGetArticulatedHandJoint(XRHandJointKind.IndexProximal, out var handJoint); var handPosition = handJoint.Pose.Position; var measuredRayPosition = handPosition; var measuredDirection = this.Joint.Pointer.Direction; this.stabilizedRay.AddSample(new Ray(measuredRayPosition, measuredDirection)); ray = new Ray(this.stabilizedRay.StabilizedPosition, this.stabilizedRay.StabilizedDirection); } } else { ray = new Ray(this.MainCursor.transform.Position, this.MainCursor.transform.WorldTransform.Forward); } if (this.Joint?.PoseIsValid == true) { var jointOrientation = Matrix4x4.CreateFromQuaternion(this.Joint.Pose.Orientation); var jointNormal = -jointOrientation.Up; var headForward = this.cam.Transform.WorldTransform.Forward; disableByPalmUp = !this.ShouldShowRay(headForward, jointNormal); } var disableByJointInvalid = true; var lineMeshVisible = false; if (ray != null && ray.Value.Position != Vector3.Zero) { var r = ray.Value; var disableByProximity = false; if (this.cursor.Pinch) { float dFactor = (Vector3.Transform(this.MainCursor.transform.Position, this.cam.Transform.WorldInverseTransform) - this.pinchPosRef).Z; dFactor = (float)Math.Pow(1 - dFactor, 4); this.transform.Position = r.GetPoint(this.pinchDist * dFactor); } else { if (this.MainCursor.Pinch && !this.LineMesh.Owner.IsEnabled) { disableByProximity = true; } else { Vector3 collPoint = r.GetPoint(1000.0f); this.transform.Position = collPoint; // Move the cursor to avoid collisions Vector3 from = r.GetPoint(-0.1f); Vector3 to = r.GetPoint(1000.0f); HitResult3D result = this.Managers.PhysicManager3D.RayCast(ref from, ref to, this.collisionMask); if (result.Succeeded) { Vector3 dir = r.Direction; dir.Normalize(); collPoint = result.Point + (dir * 0.0025f); } float dist = (r.Position - collPoint).Length(); if (dist > 0.3f) { this.transform.Position = collPoint; if (this.MainCursor.Pinch) { // Pinch is about to happen this.pinchDist = dist; this.pinchPosRef = Vector3.Transform(this.MainCursor.transform.Position, this.cam.Transform.WorldInverseTransform); } } else { disableByProximity = true; } } } // Update line disableByJointInvalid = this.Joint != null && !Tools.IsJointValid(this.Joint); lineMeshVisible = !disableByJointInvalid && !disableByProximity && !disableByPalmUp; if (lineMeshVisible) { var distance = (this.transform.Position - r.Position).Length(); this.lineMeshTransform.Position = r.Position; this.lineMeshTransform.Scale = new Vector3(1, 1, distance); this.lineMeshTransform.LocalLookAt(this.transform.Position, Vector3.Up); this.LineMesh.TextureTiling = new Vector2(distance * 0.5f * 30.0f, 1.0f); } } this.LineMesh.Owner.IsEnabled = lineMeshVisible; this.cursor.meshRenderer.IsEnabled = lineMeshVisible; this.MainCursor.meshRenderer.IsEnabled = !disableByJointInvalid && !disableByPalmUp && !lineMeshVisible; this.cursor.Pinch = lineMeshVisible && this.MainCursor.Pinch; if (this.cursor.Pinch != this.cursor.PreviousPinch) { this.LineMesh.DiffuseTexture = this.cursor.Pinch ? null : this.handrayTexture; } }