Exemple #1
0
        public unsafe void Execute()
        {
            DistanceHit dh;

            hit    = world.CalculateDistance(input, out dh);
            result = dh;
        }
Exemple #2
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;
                }
            }
        }
Exemple #3
0
    public unsafe static void ColliderRange(CollisionWorld world, float radius, Collider coll, RigidTransform trans, ref NativeList <DistanceHit> hits)
    {
        ColliderDistanceInput input = new ColliderDistanceInput()
        {
            MaxDistance = radius,
            Collider    = &coll,
            Transform   = trans
        };

        world.CalculateDistance(input, ref hits);
    }
Exemple #4
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);
    }
Exemple #5
0
        public unsafe void Execute(int index)
        {
            DistanceHit hit;

            if (!world.CalculateDistance(inputs[index], out hit))
            {
                hit = new DistanceHit()
                {
                    RigidBodyIndex = -1
                }
            }
            ;
            results[index] = hit;
        }
    }
Exemple #6
0
    /// <summary>
    /// Returns a list of all colliders within the specified distance of the provided collider, as a list of <see cref="DistanceHit"/>.<para/>
    ///
    /// Can be used in conjunction with <see cref="ColliderCastAll"/> to get the penetration depths of any colliders (using the distance of collisions).<para/>
    ///
    /// The caller must dispose of the returned list.
    /// </summary>
    /// <param name="collider"></param>
    /// <param name="maxDistance"></param>
    /// <param name="transform"></param>
    /// <param name="collisionWorld"></param>
    /// <returns></returns>
    public unsafe static NativeList <DistanceHit> ColliderDistanceAll(PhysicsCollider collider, float maxDistance, RigidTransform transform, ref CollisionWorld collisionWorld, Entity ignore, Allocator allocator = Allocator.TempJob)
    {
        ColliderDistanceInput input = new ColliderDistanceInput()
        {
            Collider    = collider.ColliderPtr,
            MaxDistance = maxDistance,
            Transform   = transform
        };

        NativeList <DistanceHit> allDistances = new NativeList <DistanceHit>(allocator);

        if (collisionWorld.CalculateDistance(input, ref allDistances))
        {
            TrimByEntity(ref allDistances, ignore);
        }

        return(allDistances);
    }
    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);
Exemple #8
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();
            }
Exemple #9
0
 public unsafe void Execute()
 {
     world.CalculateDistance(input, ref result);
 }