Phys Material.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. #define CC4_PHMT CC4('P','H','M','T') // Physics Material
  6. /******************************************************************************/
  7. Cache<PhysMtrl> PhysMtrls("Physics Material");
  8. /******************************************************************************/
  9. PhysMtrl::PhysMtrl()
  10. {
  11. _m=null;
  12. _bounciness=_friction_static=_friction_dynamic=_density=_damping=_adamping=-1; // set -1 so when setting initial values in 'reset' they will always be changed
  13. _bounciness_mode=_friction_mode=MODE_AVG;
  14. }
  15. /******************************************************************************/
  16. void PhysMtrl::del()
  17. {
  18. if(this!=&Physics.mtrl_default) // don't allow deleting the default material because it is required to exist on PhysX
  19. if(_m)
  20. {
  21. SafeWriteLock lock(Physics._rws);
  22. if(_m)
  23. {
  24. #if PHYSX
  25. if(Physx.physics){_m->userData=null; _m->release();} // set user data to null in case material is ref counted and released later
  26. #endif
  27. _m=null;
  28. }
  29. }
  30. }
  31. PhysMtrl& PhysMtrl::create() // don't delete so pointers don't need to be reallocated, instead just reset its values
  32. {
  33. #if PHYSX
  34. if(!_m)
  35. {
  36. WriteLock lock(Physics._rws);
  37. if(!_m)
  38. {
  39. if(Physx.physics)if(_m=Physx.physics->createMaterial(0, 0, 0))_m->userData=this;
  40. }
  41. }
  42. #endif
  43. reset();
  44. return T;
  45. }
  46. void PhysMtrl::reset()
  47. {
  48. bounciness(0).frictionStatic(0).frictionDynamic(0).bouncinessMode(MODE_AVG).frictionMode(MODE_AVG).anisotropic(false).density(1).damping(0.05f).adamping(0.05f);
  49. }
  50. /******************************************************************************/
  51. Flt PhysMtrl::bounciness ()C {return _bounciness ;}
  52. Flt PhysMtrl::frictionStatic ()C {return _friction_static ;}
  53. Flt PhysMtrl::frictionDynamic()C {return _friction_dynamic;}
  54. Flt PhysMtrl:: density ()C {return _density ;} PhysMtrl& PhysMtrl:: density(Flt x) {MAX(x, 0); _density =x; return T;}
  55. Flt PhysMtrl:: damping ()C {return _damping ;} PhysMtrl& PhysMtrl:: damping(Flt x) {MAX(x, 0); _damping =x; return T;}
  56. Flt PhysMtrl::adamping ()C {return _adamping ;} PhysMtrl& PhysMtrl::adamping(Flt x) {MAX(x, 0); _adamping=x; return T;}
  57. /******************************************************************************/
  58. #if PHYSX
  59. /*Flt PhysMtrl::bounciness ()C {return _m ? _m->getRestitution () : 0;}*/ PhysMtrl& PhysMtrl::bounciness (Flt x) {SAT(x ); if(_bounciness !=x){_bounciness =x; if(_m)_m->setRestitution (x);} return T;}
  60. /*Flt PhysMtrl::frictionStatic ()C {return _m ? _m->getStaticFriction () : 0;}*/ PhysMtrl& PhysMtrl::frictionStatic (Flt x) {MAX(x, 0); if(_friction_static !=x){_friction_static =x; if(_m)_m->setStaticFriction (x);} return T;}
  61. /*Flt PhysMtrl::frictionDynamic ()C {return _m ? _m->getDynamicFriction() : 0;}*/ PhysMtrl& PhysMtrl::frictionDynamic (Flt x) {MAX(x, 0); if(_friction_dynamic!=x){_friction_dynamic=x; if(_m)_m->setDynamicFriction(x);} return T;}
  62. Flt PhysMtrl::frictionStaticA ()C {return 0;} PhysMtrl& PhysMtrl::frictionStaticA (Flt x) {return T;}
  63. Flt PhysMtrl::frictionDynamicA()C {return 0;} PhysMtrl& PhysMtrl::frictionDynamicA(Flt x) {return T;}
  64. Bool PhysMtrl::anisotropic( )C {return false;}
  65. PhysMtrl& PhysMtrl::anisotropic(Bool on) {return T;}
  66. Vec PhysMtrl::anisotropicDir( )C {return Vec(0, 1, 0);}
  67. PhysMtrl& PhysMtrl::anisotropicDir(C Vec &dir) {return T;}
  68. PhysMtrl& PhysMtrl::bouncinessMode(MODE mode)
  69. {
  70. if(_m)switch(mode)
  71. {
  72. case MODE_AVG: _m->setRestitutionCombineMode(PxCombineMode::eAVERAGE ); break;
  73. case MODE_MUL: _m->setRestitutionCombineMode(PxCombineMode::eMULTIPLY); break;
  74. case MODE_MIN: _m->setRestitutionCombineMode(PxCombineMode::eMIN ); break;
  75. case MODE_MAX: _m->setRestitutionCombineMode(PxCombineMode::eMAX ); break;
  76. }
  77. return T;
  78. }
  79. PhysMtrl& PhysMtrl::frictionMode(MODE mode)
  80. {
  81. if(_m)switch(mode)
  82. {
  83. case MODE_AVG: _m->setFrictionCombineMode(PxCombineMode::eAVERAGE ); break;
  84. case MODE_MUL: _m->setFrictionCombineMode(PxCombineMode::eMULTIPLY); break;
  85. case MODE_MIN: _m->setFrictionCombineMode(PxCombineMode::eMIN ); break;
  86. case MODE_MAX: _m->setFrictionCombineMode(PxCombineMode::eMAX ); break;
  87. }
  88. return T;
  89. }
  90. PhysMtrl::MODE PhysMtrl::bouncinessMode()C
  91. {
  92. if(_m)switch(_m->getRestitutionCombineMode())
  93. {
  94. case PxCombineMode::eAVERAGE : return MODE_AVG;
  95. case PxCombineMode::eMULTIPLY: return MODE_MUL;
  96. case PxCombineMode::eMIN : return MODE_MIN;
  97. case PxCombineMode::eMAX : return MODE_MAX;
  98. }
  99. return MODE_AVG;
  100. }
  101. PhysMtrl::MODE PhysMtrl::frictionMode()C
  102. {
  103. if(_m)switch(_m->getFrictionCombineMode())
  104. {
  105. case PxCombineMode::eAVERAGE : return MODE_AVG;
  106. case PxCombineMode::eMULTIPLY: return MODE_MUL;
  107. case PxCombineMode::eMIN : return MODE_MIN;
  108. case PxCombineMode::eMAX : return MODE_MAX;
  109. }
  110. return MODE_AVG;
  111. }
  112. #else
  113. static void Changed(PhysMtrl *material)
  114. {
  115. /*if(material)
  116. {
  117. SyncLocker locker(Physics._lock);
  118. if(Bullet.world)
  119. REP(Bullet.world->getNumCollisionObjects())
  120. if(RigidBody *rb=CAST(RigidBody, Bullet.world->getCollisionObjectArray()[i]))
  121. if(rb->material==material)rb->materialApply();
  122. }*/
  123. }
  124. PhysMtrl& PhysMtrl::bounciness (Flt x) {SAT(x ); if(_bounciness !=x){_bounciness =x; Changed(this);} return T;}
  125. PhysMtrl& PhysMtrl::frictionStatic (Flt x) {MAX(x, 0); if(_friction_static !=x){_friction_static =x; Changed(this);} return T;}
  126. PhysMtrl& PhysMtrl::frictionDynamic(Flt x) {MAX(x, 0); if(_friction_dynamic!=x){_friction_dynamic=x; Changed(this);} return T;}
  127. // TODO: Bullet
  128. Bool PhysMtrl::anisotropic ( )C {return 0;}
  129. PhysMtrl& PhysMtrl::anisotropic ( Bool on ) {return T;}
  130. Vec PhysMtrl::anisotropicDir( )C {return 0;}
  131. PhysMtrl& PhysMtrl::anisotropicDir(C Vec &dir) {return T;}
  132. Flt PhysMtrl::frictionStaticA ()C {return 0;} PhysMtrl& PhysMtrl::frictionStaticA (Flt x) {return T;}
  133. Flt PhysMtrl::frictionDynamicA()C {return 0;} PhysMtrl& PhysMtrl::frictionDynamicA(Flt x) {return T;}
  134. PhysMtrl::MODE PhysMtrl::bouncinessMode()C {return _bounciness_mode;} PhysMtrl& PhysMtrl::bouncinessMode(MODE mode) {_bounciness_mode=mode; return T;}
  135. PhysMtrl::MODE PhysMtrl::frictionMode ()C {return _friction_mode ;} PhysMtrl& PhysMtrl::frictionMode (MODE mode) {_friction_mode =mode; return T;}
  136. #endif
  137. /******************************************************************************/
  138. Bool PhysMtrl::save(File &f)C
  139. {
  140. f.putMulti(UInt(CC4_PHMT), Byte(0)); // version
  141. f.putFlt(bounciness()).putFlt(frictionStatic()).putFlt(frictionDynamic()).putFlt(density()).putFlt(damping()).putFlt(adamping()).putByte(bouncinessMode()).putByte(frictionMode());
  142. if(!anisotropic())f.putBool(false);else{f.putBool(true).putFlt(frictionStaticA()).putFlt(frictionDynamicA())<<anisotropicDir();}
  143. return f.ok();
  144. }
  145. Bool PhysMtrl::load(File &f)
  146. {
  147. create();
  148. if(f.getUInt()==CC4_PHMT)switch(f.decUIntV())
  149. {
  150. case 0:
  151. {
  152. bounciness (f.getFlt());
  153. frictionStatic (f.getFlt());
  154. frictionDynamic(f.getFlt());
  155. density (f.getFlt());
  156. damping (f.getFlt());
  157. adamping (f.getFlt());
  158. bouncinessMode ((MODE)f.getByte());
  159. frictionMode ((MODE)f.getByte());
  160. if(!f.getBool())anisotropic(false);else
  161. {
  162. anisotropic (true);
  163. frictionStaticA (f.getFlt());
  164. frictionDynamicA(f.getFlt());
  165. Vec dir; f>>dir; anisotropicDir (dir);
  166. }
  167. if(f.ok())return true;
  168. }break;
  169. }
  170. create(); return false;
  171. }
  172. Bool PhysMtrl::save(C Str &name)C
  173. {
  174. File f; if(f.writeTry(name)){if(save(f) && f.flush())return true; f.del(); FDelFile(name);}
  175. return false;
  176. }
  177. Bool PhysMtrl::load(C Str &name)
  178. {
  179. File f; if(f.readTry(name))return load(f);
  180. create(); return false;
  181. }
  182. /******************************************************************************/
  183. }
  184. /******************************************************************************/