protected void GImpactTrimeshpartVsPlaneCollision( CollisionObject body0, CollisionObject body1, GImpactMeshShapePart shape0, StaticPlaneShape shape1, bool swapped) { IndexedMatrix orgtrans0 = body0.GetWorldTransform(); IndexedMatrix orgtrans1 = body1.GetWorldTransform(); IndexedVector4 plane; PlaneShape.GetPlaneEquationTransformed(shape1, ref orgtrans1, out plane); //test box against plane AABB tribox = new AABB(); shape0.GetAabb(ref orgtrans0, out tribox.m_min, out tribox.m_max); tribox.IncrementMargin(shape1.GetMargin()); if (tribox.PlaneClassify(ref plane) != BT_PLANE_INTERSECTION_TYPE.BT_CONST_COLLIDE_PLANE) { return; } shape0.LockChildShapes(); float margin = shape0.GetMargin() + shape1.GetMargin(); IndexedVector3 vertex; int vi = shape0.GetVertexCount(); while (vi-- != 0) { shape0.GetVertex(vi, out vertex); vertex = orgtrans0 * vertex; float distance = IndexedVector3.Dot(vertex, MathUtil.Vector4ToVector3(ref plane)) - plane.W - margin; if (distance < 0.0f)//add contact { if (swapped) { AddContactPoint(body1, body0, vertex, MathUtil.Vector4ToVector3(-plane), distance); } else { AddContactPoint(body0, body1, vertex, MathUtil.Vector4ToVector3(ref plane), distance); } } } shape0.UnlockChildShapes(); }
protected void BuildMeshParts(StridingMeshInterface meshInterface) { for (int i = 0; i < meshInterface.GetNumSubParts(); ++i) { GImpactMeshShapePart newpart = new GImpactMeshShapePart(meshInterface, i); m_mesh_parts.Add(newpart); } }
//! Tells to this object that is needed to refit all the meshes public override void PostUpdate() { int i = m_mesh_parts.Count; while (i-- != 0) { GImpactMeshShapePart part = m_mesh_parts[i]; part.PostUpdate(); } m_needs_update = true; }
public override void SetMargin(float margin) { m_collisionMargin = margin; int i = m_mesh_parts.Count; while (i-- != 0) { GImpactMeshShapePart part = m_mesh_parts[i]; part.SetMargin(margin); } m_needs_update = true; }
public override void SetLocalScaling(ref IndexedVector3 scaling) { localScaling = scaling; int i = m_mesh_parts.Count; while (i-- != 0) { GImpactMeshShapePart part = m_mesh_parts[i]; part.SetLocalScaling(ref scaling); } m_needs_update = true; }
//! Collision routines //!@{ protected void CollideGjkTriangles(CollisionObject body0, CollisionObject body1, GImpactMeshShapePart shape0, GImpactMeshShapePart shape1, ObjectArray <int> pairs, int pair_count) { TriangleShapeEx tri0 = new TriangleShapeEx(); TriangleShapeEx tri1 = new TriangleShapeEx(); shape0.LockChildShapes(); shape1.LockChildShapes(); int pair_pointer = 0; #if DEBUG if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo) { BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::CollideGjkTriangles [{0}]", pair_count); } #endif while (pair_count-- != 0) { m_triface0 = pairs[pair_pointer]; m_triface1 = pairs[pair_pointer + 1]; pair_pointer += 2; shape0.GetBulletTriangle(m_triface0, tri0); shape1.GetBulletTriangle(m_triface1, tri1); //collide two convex shapes if (tri0.OverlapTestConservative(tri1)) { ConvexVsConvexCollision(body0, body1, tri0, tri1); } } shape0.UnlockChildShapes(); shape1.UnlockChildShapes(); }
protected void GImpactTrimeshpartVsPlaneCollision( CollisionObject body0, CollisionObject body1, GImpactMeshShapePart shape0, StaticPlaneShape shape1, bool swapped) { IndexedMatrix orgtrans0 = body0.GetWorldTransform(); IndexedMatrix orgtrans1 = body1.GetWorldTransform(); IndexedVector4 plane; PlaneShape.GetPlaneEquationTransformed(shape1,ref orgtrans1, out plane); //test box against plane AABB tribox = new AABB(); shape0.GetAabb(ref orgtrans0, out tribox.m_min, out tribox.m_max); tribox.IncrementMargin(shape1.GetMargin()); if (tribox.PlaneClassify(ref plane) != BT_PLANE_INTERSECTION_TYPE.BT_CONST_COLLIDE_PLANE) return; shape0.LockChildShapes(); float margin = shape0.GetMargin() + shape1.GetMargin(); IndexedVector3 vertex; int vi = shape0.GetVertexCount(); while (vi-- != 0) { shape0.GetVertex(vi, out vertex); vertex = orgtrans0 * vertex; float distance = IndexedVector3.Dot(vertex, MathUtil.Vector4ToVector3(ref plane)) - plane.W - margin; if (distance < 0.0f)//add contact { if (swapped) { AddContactPoint(body1, body0, vertex, MathUtil.Vector4ToVector3(-plane), distance); } else { AddContactPoint(body0, body1, vertex, MathUtil.Vector4ToVector3(ref plane), distance); } } } shape0.UnlockChildShapes(); }
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(); }
//! Collision routines //!@{ protected void CollideGjkTriangles(CollisionObject body0, CollisionObject body1, GImpactMeshShapePart shape0, GImpactMeshShapePart shape1, ObjectArray<int> pairs, int pair_count) { TriangleShapeEx tri0 = new TriangleShapeEx(); TriangleShapeEx tri1 = new TriangleShapeEx(); shape0.LockChildShapes(); shape1.LockChildShapes(); int pair_pointer = 0; if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo) { BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::CollideGjkTriangles [{0}]", pair_count); } while (pair_count-- != 0) { m_triface0 = pairs[pair_pointer]; m_triface1 = pairs[pair_pointer + 1]; pair_pointer += 2; shape0.GetBulletTriangle(m_triface0, tri0); shape1.GetBulletTriangle(m_triface1, tri1); //collide two convex shapes if (tri0.OverlapTestConservative(tri1)) { ConvexVsConvexCollision(body0, body1, tri0, tri1); } } shape0.UnlockChildShapes(); shape1.UnlockChildShapes(); }
public void GImpactVsShape(CollisionObject body0, CollisionObject body1, GImpactShapeInterface shape0, CollisionShape shape1, bool swapped) { if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo) { BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsShape"); } if (shape0.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE) { GImpactMeshShape meshshape0 = shape0 as GImpactMeshShape; // check this... //int& part = swapped ? m_part1 : m_part0; //part = meshshape0.GetMeshPartCount(); int part = meshshape0.GetMeshPartCount(); while (part-- != 0) { GImpactVsShape(body0, body1, meshshape0.GetMeshPart(part), shape1, swapped); } if (swapped) { m_part1 = part; } else { m_part0 = part; } return; } #if GIMPACT_VS_PLANE_COLLISION if (shape0.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE_PART && shape1.GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE) { GImpactMeshShapePart shapepart = shape0 as GImpactMeshShapePart; StaticPlaneShape planeshape = shape1 as StaticPlaneShape; GImpactTrimeshpartVsPlaneCollision(body0, body1, shapepart, planeshape, swapped); return; } #endif if (shape1.IsCompound()) { CompoundShape compoundshape = shape1 as CompoundShape; GImpactVsCompoundshape(body0, body1, shape0, compoundshape, swapped); return; } else if (shape1.IsConcave()) { ConcaveShape concaveshape = shape1 as ConcaveShape; GImpactVsConcave(body0, body1, shape0, concaveshape, swapped); return; } IndexedMatrix orgtrans0 = body0.GetWorldTransform(); IndexedMatrix orgtrans1 = body1.GetWorldTransform(); ObjectArray <int> collided_results = new ObjectArray <int>(64); GImpactVsShapeFindPairs(ref orgtrans0, ref orgtrans1, shape0, shape1, collided_results); if (collided_results.Count == 0) { return; } shape0.LockChildShapes(); using (GIM_ShapeRetriever retriever0 = BulletGlobals.GIM_ShapeRetrieverPool.Get()) { retriever0.Initialize(shape0); bool child_has_transform0 = shape0.ChildrenHasTransform(); int i = collided_results.Count; if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo) { BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsShape [{0}]", collided_results.Count); } while (i-- != 0) { int child_index = collided_results[i]; if (swapped) { m_triface1 = child_index; } else { m_triface0 = child_index; } CollisionShape colshape0 = retriever0.GetChildShape(child_index); if (child_has_transform0) { body0.SetWorldTransform(orgtrans0 * shape0.GetChildTransform(child_index)); } //collide two shapes if (swapped) { ShapeVsShapeCollision(body1, body0, shape1, colshape0); } else { ShapeVsShapeCollision(body0, body1, colshape0, shape1); } //restore transforms if (child_has_transform0) { body0.SetWorldTransform(ref orgtrans0); } } shape0.UnlockChildShapes(); } }
//! Collides two gimpact shapes /*! * \pre shape0 and shape1 couldn't be btGImpactMeshShape objects */ public void GImpactVsGImpact(CollisionObject body0, CollisionObject body1, GImpactShapeInterface shape0, GImpactShapeInterface shape1) { if (shape0.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE) { GImpactMeshShape meshshape0 = shape0 as GImpactMeshShape; m_part0 = meshshape0.GetMeshPartCount(); while (m_part0-- != 0) { GImpactVsGImpact(body0, body1, meshshape0.GetMeshPart(m_part0), shape1); } return; } if (shape1.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE) { GImpactMeshShape meshshape1 = shape1 as GImpactMeshShape; m_part1 = meshshape1.GetMeshPartCount(); while (m_part1-- != 0) { GImpactVsGImpact(body0, body1, shape0, meshshape1.GetMeshPart(m_part1)); } return; } IndexedMatrix orgtrans0 = body0.GetWorldTransform(); IndexedMatrix orgtrans1 = body1.GetWorldTransform(); PairSet pairset = new PairSet(); GImpactVsGImpactFindPairs(ref orgtrans0, ref orgtrans1, shape0, shape1, pairset); if (pairset.Count == 0) { return; } if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo) { BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsGImpact [{0}]", pairset.Count); } if (shape0.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE_PART && shape1.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE_PART) { GImpactMeshShapePart shapepart0 = shape0 as GImpactMeshShapePart; GImpactMeshShapePart shapepart1 = shape1 as GImpactMeshShapePart; //specialized function #if BULLET_TRIANGLE_COLLISION CollideGjkTriangles(body0, body1, shapepart0, shapepart1, &pairset[0].m_index1, pairset.size()); #else CollideSatTriangles(body0, body1, shapepart0, shapepart1, pairset, pairset.Count); #endif return; } //general function shape0.LockChildShapes(); shape1.LockChildShapes(); using (GIM_ShapeRetriever retriever0 = BulletGlobals.GIM_ShapeRetrieverPool.Get()) using (GIM_ShapeRetriever retriever1 = BulletGlobals.GIM_ShapeRetrieverPool.Get()) { retriever0.Initialize(shape0); retriever1.Initialize(shape1); bool child_has_transform0 = shape0.ChildrenHasTransform(); bool child_has_transform1 = shape1.ChildrenHasTransform(); int i = pairset.Count; while (i-- != 0) { GIM_PAIR pair = pairset[i]; m_triface0 = pair.m_index1; m_triface1 = pair.m_index2; CollisionShape colshape0 = retriever0.GetChildShape(m_triface0); CollisionShape colshape1 = retriever1.GetChildShape(m_triface1); if (child_has_transform0) { body0.SetWorldTransform(orgtrans0 * shape0.GetChildTransform(m_triface0)); } if (child_has_transform1) { body1.SetWorldTransform(orgtrans1 * shape1.GetChildTransform(m_triface1)); } //collide two convex shapes ConvexVsConvexCollision(body0, body1, colshape0, colshape1); if (child_has_transform0) { body0.SetWorldTransform(ref orgtrans0); } if (child_has_transform1) { body1.SetWorldTransform(ref orgtrans1); } } shape0.UnlockChildShapes(); shape1.UnlockChildShapes(); } }