试用了一下Novodex2.6.2的布料系统,感觉相当不错,
简单易用,功能强大,速度也很不错,
布料系统不仅可以用来模拟布料,同样可以用来描述毛发,以及很多可变性的物体,例如空的汽油桶的表面等等。公司就是打算用这个制作头发的效果
不多说了,以下是总结:图以及demo懒得放出了,实在不好意思拿出手
Novodex2.6.2 布料系统
1、概述:
Novodex中的布料系统是一个由很多顶点构成的用来模拟类似衣服,旗子等可变形的物体的系统。在Novodex中,布料不同于刚体模拟,布料有一个专门的类型:NxCloth,这个类没有继承自任何类型。
2、布料属性:
布料有很多属性,这些属性通过NxClothDesc类表达。以下列举常用属性:
NxMat34 NxClothDesc::globalPose 保存全局的位置和姿态
NxReal thickness 厚度
NxReal density 密度
NxReal bendingStiffness 弯曲柔软度,取值在(0,1)
NxReal stretchingStiffness 拉伸柔软度,取值在(0,1)
NxReal dampingCoefficient 震荡衰减因子,取值在(0,1)
NxReal friction 摩擦因子,取值在(0,1)
NxCollisionGroup collisionGroup 碰撞组
NxGroupsMask groupsMask 碰撞Mask
NxU32 flags 可以通过这个设置一些行为属性,常见的flags如下:
NX_CLF_DISABLE_COLLISION 取消和刚体的碰撞
NX_CLF_SELFCOLLISION Enable/disable自碰撞
NX_CLF_GRAVITY Enable/disable重力
NX_CLF_BENDING Enable/disable 弯曲阻力
NX_CLF_BENDING_ORTHO Enable/disable直角弯曲阻力
NX_CLF_COLLISION_TWOWAY Enable/disable布料和刚体的相互影响,如果disable了,布料不会影响到刚体,例如,拖动布料不会拖动刚体,但是如果Enable了,那么拖动布料会同时拖动刚体。
NX_CLF_TEARABLE 是否可撕裂,Enable后,当施加在布料上的力大到一定程度,可以撕裂布料,但是前提是必须在初始化的时候生成了撕裂线。
NX_CLF_HARDWARE 是否使用硬件模拟
3、创建布料
创建布料首先要创建NxClothDesc,NxClothDesc负责描述所有的布料属性,然后通过NxClothDesc穿件NxCloth对象。
因为创建布料需要用户指定顶点和三角形的数据,所以还需要cook数据到SDK。
但是这种创建过程十分的繁琐,Novodex SDK 提供给了我们封装了的辅助类。MyCloth类。使用这个类能够方便的创建四方形的或者不规则的布料。
创建一块宽w,高h,顶点间隔d的布料:
MyCloth(NxScene *scene, NxClothDesc &desc, NxReal w, NxReal h, NxReal d, char *texFilename, bool tearLines)
同样可以通过复杂的3d模型创建布料:
通过读入*.obj文件创建,obj文件可以通过3D MAX直接转换
MyCloth(NxScene *scene, NxClothDesc &desc, char *objFileName, NxReal scale)
4、固定布料
布料不同于刚体,所以不可能使用Joints来固定布料,NxCloth类提供了几个用于固定布料的函数:
void attachVertexToGlobalPosition(const NxU32 vertexId, const NxVec3 &pos);
vertexId是布料上的一个点,这个函数用户将布料上的一个点固定在全局空间中的一个位置。
void attachVertexToShape(NxU32 vertexId, const NxShape *shape, const NxVec3 &localPos, NxU32 attachmentFlags);
这个函数将布料上的一个点固定在一个刚体的shape上,localPos是相对于这个刚体的局部坐标。attachmentFlags表示布料将如何影响刚体的shape,这个参数有2个取值,分别是NX_CLOTH_ATTACHMENT_TWOWAY和NX_CLOTH_ATTACHMENT_TEARABLE。NX_CLOTH_ATTACHMENT_TWOWAY 表示刚体可以影响布料,布料也可以影响刚体。但是有个条件,shape必须是动态的,也就是说如果设置了NX_BF_KINEMATIC的话,布料也无法影响到shape。
NX_CLOTH_ATTACHMENT_TEARABLE表示布料不影响刚体,施加在布料的力足够大将会撕裂布料。
void attachToCollidingShapes(NxU32 attachmentFlags);
void attachToShape(const NxShape *shape, NxU32 attachmentFlags);
这2个函数将布料固定在刚体上,只要是布料和刚体相交的点,都将被固定在刚体上。
void detachFromShape(const NxShape *shape);
void freeVertex(const NxU32 vertexId);
这2个函数用于将布料解除连接。
5、渲染:
void MyCloth::draw(bool shadows)
MyCloth类提供了渲染函数,原理其实很简单,只是将创建布料时候的顶点用Vertex Array画出。
6、Sleep
为了加速渲染,可以设置sleep,当布料的速度低于某个值的时候,认为布料静止,这样Novodex将忽略对布料的计算。
通过以下函数获取/设置Sleep速度阀值:
NxReal NxCloth::getSleepLinearVelocity() const;
void NxCloth::setSleepLinearVelocity(NxReal threshold);
可以通过以下方法查询布料是否正处于Sleep中:
bool NxCloth::isSleeping() const;
可以通过以下方法强制将Cloth置于Sleep状态中:
void NxCloth::putToSleep();
可以通过以下方法强制唤醒Cloth:
void NxCloth::wakeUp(NxReal wakeCounterValue = NX_SLEEP_INTERVAL);
7、RayCasting
很多时候需要检查一条线是否和布料相交,就需要用RayCasting,NxCloth提供了这个函数:
bool raycast(const NxRay& worldRay, NxVec3 &hit, NxU32 &vertexId);
其中,hit将保存有相交的点的坐标,vertexId是布料上和线相交的点的Id
8、施加力
NxCloth类提供了施加力的函数:
virtual void addForceAtVertex(const NxVec3& force, NxU32 vertexId, NxForceMode mode = NX_FORCE);
这个函数对布料上的一点施加力。
virtual void NxCloth::addForceAtPos ( const NxVec3 & position, const NxVec3 & force,
NxReal radius, NxForceMode mode = NX_FORCE )
这个函数对空间中的一个半径区域内施加力,所有在这个区域的布料顶点都将受到影响。
virtual void NxCloth::setExternalAcceleration ( NxVec3 acceleration )
这个函数对布料上所有的点,不包括被固定的点,施加一个加速度。