Пример #1
0
    void _findHandFromVerticesUpdate2(int[] triangles, Vector3[] vertices, out Vector3 outNearPoint, out Vector3 outFarPoint, out Quaternion handRot)
    {
        //handSize = 0;
        if (_colliderHandMeshes != null)
        {
            _colliderHandMeshes.sharedMesh.Clear();
        }

        Vector3 newNearPoint, newFarPoint;

        //MyHelpMesh.GetLineFromVertices(null, vertices, out newNearPoint, out newFarPoint);

        //get 10 point which is nearest with camera plane
        findHandDataList.Clear();
        Vector3 localEyePos = SRWorkControl.Instance.viveSR.transform.InverseTransformPoint(SRWorkControl.Instance.eye.position);
        Vector3 localEyeDir = SRWorkControl.Instance.viveSR.transform.InverseTransformDirection(SRWorkControl.Instance.eye.forward);

        Vector3 cameraNormal = localEyeDir;
        //cameraNormal.y = 0; cameraNormal.Normalize();
        Plane cameraPlane = new Plane(cameraNormal, localEyePos);

        byte[] colorRGB = null;
        tempVertices.Clear();
        if (considerSkinColor)
        {
            int vid = 0;
            colorRGB = _getDummyLeftTex();
            foreach (Vector3 v in vertices)
            {
                if (IsSkinColorVert(v, colorRGB))
                {
                    tempVertices.Add(vertices[vid]);
                }
                vid++;
            }

            if (renderSkinVert)
            {
                Texture2D tex = ViveSR_DualCameraRig.Instance.DualCameraImageRenderer.UndistortedLeft[0].mainTexture as Texture2D;
                tex.LoadRawTextureData(_dummyLeftTex);
                tex.Apply();

                //byte[] bytes = tex.EncodeToJPG();
                //System.IO.File.WriteAllBytes("d:/234.jpg", bytes);
                //UnityEditor.EditorApplication.isPaused = true;
            }
        }
        else
        {
            tempVertices.AddRange(vertices);
        }

        //consider nearest from all dynamic vertices
        //foreach (Vector3 v in vertices)
        foreach (Vector3 v in tempVertices)
        {
            //limit nearest not too high
            if (Mathf.Abs(v.y - localEyePos.y) > 0.4f)
            {
                continue;
            }

            FindHandData data = new FindHandData();
            data.cameraPlaneDis = cameraPlane.GetDistanceToPoint(v);
            data.vert           = v;
            findHandDataList.Add(data);
        }
        findHandDataList.Sort();

        //get the closest points.
        float        nearestDis  = 99999;
        FindHandData nearestData = null;

        for (int a = 0; a < 10; a++)
        {
            if (a == findHandDataList.Count)
            {
                break;
            }
            float sqrDis = (findHandDataList[a].vert - localEyePos).sqrMagnitude;
            if (sqrDis < nearestDis)
            {
                nearestDis  = sqrDis;
                nearestData = findHandDataList[a];
            }
        }

        if (nearestData == null)
        {
            outNearPoint = oldNearPoint;
            outFarPoint  = oldFarPoint;
            handRot      = Quaternion.identity;
            return;
        }

        newNearPoint = nearestData.vert;

        //get 10 point which is farest with camera plane
        findHandDataList.Clear();
        foreach (Vector3 v in tempVertices)//get farest point from skin color vertices
        {
            //limit farest not too high
            if (Mathf.Abs(v.y - localEyePos.y) > 0.5f)
            {
                continue;
            }

            FindHandData data = new FindHandData();
            data.cameraPlaneDis = cameraPlane.GetDistanceToPoint(v);
            data.vert           = v;
            findHandDataList.Add(data);
        }
        findHandDataList.Sort();

        //get the point which is farest from newNearPoint
        float maxDis = 0;

        newFarPoint = newNearPoint;
        for (int a = 0; a < findHandDataList.Count; a++)
        {
            //  if (a == 10)//there are too many other point, so cannot limit the amount
            //      break;

            FindHandData data = findHandDataList[findHandDataList.Count - a - 1];

            float sqrDis = (data.vert - newNearPoint).sqrMagnitude;
            //float dddd = (data.vert - newNearPoint).magnitude;
            if (sqrDis > maxDis && sqrDis < 0.5f * 0.5f)
            {
                maxDis      = sqrDis;
                newFarPoint = data.vert;
            }
        }

        //fix the hand direction by camera forward
        Vector3 newDirection = newFarPoint - newNearPoint;

        if (Vector3.Dot(localEyeDir, newDirection.normalized) < 0)
        {
            Vector3 rec = newNearPoint;
            newNearPoint = newFarPoint;
            newFarPoint  = rec;
        }

        newNearPoint = Vector3.Lerp(oldNearPoint, newNearPoint, lowPassRatio);
        newFarPoint  = Vector3.Lerp(oldFarPoint, newFarPoint, lowPassRatio);

        //save old position
        oldFarPoint  = newFarPoint;
        oldNearPoint = newNearPoint;

        //get hand size in range
        //float handSize = 0;
        List <int>     handIB = new List <int>();
        List <Vector3> handVB = new List <Vector3>();
        int            count  = 0;

        for (int a = 0; a < triangles.Length; a += 3)
        {
            Vector3 vA = vertices[triangles[a + 0]];
            Vector3 vB = vertices[triangles[a + 1]];
            Vector3 vC = vertices[triangles[a + 2]];

            //if (considerSkinColor)
            //{
            //    if (!IsSkinColorVert(vA, colorRGB) &&
            //       !IsSkinColorVert(vB, colorRGB) &&
            //       !IsSkinColorVert(vC, colorRGB)
            //        )
            //        continue;
            //}

            Vector3 dA = newFarPoint - vA;
            Vector3 dB = newFarPoint - vB;
            Vector3 dC = newFarPoint - vC;

            if (
                dA.sqrMagnitude < handSizeRange * handSizeRange ||
                dB.sqrMagnitude < handSizeRange * handSizeRange ||
                dC.sqrMagnitude < handSizeRange * handSizeRange)
            {
                //get area
                //https://answers.unity.com/questions/291923/area-of-a-triangle-this-code-seems-to-work-why.html
                //Vector3 V = Vector3.Cross(vA - vB, vA - vC);
                //handSize += V.magnitude * 0.5f;

                handVB.Add(vA);
                handVB.Add(vB);
                handVB.Add(vC);

                handIB.Add(count + 0);
                handIB.Add(count + 1);
                handIB.Add(count + 2);
                count += 3;
            }
        }

        //recalculate far point
        if (handVB.Count > 0)
        {
            newFarPoint = Vector3.zero;
            foreach (Vector3 v in handVB)
            {
                newFarPoint += v;
            }
            newFarPoint /= handVB.Count;
        }

        //set point to world coordinate
        HandFar  = outFarPoint = newFarPoint;   // + SRWorkControl.Instance.viveSR.transform.position;
        HandNear = outNearPoint = newNearPoint; // + SRWorkControl.Instance.viveSR.transform.position;
        handRot  = Quaternion.identity;

        if (showHand)
        {
            _colliderHandMeshes.sharedMesh.Clear();
            if (handVB.Count > 0)
            {
                for (int a = 0; a < handVB.Count; a++)
                {
                    handVB[a] += SRWorkControl.Instance.viveSR.transform.position;
                }
                _colliderHandMeshes.sharedMesh.SetVertices(handVB);
                _colliderHandMeshes.sharedMesh.SetIndices(handIB.ToArray(), MeshTopology.Triangles, 0);
                _colliderHandMeshRenderer.material.color = farDebugColor;
            }
            _colliderHandObjs.GetComponent <MeshRenderer>().enabled    = true;
            _getDynamicScanObj().GetComponent <MeshRenderer>().enabled = false;
        }
        else
        {
            _colliderHandObjs.GetComponent <MeshRenderer>().enabled    = false;
            _getDynamicScanObj().GetComponent <MeshRenderer>().enabled = true;
        }


        _showDebug.gameObject.SetActive(false);
        if (Debug.isDebugBuild && DebugShow)
        {
            if (nearDebug == null)
            {
                nearDebug = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            }
            if (farDebug == null)
            {
                farDebug = GameObject.CreatePrimitive(PrimitiveType.Cube);
            }
            nearDebug.transform.localScale = Vector3.one * 0.05f;
            farDebug.transform.localScale  = Vector3.one * 0.05f;
            //Vector3.Lerp(Vector3.one * handSize, farDebug.transform.localScale, 0.1f);

            nearDebug.transform.position = outNearPoint + SRWorkControl.Instance.viveSR.transform.position;
            farDebug.transform.position  = outFarPoint + SRWorkControl.Instance.viveSR.transform.position;
            nearDebug.GetComponent <Renderer>().material.color = Color.red;
            farDebug.GetComponent <Renderer>().material.color  = Color.red;

            Destroy(nearDebug.GetComponent <Collider>());
            Destroy(farDebug.GetComponent <Collider>());

            float farDis = cameraPlane.GetDistanceToPoint(HandFar);

            _showDebug.gameObject.SetActive(true);
            _showDebug.text =
                //"handSize : " + handSize + Environment.NewLine +
                "farDis : " + farDis;
        }
    }
Пример #2
0
    void _findHandFromVerticesUpdate2(int[] triangles, Vector3[] vertices, out Vector3 outNearPoint, out Vector3 outFarPoint, out Quaternion handRot)
    {
        Vector3 newNearPoint, newFarPoint;

        //MyHelpMesh.GetLineFromVertices(null, vertices, out newNearPoint, out newFarPoint);

        //get 10 point which is nearest with camera plane
        findHandDataList.Clear();
        Vector3 localEyePos = SRWorksHand.Instance.viveSR.transform.InverseTransformPoint(SRWorksHand.Instance.eye.position);
        Vector3 localEyeDir = SRWorksHand.Instance.viveSR.transform.InverseTransformDirection(SRWorksHand.Instance.eye.forward);

        Vector3 cameraNormal = localEyeDir;
        //cameraNormal.y = 0; cameraNormal.Normalize();
        Plane cameraPlane = new Plane(cameraNormal, localEyePos);

        foreach (Vector3 v in vertices)
        {
            //limit nearest not too high
            if (Mathf.Abs(v.y - localEyePos.y) > 0.4f)
            {
                continue;
            }

            FindHandData data = new FindHandData();
            data.cameraPlaneDis = cameraPlane.GetDistanceToPoint(v);
            data.vert           = v;
            findHandDataList.Add(data);
        }
        findHandDataList.Sort();

        //get the closest points.
        float        nearestDis  = 99999;
        FindHandData nearestData = null;

        for (int a = 0; a < 10; a++)
        {
            if (a == findHandDataList.Count)
            {
                break;
            }
            float sqrDis = (findHandDataList[a].vert - localEyePos).sqrMagnitude;
            if (sqrDis < nearestDis)
            {
                nearestDis  = sqrDis;
                nearestData = findHandDataList[a];
            }
        }

        if (nearestData == null)
        {
            outNearPoint = oldNearPoint;
            outFarPoint  = oldFarPoint;
            handRot      = Quaternion.identity;
            return;
        }

        newNearPoint = nearestData.vert;

        //get 10 point which is farest with camera plane
        findHandDataList.Clear();
        foreach (Vector3 v in vertices)
        {
            //limit farest not too high
            if (Mathf.Abs(v.y - localEyePos.y) > 0.5f)
            {
                continue;
            }

            FindHandData data = new FindHandData();
            data.cameraPlaneDis = cameraPlane.GetDistanceToPoint(v);
            data.vert           = v;
            findHandDataList.Add(data);
        }
        findHandDataList.Sort();

        //get the point which is farthest from newNearPoint
        float maxDis = 0;

        newFarPoint = newNearPoint;
        for (int a = 0; a < findHandDataList.Count; a++)
        {
            //  if (a == 10)//there are too many other point, so cannot limit the head amount
            //      break;

            FindHandData data = findHandDataList[findHandDataList.Count - a - 1];

            float sqrDis = (data.vert - newNearPoint).sqrMagnitude;
            //float dddd = (data.vert - newNearPoint).magnitude;
            if (sqrDis > maxDis && sqrDis < 0.5f * 0.5f)
            {
                maxDis      = sqrDis;
                newFarPoint = data.vert;
            }
        }

        Vector3 newDirection = newFarPoint - newNearPoint;

        if (Vector3.Dot(localEyeDir, newDirection.normalized) < 0)
        {
            Vector3 rec = newNearPoint;
            newNearPoint = newFarPoint;
            newFarPoint  = rec;
        }

        newNearPoint = Vector3.Lerp(oldNearPoint, newNearPoint, dynamicHandDisDivided);
        newFarPoint  = Vector3.Lerp(oldFarPoint, newFarPoint, dynamicHandDisDivided);

        //save old position
        oldFarPoint  = newFarPoint;
        oldNearPoint = newNearPoint;

        //get hand direction
        //Vector3 handPoint;
        //if (MyHelpMesh.GetLongestPointInRange(vertices, newFarPoint, 0.1f, out handPoint))
        //{
        //    Vector3 handDir = handPoint - newFarPoint;
        //    handDir.Normalize();
        //    handRot = Quaternion.LookRotation(-handDir, Vector3.up);
        //    handRot = Quaternion.Slerp(oldHandRot, handRot, dynamicHandDisDivided);
        //    oldHandRot = handRot;
        //}

        //get hand size in range
        //float handSize = 0;
        List <int>     handIB = new List <int>();
        List <Vector3> handVB = new List <Vector3>();
        int            count  = 0;

        for (int a = 0; a < triangles.Length; a += 3)
        {
            Vector3 vA = vertices[triangles[a + 0]];
            Vector3 vB = vertices[triangles[a + 1]];
            Vector3 vC = vertices[triangles[a + 2]];
            Vector3 dA = newFarPoint - vA;
            Vector3 dB = newFarPoint - vB;
            Vector3 dC = newFarPoint - vC;

            if (
                dA.sqrMagnitude < handSizeRange * handSizeRange ||
                dB.sqrMagnitude < handSizeRange * handSizeRange ||
                dC.sqrMagnitude < handSizeRange * handSizeRange)
            {
                //get area
                //https://answers.unity.com/questions/291923/area-of-a-triangle-this-code-seems-to-work-why.html
                //Vector3 V = Vector3.Cross(vA - vB, vA - vC);
                // handSize += V.magnitude * 0.5f;

                handVB.Add(vA + SRWorksHand.Instance.viveSR.transform.position);
                handVB.Add(vB + SRWorksHand.Instance.viveSR.transform.position);
                handVB.Add(vC + SRWorksHand.Instance.viveSR.transform.position);

                handIB.Add(count + 0);
                handIB.Add(count + 1);
                handIB.Add(count + 2);
                count += 3;
            }
        }

        //recalculate far point
        if (handVB.Count > 0)
        {
            newFarPoint = Vector3.zero;
            foreach (Vector3 v in handVB)
            {
                newFarPoint += v - SRWorksHand.Instance.viveSR.transform.position;
            }
            newFarPoint /= handVB.Count;
        }

        //set point to world coordinate
        _OutFar  = outFarPoint = newFarPoint;   // + SRWorkHand.Instance.viveSR.transform.position;
        _OutNear = outNearPoint = newNearPoint; // + SRWorkHand.Instance.viveSR.transform.position;
        handRot  = Quaternion.identity;

        if (showHandMesh)
        {
            ColliderMeshes.sharedMesh.Clear();
            if (handVB.Count > 0)
            {
                ColliderMeshes.sharedMesh.SetVertices(handVB);
                ColliderMeshes.sharedMesh.SetIndices(handIB.ToArray(), MeshTopology.Triangles, 0);
            }
            ColliderObjs.GetComponent <MeshRenderer>().enabled     = true;
            GetDynamicHand().GetComponent <MeshRenderer>().enabled = true;
        }
        else
        {
            ColliderObjs.GetComponent <MeshRenderer>().enabled     = false;
            GetDynamicHand().GetComponent <MeshRenderer>().enabled = false;
        }

        _showDebug.gameObject.SetActive(false);
        if (Debug.isDebugBuild && DebugShow)
        {
            if (nearDebug == null)
            {
                nearDebug = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            }
            if (farDebug == null)
            {
                farDebug = GameObject.CreatePrimitive(PrimitiveType.Cube);
            }
            nearDebug.transform.localScale = Vector3.one * 0.05f;
            farDebug.transform.localScale  = Vector3.one * 0.05f;
            //Vector3.Lerp(Vector3.one * handSize, farDebug.transform.localScale, 0.1f);

            nearDebug.transform.position = outNearPoint + SRWorksHand.Instance.viveSR.transform.position;
            farDebug.transform.position  = outFarPoint + SRWorksHand.Instance.viveSR.transform.position;
            nearDebug.GetComponent <Renderer>().material.color = Color.red;
            farDebug.GetComponent <Renderer>().material.color  = Color.green;

            Destroy(nearDebug.GetComponent <Collider>());
            Destroy(farDebug.GetComponent <Collider>());

            float farDis = cameraPlane.GetDistanceToPoint(_OutFar);

            _showDebug.gameObject.SetActive(true);
            _showDebug.text =
                //"handSize : " + handSize + Environment.NewLine +
                "farDis : " + farDis;
        }
    }