protected override JobHandle OnUpdate(JobHandle inputDeps) { if (m_firstFrame) { var archetype = EntityManager.CreateArchetype(typeof(Translation), typeof(Rotation), typeof(Collider), typeof(LocalToWorld)); EntityManager.CreateEntity(archetype, 50, Allocator.Temp); var random = new Random(1123); Entities.WithStoreEntityQueryInField(ref m_query).WithAll <LocalToWorld>().ForEach((ref Translation c0, ref Rotation c1, ref Collider c2) => { c0.Value = random.NextFloat3(new float3(-18f), new float3(18f)); c1.Value = random.NextQuaternionRotation(); c2 = new CapsuleCollider(float3.zero, new float3(2f), 0.6f); }).Run(); m_firstFrame = false; } var typeGroup = Physics.BuildLayerChunkTypeGroup(this); CollisionLayerSettings settings = new CollisionLayerSettings { layerType = CollisionLayerType.Discrete, worldBucketCountPerAxis = new int3(1, 4, 4), worldAABB = new Latios.PhysicsEngine.AABB(-1000f, 1000f), }; Physics.BuildCollisionLayer(m_query, typeGroup, settings, Allocator.TempJob, default, out CollisionLayer layer).Complete();
protected override void OnUpdate() { if (m_firstFrame) { var archetype = EntityManager.CreateArchetype(typeof(Translation), typeof(Rotation), typeof(Collider), typeof(LocalToWorld)); EntityManager.CreateEntity(archetype, 50, Allocator.Temp); var random = new Random(1123); Entities.WithStoreEntityQueryInField(ref m_query).WithAll <LocalToWorld>().ForEach((ref Translation c0, ref Rotation c1, ref Collider c2) => { c0.Value = random.NextFloat3(new float3(-18f), new float3(18f)); c1.Value = random.NextQuaternionRotation(); c2 = new CapsuleCollider(float3.zero, new float3(2f), 0.6f); }).Run(); m_firstFrame = false; } CollisionLayerSettings settings = new CollisionLayerSettings { worldSubdivisionsPerAxis = new int3(1, 4, 4), worldAABB = new Aabb(-1000f, 1000f), }; Dependency = Physics.BuildCollisionLayer(m_query, this).WithSettings(settings).ScheduleParallel(out CollisionLayer layer, Allocator.TempJob, Dependency); Dependency = PhysicsDebug.DrawFindPairs(layer).ScheduleParallel(Dependency); Dependency = layer.Dispose(Dependency); }
//Todo: World settings? internal TestCollisionLayer(int bodyCount, CollisionLayerSettings settings, Allocator allocator) { worldMin = settings.worldAABB.min; worldAxisStride = (settings.worldAABB.max - worldMin) / settings.worldSubdivisionsPerAxis; worldSubdivisionsPerAxis = settings.worldSubdivisionsPerAxis; bucketStartsAndCounts = new NativeArray <int2>(settings.worldSubdivisionsPerAxis.x * settings.worldSubdivisionsPerAxis.y * settings.worldSubdivisionsPerAxis.z + 1, allocator, NativeArrayOptions.UninitializedMemory); xmins = new NativeArray <float>(bodyCount, allocator, NativeArrayOptions.UninitializedMemory); xmaxs = new NativeArray <float>(bodyCount, allocator, NativeArrayOptions.UninitializedMemory); yzminmaxs = new NativeArray <float4>(bodyCount, allocator, NativeArrayOptions.UninitializedMemory); bodies = new NativeArray <ColliderBody>(bodyCount, allocator, NativeArrayOptions.UninitializedMemory); }
protected override void OnUpdate() { CollisionLayerSettings settings = new CollisionLayerSettings { worldSubdivisionsPerAxis = new int3(2, 2, 2), worldAABB = new Aabb { min = new float3(-50f, -50f, -50f), max = new float3(50f, 50f, 50f) }, }; Dependency = Physics.BuildCollisionLayer(m_query, this).WithSettings(settings).ScheduleParallel(out CollisionLayer layer, Allocator.TempJob, Dependency); Dependency = PhysicsDebug.DrawLayer(layer).ScheduleParallel(Dependency); Dependency = layer.Dispose(Dependency); }
protected override void OnUpdate() { if (m_frameCount <= 1) //Due to a missing line below, I was actually profiling 200000 entities instead of 100000. This reproduces that behavior. { var archetype = EntityManager.CreateArchetype(typeof(Translation), typeof(Rotation), typeof(Collider), typeof(LocalToWorld)); EntityManager.CreateEntity(archetype, 100000, Allocator.Temp); var random = new Random(1123); Entities.ForEach((ref Translation trans, ref Rotation rot, ref Collider col) => { trans.Value = random.NextFloat3(new float3(-2000f), new float3(2000f)); rot.Value = random.NextQuaternionRotation(); col = new CapsuleCollider(random.NextFloat3(-10f, 10f), random.NextFloat3(-10f, 10f), random.NextFloat(0f, 10f)); }).Run(); } CollisionLayerSettings settings = new CollisionLayerSettings { worldSubdivisionsPerAxis = new int3(1, 4, 4), worldAABB = new Aabb(-2000f, 2000f), }; for (int i = 0; i < 3; i++) { var dcb = new DestroyCommandBuffer(Allocator.TempJob); var processor = new DestroyOnCollisionProcessor { dcb = dcb.AsParallelWriter() }; UnityEngine.Profiling.Profiler.BeginSample("BuildLayer"); Physics.BuildCollisionLayer(m_query, this).WithSettings(settings).ScheduleParallel(out CollisionLayer layer, Allocator.TempJob).Complete(); UnityEngine.Profiling.Profiler.EndSample(); UnityEngine.Profiling.Profiler.BeginSample("FindPairs"); Physics.FindPairs(layer, processor).ScheduleParallel().Complete(); UnityEngine.Profiling.Profiler.EndSample(); dcb.Dispose(); layer.Dispose(); } m_frameCount++; //This line was missing which caused me to measure 200,000 colliders instead of 100,000 }
public void BuildLayerPerformanceTests(int count, uint seed, CollisionLayerSettings settings) { Random random = new Random(seed); random.InitState(seed); World world = new World("Test World"); var system = world.CreateSystem <FixedSimulationSystemGroup>(); var eq = world.EntityManager.CreateEntityQuery(typeof(Translation), typeof(Rotation), typeof(Collider), typeof(LocalToWorld)); var archetype = world.EntityManager.CreateArchetype(typeof(Translation), typeof(Rotation), typeof(Collider), typeof(LocalToWorld)); world.EntityManager.CreateEntity(archetype, count, Allocator.Temp); new GenerateJob { random = new Random(seed), aabb = settings.worldAABB }.Run(eq); var typeGroup = BuildCollisionLayerP4.BuildLayerChunkTypeGroup(system); var layer = new TestCollisionLayer(count, settings, Allocator.TempJob); var layerIndices = new NativeArray <int>(count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var aabbs = new NativeArray <Aabb>(count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var transforms = new NativeArray <RigidTransform>(count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); SampleUnit unit = count > 9999 ? SampleUnit.Millisecond : SampleUnit.Microsecond; Measure.Method(() => { new BuildCollisionLayerP4.Part1FromQueryJob { layer = layer, aabbs = aabbs, typeGroup = typeGroup, layerIndices = layerIndices, rigidTransforms = transforms }.Run(eq); }) .SampleGroup("Part1") .WarmupCount(0) .MeasurementCount(1) .Run(); Measure.Method(() => { new BuildCollisionLayerP4.Part2Job { layer = layer, layerIndices = layerIndices }.Run(); }) .SampleGroup("Part2") .WarmupCount(0) .MeasurementCount(1) .Run(); Measure.Method(() => { new BuildCollisionLayerP4.Part3FromQueryJob { layer = layer, aabbs = aabbs, layerIndices = layerIndices, rigidTranforms = transforms, typeGroup = typeGroup }.Run(eq); }) .SampleGroup("Part3") .WarmupCount(0) .MeasurementCount(1) .Run(); var layerBetter = new TestCollisionLayer(layer, Allocator.TempJob); var layerNew = new TestCollisionLayer(layer, Allocator.TempJob); Measure.Method(() => { new BuildCollisionLayerP4.Part4Job { layer = layer }.Run(layer.BucketCount); //}.Schedule(layer.BucketCount, 1).Complete(); }) .SampleGroup("Part4Original") .WarmupCount(0) .MeasurementCount(1) .Run(); Measure.Method(() => { new BuildCollisionLayerP4.Part4JobBetter { layer = layerBetter }.Run(layerBetter.BucketCount); //}.Schedule(layer.BucketCount, 1).Complete(); }) .SampleGroup("Part4Better") .WarmupCount(0) .MeasurementCount(1) .Run(); Measure.Method(() => { new BuildCollisionLayerP4.Part4JobNew { layer = layerBetter }.Run(layerBetter.BucketCount); //}.Schedule(layer.BucketCount, 1).Complete(); }) .SampleGroup("Part4New") .WarmupCount(0) .MeasurementCount(1) .Run(); layerNew.Dispose(); layerBetter.Dispose(); layer.Dispose(); world.Dispose(); }
public void BuildLayerPerformanceTests(int count, uint seed, CollisionLayerSettings settings) { Random random = new Random(seed); random.InitState(seed); World world = new World("Test World"); var system = world.CreateSystem <FixedSimulationSystemGroup>(); var eq = world.EntityManager.CreateEntityQuery(typeof(Translation), typeof(Rotation), typeof(Collider), typeof(LocalToWorld)); var archetype = world.EntityManager.CreateArchetype(typeof(Translation), typeof(Rotation), typeof(Collider), typeof(LocalToWorld)); var e = world.EntityManager.CreateEntity(archetype, count, Allocator.Persistent); e.Dispose(); new GenerateJob { random = new Random(seed), aabb = settings.worldAABB }.Run(eq); { var typeGroup = BuildCollisionLayerP4.BuildLayerChunkTypeGroup(system); var layer = new TestCollisionLayer(count, settings, Allocator.Persistent); var layerIndices = new NativeArray <int>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var aabbs = new NativeArray <Aabb>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var transforms = new NativeArray <RigidTransform>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); SampleUnit unit = count > 9999 ? SampleUnit.Millisecond : SampleUnit.Microsecond; Measure.Method(() => { new BuildCollisionLayerP4.Part1FromQueryJob { layer = layer, aabbs = aabbs, typeGroup = typeGroup, layerIndices = layerIndices, rigidTransforms = transforms }.Run(eq); new BuildCollisionLayerP4.Part2Job { layer = layer, layerIndices = layerIndices }.Run(); new BuildCollisionLayerP4.Part3FromQueryJob { layer = layer, aabbs = aabbs, layerIndices = layerIndices, rigidTranforms = transforms, typeGroup = typeGroup }.Run(eq); new BuildCollisionLayerP4.Part4Job { layer = layer }.Run(layer.BucketCount); }) .SampleGroup("OldVersion") .WarmupCount(0) .MeasurementCount(1) .Run(); layer.Dispose(); } { var typeGroup = BuildCollisionLayerP4.BuildLayerChunkTypeGroup(system); var layer = new TestCollisionLayer(count, settings, Allocator.Persistent); var layerIndices = new NativeArray <int>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var aabbs = new NativeArray <Aabb>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var transforms = new NativeArray <RigidTransform>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); SampleUnit unit = count > 9999 ? SampleUnit.Millisecond : SampleUnit.Microsecond; Measure.Method(() => { new BuildCollisionLayerP4.Part1FromQueryJob { layer = layer, aabbs = aabbs, typeGroup = typeGroup, layerIndices = layerIndices, rigidTransforms = transforms }.Run(eq); new BuildCollisionLayerP4.Part2Job { layer = layer, layerIndices = layerIndices }.Run(); new BuildCollisionLayerP4.Part3FromQueryJob { layer = layer, aabbs = aabbs, layerIndices = layerIndices, rigidTranforms = transforms, typeGroup = typeGroup }.Run(eq); new BuildCollisionLayerP4.Part4JobBetter { layer = layer }.Run(layer.BucketCount); }) .SampleGroup("OldVersionBetter") .WarmupCount(0) .MeasurementCount(1) .Run(); layer.Dispose(); } //NewVersion { var typeGroup = BuildCollisionLayerOldVsNew.BuildLayerChunkTypeGroup(system); var layer = new TestCollisionLayer(count, settings, Allocator.Persistent); var layerIndices = new NativeArray <int>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var remapSrcArray = new NativeArray <int>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var xmins = new NativeArray <float>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var aos = new NativeArray <BuildCollisionLayerOldVsNew.ColliderAoSData>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); SampleUnit unit = count > 9999 ? SampleUnit.Millisecond : SampleUnit.Microsecond; Measure.Method(() => { new BuildCollisionLayerOldVsNew.Part1FromQueryJob { layer = layer, typeGroup = typeGroup, layerIndices = layerIndices, xmins = xmins, colliderAoS = aos }.Run(eq); new BuildCollisionLayerOldVsNew.Part2Job { layer = layer, layerIndices = layerIndices }.Run(); new BuildCollisionLayerOldVsNew.Part3Job { layerIndices = layerIndices, unsortedSrcIndices = remapSrcArray }.Run(count); new BuildCollisionLayerOldVsNew.Part4Job { unsortedSrcIndices = remapSrcArray, xmins = xmins, bucketStartAndCounts = layer.bucketStartsAndCounts }.Run(layer.BucketCount); new BuildCollisionLayerOldVsNew.Part5Job { layer = layer, colliderAoS = aos, remapSrcIndices = remapSrcArray }.Run(count); }) .SampleGroup("NewVersion") .WarmupCount(0) .MeasurementCount(1) .Run(); remapSrcArray.Dispose(); layer.Dispose(); } { var typeGroup = BuildCollisionLayerOldVsNew.BuildLayerChunkTypeGroup(system); var layer = new TestCollisionLayer(count, settings, Allocator.Persistent); var layerIndices = new NativeArray <int>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var remapSrcArray = new NativeArray <int>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var xmins = new NativeArray <float>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); var aos = new NativeArray <BuildCollisionLayerOldVsNew.ColliderAoSData>(count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); SampleUnit unit = count > 9999 ? SampleUnit.Millisecond : SampleUnit.Microsecond; Measure.Method(() => { new BuildCollisionLayerOldVsNew.Part1FromQueryJob { layer = layer, typeGroup = typeGroup, layerIndices = layerIndices, xmins = xmins, colliderAoS = aos }.Run(eq); new BuildCollisionLayerOldVsNew.Part2Job { layer = layer, layerIndices = layerIndices }.Run(); new BuildCollisionLayerOldVsNew.Part3Job { layerIndices = layerIndices, unsortedSrcIndices = remapSrcArray }.Run(count); new BuildCollisionLayerOldVsNew.Part4JobUnity { unsortedSrcIndices = remapSrcArray, xmins = xmins, bucketStartAndCounts = layer.bucketStartsAndCounts }.Run(layer.BucketCount); new BuildCollisionLayerOldVsNew.Part5Job { layer = layer, colliderAoS = aos, remapSrcIndices = remapSrcArray }.Run(count); }) .SampleGroup("NewVersionUnity") .WarmupCount(0) .MeasurementCount(1) .Run(); remapSrcArray.Dispose(); layer.Dispose(); } world.Dispose(); }