Phys [email protected] 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. /******************************************************************************/
  4. PhysMtrlEditor PhysMtrlEdit;
  5. /******************************************************************************/
  6. /******************************************************************************/
  7. cchar8 *PhysMtrlEditor::mode_t[]=
  8. {
  9. "Average" , // 0
  10. "Multiply", // 1
  11. "Minimum" , // 2
  12. "Maximum" , // 3
  13. };
  14. /******************************************************************************/
  15. void PhysMtrlEditor::Change::create(ptr user)
  16. {
  17. data=PhysMtrlEdit.edit;
  18. PhysMtrlEdit.undoVis();
  19. }
  20. void PhysMtrlEditor::Change::apply(ptr user)
  21. {
  22. PhysMtrlEdit.edit.undo(data);
  23. PhysMtrlEdit.setChanged();
  24. PhysMtrlEdit.toGui();
  25. PhysMtrlEdit.undoVis();
  26. }
  27. void PhysMtrlEditor::undoVis() {SetUndo(undos, undo, redo);}
  28. void PhysMtrlEditor::Draw(Viewport &viewport) {PhysMtrlEdit.draw();}
  29. void PhysMtrlEditor::draw()
  30. {
  31. if(sim_type)
  32. {
  33. cam.setSpherical().set();
  34. D.clear(TURQ);
  35. REPAO(actor_stat).draw(GREEN);
  36. REPAO(actor_dyn ).draw(WHITE);
  37. SetMatrix();
  38. MatrixIdentity.draw();
  39. Vec2 pos=viewport.screenPos();
  40. pos.x+=viewport.rect().w()*sim_time/sim_length;
  41. pos.y-=viewport.rect().h();
  42. Rect_D(pos, 0.025f, 0.04f).draw(ColorAlpha(BLACK, 0.5f));
  43. }
  44. }
  45. void PhysMtrlEditor::PreChanged(C Property &prop) {PhysMtrlEdit.undos.set(&prop);}
  46. void PhysMtrlEditor::Changed(C Property &prop) {PhysMtrlEdit.setChanged();}
  47. void PhysMtrlEditor::FricStat( PhysMtrlEditor &me, C Str &t) {me.edit.friction_static=TextFlt(t); me.edit.friction_static_time.getUTC();}
  48. Str PhysMtrlEditor::FricStat(C PhysMtrlEditor &me ) {return me.edit.friction_static;}
  49. void PhysMtrlEditor::FricDyn( PhysMtrlEditor &me, C Str &t) {me.edit.friction_dynamic=TextFlt(t); me.edit.friction_dynamic_time.getUTC();}
  50. Str PhysMtrlEditor::FricDyn(C PhysMtrlEditor &me ) {return me.edit.friction_dynamic;}
  51. void PhysMtrlEditor::FricMode( PhysMtrlEditor &me, C Str &t) {me.edit.friction_mode=PhysMtrl::MODE(TextInt(t)); me.edit.friction_mode_time.getUTC();}
  52. Str PhysMtrlEditor::FricMode(C PhysMtrlEditor &me ) {return me.edit.friction_mode;}
  53. void PhysMtrlEditor::Boun( PhysMtrlEditor &me, C Str &t) {me.edit.bounciness=TextFlt(t); me.edit.bounciness_time.getUTC();}
  54. Str PhysMtrlEditor::Boun(C PhysMtrlEditor &me ) {return me.edit.bounciness;}
  55. void PhysMtrlEditor::BounMode( PhysMtrlEditor &me, C Str &t) {me.edit.bounciness_mode=PhysMtrl::MODE(TextInt(t)); me.edit.bounciness_mode_time.getUTC();}
  56. Str PhysMtrlEditor::BounMode(C PhysMtrlEditor &me ) {return me.edit.bounciness_mode;}
  57. void PhysMtrlEditor::Density( PhysMtrlEditor &me, C Str &t) {me.edit.density=TextFlt(t); me.edit.density_time.getUTC();}
  58. Str PhysMtrlEditor::Density(C PhysMtrlEditor &me ) {return me.edit.density;}
  59. void PhysMtrlEditor::Damping( PhysMtrlEditor &me, C Str &t) {me.edit.damping=TextFlt(t); me.edit.damping_time.getUTC();}
  60. Str PhysMtrlEditor::Damping(C PhysMtrlEditor &me ) {return me.edit.damping;}
  61. void PhysMtrlEditor::ADamping( PhysMtrlEditor &me, C Str &t) {me.edit.adamping=TextFlt(t); me.edit.adamping_time.getUTC();}
  62. Str PhysMtrlEditor::ADamping(C PhysMtrlEditor &me ) {return me.edit.adamping;}
  63. void PhysMtrlEditor::Undo(PhysMtrlEditor &editor) {editor.undos.undo();}
  64. void PhysMtrlEditor::Redo(PhysMtrlEditor &editor) {editor.undos.redo();}
  65. void PhysMtrlEditor::Locate(PhysMtrlEditor &editor) {Proj.elmLocate(editor.elm_id);}
  66. ElmPhysMtrl* PhysMtrlEditor::data()C {return elm ? elm->physMtrlData() : null;}
  67. void PhysMtrlEditor::simType(SIM_TYPE sim_type)
  68. {
  69. sim_time=0;
  70. actor_dyn .clear();
  71. actor_stat.clear();
  72. switch(T.sim_type=sim_type)
  73. {
  74. case SIM_FRIC:
  75. {
  76. REP(7)
  77. {
  78. Matrix m; m.setRotateX(i*-0.19f); m.move(Vec((i-3)*2, 0, 0));
  79. actor_stat.New().create(OBox(Box(1.1f, 1, 10, Vec(0, -0.5f, -4.5f)), m), 0);
  80. actor_dyn .New().create(OBox(Box( 1, 1, 1, Vec(0, 0.5f, 0 )), m));
  81. }
  82. }break;
  83. case SIM_BOUNCE:
  84. {
  85. actor_stat.New().create(Box(10, 1, 10, Vec(0, -3, 0)), 0);
  86. actor_dyn .New().create(Ball(0.5f, Vec(0, 3, 0)));
  87. }break;
  88. case SIM_DAMPING:
  89. {
  90. actor_dyn.New().create(Ball(0.4f, Vec(-12, 0, 0))).vel(Vec(18, 10, 0));
  91. }break;
  92. case SIM_ADAMPING:
  93. {
  94. actor_dyn.New().create(Box(4, Vec(0, 0, 0))).gravity(false).maxAngVel(100).angVel(Vec(7, 7, 0));
  95. }break;
  96. }
  97. setMtrl();
  98. }
  99. ::PhysMtrlEditor::SIM_TYPE PhysMtrlEditor::desiredSimType()C
  100. {
  101. if(fric_stat && fric_stat->contains(Gui.ms())
  102. || fric_dyn && fric_dyn ->contains(Gui.ms())
  103. || fric_mode && fric_mode->contains(Gui.ms()))return SIM_FRIC;
  104. if(boun && boun ->contains(Gui.ms())
  105. || boun_mode && boun_mode->contains(Gui.ms()))return SIM_BOUNCE;
  106. if(damp && damp ->contains(Gui.ms()))return SIM_DAMPING;
  107. if(adamp && adamp ->contains(Gui.ms()))return SIM_ADAMPING;
  108. return SIM_NONE;
  109. }
  110. void PhysMtrlEditor::create()
  111. {
  112. fric_stat=&add("Friction Static" , MemberDesc(DATA_REAL).setFunc(FricStat, FricStat)).desc("Object friction when it is not moving").min(0);
  113. fric_dyn =&add("Friction Dynamic", MemberDesc(DATA_REAL).setFunc(FricDyn , FricDyn )).desc("Object friction when it is moving").min(0);
  114. fric_mode=&add("Friction Mode" , MemberDesc( ).setFunc(FricMode, FricMode)).setEnum(mode_t, Elms(mode_t)).desc("Operation used to calculate the friction with another object");
  115. boun =&add("Bounciness" , MemberDesc(DATA_REAL).setFunc(Boun , Boun )).desc("How much should the object bounce from others").range(0, 1);
  116. boun_mode=&add("Bounciness Mode" , MemberDesc( ).setFunc(BounMode, BounMode)).setEnum(mode_t, Elms(mode_t)).desc("Operation used to calculate the bounciness with another object");
  117. damp =&add("Damping" , MemberDesc(DATA_REAL).setFunc(Damping , Damping )).desc("Damping reduces object velocity over time").min(0);
  118. adamp =&add("Angular Damping" , MemberDesc(DATA_REAL).setFunc(ADamping, ADamping)).desc("Angular Damping reduces object angular velocity over time").min(0);
  119. add("Density" , MemberDesc(DATA_REAL).setFunc(Density , Density )).desc("Density is a multiplier applied to object mass\nValue of zero forces objects to be static (unmovable)").min(0);
  120. add();
  121. df =&add();
  122. dfs =&add();
  123. dfd =&add();
  124. dfb =&add();
  125. autoData(this);
  126. prop_max_x=::PropWin::create("Physics Material Editor", Vec2(0.02f, -0.07f), 0.036f, 0.043f, 0.2f).max.x; ::PropWin::changed(Changed, PreChanged); button[2].func(HideProjAct, SCAST(GuiObj, T)).show(); flag|=WIN_RESIZABLE;
  127. T+=undo .create(Rect_LU(0.02f, -0.01f , 0.05f, 0.05f)).func(Undo, T).focusable(false).desc("Undo"); undo.image="Gui/Misc/undo.img";
  128. T+=redo .create(Rect_LU(undo.rect().ru(), 0.05f, 0.05f)).func(Redo, T).focusable(false).desc("Redo"); redo.image="Gui/Misc/redo.img";
  129. T+=locate.create(Rect_LU(redo.rect().ru()+Vec2(0.01f, 0), 0.14f, 0.05f), "Locate").func(Locate, T).focusable(false).desc("Locate this element in the Project");
  130. // set text after creating properties so its length will not affect spacing
  131. df ->name.set(S+"Default Material (Green) :");
  132. dfs->name.set(S+"Friction Static: " +Physics.mtrl_default.frictionStatic ());
  133. dfd->name.set(S+"Friction Dynamic: "+Physics.mtrl_default.frictionDynamic());
  134. dfb->name.set(S+"Bounciness: " +Physics.mtrl_default.bounciness ());
  135. T+=viewport.create(Draw); viewport.fov=PreviewFOV;
  136. rect(Rect_C(0, 0, Min(1.7f, D.w()*2), Min(1.12f, D.h()*2)));
  137. cam.setSpherical(Vec(0), 0, 0, 0, 24);
  138. }
  139. void PhysMtrlEditor::setMtrl()
  140. {
  141. REPAO(actor_dyn).material( null); edit.copyTo(temp); temp.density(1); // set to null in case changing material props would affect all actors
  142. REPAO(actor_dyn).material(&temp);
  143. }
  144. PhysMtrlEditor& PhysMtrlEditor::hide( ) {set(null); ::PropWin::hide(); return T;}
  145. Rect PhysMtrlEditor::sizeLimit( )C {Rect r=::EE::Window::sizeLimit(); r.min.set(1.0f, 0.70f); return r;}
  146. PhysMtrlEditor& PhysMtrlEditor::rect(C Rect &rect)
  147. {
  148. ::EE::Window::rect(rect);
  149. viewport.rect(Rect(prop_max_x, -clientHeight(), clientWidth(), 0).extend(-0.02f));
  150. return T;
  151. }
  152. void PhysMtrlEditor::update(C GuiPC &gpc)
  153. {
  154. ::EE::ClosableWindow::update(gpc);
  155. if(visible() && gpc.visible)
  156. {
  157. if(Gui.ms ()==&viewport)if(Ms.b(0) || Ms.b(4)){cam.yaw-=Ms.d().x; cam.pitch+=Ms.d().y; Ms.freeze();}
  158. if(Gui.wheel()==&viewport)Clamp(cam.dist*=ScaleFactor(Ms.wheel()*-0.2f), 10, 36);
  159. REPA(Touches)if(Touches[i].guiObj()==&viewport && Touches[i].on()){cam.yaw-=Touches[i].ad().x*2.0f; cam.pitch+=Touches[i].ad().y*2.0f;}
  160. sim_time+=Time.d();
  161. if(SIM_TYPE sim=desiredSimType())if(sim!=sim_type)simType(sim);
  162. if(sim_time>sim_length )simType(sim_type);
  163. }
  164. }
  165. void PhysMtrlEditor::flush()
  166. {
  167. if(elm && changed)
  168. {
  169. if(ElmPhysMtrl *data=elm->physMtrlData())data->newVer(); // modify just before saving/sending in case we've received data from server after edit
  170. Save( edit, Proj.editPath(elm->id)); edit.copyTo(*game);
  171. Save(*game, Proj.gamePath(elm->id)); Proj.savedGame(*elm);
  172. Server.setElmLong(elm->id);
  173. }
  174. changed=false;
  175. }
  176. void PhysMtrlEditor::setChanged()
  177. {
  178. if(elm)
  179. {
  180. changed=true;
  181. edit.copyTo(*game);
  182. if(ElmPhysMtrl *data=elm->physMtrlData())data->newVer();
  183. setMtrl();
  184. }
  185. }
  186. void PhysMtrlEditor::set(Elm *elm)
  187. {
  188. if(elm && elm->type!=ELM_PHYS_MTRL)elm=null;
  189. if(T.elm!=elm)
  190. {
  191. flush();
  192. undos.del(); undoVis();
  193. T.elm =elm;
  194. T.elm_id=(elm ? elm->id : UIDZero);
  195. if(elm){edit.load(Proj.editPath(*elm)); game=PhysMtrls(Proj.gamePath(*elm));}else{edit.reset(); game=null;}
  196. toGui();
  197. setMtrl();
  198. Proj.refresh(false, false);
  199. visible(T.elm!=null).moveToTop();
  200. if(!T.elm)simType(SIM_NONE);
  201. }
  202. }
  203. void PhysMtrlEditor::toggle(Elm *elm) {if(elm==T.elm)elm=null; set(elm);}
  204. void PhysMtrlEditor::activate(Elm *elm) {set(elm); if(T.elm)::EE::GuiObj::activate();}
  205. void PhysMtrlEditor::elmChanged(C UID &elm_id)
  206. {
  207. if(elm && elm->id==elm_id)
  208. {
  209. undos.set(null, true);
  210. EditPhysMtrl temp; if(temp.load(Proj.editPath(*elm)))if(edit.sync(temp)){edit.copyTo(*game); toGui(); setMtrl();}
  211. }
  212. }
  213. void PhysMtrlEditor::erasing(C UID &elm_id) {if(elm && elm->id==elm_id)set(null);}
  214. PhysMtrlEditor::PhysMtrlEditor() : elm_id(UIDZero), elm(null), changed(false), sim_type(SIM_NONE), prop_max_x(0), sim_time(0), sim_length(3), game(null), fric_stat(null), fric_dyn(null), fric_mode(null), boun(null), boun_mode(null), damp(null), adamp(null), df(null), dfs(null), dfd(null), dfb(null), undos(true) {}
  215. /******************************************************************************/