Esempio n. 1
0
        IEnumerator StoreCalibrationData()
        {
            //re-get the OSC objects
            RigidbodyDefinition def_xz, def_minxminz;

            if (OptiTrackOSCClient.GetRigidbody(strXZ, out def_xz))
            {
                vXZOsc = def_xz.position;
            }
            if (OptiTrackOSCClient.GetRigidbody(strMinXMinZ, out def_minxminz))
            {
                vMinXMinZOsc = def_minxminz.position;
            }

            //store our anchored calibration data (virtual positions of
            vXZ       = goXZ.gameObject.transform.position;
            vMinXMinZ = goMinXMinZ.gameObject.transform.position;

            //store average y-offset for all anchors (gives user some leeway for error)... do we even need this?
            yOffset += vXZ.y - vXZOsc.y;
            yOffset += vMinXMinZ.y - vMinXMinZOsc.y;
            yOffset  = yOffset * .5f;

            //IDEA 1b
            //determine offset between vXZOsc and anchor
            Vector3 vXZOffset = vXZOsc - vXZ;

            //compare the "same" line, unrotated v rotated, to determine angle between
            Vector3 v1, v2;

            v1 = vMinXMinZ - vXZ;                               //rotated
            v2 = vMinXMinZOsc - vXZOsc;                         //unrotated
            //align the height values
            v1.y = v2.y;

            float   angle = Vector3.Angle(v1, v2);              //does this return a signed value? NOPE
            Vector3 cross = Vector3.Cross(v1, v2);

            if (cross.y < 0)
            {
                angle = -angle;                             //hope this works
            }
            //clear old anchor!
            if (anchorCenter != null)
            {
                WorldAnchorManager.Instance.RemoveAnchor(optitrackCenter.gameObject);
                yield return(new WaitForSeconds(.25f));

                store.Delete(strCenter);
                yield return(new WaitForSeconds(.25f));
            }

            //HACK because of bug when re-anchoring a pre-existing (loaded) anchor (snaps to old position), re/de/re-anchor fixes this
            WorldAnchorManager.Instance.AttachAnchor(optitrackCenter.gameObject, strCenter);
            yield return(new WaitForSeconds(.25f));

            WorldAnchorManager.Instance.RemoveAnchor(optitrackCenter.gameObject);
            yield return(new WaitForSeconds(.25f));

            //rotate world center around this angle (how do I know which direction, does this matter?
            optitrackCenter.transform.rotation = Quaternion.Euler(0, -angle, 0);
            //rotate the optitrack XZ over the same angle
            Vector3 rotatedXZ = Quaternion.Euler(0, -angle, 0) * vXZOsc;

            //subtract this from XZ Object position to get "real center" and position world center there
            optitrackCenter.position = vXZ - rotatedXZ * (v1.magnitude / v2.magnitude);             //take scale diff into account

            //apply scale
            OptiTrackOSCClient oscClient = optitrackCenter.GetComponent <OptiTrackOSCClient>();

            oscClient.scale = (v1.magnitude / v2.magnitude);

            //for some reason this snaps it to an earlier position? UGH
            WorldAnchorManager.Instance.AttachAnchor(oscClient.gameObject, strCenter);

            yield return(new WaitForSeconds(5f));

            //if followup scene is not null, go there...
            if (followupScene != null)
            {
                SceneManager.LoadScene(followupScene);
            }
        }
Esempio n. 2
0
        IEnumerator DoCalibration(bool recalibrate = false)
        {
#if !UNITY_EDITOR
            while (!WorldAnchorManager.IsInitialized)
            {
                yield return(null);
            }

            //give it some time
            yield return(new WaitForSeconds(2f));

            //get anchor store
            if (store == null)
            {
                WorldAnchorStore.GetAsync(GotStore);
                while (store == null)
                {
                    //Debug.Log("Bla");
                    yield return(null);
                }
            }

            //check if we have stored anchorData for this App & WIFI
            anchorXZ       = store.Load(strXZ, goXZ.gameObject);
            anchorMinXMinZ = store.Load(strMinXMinZ, goMinXMinZ.gameObject);
            anchorCenter   = store.Load(strCenter, optitrackCenter.gameObject);
            if (anchorCenter != null)
            {
                //load follow-up directly...
                //if (followupScene != null ) {
                //	SceneManager.LoadScene(followupScene);
                //}
                //yield break;

                //for now always recalibrate until it works...

                /*
                 * if (!recalibrate) {
                 *      //calibration already exists, only continue if we've forced re-calibration
                 *      //store current data (the actual positions will change every time you boot)
                 *      StartCoroutine(StoreCalibrationData());
                 *      yield break;
                 * } */
            }
#endif

            if (anchorCenter != null)
            {
                WorldAnchorManager.Instance.RemoveAnchor(optitrackCenter.gameObject);
                yield return(new WaitForSeconds(.25f));

                optitrackCenter.transform.position = Vector3.zero;
                optitrackCenter.transform.rotation = Quaternion.identity;
            }

            //display message "please place exactly 2 rigidbodies at XZ, -X-Z (two corners of the room)"
            feedbackCanvas.enabled = true;
            feedbackText.text      = "Place rigidbodies called \"xz\" and \"minxminz\" at positive and negative corners of the mocap space (found: 0).";
            feedbackButton.enabled = true;

            List <RigidbodyDefinition> defList = null;

            done = false;
            bool canContinue = false;
            while (!canContinue)
            {
                //check if there are three rigidbodies, and they are in the desired quadrants
                if (OptiTrackOSCClient.GetAllRigidbodies(out defList))
                {
                    int activeCount = 0;
                    for (int i = 0; i < defList.Count; ++i)
                    {
                        if (defList[i].isActive)
                        {
                            activeCount++;
                        }
                    }

                    feedbackText.text = "Place rigidbodies called \"xz\" and \"minxminz\" at positive and negative corners of the mocap space (found: " + activeCount + ").";

                    if (activeCount >= 2)
                    {
                        bool XZ = false, minXMinZ = false;
                        foreach (RigidbodyDefinition def in defList)
                        {
                            if (def.position.x > 0 && def.position.z > 0 && def.name == "xz")
                            {
                                XZ     = true;
                                vXZOsc = def.position;
                            }
                            if (def.position.x < 0 && def.position.z < 0 && def.name == "minxminz")
                            {
                                minXMinZ     = true;
                                vMinXMinZOsc = def.position;
                            }
                        }
                        if (XZ && minXMinZ && done)
                        {
                            canContinue = true;
                            continue;
                        }
                    }
                }
                yield return(null);
            }

            //display message: "align these three anchors with their correct rigidbody as best you can (height & rotation don't need to be exact)"
            //activate button
            feedbackCanvas.enabled = true;
            feedbackText.text      = "Align the two virtual anchors with the real objects you just placed. Say \"Next\" when you are done.";
            feedbackButton.enabled = true;

            //activate anchors that user must place
            goXZ.gameObject.SetActive(true);
            goMinXMinZ.gameObject.SetActive(true);

            //re-create/activate their world anchors
            ReAnchor(ref anchorXZ, ref goXZ);
            ReAnchor(ref anchorMinXMinZ, ref goMinXMinZ);

            //make sure they are movable
            goXZ.movable       = true;
            goMinXMinZ.movable = true;

            done = false;
            while (!done)
            {
                readyToCalibrate = true;
                yield return(null);
            }

            readyToCalibrate = false;

            //make sure we can't move the anchors anymore...
            goXZ.movable       = false;
            goMinXMinZ.movable = false;

            StartCoroutine(StoreCalibrationData());

            feedbackCanvas.enabled = false;

            yield return(null);
        }
Esempio n. 3
0
        public bool MockCalibration(ref Vector3 center, ref float rot, ref float scale, ref Vector3 tr, ref Vector3 bl, ref Vector3 osctr, ref Vector3 oscbl, ref float yOffset)
        {
            if (!readyToCalibrate)
            {
                return(false);
            }

            //re-get the OSC objects
            RigidbodyDefinition def_xz, def_minxminz;

            if (OptiTrackOSCClient.GetRigidbody(strXZ, out def_xz))
            {
                osctr = def_xz.position;
            }
            if (OptiTrackOSCClient.GetRigidbody(strMinXMinZ, out def_minxminz))
            {
                oscbl = def_minxminz.position;
            }

            //store our anchored calibration data (virtual positions of
            tr = goXZ.gameObject.transform.position;
            bl = goMinXMinZ.gameObject.transform.position;

            //store average y-offset for all anchors (gives user some leeway for error)... do we even need this?
            yOffset += tr.y - osctr.y;
            yOffset += bl.y - oscbl.y;
            yOffset  = yOffset * .5f;

            //IDEA 1b
            //determine offset between vXZOsc and anchor
            Vector3 vXZOffset = osctr - tr;

            //compare the "same" line, unrotated v rotated, to determine angle between
            Vector3 v1, v2;

            v1 = bl - tr;                       //rotated
            v2 = oscbl - osctr;                 //unrotated
            //align the height values
            v1.y = v2.y;

            rot = Vector3.Angle(v1, v2);                //does this return a signed value? NOPE
            Vector3 cross = Vector3.Cross(v1, v2);

            if (cross.y < 0)
            {
                rot = -rot;                             //hope this works
            }
            //rotate world center around this angle (how do I know which direction, does this matter?
            //optitrackCenter.transform.rotation = Quaternion.Euler(0, -rot, 0);

            //rotate the optitrack XZ over the same angle
            Vector3 rotatedXZ = Quaternion.Euler(0, -rot, 0) * osctr;

            //subtract this from XZ Object position to get "real center" and position world center there
            center = tr - rotatedXZ * (v1.magnitude / v2.magnitude);             //take scale diff into account

            //apply scale
            //OptiTrackOSCClient oscClient = optitrackCenter.GetComponent<OptiTrackOSCClient>();
            //oscClient.scale = (v1.magnitude / v2.magnitude);
            scale = (v1.magnitude / v2.magnitude);

            return(true);
        }