/// <summary>
 /// Casts a ray hitting all entities specified with the entityFlags. Returns true if an entity is hit, otherwise false.
 /// If a hit is registered details about the hit are returned in raycastHit.
 /// </summary>
 /// <param name="ray"></param>
 /// <param name="entityFlags"></param>
 /// <param name="raycastHit"></param>
 /// <param name="skipList"></param>
 /// <returns></returns>
 public static bool Raycast(Ray ray, EntityRaycastFlags entityFlags, out RaycastHit raycastHit, params PhysicsEntity[] skipList)
 {
     return(Raycast(ray.Origin, ray.Direction, ray.Length, entityFlags, out raycastHit, skipList));
 }
        /// <summary>
        /// Casts a ray starting from origin going along direction up until the maxDistance is reached, meanwhile hitting all entities specified by entityFlags.
        /// Returns true if an entity is hit, otherwise false. If a hit is registered details about the hit are returned in raycastHit.
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="direction"></param>
        /// <param name="maxDistance"></param>
        /// <param name="entityFlags"></param>
        /// <param name="raycastHit"></param>
        /// <param name="skipList"></param>
        /// <returns></returns>
        public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance, EntityRaycastFlags entityFlags, out RaycastHit raycastHit, params PhysicsEntity[] skipList)
        {
            raycastHit = default(RaycastHit);

            var magnitude = direction.Dot(direction);

            if (magnitude > 1.0f || magnitude < 1.0f)
            {
                direction = direction.Normalized;
            }

            var rayParams = new IPhysicalWorld.SRWIParams();

            rayParams.org      = origin;
            rayParams.dir      = direction * maxDistance;
            rayParams.objtypes = (int)entityFlags;
            rayParams.flags    = DefaultRaycastFlags;
            rayParams.nMaxHits = 1;
            rayParams.hits     = new ray_hit();

            if (skipList != null && skipList.Length > 0)
            {
                rayParams.AllocateSkipEnts(skipList.Length);

                for (int i = 0; i < skipList.Length; ++i)
                {
                    rayParams.SetSkipEnt(i, skipList[i].NativeHandle);
                }
            }
            else
            {
                rayParams.AllocateSkipEnts(0);
            }

            var hits = Global.gEnv.pPhysicalWorld.RayWorldIntersection(rayParams);

            if (hits > 0)
            {
                var   hit = rayParams.hits;
                float u   = 0;
                float v   = 0;

                var entityId = Global.gEnv.pRenderer.GetDetailedRayHitInfo(hit.pCollider, origin, direction, maxDistance, ref u, ref v);

                raycastHit = new RaycastHit
                {
                    EntityId = entityId,
                    UvPoint  = new Vec2(u, v)
                };
                RaycastHit.FromNativeHit(ref raycastHit, hit);
            }
            rayParams.DeleteSkipEnts();
            return(hits > 0);
        }
        /// <summary>
        /// Casts a ray starting from origin going along direction up until the maxDistance is reached, meanwhile hitting all entities specified by entityFlags.
        /// Returns true if an entity is hit, otherwise false.
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="direction"></param>
        /// <param name="maxDistance"></param>
        /// <param name="entityFlags"></param>
        /// <param name="skipList"></param>
        /// <returns></returns>
        public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance, EntityRaycastFlags entityFlags, params IPhysicalEntity[] skipList)
        {
            var magnitude = direction.Dot(direction);

            if (magnitude > 1.0f || magnitude < 1.0f)
            {
                direction = direction.Normalized;
            }

            var rayParams = new IPhysicalWorld.SRWIParams();

            rayParams.org      = origin;
            rayParams.dir      = direction * maxDistance;
            rayParams.objtypes = (int)entityFlags;
            rayParams.flags    = DefaultRaycastFlags;
            rayParams.nMaxHits = 1;
            rayParams.hits     = new ray_hit();

            if (skipList != null)
            {
                rayParams.AllocateSkipEnts(skipList.Length);

                for (int i = 0; i < skipList.Length; ++i)
                {
                    rayParams.SetSkipEnt(i, skipList[i]);
                }
            }
            else
            {
                rayParams.AllocateSkipEnts(0);
            }

            var hits = Global.gEnv.pPhysicalWorld.RayWorldIntersection(rayParams);

            rayParams.DeleteSkipEnts();
            return(hits > 0);
        }