Cloth.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. #include "PhysX Stream.h"
  5. /******************************************************************************/
  6. #define CC4_CLMS CC4('C','L','M','S')
  7. /******************************************************************************/
  8. Cache<ClothMesh> ClothMeshes("Cloth Mesh"); // ClothMesh Cache
  9. /******************************************************************************/
  10. // CLOTH MESH
  11. /******************************************************************************/
  12. #if PHYSX
  13. static PxClothFabric* CreateClothMesh(MeshBase &mesh, Flt scale) // assumes that 'mesh' doesn't contain quads
  14. {
  15. if(Physx.physics && mesh.vtxs() && mesh.tris())
  16. {
  17. PxClothMeshDesc desc;
  18. desc.points .data =mesh.vtx.pos();
  19. desc.points .count =mesh.vtxs();
  20. desc.points .stride=SIZE(Vec);
  21. desc.triangles.data =mesh.tri.ind();
  22. desc.triangles.count =mesh.tris();
  23. desc.triangles.stride=SIZE(VecI);
  24. // scale
  25. Vec *pos_scaled=null;
  26. if(!Equal(scale, 1))
  27. {
  28. desc.points.data=Alloc(pos_scaled, mesh.vtxs()); REPA(mesh.vtx)pos_scaled[i]=mesh.vtx.pos(i)*scale;
  29. }
  30. // cook cloth mesh
  31. OutputStream buf;
  32. PxClothFabricCooker cook(desc, Physx.vec(Vec(0,-1,0)), true); cook.save(buf, false);
  33. Free(pos_scaled);
  34. if(!buf.data || !buf.pos)Exit("ClothMesh.create");
  35. WriteLock lock(Physics._rws);
  36. InputStream input(buf.data, buf.pos);
  37. return Physx.physics->createClothFabric(input);
  38. }
  39. return null;
  40. }
  41. PxClothFabric* ClothMesh::scaledMesh(Flt scale)
  42. {
  43. // find existing
  44. REPA(_scales)if(Equal(_scales[i].scale, scale))return _scales[i].mesh;
  45. // create new one
  46. if(PxClothFabric *mesh=CreateClothMesh(_phys, scale))
  47. {
  48. Scale &s=_scales.New();
  49. s.scale=scale;
  50. return s.mesh =mesh ;
  51. }
  52. return null;
  53. }
  54. #endif
  55. /******************************************************************************/
  56. ClothMesh& ClothMesh::del()
  57. {
  58. #if PHYSX
  59. if(_scales.elms())
  60. {
  61. SafeWriteLock lock(Physics._rws);
  62. if(Physx.physics)REPA(_scales)_scales[i].mesh->release();
  63. }
  64. #endif
  65. _scales .del();
  66. _phys .del();
  67. _skin .del();
  68. _ind_buf .del();
  69. _bone_map.del();
  70. _material=null;
  71. _skeleton=null;
  72. return T;
  73. }
  74. ClothMesh::ClothMesh()
  75. {
  76. REPAO(_skin_shader)=null;
  77. REPAO(_phys_shader)=null;
  78. _skin_frst=null;
  79. _phys_frst=null;
  80. _skeleton =null;
  81. }
  82. /******************************************************************************/
  83. ClothMesh& ClothMesh::create(C MeshBase &mesh, C MaterialPtr &material, Skeleton *skeleton)
  84. {
  85. del();
  86. if(!mesh.vtx.flag() || !mesh.vtx.matrix() || !mesh.vtx.blend()) // if we're putting the whole thing to phys
  87. {
  88. _phys.create(mesh, VTX_TEX0|VTX_FLAG).quadToTri();
  89. }else
  90. {
  91. /* Rules:
  92. Vtx:
  93. All vtx with VTX_FLAG_CLOTH go to Cloth
  94. Neighbor vtx of VTX_FLAG_CLOTH have unified skin and go to Cloth and MeshRender
  95. Rest goes only to MeshRender
  96. Tri:
  97. At least one vtx with VTX_FLAG_CLOTH -> Cloth
  98. No VTX_FLAG_CLOTH -> MeshRender
  99. */
  100. MeshBase temp;
  101. temp.create(mesh, VTX_NRM|VTX_TEX0|VTX_SKIN|VTX_FLAG).quadToTri();
  102. // unify skin
  103. Memt<Bool> cloth_neighbor; cloth_neighbor.setNumZero(temp.vtxs()); // cloth or neighbor
  104. Memt<Bool> tri_as_cloth; tri_as_cloth.setNum(temp.tris());
  105. Int tris_cloth=0,
  106. tris_skin =0;
  107. REPA(temp.tri)
  108. {
  109. Int *p=temp.tri.ind(i).c, p0=p[0], p1=p[1], p2=p[2];
  110. if(tri_as_cloth[i]=FlagTest(temp.vtx.flag(p0)|temp.vtx.flag(p1)|temp.vtx.flag(p2), VTX_FLAG_CLOTH)) // if at least one vtx is meant for phys cloth
  111. {
  112. // set all to cloth and neighbor
  113. cloth_neighbor[p0]=true;
  114. cloth_neighbor[p1]=true;
  115. cloth_neighbor[p2]=true;
  116. tris_cloth++;
  117. }else
  118. {
  119. tris_skin++;
  120. }
  121. }
  122. if(tris_cloth && tris_skin<=8)REPA(temp.tri) // if only 8 tris left in skinning version, then put them also to cloth (this will probably be faster instead of additional overhead for separate MeshRender drawing)
  123. {
  124. if(!tri_as_cloth[i]) // if not yet added to cloth
  125. {
  126. Int *p=temp.tri.ind(i).c, p0=p[0], p1=p[1], p2=p[2];
  127. tri_as_cloth [ i]=true;
  128. cloth_neighbor[p0]=true;
  129. cloth_neighbor[p1]=true;
  130. cloth_neighbor[p2]=true;
  131. }
  132. }
  133. REPA(temp.vtx)if(cloth_neighbor[i]) // is neighbor or cloth
  134. {
  135. // unify skinning
  136. VecB4 &blend=temp.vtx.blend (i),
  137. &bone =temp.vtx.matrix(i);
  138. Swap(bone.c[0], bone.c[blend.maxI()]); // put most important bone to first slot
  139. blend.set(255, 0, 0, 0); // set max weight for first bone
  140. }
  141. // create mesh
  142. temp.splitFaces(_phys, null, tri_as_cloth, null, VTX_TEX0|VTX_MATRIX|VTX_FLAG); // move selected triangles cloth/neighbors to cloth keeping flags and bone indexes
  143. _skin.create (temp ); // create remaining skinned part as MeshRender
  144. T.skeleton(skeleton);
  145. }
  146. T._material=material;
  147. if(_ind_buf.create(_phys.tris()*3, _phys.vtxs()<=0x10000))if(Ptr dest=_ind_buf.lock(LOCK_WRITE))
  148. {
  149. if(_ind_buf.bit16())Copy32To16(dest, _phys.tri.ind(), _ind_buf._ind_num);
  150. else Copy32To32(dest, _phys.tri.ind(), _ind_buf._ind_num);
  151. _ind_buf.unlock();
  152. }
  153. setShader();
  154. return T;
  155. }
  156. /******************************************************************************/
  157. ClothMesh& ClothMesh::skeleton(Skeleton *skeleton)
  158. {
  159. T._skeleton=skeleton;
  160. if(skeleton && skeleton->is() && !_bone_map.same(*skeleton)) // remap only if new skeleton exists (in case it failed to load, then it could be null or have no bones, or the parameter could just have been specifically set to null in order to clear the skeleton link) and if the existing bone map is different than of the new skeleton
  161. {
  162. if(_bone_map.is()) // remap vertexes only if the mesh already had a bone map (otherwise the vertex bone could be set, but the bone map doesn't exist yet, and in that case the vertex bone data could be lost if we've performed remapping)
  163. {
  164. Memt<Byte, 256> old_to_new;
  165. _bone_map.setRemap(*skeleton, old_to_new);
  166. boneRemap(old_to_new, false); // set false to not waste time on adjusting the '_bone_map' itself, because we're going to recreate it anyway below
  167. }
  168. // setup new mesh bone info
  169. _bone_map.create(*skeleton);
  170. }
  171. return T;
  172. }
  173. /******************************************************************************/
  174. //Bool boneRename(C Str8 &src, C Str8 &dest ); // rename 'src' bone to 'dest' bone, returns true if a bone was renamed
  175. //Bool ClothMesh::boneRename(C Str8 &src, C Str8 &dest) {return _bone_map.rename(src, dest);}
  176. void ClothMesh::boneRemap (C MemPtr<Byte, 256> &old_to_new, Bool remap_names)
  177. {
  178. _phys.boneRemap(old_to_new);
  179. if(_skin.is()){MeshBase temp(_skin); temp.boneRemap(old_to_new); _skin.create(temp);}
  180. if(remap_names)_bone_map.remap(old_to_new);
  181. }
  182. void ClothMesh::setShader()
  183. {
  184. DefaultShaders(_material(), _skin.flag() , 0, false).set(_skin_shader, &_skin_frst, null);
  185. DefaultShaders(_material(), VTX_POS|VTX_NRM|VTX_TEX0, 0, false).set(_phys_shader, &_phys_frst, null);
  186. }
  187. /******************************************************************************/
  188. Bool ClothMesh::saveData(File &f, CChar *path)C
  189. {
  190. f.cmpUIntV(2); // version
  191. f._putStr(_material.name(path));
  192. if(_phys .saveData(f))
  193. if(_skin .saveData(f))
  194. if(_ind_buf .save (f))
  195. if(_bone_map.saveOld (f))
  196. {
  197. f._putStr(Skeletons.name(skeleton(), path));
  198. // physx cooked data isn't saved, because later physx versions can't read older cloth versions (at least that's how it was in the past)
  199. return f.ok();
  200. }
  201. return false;
  202. }
  203. Bool ClothMesh::loadData(File &f, CChar *path)
  204. {
  205. del();
  206. switch(f.decUIntV()) // version
  207. {
  208. case 2:
  209. {
  210. _material.require(f._getStr(), path);
  211. if(_phys .loadData(f))
  212. if(_skin .loadData(f))
  213. if(_ind_buf .load (f))
  214. if(_bone_map.loadOld (f))
  215. {
  216. skeleton(Skeletons(f._getStr(), path));
  217. setShader();
  218. if(f.ok())return true;
  219. }
  220. }break;
  221. case 1:
  222. {
  223. _material.require(f._getStr(), path);
  224. if(!_phys.loadData(f))goto error;
  225. if(!_skin.loadData(f))goto error;
  226. if( _ind_buf.create(_phys.tris()*3, _phys.vtxs()<=0x10000))if(Ptr dest=_ind_buf.lock(LOCK_WRITE))
  227. {
  228. if(_ind_buf.bit16())Copy32To16(dest, _phys.tri.ind(), _ind_buf._ind_num);
  229. else Copy32To32(dest, _phys.tri.ind(), _ind_buf._ind_num);
  230. _ind_buf.unlock();
  231. }
  232. if(!_bone_map.loadOld(f))goto error;
  233. skeleton(Skeletons(f._getStr(), path));
  234. setShader();
  235. if(f.ok())return true;
  236. }break;
  237. case 0:
  238. {
  239. _material.require(f._getStr(), path);
  240. if(!_phys.loadData(f))goto error;
  241. if(!_skin.loadData(f))goto error;
  242. if( _ind_buf.create(_phys.tris()*3, _phys.vtxs()<=0x10000))if(Ptr dest=_ind_buf.lock(LOCK_WRITE))
  243. {
  244. if(_ind_buf.bit16())Copy32To16(dest, _phys.tri.ind(), _ind_buf._ind_num);
  245. else Copy32To32(dest, _phys.tri.ind(), _ind_buf._ind_num);
  246. _ind_buf.unlock();
  247. }
  248. setShader();
  249. if(f.ok())return true;
  250. }break;
  251. }
  252. error:
  253. del(); return false;
  254. }
  255. Bool ClothMesh::save(File &f, CChar *path)C
  256. {
  257. f.putUInt(CC4_CLMS);
  258. return saveData(f, path);
  259. }
  260. Bool ClothMesh::load(File &f, CChar *path)
  261. {
  262. if(f.getUInt()==CC4_CLMS)return loadData(f, path);
  263. del(); return false;
  264. }
  265. Bool ClothMesh::save(C Str &name)C
  266. {
  267. File f; if(f.writeTry(name)){if(save(f, _GetPath(name)) && f.flush())return true; f.del(); FDelFile(name);}
  268. return false;
  269. }
  270. Bool ClothMesh::load(C Str &name)
  271. {
  272. File f; if(f.readTry(name))return load(f, _GetPath(name));
  273. del(); return false;
  274. }
  275. /******************************************************************************/
  276. // CLOTH
  277. /******************************************************************************/
  278. Cloth::Cloth() {_update_count=0; _scale=1; _cloth_mesh=null; _vtxs=null; _vtx=null; _cloth=null; _lock=null;}
  279. Cloth& Cloth::del()
  280. {
  281. unlock();
  282. #if PHYSX
  283. if(_cloth)
  284. {
  285. SafeWriteLock lock(Physics._rws);
  286. if(_cloth)
  287. {
  288. if(Physx.physics)_cloth->release();
  289. _cloth=null;
  290. }
  291. }
  292. #else
  293. // TODO: Bullet
  294. #endif
  295. _vtx_buf.del();
  296. _update_count=Physics._update_count-1; _scale=1; _cloth_mesh=null;
  297. return T;
  298. }
  299. Bool Cloth::create(ClothMesh &cloth_mesh, C Matrix &matrix)
  300. {
  301. del();
  302. #if PHYSX
  303. if(Physx.physics && Physx.world)
  304. {
  305. Matrix m=matrix;
  306. _scale=m.x.normalize();
  307. m.y.normalize();
  308. m.z.normalize();
  309. if(PxClothFabric *cm=cloth_mesh.scaledMesh(_scale))
  310. {
  311. Memt<PxClothParticle> particles;
  312. particles.setNum(cloth_mesh._phys.vtxs());
  313. REPA(particles)
  314. {
  315. particles[i].pos =Physx.vec(cloth_mesh._phys.vtx.pos(i)*matrix);
  316. particles[i].invWeight=1.0f/1;
  317. }
  318. WriteLock lock(Physics._rws);
  319. if(_cloth=Physx.physics->createCloth(PxTransform(PxIdentity), *cm, particles.data(), PxClothFlags()))
  320. if(_vtx_buf.createNum(SIZE(Vtx), cloth_mesh._phys.vtxs(), true))
  321. {
  322. T._cloth_mesh=&cloth_mesh;
  323. _cloth->setSolverFrequency(Physics.precision());
  324. Physx.world->addActor(*_cloth);
  325. return true;
  326. }
  327. }
  328. del();
  329. }
  330. #endif
  331. return false;
  332. }
  333. /******************************************************************************/
  334. #if PHYSX
  335. C Cloth::Particle* Cloth::lockRead()
  336. {
  337. #if !APPLE // fails to compile
  338. ASSERT(SIZE (*_lock->particles )==SIZE (Particle ));
  339. ASSERT(OFFSET(PxClothParticle, pos )==OFFSET(Particle, pos ));
  340. ASSERT(OFFSET(PxClothParticle, invWeight)==OFFSET(Particle, inverse_mass));
  341. #endif
  342. if(_cloth && !_lock)_lock=_cloth->lockParticleData(PxDataAccessFlag::eREADABLE);
  343. return _lock ? (Particle*)_lock->particles : null;
  344. }
  345. Cloth& Cloth::unlock()
  346. {
  347. if(_lock)
  348. {
  349. if(Physx.world)_lock->unlock(); // in case we're unlocking after deleting physics
  350. _lock=null;
  351. }
  352. return T;
  353. }
  354. Cloth& Cloth::set(C Particle *particle, Int particles)
  355. {
  356. if(_cloth && particle && particles>=_cloth->getNbParticles())_cloth->setParticles((C PxClothParticle*)particle, null);
  357. return T;
  358. }
  359. Cloth& Cloth::setCollisionBalls(C MemPtr<Ball> &balls)
  360. {
  361. if(_cloth)
  362. {
  363. PxClothCollisionSphere sphere[32]; Int elms=Min(Elms(sphere), balls.elms());
  364. REP(elms)
  365. {
  366. sphere[i].radius= balls[i].r ;
  367. sphere[i].pos =Physx.vec(balls[i].pos);
  368. }
  369. _cloth->setCollisionSpheres(sphere, elms);
  370. }
  371. return T;
  372. }
  373. Cloth& Cloth::setCollisionCapsules(C MemPtr<VecI2> &capsules)
  374. {
  375. if(_cloth)
  376. {
  377. // remove all
  378. REP(_cloth->getNbCollisionCapsules())_cloth->removeCollisionCapsule(i);
  379. // add
  380. Int elms=Min(capsules.elms(), 32);
  381. FREP(elms)_cloth->addCollisionCapsule(capsules[i].x, capsules[i].y);
  382. }
  383. return T;
  384. }
  385. #else
  386. C Cloth::Particle* Cloth:: lockRead() {return null;}
  387. Cloth& Cloth::unlock () {return T;}
  388. Cloth& Cloth::set (C Particle *particle, Int particles) {return T;}
  389. Cloth& Cloth::setCollisionBalls (C MemPtr<Ball > &balls ) {return T;}
  390. Cloth& Cloth::setCollisionCapsules(C MemPtr<VecI2> &capsules) {return T;}
  391. #endif
  392. /******************************************************************************/
  393. // GET / SET
  394. /******************************************************************************/
  395. #if PHYSX
  396. Int Cloth::vtxs ( )C {return _cloth_mesh ? _cloth_mesh->_phys.vtxs() : 0;}
  397. Ptr Cloth::obj ( )C {return _cloth ? (Ptr)_cloth->getName() : null;}
  398. Cloth& Cloth::obj (Ptr obj ) {if (_cloth) _cloth->setName((char*)obj); return T;}
  399. Bool Cloth::sleep( )C {return _cloth ? _cloth->isSleeping() : false;}
  400. Cloth& Cloth::sleep(Bool sleep) {if (_cloth)if(sleep)_cloth->putToSleep();else _cloth->wakeUp(); return T;}
  401. Vec Cloth::wind ( )C {return _cloth ? Physx.vec(_cloth->getExternalAcceleration()) : 0;}
  402. Cloth& Cloth::wind (C Vec &accel) {if (_cloth) _cloth->setExternalAcceleration(Physx.vec(accel)); return T;}
  403. Box Cloth::box ( )C {return _cloth ? Physx.box(_cloth->getWorldBounds()) : Box(0);}
  404. Bool Cloth::ccd ( )C {return _cloth ? FlagTest((UInt)_cloth->getClothFlags(), PxClothFlag::eSWEPT_CONTACT) : false;}
  405. Cloth& Cloth::ccd (Bool on) {if (_cloth) _cloth->setClothFlag ( PxClothFlag::eSWEPT_CONTACT, on); return T;}
  406. Bool Cloth::gpu ( )C {return _cloth ? FlagTest((UInt)_cloth->getClothFlags(), PxClothFlag::eGPU ) : false;}
  407. Cloth& Cloth::gpu (Bool on) {if (_cloth) _cloth->setClothFlag ( PxClothFlag::eGPU , on); return T;}
  408. #else
  409. Int Cloth::vtxs ( )C {return 0 ;}
  410. Ptr Cloth::obj ( )C {return null ;}
  411. Cloth& Cloth::obj (Ptr obj ) {return T ;}
  412. Bool Cloth::sleep( )C {return false;}
  413. Cloth& Cloth::sleep(Bool sleep) {return T ;}
  414. Vec Cloth::wind ( )C {return 0 ;}
  415. Cloth& Cloth::wind (C Vec &accel) {return T ;}
  416. Bool Cloth::ccd ( )C {return false;}
  417. Cloth& Cloth::ccd (Bool on) {return T ;}
  418. Bool Cloth::gpu ( )C {return false;}
  419. Cloth& Cloth::gpu (Bool on) {return T ;}
  420. Box Cloth::box ( )C {return 0 ;}
  421. #endif
  422. /******************************************************************************/
  423. // PARAMETERS
  424. /******************************************************************************/
  425. #if PHYSX
  426. Flt Cloth::damping ()C {return _cloth ? _cloth->getDampingCoefficient ().x : 0;}
  427. Flt Cloth::friction ()C {return _cloth ? _cloth->getFrictionCoefficient () : 0;}
  428. Flt Cloth:: drag ()C {return _cloth ? _cloth->getLinearDragCoefficient ().x : 0;}
  429. Flt Cloth::angDrag ()C {return _cloth ? _cloth->getAngularDragCoefficient().x : 0;}
  430. Flt Cloth:: inertiaScale()C {return _cloth ? _cloth->getLinearInertiaScale ().x : 0;}
  431. Flt Cloth::angInertiaScale()C {return _cloth ? _cloth->getAngularInertiaScale ().x : 0;}
  432. Flt Cloth::bending ()C {return _cloth ? 1-_cloth->getStretchConfig(PxClothFabricPhaseType::eBENDING).stiffness : 0;}
  433. Cloth& Cloth::damping (Flt damping ) {if(_cloth)_cloth->setDampingCoefficient (Physx.vec(Sat(damping ))); return T;}
  434. Cloth& Cloth::friction (Flt friction) {if(_cloth)_cloth->setFrictionCoefficient ( Sat(friction) ); return T;}
  435. Cloth& Cloth:: drag (Flt drag ) {if(_cloth)_cloth->setLinearDragCoefficient (Physx.vec(Sat(drag ))); return T;}
  436. Cloth& Cloth::angDrag (Flt drag ) {if(_cloth)_cloth->setAngularDragCoefficient(Physx.vec(Sat(drag ))); return T;}
  437. Cloth& Cloth:: inertiaScale(Flt scale ) {if(_cloth)_cloth->setLinearInertiaScale (Physx.vec(Sat(scale ))); return T;}
  438. Cloth& Cloth::angInertiaScale(Flt scale ) {if(_cloth)_cloth->setAngularInertiaScale (Physx.vec(Sat(scale ))); return T;}
  439. Cloth& Cloth::bending (Flt bending ) {if(_cloth){PxClothStretchConfig config; config.stiffness=1-bending; _cloth->setStretchConfig(PxClothFabricPhaseType::eBENDING, config);} return T;}
  440. #else
  441. Flt Cloth::damping ()C {return 0;}
  442. Flt Cloth::friction ()C {return 0;}
  443. Flt Cloth:: drag ()C {return 0;}
  444. Flt Cloth::angDrag ()C {return 0;}
  445. Flt Cloth:: inertiaScale()C {return 0;}
  446. Flt Cloth::angInertiaScale()C {return 0;}
  447. Flt Cloth::bending ()C {return 0;}
  448. Cloth& Cloth::damping (Flt damping ) {return T;}
  449. Cloth& Cloth::friction (Flt friction) {return T;}
  450. Cloth& Cloth:: drag (Flt drag ) {return T;}
  451. Cloth& Cloth::angDrag (Flt drag ) {return T;}
  452. Cloth& Cloth:: inertiaScale(Flt scale ) {return T;}
  453. Cloth& Cloth::angInertiaScale(Flt scale ) {return T;}
  454. Cloth& Cloth::bending (Flt bending ) {return T;}
  455. #endif
  456. /******************************************************************************/
  457. // DRAW
  458. /******************************************************************************/
  459. void Cloth::update()
  460. {
  461. if(_update_count!=Physics._update_count)
  462. {
  463. _update_count=Physics._update_count;
  464. #if PHYSX
  465. if(C Particle *particles=lockRead())
  466. {
  467. if(Vtx *vtx=(Vtx*)_vtx_buf.lock(LOCK_WRITE))
  468. {
  469. C Vec2 *tex=_cloth_mesh->_phys.vtx.tex0();
  470. Vtx *v =vtx;
  471. REPA(_cloth_mesh->_phys.vtx)
  472. {
  473. v->nrm.zero();
  474. v->pos=(particles++)->pos;
  475. if(tex)v->tex=*tex++;else v->tex.zero();
  476. v++;
  477. }
  478. C VecI *ind=_cloth_mesh->_phys.tri.ind();
  479. REPA(_cloth_mesh->_phys.tri)
  480. {
  481. Vec nrm=GetNormalU(vtx[ind->x].pos, vtx[ind->y].pos, vtx[ind->z].pos);
  482. vtx[ind->x].nrm+=nrm;
  483. vtx[ind->y].nrm+=nrm;
  484. vtx[ind->z].nrm+=nrm;
  485. ind++;
  486. }
  487. REPA(_cloth_mesh->_phys.vtx)vtx[i].nrm.normalize();
  488. _vtx_buf.unlock();
  489. }
  490. unlock();
  491. }
  492. #endif
  493. }
  494. }
  495. /******************************************************************************/
  496. void Cloth::_drawPhysical()C
  497. {
  498. #if DX9
  499. _vtx_buf.set();
  500. _cloth_mesh->_ind_buf.set();
  501. D3D->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, _vtx_buf.vtxs(), 0, _cloth_mesh->_phys.tris());
  502. #elif DX11
  503. _vtx_buf.set();
  504. _cloth_mesh->_ind_buf.set();
  505. D3DC->DrawIndexed(_cloth_mesh->_ind_buf._ind_num, 0, 0);
  506. #elif GL
  507. SetDefaultVAO(); _vtx_buf.set(); D.vf(VI._vf3D_cloth.vf); // OpenGL requires setting 1)VAO 2)VB+IB 3)VF
  508. _cloth_mesh->_ind_buf.set();
  509. glDrawElements(GL_TRIANGLES, _cloth_mesh->_ind_buf._ind_num, _cloth_mesh->_ind_buf.bit16() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, null);
  510. #endif
  511. }
  512. /******************************************************************************/
  513. void Cloth::drawSkinnedOutline(C AnimatedSkeleton &anim_skel, C Color &color)C
  514. {
  515. if(_cloth_mesh)if(Shader *shader=_cloth_mesh->_skin_shader[RM_OUTLINE])
  516. {
  517. anim_skel.setMatrix();
  518. C Material &mtrl=GetMaterial(_cloth_mesh->material()());
  519. Renderer.setOutline(color);
  520. D.depth(true);
  521. mtrl.setOutline(); D.cull(mtrl.cull);
  522. shader->begin(); _cloth_mesh->_skin.set().draw();
  523. ShaderEnd();
  524. }
  525. }
  526. INLINE void ClothInstances::add(C Cloth &cloth, Shader &shader, C Material &material)
  527. {
  528. ClothInstance &ci=New();
  529. ci.cloth =&cloth;
  530. ci.shader =&shader;
  531. ci.material =&material; material.incUsage();
  532. }
  533. INLINE void ClothInstances::add(C Cloth &cloth, Shader &shader, C Material &material, C Vec &vel)
  534. {
  535. ClothInstance &ci=New();
  536. ci.cloth =&cloth;
  537. ci.shader =&shader;
  538. ci.material =&material; material.incUsage();
  539. ci.vel = vel;
  540. ci.highlight= Renderer._mesh_highlight;
  541. }
  542. INLINE void ClothInstances::add(C Cloth &cloth, FRST &frst, C Material &material)
  543. {
  544. ClothInstance &ci=New();
  545. ci.cloth =&cloth;
  546. ci.shader =&frst;
  547. ci.material =&material; material.incUsage();
  548. ci.highlight= Renderer._mesh_highlight;
  549. }
  550. void Cloth::drawPhysical(C Vec &vel)C
  551. {
  552. if(_cloth && Frustum(box()))
  553. {
  554. ConstCast(T).update();
  555. C Material &material=GetMaterial(_cloth_mesh->material()());
  556. switch(Renderer._cur_type)
  557. {
  558. case RT_DEFERRED:
  559. case RT_SIMPLE : if(Shader *shader=_cloth_mesh->_phys_shader[Renderer._solid_mode_index])
  560. {
  561. SolidClothInstances.add(T, *shader, material, vel);
  562. }break;
  563. case RT_FORWARD: if(FRST *frst=_cloth_mesh->_phys_frst)if(Renderer.firstPass() || frst->all_passes)//if(Shader *shader=frst->getShader())
  564. {
  565. SolidClothInstances.add(T, *frst, material); // velocities not needed in forward renderer
  566. }break;
  567. }
  568. }
  569. }
  570. void Cloth::drawPhysicalShadow()C
  571. {
  572. if(_cloth && Frustum(box()))
  573. if(Shader *shader=_cloth_mesh->_phys_shader[RM_SHADOW])
  574. {
  575. ConstCast(T).update();
  576. ShadowClothInstances.add(T, *shader, GetMaterial(_cloth_mesh->material()()));
  577. }
  578. }
  579. void Cloth::drawPhysicalOutline(C Color &color)C
  580. {
  581. if(_cloth && Frustum(box()))
  582. if(Shader *shader=_cloth_mesh->_phys_shader[RM_OUTLINE])
  583. {
  584. ConstCast(T).update();
  585. C Material &mtrl=GetMaterial(_cloth_mesh->material()());
  586. Renderer.setOutline(color);
  587. SetOneMatrix();
  588. D.depth(true);
  589. SetDefaultVAO(); D.vf(VI._vf3D_cloth.vf); // OpenGL requires setting 1)VAO 2)VB+IB 3)VF
  590. D.cull (mtrl.cull); mtrl.setOutline();
  591. SetVtxNrmMulAdd(false);
  592. shader->begin(); _drawPhysical();
  593. ShaderEnd();
  594. SetVtxNrmMulAdd(true);
  595. }
  596. }
  597. /******************************************************************************/
  598. }
  599. /******************************************************************************/