Example #1
0
        public static void FindCollision(GImpactQuantizedBvh boxset0, ref IndexedMatrix trans0,
                                         GImpactQuantizedBvh boxset1, ref IndexedMatrix trans1,
                                         PairSet collision_pairs)
        {
            if (boxset0.GetNodeCount() == 0 || boxset1.GetNodeCount() == 0)
            {
                return;
            }

            BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0 = new BT_BOX_BOX_TRANSFORM_CACHE();

            trans_cache_1to0.CalcFromHomogenic(ref trans0, ref trans1);

#if TRI_COLLISION_PROFILING
            BulletGlobals.StartProfile("GIMPACT-TRIMESH");
#endif //TRI_COLLISION_PROFILING

            FindQuantizedCollisionPairsRecursive(boxset0, boxset1, collision_pairs, ref trans_cache_1to0, 0, 0, true);
#if TRI_COLLISION_PROFILING
            BulletGlobals.StopProfile();
#endif //TRI_COLLISION_PROFILING
        }
Example #2
0
        public void BuildIslands(IDispatcher dispatcher, CollisionWorld collisionWorld)
        {
            BulletGlobals.StartProfile("islandUnionFindAndQuickSort");

            ObjectArray <CollisionObject> collisionObjects = collisionWorld.GetCollisionObjectArray();

            m_islandmanifold.Clear();

            //we are going to sort the unionfind array, and store the element id in the size
            //afterwards, we clean unionfind, to make sure no-one uses it anymore

            GetUnionFind().sortIslands();
            int numElem = GetUnionFind().GetNumElements();

            int endIslandIndex = 1;


            //update the sleeping state for bodies, if all are sleeping
            for (int startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
            {
                int islandId = GetUnionFind().GetElement(startIslandIndex).m_id;

                if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugIslands)
                {
                    BulletGlobals.g_streamWriter.WriteLine(String.Format("buildIslands start[{0}] end[{1}] id[{2}]", startIslandIndex, endIslandIndex, islandId));
                }

                for (endIslandIndex = startIslandIndex + 1; (endIslandIndex < numElem) && (GetUnionFind().GetElement(endIslandIndex).m_id == islandId); endIslandIndex++)
                {
                }

                //int numSleeping = 0;

                bool allSleeping = true;

                for (int idx = startIslandIndex; idx < endIslandIndex; idx++)
                {
                    int i = GetUnionFind().GetElement(idx).m_sz;

                    CollisionObject colObj0 = collisionObjects[i];
                    if ((colObj0.GetIslandTag() != islandId) && (colObj0.GetIslandTag() != -1))
                    {
                        //				printf("error in island management\n");
                    }

                    Debug.Assert((colObj0.GetIslandTag() == islandId) || (colObj0.GetIslandTag() == -1));
                    if (colObj0.GetIslandTag() == islandId)
                    {
                        if (colObj0.GetActivationState() == ActivationState.ACTIVE_TAG)
                        {
                            allSleeping = false;
                        }
                        if (colObj0.GetActivationState() == ActivationState.DISABLE_DEACTIVATION)
                        {
                            allSleeping = false;
                        }
                    }
                }


                if (allSleeping)
                {
                    for (int idx = startIslandIndex; idx < endIslandIndex; idx++)
                    {
                        int             i         = GetUnionFind().GetElement(idx).m_sz;
                        CollisionObject colObj0   = collisionObjects[i];
                        int             islandTag = colObj0.GetIslandTag();
                        if (islandTag != islandId && islandTag != -1)
                        {
                            //					printf("error in island management\n");
                        }

                        Debug.Assert((islandTag == islandId) || (islandTag == -1));

                        if (islandTag == islandId)
                        {
                            colObj0.SetActivationState(ActivationState.ISLAND_SLEEPING);
                        }
                    }
                }
                else
                {
                    for (int idx = startIslandIndex; idx < endIslandIndex; idx++)
                    {
                        int i = GetUnionFind().GetElement(idx).m_sz;

                        CollisionObject colObj0   = collisionObjects[i];
                        int             islandTag = colObj0.GetIslandTag();
                        if (islandTag != islandId && islandTag != -1)
                        {
                            //					printf("error in island management\n");
                        }

                        Debug.Assert((islandTag == islandId) || (islandTag == -1));

                        if (islandTag == islandId)
                        {
                            if (colObj0.GetActivationState() == ActivationState.ISLAND_SLEEPING)
                            {
                                colObj0.SetActivationState(ActivationState.WANTS_DEACTIVATION);
                                colObj0.SetDeactivationTime(0f);
                            }
                        }
                    }
                }
            }

            int maxNumManifolds = dispatcher.GetNumManifolds();

            //#definef SPLIT_ISLANDS 1
            //#ifdef SPLIT_ISLANDS


            //#endif //SPLIT_ISLANDS


            for (int i = 0; i < maxNumManifolds; i++)
            {
                PersistentManifold manifold = dispatcher.GetManifoldByIndexInternal(i);

                CollisionObject colObj0 = manifold.GetBody0() as CollisionObject;
                CollisionObject colObj1 = manifold.GetBody1() as CollisionObject;

                ///@todo: check sleeping conditions!
                if (((colObj0 != null) && colObj0.GetActivationState() != ActivationState.ISLAND_SLEEPING) ||
                    ((colObj1 != null) && colObj1.GetActivationState() != ActivationState.ISLAND_SLEEPING))
                {
                    //kinematic objects don't merge islands, but wake up all connected objects
                    if (colObj0.IsKinematicObject() && colObj0.GetActivationState() != ActivationState.ISLAND_SLEEPING)
                    {
                        if (colObj0.HasContactResponse())
                        {
                            colObj1.Activate();
                        }
                    }
                    if (colObj1.IsKinematicObject() && colObj1.GetActivationState() != ActivationState.ISLAND_SLEEPING)
                    {
                        if (colObj1.HasContactResponse())
                        {
                            colObj0.Activate();
                        }
                    }
                    if (m_splitIslands)
                    {
                        //filtering for response
                        if (dispatcher.NeedsResponse(colObj0, colObj1))
                        {
                            m_islandmanifold.Add(manifold);
                        }
                    }
                }
            }
            BulletGlobals.StopProfile();
        }
Example #3
0
        public void BuildAndProcessIslands(IDispatcher dispatcher, CollisionWorld collisionWorld, IIslandCallback callback)
        {
            ObjectArray <CollisionObject> collisionObjects = collisionWorld.GetCollisionObjectArray();

            BuildIslands(dispatcher, collisionWorld);

            int endIslandIndex = 1;
            int startIslandIndex;
            int numElem = GetUnionFind().GetNumElements();

            BulletGlobals.StartProfile("processIslands");

            if (!m_splitIslands)
            {
                PersistentManifoldArray manifolds = dispatcher.GetInternalManifoldPointer();
                int maxNumManifolds = dispatcher.GetNumManifolds();
                callback.ProcessIsland(collisionObjects, collisionObjects.Count, manifolds, 0, maxNumManifolds, -1);
            }
            else
            {
                // Sort manifolds, based on islands
                // Sort the vector using predicate and std::sort
                //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);

                int numManifolds = m_islandmanifold.Count;

                //we should do radix sort, it it much faster (O(n) instead of O (n log2(n))

                m_islandmanifold.QuickSort(m_sortPredicate);

                //now process all active islands (sets of manifolds for now)

                int startManifoldIndex = 0;
                int endManifoldIndex   = 1;
                //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
                for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
                {
                    int islandId = GetUnionFind().GetElement(startIslandIndex).m_id;

                    if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugIslands)
                    {
                        BulletGlobals.g_streamWriter.WriteLine(String.Format("buildAndProcessIslands start[{0}] end[{1}] id[{2}]", startIslandIndex, endIslandIndex, islandId));
                    }


                    bool islandSleeping = true;

                    for (endIslandIndex = startIslandIndex; (endIslandIndex < numElem) && (GetUnionFind().GetElement(endIslandIndex).m_id == islandId); endIslandIndex++)
                    {
                        int             i       = GetUnionFind().GetElement(endIslandIndex).m_sz;
                        CollisionObject colObj0 = collisionObjects[i];
                        m_islandBodies.Add(colObj0);
                        if (colObj0.IsActive())
                        {
                            islandSleeping = false;
                        }
                    }

                    //find the accompanying contact manifold for this islandId
                    int numIslandManifolds           = 0;
                    PersistentManifold startManifold = null;

                    if (startManifoldIndex < numManifolds)
                    {
                        int curIslandId = GetIslandId(m_islandmanifold[startManifoldIndex]);

                        if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugIslands)
                        {
                            BulletGlobals.g_streamWriter.WriteLine("curIsland[{0}] startManifold[{1}].", curIslandId, startManifoldIndex);
                        }



                        if (curIslandId == islandId)
                        {
                            startManifold = m_islandmanifold[startManifoldIndex];

                            for (endManifoldIndex = startManifoldIndex + 1; (endManifoldIndex < numManifolds) && (islandId == GetIslandId(m_islandmanifold[endManifoldIndex])); endManifoldIndex++)
                            {
                                if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugIslands)
                                {
                                    BulletGlobals.g_streamWriter.WriteLine("endManifoldIndex[{0}] islandId[{1}] getIsland[{2}].", endManifoldIndex, startManifoldIndex, GetIslandId(m_islandmanifold[endManifoldIndex]));
                                }
                            }
                            /// Process the actual simulation, only if not sleeping/deactivated
                            numIslandManifolds = endManifoldIndex - startManifoldIndex;
                        }
                    }

                    if (!islandSleeping)
                    {
                        callback.ProcessIsland(m_islandBodies, m_islandBodies.Count, m_islandmanifold, startManifoldIndex, numIslandManifolds, islandId);
                        //			printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
                    }
                    else
                    {
                        if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugIslands)
                        {
                            BulletGlobals.g_streamWriter.WriteLine("islandSleeping.");
                        }
                    }

                    if (numIslandManifolds != 0)
                    {
                        startManifoldIndex = endManifoldIndex;
                    }

                    m_islandBodies.Clear();
                }
            } // else if(!splitIslands)
            BulletGlobals.StopProfile();
        }
        protected void CollideSatTriangles(CollisionObject body0,
                                           CollisionObject body1,
                                           GImpactMeshShapePart shape0,
                                           GImpactMeshShapePart shape1,
                                           PairSet pairs, int pair_count)
        {
            IndexedMatrix orgtrans0 = body0.GetWorldTransform();
            IndexedMatrix orgtrans1 = body1.GetWorldTransform();

            PrimitiveTriangle ptri0 = new PrimitiveTriangle();
            PrimitiveTriangle ptri1 = new PrimitiveTriangle();

            if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo)
            {
                BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::CollideSatTriangles [{0}]", pair_count);
            }


            shape0.LockChildShapes();
            shape1.LockChildShapes();

            int pair_pointer = 0;

            while (pair_count-- != 0)
            {
                m_triface0    = pairs[pair_pointer].m_index1;
                m_triface1    = pairs[pair_pointer].m_index2;
                pair_pointer += 1;


                shape0.GetPrimitiveTriangle(m_triface0, ptri0);
                shape1.GetPrimitiveTriangle(m_triface1, ptri1);

#if TRI_COLLISION_PROFILING
                BulletGlobal.StartProfile("gim02_tri_time");
#endif

                ptri0.ApplyTransform(ref orgtrans0);
                ptri1.ApplyTransform(ref orgtrans1);


                //build planes
                ptri0.BuildTriPlane();
                ptri1.BuildTriPlane();
                // test conservative

                if (ptri0.OverlapTestConservative(ptri1))
                {
                    if (ptri0.FindTriangleCollisionClipMethod(ptri1, m_contact_data))
                    {
                        int j = m_contact_data.m_point_count;
                        while (j-- != 0)
                        {
                            AddContactPoint(body0, body1,
                                            m_contact_data.m_points[j],
                                            MathUtil.Vector4ToVector3(ref m_contact_data.m_separating_normal),
                                            -m_contact_data.m_penetration_depth);
                        }
                    }
                }

#if TRI_COLLISION_PROFILING
                BulletGlobals.StopProfile();
#endif
            }

            shape0.UnlockChildShapes();
            shape1.UnlockChildShapes();
        }
Example #5
0
        public void Collide(IDispatcher dispatcher)
        {
            BulletGlobals.StartProfile("BroadphaseCollide");
            //SPC(m_profiling.m_total);
            /* optimize				*/
            m_sets[0].OptimizeIncremental(1 + (m_sets[0].m_leaves * m_dupdates) / 100);
            if (m_fixedleft > 0)
            {
                int count = 1 + (m_sets[1].m_leaves * m_fupdates) / 100;
                m_sets[1].OptimizeIncremental(1 + (m_sets[1].m_leaves * m_fupdates) / 100);
                m_fixedleft = Math.Max(0, m_fixedleft - count);
            }
            /* dynamic . fixed set	*/
            m_stageCurrent = (m_stageCurrent + 1) % STAGECOUNT;

            DbvtProxy current = m_stageRoots[m_stageCurrent];

            if (current != null)
            {
                DbvtTreeCollider collider = BulletGlobals.DbvtTreeColliderPool.Get();
                collider.Initialize(this);
                do
                {
                    DbvtProxy next = current.links[1];
                    ListRemove(current, ref m_stageRoots[current.stage]);
                    ListAppend(current, ref m_stageRoots[STAGECOUNT]);
#if DBVT_BP_ACCURATESLEEPING
                    m_paircache.removeOverlappingPairsContainingProxy(current, dispatcher);
                    collider.proxy = current;
                    btDbvt::collideTV(m_sets[0].m_root, current.aabb, collider);
                    btDbvt::collideTV(m_sets[1].m_root, current.aabb, collider);
#endif
                    m_sets[0].Remove(current.leaf);
                    DbvtAabbMm curAabb = DbvtAabbMm.FromMM(ref current.m_aabbMin, ref current.m_aabbMax);
                    current.leaf  = m_sets[1].Insert(ref curAabb, current);
                    current.stage = STAGECOUNT;
                    current       = next;
                } while (current != null);
                m_fixedleft = m_sets[1].m_leaves;
                BulletGlobals.DbvtTreeColliderPool.Free(collider);
                m_needcleanup = true;
            }
            /* collide dynamics		*/
            {
                DbvtTreeCollider collider = BulletGlobals.DbvtTreeColliderPool.Get();
                collider.Initialize(this);
                if (m_deferedcollide)
                {
                    //Stopwatch fdCollideStopwatch = new Stopwatch();
                    //fdCollideStopwatch.Start();
                    //SPC(m_profiling.m_fdcollide);
                    Dbvt.CollideTTpersistentStack(m_sets[0].m_root, m_sets[1].m_root, collider);
                    //fdCollideStopwatch.Stop();
                    //m_profiling.m_fdcollide += (ulong)fdCollideStopwatch.ElapsedMilliseconds;
                }
                if (m_deferedcollide)
                {
                    //Stopwatch ddCollideStopwatch = new Stopwatch();
                    //ddCollideStopwatch.Start();
                    //SPC(m_profiling.m_ddcollide);
                    Dbvt.CollideTTpersistentStack(m_sets[0].m_root, m_sets[0].m_root, collider);
                    //ddCollideStopwatch.Stop();
                    //m_profiling.m_ddcollide += (ulong)ddCollideStopwatch.ElapsedMilliseconds;
                }
                BulletGlobals.DbvtTreeColliderPool.Free(collider);
            }
            /* clean up				*/
            if (m_needcleanup)
            {
                Stopwatch cleanupStopwatch = new Stopwatch();
                cleanupStopwatch.Start();
                //SPC(m_profiling.m_cleanup);
                IList <BroadphasePair> pairs = m_paircache.GetOverlappingPairArray();
                if (pairs.Count > 0)
                {
                    int ni = Math.Min(pairs.Count, Math.Max(m_newpairs, (pairs.Count * m_cupdates) / 100));
                    for (int i = 0; i < ni; ++i)
                    {
                        BroadphasePair p  = pairs[(m_cid + i) % pairs.Count];
                        DbvtProxy      pa = p.m_pProxy0 as DbvtProxy;
                        DbvtProxy      pb = p.m_pProxy1 as DbvtProxy;
                        if (!DbvtAabbMm.Intersect(ref pa.leaf.volume, ref pb.leaf.volume))
                        {
#if DBVT_BP_SORTPAIRS
                            if (pa.m_uniqueId > pb.m_uniqueId)
                            {
                                btSwap(pa, pb);
                            }
#endif
                            m_paircache.RemoveOverlappingPair(pa, pb, dispatcher);
                            --ni; --i;
                        }
                    }
                    if (pairs.Count > 0)
                    {
                        m_cid = (m_cid + ni) % pairs.Count;
                    }
                    else
                    {
                        m_cid = 0;
                    }
                }
                cleanupStopwatch.Stop();
                //m_profiling.m_cleanup += (ulong)cleanupStopwatch.ElapsedMilliseconds;
            }
            ++m_pid;
            m_newpairs    = 1;
            m_needcleanup = false;
            if (m_updates_call > 0)
            {
                m_updates_ratio = m_updates_done / (float)m_updates_call;
            }
            else
            {
                m_updates_ratio = 0;
            }
            m_updates_done /= 2;
            m_updates_call /= 2;

            BulletGlobals.StopProfile();
        }