Example #1
0
        // I might not want to get the closest enemy, but a specific enemy.
        // might use entity.id + entity.version of an entity and get position of entity
        // if current target is destroyed, maybe seach for new target or destroy bullet
        // add another option for auto mode
        // start with auto and maybe can focus on specifics later


        public void CheckForObstacle(int index)
        {
            CollisionFilter obstacleFilter = new CollisionFilter()
            {
                BelongsTo    = ~0u,
                CollidesWith = 16u + groupIndex,
                GroupIndex   = 0
            };
            PointDistanceInput obstacePointDistanceInput = new PointDistanceInput {
                Position    = cellSeparation[index],
                MaxDistance = boidsData[index].obstacleAversionDistance,
                Filter      = obstacleFilter
            };

            if (physicsWorld.CalculateDistance(obstacePointDistanceInput, out DistanceHit obstaceHit))
            {
                cellObstaclePositions[index] = obstaceHit.Position;
                cellObstacleDistance[index]  = obstaceHit.Distance;
                if (obstaceHit.Distance < settings.boidRadius)
                {
                    Entity targetEntity = physicsWorld.CollisionWorld.Bodies[obstaceHit.RigidBodyIndex].Entity;
                    var    hash         = (int)math.hash(new int2(targetEntity.Index, targetEntity.Version));
                    damageDict.Add(hash, 1);
                    killTrigger[index] = 1;
                }
            }
            else
            {
                cellObstacleDistance[index] = boidsData[index].obstacleAversionDistance + 1;
            }
        }
Example #2
0
        public unsafe void PhysicsBodyCalculateDistancePointTest()
        {
            var geometry = new BoxGeometry
            {
                Size = new float2(1f),
            };

            using (var collider = PhysicsBoxCollider.Create(geometry))
            {
                var physicsBody = new PhysicsBody(collider);

                var queryInput = new PointDistanceInput
                {
                    Position = new float2(-10f),
                    Filter   = CollisionFilter.Default
                };

                var closestHit = new DistanceHit();
                var allHits    = new NativeList <DistanceHit>(Allocator.Temp);

                // OK case : with enough max distance
                queryInput.MaxDistance = 10000.0f;
                Assert.IsTrue(physicsBody.CalculateDistance(queryInput));
                Assert.IsTrue(physicsBody.CalculateDistance(queryInput, out closestHit));
                Assert.IsTrue(physicsBody.CalculateDistance(queryInput, ref allHits));

                // Fail case : not enough max distance
                queryInput.MaxDistance = 1;
                Assert.IsFalse(physicsBody.CalculateDistance(queryInput));
                Assert.IsFalse(physicsBody.CalculateDistance(queryInput, out closestHit));
                Assert.IsFalse(physicsBody.CalculateDistance(queryInput, ref allHits));

                allHits.Dispose();
            }
        }
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            PhysicsWorld physicsWorld = buildPhysicsWorld.PhysicsWorld;

            inputDeps = JobHandle.CombineDependencies(inputDeps, buildPhysicsWorld.FinalJobHandle);
            inputDeps = JobHandle.CombineDependencies(inputDeps, stepPhysicsWorld.FinalJobHandle);

            var jobHandle = Entities.ForEach((ref DynamicBuffer <EntityBufferElement> adjacentEntities,
                                              in Translation position, in BugComponent bug) =>
            {
                NativeList <DistanceHit> distanceHits = new NativeList <DistanceHit>(Allocator.Temp);
                var pointDistanceInput = new PointDistanceInput
                {
                    Position    = position.Value,
                    MaxDistance = bug.Radius,
                    Filter      = LayerFilter(Layer.Bug, Layer.Obstacle)
                };

                physicsWorld.CalculateDistance(pointDistanceInput, ref distanceHits);
                adjacentEntities.Clear();
                var adjacent = adjacentEntities.Reinterpret <Entity>();
                for (int i = 0; i < distanceHits.Length; i++)
                {
                    adjacent.Add(distanceHits[i].Entity);
                }

                distanceHits.Dispose();
            })
Example #4
0
        public static bool OverlapSphereCustom <T, C>(ref T target, float3 position, sfloat radius, ref C collector, CollisionFilter filter, QueryInteraction queryInteraction = QueryInteraction.Default)
            where T : struct, ICollidable
            where C : struct, ICollector <DistanceHit>
        {
            PointDistanceInput input = new PointDistanceInput
            {
                Filter      = filter,
                MaxDistance = radius,
                Position    = position
            };

            if (queryInteraction == QueryInteraction.Default)
            {
                return(target.CalculateDistance(input, ref collector));
            }
            else
            {
                unsafe
                {
                    var interactionCollector = new QueryInteractionCollector <DistanceHit, C>
                    {
                        Collector = collector
                    };

                    bool returnValue = target.CalculateDistance(input, ref interactionCollector);

                    collector = interactionCollector.Collector;
                    return(returnValue);
                }
            }
        }
Example #5
0
        protected unsafe override JobHandle OnUpdate(JobHandle inputDependencies)
        {
            var job = new DamageAreaHitDetectionSystemJob();

            job.DamageEntities = DamageAreaQuery.ToEntityArray(Allocator.TempJob);
            job.Translations   = DamageAreaQuery.ToComponentDataArray <Translation>(Allocator.TempJob);
            job.DamageAreas    = DamageAreaQuery.ToComponentDataArray <DamageArea>(Allocator.TempJob);

            job.PhysicsWorld          = _physicsWorld.PhysicsWorld;
            job.DamageAreasFromEntity = GetComponentDataFromEntity <DamageArea>();
            job.HealthsFromEntity     = GetComponentDataFromEntity <Health>();
            job.DistanceHits          = new NativeArray <DistanceHit>(128, Allocator.TempJob);

            PointDistanceInput = new PointDistanceInput
            {
                Position    = float3.zero,
                MaxDistance = 50
            };

            job.pointDistanceInput = PointDistanceInput;

            inputDependencies = job.Schedule(inputDependencies);
            inputDependencies.Complete();

            return(inputDependencies);
        }
Example #6
0
        public unsafe void RigidBodyCalculateDistancePointTest()
        {
            Physics.RigidBody rigidbody = Unity.Physics.RigidBody.Zero;

            const float size         = 1.0f;
            const float convexRadius = 0.0f;

            var queryPos = new float3(-10, -10, -10);

            rigidbody.Collider = (Collider *)BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius).GetUnsafePtr();

            var pointDistanceInput = new PointDistanceInput();

            pointDistanceInput.Position = queryPos;
            pointDistanceInput.Filter   = CollisionFilter.Default;

            var closestHit = new DistanceHit();
            var allHits    = new NativeList <DistanceHit>(Allocator.Temp);

            // OK case : with enough max distance
            pointDistanceInput.MaxDistance = 10000.0f;
            Assert.IsTrue(rigidbody.CalculateDistance(pointDistanceInput));
            Assert.IsTrue(rigidbody.CalculateDistance(pointDistanceInput, out closestHit));
            Assert.IsTrue(rigidbody.CalculateDistance(pointDistanceInput, ref allHits));

            // Fail case : not enough max distance
            pointDistanceInput.MaxDistance = 1;
            Assert.IsFalse(rigidbody.CalculateDistance(pointDistanceInput));
            Assert.IsFalse(rigidbody.CalculateDistance(pointDistanceInput, out closestHit));
            Assert.IsFalse(rigidbody.CalculateDistance(pointDistanceInput, ref allHits));
        }
Example #7
0
        static unsafe void CheckRaycastHit(ref Physics.PhysicsWorld world, RaycastInput input, RaycastHit hit, string failureMessage)
        {
            // Fetch the leaf collider
            ChildCollider leaf;
            {
                Physics.RigidBody body = world.Bodies[hit.RigidBodyIndex];
                Collider.GetLeafCollider(body.Collider, body.WorldFromBody, hit.ColliderKey, out leaf);
            }

            // Check that the hit position matches the fraction
            float3 hitPosition = input.Ray.Origin + input.Ray.Direction * hit.Fraction;

            Assert.Less(math.length(hitPosition - hit.Position), tolerance, failureMessage + ": inconsistent fraction and position");

            // Query the hit position and check that it's on the surface of the shape
            PointDistanceInput pointInput = new PointDistanceInput
            {
                Position    = math.transform(math.inverse(leaf.TransformFromChild), hit.Position),
                MaxDistance = float.MaxValue
            };
            DistanceHit distanceHit;

            leaf.Collider->CalculateDistance(pointInput, out distanceHit);
            if (((ConvexCollider *)leaf.Collider)->ConvexHull.ConvexRadius > 0.0f)
            {
                // Convex raycast approximates radius, so it's possible that the hit position is not exactly on the shape, but must at least be outside
                Assert.Greater(distanceHit.Distance, -tolerance, failureMessage);
            }
            else
            {
                Assert.AreEqual(distanceHit.Distance, 0.0f, tolerance, failureMessage);
            }
        }
Example #8
0
    private JobHandle UpdateWithCollider2ColliderQuery(JobHandle inputDeps)
    {
        var physicsWorldSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystem <BuildPhysicsWorld>();
        var collisionWorld     = physicsWorldSystem.PhysicsWorld.CollisionWorld;

        // this is probably redundant but just for safety lets include all previous physics systems
        inputDeps = JobHandle.CombineDependencies(inputDeps, finalPhysicsSystem.FinalJobHandle);
        inputDeps = JobHandle.CombineDependencies(inputDeps, buildPhysicsSystem.FinalJobHandle);
        inputDeps = JobHandle.CombineDependencies(inputDeps, stepPhysicsSystem.FinalJobHandle);

        inputDeps = Entities.ForEach((Entity entity, ref EntitiesAroundCountCmp around, in Translation translation, in PhysicsCollider collider) =>
        {
            around.count = 0;

            float3 offset          = new float3(around.range, 1, around.range);
            OverlapAabbInput input = new OverlapAabbInput()
            {
                Aabb = new Aabb()
                {
                    Min = translation.Value - offset,
                    Max = translation.Value + offset,
                },
                Filter = CollisionFilter.Default
            };

            NativeList <int> bodyIndices = new NativeList <int>(Allocator.Temp);

            // OverlapAabb is really nice and fast, all expected colliders are returned
            if (collisionWorld.OverlapAabb(input, ref bodyIndices))
            {
                for (int i = 0; i < bodyIndices.Length; ++i)
                {
                    var body = collisionWorld.Bodies[bodyIndices[i]];

                    // why this returns true for colliders in AABB instead of actual distance?
                    var colliderDistanceInput = new ColliderDistanceInput()
                    {
                        Collider    = collider.ColliderPtr,
                        Transform   = RigidTransform.identity,
                        MaxDistance = around.range
                    };

                    // why this always returns false?
                    var pointDistanceInput = new PointDistanceInput()
                    {
                        Filter      = CollisionFilter.Default,
                        MaxDistance = around.range,
                        Position    = translation.Value
                    };

                    if (body.CalculateDistance(pointDistanceInput))
                    {
                        ++around.count;
                    }
                }
            }
            bodyIndices.Dispose();
        })
Example #9
0
        public bool CalculateDistance <T>(PointDistanceInput input, ref T collector) where T : struct, ICollector <DistanceHit>
        {
            // Transform the input into body space
            MTransform worldFromBody = new MTransform(WorldFromBody);
            MTransform bodyFromWorld = Inverse(worldFromBody);

            input.Position = Mul(bodyFromWorld, input.Position);

            SetQueryContextParameters(ref input.QueryContext, ref worldFromBody);

            return(Collider.IsCreated && Collider.Value.CalculateDistance(input, ref collector));
        }
Example #10
0
            public bool DistanceLeaf <T>(PointDistanceInput input, int rigidBodyIndex, ref T collector)
                where T : struct, ICollector <DistanceHit>
            {
                rigidBodyIndex += BaseRigidBodyIndex;

                input.QueryContext.IsInitialized  = true;
                input.QueryContext.RigidBodyIndex = rigidBodyIndex;

                RigidBody body = m_Bodies[rigidBodyIndex];

                return(body.CalculateDistance(input, ref collector));
            }
Example #11
0
        public static bool CalculateDistance <T>(ref T target, PointDistanceInput input, out DistanceHit result) where T : struct, ICollidable
        {
            var collector = new ClosestHitCollector <DistanceHit>(input.MaxDistance);

            if (target.CalculateDistance(input, ref collector))
            {
                result = collector.ClosestHit;  // TODO: would be nice to avoid this copy
                return(true);
            }

            result = new DistanceHit();
            return(false);
        }
Example #12
0
            public unsafe void Execute(
                Entity entity, int index,
                [ReadOnly] ref PlayerTag tag,
                //[ReadOnly] ref GroundHitColliderData hit,
                [ReadOnly] ref Translation pos,
                ref PhysicsVelocity v
                )
            {
                var upf = 0.0f;

                if (this.JumpForce > 0.0f)
                {
                    //var hitInput = new ColliderCastInput
                    //{
                    //    Collider = (Collider*)hit.Collider.GetUnsafePtr(),
                    //    Orientation = quaternion.identity,
                    //    Start = pos.Value + math.up() * 0.05f,
                    //    End = pos.Value + math.up() * -0.1f,
                    //};
                    var hitInput = new PointDistanceInput
                    {
                        Position    = pos.Value,
                        MaxDistance = 0.1f,
                        Filter      = new CollisionFilter
                        {
                            BelongsTo    = (1 << 20) | (1 << 22) | (1 << 23),
                            CollidesWith = (1 << 20) | (1 << 22) | (1 << 23),
                            GroupIndex   = 0,
                        },
                    };
                    //var collector = new ExcludeEntityCollector
                    //{
                    //    IgnoreEntity = entity,
                    //    Rigidbodies = this.CollisionWorld.Bodies,
                    //};
                    var a     = new NativeList <DistanceHit>(Allocator.Temp);
                    var isHit = this.CollisionWorld.CalculateDistance(hitInput, ref a);
                    if (isHit && a.Length > 1)
                    {
                        upf = this.JumpForce * 0.5f;
                    }
                    a.Dispose();
                }

                var vlinear = v.Linear;
                var xyDir   = math.rotate(this.CamRotWorld, this.StickDir) * this.DeltaTime * 170;

                xyDir.y = vlinear.y + upf;

                v.Linear = math.min(xyDir, new float3(10, 1000, 10));
            }
Example #13
0
    public unsafe static void PointRange(CollisionWorld world, float radius, uint mask, float3 pos, ref NativeList <DistanceHit> hits)
    {
        PointDistanceInput input = new PointDistanceInput()
        {
            MaxDistance = radius,
            Filter      = new CollisionFilter()
            {
                CategoryBits = mask, MaskBits = mask, GroupIndex = 0
            },
            Position = pos
        };

        world.CalculateDistance(input, ref hits);
    }
Example #14
0
        public static bool OverlapCircle(ISimGameWorldReadWriteAccessor accessor, fix2 position, fix radius, NativeList <DistanceHit> outHits, Entity ignoreEntity = default)
        {
            var physicsSystem = accessor.GetExistingSystem <PhysicsWorldSystem>();

            PointDistanceInput pointDistanceInput = PointDistanceInput.Default;

            pointDistanceInput.MaxDistance = (float)radius;
            pointDistanceInput.Position    = (float2)position;

            if (ignoreEntity != Entity.Null)
            {
                pointDistanceInput.Ignore = new IgnoreHit(physicsSystem.GetPhysicsBodyIndex(ignoreEntity));
            }

            return(physicsSystem.PhysicsWorld.CalculateDistance(pointDistanceInput, ref outHits));
        }
Example #15
0
        public bool CalculateDistance <T>(PointDistanceInput input, NativeArray <RigidBody> rigidBodies, ref T collector)
            where T : struct, ICollector <DistanceHit>
        {
            if (input.Filter.IsEmpty)
            {
                return(false);
            }
            var leafProcessor = new BvhLeafProcessor(rigidBodies);

            leafProcessor.BaseRigidBodyIndex = m_DynamicTree.NumBodies;
            bool hasHit = m_StaticTree.BoundingVolumeHierarchy.Distance(input, ref leafProcessor, ref collector);

            leafProcessor.BaseRigidBodyIndex = 0;
            hasHit |= m_DynamicTree.BoundingVolumeHierarchy.Distance(input, ref leafProcessor, ref collector);

            return(hasHit);
        }
Example #16
0
        public void Execute(Entity ent, int index, [ReadOnly] ref Translation translation, ref Enemy enemy)
        {
            enemy.timer -= deltaTime;
            var input = new PointDistanceInput()
            {
                MaxDistance = enemy.rangeDie,
                Filter      = new CollisionFilter()
                {
                    CategoryBits = mask, MaskBits = mask, GroupIndex = 0
                },
                Position = translation.Value
            };
            DistanceHit hit;

            if (world.CalculateDistance(input, out hit))
            {
                cmd.DestroyEntity(index, ent);
                cmd.DestroyEntity(index, world.Bodies[hit.RigidBodyIndex].Entity);
                var e = cmd.Instantiate(index, explosionPrefab);
                cmd.SetComponent(index, e, new Translation()
                {
                    Value = hit.Position
                });
            }
            else if (enemy.timer < 0)
            {
                input.MaxDistance = enemy.rangeShoot;
                if (world.CalculateDistance(input, out hit))
                {
                    var dir = hit.Position - translation.Value;
                    dir *= enemy.rangeShoot / math.length(dir) * 0.5f;
                    cmd.DestroyEntity(index, world.Bodies[hit.RigidBodyIndex].Entity);
                    var e = cmd.Instantiate(index, lazerPrefab);
                    cmd.SetComponent(index, e, new Translation()
                    {
                        Value = translation.Value + dir
                    });
                    cmd.SetComponent(index, e, new Rotation()
                    {
                        Value = quaternion.RotateZ(math.atan2(dir.y, dir.x))
                    });
                    enemy.timer = enemy.cooldown;
                }
            }
        }
Example #17
0
        protected override void OnUpdate()
        {
            Entities.ForEach((ref Proximity proximity, ref Translation translation, ref PhysicsCollider collider) =>
            {
                ref PhysicsWorld physicsWorld = ref World.DefaultGameObjectInjectionWorld.GetExistingSystem <BuildPhysicsWorld>().PhysicsWorld;

                if (collider.Value.IsCreated)
                {
                    var pointDistanceInput = new PointDistanceInput
                    {
                        Position    = translation.Value,
                        MaxDistance = proximity.maxDistance,
                        Filter      = collider.Value.Value.Filter
                    };

                    // Assign DistanceHit data to proximiy component
                    physicsWorld.CalculateDistance(pointDistanceInput, out proximity.distanceHit);
                }
            }).WithoutBurst().Run();
            public void Execute(
                Entity entity, int jobIndex,
                [WriteOnly] ref WallHitResultData result,
                [ReadOnly] ref GroundHitSphereData sphere,
                [WriteOnly] ref Translation pos,
                [WriteOnly] ref Rotation rot
                )
            {
                //var rtf = new RigidTransform( rot.Value, pos.Value );

                var hitInput = new PointDistanceInput
                {
                    Position    = pos.Value,//math.transform( rtf, sphere.Center ),
                    MaxDistance = sphere.Distance,
                    Filter      = sphere.Filter,
                };
                //var isHit = this.CollisionWorld.CalculateDistance( hitInput, ref a );// 自身のコライダを除外できればシンプルになるんだが…

                var collector = new ClosestHitExcludeSelfCollector <DistanceHit>(sphere.Distance, entity, this.MainEntities);
                //var collector = new ClosestHitCollector<DistanceHit>( sphere.Distance );
                var isHit = this.CollisionWorld.CalculateDistance(hitInput, ref collector);

                if (collector.NumHits == 0)
                {
                    return;
                }


                result.IsHit = true;

                var n = collector.ClosestHit.SurfaceNormal;
                var p = collector.ClosestHit.Position;

                pos.Value = p + n * sphere.Distance;

                var right        = math.mul(rot.Value, new float3(1.0f, 0.0f, 0.0f));
                var forward      = math.cross(n, right);
                var safe_forward = math.select(math.forward(rot.Value), forward, math.dot(right, n) > 0.001f);

                rot.Value = quaternion.LookRotation(safe_forward, n);
            }
        public void Execute()
        {
            var pointDistanceInput = new PointDistanceInput
            {
                Position    = transData.Value,
                MaxDistance = laserData.range,
                Filter      = CollisionFilter.Default
            };

            if (collectAll)
            {
                physWorld.CalculateDistance(pointDistanceInput, ref distanceHits);
            }
            else
            {
                if (physWorld.CalculateDistance(pointDistanceInput, out Unity.Physics.DistanceHit hit))
                {
                    distanceHits.Add(hit);
                }
            }
        }
Example #20
0
        public void Execute(ref Translation translation)
        {
            NativeList <DistanceHit> hits = new NativeList <DistanceHit>(Allocator.Temp);

            CollisionFilter targetFilter = new CollisionFilter()
            {
                BelongsTo    = ~0u,
                CollidesWith = 8u,
                GroupIndex   = 0
            };

            var pointDistanceInput = new PointDistanceInput {
                Position    = translation.Value,
                MaxDistance = 50,
                Filter      = targetFilter
            };

            physicsWorld.CalculateDistance(pointDistanceInput, ref hits);

            hits.Dispose();
        }
Example #21
0
    public unsafe static bool PointRangeSingle2(CollisionWorld world, float radius, uint mask, float3 pos, out DistanceHit hit)
    {
        var rayCommands = new NativeArray <PointDistanceInput>(1, Allocator.TempJob);
        var rayResults  = new NativeArray <DistanceHit>(1, Allocator.TempJob);

        rayCommands[0] = new PointDistanceInput()
        {
            MaxDistance = radius,
            Filter      = new CollisionFilter()
            {
                CategoryBits = mask, MaskBits = mask, GroupIndex = 0
            },
            Position = pos
        };
        var handle = PointRanges(world, rayCommands, rayResults);

        handle.Complete();
        hit = rayResults[0];
        rayCommands.Dispose();
        rayResults.Dispose();
        return(hit.RigidBodyIndex != -1);
    }
Example #22
0
        private void Start()
        {
            LightningBoltGraphicEntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(MainReferences.lightningTowerManager.LightningBoltGraphicPrefab, GameDataManager.instance.Settings);

            PhysicalBouncerEntityPrefab           = GameObjectConversionUtility.ConvertGameObjectHierarchy(MainReferences.physicalTowerManager.PhysicalBouncerPrefab, GameDataManager.instance.Settings);
            PhysicalBounderNoGraphicsEntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(MainReferences.physicalTowerManager.PhysicalBouncerNoGraphicsPrefab, GameDataManager.instance.Settings);

            EnemyDistanceHits = new NativeList <DistanceHit>(Allocator.Persistent);

            BulletEnemyCollisionFilter = new CollisionFilter
            {
                BelongsTo        = 1 << 1,
                    CollidesWith = 1
            };

            PointDistanceInput = new PointDistanceInput
            {
                Position    = Vector3.zero,
                MaxDistance = 0,
                Filter      = BulletEnemyCollisionFilter
            };
        }
Example #23
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            _stepPhysicsWorld.FinalJobHandle.Complete();

            var distanceHit = new NativeList <DistanceHit>(1, Allocator.TempJob);

            Entities.WithoutBurst()
            .ForEach((Entity entity, ref PhysicsCastData physicsCastData, in Translation position,
                      in DistanceInputCommandData distanceInputCommandData) =>
            {
                var pointDistanceInput = new PointDistanceInput
                {
                    Position    = position.Value,
                    MaxDistance = distanceInputCommandData.maxDistance,
                    Filter      = distanceInputCommandData.collision
                };

                var pointDistanceJobHandle = new PointDistanceJob
                {
                    pointDistanceInput = pointDistanceInput,
                    physicsWorld       = _physicsWorld,
                    distanceHits       = distanceHit
                }.Schedule();

                pointDistanceJobHandle.Complete();

                if (distanceHit.Length > 0)
                {
                    physicsCastData.entity    = distanceHit[0].Entity;
                    physicsCastData.hasTarget = true;
                    physicsCastData.status    = Status.Targetable;
                }
                else
                {
                    physicsCastData.hasTarget = false;
                    physicsCastData.status    = Status.Idle;
                }
            })
            public unsafe void Execute(
                Entity entity, int index,
                [WriteOnly] ref GroundHitResultData ground,
                [ReadOnly] ref GroundHitSphereData sphere,
                [ReadOnly] ref Translation pos,
                [ReadOnly] ref Rotation rot
                )
            {
                //var a = new NativeList<DistanceHit>( Allocator.Temp );
                var rtf = new RigidTransform(rot.Value, pos.Value);

                var hitInput = new PointDistanceInput
                {
                    Position    = math.transform(rtf, sphere.Center),
                    MaxDistance = sphere.Distance,
                    Filter      = sphere.Filter,
                };
                //var isHit = this.CollisionWorld.CalculateDistance( hitInput, ref a );// 自身のコライダを除外できればシンプルになるんだが…
                var collector = new AnyHitExcludeSelfCollector <DistanceHit>(sphere.Distance, entity, this.MainEntities);
                var isHit     = this.CollisionWorld.CalculateDistance(hitInput, ref collector);

                //var castInput = new RaycastInput
                //{
                //    Start = math.transform( rtf, sphere.Center ),
                //    End = math.transform( rtf, sphere.Center ) + ( math.up() * -sphere.Distance ),
                //    Filter = sphere.filter,
                //};
                //var collector = new AnyHitExcludeSelfCollector2( 1.0f, entity, this.CollisionWorld.Bodies );
                //var isHit = this.CollisionWorld.CastRay( castInput, ref collector );

                //ground = new GroundHitResultData { IsGround = ( isHit && a.Length > 1 ) };
                //ground.IsGround = a.Length > 1;
                ground.IsGround = collector.NumHits > 0;
                //ground.IsGround = isHit;

                //a.Dispose();
            }
    protected override unsafe void OnUpdate()
    {
        CollisionWorld collisionWorld = buildPhysicsWorld.PhysicsWorld.CollisionWorld;

        CollisionFilter collisionFilter = new CollisionFilter()
        {
            BelongsTo        = 1u << 0,
                CollidesWith = 0u | (1u << 0) | (1u << 1),
                GroupIndex   = 0
        };

        Dependency = Entities.WithAll <AnimalTag>().ForEach((ref Translation translation, ref AnimalMovementData mvmtData, in PhysicsCollider collider, in Rotation rotation) => {
            Unity.Collections.NativeList <DistanceHit> hits = new Unity.Collections.NativeList <DistanceHit>(Unity.Collections.Allocator.Temp);
            float maxDist = 1f;

            float3 fwd = translation.Value + (mvmtData.targetDirection * 0.25f);

            // Tested in Unity 2020.1.0b10
            //ColliderDistanceInput cdi = new ColliderDistanceInput()
            //{
            //    Collider = collider.ColliderPtr,
            //    MaxDistance = maxDist,
            //    Transform = new RigidTransform(rotation.Value, translation.Value)
            //};

            PointDistanceInput pdi = new PointDistanceInput()
            {
                Filter      = collisionFilter,
                MaxDistance = maxDist,
                Position    = fwd
            };

            if (collisionWorld.CalculateDistance(pdi, ref hits))
            {
                DistanceHit closest = GetClosestHit(hits, maxDist);
                if (closest.Distance > 0.00001)
                {
                    float distance = closest.Distance;

                    float distanceFrac = 1 - (distance / maxDist);
                    distanceFrac       = math.clamp(distanceFrac, 0.25f, 1f);

                    byte colliderTags = collisionWorld.Bodies[closest.RigidBodyIndex].CustomTags;
                    float dotProduct  = 0f;
                    float angle       = 0f;
                    bool avoid        = false;

                    if (colliderTags == 1) // Collision with another animal
                    {
                        quaternion r     = collisionWorld.Bodies[closest.RigidBodyIndex].WorldFromBody.rot;
                        float3 othersFwd = math.rotate(r, new float3(0f, 0f, 1f));

                        dotProduct = (float)(math.dot(mvmtData.targetDirection, math.normalize(othersFwd)));

                        if (dotProduct < -0.7f)
                        {
                            avoid = true;
                            angle = 5.846853f * distanceFrac; //- 25f degrees
                        }
                        else if (dotProduct >= -0.001f && dotProduct < 0.975f)
                        {
                            avoid = true;
                            angle = (0.436332f - math.acos(dotProduct)) * distanceFrac; // 25 degrees
                        }
                    }
                    else if (colliderTags == 2) // Collision with terrain
                    {
                        dotProduct = math.dot(mvmtData.targetDirection, math.normalize(closest.SurfaceNormal));
                        if (dotProduct < -0.1f)
                        {
                            avoid = true;
                            angle = -(1.570796f - math.acos(dotProduct)) * distanceFrac;  //90 degrees -> parallel to surface normal
                        }
                    }

                    if (avoid)
                    {
                        quaternion newRotation   = quaternion.RotateY(angle);
                        float3 newDirection      = math.rotate(newRotation, mvmtData.direction);
                        newDirection             = math.normalizesafe(newDirection);
                        mvmtData.targetDirection = newDirection;
                    }
                }
            }
            hits.Dispose();
        }).Schedule(Dependency);
Example #26
0
            public void Execute(
                Entity entity,
                int index,
                ref VelocityComponent velocityComponent,
                ref Translation translation
                )
            {
                velocityComponent.timerCalcVelocity -= DeltaTime;
                if (velocityComponent.timerCalcVelocity > 0)
                {
                    return;
                }
                velocityComponent.timerCalcVelocity = tick;

                var input = new PointDistanceInput
                {
                    Position    = translation.Value,
                    MaxDistance = cohesionRadius,
                    Filter      = CollisionFilter
                };

                var closestHits = new NativeList <DistanceHit>(Allocator.Temp);

                if (!CollisionWorld.CalculateDistance(input, ref closestHits))
                {
                    closestHits.Dispose();
                    return;
                }

                if (closestHits.Length < 2)
                {
                    closestHits.Dispose();
                    return;
                }

                velocityComponent.cohesion        = float3.zero;
                velocityComponent.separation      = float3.zero;
                velocityComponent.separationCount = 0;
                velocityComponent.alignment       = float3.zero;

                for (int i = 0; i < closestHits.Length && i < maxBoids; i++)
                {
                    var entityHit = CollisionWorld.Bodies[closestHits[i].RigidBodyIndex].Entity;

                    velocityComponent.vector       = translation.Value - TranslationMapData[entityHit].Value;
                    velocityComponent.sqrMagnitude = Vector3.SqrMagnitude(velocityComponent.vector);

                    velocityComponent.cohesion  += TranslationMapData[entityHit].Value;
                    velocityComponent.alignment += VelocityMapData[entityHit].velocity;
                    if (velocityComponent.sqrMagnitude > 0 && velocityComponent.sqrMagnitude < separationDistance2)
                    {
                        velocityComponent.separation += velocityComponent.vector / velocityComponent.sqrMagnitude;
                        velocityComponent.separationCount++;
                    }
                }

                velocityComponent.cohesion /= closestHits.Length > maxBoids ? maxBoids : closestHits.Length;
                velocityComponent.cohesion  = Vector3.ClampMagnitude(velocityComponent.cohesion - translation.Value, maxSpeed);
                velocityComponent.cohesion *= cohesionCoefficient;
                if (velocityComponent.separationCount > 0)
                {
                    velocityComponent.separation /= velocityComponent.separationCount;
                    velocityComponent.separation  = Vector3.ClampMagnitude(velocityComponent.separation, maxSpeed);
                    velocityComponent.separation *= separationCoefficient;
                }
                velocityComponent.alignment /= closestHits.Length > maxBoids ? maxBoids : closestHits.Length;
                velocityComponent.alignment  = Vector3.ClampMagnitude(velocityComponent.alignment, maxSpeed);
                velocityComponent.alignment *= alignmentCoefficient;

                velocityComponent.velocity = Vector3.ClampMagnitude(velocityComponent.cohesion + velocityComponent.separation + velocityComponent.alignment, maxSpeed);

                closestHits.Dispose();
            }
Example #27
0
        public static bool CalculateDistance <T>(ref T target, PointDistanceInput input, ref NativeList <DistanceHit> allHits) where T : struct, ICollidable
        {
            var collector = new AllHitsCollector <DistanceHit>(input.MaxDistance, ref allHits);

            return(target.CalculateDistance(input, ref collector));
        }
Example #28
0
 public bool CalculateDistance(PointDistanceInput input, ref NativeList <DistanceHit> allHits) => QueryWrappers.CalculateDistance(ref this, input, ref allHits);
Example #29
0
        public static bool CalculateDistance <T>(ref T target, PointDistanceInput input) where T : struct, ICollidable
        {
            var collector = new AnyHitCollector <DistanceHit>(input.MaxDistance);

            return(target.CalculateDistance(input, ref collector));
        }
Example #30
0
 public bool CalculateDistance <T>(PointDistanceInput input, ref T collector) where T : struct, ICollector <DistanceHit>
 {
     return(CollisionWorld.CalculateDistance(input, ref collector));
 }