OdePlugin.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /*
  2. * Copyright (c) OpenSim project, http://sim.opensecondlife.org/
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. * * Redistributions of source code must retain the above copyright
  7. * notice, this list of conditions and the following disclaimer.
  8. * * Redistributions in binary form must reproduce the above copyright
  9. * notice, this list of conditions and the following disclaimer in the
  10. * documentation and/or other materials provided with the distribution.
  11. * * Neither the name of the <organization> nor the
  12. * names of its contributors may be used to endorse or promote products
  13. * derived from this software without specific prior written permission.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
  16. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
  19. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. *
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using OpenSim.Physics.Manager;
  30. using Ode.NET;
  31. namespace OpenSim.Physics.OdePlugin
  32. {
  33. /// <summary>
  34. /// ODE plugin
  35. /// </summary>
  36. public class OdePlugin : IPhysicsPlugin
  37. {
  38. private OdeScene _mScene;
  39. public OdePlugin()
  40. {
  41. }
  42. public bool Init()
  43. {
  44. return true;
  45. }
  46. public PhysicsScene GetScene()
  47. {
  48. if (_mScene == null)
  49. {
  50. _mScene = new OdeScene();
  51. }
  52. return (_mScene);
  53. }
  54. public string GetName()
  55. {
  56. return ("OpenDynamicsEngine");
  57. }
  58. public void Dispose()
  59. {
  60. }
  61. }
  62. public class OdeScene : PhysicsScene
  63. {
  64. static public IntPtr world;
  65. static public IntPtr space;
  66. static private IntPtr contactgroup;
  67. static private IntPtr LandGeom;
  68. static private IntPtr Land;
  69. private double[] _heightmap;
  70. static private d.NearCallback nearCallback = near;
  71. private List<OdeCharacter> _characters = new List<OdeCharacter>();
  72. private static d.ContactGeom[] contacts = new d.ContactGeom[30];
  73. private static d.Contact contact;
  74. public OdeScene()
  75. {
  76. contact.surface.mode = d.ContactFlags.Bounce | d.ContactFlags.SoftCFM;
  77. contact.surface.mu = d.Infinity;
  78. contact.surface.mu2 = 0.0f;
  79. contact.surface.bounce = 0.1f;
  80. contact.surface.bounce_vel = 0.1f;
  81. contact.surface.soft_cfm = 0.01f;
  82. world = d.WorldCreate();
  83. space = d.HashSpaceCreate(IntPtr.Zero);
  84. contactgroup = d.JointGroupCreate(0);
  85. d.WorldSetGravity(world, 0.0f, 0.0f, -0.5f);
  86. //d.WorldSetCFM(world, 1e-5f);
  87. d.WorldSetAutoDisableFlag(world, false);
  88. d.WorldSetContactSurfaceLayer(world, 0.001f);
  89. // d.CreatePlane(space, 0, 0, 1, 0);
  90. this._heightmap = new double[65536];
  91. }
  92. // This function blatantly ripped off from BoxStack.cs
  93. static private void near(IntPtr space, IntPtr g1, IntPtr g2)
  94. {
  95. //Console.WriteLine("collision callback");
  96. IntPtr b1 = d.GeomGetBody(g1);
  97. IntPtr b2 = d.GeomGetBody(g2);
  98. if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
  99. return;
  100. int count = d.Collide(g1, g2, 500, contacts, d.ContactGeom.SizeOf);
  101. for (int i = 0; i < count; ++i)
  102. {
  103. contact.geom = contacts[i];
  104. IntPtr joint = d.JointCreateContact(world, contactgroup, ref contact);
  105. d.JointAttach(joint, b1, b2);
  106. }
  107. }
  108. public override PhysicsActor AddAvatar(PhysicsVector position)
  109. {
  110. PhysicsVector pos = new PhysicsVector();
  111. pos.X = position.X;
  112. pos.Y = position.Y;
  113. pos.Z = position.Z + 20;
  114. OdeCharacter newAv = new OdeCharacter(this, pos);
  115. this._characters.Add(newAv);
  116. return newAv;
  117. }
  118. public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size)
  119. {
  120. PhysicsVector pos = new PhysicsVector();
  121. pos.X = position.X;
  122. pos.Y = position.Y;
  123. pos.Z = position.Z;
  124. PhysicsVector siz = new PhysicsVector();
  125. siz.X = size.X;
  126. siz.Y = size.Y;
  127. siz.Z = size.Z;
  128. return new OdePrim();
  129. }
  130. public override void Simulate(float timeStep)
  131. {
  132. foreach (OdeCharacter actor in _characters)
  133. {
  134. actor.Move(timeStep * 5f);
  135. }
  136. d.SpaceCollide(space, IntPtr.Zero, nearCallback);
  137. d.WorldQuickStep(world, timeStep * 5f);
  138. d.JointGroupEmpty(contactgroup);
  139. foreach (OdeCharacter actor in _characters)
  140. {
  141. actor.UpdatePosition();
  142. }
  143. }
  144. public override void GetResults()
  145. {
  146. }
  147. public override bool IsThreaded
  148. {
  149. get
  150. {
  151. return (false); // for now we won't be multithreaded
  152. }
  153. }
  154. public override void SetTerrain(float[] heightMap)
  155. {
  156. for (int i = 0; i < 65536; i++)
  157. {
  158. this._heightmap[i] = (double)heightMap[i];
  159. }
  160. IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
  161. d.GeomHeightfieldDataBuildDouble(HeightmapData, _heightmap, 0, 256, 256, 256, 256, 1.0f, 0.0f, 2.0f, 0);
  162. d.GeomHeightfieldDataSetBounds(HeightmapData, 256, 256);
  163. LandGeom = d.CreateHeightfield(space, HeightmapData, 1);
  164. d.Matrix3 R = new d.Matrix3();
  165. Axiom.MathLib.Quaternion q1 =Axiom.MathLib.Quaternion.FromAngleAxis(1.5707f, new Axiom.MathLib.Vector3(1,0,0));
  166. Axiom.MathLib.Quaternion q2 =Axiom.MathLib.Quaternion.FromAngleAxis(1.5707f, new Axiom.MathLib.Vector3(0,1,0));
  167. //Axiom.MathLib.Quaternion q3 = Axiom.MathLib.Quaternion.FromAngleAxis(3.14f, new Axiom.MathLib.Vector3(0, 0, 1));
  168. q1 = q1 * q2;
  169. //q1 = q1 * q3;
  170. Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3();
  171. float angle = 0;
  172. q1.ToAngleAxis(ref angle, ref v3);
  173. d.RFromAxisAndAngle(out R, v3.x, v3.y, v3.z, angle);
  174. d.GeomSetRotation(LandGeom, ref R);
  175. d.GeomSetPosition(LandGeom, 128, 128, 0);
  176. }
  177. public override void DeleteTerrain()
  178. {
  179. }
  180. }
  181. public class OdeCharacter : PhysicsActor
  182. {
  183. private PhysicsVector _position;
  184. private PhysicsVector _velocity;
  185. private PhysicsVector _acceleration;
  186. private bool flying;
  187. //private float gravityAccel;
  188. private IntPtr BoundingCapsule;
  189. IntPtr capsule_geom;
  190. d.Mass capsule_mass;
  191. public OdeCharacter(OdeScene parent_scene, PhysicsVector pos)
  192. {
  193. _velocity = new PhysicsVector();
  194. _position = pos;
  195. _acceleration = new PhysicsVector();
  196. d.MassSetCapsule(out capsule_mass, 5.0f, 3, 0.5f, 2f);
  197. capsule_geom = d.CreateCapsule(OdeScene.space, 0.5f, 2f);
  198. this.BoundingCapsule = d.BodyCreate(OdeScene.world);
  199. d.BodySetMass(BoundingCapsule, ref capsule_mass);
  200. d.BodySetPosition(BoundingCapsule, pos.X, pos.Y, pos.Z);
  201. d.GeomSetBody(capsule_geom, BoundingCapsule);
  202. }
  203. public override bool Flying
  204. {
  205. get
  206. {
  207. return flying;
  208. }
  209. set
  210. {
  211. flying = value;
  212. }
  213. }
  214. public override PhysicsVector Position
  215. {
  216. get
  217. {
  218. return _position;
  219. }
  220. set
  221. {
  222. _position = value;
  223. }
  224. }
  225. public override PhysicsVector Velocity
  226. {
  227. get
  228. {
  229. return _velocity;
  230. }
  231. set
  232. {
  233. _velocity = value;
  234. }
  235. }
  236. public override bool Kinematic
  237. {
  238. get
  239. {
  240. return false;
  241. }
  242. set
  243. {
  244. }
  245. }
  246. public override Axiom.MathLib.Quaternion Orientation
  247. {
  248. get
  249. {
  250. return Axiom.MathLib.Quaternion.Identity;
  251. }
  252. set
  253. {
  254. }
  255. }
  256. public override PhysicsVector Acceleration
  257. {
  258. get
  259. {
  260. return _acceleration;
  261. }
  262. }
  263. public void SetAcceleration(PhysicsVector accel)
  264. {
  265. this._acceleration = accel;
  266. }
  267. public override void AddForce(PhysicsVector force)
  268. {
  269. }
  270. public override void SetMomentum(PhysicsVector momentum)
  271. {
  272. }
  273. public void Move(float timeStep)
  274. {
  275. PhysicsVector vec = new PhysicsVector();
  276. vec.X = this._velocity.X * timeStep;
  277. vec.Y = this._velocity.Y * timeStep;
  278. if (flying)
  279. {
  280. vec.Z = (this._velocity.Z + 0.5f) * timeStep;
  281. }
  282. d.BodySetLinearVel(this.BoundingCapsule, vec.X, vec.Y, vec.Z);
  283. }
  284. public void UpdatePosition()
  285. {
  286. d.Vector3 vec = d.BodyGetPosition(BoundingCapsule);
  287. this._position.X = vec.X;
  288. this._position.Y = vec.Y;
  289. this._position.Z = vec.Z;
  290. }
  291. }
  292. public class OdePrim : PhysicsActor
  293. {
  294. private PhysicsVector _position;
  295. private PhysicsVector _velocity;
  296. private PhysicsVector _acceleration;
  297. public OdePrim()
  298. {
  299. _velocity = new PhysicsVector();
  300. _position = new PhysicsVector();
  301. _acceleration = new PhysicsVector();
  302. }
  303. public override bool Flying
  304. {
  305. get
  306. {
  307. return false; //no flying prims for you
  308. }
  309. set
  310. {
  311. }
  312. }
  313. public override PhysicsVector Position
  314. {
  315. get
  316. {
  317. PhysicsVector pos = new PhysicsVector();
  318. // PhysicsVector vec = this._prim.Position;
  319. //pos.X = vec.X;
  320. //pos.Y = vec.Y;
  321. //pos.Z = vec.Z;
  322. return pos;
  323. }
  324. set
  325. {
  326. /*PhysicsVector vec = value;
  327. PhysicsVector pos = new PhysicsVector();
  328. pos.X = vec.X;
  329. pos.Y = vec.Y;
  330. pos.Z = vec.Z;
  331. this._prim.Position = pos;*/
  332. }
  333. }
  334. public override PhysicsVector Velocity
  335. {
  336. get
  337. {
  338. return _velocity;
  339. }
  340. set
  341. {
  342. _velocity = value;
  343. }
  344. }
  345. public override bool Kinematic
  346. {
  347. get
  348. {
  349. return false;
  350. //return this._prim.Kinematic;
  351. }
  352. set
  353. {
  354. //this._prim.Kinematic = value;
  355. }
  356. }
  357. public override Axiom.MathLib.Quaternion Orientation
  358. {
  359. get
  360. {
  361. Axiom.MathLib.Quaternion res = new Axiom.MathLib.Quaternion();
  362. return res;
  363. }
  364. set
  365. {
  366. }
  367. }
  368. public override PhysicsVector Acceleration
  369. {
  370. get
  371. {
  372. return _acceleration;
  373. }
  374. }
  375. public void SetAcceleration(PhysicsVector accel)
  376. {
  377. this._acceleration = accel;
  378. }
  379. public override void AddForce(PhysicsVector force)
  380. {
  381. }
  382. public override void SetMomentum(PhysicsVector momentum)
  383. {
  384. }
  385. }
  386. }