接高度地形图和三角形网格,同样是复杂图形的创建。
先来看看效果
左边通过提供的顶点生成的多面体,右边创建一个由球体与长方体组成的组合形状
首先来了解凸多面体
根据提供的顶点创建一个凸多面体形状,无论给定的顶点顺序是怎样的,都是创建一个由这些顶点组成的凸多面体。
先来看看btConvexHullShape的解释及构造函数
///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z),the strIDing defines the number of bytes between each point,in memory.///It is easIEr to not pass any points in the constructor,and just add one point at a time,using addPoint.///btConvexHullShape make an internal copy of the points.btConvexHullShape(const btScalar* points=0,int numPoints=0,int strIDe=sizeof(btVector3));
第一个参数就是顶点数据,第二个是顶点个数,第三个是每个顶点占得字节。
同时提出不需要一次将所有的顶点全部给出,以后可以添加:
voID addPoint(const btVector3& point,bool recalculateLocalAabb = true);
增加的顶点信息,是否重新计算AABB包围盒
对于提供顶点数据,用户不需要一直保存,看源码可知btConvexHullShape会用btAlignedobjectArray<btVector3>m_unscaledPoints;
来保存这些顶点数据。
来个示例
看上图,为什么会出现一个是三棱锥,而一个却不是呢?,其实两个形状是一样的,请看我慢慢道来。
前面的解释btConvexHullShape会根据提供的数据建立多面体,我们要牢记在心。
通过查看继承关系图,我们知道btConvexHullShape继承自btpolyhedralConvexShape,
而btpolyhedralConvexShape,提供了
///optional method mainly used to generate multiple contact points by clipPing polyhedral features (faces/edges)///experimental/work-in-progressvirtual bool initializepolyhedralFeatures(int shiftVerticesBymargin=0);
可以这样理解,将提供的点格式化成多面体,也就是说提供顶点后就可以调用initializepolyhedralFeatures
格式化成多面体。
上图下方是按我们提供的顶点的顺序生成的结果,上方为格式化后的结果
下面来看看笔者是如何加入到PhysicsWorld3D
btRigIDBody* PhysicsWorld3D::addConvexHull(const float* floatData,int numPoints,const btVector3& position,bool bpoly,const PhysicsMaterial3D& material){ btConvexHullShape* colShape = new btConvexHullShape(floatData,numPoints,sizeof(btVector3)); if (bpoly) { colShape->initializepolyhedralFeatures(); } auto body = getbody(colShape,position,material); _world->addRigIDBody(body); return body;}btRigIDBody* PhysicsWorld3D::addConvexHull(std::vector<btVector3>& points,const PhysicsMaterial3D& material){ auto body = addConvexHull(points[0].m_floats,points.size(),bpoly,material); return body;}
提供两个重载函数,一个是直接将包含顶点数据的浮点数据指针作为参数,另一个是将顶点数组作为参数。
提供第二个重载的目的就是为了从直接将raw文件的数据传入来生成多面体,还记得raw文件吧?Bullet(Cocos2dx)之创建地形
看个例子
std::vector<float> points;PhysicsHelper3D::loadRaw("monkey.raw",points); // blender 猴头_convexBody = _world->addConvexHull(&points[0],points.size() / 3,btVector3(-2,5),false,PhysicsMaterial3D(5.f,0.5f,0.f));_convexBody = _world->addConvexHull(&points[0],btVector3(2,true,0.f));
右不格式化,左为格式化
再来了解一下组合形状
简言之,将多个形状组合成一个图形,最上面的图片右方就是一个组合形状
可由多个不同的PrimitiveShape组成
构造函数很简单
btCompoundShape(bool enableDynamicAabbTree = true);
默认开启动态树,优化
关键是增加碰撞形状
voID addChildShape(const bttransform& localtransform,btCollisionShape* shape);
localtransform形状相对偏移,shape碰撞形状。
相对偏移:加入最终btCompoundShape在(0,0),相对偏移就是相对于(0,0)
得出要想获得组合形状就要自己创建btCollisionShape,然后添加到btCompoundShape
笔者做了简单的封装
struct PhysiCSShapeInfo3D{ btCollisionShape* colShape; bttransform transform; PhysiCSShapeInfo3D() {}; PhysiCSShapeInfo3D(btCollisionShape* shape,bttransform& trans) : colShape(shape),transform(trans) {}};
提供简单的结构体来传递CollisionShapes属性
btRigIDBody* PhysicsWorld3D::addCompound(std::vector<PhysiCSShapeInfo3D>& shapeList,const PhysicsMaterial3D& material){ btCompoundShape* shape = new btCompoundShape; for (auto& shapeInfo : shapeList) { shape->addChildShape(shapeInfo.transform,shapeInfo.colShape); } auto body = getbody(shape,material); _world->addRigIDBody(body); return body;}
std::vector<PhysiCSShapeInfo3D>&shapeList形状属性列表,来获取组合形状的刚体
来个例子
//1
shape=newbtBoxShape(btVector3(1.f,1.f,1.f));
shapeInfo.colShape=shape;
trans.setorigin(btVector3(0,1,0));
shapeInfo.transform=trans;
_shapes.push_back(shapeInfo);
//2
shape=btSphereShape(1.f);
shapeInfo.colShape=shape;
trans.setorigin(
shapeInfo.transform=trans;
_shapes.push_back(shapeInfo);
_world->addCompound(_shapes,
上例创建一个上为球体,下为长方体的组合形状
当然也可以通过球体和圆柱创建保龄球,也就可以写出一个保龄球的小游戏。
源代码
总结以上是内存溢出为你收集整理的Bullet(Cocos2dx)之凸多面体形状和组合形状全部内容,希望文章能够帮你解决Bullet(Cocos2dx)之凸多面体形状和组合形状所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)