void collisionShapeNode::computeCollisionShape(const MPlug& plug, MDataBlock& data) { //std::cout << collisionShapeNode::collisionMarginOffset << std::endl; MObject thisObject(thisMObject()); MPlug plgInShape(thisObject, ia_shape); if (isCompound(plgInShape)) { m_collision_shape = createCompositeShape(plgInShape); } else { MObject thisObject(thisMObject()); MPlug plgType(thisObject, ia_type); int type; plgType.getValue(type); switch(type) { case 4: //box m_collision_shape = solver_t::create_box_shape(); break; case 5: //sphere m_collision_shape = solver_t::create_sphere_shape(); break; case 6: //plane m_collision_shape = solver_t::create_plane_shape(); break; default: { MPlugArray plgaConnectedTo; plgInShape.connectedTo(plgaConnectedTo, true, true); int numSelectedShapes = plgaConnectedTo.length(); if(numSelectedShapes > 0) { MObject node = plgaConnectedTo[0].node(); m_collision_shape = createCollisionShape(node); } } } } //btAssert(m_collision_shape); data.setClean(plug); }
collision_shape_t::pointer collisionShapeNode::createCollisionShape(const MObject& node) { collision_shape_t::pointer collision_shape = 0; MObject thisObject(thisMObject()); MPlug plgType(thisObject, ia_type); int type; plgType.getValue(type); switch(type) { case 0: { //convex hull { if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); btAlignedObjectArray<btVector3> btVerts; //mb for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); #if UPDATE_SHAPE //future collision margin adjust btVerts.push_back(btVector3(mpoints[i].x, mpoints[i].y, mpoints[i].z)); //mb #endif } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } #if UPDATE_SHAPE //future collision margin adjust btAlignedObjectArray<btVector3> planeEquations; btGeometryUtil::getPlaneEquationsFromVertices(btVerts, planeEquations); btAlignedObjectArray<btVector3> shiftedPlaneEquations; for (int p=0;p<planeEquations.size();p++) { btVector3 plane = planeEquations[p]; plane[3] += collisionShapeNode::collisionMarginOffset; shiftedPlaneEquations.push_back(plane); } btAlignedObjectArray<btVector3> shiftedVertices; btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations, shiftedVertices); std::vector<vec3f> shiftedVerticesVec3f(shiftedVertices.size()); for(size_t i = 0; i < shiftedVertices.size(); ++i) { shiftedVerticesVec3f[i] = vec3f(shiftedVertices[i].getX(), shiftedVertices[i].getY(), shiftedVertices[i].getZ()); //std::cout << "orig verts: " << vertices[i][0] << " " << vertices[i][1] << " " << vertices[i][2] << std::endl; //std::cout << "shft verts: " << shiftedVertices[i].getX() << " " << shiftedVertices[i].getY() << " " << shiftedVertices[i].getZ() << std::endl; //std::cout << std::endl; } collision_shape = solver_t::create_convex_hull_shape(&(shiftedVerticesVec3f[0]), shiftedVerticesVec3f.size(), &(normals[0]), &(indices[0]), indices.size()); #endif #if UPDATE_SHAPE == 0 collision_shape = solver_t::create_convex_hull_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size()); //original #endif } } } break; case 1: { //mesh { if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } bool dynamicMesh = true; collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size(),dynamicMesh); } } } break; case 2: //cylinder break; case 3: //capsule break; case 7: //btBvhTriangleMeshShape { if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } bool dynamicMesh = false; collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size(),dynamicMesh); } } break; case 8: //hacd convex decomposition { { if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } bool dynamicMesh = false; collision_shape = solver_t::create_hacd_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size(),dynamicMesh); } } } break; default: { } } return collision_shape; }
void collisionShapeNode::computeCollisionShape(const MPlug& plug, MDataBlock& data) { // std::cout << "collisionShapeNode::computeCollisionShape" << std::endl; MObject thisObject(thisMObject()); MPlug plgInShape(thisObject, ia_shape); MPlug plgType(thisObject, ia_type); int type; plgType.getValue(type); switch(type) { case 0: { //convex hull MPlugArray plgaConnectedTo; plgInShape.connectedTo(plgaConnectedTo, true, true); if(plgaConnectedTo.length() > 0) { MObject node = plgaConnectedTo[0].node(); if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } m_collision_shape = solver_t::create_convex_hull_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size()); } } } break; case 1: //mesh { //convex hull MPlugArray plgaConnectedTo; plgInShape.connectedTo(plgaConnectedTo, true, true); if(plgaConnectedTo.length() > 0) { MObject node = plgaConnectedTo[0].node(); if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } m_collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size()); } } } break; case 2: //cylinder break; case 3: //capsule break; case 4: //box m_collision_shape = solver_t::create_box_shape(); break; case 5: //sphere m_collision_shape = solver_t::create_sphere_shape(); break; case 6: //plane m_collision_shape = solver_t::create_plane_shape(); break; } assert(m_collision_shape); data.setClean(plug); }