public bool4 Raycast(NativeBVHTree.Ray ray, float3 invD)
        {
            float4 lx     = Lx - new float4(ray.origin.x);
            float4 hx     = Hx - new float4(ray.origin.x);
            float4 nearXt = lx * new float4(invD.x);
            float4 farXt  = hx * new float4(invD.x);

            float4 ly     = Ly - new float4(ray.origin.y);
            float4 hy     = Hy - new float4(ray.origin.y);
            float4 nearYt = ly * new float4(invD.y);
            float4 farYt  = hy * new float4(invD.y);

            float4 lz     = Lz - new float4(ray.origin.z);
            float4 hz     = Hz - new float4(ray.origin.z);
            float4 nearZt = lz * new float4(invD.z);
            float4 farZt  = hz * new float4(invD.z);

            float4 nearX = math.min(nearXt, farXt);
            float4 farX  = math.max(nearXt, farXt);

            float4 nearY = math.min(nearYt, farYt);
            float4 farY  = math.max(nearYt, farYt);

            float4 nearZ = math.min(nearZt, farZt);
            float4 farZ  = math.max(nearZt, farZt);

            float4 nearMax = math.max(math.max(math.max(nearX, nearY), nearZ), float4.zero);
            float4 farMin  = math.min(math.min(farX, farY), farZ);

            return((nearMax <= farMin) & (lx <= hx));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Per: Christer Ericson - Real-Time Collision Detection (p. 179)
        /// </summary>
        public bool RayQuery(NativeBVHTree.Ray ray)
        {
            var m = ray.origin - center;
            var c = math.dot(m, m) - radius * radius;

            // If there is definitely at least one real root, there must be an intersection
            if (c <= 0.0f)
            {
                return(true);
            }
            var b = math.dot(m, ray.direction);

            // Early exit if ray origin outside sphere and ray pointing away from sphere
            if (b > 0.0f)
            {
                return(false);
            }
            var disc = b * b - c;

            // A negative discriminant corresponds to ray missing sphere
            if (disc < 0.0f)
            {
                return(false);
            }
            // Now ray must hit sphere
            return(true);
        }
Exemplo n.º 3
0
        public bool RayQuery(NativeBVHTree.Ray ray)
        {
            fixed(Collider *target = &this)
            {
                switch (type)
                {
                case Type.Box:
                    return(((BoxCollider *)target->data)->RayQuery(ray));

                case Type.Sphere:
                    return(((SphereCollider *)target->data)->RayQuery(ray));

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                default:
                    throw new ArgumentOutOfRangeException();
#endif
                }
            }
        }
Exemplo n.º 4
0
        public bool RayQuery(NativeBVHTree.Ray ray)
        {
            var invD = 1 / ray.direction;

            return(IntersectionUtils.DoesOverlap(LowerBound, UpperBound, ref ray, invD));
        }
        public IEnumerator Test()
        {
            int amount = 3000;

            Random.InitState(0);
            var go = new GameObject("debug");

            go.AddComponent <NativeBVHDebugDrawer>();
            var world = new BVHTreeWorld(amount, Allocator.Persistent);

            var movingObjects = new List <MovingObject>();

            NativeBVHDebugDrawer.LastTree = world.tree;
            NativeList <Collider> colliders = new NativeList <Collider>(amount, Allocator.TempJob);

            for (int i = 0; i < amount / 2; i++)
            {
                var center = new float3(UnityEngine.Random.Range(0, 0), UnityEngine.Random.Range(0, 0), UnityEngine.Random.Range(0, 0));
                var size   = new float3(UnityEngine.Random.Range(1, 3), UnityEngine.Random.Range(1, 3), UnityEngine.Random.Range(1, 3));
                colliders.Add(BoxCollider.Create(center, size));
            }

            for (int i = 0; i < amount / 2; i++)
            {
                var center = new float3(UnityEngine.Random.Range(0, 0), UnityEngine.Random.Range(0, 0), UnityEngine.Random.Range(0, 0));
                colliders.Add(SphereCollider.Create(center, UnityEngine.Random.Range(10, 15)));
            }

            new BVHTreeWorld.InsertJob {
                Tree      = world.tree,
                Bodies    = new NativeList <BVHTreeWorld.Body>(0, Allocator.TempJob),
                Colliders = new NativeList <Collider>(0, Allocator.TempJob),
            }.Run();

            new BVHTreeWorld.InsertJob {
                Tree      = world.tree,
                Bodies    = world.bodies,
                Colliders = colliders,
            }.Run();

            var until = Time.time + 30;

            // Prep raycast
            var rayResult  = new NativeList <int>(64, Allocator.TempJob);
            var rayVisited = new NativeList <int>(64, Allocator.TempJob);
            var ray        = new NativeBVHTree.Ray {
                origin      = new float3(-30, -30, 0),
                direction   = math.normalize(new float3(5, 5, 5)),
                minDistance = 0,
                maxDistance = 500
            };
            // Job
            var job = new RaycastJob {
                Tree    = world.tree,
                Ray     = ray,
                Results = rayResult,
            };

            for (var i = 0; i < world.bodies.Length; i++)
            {
                movingObjects.Add(new MovingObject {
                    transform = RigidTransform.identity,
                    velocity  = new float3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f))
                });
            }

            while (Time.time < until)
            {
                // Update
                Profiler.BeginSample("BVH - World.Update");
                world.Update();
                Profiler.EndSample();
                Profiler.BeginSample("BVH - Raycast");
                job.Run();
                Profiler.EndSample();
                yield return(null);

                for (var i = 0; i < world.bodies.Length; i++)
                {
                    // Update position
                    var movingObject = movingObjects[i];
                    movingObject.transform.pos += movingObject.velocity * Time.deltaTime * 2;
                    movingObjects[i]            = movingObject;
                    // And update world
                    world.UpdateTransform(i, movingObject.transform);
                }

                // Debug
                NativeBVHDebugDrawer.LastTree           = world.tree;
                NativeBVHDebugDrawer.LastTreeHits       = rayResult.ToArray();
                NativeBVHDebugDrawer.LastTreeRayVisited = new bool[world.tree.DebugGetTotalNodesLength() + 1];
                foreach (var i in rayVisited)
                {
                    NativeBVHDebugDrawer.LastTreeRayVisited[i] = true;
                }
                NativeBVHDebugDrawer.LastRay = ray;
            }
        }
Exemplo n.º 6
0
 public static bool DoesOverlap(ref AABB3D box, ref NativeBVHTree.Ray ray, float3 invD)
 {
     return(IntersectTest(box.LowerBound, box.UpperBound, ray.origin, ray.minDistance, ray.maxDistance, invD, out _));
 }
Exemplo n.º 7
0
 public static bool DoesOverlap(float3 boxMin, float3 boxMax, ref NativeBVHTree.Ray ray, float3 invD)
 {
     return(IntersectTest(boxMin, boxMax, ray.origin, ray.minDistance, ray.maxDistance, invD, out _));
 }