public static Mesh GetHeightMesh(this Mesh pointsMesh) { if (pointsMesh.vertexCount > 0) { int2 minInt = (int2)math.floor(((float3)(pointsMesh.bounds.min)).xz); int2 maxInt = (int2)math.ceil(((float3)(pointsMesh.bounds.max)).xz); int2 sizeInt = maxInt - minInt; var originVertices = new NativeArray <Vector3>(pointsMesh.vertices, Allocator.TempJob); var hashMap = new NativeMultiHashMap <int, int>(pointsMesh.vertices.Length, Allocator.TempJob); var minHeightIndex = new NativeArray <int>(originVertices.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); new GetHashMap() { min = minInt, size = sizeInt, vertices = originVertices, hashMap = hashMap.ToConcurrent(), minHeightIndex = minHeightIndex }.Schedule(originVertices.Length, 128).Complete(); new GetMinHeightIndex() { vertices = originVertices, minHeightIndex = minHeightIndex }.Schedule(hashMap, 128).Complete(); hashMap.Dispose(); var list = new NativeList <int>(originVertices.Length, Allocator.TempJob); new FilterMinHeightPoints() { minHeightIndex = minHeightIndex }.ScheduleAppend(list, list.Capacity, 128).Complete(); var minHeightPoints = new NativeArray <Vector3>(list.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); new GetMinHeightPoints() { vertices = originVertices, list = list, minHeightIndex = minHeightIndex, minHeightPoints = minHeightPoints }.Schedule(minHeightPoints.Length, 128).Complete(); minHeightIndex.Dispose(); list.Dispose(); originVertices.Dispose(); var flatMeshVertices = new NativeArray <Vector3>((sizeInt.x + 1) * (sizeInt.y + 1), Allocator.TempJob, NativeArrayOptions.UninitializedMemory); new InitHeightMeshVertices() { min = minInt, size = sizeInt, flatMeshVertices = flatMeshVertices }.Schedule(flatMeshVertices.Length, 128).Complete(); var indicesHeightMap = new NativeHashMap <int, float>(minHeightPoints.Length, Allocator.TempJob); new InsertIndicesHeightMap() { min = minInt, size = sizeInt, indicesHeightMap = indicesHeightMap.ToConcurrent(), minHeightPoints = minHeightPoints }.Schedule(indicesHeightMap.Capacity, 128).Complete(); minHeightPoints.Dispose(); new AddMinHeightPointsOffset() { flatMeshVertices = flatMeshVertices, indicesHeightMap = indicesHeightMap }.Schedule(flatMeshVertices.Length, 128).Complete(); indicesHeightMap.Dispose(); var vertices = new NativeArray <Vector3>((sizeInt.x + 1) * (sizeInt.y + 1), Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <Vector3> .Copy(flatMeshVertices, vertices); new SetHeightOfEdgePoints() { size = sizeInt, flatMeshVertices = flatMeshVertices, heightMeshVertices_write = vertices }.Schedule(flatMeshVertices.Length, 128).Complete(); flatMeshVertices.Dispose(); var trianglesInt6 = new NativeArray <int6>(sizeInt.x * sizeInt.y, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); new GetTriangles() { size = sizeInt, triangles = trianglesInt6 }.Schedule(trianglesInt6.Length, 128).Complete(); var triangles = new NativeArray <int>(trianglesInt6.Length * 6, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); unsafe { UnsafeUtility.MemCpy(triangles.GetUnsafePtr(), trianglesInt6.GetUnsafeReadOnlyPtr(), triangles.Length * sizeof(int)); } trianglesInt6.Dispose(); Mesh mesh = new Mesh() { indexFormat = vertices.Length > 65535 ? IndexFormat.UInt32 : IndexFormat.UInt16, vertices = vertices.ToArray(), triangles = triangles.ToArray() }; vertices.Dispose(); triangles.Dispose(); return(mesh); } else { return(new Mesh()); } }
protected override JobHandle OnUpdate(JobHandle inputDeps) { if (cameraTransform == null) { cameraTransform = GameObject.Find("Main Camera").transform; } EntityManager.GetAllUniqueSharedComponentData(uniqueTypes); ComponentDataArray <SPHCollider> colliders = SPHColliderGroup.GetComponentDataArray <SPHCollider>(); int colliderCount = colliders.Length; for (int typeIndex = 1; typeIndex < uniqueTypes.Count; typeIndex++) { // Get the current chunk setting SPHParticle settings = uniqueTypes[typeIndex]; SPHCharacterGroup.SetFilter(settings); // Cache the data ComponentDataArray <Position> positions = SPHCharacterGroup.GetComponentDataArray <Position>(); ComponentDataArray <SPHVelocity> velocities = SPHCharacterGroup.GetComponentDataArray <SPHVelocity>(); int cacheIndex = typeIndex - 1; int particleCount = positions.Length; NativeMultiHashMap <int, int> hashMap = new NativeMultiHashMap <int, int>(particleCount, Allocator.TempJob); NativeArray <Position> particlesPosition = new NativeArray <Position>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <SPHVelocity> particlesVelocity = new NativeArray <SPHVelocity>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <float3> particlesForces = new NativeArray <float3>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <float> particlesPressure = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <float> particlesDensity = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <int> particleIndices = new NativeArray <int>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <int> cellOffsetTableNative = new NativeArray <int>(cellOffsetTable, Allocator.TempJob); NativeArray <SPHCollider> copyColliders = new NativeArray <SPHCollider>(colliderCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); // Add new or dispose previous particle chunks PreviousParticle nextParticles = new PreviousParticle { hashMap = hashMap, particlesPosition = particlesPosition, particlesVelocity = particlesVelocity, particlesForces = particlesForces, particlesPressure = particlesPressure, particlesDensity = particlesDensity, particleIndices = particleIndices, cellOffsetTable = cellOffsetTableNative, copyColliders = copyColliders }; if (cacheIndex > previousParticles.Count - 1) { previousParticles.Add(nextParticles); } else { previousParticles[cacheIndex].hashMap.Dispose(); previousParticles[cacheIndex].particlesPosition.Dispose(); previousParticles[cacheIndex].particlesVelocity.Dispose(); previousParticles[cacheIndex].particlesForces.Dispose(); previousParticles[cacheIndex].particlesPressure.Dispose(); previousParticles[cacheIndex].particlesDensity.Dispose(); previousParticles[cacheIndex].particleIndices.Dispose(); previousParticles[cacheIndex].cellOffsetTable.Dispose(); previousParticles[cacheIndex].copyColliders.Dispose(); } previousParticles[cacheIndex] = nextParticles; // Copy the component data to native arrays CopyComponentData <Position> particlesPositionJob = new CopyComponentData <Position> { Source = positions, Results = particlesPosition }; JobHandle particlesPositionJobHandle = particlesPositionJob.Schedule(particleCount, 64, inputDeps); CopyComponentData <SPHVelocity> particlesVelocityJob = new CopyComponentData <SPHVelocity> { Source = velocities, Results = particlesVelocity }; JobHandle particlesVelocityJobHandle = particlesVelocityJob.Schedule(particleCount, 64, inputDeps); CopyComponentData <SPHCollider> copyCollidersJob = new CopyComponentData <SPHCollider> { Source = colliders, Results = copyColliders }; JobHandle copyCollidersJobHandle = copyCollidersJob.Schedule(colliderCount, 64, inputDeps); MemsetNativeArray <float> particlesPressureJob = new MemsetNativeArray <float> { Source = particlesPressure, Value = 0.0f }; JobHandle particlesPressureJobHandle = particlesPressureJob.Schedule(particleCount, 64, inputDeps); MemsetNativeArray <float> particlesDensityJob = new MemsetNativeArray <float> { Source = particlesDensity, Value = 0.0f }; JobHandle particlesDensityJobHandle = particlesDensityJob.Schedule(particleCount, 64, inputDeps); MemsetNativeArray <int> particleIndicesJob = new MemsetNativeArray <int> { Source = particleIndices, Value = 0 }; JobHandle particleIndicesJobHandle = particleIndicesJob.Schedule(particleCount, 64, inputDeps); MemsetNativeArray <float3> particlesForcesJob = new MemsetNativeArray <float3> { Source = particlesForces, Value = new float3(0, 0, 0) }; JobHandle particlesForcesJobHandle = particlesForcesJob.Schedule(particleCount, 64, inputDeps); // Put positions into a hashMap HashPositions hashPositionsJob = new HashPositions { positions = particlesPosition, hashMap = hashMap.ToConcurrent(), cellRadius = settings.radius }; JobHandle hashPositionsJobHandle = hashPositionsJob.Schedule(particleCount, 64, particlesPositionJobHandle); JobHandle mergedPositionIndicesJobHandle = JobHandle.CombineDependencies(hashPositionsJobHandle, particleIndicesJobHandle); MergeParticles mergeParticlesJob = new MergeParticles { particleIndices = particleIndices }; JobHandle mergeParticlesJobHandle = mergeParticlesJob.Schedule(hashMap, 64, mergedPositionIndicesJobHandle); JobHandle mergedMergedParticlesDensityPressure = JobHandle.CombineDependencies(mergeParticlesJobHandle, particlesPressureJobHandle, particlesDensityJobHandle); // Compute density pressure ComputeDensityPressure computeDensityPressureJob = new ComputeDensityPressure { particlesPosition = particlesPosition, densities = particlesDensity, pressures = particlesPressure, hashMap = hashMap, cellOffsetTable = cellOffsetTableNative, settings = settings }; JobHandle computeDensityPressureJobHandle = computeDensityPressureJob.Schedule(particleCount, 64, mergedMergedParticlesDensityPressure); JobHandle mergeComputeDensityPressureVelocityForces = JobHandle.CombineDependencies(computeDensityPressureJobHandle, particlesForcesJobHandle, particlesVelocityJobHandle); // Compute forces ComputeForces computeForcesJob = new ComputeForces { particlesPosition = particlesPosition, particlesVelocity = particlesVelocity, particlesForces = particlesForces, particlesPressure = particlesPressure, particlesDensity = particlesDensity, cellOffsetTable = cellOffsetTableNative, hashMap = hashMap, settings = settings }; JobHandle computeForcesJobHandle = computeForcesJob.Schedule(particleCount, 64, mergeComputeDensityPressureVelocityForces); // Integrate Integrate integrateJob = new Integrate { particlesPosition = particlesPosition, particlesVelocity = particlesVelocity, particlesDensity = particlesDensity, particlesForces = particlesForces }; JobHandle integrateJobHandle = integrateJob.Schedule(particleCount, 64, computeForcesJobHandle); JobHandle mergedIntegrateCollider = JobHandle.CombineDependencies(integrateJobHandle, copyCollidersJobHandle); // Compute Colliders ComputeColliders computeCollidersJob = new ComputeColliders { particlesPosition = particlesPosition, particlesVelocity = particlesVelocity, copyColliders = copyColliders, settings = settings }; JobHandle computeCollidersJobHandle = computeCollidersJob.Schedule(particleCount, 64, mergedIntegrateCollider); // Apply positions ApplyPositions applyPositionsJob = new ApplyPositions { particlesPosition = particlesPosition, particlesVelocity = particlesVelocity, positions = positions, velocities = velocities }; JobHandle applyPositionsJobHandle = applyPositionsJob.Schedule(particleCount, 64, computeCollidersJobHandle); inputDeps = applyPositionsJobHandle; } // Done uniqueTypes.Clear(); return(inputDeps); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { dispose_resources(); handle_ = inputDeps; player_colliders_ = new NativeArray <SphereCollider>(player_group_.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); enemy_colliders_ = new NativeArray <SphereCollider>(enemy_group_.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); player_bullet_colliders_ = new NativeArray <SphereCollider>(player_bullet_group_.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); enemy_bullet_colliders_ = new NativeArray <SphereCollider>(enemy_bullet_group_.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); player_hashmap_ = new NativeMultiHashMap <int, int>(player_group_.Length * 27 /* expanded */, Allocator.TempJob); enemy_hashmap_ = new NativeMultiHashMap <int, int>(enemy_group_.Length * 27 /* expanded */, Allocator.TempJob); player_bullet_hashmap_ = new NativeMultiHashMap <int, int>(player_bullet_group_.Length * 27 /* expand */, Allocator.TempJob); enemy_bullet_hashmap_ = new NativeMultiHashMap <int, int>(enemy_bullet_group_.Length * 27 /* expand */, Allocator.TempJob); var initial_player_collider_job = new CopyComponentData <SphereCollider> { Source = player_group_.sphere_collider_list_, Results = player_colliders_, }; var initial_player_collider_handle_ = initial_player_collider_job.Schedule(player_group_.Length, 32, handle_); var initial_enemy_collider_job = new CopyComponentData <SphereCollider> { Source = enemy_group_.sphere_collider_list_, Results = enemy_colliders_, }; var initial_enemy_collider_handle_ = initial_enemy_collider_job.Schedule(enemy_group_.Length, 32, handle_); var initial_player_bullet_collider_job = new CopyComponentData <SphereCollider> { Source = player_bullet_group_.sphere_collider_list_, Results = player_bullet_colliders_, }; var initial_player_bullet_collider_handle_ = initial_player_bullet_collider_job.Schedule(player_bullet_group_.Length, 32, handle_); var initial_enemy_bullet_collider_job = new CopyComponentData <SphereCollider> { Source = enemy_bullet_group_.sphere_collider_list_, Results = enemy_bullet_colliders_, }; var initial_enemy_bullet_collider_handle_ = initial_enemy_bullet_collider_job.Schedule(enemy_bullet_group_.Length, 32, handle_); const float CELL_RADIUS = 8f; var initial_player_hashmap_job = new HashPositions { cell_radius_ = CELL_RADIUS, offsets_ = offsets_, sphere_collider_list_ = player_group_.sphere_collider_list_, hashmap_ = player_hashmap_.ToConcurrent(), }; var initial_player_hashmap_handle_ = initial_player_hashmap_job.Schedule(player_group_.Length, 32, handle_); var initial_enemy_hashmap_job = new HashPositions { cell_radius_ = CELL_RADIUS, offsets_ = offsets_, sphere_collider_list_ = enemy_group_.sphere_collider_list_, hashmap_ = enemy_hashmap_.ToConcurrent(), }; var initial_enemy_hashmap_handle_ = initial_enemy_hashmap_job.Schedule(enemy_group_.Length, 32, handle_); var initial_player_bullet_hashmap_job = new HashPositions { cell_radius_ = CELL_RADIUS, offsets_ = offsets_, sphere_collider_list_ = player_bullet_group_.sphere_collider_list_, hashmap_ = player_bullet_hashmap_.ToConcurrent(), }; var initial_player_bullet_hashmap_handle_ = initial_player_bullet_hashmap_job.Schedule(player_bullet_group_.Length, 32, handle_); var initial_enemy_bullet_hashmap_job = new HashPositions { cell_radius_ = CELL_RADIUS, offsets_ = offsets_, sphere_collider_list_ = enemy_bullet_group_.sphere_collider_list_, hashmap_ = enemy_bullet_hashmap_.ToConcurrent(), }; var initial_enemy_bullet_hashmap_handle_ = initial_enemy_bullet_hashmap_job.Schedule(enemy_bullet_group_.Length, 32, handle_); { var handle_s = new NativeArray <JobHandle>(8, Allocator.Temp); var idx = 0; handle_s[idx] = initial_player_collider_handle_; ++idx; handle_s[idx] = initial_enemy_collider_handle_; ++idx; handle_s[idx] = initial_player_bullet_collider_handle_; ++idx; handle_s[idx] = initial_enemy_bullet_collider_handle_; ++idx; handle_s[idx] = initial_player_hashmap_handle_; ++idx; handle_s[idx] = initial_enemy_hashmap_handle_; ++idx; handle_s[idx] = initial_player_bullet_hashmap_handle_; ++idx; handle_s[idx] = initial_enemy_bullet_hashmap_handle_; ++idx; handle_ = JobHandle.CombineDependencies(handle_s); handle_s.Dispose(); } { var job = new CheckEnemyToPlayer { cell_radius_ = CELL_RADIUS, enemy_colliders_ = enemy_colliders_, player_colliders_ = player_colliders_, player_hashmap_ = player_hashmap_, enemy_list_ = enemy_group_.enemy_list_, player_list_ = player_group_.player_list_, }; handle_ = job.Schedule(enemy_group_.Length, 32, handle_); } { var job = new CheckEnemyBulletToPlayer { time_ = Time.GetCurrent(), cell_radius_ = CELL_RADIUS, enemy_bullet_colliders_ = enemy_bullet_colliders_, player_colliders_ = player_colliders_, player_hashmap_ = player_hashmap_, player_list_ = player_group_.player_list_, destroyable_list_ = enemy_bullet_group_.destroyable_list_, enemy_bullet_collision_info_list_ = enemy_bullet_group_.collision_info_list_, }; handle_ = job.Schedule(enemy_bullet_group_.Length, 32, handle_); } { var job = new CheckPlayerBulletToEnemy { time_ = Time.GetCurrent(), cell_radius_ = CELL_RADIUS, player_bullet_colliders_ = player_bullet_colliders_, enemy_colliders_ = enemy_colliders_, enemy_hashmap_ = enemy_hashmap_, destroyable_list_ = player_bullet_group_.destroyable_list_, enemy_list_ = enemy_group_.enemy_list_, player_bullet_collision_info_list_ = player_bullet_group_.collision_info_list_, }; handle_ = job.Schedule(player_bullet_group_.Length, 32, handle_); } return(handle_); }
//La data del sphereParticle es compartiiiida protected override JobHandle OnUpdate(JobHandle inputDeps) { if (cameraTransform == null) { cameraTransform = GameObject.Find("Main Camera").transform; } EntityManager.GetAllUniqueSharedComponentData(uniqueTypes); ComponentDataArray <SMBCollider> colliders = SMBColliderGroup.GetComponentDataArray <SMBCollider>(); int colliderCount = colliders.Length; for (int typeIndex = 1; typeIndex < uniqueTypes.Count; typeIndex++) { // Get the current chunk setting SMBProperties settings = uniqueTypes[typeIndex]; //SMBDestination smbdestination = _destination[typeIndex]; SMBCharacterGroup.SetFilter(settings); // Cache the data ComponentDataArray <Position> positions = SMBCharacterGroup.GetComponentDataArray <Position>(); ComponentDataArray <SMBVelocity> velocities = SMBCharacterGroup.GetComponentDataArray <SMBVelocity>(); ComponentDataArray <SMBDestination> SMBdestinations = SMBCharacterGroup.GetComponentDataArray <SMBDestination>(); ComponentDataArray <SMBSspeed> SMBSspeeds = SMBCharacterGroup.GetComponentDataArray <SMBSspeed>(); ComponentDataArray <SMBPath> indexPaths = SMBCharacterGroup.GetComponentDataArray <SMBPath>(); int cacheIndex = typeIndex - 1; int particleCount = positions.Length; NativeMultiHashMap <int, int> hashMap = new NativeMultiHashMap <int, int>(particleCount, Allocator.TempJob); NativeArray <Position> particlesPosition = new NativeArray <Position>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <Position> finalposition = new NativeArray <Position>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <SMBVelocity> particlesVelocity = new NativeArray <SMBVelocity>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <SMBDestination> particlesDestination = new NativeArray <SMBDestination>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <SMBSspeed> particlesSspeed = new NativeArray <SMBSspeed>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <SMBPath> particlesindexPaths = new NativeArray <SMBPath>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <float3> particlesForces = new NativeArray <float3>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <float> particlesPressure = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <float> particlesDensity = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <int> particleIndices = new NativeArray <int>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <int> cellOffsetTableNative = new NativeArray <int>(cellOffsetTable, Allocator.TempJob); NativeArray <SMBCollider> copyColliders = new NativeArray <SMBCollider>(colliderCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); // Add new or dispose previous particle chunks PreviousParticle nextParticles = new PreviousParticle { hashMap = hashMap, particlesPosition = particlesPosition, particlesVelocity = particlesVelocity, particlesDestination = particlesDestination, particlesSspeed = particlesSspeed, particlesindexPaths = particlesindexPaths, particlesForces = particlesForces, particlesPressure = particlesPressure, particlesDensity = particlesDensity, particleIndices = particleIndices, cellOffsetTable = cellOffsetTableNative, copyColliders = copyColliders }; if (cacheIndex > previousParticles.Count - 1) { previousParticles.Add(nextParticles); } else { previousParticles[cacheIndex].hashMap.Dispose(); previousParticles[cacheIndex].particlesPosition.Dispose(); previousParticles[cacheIndex].particlesVelocity.Dispose(); previousParticles[cacheIndex].particlesDestination.Dispose(); previousParticles[cacheIndex].particlesSspeed.Dispose(); previousParticles[cacheIndex].particlesindexPaths.Dispose(); previousParticles[cacheIndex].particlesForces.Dispose(); previousParticles[cacheIndex].particlesPressure.Dispose(); previousParticles[cacheIndex].particlesDensity.Dispose(); previousParticles[cacheIndex].particleIndices.Dispose(); previousParticles[cacheIndex].cellOffsetTable.Dispose(); previousParticles[cacheIndex].copyColliders.Dispose(); } previousParticles[cacheIndex] = nextParticles; // Copy the component data to native arrays CopyComponentData <Position> particlesPositionJob = new CopyComponentData <Position> { Source = positions, Results = particlesPosition }; JobHandle particlesPositionJobHandle = particlesPositionJob.Schedule(particleCount, 64, inputDeps); CopyComponentData <SMBVelocity> particlesVelocityJob = new CopyComponentData <SMBVelocity> { Source = velocities, Results = particlesVelocity }; JobHandle particlesVelocityJobHandle = particlesVelocityJob.Schedule(particleCount, 64, inputDeps); CopyComponentData <SMBDestination> particlesDestinationJob = new CopyComponentData <SMBDestination> { Source = SMBdestinations, Results = particlesDestination }; JobHandle particlesDestinationJobHandle = particlesDestinationJob.Schedule(particleCount, 64, inputDeps); CopyComponentData <SMBSspeed> particlesSspeedJob = new CopyComponentData <SMBSspeed> { Source = SMBSspeeds, Results = particlesSspeed }; JobHandle particlesSspeedJobHandle = particlesSspeedJob.Schedule(particleCount, 64, inputDeps); CopyComponentData <SMBCollider> copyCollidersJob = new CopyComponentData <SMBCollider> { Source = colliders, Results = copyColliders }; JobHandle copyCollidersJobHandle = copyCollidersJob.Schedule(colliderCount, 64, inputDeps); MemsetNativeArray <float> particlesPressureJob = new MemsetNativeArray <float> { Source = particlesPressure, Value = 0.0f }; JobHandle particlesPressureJobHandle = particlesPressureJob.Schedule(particleCount, 64, inputDeps); MemsetNativeArray <float> particlesDensityJob = new MemsetNativeArray <float> { Source = particlesDensity, Value = 0.0f }; JobHandle particlesDensityJobHandle = particlesDensityJob.Schedule(particleCount, 64, inputDeps); MemsetNativeArray <int> particleIndicesJob = new MemsetNativeArray <int> { Source = particleIndices, Value = 0 }; JobHandle particleIndicesJobHandle = particleIndicesJob.Schedule(particleCount, 64, inputDeps); MemsetNativeArray <float3> particlesForcesJob = new MemsetNativeArray <float3> { Source = particlesForces, Value = new float3(0, 0, 0) }; JobHandle particlesForcesJobHandle = particlesForcesJob.Schedule(particleCount, 64, inputDeps); MemsetNativeArray <Position> finalpositionJob = new MemsetNativeArray <Position> { Source = finalposition, Value = new Position { Value = new float3() } }; JobHandle finalpositionJobHandle = finalpositionJob.Schedule(particleCount, 64, inputDeps); //JobHandle computepathsJobHandle = particlesPositionJobHandle; if (first) { int index = 0, firsTriangle = 1; for (int i = 0; i < particleCount; ++i) { astar.cleanStructures(); astar.setOrigin(positions[i].Value); astar.setDestination(SMBdestinations[i].destination); astar.trianglePath2(); //Allpaths.AddRange(astar.trianglePath2()); wayPointsPath.AddRange(astar.getWayPoints()); int aux = wayPointsPath.Count; if (aux - index == 0) { firsTriangle = -1; } else { firsTriangle = 1; } Unity.Mathematics.Random ola = new Unity.Mathematics.Random(1); indexPaths[i] = new SMBPath { indexIni = index, indexFin = aux, NextPoint = new float3(), Firsttriangle = firsTriangle, recalculate = ola.NextInt(15), fordwarDir = new float3() }; index = aux; } first = false; } //Una vez llegado al destino ir a otro, funciona pero va muuuuy lento /*else * { * int index = 0, firsTriangle = 1, aux = 0; * int diff = 0; * for (int i = 0; i < particleCount; ++i) * { * index = indexPaths[i].indexIni + diff; * aux = indexPaths[i].indexFin + diff; * float3 NextPoint = indexPaths[i].NextPoint, fordwarDir = indexPaths[i].fordwarDir; * int recalculate = indexPaths[i].recalculate; * firsTriangle = indexPaths[i].Firsttriangle; * if (SMBdestinations[i].finished == 1) * { * firsTriangle = 1; * astar.cleanStructures(); * astar.setOrigin(positions[i].Value); * astar.setDestination(SMBdestinations[i].destinations2); * astar.trianglePath2(); * int count = 0; * if (i == 0) * { * wayPointsPath.RemoveRange(0, indexPaths[i].indexFin); * index = 0; * count = indexPaths[i].indexFin; * } * else * { * index = indexPaths[i - 1].indexFin; * count = indexPaths[i].indexFin + diff - indexPaths[i - 1].indexFin; * wayPointsPath.RemoveRange(indexPaths[i - 1].indexFin, count); * } * List<SMBWaypoint> wayaux = astar.getWayPoints(); * wayPointsPath.InsertRange(index, wayaux); * * aux = wayaux.Count; * * indexPaths[i] = new SMBPath { indexIni = index, indexFin = aux + index, NextPoint = new float3(), Firsttriangle = firsTriangle, recalculate = recalculate, fordwarDir = new float3() }; * SMBdestinations[i] = new SMBDestination {finished = 2, destinations2 = SMBdestinations[i].destinations2, destination = SMBdestinations[i].destination }; * diff += aux - count; * } * else indexPaths[i] = new SMBPath { indexIni = index, indexFin = aux, NextPoint = NextPoint, Firsttriangle = firsTriangle, recalculate = recalculate, fordwarDir = fordwarDir }; * } * }*/ NativeArray <SMBWaypoint> NwayPointspaths = new NativeArray <SMBWaypoint>(wayPointsPath.Count, Allocator.TempJob); //MemsetNativeArray<SMBWaypoint> waypointsJob = new MemsetNativeArray<SMBWaypoint> { Source = NwayPointspaths, Value = new SMBWaypoint { } }; //NativeArray<int>.Copy(Allpaths.ToArray(), paths); NativeArray <SMBWaypoint> .Copy(wayPointsPath.ToArray(), NwayPointspaths, wayPointsPath.Count); //CopyComponentData<SMBDestination> particlesDestinationJob = new CopyComponentData<SMBDestination> { Source = SMBdestinations, Results = particlesDestination }; //JobHandle particlesDestinationJobHandle = particlesDestinationJob.Schedule(particleCount, 64, inputDeps); CopyComponentData <SMBPath> particlesIndexPathJob = new CopyComponentData <SMBPath> { Source = indexPaths, Results = particlesindexPaths }; JobHandle particlesIndexPathJobHandle = particlesIndexPathJob.Schedule(particleCount, 64, inputDeps); // Put positions into a hashMap HashPositions hashPositionsJob = new HashPositions { positions = particlesPosition, hashMap = hashMap.ToConcurrent(), cellRadius = settings.radius }; JobHandle hashPositionsJobHandle = hashPositionsJob.Schedule(particleCount, 64, particlesPositionJobHandle); JobHandle mergedPositionIndicesJobHandle = JobHandle.CombineDependencies(hashPositionsJobHandle, particleIndicesJobHandle); MergeParticles mergeParticlesJob = new MergeParticles { particleIndices = particleIndices }; JobHandle mergeParticlesJobHandle = mergeParticlesJob.Schedule(hashMap, 64, mergedPositionIndicesJobHandle); JobHandle mergedMergedParticlesDensityPressure = JobHandle.CombineDependencies(mergeParticlesJobHandle, particlesPressureJobHandle, particlesDensityJobHandle); // Compute density pressure ComputeDensityPressure computeDensityPressureJob = new ComputeDensityPressure { particlesPosition = particlesPosition, densities = particlesDensity, pressures = particlesPressure, hashMap = hashMap, cellOffsetTable = cellOffsetTableNative, settings = settings }; JobHandle computeDensityPressureJobHandle = computeDensityPressureJob.Schedule(particleCount, 64, mergedMergedParticlesDensityPressure); JobHandle mergeComputeDensityPressureVelocityForces = JobHandle.CombineDependencies(computeDensityPressureJobHandle, particlesForcesJobHandle, particlesVelocityJobHandle); // Compute forces ComputeForces computeForcesJob = new ComputeForces { particlesPosition = particlesPosition, particlesVelocity = particlesVelocity, particlesForces = particlesForces, particlesPressure = particlesPressure, particlesDensity = particlesDensity, cellOffsetTable = cellOffsetTableNative, hashMap = hashMap, settings = settings }; JobHandle computeForcesJobHandle = computeForcesJob.Schedule(particleCount, 64, mergeComputeDensityPressureVelocityForces); // Integrate Integrate integrateJob = new Integrate { particlesPosition = particlesPosition, particlesVelocity = particlesVelocity, particlesDensity = particlesDensity, particlesForces = particlesForces }; JobHandle integrateJobHandle = integrateJob.Schedule(particleCount, 64, computeForcesJobHandle); JobHandle mergedIntegrateCollider = JobHandle.CombineDependencies(integrateJobHandle, copyCollidersJobHandle); //JobHandle mergedIntegrateCollider = JobHandle.CombineDependencies(particlesPositionJobHandle, particlesVelocityJobHandle, copyCollidersJobHandle); // Compute Colliders ComputeColliders computeCollidersJob = new ComputeColliders { particlesPosition = particlesPosition, particlesVelocity = particlesVelocity, copyColliders = copyColliders, settings = settings }; JobHandle computeCollidersJobHandle = computeCollidersJob.Schedule(particleCount, 64, mergedIntegrateCollider); JobHandle allReady = JobHandle.CombineDependencies(computeCollidersJobHandle, particlesIndexPathJobHandle, particlesDestinationJobHandle); ComputeNewPoint computeNewPointJob = new ComputeNewPoint { particlesPosition = particlesPosition, waypoints = NwayPointspaths, indexPaths = particlesindexPaths, particlesDestination = particlesDestination }; JobHandle computeNewPointJobHandle = computeNewPointJob.Schedule(particleCount, 64, allReady); computeNewPointJobHandle = JobHandle.CombineDependencies(computeNewPointJobHandle, finalpositionJobHandle); RecomputeNewPoint RecomputeNewPointJob = new RecomputeNewPoint { particlesPosition = particlesPosition, waypoints = NwayPointspaths, indexPaths = particlesindexPaths }; JobHandle RecomputeNewPointJobHandle = RecomputeNewPointJob.Schedule(particleCount, 64, computeNewPointJobHandle); JobHandle preparedToComputePositions = JobHandle.CombineDependencies(RecomputeNewPointJobHandle, particlesSspeedJobHandle); ComputePosition computePositionJob = new ComputePosition { particlesPosition = particlesPosition, particlesDestination = particlesDestination, particlesSspeed = particlesSspeed, particlesVelocity = particlesVelocity, indexPaths = particlesindexPaths, hashMap = hashMap, settings = settings, cellOffsetTable = cellOffsetTableNative, finalPosition = finalposition }; JobHandle comptePositionJobHandle = computePositionJob.Schedule(particleCount, 64, preparedToComputePositions); // Apply positions ApplyPositions applyPositionsJob = new ApplyPositions { particlesPosition = finalposition, particlesVelocity = particlesVelocity, particlesindexPaths = particlesindexPaths, //particlesDestination = particlesDestination, particlesSspeed = particlesSspeed, positions = positions, velocities = velocities, indexPaths = indexPaths, SMBSspeeds = SMBSspeeds, //SMBdestinations = SMBdestinations, }; JobHandle applyPositionsJobHandle = applyPositionsJob.Schedule(particleCount, 64, comptePositionJobHandle); inputDeps = applyPositionsJobHandle; inputDeps.Complete(); NwayPointspaths.Dispose(); finalposition.Dispose(); } // Done uniqueTypes.Clear(); return(inputDeps); }
void UpdateFrozenChunkCache() { var visibleLocalToWorldOrderVersion = EntityManager.GetComponentOrderVersion <VisibleLocalToWorld>(); var frozenOrderVersion = EntityManager.GetComponentOrderVersion <Frozen>(); var staticChunksOrderVersion = math.min(visibleLocalToWorldOrderVersion, frozenOrderVersion); if (staticChunksOrderVersion == m_LastFrozenChunksOrderVersion) { return; } // Dispose if (m_FrozenChunks.IsCreated) { m_FrozenChunks.Dispose(); } if (m_FrozenChunkBounds.IsCreated) { m_FrozenChunkBounds.Dispose(); } var sharedComponentCount = EntityManager.GetSharedComponentCount(); var HPMeshInstanceRendererType = GetArchetypeChunkSharedComponentType <HPMeshInstanceRenderer>(); var worldMeshRenderBoundsType = GetArchetypeChunkComponentType <WorldMeshRenderBounds>(true); // Allocate temp data var chunkRendererMap = new NativeMultiHashMap <int, int>(100000, Allocator.TempJob); var foundArchetypes = new NativeList <EntityArchetype>(Allocator.TempJob); Profiler.BeginSample("CreateArchetypeChunkArray"); var chunks = m_FrozenChunksQuery.CreateArchetypeChunkArray(Allocator.TempJob); Profiler.EndSample(); m_FrozenChunks = new NativeArray <ArchetypeChunk>(chunks.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); m_FrozenChunkBounds = new NativeArray <WorldMeshRenderBounds>(chunks.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var mapChunkRenderersJob = new MapChunkRenderers { Chunks = chunks, HPMeshInstanceRendererType = HPMeshInstanceRendererType, ChunkRendererMap = chunkRendererMap.ToConcurrent() }; var mapChunkRenderersJobHandle = mapChunkRenderersJob.Schedule(chunks.Length, 64); var gatherSortedChunksJob = new GatherSortedChunks { ChunkRendererMap = chunkRendererMap, SharedComponentCount = sharedComponentCount, SortedChunks = m_FrozenChunks, Chunks = chunks }; var gatherSortedChunksJobHandle = gatherSortedChunksJob.Schedule(mapChunkRenderersJobHandle); var updateChangedChunkBoundsJob = new UpdateChunkBounds { Chunks = m_FrozenChunks, WorldMeshRenderBoundsType = worldMeshRenderBoundsType, ChunkBounds = m_FrozenChunkBounds }; var updateChangedChunkBoundsJobHandle = updateChangedChunkBoundsJob.Schedule(chunks.Length, 64, gatherSortedChunksJobHandle); updateChangedChunkBoundsJobHandle.Complete(); foundArchetypes.Dispose(); chunkRendererMap.Dispose(); chunks.Dispose(); m_LastFrozenChunksOrderVersion = staticChunksOrderVersion; }
protected override JobHandle OnUpdate(JobHandle inputDeps) { if (DesiredCloudID2AgentInWindow.Capacity != m_CloudDataGroup.Length * 2) { DesiredCloudID2AgentInWindow.Dispose(); DesiredCloudID2AgentInWindow = new NativeHashMap <int, int>(m_CloudDataGroup.Length * 2, Allocator.Persistent); CloudID2AgentInWindow.Dispose(); CloudID2AgentInWindow = new NativeHashMap <int, int>(m_CloudDataGroup.Length * 2, Allocator.Persistent); } else { DesiredCloudID2AgentInWindow.Clear(); CloudID2AgentInWindow.Clear(); } parameterBuffer.Clear(); SpawnedAgentsInFrame.Clear(); var cg = ComponentGroups[m_AgentDataGroup.GroupIndex]; //JobHandle[] jobs = new JobHandle[m_CloudDataGroup.Length]; for (int i = 0; i < m_CloudDataGroup.Length; i++) { AgentCloudID newCloudID = new AgentCloudID { CloudID = i }; cg.SetFilter <AgentCloudID>(newCloudID); //CurrentInAreaJob newAreajob = new CurrentInAreaJob //{ // AgentData = cg.GetComponentDataArray<BioCrowds.AgentData>(), // CloudData = m_CloudDataGroup.CloudData, // CloudID2AgentInWindow = CloudID2AgentInWindow.ToConcurrent(), // CloudMarkersMap = m_CellMarkSystem.cloudID2MarkedCellsMap, // Position = cg.GetComponentDataArray<Position>() //}; //jobs[i] = newAreajob.Schedule(m_CloudDataGroup.Length, 1, inputDeps); int quantity = cg.CalculateLength(); //Debug.Log("Cloud " + i + " has " + quantity + " agents"); CloudID2AgentInWindow.TryAdd(i, quantity); } //for (int i = 0; i < m_CloudDataGroup.Length; i++) //{ // jobs[i].Complete(); //} if (_ChangedWindow) { var resetAcummulators = new ResetCloudAccumulator { AgentsPerCloud = CloudID2AgentInWindow, CloudData = m_CloudDataGroup.CloudData, Counter = m_CloudDataGroup.SpawnedAgents }; var resetJob = resetAcummulators.Schedule(m_CloudDataGroup.Length, 1, inputDeps); resetJob.Complete(); } var desiredJob = new DesiredCloudAgent2CrowdAgentJob { cellid2pos = m_CellID2PosSystem.cellId2Cellfloat3, cloudDensities = m_heatmap.cloudDensities, CloudData = m_CloudDataGroup.CloudData, CloudMarkersMap = m_CellMarkSystem.cloudID2MarkedCellsMap, desiredQuantity = DesiredCloudID2AgentInWindow.ToConcurrent() }; var desiredJobHandle = desiredJob.Schedule(m_CloudDataGroup.Length, 1, inputDeps); desiredJobHandle.Complete(); AddDifferencePerCloudJob differenceJob = new AddDifferencePerCloudJob { buffer = parameterBuffer.ToConcurrent(), CloudData = m_CloudDataGroup.CloudData, CloudGoal = m_CloudDataGroup.CloudGoal, CloudID2AgentInWindow = CloudID2AgentInWindow, CloudMarkersMap = m_CellMarkSystem.cloudID2MarkedCellsMap, DesiredCloudID2AgentInWindow = DesiredCloudID2AgentInWindow, AddedAgentsPerCloud = SpawnedAgentsInFrame.ToConcurrent(), Counter = m_CloudDataGroup.SpawnedAgents }; var diffJobHandle = differenceJob.Schedule(m_CloudDataGroup.Length, 1, inputDeps); diffJobHandle.Complete(); CloudAgentAccumulator accumulatorJob = new CloudAgentAccumulator { AddedAgentsInFramePerCloud = SpawnedAgentsInFrame, Counter = m_CloudDataGroup.SpawnedAgents, CloudData = m_CloudDataGroup.CloudData }; var accumJobHandle = accumulatorJob.Schedule(m_CloudDataGroup.Length, 1, diffJobHandle); accumJobHandle.Complete(); //Debug.Log("L1 " + parameterBuffer.Length); //for(int i = 0; i < m_CloudDataGroup.Length; i++) //{ // Debug.Log("Spawned Agents in Cloud" + m_CloudDataGroup.CloudData[i].ID + " : " + m_CloudDataGroup.SpawnedAgents[i].Quantity); //} _ChangedWindow = false; return(accumJobHandle); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { var settings = ECSController.FlockParams; var gameSettings = GlobalSettings.Instance; EntityManager.GetAllUniqueSharedComponentData(UniqueTypes); int targetsCount = BoidTargetsGroup.CalculateLength(); int obstaclesCount = BoidObstaclesGroup.CalculateLength(); UIControl.Instance.NrOfObstacles = obstaclesCount; // Ignore typeIndex 0, can't use the default for anything meaningful. for (int typeIndex = 1; typeIndex < UniqueTypes.Count; typeIndex++) { Boid boid = UniqueTypes[typeIndex]; BoidGroup.SetFilter(boid); var boidCount = BoidGroup.CalculateLength(); UIControl.Instance.NrOfBoidsAlive = boidCount; var cacheIndex = typeIndex - 1; // containers that store all the data. var cellIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var hashMap = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob); var cellCount = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var cellAlignment = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var cellPositions = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var targetsPositions = new NativeArray <float3>(targetsCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var closestTargetIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var obstaclesPositions = new NativeArray <float3>(obstaclesCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var closestObstacleIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var closestObstacleSqDistances = new NativeArray <float>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); float3 sumOfAllBoidsPositions = float3.zero; // copy values to buffers. var initialCellAlignmentJob = new CopyHeadingsInBuffer { headingsResult = cellAlignment }; var initialCellAlignmentJobHandle = initialCellAlignmentJob.Schedule(BoidGroup, inputDeps); var initialCopyPositionJob = new CopyPositionsInBuffer { positionsResult = cellPositions }; var initialCopyPositionJobHandle = initialCopyPositionJob.Schedule(BoidGroup, inputDeps); var sumPositionsJob = new SumPositions { positionsSum = sumOfAllBoidsPositions }; var sumPositionsJobHandle = sumPositionsJob.Schedule(BoidGroup, inputDeps); // copy targets positions var copyPositionsOfTargetsJob = new CopyPositionsInBuffer { positionsResult = targetsPositions }; var copyPositionsOfTargetsJobHandle = copyPositionsOfTargetsJob.Schedule(BoidTargetsGroup, inputDeps); // copy obstacles positions var copyPositionsOfObstaclesJob = new CopyPositionsInBuffer { positionsResult = obstaclesPositions }; var copyPositionsOfObstaclesJobHandle = copyPositionsOfObstaclesJob.Schedule(BoidObstaclesGroup, inputDeps); var newCellData = new CellsData { indicesOfCells = cellIndices, hashMapBlockIndexWithBoidsIndex = hashMap, sumOfDirectionsOnCells = cellAlignment, sumOfPositionsOnCells = cellPositions, nrOfBoidsOnCells = cellCount, targetsPositions = targetsPositions, closestTargetIndices = closestTargetIndices, closestObstacleIndices = closestObstacleIndices, closestObstacleSqDistances = closestObstacleSqDistances, obstaclesPositions = obstaclesPositions, }; if (cacheIndex > (_CellsData.Count - 1)) { _CellsData.Add(newCellData); } else { DisposeCellData(_CellsData[cacheIndex]); } _CellsData[cacheIndex] = newCellData; // hash the entity position var hashPositionsJob = new HashPositionsToHashMap { hashMap = hashMap.ToConcurrent(), cellRadius = ECSController.Instance.CellSizeVaried, positionOffsetVary = ECSController.Instance.PositionNeighbourCubeOffset }; var hashPositionsJobHandle = hashPositionsJob.Schedule(BoidGroup, inputDeps); // set all cell count to 1. var initialCellCountJob = new MemsetNativeArray <int> { Source = cellCount, Value = 1 }; var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, inputDeps); // bariers. from now on we need to use the created buffers. // and we need to know that they are finished. var initialCellBarrierJobHandle = JobHandle.CombineDependencies( initialCellAlignmentJobHandle, initialCopyPositionJobHandle, initialCellCountJobHandle); var mergeCellsBarrierJobHandle = JobHandle.CombineDependencies( hashPositionsJobHandle, initialCellBarrierJobHandle, sumPositionsJobHandle); var targetsJobHandle = JobHandle.CombineDependencies(mergeCellsBarrierJobHandle, copyPositionsOfTargetsJobHandle, copyPositionsOfObstaclesJobHandle); var mergeCellsJob = new MergeCellsJob { indicesOfCells = cellIndices, cellAlignment = cellAlignment, cellPositions = cellPositions, cellCount = cellCount, targetsPositions = targetsPositions, closestTargetIndexToCells = closestTargetIndices, closestObstacleSqDistanceToCells = closestObstacleSqDistances, closestObstacleIndexToCells = closestObstacleIndices, obstaclesPositions = obstaclesPositions }; // job now depends on last barrier. var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, targetsJobHandle); EntityCommandBuffer.Concurrent commandBuffer = barrierCommand.CreateCommandBuffer().ToConcurrent(); NativeQueue <float3> killedPositionsQueue = new NativeQueue <float3>(Allocator.TempJob); var steerJob = new MoveBoids { cellIndices = newCellData.indicesOfCells, alignmentWeight = gameSettings.AlignmentWeight, separationWeight = gameSettings.SeparationWeight, cohesionWeight = gameSettings.CohesionWeight, cellSize = ECSController.Instance.CellSizeVaried, sphereBoundarySize = gameSettings.SphereBoundarySize, sphereBoundaryWeight = gameSettings.BoundaryWeight, moveSpeed = gameSettings.MoveSpeed, cellAlignment = cellAlignment, cellPositions = cellPositions, cellCount = cellCount, dt = Time.deltaTime, walkToFlockCenterWeight = gameSettings.WalkToFlockCenterWeight, sumOfAllPositions = sumOfAllBoidsPositions, nrOfTotalBoids = boidCount, maintainYWeight = gameSettings.maintainYWeight, yLength = gameSettings.yLength, perlinNoiseScale = settings.perlinNoiseScale, targetsPositions = targetsPositions, cellClosestTargetsIndices = closestTargetIndices, goToTargetsWeight = gameSettings.goToTargetsWeight, obstaclesPositions = obstaclesPositions, cellClosestObstaclesIndices = closestObstacleIndices, cellClosestObstaclesSqDistances = closestObstacleSqDistances, startAvoidingObstacleAtDistance = gameSettings.avoidDistanceObstacles, avoidObstaclesWeight = gameSettings.avoidObstaclesWeight, terrainY = ECSController.TerrainY, distanceToAvoidTerrain = settings.distanceToAvoidTerrain, avoidTerrainWeight = gameSettings.avoidTerrainWeight, avoidXZwhileHeightBiggerThan = settings.avoidXZwhileHeightBiggerThan, avoidXZwhileHeightBiggerFade = settings.avoidXZwhileHeightBiggerFade, obstacleKillRadius = settings.obstacleKillRadius, commandBuffer = commandBuffer, diedPositions = killedPositionsQueue.ToConcurrent(), }; // job depends on merge cells job var steerJobHandle = steerJob.Schedule(BoidGroup, mergeCellsJobHandle); barrierCommand.AddJobHandleForProducer(steerJobHandle); steerJobHandle.Complete(); if (killedPositionsQueue.TryDequeue(out float3 pos)) { GameController.Instance.KilledBoidAt(pos); } killedPositionsQueue.Dispose(); inputDeps = steerJobHandle; BoidGroup.AddDependency(inputDeps); } UniqueTypes.Clear(); return(inputDeps); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { EntityManager.GetAllUniqueSharedComponentData(m_UniqueTypes); var obstacleCount = m_ObstacleGroup.CalculateLength(); var targetCount = m_TargetGroup.CalculateLength(); // Ignore typeIndex 0, can't use the default for anything meaningful. for (int typeIndex = 1; typeIndex < m_UniqueTypes.Count; typeIndex++) { var settings = m_UniqueTypes[typeIndex]; m_BoidGroup.SetFilter(settings); var boidCount = m_BoidGroup.CalculateLength(); var cacheIndex = typeIndex - 1; var cellIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var hashMap = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob); var cellObstacleDistance = new NativeArray <float>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var cellObstaclePositionIndex = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var cellTargetPositionIndex = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var cellCount = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var cellAlignment = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var cellSeparation = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var copyTargetPositions = new NativeArray <float3>(targetCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var copyObstaclePositions = new NativeArray <float3>(obstacleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var initialCellAlignmentJob = new CopyHeadings { headings = cellAlignment }; var initialCellAlignmentJobHandle = initialCellAlignmentJob.ScheduleGroup(m_BoidGroup, inputDeps); var initialCellSeparationJob = new CopyPositions { positions = cellSeparation }; var initialCellSeparationJobHandle = initialCellSeparationJob.ScheduleGroup(m_BoidGroup, inputDeps); var copyTargetPositionsJob = new CopyPositions { positions = copyTargetPositions }; var copyTargetPositionsJobHandle = copyTargetPositionsJob.ScheduleGroup(m_TargetGroup, inputDeps); var copyObstaclePositionsJob = new CopyPositions { positions = copyObstaclePositions }; var copyObstaclePositionsJobHandle = copyObstaclePositionsJob.ScheduleGroup(m_ObstacleGroup, inputDeps); var nextCells = new PrevCells { cellIndices = cellIndices, hashMap = hashMap, copyObstaclePositions = copyObstaclePositions, copyTargetPositions = copyTargetPositions, cellAlignment = cellAlignment, cellSeparation = cellSeparation, cellObstacleDistance = cellObstacleDistance, cellObstaclePositionIndex = cellObstaclePositionIndex, cellTargetPositionIndex = cellTargetPositionIndex, cellCount = cellCount }; if (cacheIndex > (m_PrevCells.Count - 1)) { m_PrevCells.Add(nextCells); } else { m_PrevCells[cacheIndex].hashMap.Dispose(); m_PrevCells[cacheIndex].cellIndices.Dispose(); m_PrevCells[cacheIndex].cellObstaclePositionIndex.Dispose(); m_PrevCells[cacheIndex].cellTargetPositionIndex.Dispose(); m_PrevCells[cacheIndex].copyTargetPositions.Dispose(); m_PrevCells[cacheIndex].copyObstaclePositions.Dispose(); m_PrevCells[cacheIndex].cellAlignment.Dispose(); m_PrevCells[cacheIndex].cellSeparation.Dispose(); m_PrevCells[cacheIndex].cellObstacleDistance.Dispose(); m_PrevCells[cacheIndex].cellCount.Dispose(); } m_PrevCells[cacheIndex] = nextCells; var hashPositionsJob = new HashPositions { hashMap = hashMap.ToConcurrent(), cellRadius = settings.CellRadius }; var hashPositionsJobHandle = hashPositionsJob.ScheduleGroup(m_BoidGroup, inputDeps); var initialCellCountJob = new MemsetNativeArray <int> { Source = cellCount, Value = 1 }; var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, inputDeps); var initialCellBarrierJobHandle = JobHandle.CombineDependencies(initialCellAlignmentJobHandle, initialCellSeparationJobHandle, initialCellCountJobHandle); var copyTargetObstacleBarrierJobHandle = JobHandle.CombineDependencies(copyTargetPositionsJobHandle, copyObstaclePositionsJobHandle); var mergeCellsBarrierJobHandle = JobHandle.CombineDependencies(hashPositionsJobHandle, initialCellBarrierJobHandle, copyTargetObstacleBarrierJobHandle); var mergeCellsJob = new MergeCells { cellIndices = cellIndices, cellAlignment = cellAlignment, cellSeparation = cellSeparation, cellObstacleDistance = cellObstacleDistance, cellObstaclePositionIndex = cellObstaclePositionIndex, cellTargetPositionIndex = cellTargetPositionIndex, cellCount = cellCount, targetPositions = copyTargetPositions, obstaclePositions = copyObstaclePositions }; var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, mergeCellsBarrierJobHandle); var steerJob = new Steer { cellIndices = nextCells.cellIndices, settings = settings, cellAlignment = cellAlignment, cellSeparation = cellSeparation, cellObstacleDistance = cellObstacleDistance, cellObstaclePositionIndex = cellObstaclePositionIndex, cellTargetPositionIndex = cellTargetPositionIndex, cellCount = cellCount, targetPositions = copyTargetPositions, obstaclePositions = copyObstaclePositions, dt = Time.deltaTime, }; var steerJobHandle = steerJob.ScheduleGroup(m_BoidGroup, mergeCellsJobHandle); inputDeps = steerJobHandle; m_BoidGroup.AddDependency(inputDeps); } m_UniqueTypes.Clear(); return(inputDeps); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { var targetCount = m_TargetGroup.CalculateLength(); if (m_Capacity < targetCount) { if (m_NodeMap.IsCreated) { m_NodeMap.Dispose(); } if (m_TranslationMap.IsCreated) { m_TranslationMap.Dispose(); } m_Capacity = math.max(100, targetCount + targetCount >> 1); m_NodeMap = new NativeMultiHashMap <int2, Entity>(m_Capacity, Allocator.Persistent); m_TranslationMap = new NativeHashMap <Entity, float3>(m_Capacity, Allocator.Persistent); } else { m_NodeMap.Clear(); m_TranslationMap.Clear(); } var count = m_Group.CalculateLength(); if (count > 0) { var entityArray = new NativeArray <Entity>(count, Allocator.TempJob); var targetEntityArray = new NativeArray <Entity>(count, Allocator.TempJob); var engagedArray = new NativeArray <@bool>(count, Allocator.TempJob); var commandBufferSystem = World.GetExistingManager <BeginSimulationEntityCommandBufferSystem>(); var commandBuffer = commandBufferSystem.CreateCommandBuffer(); inputDeps = new ConsolidateNodesJob { NodeMap = m_NodeMap.ToConcurrent(), TranslationMap = m_TranslationMap.ToConcurrent(), NodeSize = NodeSize }.Schedule(this, inputDeps); inputDeps = new EngageNearestTargetJob { NodeMap = m_NodeMap, TranslationMap = m_TranslationMap, EntityArray = entityArray, TargetArray = targetEntityArray, EngagedArray = engagedArray, TargetFromEntity = GetComponentDataFromEntity <Target>(), FactionFromEntity = GetComponentDataFromEntity <Faction>(true), DeadFromEntity = GetComponentDataFromEntity <Dead>(true), NodeSize = NodeSize }.Schedule(this, inputDeps); inputDeps = new AddTargetJob { CommandBuffer = commandBuffer.ToConcurrent(), EntityArray = entityArray, TargetArray = targetEntityArray, EngagedArray = engagedArray, TargetFromEntity = GetComponentDataFromEntity <Target>() }.Schedule(count, 64, inputDeps); commandBufferSystem.AddJobHandleForProducer(inputDeps); } return(inputDeps); }
private IEnumerator GenerateNational() { var nationalCapitals = new NativeArray <int>( _politicalBox.CountryHistories.Select(country => country.capital).ToArray(), Allocator.TempJob); var provinceOwnership = new NativeArray <int>( _dataBox.Provinces.Select(province => province.Owner).ToArray(), Allocator.TempJob); var provinceLifeRating = new NativeArray <int>( _dataBox.Provinces.Select(province => province.LifeRating).ToArray(), Allocator.TempJob); var contiguousProvinces = new NativeMultiHashMap <int, float2>(_dataBox.Provinces.Length, Allocator.TempJob); var checkedProvinces = new NativeArray <bool>(_dataBox.Provinces.Length, Allocator.TempJob); var furthestNational = new NativeArray <float2>(_politicalBox.CountryHistories.Length, Allocator.TempJob); _centerNational = new NativeArray <float2>(_politicalBox.CountryHistories.Length, Allocator.TempJob); _longestNational = new NativeArray <float>(_politicalBox.CountryHistories.Length, Allocator.TempJob); _nationalAngles = new NativeArray <float>(_politicalBox.CountryHistories.Length, Allocator.TempJob); _contiguousJobHandle = new ContiguousJob { BorderEnds = _dataBox.BorderEnds, BorderIndices = _dataBox.BorderIndices, CheckedProvinces = checkedProvinces, ContiguousProvinces = contiguousProvinces.ToConcurrent(), ProvinceCentroids = _centerPoints, ProvinceLifeRating = provinceLifeRating, ProvinceOwnership = provinceOwnership, ProvincePixels = _numPoints, NationalCapitals = nationalCapitals, CenterNationals = _centerNational }.Schedule(_politicalBox.CountryHistories.Length, 1, _initialJobHandle); _contiguousJobHandle = new LongestJob { CenterPoints = _centerNational, FurthestPoint = furthestNational, LongestDistance = _longestNational, PointsFound = contiguousProvinces }.Schedule(_politicalBox.CountryHistories.Length, 1, _contiguousJobHandle); _contiguousJobHandle = new AnglesJob { CenterPoints = _centerNational, FurthestPoint = furthestNational, Angles = _nationalAngles }.Schedule(_politicalBox.CountryHistories.Length, 1, _contiguousJobHandle); while (!_contiguousJobHandle.IsCompleted) { yield return(null); } _contiguousJobHandle.Complete(); _numPoints.Dispose(); provinceLifeRating.Dispose(); provinceOwnership.Dispose(); nationalCapitals.Dispose(); contiguousProvinces.Dispose(); checkedProvinces.Dispose(); furthestNational.Dispose(); InstantiateNames(nationalHeader.transform, _centerNational, _nationalAngles, _stringBox.CountryNames, _longestNational, true, out _nationalLoaded); }
public void CreationTopologicalListJobTest() { var b = new Bounds(new float3(9400F, 400F, 0.5F), new float3(9600F, 5200F, 0.5F) * 2F); var spatialHash = new SpatialHash <IsometricData>(b, new float3(192F, 144F, 1F), Allocator.TempJob); var isoObject = new IsometricData { IsoPosition = new float3(17F, -1F, 0F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(39.99997F, -144F), ScreenMax = new float2(71.99997F, -112F) }; //1 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(16F, -1F, 0F), IsoSize = new float3(3F, 1F, 1F), ScreenMin = new float2(-8.000031F, -136F), ScreenMax = new float2(55.99997F, -88F) }; //2 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(13F, -1F, 3F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(-24.00002F, -64F), ScreenMax = new float2(7.999985F, -32F) }; //3 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(17F, -2F, 0F), IsoSize = new float3(3F, 1F, 1F), ScreenMin = new float2(-8.000031F, -152F), ScreenMax = new float2(55.99997F, -104F) }; //4 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(13F, -4F, 2F), IsoSize = new float3(1F, 3F, 1F), ScreenMin = new float2(-72.00002F, -104F), ScreenMax = new float2(-8.000015F, -56F) }; //5 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(14F, -2F, 0F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(-24.00003F, -128F), ScreenMax = new float2(7.999969F, -96F) }; //6 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(14F, -5F, 0F), IsoSize = new float3(1F, 3F, 1F), ScreenMin = new float2(-72.00003F, -152F), ScreenMax = new float2(-8.000031F, -104F) }; //7 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(20F, -1F, 0F), IsoSize = new float3(3F, 1F, 1F), ScreenMin = new float2(55.99997F, -168F), ScreenMax = new float2(120F, -120F) }; //8 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(14F, -1F, 1F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(-8.000031F, -104F), ScreenMax = new float2(23.99997F, -72F) }; //9 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(13F, -2F, 1F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(-40.00002F, -104F), ScreenMax = new float2(-8.000031F, -72F) }; //10 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(17F, -1F, 1F), IsoSize = new float3(3F, 1F, 1F), ScreenMin = new float2(7.999969F, -128F), ScreenMax = new float2(71.99997F, -80F) }; //11 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(13F, -1F, 1F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(-24.00002F, -96F), ScreenMax = new float2(7.999969F, -64F) }; //12 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(14F, -2F, 1F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(-24.00003F, -112F), ScreenMax = new float2(7.999969F, -80F) }; //13 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(18F, -1F, 1F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(55.99997F, -136F), ScreenMax = new float2(87.99997F, -104F) }; //14 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(16F, -1F, 2F), IsoSize = new float3(3F, 1F, 1F), ScreenMin = new float2(-8.000015F, -104F), ScreenMax = new float2(55.99997F, -56F) }; //15 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(13F, -1F, 0F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(-24.00003F, -112F), ScreenMax = new float2(7.999969F, -80F) }; //16 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(13F, -5F, 0F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(-88.00003F, -144F), ScreenMax = new float2(-56.00003F, -112F) }; //17 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(13F, -1F, 2F), IsoSize = new float3(1F, 1F, 1F), ScreenMin = new float2(-24.00002F, -80F), ScreenMax = new float2(7.999985F, -48F) }; //18 spatialHash.Add(ref isoObject); isoObject = new IsometricData { IsoPosition = new float3(13F, -4F, 0F), IsoSize = new float3(1F, 3F, 1F), ScreenMin = new float2(-72.00003F, -136F), ScreenMax = new float2(-8.000031F, -88F) }; //19 spatialHash.Add(ref isoObject); const int iTemCount = 19; var chunkIndicies = new NativeList <int3>(Allocator.TempJob); var cellCount = spatialHash.CellCount; for (int x = 0; x < cellCount.x; x++) { for (int y = 0; y < cellCount.y; y++) { for (int z = 0; z < cellCount.x; z++) { chunkIndicies.Add(new int3(x, y, z)); } } } var topologicalListFrontToBack = new NativeMultiHashMap <int, int>(60, Allocator.TempJob); var queue = new NativeQueue <int>(Allocator.TempJob); var job = new IsoSortingSystem.CreationTopologicalListJob { SpatialHashing = spatialHash, ChunkList = chunkIndicies, TopologicalListFrontToBack = topologicalListFrontToBack.ToConcurrent(), IsometricDataPresent = queue.ToConcurrent() }; job.Schedule(chunkIndicies, 1).Complete(); var hashset = new HashSet <int>(); while (queue.Count > 0) { hashset.Add(queue.Dequeue()); } Assert.AreEqual(iTemCount, hashset.Count); FindAllItem(topologicalListFrontToBack, 18, 3, 5, 3, 15); FindAllItem(topologicalListFrontToBack, 16, 5, 6, 7, 10, 12, 13, 2, 4, 6, 9, 12, 13, 15, 19); FindAllItem(topologicalListFrontToBack, 15); FindAllItem(topologicalListFrontToBack, 14); FindAllItem(topologicalListFrontToBack, 13); FindAllItem(topologicalListFrontToBack, 12, 9, 5, 13, 10, 13, 15, 18, 18); FindAllItem(topologicalListFrontToBack, 11, 14, 15); FindAllItem(topologicalListFrontToBack, 9, 11, 13, 15); FindAllItem(topologicalListFrontToBack, 8, 14); FindAllItem(topologicalListFrontToBack, 6, 4, 7, 13, 13); FindAllItem(topologicalListFrontToBack, 4); FindAllItem(topologicalListFrontToBack, 3); FindAllItem(topologicalListFrontToBack, 2, 1, 4, 6, 9, 11, 13, 15); FindAllItem(topologicalListFrontToBack, 1, 4, 8, 11, 14); FindAllItem(topologicalListFrontToBack, 19, 5, 6, 7, 10, 13, 17); FindAllItem(topologicalListFrontToBack, 17, 7); FindAllItem(topologicalListFrontToBack, 10, 5, 13); FindAllItem(topologicalListFrontToBack, 7); FindAllItem(topologicalListFrontToBack, 5); spatialHash.Dispose(); chunkIndicies.Dispose(); topologicalListFrontToBack.Dispose(); queue.Dispose(); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { //skip to next frame to make sure all the vehicles are initialized if (framesToSkip > 0) { framesToSkip--; return(inputDeps); } if (!isDoneSetup) { isDoneSetup = true; return(OneTimeSetup(inputDeps)); } //schedule resolve next path JobHandle resolveNodeJob = new GetVehicleBodyPositionJob { commandBuffer = m_EntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent(), paths = this.paths, }.Schedule(this, inputDeps); //schedule clear paths occupancy JobHandle clearPathsJob = new ClearPathsOccupancyJob { }.Schedule(this, resolveNodeJob); NativeMultiHashMap <int, VehiclePosition> hashMap = new NativeMultiHashMap <int, VehiclePosition>(10000, Allocator.TempJob); //schedule move vehicle job JobHandle moveVehicleJob = new MoveVehicleBodyJob { commandBuffer = m_EntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent(), map = hashMap.ToConcurrent(), }.Schedule(this, clearPathsJob); moveVehicleJob.Complete(); NativeArray <VehicleBodyMoveAndRotate> vehicleBodies = GetEntityQuery(ComponentType.ReadOnly(typeof(VehicleBodyMoveAndRotate))).ToComponentDataArray <VehicleBodyMoveAndRotate>(Allocator.TempJob, out moveVehicleJob); //schedule move wheel job JobHandle moveVehicleWheelJob = new MoveVehicleWheelJob { deltaTime = Time.deltaTime, commandBuffer = m_EntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent(), bodies = vehicleBodies, }.Schedule(this, moveVehicleJob); //Schedule filljob JobHandle fillPathOccupancy = new FillPathsOccupancyJob { map = hashMap, }.Schedule(this, moveVehicleJob); fillPathOccupancy.Complete(); moveVehicleWheelJob.Complete(); hashMap.Dispose(); vehicleBodies.Dispose(); return(fillPathOccupancy); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { if (AgentMarkers.Capacity < agentGroup.Agents.Length * qtdMarkers * 4) { AgentMarkers.Dispose(); AgentMarkers = new NativeMultiHashMap <int, float3>(agentGroup.Agents.Length * qtdMarkers * 4, Allocator.Persistent); } else { AgentMarkers.Clear(); } if (!CellTagSystem.AgentIDToPos.IsCreated) { return(inputDeps); } TakeMarkers takeMarkersJob = new TakeMarkers { AgentIDToPos = CellTagSystem.AgentIDToPos, AgentMarkers = AgentMarkers.ToConcurrent(), cellToAgent = CellTagSystem.CellToMarkedAgents, MarkerCell = markerGroup.MarkerCell, MarkerPos = markerGroup.Position, Densities = LocalDensities.ToConcurrent() //Entities = markerGroup.Entities, //CommandBuffer = m_SpawnerBarrier.CreateCommandBuffer().ToConcurrent() }; //if (CellTagSystem.AgentIDToPos.IsCreated) // { JobHandle takeMakersHandle = takeMarkersJob.Schedule(markerGroup.Length, 64, inputDeps); takeMakersHandle.Complete(); NativeMultiHashMap <int, float3> agtM = AgentMarkers; NativeMultiHashMapIterator <int> iter; float3 marker; for (int i = 0; i < agentGroup.Length; i++) { bool keepGoing = agtM.TryGetFirstValue(agentGroup.Agents[i].ID, out marker, out iter); if (keepGoing) { //Debug.Log(i); Debug.DrawLine(agentGroup.Positions[i].Value, marker); while (agtM.TryGetNextValue(out marker, ref iter)) { Debug.DrawLine(agentGroup.Positions[i].Value, marker); } } } return(takeMakersHandle); // } // return inputDeps; }
protected override JobHandle OnUpdate(JobHandle inputDeps) { //---------check if we need to run---------// var entSchedule = GetSingletonEntity <CpSysSchedule>(); var cpSchedule = GetSingleton <CpSysSchedule>(); if (!cpSchedule.CanRunSysUpdateAtt()) { return(inputDeps); } _lastRunFrame = Time.frameCount; var em = World.Active.EntityManager; //---------preapre---------// is_converge_arr[0] = true; int cnt_relation = _group_rel.CalculateLength(); var access_att_ro = GetComponentDataFromEntity <CpAttitude>(isReadOnly: true); var access_att_rw = GetComponentDataFromEntity <CpAttitude>(); var access_schedule = GetComponentDataFromEntity <CpSysSchedule>(); var access_dirty = GetComponentDataFromEntity <CpIsDirty>(isReadOnly: false); var accbuf_relation = GetBufferFromEntity <CpRelationBuf>(isReadOnly: true); //---------run---------// //---------collect modifications---------// var jobCollect = new CollectJob { acc_att = access_att_ro, is_converge_arr = is_converge_arr, orig_attitudes = orig_attitudes.ToConcurrent(), target_mods = target_mods.ToConcurrent(), unique_nodes = unique_nodes.ToConcurrent(), }.Schedule(this, inputDeps); var jobCheckConverge = new CheckConvergeJob { is_converge_arr = is_converge_arr, entSchedule = entSchedule, acc_schedule = access_schedule, }.Schedule(jobCollect); //---------assign back to attitudes---------// var jobWriteBack = new WriteBackJob { acc_att = access_att_rw, }.Schedule(target_mods, 1, jobCollect); var jobClearTargetMods = target_mods.ClearWithJob(jobWriteBack); var jobSetDirtyNode = new SetDirtyByTargetNodes { orig_attitude = orig_attitudes, accbuf_relation = accbuf_relation, acc_att = access_att_ro, acc_dirty = access_dirty, NODE_THRES = NODE_MOD_THRES, }.Schedule(unique_nodes, 8, jobWriteBack); var jobClearUniqueNodes = unique_nodes.ClearWithJob(jobSetDirtyNode); var jobClearOrigAttitude = orig_attitudes.ClearWithJob(jobSetDirtyNode); var handle_clear = JobHandle.CombineDependencies(jobClearTargetMods, jobClearUniqueNodes, jobClearOrigAttitude); return(JobHandle.CombineDependencies(handle_clear, jobCheckConverge)); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { this.DisposeBuffers(); var handle = inputDeps; // ---------------------------------------------- // Allocate Memory var groupLength = this._rendererGroup.CalculateLength(); this._localToWorlds = new NativeArray <LocalToWorld>(groupLength, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); this._animationPlayData = new NativeArray <AnimationPlayData>(groupLength, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); // ---------------------------------------------- // CopyComponentData handle = new CopyComponentData <LocalToWorld> { Source = this._rendererGroup.GetComponentDataArray <LocalToWorld>(), Results = this._localToWorlds, }.Schedule(groupLength, 32, handle); handle = new CopyComponentData <AnimationPlayData> { Source = this._rendererGroup.GetComponentDataArray <AnimationPlayData>(), Results = this._animationPlayData, }.Schedule(groupLength, 32, handle); // ---------------------------------------------- // アニメーションタイプ毎に再生情報を振り分けていく // FIXME: 今回の実装でNativeMultiHashMapで確保しているメモリはサンプルのために適当。 // → ここらの仕様は最大描画数などを考慮した上で、どれくらい必要なのかすり合わせた方が良いかと思われる。 var playDataMap = new NativeMultiHashMap <int, SendPlayData>(1000000, Allocator.TempJob); handle = new MapAnimationPlayDataJob { LocalToWorlds = this._localToWorlds, AnimationPlayData = this._animationPlayData, SendPlayDataMap = playDataMap.ToConcurrent(), }.Schedule(groupLength, 32, handle); // ---------------------------------------------- // 再生情報の更新 handle = new PlayAnimationJob { DeltaTime = Time.deltaTime, AnimationLengthList = this._animationLengthList, MaxAnimationType = this._maxAnimationType, }.Schedule(this, handle); handle.Complete(); // ---------------------------------------------- // GPU Instancing for (int i = 0; i < this._maxAnimationType; ++i) { // アニメーションタイプに応じた再生情報の取得 var buffer = new NativeArray <SendPlayData>(groupLength, Allocator.Temp); SendPlayData sendPlayData; NativeMultiHashMapIterator <int> it; int instanceCount = 0; // ※ iの値はAnimationTypeに該当 if (!playDataMap.TryGetFirstValue(i, out sendPlayData, out it)) { continue; } do { // 同一のアニメーションが再生されているインスタンスの再生情報をbufferに確保していく。 buffer[instanceCount] = sendPlayData; ++instanceCount; } while (playDataMap.TryGetNextValue(out sendPlayData, ref it)); // Materialに対し再生するアニメーションデータなど(ComputeBuffer)を設定していく。 var renderer = this._animationMeshes[i]; var computeBuffers = this._sendBuffers[i]; // 初回 or 同一のアニメーションが再生されているインスタンス数に変更があったらバッファを初期化 if (computeBuffers.CurrentInstance <= 0 || computeBuffers.CurrentInstance != instanceCount) { if (computeBuffers.SendPlayBuffer != null) { computeBuffers.SendPlayBuffer.Release(); } computeBuffers.SendPlayBuffer = new ComputeBuffer(instanceCount, Marshal.SizeOf(typeof(SendPlayData))); if (computeBuffers.GPUInstancingArgsBuffer != null) { computeBuffers.GPUInstancingArgsBuffer.Release(); } computeBuffers.GPUInstancingArgsBuffer = new ComputeBuffer(1, this._GPUInstancingArgs.Length * sizeof(uint), ComputeBufferType.IndirectArguments); computeBuffers.CurrentInstance = instanceCount; } // 再生情報の設定 var bufferSlice = buffer.Slice(0, instanceCount); var copyArray = new NativeArray <SendPlayData>(bufferSlice.Length, Allocator.Temp); bufferSlice.CopyTo(copyArray); // ※ComputeBufferにはNativeArrayを渡すことが可能。(内部的にもポインタ渡ししていた覚え) computeBuffers.SendPlayBuffer.SetData(copyArray); renderer.AnimationMaterial.SetBuffer(this._playDataBufferID, computeBuffers.SendPlayBuffer); // 「Graphics.DrawMeshInstancedIndirect -> bufferWithArgs」の設定 this._GPUInstancingArgs[0] = (uint)renderer.Mesh.GetIndexCount(0); this._GPUInstancingArgs[1] = (uint)instanceCount; this._GPUInstancingArgs[2] = (uint)renderer.Mesh.GetIndexStart(0); this._GPUInstancingArgs[3] = (uint)renderer.Mesh.GetBaseVertex(0); computeBuffers.GPUInstancingArgsBuffer.SetData(this._GPUInstancingArgs); // 描画 Graphics.DrawMeshInstancedIndirect( renderer.Mesh, 0, renderer.AnimationMaterial, new Bounds(Vector3.zero, 1000000 * Vector3.one), computeBuffers.GPUInstancingArgsBuffer); buffer.Dispose(); copyArray.Dispose(); } playDataMap.Dispose(); return(handle); }