Exemplo n.º 1
0
        public static bool Raycast(Ray ray, out float t, Vector3 p0, Vector3 p1, Vector3 p2, TriangleEpsilon epsilon = new TriangleEpsilon())
        {
            t = 0.0f;

            float rayEnter;
            Plane trianglePlane = new Plane(p0, p1, p2);

            if (trianglePlane.Raycast(ray, out rayEnter) &&
                Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2, epsilon))
            {
                t = rayEnter;
                return(true);
            }

            if (epsilon.ExtrudeEps != 0.0f)
            {
                float dot = Vector3Ex.AbsDot(ray.direction, trianglePlane.normal);
                if (dot < ExtrudeEpsThreshold.Get)
                {
                    OOBB oobb = Calc3DTriangleOOBB(p0, p1, p2, trianglePlane.normal, epsilon);
                    return(BoxMath.Raycast(ray, oobb.Center, oobb.Size, oobb.Rotation));
                }
            }

            return(false);
        }
Exemplo n.º 2
0
        public static bool Raycast(Ray ray, out float t, Vector3 quadCenter, float quadWidth, float quadHeight, Vector3 quadRight, Vector3 quadUp, QuadEpsilon epsilon = new QuadEpsilon())
        {
            t = 0.0f;
            Vector3 quadNormal = Vector3.Normalize(Vector3.Cross(quadRight, quadUp));
            Plane   quadPlane  = new Plane(quadNormal, quadCenter);

            float rayEnter;

            if (quadPlane.Raycast(ray, out rayEnter) &&
                Contains3DPoint(ray.GetPoint(rayEnter), false, quadCenter, quadWidth, quadHeight, quadRight, quadUp, epsilon))
            {
                t = rayEnter;
                return(true);
            }

            if (epsilon.ExtrudeEps != 0.0f)
            {
                float dot = Vector3Ex.AbsDot(ray.direction, quadPlane.normal);
                if (dot < ExtrudeEpsThreshold.Get)
                {
                    OOBB quadOOBB = Calc3DQuadOOBB(quadCenter, new Vector2(quadWidth, quadHeight), Quaternion.LookRotation(quadNormal, quadUp), epsilon);
                    return(BoxMath.Raycast(ray, quadOOBB.Center, quadOOBB.Size, quadOOBB.Rotation));
                }
            }

            return(false);
        }
Exemplo n.º 3
0
        public static bool RaycastWire(Ray ray, out float t, Vector3 quadCenter, float quadWidth, float quadHeight, Vector3 quadRight, Vector3 quadUp, QuadEpsilon epsilon = new QuadEpsilon())
        {
            t = 0.0f;
            Vector3    quadNormal   = Vector3.Normalize(Vector3.Cross(quadRight, quadUp));
            Plane      quadPlane    = new Plane(quadNormal, quadCenter);
            Vector2    quadSize     = new Vector2(quadWidth, quadHeight);
            Quaternion quadRotation = Quaternion.LookRotation(quadNormal, quadUp);

            float rayEnter;

            if (quadPlane.Raycast(ray, out rayEnter))
            {
                Vector3 intersectPt  = ray.GetPoint(rayEnter);
                var     cornerPoints = Calc3DQuadCornerPoints(quadCenter, quadSize, quadRotation);

                float distFromSegment = intersectPt.GetDistanceToSegment(cornerPoints[(int)QuadCorner.TopLeft], cornerPoints[(int)QuadCorner.TopRight]);
                if (distFromSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distFromSegment = intersectPt.GetDistanceToSegment(cornerPoints[(int)QuadCorner.TopRight], cornerPoints[(int)QuadCorner.BottomRight]);
                if (distFromSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distFromSegment = intersectPt.GetDistanceToSegment(cornerPoints[(int)QuadCorner.BottomRight], cornerPoints[(int)QuadCorner.BottomLeft]);
                if (distFromSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distFromSegment = intersectPt.GetDistanceToSegment(cornerPoints[(int)QuadCorner.BottomLeft], cornerPoints[(int)QuadCorner.TopLeft]);
                if (distFromSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }
            }

            if (epsilon.ExtrudeEps != 0.0f)
            {
                float dot = Vector3Ex.AbsDot(ray.direction, quadPlane.normal);
                if (dot < ExtrudeEpsThreshold.Get)
                {
                    OOBB quadOOBB = Calc3DQuadOOBB(quadCenter, quadSize, Quaternion.LookRotation(quadNormal, quadUp), epsilon);
                    return(BoxMath.Raycast(ray, quadOOBB.Center, quadOOBB.Size, quadOOBB.Rotation));
                }
            }

            return(false);
        }
Exemplo n.º 4
0
        public GameObjectRayHit RaycastSpriteObject(Ray ray, GameObject gameObject)
        {
            float t;
            OOBB  worldOOBB = ObjectBounds.CalcSpriteWorldOOBB(gameObject);

            if (!worldOOBB.IsValid)
            {
                return(null);
            }

            if (BoxMath.Raycast(ray, out t, worldOOBB.Center, worldOOBB.Size, worldOOBB.Rotation))
            {
                return(new GameObjectRayHit(ray, gameObject, worldOOBB.GetPointFaceNormal(ray.GetPoint(t)), t));
            }

            return(null);
        }
Exemplo n.º 5
0
        public static bool RaycastWire(Ray ray, out float t, Vector3 p0, Vector3 p1, Vector3 p2, TriangleEpsilon epsilon = new TriangleEpsilon())
        {
            t = 0.0f;

            float rayEnter;
            Plane trianglePlane = new Plane(p0, p1, p2);

            if (trianglePlane.Raycast(ray, out rayEnter))
            {
                Vector3 intersectPt   = ray.GetPoint(rayEnter);
                float   distToSegment = intersectPt.GetDistanceToSegment(p0, p1);
                if (distToSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distToSegment = intersectPt.GetDistanceToSegment(p1, p2);
                if (distToSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distToSegment = intersectPt.GetDistanceToSegment(p2, p0);
                if (distToSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }
            }

            if (epsilon.ExtrudeEps != 0.0f)
            {
                float dot = Vector3Ex.AbsDot(ray.direction, trianglePlane.normal);
                if (dot < ExtrudeEpsThreshold.Get)
                {
                    OOBB oobb = Calc3DTriangleOOBB(p0, p1, p2, trianglePlane.normal, epsilon);
                    return(BoxMath.Raycast(ray, oobb.Center, oobb.Size, oobb.Rotation));
                }
            }

            return(false);
        }
Exemplo n.º 6
0
        public List <GameObjectRayHit> RaycastAll(Ray ray, SceneRaycastPrecision raycastPresicion)
        {
            var nodeHits = _objectTree.RaycastAll(ray);

            if (nodeHits.Count == 0)
            {
                return(new List <GameObjectRayHit>());
            }

            var boundsQConfig = new ObjectBounds.QueryConfig();

            boundsQConfig.ObjectTypes  = GameObjectTypeHelper.AllCombined;
            boundsQConfig.NoVolumeSize = EditorScene.Get.NoVolumeObjectSize;

            if (raycastPresicion == SceneRaycastPrecision.BestFit)
            {
                var hitList = new List <GameObjectRayHit>(10);
                foreach (var nodeHit in nodeHits)
                {
                    GameObject sceneObject = nodeHit.HitNode.Data;
                    if (sceneObject == null || !sceneObject.activeInHierarchy)
                    {
                        continue;
                    }

                    Renderer renderer = sceneObject.GetComponent <Renderer>();
                    if (renderer != null && !renderer.isVisible)
                    {
                        continue;
                    }

                    GameObjectType objectType = sceneObject.GetGameObjectType();
                    if (objectType == GameObjectType.Mesh)
                    {
                        GameObjectRayHit objectHit = RaycastMeshObject(ray, sceneObject);
                        if (objectHit != null)
                        {
                            hitList.Add(objectHit);
                        }
                    }
                    else
                    if (objectType == GameObjectType.Terrain)
                    {
                        TerrainCollider terrainCollider = sceneObject.GetComponent <TerrainCollider>();
                        if (terrainCollider != null)
                        {
                            RaycastHit hitInfo;
                            if (terrainCollider.Raycast(ray, out hitInfo, float.MaxValue))
                            {
                                hitList.Add(new GameObjectRayHit(ray, hitInfo));
                            }
                        }
                    }
                    else
                    if (objectType == GameObjectType.Sprite)
                    {
                        GameObjectRayHit objectHit = RaycastSpriteObject(ray, sceneObject);
                        if (objectHit != null)
                        {
                            hitList.Add(objectHit);
                        }
                    }
                    else
                    {
                        OOBB worldOOBB = ObjectBounds.CalcWorldOOBB(sceneObject, boundsQConfig);
                        if (worldOOBB.IsValid)
                        {
                            float t;
                            if (BoxMath.Raycast(ray, out t, worldOOBB.Center, worldOOBB.Size, worldOOBB.Rotation))
                            {
                                var faceDesc = BoxMath.GetFaceClosestToPoint(ray.GetPoint(t), worldOOBB.Center, worldOOBB.Size, worldOOBB.Rotation);
                                var hit      = new GameObjectRayHit(ray, sceneObject, faceDesc.Plane.normal, t);
                                hitList.Add(hit);
                            }
                        }
                    }
                }

                return(hitList);
            }
            else
            if (raycastPresicion == SceneRaycastPrecision.Box)
            {
                var hitList = new List <GameObjectRayHit>(10);
                foreach (var nodeHit in nodeHits)
                {
                    GameObject sceneObject = nodeHit.HitNode.Data;
                    if (sceneObject == null || !sceneObject.activeInHierarchy)
                    {
                        continue;
                    }

                    Renderer renderer = sceneObject.GetComponent <Renderer>();
                    if (renderer != null && !renderer.isVisible)
                    {
                        continue;
                    }

                    OOBB worldOOBB = ObjectBounds.CalcWorldOOBB(sceneObject, boundsQConfig);
                    if (worldOOBB.IsValid)
                    {
                        float t;
                        if (BoxMath.Raycast(ray, out t, worldOOBB.Center, worldOOBB.Size, worldOOBB.Rotation))
                        {
                            var faceDesc = BoxMath.GetFaceClosestToPoint(ray.GetPoint(t), worldOOBB.Center, worldOOBB.Size, worldOOBB.Rotation);
                            var hit      = new GameObjectRayHit(ray, sceneObject, faceDesc.Plane.normal, t);
                            hitList.Add(hit);
                        }
                    }
                }

                return(hitList);
            }

            return(new List <GameObjectRayHit>());
        }