void ConvexShape::_updateCollision() { SAFE_DELETE( mPhysicsRep ); if ( !PHYSICSMGR ) return; PhysicsCollision *colShape = PHYSICSMGR->createCollision(); // We need the points untransformed! Vector<Point3F> rawPoints; MatrixF xfm( getWorldTransform() ); xfm.setPosition( Point3F::Zero ); for ( U32 i=0; i < mGeometry.points.size(); i++ ) { Point3F p = mGeometry.points[i]; xfm.mulP( p ); rawPoints.push_back( p ); } // The convex generation from a point cloud // can fail at times... give up in that case. if ( !colShape->addConvex( mGeometry.points.address(), mGeometry.points.size(), MatrixF::Identity ) ) { delete colShape; return; } PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" ); mPhysicsRep = PHYSICSMGR->createBody(); mPhysicsRep->init( colShape, 0, 0, this, world ); mPhysicsRep->setTransform( getTransform() ); }
PhysicsCollision* CollisionComponent::buildColShapes() { PROFILE_SCOPE(CollisionComponent_buildColShapes); PhysicsCollision *colShape = NULL; U32 surfaceKey = 0; TSShape* shape = mOwnerRenderInterface->getShape(); if (mCollisionType == VisibleMesh) { // Here we build triangle collision meshes from the // visible detail levels. // A negative subshape on the detail means we don't have geometry. const TSShape::Detail &detail = shape->details[0]; if (detail.subShapeNum < 0) return NULL; // We don't try to optimize the triangles we're given // and assume the art was created properly for collision. ConcretePolyList polyList; polyList.setTransform(&MatrixF::Identity, mOwner->getScale()); // Create the collision meshes. S32 start = shape->subShapeFirstObject[detail.subShapeNum]; S32 end = start + shape->subShapeNumObjects[detail.subShapeNum]; for (S32 o = start; o < end; o++) { const TSShape::Object &object = shape->objects[o]; if (detail.objectDetailNum >= object.numMeshes) continue; // No mesh or no verts.... nothing to do. TSMesh *mesh = shape->meshes[object.startMeshIndex + detail.objectDetailNum]; if (!mesh || mesh->mNumVerts == 0) continue; // Gather the mesh triangles. polyList.clear(); mesh->buildPolyList(0, &polyList, surfaceKey, NULL); // Create the collision shape if we haven't already. if (!colShape) colShape = PHYSICSMGR->createCollision(); // Get the object space mesh transform. MatrixF localXfm; shape->getNodeWorldTransform(object.nodeIndex, &localXfm); colShape->addTriangleMesh(polyList.mVertexList.address(), polyList.mVertexList.size(), polyList.mIndexList.address(), polyList.mIndexList.size() / 3, localXfm); } // Return what we built... if anything. return colShape; } else if (mCollisionType == CollisionMesh) { // Scan out the collision hulls... // // TODO: We need to support LOS collision for physics. // for (U32 i = 0; i < shape->details.size(); i++) { const TSShape::Detail &detail = shape->details[i]; const String &name = shape->names[detail.nameIndex]; // Is this a valid collision detail. if (!dStrStartsWith(name, colisionMeshPrefix) || detail.subShapeNum < 0) continue; // Now go thru the meshes for this detail. S32 start = shape->subShapeFirstObject[detail.subShapeNum]; S32 end = start + shape->subShapeNumObjects[detail.subShapeNum]; if (start >= end) continue; for (S32 o = start; o < end; o++) { const TSShape::Object &object = shape->objects[o]; const String &meshName = shape->names[object.nameIndex]; if (object.numMeshes <= detail.objectDetailNum) continue; // No mesh, a flat bounds, or no verts.... nothing to do. TSMesh *mesh = shape->meshes[object.startMeshIndex + detail.objectDetailNum]; if (!mesh || mesh->getBounds().isEmpty() || mesh->mNumVerts == 0) continue; // We need the default mesh transform. MatrixF localXfm; shape->getNodeWorldTransform(object.nodeIndex, &localXfm); // We have some sort of collision shape... so allocate it. if (!colShape) colShape = PHYSICSMGR->createCollision(); // Any other mesh name we assume as a generic convex hull. // // Collect the verts using the vertex polylist which will // filter out duplicates. This is importaint as the convex // generators can sometimes fail with duplicate verts. // VertexPolyList polyList; MatrixF meshMat(localXfm); Point3F t = meshMat.getPosition(); t.convolve(mOwner->getScale()); meshMat.setPosition(t); polyList.setTransform(&MatrixF::Identity, mOwner->getScale()); mesh->buildPolyList(0, &polyList, surfaceKey, NULL); colShape->addConvex(polyList.getVertexList().address(), polyList.getVertexList().size(), meshMat); } // objects } // details } return colShape; }