private Vector2 GetClosestMouseHit()
    {
        foreach (Camera camera in m_Cameras)
        {
            Ray          ray = camera.ScreenPointToRay(Input.mousePosition);
            VRRaycastHit hit = RaycastMesh(ray.origin, ray.direction);
            if (hit != null)
            {
                return(hit.textureCoord);
            }
        }

        return(new Vector2(-1, -1));
    }
    public VRRaycastHit RaycastMesh(Vector3 rayOrigin, Vector3 rayDirection)
    {
        for (int i = 0; i < m_RaycastMeshTriangles.Length; i += 3)
        {
            int i0 = m_RaycastMeshTriangles[i];
            int i1 = m_RaycastMeshTriangles[i + 1];
            int i2 = m_RaycastMeshTriangles[i + 2];

            VRRaycastHit raycastHit = _RaycastTriangle(i0, i1, i2, rayOrigin, rayDirection);

            if (raycastHit != null)
            {
                return(raycastHit);
            }
        }

        return(null);
    }
    private VRRaycastHit _RaycastTriangle(int i0, int i1, int i2, Vector3 rayOrigin, Vector3 rayDirection)
    {
        Vector3 p0 = transform.TransformPoint(m_RaycastMeshVertices[i0]);
        Vector3 p1 = transform.TransformPoint(m_RaycastMeshVertices[i1]);
        Vector3 p2 = transform.TransformPoint(m_RaycastMeshVertices[i2]);

        // Möller–Trumbore intersection algorithm
        // http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm

        // edge 1
        Vector3 E1 = p1 - p0;

        // edge 2
        Vector3 E2 = p2 - p0;

        // edge 3 - only for testing degenerate triangles
        Vector3 E3 = p2 - p0;

        if (E1.sqrMagnitude < 0.00001f || E2.sqrMagnitude < 0.00001f || E3.sqrMagnitude < 0.00001f)
        {
            // Skip degenerate triangle
            return(null);
        }

        //Begin calculating determinant - also used to calculate u parameter
        Vector3 P   = Vector3.Cross(rayDirection, E2);
        float   det = Vector3.Dot(E1, P);

        if (det > -0.00001f && det < 0.00001f)
        {
            //if determinant is near zero, ray lies in plane of triangle
            return(null);
        }

        float inv_det = 1.0f / det;
        //Calculate distance from V1 to ray origin
        Vector3 T = rayOrigin - p0;
        //Calculate u parameter and test bound
        float u = Vector3.Dot(T, P) * inv_det;

        if (u < 0.0f || u > 1.0f)
        {
            //The intersection lies outside of the triangle
            return(null);
        }

        //Prepare to test v parameter
        Vector3 Q = Vector3.Cross(T, E1);
        //Calculate V parameter and test bound
        float v = Vector3.Dot(rayDirection, Q) * inv_det;

        if (v < 0.0f || u + v > 1.0f)
        {
            //The intersection lies outside of the triangle
            return(null);
        }

        float t = Vector3.Dot(E2, Q) * inv_det;

        if (t <= 0.00001f)
        {
            // Intersection is before origin
            return(null);
        }

        // We have an intersection, now compute uv

        Vector3 hitPoint = rayOrigin + (rayDirection * t);

        Vector3 w = hitPoint - p0;

        Vector3 vCrossW = Vector3.Cross(E2, w);
        Vector3 vCrossU = Vector3.Cross(E2, E1);

        if (Vector3.Dot(vCrossW, vCrossU) < 0.0f)
        {
            return(null);
        }

        Vector3 uCrossW = Vector3.Cross(E1, w);
        Vector3 uCrossV = Vector3.Cross(E1, E2);

        if (Vector3.Dot(uCrossW, uCrossV) < 0.0f)
        {
            return(null);
        }

        float denom = uCrossV.magnitude;
        float b1    = vCrossW.magnitude / denom;
        float b2    = uCrossW.magnitude / denom;

        if ((b1 <= 1.0f) && (b2 <= 1.0f) && (b1 + b2 <= 1.0f))
        {
            float   b0  = 1.0f - b1 - b2;
            Vector2 uv0 = m_RaycastMeshUV[i0];
            Vector2 uv1 = m_RaycastMeshUV[i1];
            Vector2 uv2 = m_RaycastMeshUV[i2];
            Vector2 uv  = new Vector2(b0 * uv0.x + b1 * uv1.x + b2 * uv2.x, b0 * uv0.y + b1 * uv1.y + b2 * uv2.y);

            VRRaycastHit raycastHit = new VRRaycastHit();
            raycastHit.collider     = GetComponent <Collider>();
            raycastHit.distance     = t;
            raycastHit.normal       = vCrossU.normalized;
            raycastHit.point        = hitPoint;
            raycastHit.textureCoord = uv;
            return(raycastHit);
        }
        else
        {
            return(null);
        }
    }
Beispiel #4
0
    protected void _RaySelection()
    {
        // Ray picking
        Vector3 rayOrigin = transform.position;
        Vector3 rayDirection = transform.TransformDirection(Vector3.forward);

        VRSelection newSelection = null;

        foreach (RaycastHit raycastHit in Physics.RaycastAll(rayOrigin, rayDirection, m_Wand.GetDefaultRayLength()))
        {
            if (newSelection != null && raycastHit.distance >= newSelection.SelectionDistance)
            {
                continue;
            }

            GameObject objectHit = raycastHit.collider.gameObject;

            if (objectHit.name != "VRWand")
            {
                // Ignore GameObject without the VRActor component
                if (objectHit.GetComponent<VRActor>() == null)
                {
                    continue;
                }

                VRWebView webView = objectHit.GetComponent<VRWebView>();
                VRRaycastHit completeHit = null;
                if (webView != null)
                {
                    completeHit = webView.RaycastMesh(rayOrigin, rayDirection);
                }
                else
                {
                    completeHit = new VRRaycastHit(raycastHit);
                }

                if (completeHit != null)
                {
                    // Special case : pass through transparent pixels of web views.
                    if (webView != null)
                    {
                        if (!webView.GetComponent<Renderer>().enabled || webView.IsPixelEmpty(completeHit.textureCoord))
                        {
                            continue;
                        }
                    }

                    // Create selection if it does not exist
                    if (newSelection == null)
                    {
                        newSelection = new VRSelection();
                    }

                    newSelection.SourceWand = m_Wand;
                    newSelection.SelectedObject = objectHit;
                    newSelection.TextureCoordinate = completeHit.textureCoord;
                    newSelection.SelectionDistance = completeHit.distance;
                    newSelection.SelectionContact = completeHit.point;
                    newSelection.SelectionNormal = completeHit.normal;
                }
            }
        }

        m_LastSelection = m_SelectionMgr.GetSelection();
        m_SelectionMgr.SetSelection(newSelection);
    }
Beispiel #5
0
    private VRRaycastHit _RaycastTriangle(int i0, int i1, int i2, Vector3 rayOrigin, Vector3 rayDirection)
    {
        Vector3 p0 = transform.TransformPoint(m_RaycastMeshVertices[i0]);
        Vector3 p1 = transform.TransformPoint(m_RaycastMeshVertices[i1]);
        Vector3 p2 = transform.TransformPoint(m_RaycastMeshVertices[i2]);

        // Möller–Trumbore intersection algorithm
        // http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm

        // edge 1
        Vector3 E1 = p1 - p0;

        // edge 2
        Vector3 E2 = p2 - p0;

        // edge 3 - only for testing degenerate triangles
        Vector3 E3 = p2 - p0;
        if( E1.sqrMagnitude < 0.00001f || E2.sqrMagnitude < 0.00001f || E3.sqrMagnitude < 0.00001f )
        {
            // Skip degenerate triangle
            return null;
        }

        //Begin calculating determinant - also used to calculate u parameter
        Vector3 P = Vector3.Cross(rayDirection, E2);
        float det = Vector3.Dot(E1, P);
        if (det > -0.00001f && det < 0.00001f)
        {
            //if determinant is near zero, ray lies in plane of triangle
            return null;
        }

        float inv_det = 1.0f / det;
        //Calculate distance from V1 to ray origin
        Vector3 T = rayOrigin - p0;
        //Calculate u parameter and test bound
        float u = Vector3.Dot(T, P) * inv_det;
        if (u < 0.0f || u > 1.0f)
        {
            //The intersection lies outside of the triangle
            return null;
        }

        //Prepare to test v parameter
        Vector3 Q = Vector3.Cross(T, E1);
        //Calculate V parameter and test bound
        float v = Vector3.Dot(rayDirection, Q) * inv_det;
        if (v < 0.0f || u + v > 1.0f)
        {
            //The intersection lies outside of the triangle
            return null;
        }

        float t = Vector3.Dot(E2, Q) * inv_det;

        if (t <= 0.00001f)
        {
            // Intersection is before origin
            return null;
        }

        // We have an intersection, now compute uv

        Vector3 hitPoint = rayOrigin + (rayDirection * t);

        Vector3 w = hitPoint - p0;

        Vector3 vCrossW = Vector3.Cross(E2, w);
        Vector3 vCrossU = Vector3.Cross(E2, E1);

        if (Vector3.Dot(vCrossW, vCrossU) < 0.0f)
        {
            return null;
        }

        Vector3 uCrossW = Vector3.Cross(E1, w);
        Vector3 uCrossV = Vector3.Cross(E1, E2);

        if (Vector3.Dot(uCrossW, uCrossV) < 0.0f)
        {
            return null;
        }

        float denom = uCrossV.magnitude;
        float b1 = vCrossW.magnitude / denom;
        float b2 = uCrossW.magnitude / denom;

        if ((b1 <= 1.0f) && (b2 <= 1.0f) && (b1 + b2 <= 1.0f))
        {
            float b0 = 1.0f - b1 - b2;
            Vector2 uv0 = m_RaycastMeshUV[i0];
            Vector2 uv1 = m_RaycastMeshUV[i1];
            Vector2 uv2 = m_RaycastMeshUV[i2];
            Vector2 uv = new Vector2(b0 * uv0.x + b1 * uv1.x + b2 * uv2.x, b0 * uv0.y + b1 * uv1.y + b2 * uv2.y);

            VRRaycastHit raycastHit = new VRRaycastHit();
            raycastHit.collider = GetComponent<Collider>();
            raycastHit.distance = t;
            raycastHit.normal = vCrossU.normalized;
            raycastHit.point = hitPoint;
            raycastHit.textureCoord = uv;
            return raycastHit;
        }
        else
        {
            return null;
        }
    }
Beispiel #6
0
    protected void _RaySelection()
    {
        // Ray picking
        Vector3 rayOrigin    = transform.position;
        Vector3 rayDirection = transform.TransformDirection(Vector3.forward);

        VRSelection newSelection = null;

        foreach (RaycastHit raycastHit in Physics.RaycastAll(rayOrigin, rayDirection, m_Wand.GetDefaultRayLength()))
        {
            if (newSelection != null && raycastHit.distance >= newSelection.SelectionDistance)
            {
                continue;
            }

            GameObject objectHit = raycastHit.collider.gameObject;

            if (objectHit.name != "VRWand")
            {
                // Ignore GameObject without the VRActor component
                if (objectHit.GetComponent <VRActor>() == null)
                {
                    continue;
                }

                VRWebView    webView     = objectHit.GetComponent <VRWebView>();
                VRRaycastHit completeHit = null;
                if (webView != null)
                {
                    completeHit = webView.RaycastMesh(rayOrigin, rayDirection);
                }
                else
                {
                    completeHit = new VRRaycastHit(raycastHit);
                }

                if (completeHit != null)
                {
                    // Special case : pass through transparent pixels of web views.
                    if (webView != null)
                    {
                        if (!webView.GetComponent <Renderer>().enabled || webView.IsPixelEmpty(completeHit.textureCoord))
                        {
                            continue;
                        }
                    }

                    // Create selection if it does not exist
                    if (newSelection == null)
                    {
                        newSelection = new VRSelection();
                    }

                    newSelection.SourceWand        = m_Wand;
                    newSelection.SelectedObject    = objectHit;
                    newSelection.TextureCoordinate = completeHit.textureCoord;
                    newSelection.SelectionDistance = completeHit.distance;
                    newSelection.SelectionContact  = completeHit.point;
                    newSelection.SelectionNormal   = completeHit.normal;
                }
            }
        }

        m_LastSelection = m_SelectionMgr.GetSelection();
        m_SelectionMgr.SetSelection(newSelection);
    }