public void GImpactVsCompoundshape(CollisionObject body0, CollisionObject body1, GImpactShapeInterface shape0, CompoundShape shape1, bool swapped) { IndexedMatrix orgtrans1 = body1.GetWorldTransform(); if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo) { BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsCompoundshape"); } int i = shape1.GetNumChildShapes(); while (i-- != 0) { CollisionShape colshape1 = shape1.GetChildShape(i); IndexedMatrix childtrans1 = orgtrans1 * shape1.GetChildTransform(i); body1.SetWorldTransform(ref childtrans1); //collide child shape GImpactVsShape(body0, body1, shape0, colshape1, swapped); //restore transforms body1.SetWorldTransform(ref orgtrans1); } }
private void PreallocateChildAlgorithms(CollisionObject body0, CollisionObject body1) { CollisionObject colObj = m_isSwapped ? body1 : body0; CollisionObject otherObj = m_isSwapped ? body0 : body1; Debug.Assert(colObj.GetCollisionShape().IsCompound()); CompoundShape compoundShape = (CompoundShape)(colObj.GetCollisionShape()); int numChildren = compoundShape.GetNumChildShapes(); int i; //m_childCollisionAlgorithms.resize(numChildren); m_childCollisionAlgorithms.Clear(); for (i = 0; i < numChildren; i++) { if (compoundShape.GetDynamicAabbTree() != null) { m_childCollisionAlgorithms.Add(null); } else { CollisionShape tmpShape = colObj.GetCollisionShape(); CollisionShape childShape = compoundShape.GetChildShape(i); colObj.InternalSetTemporaryCollisionShape(childShape); CollisionAlgorithm ca = m_dispatcher.FindAlgorithm(colObj, otherObj, m_sharedManifold); m_childCollisionAlgorithms.Add(ca); colObj.InternalSetTemporaryCollisionShape(tmpShape); } } }
public override float CalculateTimeOfImpact(CollisionObject body0, CollisionObject body1, DispatcherInfo dispatchInfo, ManifoldResult resultOut) { resultOut = null; CollisionObject colObj = m_isSwapped ? body1 : body0; CollisionObject otherObj = m_isSwapped ? body0 : body1; Debug.Assert(colObj.GetCollisionShape().IsCompound()); CompoundShape compoundShape = (CompoundShape)(colObj.GetCollisionShape()); //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps //If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals //given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means: //determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1 //then use each overlapping node AABB against Tree0 //and vise versa. float hitFraction = 1f; int numChildren = m_childCollisionAlgorithms.Count; IndexedMatrix orgTrans; float frac; for (int i = 0; i < numChildren; i++) { //temporarily exchange parent btCollisionShape with childShape, and recurse CollisionShape childShape = compoundShape.GetChildShape(i); //backup orgTrans = colObj.GetWorldTransform(); IndexedMatrix childTrans = compoundShape.GetChildTransform(i); IndexedMatrix newChildWorldTrans = orgTrans * childTrans; colObj.SetWorldTransform(ref newChildWorldTrans); CollisionShape tmpShape = colObj.GetCollisionShape(); colObj.InternalSetTemporaryCollisionShape(childShape); frac = m_childCollisionAlgorithms[i].CalculateTimeOfImpact(colObj, otherObj, dispatchInfo, resultOut); if (frac < hitFraction) { hitFraction = frac; } //revert back colObj.InternalSetTemporaryCollisionShape(tmpShape); colObj.SetWorldTransform(ref orgTrans); } return(hitFraction); }
public override void Process(DbvtNode leaf) { int index = leaf.dataAsInt; CompoundShape compoundShape = (CompoundShape)(m_compoundColObj.GetCollisionShape()); CollisionShape childShape = compoundShape.GetChildShape(index); if (m_dispatchInfo.getDebugDraw() != null && (((m_dispatchInfo.getDebugDraw().GetDebugMode() & DebugDrawModes.DBG_DrawAabb)) != 0)) { IndexedVector3 worldAabbMin; IndexedVector3 worldAabbMax; IndexedMatrix orgTrans = m_compoundColObj.GetWorldTransform(); AabbUtil2.TransformAabb(leaf.volume.Mins(), leaf.volume.Maxs(), 0f, ref orgTrans, out worldAabbMin, out worldAabbMax); m_dispatchInfo.getDebugDraw().DrawAabb(worldAabbMin, worldAabbMax, new IndexedVector3(1, 0, 0)); } ProcessChildShape(childShape, index); }
public void GImpactVsCompoundshape(CollisionObject body0, CollisionObject body1, GImpactShapeInterface shape0, CompoundShape shape1, bool swapped) { IndexedMatrix orgtrans1 = body1.GetWorldTransform(); if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo) { BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsCompoundshape"); } int i = shape1.GetNumChildShapes(); while (i-- != 0) { CollisionShape colshape1 = shape1.GetChildShape(i); IndexedMatrix childtrans1 = orgtrans1 * shape1.GetChildTransform(i); body1.SetWorldTransform(ref childtrans1); //collide child shape GImpactVsShape(body0, body1, shape0, colshape1, swapped); //restore transforms body1.SetWorldTransform(ref orgtrans1); } }
public override void ProcessCollision(CollisionObject body0, CollisionObject body1, DispatcherInfo dispatchInfo, ManifoldResult resultOut) { //resultOut = null; CollisionObject colObj = m_isSwapped ? body1 : body0; CollisionObject otherObj = m_isSwapped ? body0 : body1; Debug.Assert(colObj.GetCollisionShape().IsCompound()); CompoundShape compoundShape = (CompoundShape)(colObj.GetCollisionShape()); ///btCompoundShape might have changed: ////make sure the internal child collision algorithm caches are still valid if (compoundShape.GetUpdateRevision() != m_compoundShapeRevision) { ///clear and update all RemoveChildAlgorithms(); PreallocateChildAlgorithms(body0, body1); } Dbvt tree = compoundShape.GetDynamicAabbTree(); //use a dynamic aabb tree to cull potential child-overlaps using (CompoundLeafCallback callback = BulletGlobals.CompoundLeafCallbackPool.Get()) { callback.Initialize(colObj, otherObj, m_dispatcher, dispatchInfo, resultOut, this, m_childCollisionAlgorithms, m_sharedManifold); ///we need to refresh all contact manifolds ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm { m_manifoldArray.Clear(); for (int i = 0; i < m_childCollisionAlgorithms.Count; i++) { if (m_childCollisionAlgorithms[i] != null) { m_childCollisionAlgorithms[i].GetAllContactManifolds(m_manifoldArray); for (int m = 0; m < m_manifoldArray.Count; m++) { if (m_manifoldArray[m].GetNumContacts() > 0) { resultOut.SetPersistentManifold(m_manifoldArray[m]); resultOut.RefreshContactPoints(); resultOut.SetPersistentManifold(null);//??necessary? } } m_manifoldArray.Clear(); } } } if (tree != null) { IndexedVector3 localAabbMin; IndexedVector3 localAabbMax; IndexedMatrix otherInCompoundSpace; //otherInCompoundSpace = MathUtil.BulletMatrixMultiply(colObj.GetWorldTransform(),otherObj.GetWorldTransform()); otherInCompoundSpace = colObj.GetWorldTransform().Inverse() * otherObj.GetWorldTransform(); otherObj.GetCollisionShape().GetAabb(ref otherInCompoundSpace, out localAabbMin, out localAabbMax); DbvtAabbMm bounds = DbvtAabbMm.FromMM(ref localAabbMin, ref localAabbMax); //process all children, that overlap with the given AABB bounds Dbvt.CollideTV(tree.m_root, ref bounds, callback, tree.CollideTVStack, ref tree.CollideTVCount); } else { //iterate over all children, perform an AABB check inside ProcessChildShape int numChildren = m_childCollisionAlgorithms.Count; for (int i = 0; i < numChildren; i++) { callback.ProcessChildShape(compoundShape.GetChildShape(i), i); } } { //iterate over all children, perform an AABB check inside ProcessChildShape int numChildren = m_childCollisionAlgorithms.Count; m_manifoldArray.Clear(); CollisionShape childShape = null; IndexedMatrix orgTrans; IndexedMatrix orgInterpolationTrans; IndexedMatrix newChildWorldTrans; for (int i = 0; i < numChildren; i++) { if (m_childCollisionAlgorithms[i] != null) { childShape = compoundShape.GetChildShape(i); //if not longer overlapping, remove the algorithm orgTrans = colObj.GetWorldTransform(); orgInterpolationTrans = colObj.GetInterpolationWorldTransform(); IndexedMatrix childTrans = compoundShape.GetChildTransform(i); newChildWorldTrans = orgTrans * childTrans; //perform an AABB check first IndexedVector3 aabbMin0; IndexedVector3 aabbMax0; IndexedVector3 aabbMin1; IndexedVector3 aabbMax1; childShape.GetAabb(ref newChildWorldTrans, out aabbMin0, out aabbMax0); otherObj.GetCollisionShape().GetAabb(otherObj.GetWorldTransform(), out aabbMin1, out aabbMax1); if (!AabbUtil2.TestAabbAgainstAabb2(ref aabbMin0, ref aabbMax0, ref aabbMin1, ref aabbMax1)) { m_dispatcher.FreeCollisionAlgorithm(m_childCollisionAlgorithms[i]); m_childCollisionAlgorithms[i] = null; } } } } } }