00001 /* *********************************************************************************** 00002 Writer: Sebastien Bloc 00003 Copyright: 2003-2004 00004 eMail: sebastien.bloc@free.fr 00005 URL: http://mignonsoft.free.fr 00006 00007 This program is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU General Public License 00009 as published by the Free Software Foundation; either version 2 00010 of the License, or (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 http://www.gnu.org/copyleft/gpl.html 00017 *********************************************************************************** */ 00018 00019 #include "inertia.h" 00020 #include "control.h" 00021 #include "controlEngine.h" 00022 00023 extern ControlEngine ce; 00024 00025 Inertia::Inertia() 00026 { 00027 viewTime = 0; 00028 inertiaTime = 0; 00029 } 00030 00031 void Inertia::Start(double _viewTime,double _inertiaTime) 00032 { 00033 viewTime = _viewTime; 00034 inertiaTime = _inertiaTime; 00035 timer.GetDeltaTime(TRUE); 00036 } 00037 00038 void Inertia::Add(Point2D<int> element) 00039 { 00040 ElemStack elemStack; 00041 elemStack.elem=element; 00042 elemStack.timing = timer.GetDeltaTime(FALSE); 00043 stack.Push(elemStack); 00044 } 00045 00046 Point2D<double> Inertia::GetMoyValue() 00047 { 00048 double timing = timer.GetDeltaTime(FALSE); 00049 Point2D<double> power; 00050 ElemStack elemStack; 00051 double timeInside=-1; 00052 00053 // on elimine tout les elements dont le timing est depasée 00054 while (1) 00055 { 00056 if (!stack.GetNbElem()) return power; 00057 elemStack = stack.FrontPeek(); 00058 timeInside = elemStack.timing+inertiaTime-timing+viewTime; 00059 if (timeInside>0) break; 00060 stack.FrontPop(); 00061 }; 00062 00063 power.x = (double)elemStack.elem.x*timeInside; 00064 power.y = (double)elemStack.elem.y*timeInside; 00065 00066 // on ajout tout le rest 00067 double lastTime=0; // gestion des coupures entre elements 00068 double deltaTime; 00069 for (stack.i=0;stack.i.More();stack.i++) 00070 { 00071 elemStack = stack.i.GetElem(); 00072 timeInside = timing-elemStack.timing; 00073 deltaTime=timeInside-lastTime; 00074 lastTime=timeInside; 00075 if (timeInside>inertiaTime) timeInside = inertiaTime; 00076 power.x += (double)elemStack.elem.x*deltaTime; 00077 power.y += (double)elemStack.elem.y*deltaTime; 00078 } 00079 00080 // calcul de moyenne 00081 power/=viewTime; // T doit avoir "void operateur/=(double)" 00082 return power; 00083 } 00084 00085 EventInertia::EventInertia() 00086 { 00087 numButton= -1; 00088 face = -1; 00089 enable = FALSE; 00090 } 00091 00092 void EventInertia::Init(int _numButton) 00093 { 00094 numButton=_numButton; 00095 } 00096 00097 void EventInertia::operator=(EventInertia &src) 00098 { 00099 enable = src.enable; 00100 face = src.face; 00101 mousePos = src.mousePos; 00102 mouseState = src.mouseState; 00103 numButton = src.numButton; 00104 timer = src.timer; 00105 vectorInertia = src.vectorInertia; 00106 } 00107 00108 void EventInertia::Start(int _face,Point2D<double> _vectorInertia) 00109 { 00110 face = _face; 00111 vectorInertia = _vectorInertia; 00112 ce.pickingInertia=ce.pickingCursor; 00113 mouseState = &ce.pickingInertia.mouse; 00114 mousePos.x = mouseState->pos.x; 00115 mousePos.y = mouseState->pos.y; 00116 SwitchButton(); 00117 00118 BindTimer(timer,OnInertia,40); 00119 } 00120 00121 void EventInertia::SwitchButton() 00122 { 00123 switch (numButton) 00124 { 00125 case 0: mouseState->leftBtn=!mouseState->leftBtn; break; // left 00126 case 1: mouseState->midBtn=!mouseState->midBtn; break; // mid 00127 case 2: mouseState->rightBtn=!mouseState->rightBtn; break; // right 00128 } 00129 } 00130 00131 void EventInertia::Stop() 00132 { 00133 timer.Stop(); 00134 enable=FALSE; 00135 ce.usingInertia--; 00136 switch (numButton) 00137 { 00138 case 0: ce.pickingInertia.OnLButtonUp(); break; 00139 case 1: ce.pickingInertia.OnMButtonUp(); break; 00140 case 2: ce.pickingInertia.OnRButtonUp(); break; 00141 } 00142 } 00143 00144 #define TIME_MOVE_ON_INERTIA 2.0 // durée de l'inertie: 2 seconds 00145 int EventInertia::OnInertia(Timer *timerCur) 00146 { 00147 double delta = timer.GetDeltaTime(); 00148 double coef = (TIME_MOVE_ON_INERTIA-delta)/TIME_MOVE_ON_INERTIA; 00149 if (coef<=0) 00150 { 00151 Stop(); 00152 return 0; 00153 } 00154 00155 Point2D<double> vectorInertiaCur=vectorInertia*coef; 00156 00157 mousePos.x-=vectorInertiaCur.x; 00158 mousePos.y-=vectorInertiaCur.y; 00159 00160 ce.pickingInertia.OnMouseMove((int)mousePos.x,(int)mousePos.y); 00161 return 0; 00162 }