Пример #1
0
    public void Calc(Vector3[] positions, Vector3[] velocities, FlockInfo frInfo)
    {
        System.Array.Clear(_pointCounters, 0, _pointCounters.Length);
        System.Array.Clear(_pointIndices, 0, _pointIndices.Length);
        _queue.WriteToBuffer(_pointCounters, _pointCountersBuffer, false, _events);
        _queue.WriteToBuffer(_pointIndices, _pointIndicesBuffer, false, _events);

        var positionsBuffer = new Cloo.ComputeBuffer<Vector3>(
            _context, ComputeMemoryFlags.CopyHostPointer, positions);
        var velocitiesBuffer = new Cloo.ComputeBuffer<Vector3>(
            _context, ComputeMemoryFlags.CopyHostPointer, velocities);

        _boundaryKernel.SetMemoryArgument(0, positionsBuffer);

        _updateGridKernel.SetMemoryArgument(0, positionsBuffer);

        _updateBoidsKernel.SetMemoryArgument(0, positionsBuffer);
        _updateBoidsKernel.SetMemoryArgument(1, velocitiesBuffer);
        _updateBoidsKernel.SetValueArgument(5, frInfo);

        //var startTime = Time.realtimeSinceStartup;
        _queue.Execute(_boundaryKernel, null, new long[]{ positions.Length }, null, _events);
        _queue.Execute(_updateGridKernel, null, new long[]{ positions.Length }, null, _events);
        _queue.Execute(_updateBoidsKernel, null, new long[]{ positions.Length }, null, _events);
        _queue.ReadFromBuffer(_pointCountersBuffer, ref _pointCounters, false, _events);
        _queue.ReadFromBuffer(_pointIndicesBuffer, ref _pointIndices, false, _events);
        _queue.ReadFromBuffer(positionsBuffer, ref positions, false, _events);
        _queue.ReadFromBuffer(velocitiesBuffer, ref velocities, false, _events);
        _queue.Finish();
        //Debug.Log("Elapsed: " + (Time.realtimeSinceStartup - startTime));

        #if false
        var counterSum = _pointCounters.Sum();
        if (positions.Length != counterSum)
            Debug.Log(string.Format("Counter sum must be {0} but {1}", positions.Length, counterSum));
        for (int i = 0; i < positions.Length; i++) {
            var p = positions[i];
            var cellPos = new Vector3(
                (p.x - _gridInfo.worldOrigin.x) / _gridInfo.cellSize.x,
                (p.y - _gridInfo.worldOrigin.y) / _gridInfo.cellSize.y,
                (p.z - _gridInfo.worldOrigin.z) / _gridInfo.cellSize.z);
            var cellId = (int)(cellPos.x) + _gridInfo.nGridPartitions
                * ((int)(cellPos.y) + _gridInfo.nGridPartitions * (int)(cellPos.z));
            if (!Enumerable.Range(cellId * _gridInfo.maxIndices, _gridInfo.maxIndices).Any(iter => _pointIndices[iter] == i))
                Debug.Log(string.Format("Index is wrong at {0}", i));
        }
        #endif
    }
    public void BoidFunc(FlockInfo flockInfo)
    {
        // zeroing out vectors
        cohesion   = Vector3.zero;
        allignment = Vector3.zero;
        separation = Vector3.zero;
        stearing   = Vector3.zero;

        // Loops through every boids positions, forward and checks the distance
        for (int i = 0; i < flockInfo.count; i++)
        {
            cohesion   += flockInfo.boidsPos[i];
            allignment += flockInfo.boidsForward[i];
            separation += Separation(flockInfo.boidsPos[i], flockInfo.distance);
        }

        // Calculates cohesion rule vector
        cohesion = cohesion / flockInfo.count;
        cohesion = (cohesion - oldPos) / 50f;

        // Calculates allignment rule vector
        allignment = allignment / (flockInfo.count - 1);
        allignment = (allignment - oldForward) / 4f;

        // Calculates seperation rule vector
        separation = separation / 5f;

        // Calculates avoidance rule vector
        stearing = stearing / 2f;

        // Calculates goal rule vector
        goal = flockInfo.flockPos - oldPos;
        goal = goal / 50f;

        // Multiplies every rule with a weight for changing behaviour
        cohesion   = cohesion * flockInfo.cohesionWeight;
        allignment = allignment * flockInfo.allignmentWeight;
        separation = separation * flockInfo.separationWeight;
        stearing   = stearing * flockInfo.stearingWeight;
        goal       = goal * flockInfo.goalWeight;

        // Lerps between the old direction and the new direction over time to reduce jitter and snapping
        newForward = Vector3.Lerp(oldForward, cohesion + allignment + separation + stearing + goal, flockInfo.dt);
    }