public void DoubleDispose() { using (var ms = new MemoryStream()) { var blockStream = new BlockStream(Zstd, ms, CompressionMode.Compress); blockStream.Dispose(); blockStream.Dispose(); } }
public void ToArray([Values(1, 100, 200)] int count, [Values(1, 3, 10)] int batchSize) { var stream = new BlockStream(count, 0x11843789); var fillInts = new WriteInts { Writer = stream }; fillInts.Schedule(count, batchSize).Complete(); var array = stream.ToNativeArray <int>(); int itemIndex = 0; for (int i = 0; i != count; ++i) { for (int j = 0; j < i; ++j) { Assert.AreEqual(j, array[itemIndex]); itemIndex++; } } array.Dispose(); stream.Dispose(); }
public void Dispose() { if (!_leaveOpen) { _blockStream.Dispose(); } _writer.Dispose(); }
public void WriteWithoutBegin() { var stream = new BlockStream(1, 0x9b98651c); BlockStream.Writer writer = stream; Assert.Throws <ArgumentException>(() => writer.Write(5)); stream.Dispose(); }
public void OutOfBoundsWrite() { var stream = new BlockStream(1); BlockStream.Writer writer = stream; Assert.Throws <UnityEngine.Assertions.AssertionException>(() => writer.BeginForEachIndex(-1)); Assert.Throws <UnityEngine.Assertions.AssertionException>(() => writer.BeginForEachIndex(2)); stream.Dispose(); }
public void OutOfBoundsWrite() { var stream = new BlockStream(1, 0x9b98651c); BlockStream.Writer writer = stream; Assert.Throws <ArgumentException>(() => writer.BeginForEachIndex(-1)); Assert.Throws <ArgumentException>(() => writer.BeginForEachIndex(2)); stream.Dispose(); }
public void CreateAndDestroy([Values(1, 100, 200)] int count) { var stream = new BlockStream(count, 0x9b98651b); Assert.IsTrue(stream.IsCreated); Assert.IsTrue(stream.ForEachCount == count); Assert.IsTrue(stream.ComputeItemCount() == 0); stream.Dispose(); Assert.IsFalse(stream.IsCreated); }
public void JacobianIteratorHasJacobiansLeftTest() { var jacobianStream = new BlockStream(1, 0x01234567); BlockStream.Reader jacobianStreamReader = jacobianStream; int workItemIndex = 0; var jacIterator = new JacobianIterator(jacobianStreamReader, workItemIndex); Assert.IsFalse(jacIterator.HasJacobiansLeft()); jacobianStream.Dispose(); }
public void Dispose() { _dataFile?.Flush(); _dataFile?.Close(); _dataFile?.Dispose(); _dataFile = null; _indexFile?.Flush(); _indexFile?.Close(); _indexFile?.Dispose(); _indexFile = null; }
protected override JobHandle OnUpdate(JobHandle inputDeps) { if (m_CharacterControllersGroup.CalculateEntityCount() == 0) { return(inputDeps); } var chunks = m_CharacterControllersGroup.CreateArchetypeChunkArray(Allocator.TempJob); var ccComponentType = GetArchetypeChunkComponentType <CharacterControllerComponentData>(); var ccInternalType = GetArchetypeChunkComponentType <CharacterControllerInternalData>(); var physicsColliderType = GetArchetypeChunkComponentType <PhysicsCollider>(); var translationType = GetArchetypeChunkComponentType <Translation>(); var rotationType = GetArchetypeChunkComponentType <Rotation>(); BlockStream deferredImpulses = new BlockStream(chunks.Length, 0xCA37B9F2); var ccJob = new CharacterControllerJob() { // Archetypes CharacterControllerComponentType = ccComponentType, CharacterControllerInternalType = ccInternalType, PhysicsColliderType = physicsColliderType, TranslationType = translationType, RotationType = rotationType, // Input DeltaTime = Time.fixedDeltaTime, PhysicsWorld = m_BuildPhysicsWorldSystem.PhysicsWorld, DeferredImpulseWriter = deferredImpulses }; inputDeps = JobHandle.CombineDependencies(inputDeps, m_ExportPhysicsWorldSystem.FinalJobHandle); inputDeps = ccJob.Schedule(m_CharacterControllersGroup, inputDeps); var applyJob = new ApplyDefferedPhysicsUpdatesJob() { Chunks = chunks, DeferredImpulseReader = deferredImpulses, PhysicsVelocityData = GetComponentDataFromEntity <PhysicsVelocity>(), PhysicsMassData = GetComponentDataFromEntity <PhysicsMass>(), TranslationData = GetComponentDataFromEntity <Translation>(), RotationData = GetComponentDataFromEntity <Rotation>() }; inputDeps = applyJob.Schedule(inputDeps); var disposeHandle = deferredImpulses.Dispose(inputDeps); // Must finish all jobs before physics step end m_EndFramePhysicsSystem.HandlesToWaitFor.Add(disposeHandle); return(inputDeps); }
public void ItemCount([Values(1, 100, 200)] int count, [Values(1, 3, 10)] int batchSize) { var stream = new BlockStream(count, 0xd3e8afdd); var fillInts = new WriteInts { Writer = stream }; fillInts.Schedule(count, batchSize).Complete(); Assert.AreEqual(count * (count - 1) / 2, stream.ComputeItemCount()); stream.Dispose(); }
public void ParallelWriteThrows() { var stream = new BlockStream(100, 0xd3e8afdd); var fillInts = new WriteInts { Writer = stream }; var writerJob = fillInts.Schedule(100, 16); Assert.Throws <InvalidOperationException>(() => fillInts.Schedule(100, 16)); writerJob.Complete(); stream.Dispose(); }
public void DisposeAfterSchedule() { var stream = new BlockStream(100, 0xd3e8afdd); var fillInts = new WriteInts { Writer = stream }; var writerJob = fillInts.Schedule(100, 16); var disposeJob = stream.Dispose(writerJob); Assert.IsFalse(stream.IsCreated); disposeJob.Complete(); }
public void IncorrectTypedReads() { var stream = new BlockStream(1); BlockStream.Writer writer = stream; writer.BeginForEachIndex(0); writer.Write <int>(5); writer.EndForEachIndex(); BlockStream.Reader reader = stream; reader.BeginForEachIndex(0); Assert.Throws <UnityEngine.Assertions.AssertionException>(() => reader.Read <float>()); stream.Dispose(); }
public void PopulateInts([Values(1, 100, 200)] int count, [Values(1, 3, 10)] int batchSize) { var stream = new BlockStream(count, 0x9b98651c); var fillInts = new WriteInts { Writer = stream }; var jobHandle = fillInts.Schedule(count, batchSize); var compareInts = new ReadInts { Reader = stream }; var res0 = compareInts.Schedule(count, batchSize, jobHandle); var res1 = compareInts.Schedule(count, batchSize, jobHandle); res0.Complete(); res1.Complete(); stream.Dispose(); }
public void TreeOverlapPerfTest(int elementCount, bool newOverlap) { // Execute dummy job just to get Burst compilation out of the way. { var dummyBlockStream = new BlockStream(1, 0, Allocator.TempJob); var dummyNodes = new NativeArray <Node>(0, Allocator.TempJob); var dummyFilters = new NativeArray <CollisionFilter>(0, Allocator.TempJob); new TestTreeOverlapJob { CollisionPairWriter = dummyBlockStream, Nodes = dummyNodes, Filter = dummyFilters, NumObjects = 0, DummyRun = true }.Run(); dummyBlockStream.Dispose(); dummyNodes.Dispose(); dummyFilters.Dispose(); } elementCount *= 2; int numNodes = elementCount / 3 * 2 + 4; var points = new NativeArray <PointAndIndex>(elementCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var aabbs = new NativeArray <Aabb>(elementCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var filters = new NativeArray <CollisionFilter>(elementCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); // Override filter data with default filters. for (int i = 0; i < filters.Length; i++) { filters[i] = CollisionFilter.Default; } InitInputWithCopyArrays(points, aabbs, filters); var nodes = new NativeArray <Node>(numNodes, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var bvh = new BoundingVolumeHierarchy(nodes); bvh.Build(points, aabbs, out int numNodesOut); bvh.CheckIntegrity(); var collisionPairs = new BlockStream(1, 0xd586fc6e); var job = new TestTreeOverlapJob { Nodes = nodes, Filter = filters, NumObjects = elementCount, CollisionPairWriter = collisionPairs, DummyRun = false }; Measure.Method(() => { job.Run(); }).Definition(sampleUnit: SampleUnit.Millisecond) .MeasurementCount(1) .Run(); points.Dispose(); aabbs.Dispose(); nodes.Dispose(); collisionPairs.Dispose(); filters.Dispose(); }
public unsafe void OverlapTaskFilteringTest([Values(2, 10, 33, 100)] int elementCount) { elementCount *= 2; int numNodes = elementCount + Constants.MaxNumTreeBranches; var points = new NativeArray <PointAndIndex>(elementCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var aabbs = new NativeArray <Aabb>(elementCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var bodyFilters = new NativeArray <CollisionFilter>(elementCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory); InitInputWithCopyArrays(points, aabbs, bodyFilters); var nodes = new NativeArray <Node>(numNodes, Allocator.Temp, NativeArrayOptions.UninitializedMemory); Node *nodesPtr = (Node *)nodes.GetUnsafePtr(); var seenUnfiltered = new HashSet <BodyIndexPair>(); { var bvhUnfiltered = new BoundingVolumeHierarchy(nodes); bvhUnfiltered.Build(points, aabbs, out int numNodesOut); bvhUnfiltered.CheckIntegrity(); EverythingWriter pairWriter = new EverythingWriter { SeenPairs = seenUnfiltered }; BoundingVolumeHierarchy.TreeOverlap(ref pairWriter, nodesPtr, nodesPtr); } var nodeFilters = new NativeArray <CollisionFilter>(numNodes, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var bvhFiltered = new BoundingVolumeHierarchy(nodes, nodeFilters); int numNodesFilteredTree; bvhFiltered.Build(points, aabbs, out numNodesFilteredTree); bvhFiltered.BuildCombinedCollisionFilter(bodyFilters, 0, numNodesFilteredTree - 1); var filteredCollisionPairs = new BlockStream(1, 0xec87b613); BlockStream.Writer filteredPairWriter = filteredCollisionPairs; filteredPairWriter.BeginForEachIndex(0); CollisionFilter *bodyFiltersPtr = (CollisionFilter *)bodyFilters.GetUnsafePtr(); var bufferedPairs = new Broadphase.BodyPairWriter(&filteredPairWriter, bodyFiltersPtr); CollisionFilter *nodeFiltersPtr = (CollisionFilter *)nodeFilters.GetUnsafePtr(); BoundingVolumeHierarchy.TreeOverlap(ref bufferedPairs, nodesPtr, nodesPtr, nodeFiltersPtr, nodeFiltersPtr); bufferedPairs.Close(); filteredPairWriter.EndForEachIndex(); BlockStream.Reader filteredPairReader = filteredCollisionPairs; filteredPairReader.BeginForEachIndex(0); // Check that every pair in our filtered set also appears in the unfiltered set while (filteredPairReader.RemainingItemCount > 0) { var pair = filteredPairReader.Read <BodyIndexPair>(); Assert.IsTrue(seenUnfiltered.Contains(pair)); seenUnfiltered.Remove(pair); // Remove the pair } // Pairs were removed, so the only remaining ones should be filtered foreach (BodyIndexPair pair in seenUnfiltered) { bool shouldCollide = CollisionFilter.IsCollisionEnabled(bodyFilters[pair.BodyAIndex], bodyFilters[pair.BodyBIndex]); Assert.IsFalse(shouldCollide); } nodeFilters.Dispose(); nodes.Dispose(); bodyFilters.Dispose(); aabbs.Dispose(); points.Dispose(); filteredCollisionPairs.Dispose(); }
public unsafe void BuildTreeAndOverlapTasks([Values(2, 10, 33, 100)] int elementCount) { const int threadCount = 8; elementCount *= 2; int numNodes = elementCount + Constants.MaxNumTreeBranches; var points = new NativeArray <PointAndIndex>(elementCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var aabbs = new NativeArray <Aabb>(elementCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var filters = new NativeArray <CollisionFilter>(elementCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var nodefilters = new NativeArray <CollisionFilter>(numNodes, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var branchCount = new NativeArray <int>(1, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); InitInputWithCopyArrays(points, aabbs, filters); // Override filter data with default filters. for (int i = 0; i < filters.Length; i++) { filters[i] = CollisionFilter.Default; } for (int i = 0; i < nodefilters.Length; i++) { nodefilters[i] = CollisionFilter.Default; } var nodes = new NativeArray <Node>(numNodes, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var ranges = new NativeArray <Range>(Constants.MaxNumTreeBranches, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var branchNodeOffset = new NativeArray <int>(Constants.MaxNumTreeBranches, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var shouldDoWork = new NativeArray <int>(1, Allocator.TempJob); shouldDoWork[0] = 1; int oldBranchCount = branchCount[0]; JobHandle handle = new BuildFirstNLevelsJob { Points = points, Nodes = (Node *)nodes.GetUnsafePtr(), Ranges = ranges, BranchNodeOffsets = branchNodeOffset, BranchCount = branchCount, ThreadCount = threadCount, ShouldDoWork = shouldDoWork }.Schedule(); handle = new BuildBranchesJob { Points = points, Aabbs = aabbs, BodyFilters = filters, Nodes = (Node *)nodes.GetUnsafePtr(), Ranges = ranges, BranchNodeOffsets = branchNodeOffset, BranchCount = branchCount }.ScheduleUnsafeIndex0(branchCount, 1, handle); new FinalizeTreeJob { Aabbs = aabbs, LeafFilters = filters, Nodes = (Node *)nodes.GetUnsafePtr(), BranchNodeOffsets = branchNodeOffset, NumNodes = numNodes, BranchCount = branchCount, ShouldDoWork = shouldDoWork, OldBranchCount = oldBranchCount }.Schedule(handle).Complete(); int numBranchOverlapPairs = branchCount[0] * (branchCount[0] + 1) / 2; var nodePairIndices = new NativeList <int2>(Allocator.TempJob); nodePairIndices.ResizeUninitialized(numBranchOverlapPairs); var collisionPairs = new BlockStream(numBranchOverlapPairs, 0xb08c3d78); handle = new Broadphase.DynamicVsDynamicBuildBranchNodePairsJob { Ranges = ranges, NumBranches = branchCount, NodePairIndices = nodePairIndices }.Schedule(); handle = new Broadphase.DynamicVsDynamicFindOverlappingPairsJob { DynamicNodes = nodes, PairWriter = collisionPairs, BodyFilters = filters, NodePairIndices = nodePairIndices, DynamicNodeFilters = nodefilters, }.Schedule(nodePairIndices, numBranchOverlapPairs, handle); handle.Complete(); int numPairs = collisionPairs.ComputeItemCount(); Assert.AreEqual(elementCount / 2, numPairs); //Debug.Log($"Num colliding pairs: {numPairs}"); var bvh = new BoundingVolumeHierarchy(nodes); bvh.CheckIntegrity(); nodePairIndices.Dispose(); filters.Dispose(); nodefilters.Dispose(); nodes.Dispose(); ranges.Dispose(); collisionPairs.Dispose(); branchCount.Dispose(); shouldDoWork.Dispose(); }
public void Dispose() { _reader.Dispose(); _blockStream.Dispose(); }
public unsafe void ManifoldQueryTest() { const uint seed = 0x98765432; Random rnd = new Random(seed); int numWorlds = 1000; uint dbgWorld = 0; if (dbgWorld > 0) { numWorlds = 1; } for (int iWorld = 0; iWorld < numWorlds; iWorld++) { // Save state to repro this query without doing everything that came before it if (dbgWorld > 0) { rnd.state = dbgWorld; } uint worldState = rnd.state; Physics.PhysicsWorld world = TestUtils.GenerateRandomWorld(ref rnd, rnd.NextInt(1, 20), 3.0f); // Manifold test // TODO would be nice if we could change the world collision tolerance for (int iBodyA = 0; iBodyA < world.NumBodies; iBodyA++) { for (int iBodyB = iBodyA + 1; iBodyB < world.NumBodies; iBodyB++) { Physics.RigidBody bodyA = world.Bodies[iBodyA]; Physics.RigidBody bodyB = world.Bodies[iBodyB]; if (bodyA.Collider->Type == ColliderType.Mesh && bodyB.Collider->Type == ColliderType.Mesh) { continue; // TODO - no mesh-mesh manifold support yet } // Build manifolds BlockStream contacts = new BlockStream(1, 0, Allocator.Temp); BlockStream.Writer contactWriter = contacts; contactWriter.BeginForEachIndex(0); ManifoldQueries.BodyBody(ref world, new BodyIndexPair { BodyAIndex = iBodyA, BodyBIndex = iBodyB }, 1.0f, ref contactWriter); contactWriter.EndForEachIndex(); // Read each manifold BlockStream.Reader contactReader = contacts; contactReader.BeginForEachIndex(0); int manifoldIndex = 0; while (contactReader.RemainingItemCount > 0) { string failureMessage = iWorld + " (" + worldState + ") " + iBodyA + " vs " + iBodyB + " #" + manifoldIndex; manifoldIndex++; // Read the manifold header ContactHeader header = contactReader.Read <ContactHeader>(); ConvexConvexManifoldQueries.Manifold manifold = new ConvexConvexManifoldQueries.Manifold(); manifold.NumContacts = header.NumContacts; manifold.Normal = header.Normal; // Get the leaf shapes ChildCollider leafA, leafB; { Collider.GetLeafCollider(bodyA.Collider, bodyA.WorldFromBody, header.ColliderKeys.ColliderKeyA, out leafA); Collider.GetLeafCollider(bodyB.Collider, bodyB.WorldFromBody, header.ColliderKeys.ColliderKeyB, out leafB); } // Read each contact point int minIndex = 0; for (int iContact = 0; iContact < header.NumContacts; iContact++) { // Read the contact and find the closest ContactPoint contact = contactReader.Read <ContactPoint>(); manifold[iContact] = contact; if (contact.Distance < manifold[minIndex].Distance) { minIndex = iContact; } // Check that the contact point is on or inside the shape CheckPointOnSurface(ref leafA, contact.Position + manifold.Normal * contact.Distance, failureMessage + " contact " + iContact + " leaf A"); CheckPointOnSurface(ref leafB, contact.Position, failureMessage + " contact " + iContact + " leaf B"); } // Check the closest point { ContactPoint closestPoint = manifold[minIndex]; RigidTransform aFromWorld = math.inverse(leafA.TransformFromChild); DistanceQueries.Result result = new DistanceQueries.Result { PositionOnAinA = math.transform(aFromWorld, closestPoint.Position + manifold.Normal * closestPoint.Distance), NormalInA = math.mul(aFromWorld.rot, manifold.Normal), Distance = closestPoint.Distance }; MTransform aFromB = new MTransform(math.mul(aFromWorld, leafB.TransformFromChild)); float referenceDistance = DistanceQueries.ConvexConvex(leafA.Collider, leafB.Collider, aFromB).Distance; ValidateDistanceResult(result, ref ((ConvexCollider *)leafA.Collider)->ConvexHull, ref ((ConvexCollider *)leafB.Collider)->ConvexHull, aFromB, referenceDistance, failureMessage + " closest point"); } // Check that the manifold is flat CheckManifoldFlat(ref manifold, manifold.Normal, failureMessage + ": non-flat A"); CheckManifoldFlat(ref manifold, float3.zero, failureMessage + ": non-flat B"); } contacts.Dispose(); } } world.Dispose(); // TODO leaking memory if the test fails } }