void csBulletCollider::FillWithColliderGeometry ( csRef<iGeneralFactoryState> genmesh_fact) { // @@@ TODO #if 0 switch (geomType) { case BOX_COLLIDER_GEOMETRY: { SimdTransform trans; SimdVector3 max; SimdVector3 min; BoxShape* b = (BoxShape*)pc->GetRigidBody ()->GetCollisionShape (); csBox3 box; for (int i = 0; i < b->GetNumVertices (); i++) { SimdVector3 vtx; b->GetVertex (i, vtx); box.AddBoundingVertexTest (csVector3 (vtx[0], vtx[1], vtx[2])); } genmesh_fact->GenerateBox (box); genmesh_fact->CalculateNormals (); } break; default: break; } #endif }
size_t collide(CircleShape &circle, BoxShape &box, float dt, Contact *pxContacts, size_t numMaxContacts) { dt, pxContacts, numMaxContacts; const Point2f &p1 = circle.body.getPosition(); const Point2f &p2 = box.body.getPosition(); // work in the box's coordinate system const Point2f kDiff = p1 - p2; // compute squared distance and closest point on box float fSqrDistance = 0.0f, fDelta; Point2f kClosest(kDiff * box.GetDir(0), kDiff * box.GetDir(1)); const Point2f &extents = box.GetExtents(); if (kClosest.x < -extents.x) { fDelta = kClosest.x + extents.x; fSqrDistance += fDelta*fDelta; kClosest.x = -extents.x; } else if (kClosest.x > extents.x) { fDelta = kClosest.x - extents.x; fSqrDistance += fDelta*fDelta; kClosest.x = extents.x; } if (kClosest.y < -extents.y) { fDelta = kClosest.y + extents.y; fSqrDistance += fDelta*fDelta; kClosest.y = -extents.y; } else if (kClosest.y > extents.y) { fDelta = kClosest.y - extents.y; fSqrDistance += fDelta*fDelta; kClosest.y = extents.y; } if (fSqrDistance > circle.GetRadius() * circle.GetRadius()) { return 0; } Point2f d = p2 + kClosest - p1; d.Normalize(); pxContacts[0] = Contact(p1 + d * circle.GetRadius(), p2 + kClosest, &circle.body, &box.body); return 1; }
/* ========== Frustum::BoxInFrustum Checks if a box is in the frustum. ========== */ FrustumResult::Value Frustum::BoxInFrustum( const BoxShape& box ) const { glm::vec3 positiveVertex, negativeVertex; FrustumResult::Value ret = FrustumResult::INSIDE; for ( int i = 0; i < 6; ++i ) { negativeVertex = box.GetNegativeVertex( glm::vec3( m_planes[i] ) ); positiveVertex = box.GetPositiveVertex( glm::vec3( m_planes[i] ) ); if ( glm::dot( glm::vec3( m_planes[i] ), positiveVertex ) + m_planes[i].w < 0 ) { return FrustumResult::OUTSIDE; } else if ( glm::dot( glm::vec3( m_planes[i] ), negativeVertex ) + m_planes[i].w < 0 ) { ret = FrustumResult::INTERSECT; } } return ret; /* glm::vec3 positiveVertex; glm::vec3 negativeVertex; const Transform& boxTransform = box.GetImmutableTransform(); if ( std::abs( boxTransform.GetRotation().y ) < 0.001f ) { positiveVertex = box.GetPositiveVertex( m_planes[i].GetNormal() ); negativeVertex = box.GetNegativeVertex( m_planes[i].GetNormal() ); } else { glm::vec3 normalBox( glm::dot( boxTransform.GetRight(), m_planes[i].GetNormal() ), glm::dot( boxTransform.GetUp(), m_planes[i].GetNormal() ), glm::dot( boxTransform .GetForward(), m_planes[i].GetNormal() ) ); positiveVertex = box.GetPositiveVertex( normalBox ); negativeVertex = box.GetNegativeVertex( normalBox ); } if ( m_planes[i].Distance( positiveVertex ) < 0 ) { return FrustumResult::OUTSIDE; } else if ( m_planes[i].Distance( negativeVertex ) < 0 ) { return FrustumResult::INTERSECT; } } */ }
bool testOBBPlane( RigidBody& box, RigidBody& plane) { BoxShape boxs = (BoxShape&)box.getShapeReference(); float d = ((PlaneShape&)plane.getShapeReference()).getDistance(); Mat<float> n( ((PlaneShape&)plane.getShapeReference()).getNormal()); Mat<float> e((float)0,3,3); for(int i=1;i<=3;i++) e.set(1.0f, i,i); //identity matrix to be rotated in order to have the basis related to the coordinate frame of the box : e = extract( box.getTransformation(), 1,1, 3,3) * e; float r = boxs.getHeight()*fabs_( dotProduct( Cola(e,1), n) ) + boxs.getWidth()*fabs_( dotProduct( Cola(e,2), n) ) + boxs.getDepth()*fabs_( dotProduct( Cola(e,3), n) ); float s = dotProduct( n, box.getPosition()) - d; return fabs_(s) <= r; }
bool IntervalIntersect(const Point2f& xAxis, const BoxShape& box1, const BoxShape& box2, float& depth) { float min0, max0; float min1, max1; box1.GetInterval(xAxis, min0, max0); box2.GetInterval(xAxis, min1, max1); if (min0 > max1 || min1 > max0) return false; float d0 = max1 - min0; float d1 = max0 - min1; if (d0 < d1) depth = d0; else depth = d1; return true; }
int main(int argc,char** argv) { raytracePicture = new RenderTexture(screenWidth,screenHeight); myBox.SetMargin(0.02f); myCone.SetMargin(0.2f); simplex.SetSimplexSolver(&simplexSolver); simplex.AddVertex(SimdPoint3(-1,0,-1)); simplex.AddVertex(SimdPoint3(1,0,-1)); simplex.AddVertex(SimdPoint3(0,0,1)); simplex.AddVertex(SimdPoint3(0,1,0)); /// convex hull of 5 spheres #define NUM_SPHERES 5 SimdVector3 inertiaHalfExtents(10.f,10.f,10.f); SimdVector3 positions[NUM_SPHERES] = { SimdVector3(-1.2f, -0.3f, 0.f), SimdVector3(0.8f, -0.3f, 0.f), SimdVector3(0.5f, 0.6f, 0.f), SimdVector3(-0.5f, 0.6f, 0.f), SimdVector3(0.f, 0.f, 0.f) }; SimdScalar radi[NUM_SPHERES] = { 0.35f,0.35f,0.45f,0.40f,0.40f }; MultiSphereShape multiSphereShape(inertiaHalfExtents,positions,radi,NUM_SPHERES); ConvexHullShape convexHullShape(positions,3); //choose shape shapePtr[0] = &myCone; shapePtr[1] =&simplex; shapePtr[2] =&convexHullShape; shapePtr[3] =&myMink;//myBox; simplex.SetMargin(0.3f); setCameraDistance(6.f); return glutmain(argc, argv,screenWidth,screenHeight,"Minkowski-Sum Raytracer Demo"); }
void Raytracer::initPhysics() { raytracePicture = new RenderTexture(screenWidth,screenHeight); myBox.SetMargin(0.02f); myCone.SetMargin(0.2f); simplex.SetSimplexSolver(&simplexSolver); simplex.AddVertex(SimdPoint3(-1,0,-1)); simplex.AddVertex(SimdPoint3(1,0,-1)); simplex.AddVertex(SimdPoint3(0,0,1)); simplex.AddVertex(SimdPoint3(0,1,0)); /// convex hull of 5 spheres #define NUM_SPHERES 5 SimdVector3 inertiaHalfExtents(10.f,10.f,10.f); SimdVector3 positions[NUM_SPHERES] = { SimdVector3(-1.2f, -0.3f, 0.f), SimdVector3(0.8f, -0.3f, 0.f), SimdVector3(0.5f, 0.6f, 0.f), SimdVector3(-0.5f, 0.6f, 0.f), SimdVector3(0.f, 0.f, 0.f) }; // MultiSphereShape* multiSphereShape = new MultiSphereShape(inertiaHalfExtents,positions,radi,NUM_SPHERES); ConvexHullShape* convexHullShape = new ConvexHullShape(positions,3); //choose shape shapePtr[0] = &myCone; shapePtr[1] =&simplex; shapePtr[2] =convexHullShape; shapePtr[3] =&myMink;//myBox;//multiSphereShape simplex.SetMargin(0.3f); }
size_t collide(BoxShape &box1, BoxShape &box2, float dt, Contact *pxContacts, size_t numMaxContacts) { dt; Point2f xAxis [4]; float fDepth[4]; xAxis[0] = box1.GetDir(0); if (!IntervalIntersect(xAxis[0], box1, box2, fDepth[0])) return 0; xAxis[1] = box1.GetDir(1); if (!IntervalIntersect(xAxis[1], box1, box2, fDepth[1])) return 0; xAxis[2] = box2.GetDir(0); if (!IntervalIntersect(xAxis[2], box1, box2, fDepth[2])) return 0; xAxis[3] = box2.GetDir(1); if (!IntervalIntersect(xAxis[3], box1, box2, fDepth[3])) return 0; float dcoll; Point2f Ncoll; if (!FindCollisionPlane(xAxis, fDepth, Ncoll, dcoll)) return 0; Point2f D = box1.body.getPosition() - box2.body.getPosition(); if (D * Ncoll < 0.0f) Ncoll *= -1.0f; Point2f xPoints0[4]; Point2f xPoints1[4]; size_t numPoints0; size_t numPoints1; numPoints0 = box1.FindSupportPoints( Ncoll, xPoints0); numPoints1 = box2.FindSupportPoints(-Ncoll, xPoints1); if (!ConvertSupportPointsToContacts(box1, box2, Ncoll, xPoints0, numPoints0, xPoints1, numPoints1, pxContacts, numMaxContacts)) return 0; return numMaxContacts; }
/* ========== CylinderShape::UpdateBoundingDimensions Updates the bounding dimensions of the cylinder. ========== */ void CylinderShape::UpdateBoundingDimensions( void ) { //Convert it to a box and use that BoxShape* box = BoxShape::CreateFromCylinder( *this ); m_boundingDimensions = box->GetBoundingDimensions(); delete box; }