// Apply the flocking behaviour using a buffer private ReynoldsMovementValues GetFlockingBehaviour(ref Translation agentTranslation, ref float3 preVelocity, ref DynamicBuffer <float3> nearbyCrowdPosList, ref DynamicBuffer <float3> nearbyCrowdVelList, ref ReynoldsFlockBehaviour flockBehaviour, ReynoldsMovementValues movement) { float3 move = float3.zero; // where the agent will move // Calculate Avoidance first float3 avoidance = CalculateAvoidance(ref agentTranslation.Value, ref nearbyCrowdPosList, ref flockBehaviour); //if the avoidance is not zero if (!avoidance.Equals(float3.zero)) { avoidance = math.normalize(avoidance); avoidance *= flockBehaviour.AvoidanceWeight; move += avoidance; //Debug.Log("Move after avoid: " +move); } // Calculate cohesion float3 cohesion = CalculateCohesion(ref agentTranslation.Value, ref preVelocity, ref nearbyCrowdPosList, ref nearbyCrowdVelList, ref flockBehaviour); if (!cohesion.Equals(float3.zero)) { //Debug.Log("Cohes Dst Sq: " +math.distancesq(float3.zero,cohesion)); //if the avoidance is not normalized (The square of the length of the position is greater than the square of the weights) if (math.distancesq(float3.zero, cohesion) > flockBehaviour.CohesionWeight * flockBehaviour.CohesionWeight) { //normalize the movement vector cohesion = math.normalize(cohesion); cohesion *= flockBehaviour.CohesionWeight; } move += cohesion; //Debug.Log("Move after cohes: " +move); } // May want to calculate alignment after, but not at time of writing this ReynoldsMovementValues movementValues = new ReynoldsMovementValues { flockMovement = move, seekMovement = movement.seekMovement, fleeMovement = movement.fleeMovement }; //Debug.Log("Flock stored: " +movementValues.flockMovement); return(movementValues); //movement.flockMovement = move; //float moveSpeed = 5f; //movement speed //agentTranslation.Value += move * moveSpeed * Time.deltaTime; //add movement to the translation //return move; }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { NativeArray <Entity> entityArray = chunk.GetNativeArray(entityType); BufferAccessor <ReynoldsNearbyFlockPos> nearbyPosBuffers = chunk.GetBufferAccessor <ReynoldsNearbyFlockPos>(nearbyPosBufferType); BufferAccessor <ReynoldsNearbyFlockVel> nearbyVelBuffers = chunk.GetBufferAccessor <ReynoldsNearbyFlockVel>(nearbyVelBufferType); NativeArray <Translation> transArray = chunk.GetNativeArray(translationType); NativeArray <ReynoldsFlockBehaviour> flockArray = chunk.GetNativeArray(flockType); NativeArray <PreviousMovement> preVelArray = chunk.GetNativeArray(preVelType); NativeArray <ReynoldsMovementValues> movementArray = chunk.GetNativeArray(reynoldsMovementValuesType); for (int i = 0; i < chunk.Count; i++) { Entity entity = entityArray[i]; DynamicBuffer <ReynoldsNearbyFlockPos> posBuffer = nearbyPosBuffers[i]; DynamicBuffer <ReynoldsNearbyFlockVel> velBuffer = nearbyVelBuffers[i]; Translation trans = transArray[i]; ReynoldsFlockBehaviour flockBehaviour = flockArray[i]; PreviousMovement preVel = preVelArray[i]; ReynoldsMovementValues movement = movementArray[i]; float3 agentPosition = trans.Value; // the position of the seeker DynamicBuffer <float3> nearCrowdPosList = posBuffer.Reinterpret <float3>(); // reinterpret the buffer so that it is used like a buffer of float3s nearCrowdPosList.Clear(); DynamicBuffer <float3> nearCrowdVelList = velBuffer.Reinterpret <float3>(); // reinterpret the buffer so that it is used like a buffer of float3s nearCrowdVelList.Clear(); float searchRadius = math.max(flockBehaviour.CohesionRadius, flockBehaviour.AvoidanceRadius); // Choose the farther radius int hashMapKey = MovingQuadrantSystem.GetPositionHashMapKey(trans.Value); // Calculate the hash key of the seeker in question FindCrowdAgents(hashMapKey, agentPosition, entity, ref nearCrowdPosList, ref nearCrowdVelList, ref searchRadius); // Seach the quadrant that the seeker is in FindCrowdAgents(hashMapKey + 1, agentPosition, entity, ref nearCrowdPosList, ref nearCrowdVelList, ref searchRadius); // search the quadrant to the right FindCrowdAgents(hashMapKey - 1, agentPosition, entity, ref nearCrowdPosList, ref nearCrowdVelList, ref searchRadius); // search the quadrant to the left FindCrowdAgents(hashMapKey + MovingQuadrantSystem.quadrantYMultiplier, agentPosition, entity, ref nearCrowdPosList, ref nearCrowdVelList, ref searchRadius); // quadrant above FindCrowdAgents(hashMapKey - MovingQuadrantSystem.quadrantYMultiplier, agentPosition, entity, ref nearCrowdPosList, ref nearCrowdVelList, ref searchRadius); // quadrant below FindCrowdAgents(hashMapKey + 1 + MovingQuadrantSystem.quadrantYMultiplier, agentPosition, entity, ref nearCrowdPosList, ref nearCrowdVelList, ref searchRadius); // up right FindCrowdAgents(hashMapKey - 1 + MovingQuadrantSystem.quadrantYMultiplier, agentPosition, entity, ref nearCrowdPosList, ref nearCrowdVelList, ref searchRadius); // up left FindCrowdAgents(hashMapKey + 1 - MovingQuadrantSystem.quadrantYMultiplier, agentPosition, entity, ref nearCrowdPosList, ref nearCrowdVelList, ref searchRadius); // down right FindCrowdAgents(hashMapKey - 1 - MovingQuadrantSystem.quadrantYMultiplier, agentPosition, entity, ref nearCrowdPosList, ref nearCrowdVelList, ref searchRadius); // down left movementArray[i] = GetFlockingBehaviour(ref trans, ref preVel.value, ref nearCrowdPosList, ref nearCrowdVelList, ref flockBehaviour, movement); } }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { NativeArray <Translation> transArray = chunk.GetNativeArray(translationType); NativeArray <ReynoldsMovementValues> movementArray = chunk.GetNativeArray(reynoldsMovementValuesType); NativeArray <HasReynoldsSeekTargetPos> seekTargetArray = chunk.GetNativeArray(seekType); for (int i = 0; i < chunk.Count; i++) { Translation trans = transArray[i]; ReynoldsMovementValues movement = movementArray[i]; HasReynoldsSeekTargetPos targetPos = seekTargetArray[i]; float3 move = targetPos.targetPos - trans.Value; movementArray[i] = new ReynoldsMovementValues { flockMovement = movement.flockMovement, seekMovement = move, fleeMovement = movement.fleeMovement }; } }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { NativeArray <Translation> transArray = chunk.GetNativeArray(translationType); NativeArray <ReynoldsMovementValues> movementArray = chunk.GetNativeArray(reynoldsMovementValuesType); NativeArray <HasReynoldsFleeTargetPos> fleeTargetArray = chunk.GetNativeArray(fleeType); NativeArray <ReynoldsFleeSafeDistance> safeDistArray = chunk.GetNativeArray(safeDistType); for (int i = 0; i < chunk.Count; i++) { Translation trans = transArray[i]; ReynoldsMovementValues movement = movementArray[i]; HasReynoldsFleeTargetPos targetPos = fleeTargetArray[i]; ReynoldsFleeSafeDistance safeDist = safeDistArray[i]; float3 move = trans.Value - targetPos.targetPos; // from the target to the agent if (math.distance(targetPos.targetPos, trans.Value) < safeDist.safeDistance) { //get a vector from target through the agent to the safe distance (a point in the safe distance sphere in the same direction as the direction from target to agent) move = (math.normalize(move) * safeDist.safeDistance) - trans.Value; // then get the vector from the agent to the point on the safe distance sphere // this makes the flee movement greater the closer the agent is to the flee target movementArray[i] = new ReynoldsMovementValues { flockMovement = movement.flockMovement, seekMovement = movement.seekMovement, fleeMovement = move }; } else { movementArray[i] = new ReynoldsMovementValues { flockMovement = movement.flockMovement, seekMovement = movement.seekMovement, fleeMovement = float3.zero }; } } }