ODEVehicleSettings.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Reflection;
  30. using System.Runtime.InteropServices;
  31. using log4net;
  32. using OpenMetaverse;
  33. using Ode.NET;
  34. using OpenSim.Framework;
  35. using OpenSim.Region.Physics.Manager;
  36. namespace OpenSim.Region.Physics.OdePlugin
  37. {
  38. public class ODEVehicleSettings
  39. {
  40. public Vehicle Type
  41. {
  42. get { return m_type; }
  43. }
  44. public IntPtr Body
  45. {
  46. get { return m_body; }
  47. }
  48. private int frcount = 0;
  49. // private float frmod = 3.0f;
  50. private Vehicle m_type = Vehicle.TYPE_NONE;
  51. // private OdeScene m_parentScene = null;
  52. private IntPtr m_body = IntPtr.Zero;
  53. private IntPtr m_jointGroup = IntPtr.Zero;
  54. private IntPtr m_aMotor = IntPtr.Zero;
  55. private IntPtr m_lMotor1 = IntPtr.Zero;
  56. // private IntPtr m_lMotor2 = IntPtr.Zero;
  57. // private IntPtr m_lMotor3 = IntPtr.Zero;
  58. // Vehicle properties
  59. // private Quaternion m_referenceFrame = Quaternion.Identity;
  60. private Vector3 m_angularFrictionTimescale = Vector3.Zero;
  61. private Vector3 m_angularMotorDirection = Vector3.Zero;
  62. private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero;
  63. private Vector3 m_linearFrictionTimescale = Vector3.Zero;
  64. private Vector3 m_linearMotorDirection = Vector3.Zero;
  65. private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero;
  66. // private Vector3 m_linearMotorOffset = Vector3.Zero;
  67. // private float m_angularDeflectionEfficiency = 0;
  68. // private float m_angularDeflectionTimescale = 0;
  69. private float m_angularMotorDecayTimescale = 0;
  70. private float m_angularMotorTimescale = 0;
  71. // private float m_bankingEfficiency = 0;
  72. // private float m_bankingMix = 0;
  73. // private float m_bankingTimescale = 0;
  74. // private float m_buoyancy = 0;
  75. // private float m_hoverHeight = 0;
  76. // private float m_hoverEfficiency = 0;
  77. // private float m_hoverTimescale = 0;
  78. // private float m_linearDeflectionEfficiency = 0;
  79. // private float m_linearDeflectionTimescale = 0;
  80. private float m_linearMotorDecayTimescale = 0;
  81. private float m_linearMotorTimescale = 0;
  82. private float m_verticalAttractionEfficiency = 0;
  83. private float m_verticalAttractionTimescale = 0;
  84. private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
  85. private Vector3 m_lastAngularVelocityVector = Vector3.Zero;
  86. private VehicleFlag m_flags = (VehicleFlag) 0;
  87. // private bool m_LinearMotorSetLastFrame = false;
  88. internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
  89. {
  90. switch (pParam)
  91. {
  92. case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
  93. if (pValue < 0.01f) pValue = 0.01f;
  94. // m_angularDeflectionEfficiency = pValue;
  95. break;
  96. case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
  97. if (pValue < 0.01f) pValue = 0.01f;
  98. // m_angularDeflectionTimescale = pValue;
  99. break;
  100. case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
  101. if (pValue < 0.01f) pValue = 0.01f;
  102. m_angularMotorDecayTimescale = pValue;
  103. break;
  104. case Vehicle.ANGULAR_MOTOR_TIMESCALE:
  105. if (pValue < 0.01f) pValue = 0.01f;
  106. m_angularMotorTimescale = pValue;
  107. break;
  108. case Vehicle.BANKING_EFFICIENCY:
  109. if (pValue < 0.01f) pValue = 0.01f;
  110. // m_bankingEfficiency = pValue;
  111. break;
  112. case Vehicle.BANKING_MIX:
  113. if (pValue < 0.01f) pValue = 0.01f;
  114. // m_bankingMix = pValue;
  115. break;
  116. case Vehicle.BANKING_TIMESCALE:
  117. if (pValue < 0.01f) pValue = 0.01f;
  118. // m_bankingTimescale = pValue;
  119. break;
  120. case Vehicle.BUOYANCY:
  121. // m_buoyancy = pValue;
  122. break;
  123. case Vehicle.HOVER_EFFICIENCY:
  124. // m_hoverEfficiency = pValue;
  125. break;
  126. case Vehicle.HOVER_HEIGHT:
  127. // m_hoverHeight = pValue;
  128. break;
  129. case Vehicle.HOVER_TIMESCALE:
  130. if (pValue < 0.01f) pValue = 0.01f;
  131. // m_hoverTimescale = pValue;
  132. break;
  133. case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
  134. if (pValue < 0.01f) pValue = 0.01f;
  135. // m_linearDeflectionEfficiency = pValue;
  136. break;
  137. case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
  138. if (pValue < 0.01f) pValue = 0.01f;
  139. // m_linearDeflectionTimescale = pValue;
  140. break;
  141. case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
  142. if (pValue < 0.01f) pValue = 0.01f;
  143. m_linearMotorDecayTimescale = pValue;
  144. break;
  145. case Vehicle.LINEAR_MOTOR_TIMESCALE:
  146. if (pValue < 0.01f) pValue = 0.01f;
  147. m_linearMotorTimescale = pValue;
  148. break;
  149. case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
  150. if (pValue < 0.01f) pValue = 0.01f;
  151. m_verticalAttractionEfficiency = pValue;
  152. break;
  153. case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
  154. if (pValue < 0.01f) pValue = 0.01f;
  155. m_verticalAttractionTimescale = pValue;
  156. break;
  157. // These are vector properties but the engine lets you use a single float value to
  158. // set all of the components to the same value
  159. case Vehicle.ANGULAR_FRICTION_TIMESCALE:
  160. m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
  161. break;
  162. case Vehicle.ANGULAR_MOTOR_DIRECTION:
  163. m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
  164. m_angularMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
  165. break;
  166. case Vehicle.LINEAR_FRICTION_TIMESCALE:
  167. m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
  168. break;
  169. case Vehicle.LINEAR_MOTOR_DIRECTION:
  170. m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
  171. m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
  172. break;
  173. case Vehicle.LINEAR_MOTOR_OFFSET:
  174. // m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
  175. break;
  176. }
  177. Reset();
  178. }
  179. internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue)
  180. {
  181. switch (pParam)
  182. {
  183. case Vehicle.ANGULAR_FRICTION_TIMESCALE:
  184. m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
  185. break;
  186. case Vehicle.ANGULAR_MOTOR_DIRECTION:
  187. m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
  188. m_angularMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
  189. break;
  190. case Vehicle.LINEAR_FRICTION_TIMESCALE:
  191. m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
  192. break;
  193. case Vehicle.LINEAR_MOTOR_DIRECTION:
  194. m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
  195. m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
  196. break;
  197. case Vehicle.LINEAR_MOTOR_OFFSET:
  198. // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
  199. break;
  200. }
  201. Reset();
  202. }
  203. internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
  204. {
  205. switch (pParam)
  206. {
  207. case Vehicle.REFERENCE_FRAME:
  208. // m_referenceFrame = pValue;
  209. break;
  210. }
  211. Reset();
  212. }
  213. internal void ProcessTypeChange(Vehicle pType)
  214. {
  215. if (m_type == Vehicle.TYPE_NONE && pType != Vehicle.TYPE_NONE)
  216. {
  217. // Activate whatever it is
  218. SetDefaultsForType(pType);
  219. Reset();
  220. }
  221. else if (m_type != Vehicle.TYPE_NONE && pType != Vehicle.TYPE_NONE)
  222. {
  223. // Set properties
  224. SetDefaultsForType(pType);
  225. // then reset
  226. Reset();
  227. }
  228. else if (m_type != Vehicle.TYPE_NONE && pType == Vehicle.TYPE_NONE)
  229. {
  230. m_type = pType;
  231. Destroy();
  232. }
  233. }
  234. internal void Disable()
  235. {
  236. if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
  237. return;
  238. if (m_aMotor != IntPtr.Zero)
  239. {
  240. }
  241. }
  242. internal void Enable(IntPtr pBody, OdeScene pParentScene)
  243. {
  244. if (m_type == Vehicle.TYPE_NONE)
  245. return;
  246. m_body = pBody;
  247. // m_parentScene = pParentScene;
  248. if (m_jointGroup == IntPtr.Zero)
  249. m_jointGroup = d.JointGroupCreate(3);
  250. if (pBody != IntPtr.Zero)
  251. {
  252. if (m_lMotor1 == IntPtr.Zero)
  253. {
  254. d.BodySetAutoDisableFlag(Body, false);
  255. m_lMotor1 = d.JointCreateLMotor(pParentScene.world, m_jointGroup);
  256. d.JointSetLMotorNumAxes(m_lMotor1, 1);
  257. d.JointAttach(m_lMotor1, Body, IntPtr.Zero);
  258. }
  259. if (m_aMotor == IntPtr.Zero)
  260. {
  261. m_aMotor = d.JointCreateAMotor(pParentScene.world, m_jointGroup);
  262. d.JointSetAMotorNumAxes(m_aMotor, 3);
  263. d.JointAttach(m_aMotor, Body, IntPtr.Zero);
  264. }
  265. }
  266. }
  267. internal void Reset()
  268. {
  269. if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
  270. return;
  271. }
  272. internal void Destroy()
  273. {
  274. if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
  275. return;
  276. if (m_aMotor != IntPtr.Zero)
  277. {
  278. d.JointDestroy(m_aMotor);
  279. }
  280. if (m_lMotor1 != IntPtr.Zero)
  281. {
  282. d.JointDestroy(m_lMotor1);
  283. }
  284. }
  285. internal void Step(float pTimestep)
  286. {
  287. if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
  288. return;
  289. frcount++;
  290. if (frcount > 100)
  291. frcount = 0;
  292. VerticalAttractor(pTimestep);
  293. LinearMotor(pTimestep);
  294. AngularMotor(pTimestep);
  295. }
  296. private void SetDefaultsForType(Vehicle pType)
  297. {
  298. m_type = pType;
  299. switch (pType)
  300. {
  301. case Vehicle.TYPE_SLED:
  302. m_linearFrictionTimescale = new Vector3(30, 1, 1000);
  303. m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
  304. m_linearMotorDirection = Vector3.Zero;
  305. m_linearMotorTimescale = 1000;
  306. m_linearMotorDecayTimescale = 120;
  307. m_angularMotorDirection = Vector3.Zero;
  308. m_angularMotorTimescale = 1000;
  309. m_angularMotorDecayTimescale = 120;
  310. // m_hoverHeight = 0;
  311. // m_hoverEfficiency = 10;
  312. // m_hoverTimescale = 10;
  313. // m_buoyancy = 0;
  314. // m_linearDeflectionEfficiency = 1;
  315. // m_linearDeflectionTimescale = 1;
  316. // m_angularDeflectionEfficiency = 1;
  317. // m_angularDeflectionTimescale = 1000;
  318. // m_bankingEfficiency = 0;
  319. // m_bankingMix = 1;
  320. // m_bankingTimescale = 10;
  321. // m_referenceFrame = Quaternion.Identity;
  322. m_flags &=
  323. ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
  324. VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
  325. m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
  326. break;
  327. case Vehicle.TYPE_CAR:
  328. m_linearFrictionTimescale = new Vector3(100, 2, 1000);
  329. m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
  330. m_linearMotorDirection = Vector3.Zero;
  331. m_linearMotorTimescale = 1;
  332. m_linearMotorDecayTimescale = 60;
  333. m_angularMotorDirection = Vector3.Zero;
  334. m_angularMotorTimescale = 1;
  335. m_angularMotorDecayTimescale = 0.8f;
  336. // m_hoverHeight = 0;
  337. // // m_hoverEfficiency = 0;
  338. // // m_hoverTimescale = 1000;
  339. // // m_buoyancy = 0;
  340. // // m_linearDeflectionEfficiency = 1;
  341. // // m_linearDeflectionTimescale = 2;
  342. // // m_angularDeflectionEfficiency = 0;
  343. // m_angularDeflectionTimescale = 10;
  344. m_verticalAttractionEfficiency = 1;
  345. m_verticalAttractionTimescale = 10;
  346. // m_bankingEfficiency = -0.2f;
  347. // m_bankingMix = 1;
  348. // m_bankingTimescale = 1;
  349. // m_referenceFrame = Quaternion.Identity;
  350. m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
  351. m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY |
  352. VehicleFlag.LIMIT_MOTOR_UP);
  353. break;
  354. case Vehicle.TYPE_BOAT:
  355. m_linearFrictionTimescale = new Vector3(10, 3, 2);
  356. m_angularFrictionTimescale = new Vector3(10,10,10);
  357. m_linearMotorDirection = Vector3.Zero;
  358. m_linearMotorTimescale = 5;
  359. m_linearMotorDecayTimescale = 60;
  360. m_angularMotorDirection = Vector3.Zero;
  361. m_angularMotorTimescale = 4;
  362. m_angularMotorDecayTimescale = 4;
  363. // m_hoverHeight = 0;
  364. // m_hoverEfficiency = 0.5f;
  365. // m_hoverTimescale = 2;
  366. // m_buoyancy = 1;
  367. // m_linearDeflectionEfficiency = 0.5f;
  368. // m_linearDeflectionTimescale = 3;
  369. // m_angularDeflectionEfficiency = 0.5f;
  370. // m_angularDeflectionTimescale = 5;
  371. m_verticalAttractionEfficiency = 0.5f;
  372. m_verticalAttractionTimescale = 5;
  373. // m_bankingEfficiency = -0.3f;
  374. // m_bankingMix = 0.8f;
  375. // m_bankingTimescale = 1;
  376. // m_referenceFrame = Quaternion.Identity;
  377. m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
  378. m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_UP_ONLY |
  379. VehicleFlag.LIMIT_MOTOR_UP);
  380. break;
  381. case Vehicle.TYPE_AIRPLANE:
  382. m_linearFrictionTimescale = new Vector3(200, 10, 5);
  383. m_angularFrictionTimescale = new Vector3(20, 20, 20);
  384. m_linearMotorDirection = Vector3.Zero;
  385. m_linearMotorTimescale = 2;
  386. m_linearMotorDecayTimescale = 60;
  387. m_angularMotorDirection = Vector3.Zero;
  388. m_angularMotorTimescale = 4;
  389. m_angularMotorDecayTimescale = 4;
  390. // m_hoverHeight = 0;
  391. // m_hoverEfficiency = 0.5f;
  392. // m_hoverTimescale = 1000;
  393. // m_buoyancy = 0;
  394. // m_linearDeflectionEfficiency = 0.5f;
  395. // m_linearDeflectionTimescale = 3;
  396. // m_angularDeflectionEfficiency = 1;
  397. // m_angularDeflectionTimescale = 2;
  398. m_verticalAttractionEfficiency = 0.9f;
  399. m_verticalAttractionTimescale = 2;
  400. // m_bankingEfficiency = 1;
  401. // m_bankingMix = 0.7f;
  402. // m_bankingTimescale = 2;
  403. // m_referenceFrame = Quaternion.Identity;
  404. m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
  405. VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
  406. m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
  407. break;
  408. case Vehicle.TYPE_BALLOON:
  409. m_linearFrictionTimescale = new Vector3(5, 5, 5);
  410. m_angularFrictionTimescale = new Vector3(10, 10, 10);
  411. m_linearMotorDirection = Vector3.Zero;
  412. m_linearMotorTimescale = 5;
  413. m_linearMotorDecayTimescale = 60;
  414. m_angularMotorDirection = Vector3.Zero;
  415. m_angularMotorTimescale = 6;
  416. m_angularMotorDecayTimescale = 10;
  417. // m_hoverHeight = 5;
  418. // m_hoverEfficiency = 0.8f;
  419. // m_hoverTimescale = 10;
  420. // m_buoyancy = 1;
  421. // m_linearDeflectionEfficiency = 0;
  422. // m_linearDeflectionTimescale = 5;
  423. // m_angularDeflectionEfficiency = 0;
  424. // m_angularDeflectionTimescale = 5;
  425. m_verticalAttractionEfficiency = 1;
  426. m_verticalAttractionTimescale = 1000;
  427. // m_bankingEfficiency = 0;
  428. // m_bankingMix = 0.7f;
  429. // m_bankingTimescale = 5;
  430. // m_referenceFrame = Quaternion.Identity;
  431. m_flags = (VehicleFlag)0;
  432. break;
  433. }
  434. }
  435. private void VerticalAttractor(float pTimestep)
  436. {
  437. // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air.
  438. // The amotor needs a few seconds to stabilize so without it, the avatar shoots up sky high when you
  439. // change appearance and when you enter the simulator
  440. // After this routine is done, the amotor stabilizes much quicker
  441. d.Mass objMass;
  442. d.BodyGetMass(Body, out objMass);
  443. //d.BodyGetS
  444. d.Vector3 feet;
  445. d.Vector3 head;
  446. d.BodyGetRelPointPos(m_body, 0.0f, 0.0f, -1.0f, out feet);
  447. d.BodyGetRelPointPos(m_body, 0.0f, 0.0f, 1.0f, out head);
  448. float posture = head.Z - feet.Z;
  449. //Console.WriteLine(String.Format("head: <{0},{1},{2}>, feet:<{3},{4},{5}> diff:<{6},{7},{8}>", head.X, head.Y, head.Z, feet.X,
  450. // feet.Y, feet.Z, head.X - feet.X, head.Y - feet.Y, head.Z - feet.Z));
  451. //Console.WriteLine(String.Format("diff:<{0},{1},{2}>",head.X - feet.X, head.Y - feet.Y, head.Z - feet.Z));
  452. // restoring force proportional to lack of posture:
  453. float servo = (2.5f - posture) * (objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep)) * objMass.mass;
  454. d.BodyAddForceAtRelPos(m_body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f);
  455. d.BodyAddForceAtRelPos(m_body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f);
  456. //d.BodyAddTorque(m_body, (head.X - feet.X) * servo, (head.Y - feet.Y) * servo, (head.Z - feet.Z) * servo);
  457. //d.Matrix3 bodyrotation = d.BodyGetRotation(Body);
  458. //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22);
  459. }
  460. private void LinearMotor(float pTimestep)
  461. {
  462. if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
  463. {
  464. Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
  465. m_lastLinearVelocityVector += (addAmount*10);
  466. // This will work temporarily, but we really need to compare speed on an axis
  467. if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
  468. m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
  469. if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
  470. m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
  471. if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
  472. m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
  473. //Console.WriteLine("add: " + addAmount);
  474. Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
  475. //Console.WriteLine("decay: " + decayfraction);
  476. m_linearMotorDirection -= m_linearMotorDirection * decayfraction;
  477. //Console.WriteLine("actual: " + m_linearMotorDirection);
  478. }
  479. //System.Console.WriteLine(m_linearMotorDirection + " " + m_lastLinearVelocityVector);
  480. SetLinearMotorProperties();
  481. Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
  482. m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
  483. //m_linearMotorDirection *= decayamount;
  484. }
  485. private void SetLinearMotorProperties()
  486. {
  487. Vector3 dirNorm = m_lastLinearVelocityVector;
  488. dirNorm.Normalize();
  489. d.Mass objMass;
  490. d.BodyGetMass(Body, out objMass);
  491. d.Quaternion rot = d.BodyGetQuaternion(Body);
  492. Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
  493. dirNorm *= rotq;
  494. if (m_lMotor1 != IntPtr.Zero)
  495. {
  496. d.JointSetLMotorAxis(m_lMotor1, 0, 1, dirNorm.X, dirNorm.Y, dirNorm.Z);
  497. d.JointSetLMotorParam(m_lMotor1, (int)dParam.Vel, m_lastLinearVelocityVector.Length());
  498. d.JointSetLMotorParam(m_lMotor1, (int)dParam.FMax, 35f * objMass.mass);
  499. }
  500. }
  501. private void AngularMotor(float pTimestep)
  502. {
  503. if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
  504. {
  505. Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep);
  506. m_lastAngularVelocityVector += (addAmount * 10);
  507. // This will work temporarily, but we really need to compare speed on an axis
  508. if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X))
  509. m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X;
  510. if (Math.Abs(m_lastAngularVelocityVector.Y) > Math.Abs(m_angularMotorDirectionLASTSET.Y))
  511. m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y;
  512. if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z))
  513. m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z;
  514. //Console.WriteLine("add: " + addAmount);
  515. Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep)));
  516. //Console.WriteLine("decay: " + decayfraction);
  517. m_angularMotorDirection -= m_angularMotorDirection * decayfraction;
  518. //Console.WriteLine("actual: " + m_linearMotorDirection);
  519. }
  520. //System.Console.WriteLine(m_linearMotorDirection + " " + m_lastLinearVelocityVector);
  521. SetAngularMotorProperties();
  522. Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
  523. m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount;
  524. //m_linearMotorDirection *= decayamount;
  525. }
  526. private void SetAngularMotorProperties()
  527. {
  528. d.Mass objMass;
  529. d.BodyGetMass(Body, out objMass);
  530. //d.Quaternion rot = d.BodyGetQuaternion(Body);
  531. //Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
  532. Vector3 axis0 = Vector3.UnitX;
  533. Vector3 axis1 = Vector3.UnitY;
  534. Vector3 axis2 = Vector3.UnitZ;
  535. //axis0 *= rotq;
  536. //axis1 *= rotq;
  537. //axis2 *= rotq;
  538. if (m_aMotor != IntPtr.Zero)
  539. {
  540. d.JointSetAMotorAxis(m_aMotor, 0, 1, axis0.X, axis0.Y, axis0.Z);
  541. d.JointSetAMotorAxis(m_aMotor, 1, 1, axis1.X, axis1.Y, axis1.Z);
  542. d.JointSetAMotorAxis(m_aMotor, 2, 1, axis2.X, axis2.Y, axis2.Z);
  543. d.JointSetAMotorParam(m_aMotor, (int)dParam.FMax, 30*objMass.mass);
  544. d.JointSetAMotorParam(m_aMotor, (int)dParam.FMax2, 30*objMass.mass);
  545. d.JointSetAMotorParam(m_aMotor, (int)dParam.FMax3, 30 * objMass.mass);
  546. d.JointSetAMotorParam(m_aMotor, (int)dParam.Vel, m_lastAngularVelocityVector.X);
  547. d.JointSetAMotorParam(m_aMotor, (int)dParam.Vel2, m_lastAngularVelocityVector.Y);
  548. d.JointSetAMotorParam(m_aMotor, (int)dParam.Vel3, m_lastAngularVelocityVector.Z);
  549. }
  550. }
  551. }
  552. }