上下求索
探索DirectX9.0)

试用了一下Novodex2.6.2的布料系统,感觉相当不错,
简单易用,功能强大,速度也很不错,
布料系统不仅可以用来模拟布料,同样可以用来描述毛发,以及很多可变性的物体,例如空的汽油桶的表面等等。公司就是打算用这个制作头发的效果

不多说了,以下是总结:图以及demo懒得放出了,实在不好意思拿出手


 

Novodex2.6.2 布料系统

1、概述:

Novodex中的布料系统是一个由很多顶点构成的用来模拟类似衣服,旗子等可变形的物体的系统。在Novodex中,布料不同于刚体模拟,布料有一个专门的类型:NxCloth,这个类没有继承自任何类型。

 

2、布料属性:

布料有很多属性,这些属性通过NxClothDesc类表达。以下列举常用属性:

NxMat34 NxClothDesc::globalPose 保存全局的位置和姿态

NxReal thickness                       厚度

NxReal density                          密度

NxReal bendingStiffness             弯曲柔软度,取值在(01

NxReal stretchingStiffness          拉伸柔软度,取值在(01

NxReal dampingCoefficient  震荡衰减因子,取值在(01

NxReal friction                          摩擦因子,取值在(01

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、创建布料

创建布料首先要创建NxClothDescNxClothDesc负责描述所有的布料属性,然后通过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_TWOWAYNX_CLOTH_ATTACHMENT_TEARABLENX_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画出。

 

6Sleep

为了加速渲染,可以设置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);  

 

 

7RayCasting

很多时候需要检查一条线是否和布料相交,就需要用RayCastingNxCloth提供了这个函数:

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   )

这个函数对布料上所有的点,不包括被固定的点,施加一个加速度。

 

posted on 2006-12-08 17:55  大河马和小魔鱼  阅读(2174)  评论(5编辑  收藏  举报