//============================ // this is run once per frame //============================ void Update() { if (Input.GetKeyDown(KeyCode.Escape)) { Application.Quit(); } // only perform if we are actually connected if (isConnected) { // check for keypresses to request texture if (Input.GetKeyUp(KeyCode.T) && playerActor != -1) { RequestTexture(playerActor); } // make sure we lock access before doing anything communicationMutex.WaitOne(); // remove actor objects for actors that have disappeared List <int> actorsToRemove = new List <int>(); foreach (KeyValuePair <int, GameObject> kvp in actorObjects) { if (actors.ContainsKey(kvp.Key)) { continue; } actorsToRemove.Add(kvp.Key); } foreach (int id in actorsToRemove) { Destroy(actorObjects[id]); actorObjects.Remove(id); } // fetch current pose for all skeletons int i = -1; foreach (KeyValuePair <int, CapturyActor> kvp in actors) { ++i; // get the actor id int actorID = kvp.Key; // add game object for actor if (!actorObjects.ContainsKey(actorID)) { GameObject actor = (GameObject)Instantiate(actorTemplateObject); Debug.Log("lol: " + actorTemplateObject.name); actor.SetActive(true); actorObjects.Add(actorID, actor); ConnectSkeleton(actorID, actor.transform); } // check if we need to initialize the player if (playerActor == -1 && i == playerActorIndex) { playerActor = actorID; Captury_synchronizeTime(); } // check if the actor is mapped to something, if not, ignore if (skeletons[actorID].reference == null) { continue; } // check whether we can calibrate the coordinate systems against each other /* if (headTransform != null && headTransforms.ContainsKey(actorID) && !headTransforms[actorID].consumed && headTransforms[actorID].timestamp > Captury_getTime() - 500000) * { * Camera cam = GameObject.Find("/OVRController/Camera").GetComponent<Camera>(); * GameObject cube = GameObject.Find("/Cube"); * cube.transform.rotation = headTransforms[actorID].rotation; * * Quaternion delta = headTransforms[actorID].rotation * Quaternion.Inverse(cam.transform.localRotation); * float angle; * Vector3 axis; * cam.transform.localRotation.ToAngleAxis(out angle, out axis); * Debug.Log(String.Format("oculus angle {0} axis {1} {2} {3} ", angle, axis.x, axis.y, axis.z)); * headTransforms[actorID].rotation.ToAngleAxis(out angle, out axis); * Debug.Log(String.Format("head angle {0} axis {1} {2} {3} ", angle, axis.x, axis.y, axis.z)); * delta.ToAngleAxis(out angle, out axis); * float dist = (headTransforms[actorID].translation - headTransform.position).magnitude; * Debug.Log(String.Format("delta angle {0} axis {1} {2} {3} dist {4}", angle, axis.x, axis.y, axis.z, dist)); * if (dist < 0.2 && Math.Abs(axis.y) > headTransforms[actorID].bestAccuracy) * { * CameraFollower cfScript = GameObject.Find("/OVRController").GetComponent<CameraFollower>(); * cfScript.orientationOffset = Quaternion.Euler(0,180,0) * delta;// Quaternion.Inverse(delta); * headTransforms[actorID].bestAccuracy = Math.Abs(axis.y); * } * headTransforms[actorID].consumed = true; * } * * // send head orientation back to captury live to refine the tracking * if (playerActor == actorID && cameraTransform != null) * { * Quaternion q = ConvertRotationToLive(cameraTransform.rotation); * float[] array = new float[4]; * array[0] = q.x; * array[1] = q.y; * array[2] = q.z; * array[3] = q.w; * GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); * IntPtr data = handle.AddrOfPinnedObject(); * // TODO: only send constraint back when we have a common calibration between live and the oculus * //int result = Captury_setRotationConstraint(actorID, 7, data, 0, 1.0f); * if (handle.IsAllocated) * handle.Free(); * } */ // get pointer to pose IntPtr poseData = Captury_getCurrentPose(actorPointers[actorID]); // check if we actually got data, if not, continue if (poseData == IntPtr.Zero) { // something went wrong, get error message IntPtr msg = Captury_getLastErrorMessage(); string errmsg = Marshal.PtrToStringAnsi(msg); Debug.Log("Stream error: " + errmsg); Captury_freeErrorMessage(msg); continue; } // Debug.Log("received pose for " + actorID); // convert the pose CapturyPose pose = (CapturyPose)Marshal.PtrToStructure(poseData, typeof(CapturyPose)); // get the data into a float array float[] values = new float[pose.numValues * 6]; Marshal.Copy(pose.values, values, 0, pose.numValues * 6); Debug.Log("Value :" + values.Length); Debug.Log("received pose with numvalues: " + pose.numValues + " skeleton has joints: " + skeletons[actorID].joints.Length); Debug.Log("Send values over photon network..."); this.photonView.RPC("sendValues", PhotonTargets.Others, values); // now loop over all joints Vector3 pos = new Vector3(); Vector3 rot = new Vector3(); for (int jointID = 0; jointID < skeletons[actorID].joints.Length; jointID++) { // ignore any joints that do not map to a transform if (skeletons[actorID].joints[jointID].transform == null) { continue; } // set offset and rotation int baseIndex = jointID * 6; pos.Set(values[baseIndex + 0], values[baseIndex + 1], values[baseIndex + 2]); rot.Set(values[baseIndex + 3], values[baseIndex + 4], values[baseIndex + 5]); skeletons[actorID].joints[jointID].transform.position = ConvertPosition(pos); skeletons[actorID].joints[jointID].transform.rotation = ConvertRotation(rot); // if (jointID == 0) // Debug.Log("updating joint" + skeletons[actorID].joints[jointID].name + " " + pos); } // finally, free the pose data again, as we are finished Captury_freePose(poseData); } communicationMutex.ReleaseMutex(); } }
//============================ // this is run once per frame //============================ void Update() { if (Input.GetKeyDown(KeyCode.Escape)) { Application.Quit(); } // only perform if we are actually connected if (isConnected) { // check for keypresses to request texture if (Input.GetKeyUp(KeyCode.T) && playerActor != -1) { RequestTexture(playerActor); } // make sure we lock access before doing anything communicationMutex.WaitOne(); // remove actor objects for actors that have disappeared List <int> actorsToRemove = new List <int>(); foreach (KeyValuePair <int, GameObject> kvp in actorObjects) { if (actors.ContainsKey(kvp.Key)) { continue; } actorsToRemove.Add(kvp.Key); } foreach (int id in actorsToRemove) { Destroy(actorObjects[id]); actorObjects.Remove(id); } // fetch current pose for all skeletons int i = -1; foreach (KeyValuePair <int, CapturyActor> kvp in actors) { ++i; // get the actor id int actorID = kvp.Key; // add game object for actor if (!actorObjects.ContainsKey(actorID)) { GameObject actor = (GameObject)Instantiate(actorTemplateObject); actor.SetActive(true); actorObjects.Add(actorID, actor); ConnectSkeleton(actor.transform); } // check if we need to initialize the player if (playerActor == -1 && i == playerActorIndex) { playerActor = actorID; Captury_synchronizeTime(); } // check if the actor is mapped to something, if not, ignore if (skeletons[actorID].reference == null) { continue; } // get pointer to pose IntPtr poseData = Captury_getCurrentPose(actorPointers[actorID]); // check if we actually got data, if not, continue if (poseData == IntPtr.Zero) { // something went wrong, get error message IntPtr msg = Captury_getLastErrorMessage(); string errmsg = Marshal.PtrToStringAnsi(msg); Debug.Log("Stream error: " + errmsg); Captury_freeErrorMessage(msg); continue; } // Debug.Log("received pose for " + actorID); // convert the pose CapturyPose pose = (CapturyPose)Marshal.PtrToStructure(poseData, typeof(CapturyPose)); // get the data into a float array float[] values = new float[pose.numValues]; Marshal.Copy(pose.values, values, 0, pose.numValues); this.photonView.RPC("sendValues", PhotonTargets.Others, values, actorID); // now loop over all joints Vector3 pos = new Vector3(); Vector3 rot = new Vector3(); for (int jointID = 0; jointID < skeletons[actorID].joints.Length; jointID++) { // ignore any joints that do not map to a transform if (skeletons[actorID].joints[jointID].transform == null) { continue; } // set offset and rotation int baseIndex = jointID * 6; pos.Set(values[baseIndex + 0], values[baseIndex + 1], values[baseIndex + 2]); rot.Set(values[baseIndex + 3], values[baseIndex + 4], values[baseIndex + 5]); skeletons[actorID].joints[jointID].transform.position = ConvertPosition(pos); skeletons[actorID].joints[jointID].transform.rotation = ConvertRotation(rot); // if (jointID == 0) // Debug.Log("updating joint" + skeletons[actorID].joints[jointID].name + " " + pos); } // finally, free the pose data again, as we are finished Captury_freePose(poseData); } communicationMutex.ReleaseMutex(); } }