/// <summary> /// raycasts then spherecasts in a direction to find dynamic object being gazed at. returns true if hits dynamic /// </summary> /// <param name="pos"></param> /// <param name="direction"></param> /// <param name="distance"></param> /// <param name="radius"></param> /// <returns></returns> public virtual bool DynamicRaycast(Vector3 pos, Vector3 direction, float distance, float radius, out float hitDistance, out DynamicObject hitDynamic, out Vector3 worldHitPoint, out Vector3 localHitPoint, out Vector2 hitTextureCoord) { //TODO raycast to dynamic. if failed, spherecast with radius //if hit dynamic, return info RaycastHit hit = new RaycastHit(); bool didhitdynamic = false; hitDynamic = null; hitDistance = 0; worldHitPoint = Vector3.zero; localHitPoint = Vector3.zero; hitTextureCoord = Vector2.zero; if (Physics.Raycast(pos, direction, out hit, distance, CognitiveVR_Preferences.Instance.DynamicLayerMask, QueryTriggerInteraction.Ignore)) { if (CognitiveVR_Preferences.S_DynamicObjectSearchInParent) { hitDynamic = hit.collider.GetComponentInParent <DynamicObject>(); } else { hitDynamic = hit.collider.GetComponent <DynamicObject>(); } if (hitDynamic != null) { didhitdynamic = true; worldHitPoint = hit.point; Vector3 LocalGaze = hitDynamic.transform.InverseTransformPointUnscaled(worldHitPoint); float relativeScalex = hitDynamic.transform.lossyScale.x / hitDynamic.StartingScale.x; float relativeScaley = hitDynamic.transform.lossyScale.y / hitDynamic.StartingScale.y; float relativeScalez = hitDynamic.transform.lossyScale.z / hitDynamic.StartingScale.z; localHitPoint.x = LocalGaze.x / relativeScalex; localHitPoint.y = LocalGaze.y / relativeScaley; localHitPoint.z = LocalGaze.z / relativeScalez; //Vector3 relativeScale = new Vector3( // hitDynamic.transform.lossyScale.x / hitDynamic.StartingScale.x, // hitDynamic.transform.lossyScale.y / hitDynamic.StartingScale.y, // hitDynamic.transform.lossyScale.z / hitDynamic.StartingScale.z); //localHitPoint = new Vector3(LocalGaze.x / relativeScale.x, LocalGaze.y / relativeScale.y, LocalGaze.z / relativeScale.z); hitDistance = hit.distance; hitTextureCoord = hit.textureCoord; } } if (!didhitdynamic && Physics.SphereCast(pos, radius, direction, out hit, distance, CognitiveVR_Preferences.Instance.DynamicLayerMask, QueryTriggerInteraction.Ignore)) { if (CognitiveVR_Preferences.Instance.DynamicObjectSearchInParent) { hitDynamic = hit.collider.GetComponentInParent <DynamicObject>(); } else { hitDynamic = hit.collider.GetComponent <DynamicObject>(); } if (hitDynamic != null) { didhitdynamic = true; worldHitPoint = hit.point; Vector3 LocalGaze = hitDynamic.transform.InverseTransformPointUnscaled(worldHitPoint); float relativeScalex = hitDynamic.transform.lossyScale.x / hitDynamic.StartingScale.x; float relativeScaley = hitDynamic.transform.lossyScale.y / hitDynamic.StartingScale.y; float relativeScalez = hitDynamic.transform.lossyScale.z / hitDynamic.StartingScale.z; localHitPoint.x = LocalGaze.x / relativeScalex; localHitPoint.y = LocalGaze.y / relativeScaley; localHitPoint.z = LocalGaze.z / relativeScalez; //Vector3 relativeScale = new Vector3( // hitDynamic.transform.lossyScale.x / hitDynamic.StartingScale.x, // hitDynamic.transform.lossyScale.y / hitDynamic.StartingScale.y, // hitDynamic.transform.lossyScale.z / hitDynamic.StartingScale.z); //localHitPoint = new Vector3(LocalGaze.x / relativeScale.x, LocalGaze.y / relativeScale.y, LocalGaze.z / relativeScale.z); hitDistance = hit.distance; hitTextureCoord = hit.textureCoord; } } return(didhitdynamic); }
//each row is 30 pixels void DrawDynamicObject(DynamicObject dynamic, Rect rect, bool darkbackground) { Event e = Event.current; if (e.isMouse && e.type == EventType.mouseDown) { if (e.mousePosition.x < rect.x || e.mousePosition.x > rect.x + rect.width || e.mousePosition.y < rect.y || e.mousePosition.y > rect.y + rect.height) { } else { if (e.shift) //add to selection { GameObject[] gos = new GameObject[Selection.transforms.Length + 1]; Selection.gameObjects.CopyTo(gos, 0); gos[gos.Length - 1] = dynamic.gameObject; Selection.objects = gos; } else { Selection.activeTransform = dynamic.transform; } } } if (darkbackground) { GUI.Box(rect, "", "dynamicentry_even"); } else { GUI.Box(rect, "", "dynamicentry_odd"); } //GUI.color = Color.white; Rect mesh = new Rect(rect.x + 10, rect.y, 120, rect.height); Rect gameobject = new Rect(rect.x + 160, rect.y, 120, rect.height); //Rect id = new Rect(rect.x + 290, rect.y, 120, rect.height); Rect collider = new Rect(rect.x + 320, rect.y, 24, rect.height); Rect uploaded = new Rect(rect.x + 380, rect.y, 24, rect.height); if (dynamic.UseCustomMesh) { GUI.Label(mesh, dynamic.MeshName, "dynamiclabel"); } else { GUI.Label(mesh, dynamic.CommonMesh.ToString(), "dynamiclabel"); } GUI.Label(gameobject, dynamic.gameObject.name, "dynamiclabel"); if (!dynamic.HasCollider()) { GUI.Label(collider, new GUIContent(EditorCore.Alert, "Tracking Gaze requires a collider"), "image_centered"); } if (EditorCore.GetExportedDynamicObjectNames().Contains(dynamic.MeshName) || !dynamic.UseCustomMesh) { GUI.Label(uploaded, EditorCore.Checkmark, "image_centered"); } else { GUI.Label(uploaded, EditorCore.EmptyCheckmark, "image_centered"); } }
void OnVectorChanged(DynamicObject dynamic, bool right, string name, int input, float x, float y, List <ButtonState> states) { states.Add(new ButtonState(name, input, x, y, true)); }
//writes for normalized inputs (touchpads) void OnVectorChanged(DynamicObject dynamic, bool right, string name, int input, Vector2 vector, List <ButtonState> states) { states.Add(new ButtonState(name, input, vector.x, vector.y, true)); }
//writes for 0-100 inputs (triggers) void OnSingleChanged(DynamicObject dynamic, bool right, string name, int single, List <ButtonState> states) { states.Add(new ButtonState(name, single)); }
void OnButtonChanged(DynamicObject dynamic, bool right, string name, bool down, List <ButtonState> states) { states.Add(new ButtonState(name, down ? 100 : 0)); }
//writes manifest entry and object snapshot to string then send http request public IEnumerator Thread_StringThenSend(Queue <DynamicObjectManifestEntry> SendObjectManifest, Queue <DynamicObjectSnapshot> SendObjectSnapshots, CognitiveVR_Preferences.SceneSettings trackingSettings, string uniqueid, double sessiontimestamp, string sessionid) { //save and clear snapshots and manifest entries DynamicObjectManifestEntry[] tempObjectManifest = new DynamicObjectManifestEntry[SendObjectManifest.Count]; SendObjectManifest.CopyTo(tempObjectManifest, 0); SendObjectManifest.Clear(); DynamicObjectSnapshot[] tempSnapshots = new DynamicObjectSnapshot[SendObjectSnapshots.Count]; SendObjectSnapshots.CopyTo(tempSnapshots, 0); //for (int i = 0; i<tempSnapshots.Length; i++) //{ // var s = DynamicObject.SetSnapshot(tempSnapshots[i]); // Debug.Log(">>>>>>>>>>>>>queue snapshot " + s); //} //write manifest entries to thread List <string> manifestEntries = new List <string>(); bool done = true; if (tempObjectManifest.Length > 0) { done = false; new System.Threading.Thread(() => { for (int i = 0; i < tempObjectManifest.Length; i++) { manifestEntries.Add(DynamicObject.SetManifestEntry(tempObjectManifest[i])); } done = true; }).Start(); while (!done) { yield return(null); } } List <string> snapshots = new List <string>(); if (tempSnapshots.Length > 0) { done = false; new System.Threading.Thread(() => { for (int i = 0; i < tempSnapshots.Length; i++) { snapshots.Add(DynamicObject.SetSnapshot(tempSnapshots[i])); } //System.GC.Collect(); done = true; }).Start(); while (!done) { yield return(null); } } while (SendObjectSnapshots.Count > 0) { SendObjectSnapshots.Dequeue().ReturnToPool(); } DynamicObject.SendSavedSnapshots(manifestEntries, snapshots, trackingSettings, uniqueid, sessiontimestamp, sessionid); }
/// <summary> /// raycasts then spherecasts in a direction to find dynamic object being gazed at. returns true if hits dynamic /// </summary> /// <param name="pos"></param> /// <param name="direction"></param> /// <param name="distance"></param> /// <param name="radius"></param> /// <returns></returns> public virtual bool DynamicRaycast(Vector3 pos, Vector3 direction, float distance, float radius, out float hitDistance, out DynamicObject hitDynamic, out Vector3 worldHitPoint, out Vector2 hitTextureCoord) { //TODO raycast to dynamic. if failed, spherecast with radius //if hit dynamic, return info RaycastHit hit = new RaycastHit(); bool didhitdynamic = false; hitDynamic = null; hitDistance = 0; worldHitPoint = Vector3.zero; hitTextureCoord = Vector2.zero; if (Physics.Raycast(pos, direction, out hit, distance)) { if (CognitiveVR_Preferences.S_DynamicObjectSearchInParent) { hitDynamic = hit.collider.GetComponentInParent <DynamicObject>(); } else { hitDynamic = hit.collider.GetComponent <DynamicObject>(); } if (hitDynamic != null) { didhitdynamic = true; worldHitPoint = hit.point; hitDistance = hit.distance; hitTextureCoord = hit.textureCoord; } } if (!didhitdynamic && Physics.SphereCast(pos, radius, direction, out hit, distance)) { if (CognitiveVR_Preferences.Instance.DynamicObjectSearchInParent) { hitDynamic = hit.collider.GetComponentInParent <DynamicObject>(); } else { hitDynamic = hit.collider.GetComponent <DynamicObject>(); } if (hitDynamic != null) { didhitdynamic = true; worldHitPoint = hit.point; hitDistance = hit.distance; hitTextureCoord = hit.textureCoord; } } return(didhitdynamic); }
void RecordEyeCapture() { //check for new fixation //check for ending fixation //update eyecapture state if (!IsFixating) { //check if this is the start of a new fixation. set this and all next captures to this //the 'current' fixation we're checking is 1 second behind recoding eye captures if (TryBeginLocalFixation(index)) { ActiveFixation.IsLocal = true; //FixationTransform set in TryBeginLocalFixation IsFixating = true; } else { if (TryBeginFixation()) { ActiveFixation.IsLocal = false; //FixationTransform = null; IsFixating = true; } } } else { //center is about 0.01 //off screen is ~0.3 EyeCaptures[index].OffTransform = IsGazeOffTransform(EyeCaptures[index]); EyeCaptures[index].OutOfRange = IsGazeOutOfRange(EyeCaptures[index]); ActiveFixation.AddEyeCapture(EyeCaptures[index]); ActiveFixation.DurationMs = EyeCaptures[index].Time - ActiveFixation.StartMs; if (CheckEndFixation(ActiveFixation)) { FixationCore.RecordFixation(ActiveFixation); IsFixating = false; if (ActiveFixation.IsLocal) { ActiveFixation.LocalTransform = null; } CachedEyeCapturePositions.Clear(); } } //reset all values EyeCaptures[index].Discard = false; EyeCaptures[index].SkipPositionForFixationAverage = false; EyeCaptures[index].OffTransform = false; EyeCaptures[index].OutOfRange = false; bool areEyesClosed = AreEyesClosed(); #if CVR_PUPIL // discard gaze point if confidence too low. WILL THIS CONFLICT WITH BLINKING? //EyeCaptures[index].Discard = PupilTools.FloatFromDictionary(PupilTools.gazeDictionary, "confidence") < 0.5f; #endif #if CVR_TOBIIVR // discard gaze point if direction from either eye is invalid. WILL THIS CONFLICT WITH BLINKING? //EyeCaptures[index].Discard = currentData.Right.GazeDirectionValid && currentData.Left.GazeDirectionValid ? false : true; #endif #if CVR_AH //EyeCaptures[index].Discard = eyetracker.CurrentTrackingState == EyeTracker.TrackingState.TrackingUnknown || (eyetracker.CurrentTrackingState == EyeTracker.TrackingState.TrackingLost && !areEyesClosed); #endif //set new current values EyeCaptures[index].EyesClosed = areEyesClosed; EyeCaptures[index].HmdPosition = GameplayReferences.HMD.position; EyeCaptures[index].Time = EyeCaptureTimestamp(); Vector3 world; DynamicObject hitDynamic = null; var hitresult = GazeRaycast(out world, out hitDynamic); if (hitresult == GazeRaycastResult.HitWorld) { //hit something as expected EyeCaptures[index].WorldPosition = world; if (hitDynamic != null) { EyeCaptures[index].HitDynamicTransform = hitDynamic.transform; EyeCaptures[index].LocalPosition = hitDynamic.transform.InverseTransformPoint(world); } else { EyeCaptures[index].HitDynamicTransform = null; } } else if (hitresult == GazeRaycastResult.HitNothing) { //eye capture world point could be used for getting the direction, but position is invalid (on skybox) EyeCaptures[index].SkipPositionForFixationAverage = true; EyeCaptures[index].HitDynamicTransform = null; EyeCaptures[index].WorldPosition = world; } else if (hitresult == GazeRaycastResult.Invalid) { EyeCaptures[index].SkipPositionForFixationAverage = true; EyeCaptures[index].HitDynamicTransform = null; EyeCaptures[index].Discard = true; } #if UNITY_EDITOR || DEVELOPMENT_BUILD if (float.IsNaN(world.x) || float.IsNaN(world.y) || float.IsNaN(world.z)) { } else if (lastEyeTrackingPointer != null) { lastEyeTrackingPointer.transform.position = world; } //turned invalid somewhere VISGazepoints.Add(EyeCaptures[index].WorldPosition); #endif index = (index + 1) % CachedEyeCaptures; }