ODECharacter.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  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 OpenSim 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 Axiom.Math;
  29. using Ode.NET;
  30. using OpenSim.Framework;
  31. using OpenSim.Region.Physics.Manager;
  32. namespace OpenSim.Region.Physics.OdePlugin
  33. {
  34. /// <summary>
  35. /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves.
  36. /// </summary>
  37. public enum dParam : int
  38. {
  39. LowStop = 0,
  40. HiStop = 1,
  41. Vel = 2,
  42. FMax = 3,
  43. FudgeFactor = 4,
  44. Bounce = 5,
  45. CFM = 6,
  46. ERP = 7,
  47. StopCFM = 8,
  48. LoStop2 = 256,
  49. HiStop2 = 257,
  50. LoStop3 = 512,
  51. HiStop3 = 513
  52. }
  53. public class OdeCharacter : PhysicsActor
  54. {
  55. //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  56. private PhysicsVector _position;
  57. private d.Vector3 _zeroPosition;
  58. private d.Matrix3 m_StandUpRotation;
  59. private bool _zeroFlag = false;
  60. private bool m_lastUpdateSent = false;
  61. private PhysicsVector _velocity;
  62. private PhysicsVector _target_velocity;
  63. private PhysicsVector _acceleration;
  64. private PhysicsVector m_rotationalVelocity;
  65. private float m_mass = 80f;
  66. private float m_density = 60f;
  67. private bool m_pidControllerActive = true;
  68. private float PID_D = 800.0f;
  69. private float PID_P = 900.0f;
  70. //private static float POSTURE_SERVO = 10000.0f;
  71. public static float CAPSULE_RADIUS = 0.37f;
  72. public float CAPSULE_LENGTH = 2.140599f;
  73. private float m_tensor = 3800000f;
  74. private bool flying = false;
  75. private bool m_iscolliding = false;
  76. private bool m_iscollidingGround = false;
  77. private bool m_wascolliding = false;
  78. private bool m_wascollidingGround = false;
  79. private bool m_iscollidingObj = false;
  80. private bool m_alwaysRun = false;
  81. private bool m_hackSentFall = false;
  82. private bool m_hackSentFly = false;
  83. public uint m_localID = 0;
  84. public bool m_returnCollisions = false;
  85. private float m_buoyancy = 0f;
  86. private CollisionLocker ode;
  87. private string m_name = String.Empty;
  88. private bool[] m_colliderarr = new bool[11];
  89. private bool[] m_colliderGroundarr = new bool[11];
  90. // Default we're a Character
  91. private CollisionCategories m_collisionCategories = (CollisionCategories.Character);
  92. // Default, Collide with Other Geometries, spaces, bodies and characters.
  93. private CollisionCategories m_collisionFlags = (CollisionCategories.Geom
  94. | CollisionCategories.Space
  95. | CollisionCategories.Body
  96. | CollisionCategories.Character
  97. | CollisionCategories.Land);
  98. public IntPtr Body;
  99. private OdeScene _parent_scene;
  100. public IntPtr Shell;
  101. public IntPtr Amotor;
  102. public d.Mass ShellMass;
  103. public bool collidelock = false;
  104. public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos, CollisionLocker dode, PhysicsVector size)
  105. {
  106. ode = dode;
  107. _velocity = new PhysicsVector();
  108. _target_velocity = new PhysicsVector();
  109. _position = pos;
  110. _acceleration = new PhysicsVector();
  111. _parent_scene = parent_scene;
  112. if (System.Environment.OSVersion.Platform == PlatformID.Unix)
  113. {
  114. m_tensor = 2000000f;
  115. }
  116. else
  117. {
  118. m_tensor = 1300000f;
  119. }
  120. m_StandUpRotation =
  121. new d.Matrix3(0.5f, 0.7071068f, 0.5f, -0.7071068f, 0f, 0.7071068f, 0.5f, -0.7071068f,
  122. 0.5f);
  123. for (int i = 0; i < 11; i++)
  124. {
  125. m_colliderarr[i] = false;
  126. }
  127. CAPSULE_LENGTH = (size.Z - ((size.Z * 0.52f)));
  128. lock (OdeScene.OdeLock)
  129. {
  130. AvatarGeomAndBodyCreation(pos.X, pos.Y, pos.Z, m_tensor);
  131. }
  132. m_name = avName;
  133. parent_scene.geom_name_map[Shell] = avName;
  134. parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
  135. }
  136. public override int PhysicsActorType
  137. {
  138. get { return (int) ActorTypes.Agent; }
  139. set { return; }
  140. }
  141. /// <summary>
  142. /// If this is set, the avatar will move faster
  143. /// </summary>
  144. public override bool SetAlwaysRun
  145. {
  146. get { return m_alwaysRun; }
  147. set { m_alwaysRun = value; }
  148. }
  149. public override uint LocalID
  150. {
  151. set { m_localID = value; }
  152. }
  153. public override bool Grabbed
  154. {
  155. set { return; }
  156. }
  157. public override bool Selected
  158. {
  159. set { return; }
  160. }
  161. public override float Buoyancy
  162. {
  163. get { return m_buoyancy; }
  164. set { m_buoyancy = value; }
  165. }
  166. public override bool FloatOnWater
  167. {
  168. set { return; }
  169. }
  170. public override bool IsPhysical
  171. {
  172. get { return false; }
  173. set { return; }
  174. }
  175. public override bool ThrottleUpdates
  176. {
  177. get { return false; }
  178. set { return; }
  179. }
  180. public override bool Flying
  181. {
  182. get { return flying; }
  183. set { flying = value; }
  184. }
  185. /// <summary>
  186. /// Returns if the avatar is colliding in general.
  187. /// This includes the ground and objects and avatar.
  188. /// </summary>
  189. public override bool IsColliding
  190. {
  191. get { return m_iscolliding; }
  192. set
  193. {
  194. int i;
  195. int truecount = 0;
  196. int falsecount = 0;
  197. if (m_colliderarr.Length >= 10)
  198. {
  199. for (i = 0; i < 10; i++)
  200. {
  201. m_colliderarr[i] = m_colliderarr[i + 1];
  202. }
  203. }
  204. m_colliderarr[10] = value;
  205. for (i = 0; i < 11; i++)
  206. {
  207. if (m_colliderarr[i])
  208. {
  209. truecount++;
  210. }
  211. else
  212. {
  213. falsecount++;
  214. }
  215. }
  216. // Equal truecounts and false counts means we're colliding with something.
  217. if (falsecount > 1.2*truecount)
  218. {
  219. m_iscolliding = false;
  220. }
  221. else
  222. {
  223. m_iscolliding = true;
  224. }
  225. if (m_wascolliding != m_iscolliding)
  226. {
  227. //base.SendCollisionUpdate(new CollisionEventUpdate());
  228. }
  229. m_wascolliding = m_iscolliding;
  230. }
  231. }
  232. /// <summary>
  233. /// Returns if an avatar is colliding with the ground
  234. /// </summary>
  235. public override bool CollidingGround
  236. {
  237. get { return m_iscollidingGround; }
  238. set
  239. {
  240. // Collisions against the ground are not really reliable
  241. // So, to get a consistant value we have to average the current result over time
  242. // Currently we use 1 second = 10 calls to this.
  243. int i;
  244. int truecount = 0;
  245. int falsecount = 0;
  246. if (m_colliderGroundarr.Length >= 10)
  247. {
  248. for (i = 0; i < 10; i++)
  249. {
  250. m_colliderGroundarr[i] = m_colliderGroundarr[i + 1];
  251. }
  252. }
  253. m_colliderGroundarr[10] = value;
  254. for (i = 0; i < 11; i++)
  255. {
  256. if (m_colliderGroundarr[i])
  257. {
  258. truecount++;
  259. }
  260. else
  261. {
  262. falsecount++;
  263. }
  264. }
  265. // Equal truecounts and false counts means we're colliding with something.
  266. if (falsecount > 1.2*truecount)
  267. {
  268. m_iscollidingGround = false;
  269. }
  270. else
  271. {
  272. m_iscollidingGround = true;
  273. }
  274. if (m_wascollidingGround != m_iscollidingGround)
  275. {
  276. //base.SendCollisionUpdate(new CollisionEventUpdate());
  277. }
  278. m_wascollidingGround = m_iscollidingGround;
  279. }
  280. }
  281. /// <summary>
  282. /// Returns if the avatar is colliding with an object
  283. /// </summary>
  284. public override bool CollidingObj
  285. {
  286. get { return m_iscollidingObj; }
  287. set
  288. {
  289. m_iscollidingObj = value;
  290. if (value)
  291. m_pidControllerActive = false;
  292. else
  293. m_pidControllerActive = true;
  294. }
  295. }
  296. /// <summary>
  297. /// turn the PID controller on or off.
  298. /// The PID Controller will turn on all by itself in many situations
  299. /// </summary>
  300. /// <param name="status"></param>
  301. public void SetPidStatus(bool status)
  302. {
  303. m_pidControllerActive = status;
  304. }
  305. public override bool Stopped
  306. {
  307. get { return _zeroFlag; }
  308. }
  309. /// <summary>
  310. /// This 'puts' an avatar somewhere in the physics space.
  311. /// Not really a good choice unless you 'know' it's a good
  312. /// spot otherwise you're likely to orbit the avatar.
  313. /// </summary>
  314. public override PhysicsVector Position
  315. {
  316. get { return _position; }
  317. set
  318. {
  319. lock (OdeScene.OdeLock)
  320. {
  321. d.BodySetPosition(Body, value.X, value.Y, value.Z);
  322. _position = value;
  323. }
  324. }
  325. }
  326. public override PhysicsVector RotationalVelocity
  327. {
  328. get { return m_rotationalVelocity; }
  329. set { m_rotationalVelocity = value; }
  330. }
  331. /// <summary>
  332. /// This property sets the height of the avatar only. We use the height to make sure the avatar stands up straight
  333. /// and use it to offset landings properly
  334. /// </summary>
  335. public override PhysicsVector Size
  336. {
  337. get { return new PhysicsVector(CAPSULE_RADIUS*2, CAPSULE_RADIUS*2, CAPSULE_LENGTH); }
  338. set
  339. {
  340. m_pidControllerActive = true;
  341. lock (OdeScene.OdeLock)
  342. {
  343. d.JointDestroy(Amotor);
  344. PhysicsVector SetSize = value;
  345. float prevCapsule = CAPSULE_LENGTH;
  346. float capsuleradius = CAPSULE_RADIUS;
  347. //capsuleradius = 0.2f;
  348. CAPSULE_LENGTH = (SetSize.Z - ((SetSize.Z*0.52f))); // subtract 43% of the size
  349. //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
  350. d.BodyDestroy(Body);
  351. _parent_scene.waitForSpaceUnlock(_parent_scene.space);
  352. d.GeomDestroy(Shell);
  353. AvatarGeomAndBodyCreation(_position.X, _position.Y,
  354. _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
  355. Velocity = new PhysicsVector(0f, 0f, 0f);
  356. }
  357. _parent_scene.geom_name_map[Shell] = m_name;
  358. _parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
  359. }
  360. }
  361. /// <summary>
  362. /// This creates the Avatar's physical Surrogate at the position supplied
  363. /// </summary>
  364. /// <param name="npositionX"></param>
  365. /// <param name="npositionY"></param>
  366. /// <param name="npositionZ"></param>
  367. private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor)
  368. {
  369. if (System.Environment.OSVersion.Platform == PlatformID.Unix)
  370. {
  371. m_tensor = 2000000f;
  372. }
  373. else
  374. {
  375. m_tensor = 550000f;
  376. }
  377. int dAMotorEuler = 1;
  378. _parent_scene.waitForSpaceUnlock(_parent_scene.space);
  379. Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
  380. d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
  381. d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
  382. d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH);
  383. Body = d.BodyCreate(_parent_scene.world);
  384. d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
  385. d.BodySetMass(Body, ref ShellMass);
  386. d.Matrix3 m_caprot;
  387. // 90 Stand up on the cap of the capped cyllinder
  388. d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2));
  389. d.GeomSetRotation(Shell, ref m_caprot);
  390. d.BodySetRotation(Body, ref m_caprot);
  391. d.GeomSetBody(Shell, Body);
  392. // The purpose of the AMotor here is to keep the avatar's physical
  393. // surrogate from rotating while moving
  394. Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
  395. d.JointAttach(Amotor, Body, IntPtr.Zero);
  396. d.JointSetAMotorMode(Amotor, dAMotorEuler);
  397. d.JointSetAMotorNumAxes(Amotor, 3);
  398. d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
  399. d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
  400. d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
  401. d.JointSetAMotorAngle(Amotor, 0, 0);
  402. d.JointSetAMotorAngle(Amotor, 1, 0);
  403. d.JointSetAMotorAngle(Amotor, 2, 0);
  404. // These lowstops and high stops are effectively (no wiggle room)
  405. d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f);
  406. d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f);
  407. d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f);
  408. d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f);
  409. d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f);
  410. d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f);
  411. // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the
  412. // capped cyllinder will fall over
  413. d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f);
  414. d.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor);
  415. //d.Matrix3 bodyrotation = d.BodyGetRotation(Body);
  416. //d.QfromR(
  417. //d.Matrix3 checkrotation = new d.Matrix3(0.7071068,0.5, -0.7071068,
  418. //
  419. //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22);
  420. //standupStraight();
  421. }
  422. //
  423. /// <summary>
  424. /// Uses the capped cyllinder volume formula to calculate the avatar's mass.
  425. /// This may be used in calculations in the scene/scenepresence
  426. /// </summary>
  427. public override float Mass
  428. {
  429. get
  430. {
  431. float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH);
  432. return m_density*AVvolume;
  433. }
  434. }
  435. public override void link(PhysicsActor obj)
  436. {
  437. }
  438. public override void delink()
  439. {
  440. }
  441. // TODO: unused:
  442. // private void standupStraight()
  443. // {
  444. // // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air.
  445. // // The amotor needs a few seconds to stabilize so without it, the avatar shoots up sky high when you
  446. // // change appearance and when you enter the simulator
  447. // // After this routine is done, the amotor stabilizes much quicker
  448. // d.Vector3 feet;
  449. // d.Vector3 head;
  450. // d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet);
  451. // d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head);
  452. // float posture = head.Z - feet.Z;
  453. // // restoring force proportional to lack of posture:
  454. // float servo = (2.5f - posture) * POSTURE_SERVO;
  455. // d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f);
  456. // d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f);
  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. public override PhysicsVector Force
  461. {
  462. get { return new PhysicsVector(_target_velocity.X, _target_velocity.Y, _target_velocity.Z); }
  463. }
  464. public override PhysicsVector CenterOfMass
  465. {
  466. get { return PhysicsVector.Zero; }
  467. }
  468. public override PhysicsVector GeometricCenter
  469. {
  470. get { return PhysicsVector.Zero; }
  471. }
  472. public override PrimitiveBaseShape Shape
  473. {
  474. set { return; }
  475. }
  476. public override PhysicsVector Velocity
  477. {
  478. get {
  479. // There's a problem with PhysicsVector.Zero! Don't Use it Here!
  480. if (_zeroFlag)
  481. return new PhysicsVector(0f, 0f, 0f);
  482. m_lastUpdateSent = false;
  483. return _velocity;
  484. }
  485. set
  486. {
  487. m_pidControllerActive = true;
  488. _target_velocity = value;
  489. }
  490. }
  491. public override float CollisionScore
  492. {
  493. get { return 0f; }
  494. }
  495. public override bool Kinematic
  496. {
  497. get { return false; }
  498. set { }
  499. }
  500. public override Quaternion Orientation
  501. {
  502. get { return Quaternion.Identity; }
  503. set {
  504. //Matrix3 or = Orientation.ToRotationMatrix();
  505. //d.Matrix3 ord = new d.Matrix3(or.m00, or.m10, or.m20, or.m01, or.m11, or.m21, or.m02, or.m12, or.m22);
  506. //d.BodySetRotation(Body, ref ord);
  507. }
  508. }
  509. public override PhysicsVector Acceleration
  510. {
  511. get { return _acceleration; }
  512. }
  513. public void SetAcceleration(PhysicsVector accel)
  514. {
  515. m_pidControllerActive = true;
  516. _acceleration = accel;
  517. }
  518. /// <summary>
  519. /// Adds the force supplied to the Target Velocity
  520. /// The PID controller takes this target velocity and tries to make it a reality
  521. /// </summary>
  522. /// <param name="force"></param>
  523. public override void AddForce(PhysicsVector force)
  524. {
  525. m_pidControllerActive = true;
  526. _target_velocity.X += force.X;
  527. _target_velocity.Y += force.Y;
  528. _target_velocity.Z += force.Z;
  529. //m_lastUpdateSent = false;
  530. }
  531. /// <summary>
  532. /// After all of the forces add up with 'add force' we apply them with doForce
  533. /// </summary>
  534. /// <param name="force"></param>
  535. public void doForce(PhysicsVector force)
  536. {
  537. if (!collidelock)
  538. {
  539. d.BodyAddForce(Body, force.X, force.Y, force.Z);
  540. //d.BodySetRotation(Body, ref m_StandUpRotation);
  541. //standupStraight();
  542. }
  543. }
  544. public override void SetMomentum(PhysicsVector momentum)
  545. {
  546. }
  547. /// <summary>
  548. /// Called from Simulate
  549. /// This is the avatar's movement control + PID Controller
  550. /// </summary>
  551. /// <param name="timeStep"></param>
  552. public void Move(float timeStep)
  553. {
  554. // no lock; for now it's only called from within Simulate()
  555. // If the PID Controller isn't active then we set our force
  556. // calculating base velocity to the current position
  557. if (System.Environment.OSVersion.Platform == PlatformID.Unix)
  558. {
  559. PID_D = 3200.0f;
  560. PID_P = 1400.0f;
  561. }
  562. else
  563. {
  564. PID_D = 2200.0f;
  565. PID_P = 900.0f;
  566. }
  567. if (m_pidControllerActive == false)
  568. {
  569. _zeroPosition = d.BodyGetPosition(Body);
  570. }
  571. //PidStatus = true;
  572. PhysicsVector vec = new PhysicsVector();
  573. d.Vector3 vel = d.BodyGetLinearVel(Body);
  574. float movementdivisor = 1f;
  575. if (!m_alwaysRun)
  576. {
  577. movementdivisor = 1.3f;
  578. }
  579. else
  580. {
  581. movementdivisor = 0.8f;
  582. }
  583. // if velocity is zero, use position control; otherwise, velocity control
  584. if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding)
  585. {
  586. // keep track of where we stopped. No more slippin' & slidin'
  587. if (!_zeroFlag)
  588. {
  589. _zeroFlag = true;
  590. _zeroPosition = d.BodyGetPosition(Body);
  591. }
  592. if (m_pidControllerActive)
  593. {
  594. // We only want to deactivate the PID Controller if we think we want to have our surrogate
  595. // react to the physics scene by moving it's position.
  596. // Avatar to Avatar collisions
  597. // Prim to avatar collisions
  598. d.Vector3 pos = d.BodyGetPosition(Body);
  599. vec.X = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
  600. vec.Y = (_target_velocity.Y - vel.Y)*(PID_D) + (_zeroPosition.Y - pos.Y)* (PID_P * 2);
  601. if (flying)
  602. {
  603. vec.Z = (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
  604. }
  605. }
  606. //PidStatus = true;
  607. }
  608. else
  609. {
  610. m_pidControllerActive = true;
  611. _zeroFlag = false;
  612. if (m_iscolliding && !flying)
  613. {
  614. // We're flying and colliding with something
  615. vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D);
  616. vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D);
  617. }
  618. else if (m_iscolliding && flying)
  619. {
  620. // We're flying and colliding with something
  621. vec.X = ((_target_velocity.X/movementdivisor) - vel.X)*(PID_D / 16);
  622. vec.Y = ((_target_velocity.Y/movementdivisor) - vel.Y)*(PID_D / 16);
  623. }
  624. else if (!m_iscolliding && flying)
  625. {
  626. // We're flying and colliding with something
  627. vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D/6);
  628. vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D/6);
  629. }
  630. if (m_iscolliding && !flying && _target_velocity.Z > 0.0f)
  631. {
  632. // We're colliding with something and we're not flying but we're moving
  633. // This means we're walking or running.
  634. d.Vector3 pos = d.BodyGetPosition(Body);
  635. vec.Z = (_target_velocity.Z - vel.Z)*PID_D + (_zeroPosition.Z - pos.Z)*PID_P;
  636. if (_target_velocity.X > 0)
  637. {
  638. vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D;
  639. }
  640. if (_target_velocity.Y > 0)
  641. {
  642. vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D;
  643. }
  644. }
  645. else if (!m_iscolliding && !flying)
  646. {
  647. // we're not colliding and we're not flying so that means we're falling!
  648. // m_iscolliding includes collisions with the ground.
  649. d.Vector3 pos = d.BodyGetPosition(Body);
  650. if (_target_velocity.X > 0)
  651. {
  652. vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D;
  653. }
  654. if (_target_velocity.Y > 0)
  655. {
  656. vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D;
  657. }
  658. }
  659. if (flying)
  660. {
  661. vec.Z = (_target_velocity.Z - vel.Z) * (PID_D);
  662. }
  663. }
  664. if (flying)
  665. {
  666. vec.Z += (9.8f*m_mass);
  667. }
  668. doForce(vec);
  669. }
  670. /// <summary>
  671. /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence.
  672. /// </summary>
  673. public void UpdatePositionAndVelocity()
  674. {
  675. // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
  676. d.Vector3 vec = d.BodyGetPosition(Body);
  677. // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
  678. if (vec.X < 0.0f) vec.X = 0.0f;
  679. if (vec.Y < 0.0f) vec.Y = 0.0f;
  680. if (vec.X > 255.95f) vec.X = 255.95f;
  681. if (vec.Y > 255.95f) vec.Y = 255.95f;
  682. _position.X = vec.X;
  683. _position.Y = vec.Y;
  684. _position.Z = vec.Z;
  685. // Did we move last? = zeroflag
  686. // This helps keep us from sliding all over
  687. if (_zeroFlag)
  688. {
  689. _velocity.X = 0.0f;
  690. _velocity.Y = 0.0f;
  691. _velocity.Z = 0.0f;
  692. // Did we send out the 'stopped' message?
  693. if (!m_lastUpdateSent)
  694. {
  695. m_lastUpdateSent = true;
  696. //base.RequestPhysicsterseUpdate();
  697. }
  698. }
  699. else
  700. {
  701. m_lastUpdateSent = false;
  702. vec = d.BodyGetLinearVel(Body);
  703. _velocity.X = (vec.X);
  704. _velocity.Y = (vec.Y);
  705. _velocity.Z = (vec.Z);
  706. if (_velocity.Z < -6 && !m_hackSentFall)
  707. {
  708. // Collisionupdates will be used in the future, right now the're not being used.
  709. m_hackSentFall = true;
  710. //base.SendCollisionUpdate(new CollisionEventUpdate());
  711. m_pidControllerActive = false;
  712. }
  713. else if (flying && !m_hackSentFly)
  714. {
  715. //m_hackSentFly = true;
  716. //base.SendCollisionUpdate(new CollisionEventUpdate());
  717. }
  718. else
  719. {
  720. m_hackSentFly = false;
  721. m_hackSentFall = false;
  722. }
  723. }
  724. }
  725. /// <summary>
  726. /// Cleanup the things we use in the scene.
  727. /// </summary>
  728. public void Destroy()
  729. {
  730. lock (OdeScene.OdeLock)
  731. {
  732. // Kill the Amotor
  733. d.JointDestroy(Amotor);
  734. //kill the Geometry
  735. _parent_scene.waitForSpaceUnlock(_parent_scene.space);
  736. d.GeomDestroy(Shell);
  737. _parent_scene.geom_name_map.Remove(Shell);
  738. //kill the body
  739. d.BodyDestroy(Body);
  740. }
  741. }
  742. public override void CrossingFailure()
  743. {
  744. }
  745. public override PhysicsVector PIDTarget { set { return; } }
  746. public override bool PIDActive { set { return; } }
  747. public override float PIDTau { set { return; } }
  748. }
  749. }