private void Foreach(int key, QuadrantData me, ref float3 avoidanceForce, ref float3 convinientForce, ref int bros, float radius)
        {
            if (targetMap.TryGetFirstValue(key, out EntitiesHashMap.MyData other, out NativeMultiHashMapIterator <int> iterator))
            {
                do
                {
                    var direction = me.position - other.position;
                    var distance  = math.length(direction);

                    if (me.broId == other.data2.broId && distance < 2 * radius)
                    {
                        convinientForce += other.data2.direction;
                        bros++;
                        distance *= 2f;
                    }

                    var distanceNormalized = (radius - distance) / (radius);

                    if (distanceNormalized > 0f && distanceNormalized < 1f)
                    {
                        var dot = (math.dot(math.normalizesafe(-direction), math.normalizesafe(me.direction)) + 1f) * 0.5f;

                        var forceMultiplyer = math.length(other.data2.direction) + 0.7f;

                        var multiplyer = distanceNormalized * dot * forceMultiplyer;

                        var multiplyerSin = math.sin(multiplyer * math.PI / 2f);

                        avoidanceForce += math.normalizesafe(other.data2.direction) * multiplyerSin;

                        avoidanceForce += direction / radius;
                    }
                } while (targetMap.TryGetNextValue(out other, ref iterator));
            }
        }
示例#2
0
        public void Execute(Entity e, int jobIndex, [ReadOnly] ref Translation translation, [ReadOnly] ref QuadrantEntityComponent quadEntity)
        {
            int          hashKey = GetPositionHashMapKey(translation.Value);
            QuadrantData data    = new QuadrantData
            {
                e              = e,
                position       = translation.Value,
                quadEntityData = quadEntity
            };

            EntityHashMap.Add(hashKey, data);
        }
示例#3
0
        private void ForeachAround(QuadrantData me, ref float3 avoidanceForce, float radius)
        {
            var position = me.position;
            var key      = QuadrantVariables.GetPositionHashMapKey(position);

            Foreach(key, me, ref avoidanceForce, radius);
            key = QuadrantVariables.GetPositionHashMapKey(position, new float3(1, 0, 0));
            Foreach(key, me, ref avoidanceForce, radius);
            key = QuadrantVariables.GetPositionHashMapKey(position, new float3(-1, 0, 0));
            Foreach(key, me, ref avoidanceForce, radius);
            key = QuadrantVariables.GetPositionHashMapKey(position, new float3(0, 0, 1));
            Foreach(key, me, ref avoidanceForce, radius);
            key = QuadrantVariables.GetPositionHashMapKey(position, new float3(0, 0, -1));
            Foreach(key, me, ref avoidanceForce, radius);
        }
示例#4
0
        private void Foreach(int key, QuadrantData me, ref float3 avoidanceForce, float radius)
        {
            if (targetMap.TryGetFirstValue(key, out EntitiesHashMap.MyData other, out NativeMultiHashMapIterator <int> iterator))
            {
                do
                {
                    var direction          = me.position - other.position;
                    var distance           = math.length(direction);
                    var distanceNormalized = (radius - distance) / (radius);

                    if (distanceNormalized > 0f && distanceNormalized < 1f)
                    {
                        var multiplyer = math.dot(math.normalizesafe(me.direction), distanceNormalized) + 1f;
                        avoidanceForce += direction / radius;
                    }
                } while (targetMap.TryGetNextValue(out other, ref iterator));
            }
        }
        protected override void OnUpdate()
        {
            var flockingSettings = flockingSettingsSystem.FlockingSettings;
            var quadrantHashMap  = PathQuadrantSystem.QuadrantHashMap;
            var isDebugging      = IsDebugging;

            Entities
            .WithNone <PathProblem>()
            .WithReadOnly(quadrantHashMap)
            .ForEach((Entity entity, ref PathSteering steering, in PathFlocking flocking, in PathAgent agent, in LocalToWorld localToWorld) =>
            {
                var entityHashMapKey = PathQuadrantSystem.HashPosition(localToWorld.Position, flockingSettings);

                var separationNeighbors = 0;
                var alignmentNeighbors  = 0;
                var cohesionNeighbors   = 0;

                var cohesionPos   = float3.zero;
                var alignmentVec  = float3.zero;
                var separationVec = float3.zero;

                var closestQuadrantData = new QuadrantData();

                PathQuadrantSystem.SearchQuadrantNeighbors(
                    in quadrantHashMap, entityHashMapKey, entity, flocking, localToWorld.Position, flockingSettings,
                    ref separationNeighbors, ref alignmentNeighbors, ref cohesionNeighbors, ref cohesionPos,
                    ref alignmentVec, ref separationVec, ref closestQuadrantData);

                var closestDistance = math.distancesq(localToWorld.Position, closestQuadrantData.LocalToWorld.Position);

                if (separationNeighbors > 0)
                {
                    separationVec /= separationNeighbors;

                    if (math.lengthsq(separationVec) > 0.5f)
                    {
                        separationVec += steering.CurrentHeading;                                              // Limit clumping of close agents.
                    }
                }
                else
                {
                    separationVec = steering.CurrentHeading;
                }

                if (alignmentNeighbors > 0)
                {
                    alignmentVec /= alignmentNeighbors;
                }
                else
                {
                    alignmentVec = steering.CurrentHeading;
                }

                if (cohesionNeighbors > 0)
                {
                    cohesionPos /= cohesionNeighbors;
                }
                else
                {
                    cohesionPos = localToWorld.Position;
                }

                var nearestAgentCollisionDistanceFromRadius = closestDistance - flocking.AgentAversionDistance;
                var nearestAgentDirection  = math.normalizesafe(localToWorld.Position - closestQuadrantData.LocalToWorld.Position);
                var agentAvoidanceSteering = flockingSettings.AgentCollisionAvoidanceStrength * nearestAgentDirection;

                agentAvoidanceSteering =
                    (nearestAgentCollisionDistanceFromRadius < 0 && !agentAvoidanceSteering.Equals(float3.zero))
                                ? agentAvoidanceSteering
                                : steering.CurrentHeading;

                if (nearestAgentCollisionDistanceFromRadius < 0 && isDebugging)
                {
                    Debug.DrawRay(localToWorld.Position, -nearestAgentDirection * 2f, Color.blue);
                }

                var alignmentSteering  = math.normalizesafe(alignmentVec) * flockingSettings.AlignmentWeight;
                var cohesionSteering   = math.normalizesafe(cohesionPos - localToWorld.Position) * flockingSettings.CohesionWeight;
                var separationSteering = math.normalizesafe(separationVec) * flockingSettings.SeparationWeight;

                steering.AgentAvoidanceSteering = agentAvoidanceSteering;
                steering.CohesionSteering       = cohesionSteering;
                steering.SeparationSteering     = separationSteering;
                steering.AlignmentSteering      = alignmentSteering;
            }
示例#6
0
 private static void ChangeClosestTarget(ref EntityWithPosition closestTarget, ref float closestTargetDistance, QuadrantData quadrantData, EntityDescription entityDesc)
 {
     if (closestTarget.entity == Entity.Null)
     {
         // No target
         closestTarget = new EntityWithPosition {
             entity = quadrantData.entity, position = quadrantData.position
         };
         closestTargetDistance = math.distancesq(entityDesc.location.Position, quadrantData.position);
     }
     else
     {
         if (math.distancesq(entityDesc.location.Position, quadrantData.position) < closestTargetDistance)
         {
             // This target is closer
             closestTarget = new EntityWithPosition {
                 entity = quadrantData.entity, position = quadrantData.position
             };
             closestTargetDistance = math.distancesq(entityDesc.location.Position, quadrantData.position);
         }
     }
 }