Exemplo n.º 1
0
 ///<summary>
 /// Constructs a new contact manifold.
 ///</summary>
 protected TriangleMeshConvexContactManifold()
 {
     contacts               = new RawList <Contact>(4);
     unusedContacts         = new UnsafeResourcePool <Contact>(4);
     contactIndicesToRemove = new RawList <int>(4);
     activePairTesters      = new QuickDictionary <TriangleIndices, TrianglePairTester>(BufferPools <TriangleIndices> .Locking, BufferPools <TrianglePairTester> .Locking, BufferPools <int> .Locking, 3);
 }
Exemplo n.º 2
0
 /// <summary>
 /// Creates a new memory pool.
 /// </summary>
 /// <param name="memoryPoolSize">Size of the pool in elements.</param>
 public Allocator(long memoryPoolSize, int allocationCountEstimate = 128)
 {
     this.Capacity = memoryPoolSize;
     QuickDictionary <ulong, Allocation, Array <ulong>, Array <Allocation>, Array <int>, PrimitiveComparer <ulong> > .Create(
         new PassthroughArrayPool <ulong>(), new PassthroughArrayPool <Allocation>(), new PassthroughArrayPool <int>(),
         SpanHelper.GetContainingPowerOf2(allocationCountEstimate), 3, out allocations);
 }
Exemplo n.º 3
0
        public override void Update(double dt)
        {
            RigidTransform transform       = new RigidTransform(mesh.Position);
            RigidTransform convexTransform = convex.WorldTransform;

            ContactRefresher.ContactRefresh(contacts, supplementData, ref convexTransform, ref transform, contactIndicesToRemove);
            RemoveQueuedContacts();
            var overlaps = new QuickList <Vector3i>(BufferPools <Vector3i> .Thread);

            mesh.ChunkShape.GetOverlaps(mesh.Position, convex.BoundingBox, ref overlaps);
            var candidatesToAdd = new QuickList <ContactData>(BufferPools <ContactData> .Thread, BufferPool <int> .GetPoolIndex(overlaps.Count));

            for (int i = 0; i < overlaps.Count; i++)
            {
                if (!ActivePairs.TryGetValue(overlaps.Elements[i], out GeneralConvexPairTester manifold))
                {
                    manifold = GetPair(ref overlaps.Elements[i]);
                }
                else
                {
                    ActivePairs.FastRemove(overlaps.Elements[i]);
                }
                activePairsBackBuffer.Add(overlaps.Elements[i], manifold);
                if (manifold.GenerateContactCandidate(out ContactData contactCandidate))
                {
                    candidatesToAdd.Add(ref contactCandidate);
                }
            }
            overlaps.Dispose();
            for (int i = ActivePairs.Count - 1; i >= 0; i--)
            {
                ReturnPair(ActivePairs.Values[i]);
                ActivePairs.FastRemove(ActivePairs.Keys[i]);
            }
            var temp = ActivePairs;

            ActivePairs           = activePairsBackBuffer;
            activePairsBackBuffer = temp;
            if (contacts.Count + candidatesToAdd.Count > 4)
            {
                var reducedCandidates = new QuickList <ContactData>(BufferPools <ContactData> .Thread, 3);
                ContactReducer.ReduceContacts(contacts, ref candidatesToAdd, contactIndicesToRemove, ref reducedCandidates);
                RemoveQueuedContacts();
                for (int i = reducedCandidates.Count - 1; i >= 0; i--)
                {
                    Add(ref reducedCandidates.Elements[i]);
                    reducedCandidates.RemoveAt(i);
                }
                reducedCandidates.Dispose();
            }
            else if (candidatesToAdd.Count > 0)
            {
                for (int i = 0; i < candidatesToAdd.Count; i++)
                {
                    Add(ref candidatesToAdd.Elements[i]);
                }
            }
            candidatesToAdd.Dispose();
        }
        public SimulationProfiler(int initialStageCount = 8)
        {
            QuickDictionary <object, double, Array <object>, Array <double>, Array <int>, ReferenceComparer <object> > .Create(
                objectPool, doublePool, intPool, SpanHelper.GetContainingPowerOf2(initialStageCount), 3, out stages);

            QuickDictionary <object, long, Array <object>, Array <long>, Array <int>, ReferenceComparer <object> > .Create(
                objectPool, longPool, intPool, SpanHelper.GetContainingPowerOf2(initialStageCount), 3, out startTimeStamps);
        }
Exemplo n.º 5
0
 public ContactEvents(TEventHandler eventHandler, BufferPool pool, IThreadDispatcher threadDispatcher, int initialListenerCapacity = 32)
 {
     this.EventHandler     = eventHandler;
     this.pool             = pool;
     this.threadDispatcher = threadDispatcher;
     pendingWorkerAdds     = new QuickList <PendingNewEntry> [threadDispatcher == null ? 1: threadDispatcher.ThreadCount];
     listeners             = new QuickDictionary <CollidableReference, QuickList <PreviousCollisionData>, CollidableReferenceComparer>(initialListenerCapacity, pool);
 }
Exemplo n.º 6
0
        public Crafter()
        {
            id = new QuickDictionary <Item>();

            itemPool = new Dictionary <Item, int>();
            cheapest = new Dictionary <Item, int>();
            Recipes  = new List <Recipe>();
        }
Exemplo n.º 7
0
 public DefaultPoseIntegratorCallbacks(IUnmanagedMemoryPool pool, Vector3?gravity = null, float linearDamping = .03f, float angularDamping = .03f) : this()
 {
     Gravity                   = gravity ?? new Vector3(0, -9.81f, 0);
     LinearDamping             = linearDamping;
     AngularDamping            = angularDamping;
     _angularDampingDictionary = new QuickDictionary <int, float, IntComparer>(1, pool);
     _linearDampingDictionary  = new QuickDictionary <int, float, IntComparer>(1, pool);
     _linearDampingDictionary.Add(-1, LinearDamping, pool);
     _angularDampingDictionary.Add(-1, AngularDamping, pool);
 }
Exemplo n.º 8
0
        public unsafe void Render(DeviceContext context, Camera camera, Int2 screenResolution, Span <MeshInstance> instances, int start, int count)
        {
            //Examine the set of instances and batch them into groups using the same mesh data.
            var batches = new QuickDictionary <ulong, QuickList <MeshInstance>, PrimitiveComparer <ulong> >(16, meshCache.Pool);
            var end     = start + count;

            for (int i = start; i < end; ++i)
            {
                ref var instance = ref instances[i];
                ref var id       = ref Unsafe.As <int, ulong>(ref instance.VertexStart);
Exemplo n.º 9
0
 /// <summary>
 /// Creates a new memory pool.
 /// </summary>
 /// <param name="memoryPoolSize">Size of the pool in elements.</param>
 /// <param name="idBufferPool">Buffer pool to use in the allocator. If null, the allocator picks.</param>
 /// <param name="allocationBufferPool">Buffer pool to use in the allocator. If null, the allocator picks.</param>
 /// <param name="tableBufferPool">Buffer pool to use in the allocator. If null, the allocator picks.</param>
 public Allocator(long memoryPoolSize,
     BufferPool<ulong> idBufferPool = null, BufferPool<Allocation> allocationBufferPool = null, BufferPool<int> tableBufferPool = null)
 {
     this.memoryPoolSize = memoryPoolSize;
     if (idBufferPool == null)
         idBufferPool = BufferPools<ulong>.Locking;
     if (allocationBufferPool == null)
         allocationBufferPool = BufferPools<Allocation>.Locking;
     if (tableBufferPool == null)
         tableBufferPool = BufferPools<int>.Locking;
     allocations = new QuickDictionary<ulong, Allocation>(idBufferPool, allocationBufferPool, tableBufferPool);
 }
Exemplo n.º 10
0
 ///<summary>
 /// Cleans up the manifold.
 ///</summary>
 public override void CleanUp()
 {
     supplementData.Clear();
     convex = null;
     for (int i = activePairTesters.Count - 1; i >= 0; --i)
     {
         activePairTesters.Values[i].CleanUp();
         GiveBackTester(activePairTesters.Values[i]);
     }
     activePairTesters.Dispose();
     activePairTesters = new QuickDictionary <TriangleIndices, TrianglePairTester>(BufferPools <TriangleIndices> .Locking, BufferPools <TrianglePairTester> .Locking, BufferPools <int> .Locking, 3);
     CleanUpOverlappingTriangles();
     base.CleanUp();
 }
Exemplo n.º 11
0
 public override void Initialize(Collidable newCollidableA, Collidable newCollidableB)
 {
     convex = newCollidableA as ConvexCollidable;
     mesh   = newCollidableB as FullChunkObject;
     if (convex == null || mesh == null)
     {
         convex = newCollidableB as ConvexCollidable;
         mesh   = newCollidableA as FullChunkObject;
         if (convex == null || mesh == null)
         {
             throw new ArgumentException("Inappropriate types used to initialize contact manifold.");
         }
     }
     ActivePairs           = new QuickDictionary <Vector3i, GeneralConvexPairTester>(BufferPools <Vector3i> .Locking, BufferPools <GeneralConvexPairTester> .Locking, BufferPools <int> .Locking, 3);
     activePairsBackBuffer = new QuickDictionary <Vector3i, GeneralConvexPairTester>(BufferPools <Vector3i> .Locking, BufferPools <GeneralConvexPairTester> .Locking, BufferPools <int> .Locking, 3);
 }
        public static void TestDictionaryResizing <TSpan, TPool>(TPool pool)
            where TSpan : ISpan <int>
            where TPool : IMemoryPool <int, TSpan>
        {
            Random random = new Random(5);

            QuickDictionary <int, int, TSpan, TSpan, TSpan, PrimitiveComparer <int> > .Create(pool, pool, pool, 2, 3, out var dictionary);

            Dictionary <int, int> controlDictionary = new Dictionary <int, int>();

            for (int iterationIndex = 0; iterationIndex < 100000; ++iterationIndex)
            {
                if (random.NextDouble() < 0.7)
                {
                    dictionary.Add(iterationIndex, iterationIndex, pool, pool, pool);
                    controlDictionary.Add(iterationIndex, iterationIndex);
                }
                if (random.NextDouble() < 0.2)
                {
                    var indexToRemove = random.Next(dictionary.Count);
                    var toRemove      = dictionary.Keys[indexToRemove];
                    dictionary.FastRemove(toRemove);
                    controlDictionary.Remove(toRemove);
                }
                if (iterationIndex % 1000 == 0)
                {
                    dictionary.EnsureCapacity(dictionary.Count * 3, pool, pool, pool);
                }
                else if (iterationIndex % 7777 == 0)
                {
                    dictionary.Compact(pool, pool, pool);
                }
            }

            Debug.Assert(dictionary.Count == controlDictionary.Count);
            for (int i = 0; i < dictionary.Count; ++i)
            {
                Debug.Assert(controlDictionary.ContainsKey(dictionary.Keys[i]));
            }
            foreach (var element in controlDictionary.Keys)
            {
                Debug.Assert(dictionary.ContainsKey(element));
            }
            dictionary.Dispose(pool, pool, pool);
        }
        public override void Initialize(Collidable newCollidableA, Collidable newCollidableB)
        {
            convex    = newCollidableA as ConvexCollidable;
            voxelGrid = newCollidableB as VoxelGrid;


            if (convex == null || voxelGrid == null)
            {
                convex    = newCollidableB as ConvexCollidable;
                voxelGrid = newCollidableA as VoxelGrid;
                if (convex == null || voxelGrid == null)
                {
                    throw new ArgumentException("Inappropriate types used to initialize contact manifold.");
                }
            }
            ActivePairs           = new QuickDictionary <Int3, GeneralConvexPairTester>(BufferPools <Int3> .Locking, BufferPools <GeneralConvexPairTester> .Locking, BufferPools <int> .Locking, 3);
            activePairsBackBuffer = new QuickDictionary <Int3, GeneralConvexPairTester>(BufferPools <Int3> .Locking, BufferPools <GeneralConvexPairTester> .Locking, BufferPools <int> .Locking, 3);
        }
Exemplo n.º 14
0
 /// <summary>
 /// Creates a new memory pool.
 /// </summary>
 /// <param name="memoryPoolSize">Size of the pool in elements.</param>
 /// <param name="idBufferPool">Buffer pool to use in the allocator. If null, the allocator picks.</param>
 /// <param name="allocationBufferPool">Buffer pool to use in the allocator. If null, the allocator picks.</param>
 /// <param name="tableBufferPool">Buffer pool to use in the allocator. If null, the allocator picks.</param>
 public Allocator(long memoryPoolSize,
                  BufferPool <ulong> idBufferPool = null, BufferPool <Allocation> allocationBufferPool = null, BufferPool <int> tableBufferPool = null)
 {
     this.memoryPoolSize = memoryPoolSize;
     if (idBufferPool == null)
     {
         idBufferPool = BufferPools <ulong> .Locking;
     }
     if (allocationBufferPool == null)
     {
         allocationBufferPool = BufferPools <Allocation> .Locking;
     }
     if (tableBufferPool == null)
     {
         tableBufferPool = BufferPools <int> .Locking;
     }
     allocations = new QuickDictionary <ulong, Allocation>(idBufferPool, allocationBufferPool, tableBufferPool);
 }
Exemplo n.º 15
0
        public static void TestDictionaryResizing()
        {
            Random random = new Random(5);
            UnsafeBufferPool<int> pool = new UnsafeBufferPool<int>();
            QuickDictionary<int, int> dictionary = new QuickDictionary<int, int>(pool, pool, pool);
            Dictionary<int, int> controlDictionary = new Dictionary<int, int>();

            for (int iterationIndex = 0; iterationIndex < 100000; ++iterationIndex)
            {
                if (random.NextDouble() < 0.7)
                {
                    dictionary.Add(iterationIndex, iterationIndex);
                    controlDictionary.Add(iterationIndex, iterationIndex);
                }
                if (random.NextDouble() < 0.2)
                {
                    var indexToRemove = random.Next(dictionary.Count);
                    var toRemove = dictionary.Keys[indexToRemove];
                    dictionary.FastRemove(toRemove);
                    controlDictionary.Remove(toRemove);
                }
                if (iterationIndex % 1000 == 0)
                {
                    dictionary.EnsureCapacity(dictionary.Count * 3);
                }
                else if (iterationIndex % 7777 == 0)
                {
                    dictionary.Compact();
                }
            }

            Assert.IsTrue(dictionary.Count == controlDictionary.Count);
            for (int i = 0; i < dictionary.Count; ++i)
            {
                Assert.IsTrue(controlDictionary.ContainsKey(dictionary.Keys[i]));
            }
            foreach (var element in controlDictionary.Keys)
            {
                Assert.IsTrue(dictionary.ContainsKey(element));
            }
        }
Exemplo n.º 16
0
        public static void TestDictionaryResizing()
        {
            Random random = new Random(5);
            UnsafeBufferPool <int>     pool              = new UnsafeBufferPool <int>();
            QuickDictionary <int, int> dictionary        = new QuickDictionary <int, int>(pool, pool, pool);
            Dictionary <int, int>      controlDictionary = new Dictionary <int, int>();

            for (int iterationIndex = 0; iterationIndex < 100000; ++iterationIndex)
            {
                if (random.NextDouble() < 0.7)
                {
                    dictionary.Add(iterationIndex, iterationIndex);
                    controlDictionary.Add(iterationIndex, iterationIndex);
                }
                if (random.NextDouble() < 0.2)
                {
                    var indexToRemove = random.Next(dictionary.Count);
                    var toRemove      = dictionary.Keys[indexToRemove];
                    dictionary.FastRemove(toRemove);
                    controlDictionary.Remove(toRemove);
                }
                if (iterationIndex % 1000 == 0)
                {
                    dictionary.EnsureCapacity(dictionary.Count * 3);
                }
                else if (iterationIndex % 7777 == 0)
                {
                    dictionary.Compact();
                }
            }

            Assert.IsTrue(dictionary.Count == controlDictionary.Count);
            for (int i = 0; i < dictionary.Count; ++i)
            {
                Assert.IsTrue(controlDictionary.ContainsKey(dictionary.Keys[i]));
            }
            foreach (var element in controlDictionary.Keys)
            {
                Assert.IsTrue(dictionary.ContainsKey(element));
            }
        }
Exemplo n.º 17
0
        public unsafe void Render(DeviceContext context, Camera camera, Int2 screenResolution, MeshInstance[] instances, int start, int count)
        {
            //Examine the set of instances and batch them into groups using the same mesh data.
            var keyPool      = meshCache.Pool.SpecializeFor <ulong>();
            var valuePool    = meshCache.Pool.SpecializeFor <QuickList <MeshInstance, Buffer <MeshInstance> > >();
            var tablePool    = meshCache.Pool.SpecializeFor <int>();
            var instancePool = meshCache.Pool.SpecializeFor <MeshInstance>();

            //(but is this ENOUGH generics?)
            QuickDictionary <
                ulong, QuickList <MeshInstance,
                                  Buffer <MeshInstance> >, Buffer <ulong>,
                Buffer <QuickList <MeshInstance, Buffer <MeshInstance> > >, Buffer <int>,
                PrimitiveComparer <ulong> > .Create(keyPool, valuePool, tablePool, 4, 3, out var batches);

            var end = start + count;

            for (int i = start; i < end; ++i)
            {
                ref var instance = ref instances[i];
                ref var id       = ref Unsafe.As <int, ulong>(ref instance.VertexStart);
Exemplo n.º 18
0
 public override void Update(double dt)
 {
     RigidTransform transform = new RigidTransform(mesh.Position);
     RigidTransform convexTransform = convex.WorldTransform;
     ContactRefresher.ContactRefresh(contacts, supplementData, ref convexTransform, ref transform, contactIndicesToRemove);
     RemoveQueuedContacts();
     var overlaps = new QuickList<Vector3i>(BufferPools<Vector3i>.Thread);
     mesh.ChunkShape.GetOverlaps(mesh.Position, convex.BoundingBox, ref overlaps);
     var candidatesToAdd = new QuickList<ContactData>(BufferPools<ContactData>.Thread, BufferPool<int>.GetPoolIndex(overlaps.Count));
     for (int i = 0; i < overlaps.Count; i++)
     {
         GeneralConvexPairTester manifold;
         if (!ActivePairs.TryGetValue(overlaps.Elements[i], out manifold))
         {
             manifold = GetPair(ref overlaps.Elements[i]);
         }
         else
         {
             ActivePairs.FastRemove(overlaps.Elements[i]);
         }
         activePairsBackBuffer.Add(overlaps.Elements[i], manifold);
         ContactData contactCandidate;
         if (manifold.GenerateContactCandidate(out contactCandidate))
         {
             candidatesToAdd.Add(ref contactCandidate);
         }
     }
     overlaps.Dispose();
     for (int i = ActivePairs.Count - 1; i >= 0; i--)
     {
         ReturnPair(ActivePairs.Values[i]);
         ActivePairs.FastRemove(ActivePairs.Keys[i]);
     }
     var temp = ActivePairs;
     ActivePairs = activePairsBackBuffer;
     activePairsBackBuffer = temp;
     if (contacts.Count + candidatesToAdd.Count > 4)
     {
         var reducedCandidates = new QuickList<ContactData>(BufferPools<ContactData>.Thread, 3);
         ContactReducer.ReduceContacts(contacts, ref candidatesToAdd, contactIndicesToRemove, ref reducedCandidates);
         RemoveQueuedContacts();
         for (int i = reducedCandidates.Count - 1; i >= 0; i--)
         {
             Add(ref reducedCandidates.Elements[i]);
             reducedCandidates.RemoveAt(i);
         }
         reducedCandidates.Dispose();
     }
     else if (candidatesToAdd.Count > 0)
     {
         for (int i = 0; i < candidatesToAdd.Count; i++)
         {
             Add(ref candidatesToAdd.Elements[i]);
         }
     }
     candidatesToAdd.Dispose();
 }
Exemplo n.º 19
0
 /// <summary>
 /// Creates a new allocator.
 /// </summary>
 /// <param name="capacity">Size of the memory handled by the allocator in elements.</param>
 /// <param name="initialAllocationCapacity">Estimated number of allocations to allocate room for in the internal structures.</param>
 /// <param name="pool">Pool to pull internal resources from.</param>
 public Allocator(long capacity, BufferPool pool, int initialAllocationCapacity = 128)
 {
     this.pool     = pool;
     this.Capacity = capacity;
     allocations   = new QuickDictionary <ulong, Allocation, PrimitiveComparer <ulong> >(initialAllocationCapacity, 2, pool);
 }
Exemplo n.º 20
0
 public override void Initialize(Collidable newCollidableA, Collidable newCollidableB)
 {
     convex = newCollidableA as ConvexCollidable;
     mesh = newCollidableB as FullChunkObject;
     if (convex == null || mesh == null)
     {
         convex = newCollidableB as ConvexCollidable;
         mesh = newCollidableA as FullChunkObject;
         if (convex == null || mesh == null)
         {
             throw new ArgumentException("Inappropriate types used to initialize contact manifold.");
         }
     }
     ActivePairs = new QuickDictionary<Vector3i, GeneralConvexPairTester>(BufferPools<Vector3i>.Locking, BufferPools<GeneralConvexPairTester>.Locking, BufferPools<int>.Locking, 3);
     activePairsBackBuffer = new QuickDictionary<Vector3i, GeneralConvexPairTester>(BufferPools<Vector3i>.Locking, BufferPools<GeneralConvexPairTester>.Locking, BufferPools<int>.Locking, 3);
 }
Exemplo n.º 21
0
 public Maker()
 {
     currentItems = new QuickDictionary <Item>();
     craftJobs    = new CraftJobs <Recipe>();
 }
Exemplo n.º 22
0
		public override void Update( float dt )
		{
			//Refresh the contact manifold for this frame.
			var transform = new RigidTransform( voxelBlob.Position );
			var convexTransform = convex.WorldTransform;
			ContactRefresher.ContactRefresh( contacts, supplementData, ref convexTransform, ref transform, contactIndicesToRemove );
			RemoveQueuedContacts();

			//Collect the set of overlapped cell indices.
			//Not the fastest way to do this, but it's relatively simple and easy.
			var overlaps = new QuickList<Int3>( BufferPools<Int3>.Thread );
			voxelBlob.Shape.GetOverlaps( voxelBlob.Position, convex.BoundingBox, ref overlaps );

			var candidatesToAdd = new QuickList<ContactData>( BufferPools<ContactData>.Thread, BufferPool<int>.GetPoolIndex( overlaps.Count ) );
			for( int i = 0; i < overlaps.Count; ++i )
			{
				GeneralConvexPairTester manifold;
				if( !ActivePairs.TryGetValue( overlaps.Elements[i], out manifold ) )
				{
					//This manifold did not previously exist.
					manifold = GetPair( ref overlaps.Elements[i] );
				}
				else
				{
					//It did previously exist.
					ActivePairs.FastRemove( overlaps.Elements[i] );
				}
				activePairsBackBuffer.Add( overlaps.Elements[i], manifold );
				ContactData contactCandidate;
				if( manifold.GenerateContactCandidate( out contactCandidate ) )
				{

					candidatesToAdd.Add( ref contactCandidate );
				}
			}
			overlaps.Dispose();
			//Any pairs remaining in the activePairs set no longer exist. Clean them up.
			for( int i = ActivePairs.Count - 1; i >= 0; --i )
			{
				ReturnPair( ActivePairs.Values[i] );
				ActivePairs.FastRemove( ActivePairs.Keys[i] );
			}
			//Swap the pair sets.
			var temp = ActivePairs;
			ActivePairs = activePairsBackBuffer;
			activePairsBackBuffer = temp;

			//Check if adding the new contacts would overflow the manifold.
			if( contacts.Count + candidatesToAdd.Count > 4 )
			{
				//Adding all the contacts would overflow the manifold.  Reduce to the best subset.
				var reducedCandidates = new QuickList<ContactData>( BufferPools<ContactData>.Thread, 3 );
				ContactReducer.ReduceContacts( contacts, ref candidatesToAdd, contactIndicesToRemove, ref reducedCandidates );
				RemoveQueuedContacts();
				for( int i = reducedCandidates.Count - 1; i >= 0; i-- )
				{
					Add( ref reducedCandidates.Elements[i] );
					reducedCandidates.RemoveAt( i );
				}
				reducedCandidates.Dispose();
			}
			else if( candidatesToAdd.Count > 0 )
			{
				//Won't overflow the manifold, so just toss it in.
				for( int i = 0; i < candidatesToAdd.Count; i++ )
				{
					Add( ref candidatesToAdd.Elements[i] );
				}
			}


			candidatesToAdd.Dispose();

		}
Exemplo n.º 23
0
		public override void Initialize( Collidable newCollidableA, Collidable newCollidableB )
		{
			convex = newCollidableA as ConvexCollidable;
			voxelBlob = newCollidableB as VoxelBlob;


			if( convex == null || voxelBlob == null )
			{
				convex = newCollidableB as ConvexCollidable;
				voxelBlob = newCollidableA as VoxelBlob;
				if( convex == null || voxelBlob == null )
					throw new ArgumentException( "Inappropriate types used to initialize contact manifold." );
			}
			ActivePairs = new QuickDictionary<Int3, GeneralConvexPairTester>( BufferPools<Int3>.Locking, BufferPools<GeneralConvexPairTester>.Locking, BufferPools<int>.Locking, 3 );
			activePairsBackBuffer = new QuickDictionary<Int3, GeneralConvexPairTester>( BufferPools<Int3>.Locking, BufferPools<GeneralConvexPairTester>.Locking, BufferPools<int>.Locking, 3 );

		}
Exemplo n.º 24
0
        public static void Test()
        {
            //var random = new Random(5);
            //var comparer = new CollidablePairComparer();
            //for (int i = 0; i < 10000; ++i)
            //{
            //    var a = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //    var b = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //    var pair1 = new CollidablePair(a, b);
            //    var pair2 = new CollidablePair(b, a);
            //    Debug.Assert(comparer.Hash(ref pair1) == comparer.Hash(ref pair2));
            //    Debug.Assert(comparer.Equals(ref pair1, ref pair2));
            //}
            //for (int i = 0; i < 10000; ++i)
            //{
            //    var a = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //    var b = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //    var pair1 = new CollidablePair(a, b);
            //    CollidablePair pair2;
            //    do
            //    {
            //        var a2 = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //        var b2 = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //        pair2 = new CollidablePair(a2, b2);
            //    } while (
            //    (pair2.A.Packed == pair1.A.Packed && pair2.B.Packed == pair1.B.Packed) ||
            //    (pair2.B.Packed == pair1.A.Packed && pair2.A.Packed == pair1.B.Packed));
            //    Debug.Assert(!comparer.Equals(ref pair1, ref pair2));
            //}


            const int iterationCount          = 1000;
            const int perLayerCollidableCount = 900;
            const int layerCount = 10;

            int[] creationRemap = new int[perLayerCollidableCount * (layerCount - 1)];
            int[] lookupRemap   = new int[creationRemap.Length];
            for (int i = 0; i < creationRemap.Length; ++i)
            {
                creationRemap[i] = i;
                lookupRemap[i]   = i;
            }

            BufferPool pool       = new BufferPool();
            var        dictionary = new QuickDictionary <CollidablePair, int, CollidablePairComparer>(creationRemap.Length, 1, pool);

            var random = new Random(5);

            for (int i = 0; i < creationRemap.Length - 1; ++i)
            {
                {
                    var temp       = creationRemap[i];
                    var swapTarget = random.Next(i + 1, creationRemap.Length);
                    creationRemap[i]          = creationRemap[swapTarget];
                    creationRemap[swapTarget] = temp;
                }
                {
                    var temp       = lookupRemap[i];
                    var swapTarget = random.Next(i + 1, lookupRemap.Length);
                    lookupRemap[i]          = lookupRemap[swapTarget];
                    lookupRemap[swapTarget] = temp;
                }
            }

            int       accumulator      = 0;
            double    totalTime        = 0;
            const int warmupIterations = 128;

            for (int iterationIndex = 0; iterationIndex < iterationCount + warmupIterations; ++iterationIndex)
            {
                dictionary.Clear();
                for (int i = 0; i < creationRemap.Length; ++i)
                {
                    var index = creationRemap[i];
                    var pair  = new CollidablePair
                    {
                        A = new CollidableReference(CollidableMobility.Kinematic, index),
                        B = new CollidableReference(CollidableMobility.Dynamic, index + perLayerCollidableCount)
                    };
                    dictionary.AddUnsafely(ref pair, index);
                }
                CacheBlaster.Blast();
                //Prewarm the remap into cache to more closely mirror the behavior in the narrow phase.
                for (int i = 0; i < lookupRemap.Length; ++i)
                {
                    accumulator += lookupRemap[i];
                }
                var start = Stopwatch.GetTimestamp();
                for (int i = 0; i < lookupRemap.Length; ++i)
                {
                    var collidableIndex = lookupRemap[i];
                    var pair            = new CollidablePair
                    {
                        A = new CollidableReference(CollidableMobility.Kinematic, collidableIndex),
                        B = new CollidableReference(CollidableMobility.Dynamic, collidableIndex + perLayerCollidableCount)
                    };
                    var dictionaryIndex = dictionary.IndexOf(ref pair);
                    accumulator += dictionaryIndex;
                }
                var end = Stopwatch.GetTimestamp();
                if (iterationIndex >= warmupIterations)
                {
                    totalTime += (end - start) / (double)Stopwatch.Frequency;
                }
            }
            Console.WriteLine($"Time per lookup (ns): {1e9 * totalTime / (iterationCount * creationRemap.Length)}, acc{accumulator}");

            pool.Clear();
        }
        public override void Update(float dt)
        {
            //Refresh the contact manifold for this frame.
            var transform       = new RigidTransform(voxelGrid.Position);
            var convexTransform = convex.WorldTransform;

            ContactRefresher.ContactRefresh(contacts, supplementData, ref convexTransform, ref transform, contactIndicesToRemove);
            RemoveQueuedContacts();

            //Collect the set of overlapped cell indices.
            //Not the fastest way to do this, but it's relatively simple and easy.
            var overlaps = new QuickList <Int3>(BufferPools <Int3> .Thread);

            voxelGrid.Shape.GetOverlaps(voxelGrid.Position, convex.BoundingBox, ref overlaps);

            var candidatesToAdd = new QuickList <ContactData>(BufferPools <ContactData> .Thread, BufferPool <int> .GetPoolIndex(overlaps.Count));

            for (int i = 0; i < overlaps.Count; ++i)
            {
                GeneralConvexPairTester manifold;
                if (!ActivePairs.TryGetValue(overlaps.Elements[i], out manifold))
                {
                    //This manifold did not previously exist.
                    manifold = GetPair(ref overlaps.Elements[i]);
                }
                else
                {
                    //It did previously exist.
                    ActivePairs.FastRemove(overlaps.Elements[i]);
                }
                activePairsBackBuffer.Add(overlaps.Elements[i], manifold);
                ContactData contactCandidate;
                if (manifold.GenerateContactCandidate(out contactCandidate))
                {
                    candidatesToAdd.Add(ref contactCandidate);
                }
            }
            overlaps.Dispose();
            //Any pairs remaining in the activePairs set no longer exist. Clean them up.
            for (int i = ActivePairs.Count - 1; i >= 0; --i)
            {
                ReturnPair(ActivePairs.Values[i]);
                ActivePairs.FastRemove(ActivePairs.Keys[i]);
            }
            //Swap the pair sets.
            var temp = ActivePairs;

            ActivePairs           = activePairsBackBuffer;
            activePairsBackBuffer = temp;

            //Check if adding the new contacts would overflow the manifold.
            if (contacts.Count + candidatesToAdd.Count > 4)
            {
                //Adding all the contacts would overflow the manifold.  Reduce to the best subset.
                var reducedCandidates = new QuickList <ContactData>(BufferPools <ContactData> .Thread, 3);
                ContactReducer.ReduceContacts(contacts, ref candidatesToAdd, contactIndicesToRemove, ref reducedCandidates);
                RemoveQueuedContacts();
                for (int i = reducedCandidates.Count - 1; i >= 0; i--)
                {
                    Add(ref reducedCandidates.Elements[i]);
                    reducedCandidates.RemoveAt(i);
                }
                reducedCandidates.Dispose();
            }
            else if (candidatesToAdd.Count > 0)
            {
                //Won't overflow the manifold, so just toss it in.
                for (int i = 0; i < candidatesToAdd.Count; i++)
                {
                    Add(ref candidatesToAdd.Elements[i]);
                }
            }


            candidatesToAdd.Dispose();
        }