1
0

POSPlugin.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  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. */
  28. using System;
  29. using System.Collections.Generic;
  30. using Axiom.Math;
  31. using OpenSim.Framework;
  32. using OpenSim.Region.Physics.Manager;
  33. namespace OpenSim.Region.Physics.POSPlugin
  34. {
  35. /// <summary>
  36. /// for now will be a very POS physics engine
  37. /// </summary>
  38. public class POSPlugin : IPhysicsPlugin
  39. {
  40. public POSPlugin()
  41. {
  42. }
  43. public bool Init()
  44. {
  45. return true;
  46. }
  47. public PhysicsScene GetScene()
  48. {
  49. return new POSScene();
  50. }
  51. public string GetName()
  52. {
  53. return ("POS");
  54. }
  55. public void Dispose()
  56. {
  57. }
  58. }
  59. public class POSScene : PhysicsScene
  60. {
  61. private List<POSCharacter> _characters = new List<POSCharacter>();
  62. private List<POSPrim> _prims = new List<POSPrim>();
  63. private float[] _heightMap;
  64. private const float gravity = -9.8f;
  65. public POSScene()
  66. {
  67. }
  68. public override void Initialise(IMesher meshmerizer)
  69. {
  70. // Does nothing right now
  71. }
  72. public override void Dispose()
  73. {
  74. }
  75. public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
  76. {
  77. POSCharacter act = new POSCharacter();
  78. act.Position = position;
  79. _characters.Add(act);
  80. return act;
  81. }
  82. public override void RemovePrim(PhysicsActor prim)
  83. {
  84. POSPrim p = (POSPrim) prim;
  85. if (_prims.Contains(p))
  86. {
  87. _prims.Remove(p);
  88. }
  89. }
  90. public override void RemoveAvatar(PhysicsActor character)
  91. {
  92. POSCharacter act = (POSCharacter) character;
  93. if (_characters.Contains(act))
  94. {
  95. _characters.Remove(act);
  96. }
  97. }
  98. /*
  99. public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
  100. {
  101. return null;
  102. }
  103. */
  104. public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
  105. PhysicsVector size, Quaternion rotation)
  106. {
  107. return AddPrimShape(primName, pbs, position, size, rotation, false);
  108. }
  109. public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
  110. PhysicsVector size, Quaternion rotation, bool isPhysical)
  111. {
  112. POSPrim prim = new POSPrim();
  113. prim.Position = position;
  114. prim.Orientation = rotation;
  115. prim.Size = size;
  116. _prims.Add(prim);
  117. return prim;
  118. }
  119. private bool check_collision(POSCharacter c, POSPrim p)
  120. {
  121. /*
  122. Console.WriteLine("checking whether " + c + " collides with " + p +
  123. " absX: " + Math.Abs(p.Position.X - c.Position.X) +
  124. " sizeX: " + p.Size.X * 0.5 + 0.5);
  125. */
  126. Vector3 rotatedPos = p.Orientation.Inverse()*
  127. new Vector3(c.Position.X - p.Position.X, c.Position.Y - p.Position.Y,
  128. c.Position.Z - p.Position.Z);
  129. Vector3 avatarSize = p.Orientation.Inverse()*new Vector3(c.Size.X, c.Size.Y, c.Size.Z);
  130. if (Math.Abs(rotatedPos.x) >= (p.Size.X*0.5 + Math.Abs(avatarSize.x)))
  131. {
  132. return false;
  133. }
  134. if (Math.Abs(rotatedPos.y) >= (p.Size.Y*0.5 + Math.Abs(avatarSize.y)))
  135. {
  136. return false;
  137. }
  138. if (Math.Abs(rotatedPos.z) >= (p.Size.Z*0.5 + Math.Abs(avatarSize.z)))
  139. {
  140. return false;
  141. }
  142. return true;
  143. }
  144. private bool check_all_prims(POSCharacter c)
  145. {
  146. for (int i = 0; i < _prims.Count; ++i)
  147. {
  148. if (check_collision(c, _prims[i]))
  149. {
  150. return true;
  151. }
  152. }
  153. return false;
  154. }
  155. public override void AddPhysicsActorTaint(PhysicsActor prim)
  156. {
  157. }
  158. public override float Simulate(float timeStep)
  159. {
  160. float fps = 0;
  161. for (int i = 0; i < _characters.Count; ++i)
  162. {
  163. fps++;
  164. POSCharacter character = _characters[i];
  165. float oldposX = character.Position.X;
  166. float oldposY = character.Position.Y;
  167. float oldposZ = character.Position.Z;
  168. if (!character.Flying)
  169. {
  170. character._target_velocity.Z += gravity*timeStep;
  171. }
  172. bool forcedZ = false;
  173. character.Position.X += character._target_velocity.X*timeStep;
  174. character.Position.Y += character._target_velocity.Y*timeStep;
  175. if (character.Position.Y < 0)
  176. {
  177. character.Position.Y = 0.1F;
  178. }
  179. else if (character.Position.Y >= Constants.RegionSize)
  180. {
  181. character.Position.Y = Constants.RegionSize - 0.1f;
  182. }
  183. if (character.Position.X < 0)
  184. {
  185. character.Position.X = 0.1F;
  186. }
  187. else if (character.Position.X >= Constants.RegionSize)
  188. {
  189. character.Position.X = Constants.RegionSize - 0.1f;
  190. }
  191. float terrainheight = _heightMap[(int)character.Position.Y * Constants.RegionSize + (int)character.Position.X];
  192. if (character.Position.Z + (character._target_velocity.Z*timeStep) < terrainheight + 2)
  193. {
  194. character.Position.Z = terrainheight + 1.0f;
  195. forcedZ = true;
  196. }
  197. else
  198. {
  199. character.Position.Z += character._target_velocity.Z*timeStep;
  200. }
  201. /// this is it -- the magic you've all been waiting for! Ladies and gentlemen --
  202. /// Completely Bogus Collision Detection!!!
  203. /// better known as the CBCD algorithm
  204. if (check_all_prims(character))
  205. {
  206. character.Position.Z = oldposZ; // first try Z axis
  207. if (check_all_prims(character))
  208. {
  209. character.Position.Z = oldposZ + 0.4f; // try harder
  210. if (check_all_prims(character))
  211. {
  212. character.Position.X = oldposX;
  213. character.Position.Y = oldposY;
  214. character.Position.Z = oldposZ;
  215. character.Position.X = character.Position.X + (character._target_velocity.X*timeStep);
  216. if (check_all_prims(character))
  217. {
  218. character.Position.X = oldposX;
  219. }
  220. character.Position.Y = character.Position.Y + (character._target_velocity.Y*timeStep);
  221. if (check_all_prims(character))
  222. {
  223. character.Position.Y = oldposY;
  224. }
  225. }
  226. else
  227. {
  228. forcedZ = true;
  229. }
  230. }
  231. else
  232. {
  233. forcedZ = true;
  234. }
  235. }
  236. if (character.Position.Y < 0)
  237. {
  238. character.Position.Y = 0.1F;
  239. }
  240. else if (character.Position.Y >= Constants.RegionSize)
  241. {
  242. character.Position.Y = Constants.RegionSize - 0.1f;
  243. }
  244. if (character.Position.X < 0)
  245. {
  246. character.Position.X = 0.1F;
  247. }
  248. else if (character.Position.X >= Constants.RegionSize)
  249. {
  250. character.Position.X = Constants.RegionSize - 0.1f;
  251. }
  252. character._velocity.X = (character.Position.X - oldposX)/timeStep;
  253. character._velocity.Y = (character.Position.Y - oldposY)/timeStep;
  254. if (forcedZ)
  255. {
  256. character._velocity.Z = 0;
  257. character._target_velocity.Z = 0;
  258. ((PhysicsActor)character).IsColliding = true;
  259. character.RequestPhysicsterseUpdate();
  260. }
  261. else
  262. {
  263. ((PhysicsActor)character).IsColliding = false;
  264. character._velocity.Z = (character.Position.Z - oldposZ)/timeStep;
  265. }
  266. }
  267. return fps;
  268. }
  269. public override void GetResults()
  270. {
  271. }
  272. public override bool IsThreaded
  273. {
  274. get { return (false); // for now we won't be multithreaded
  275. }
  276. }
  277. public override void SetTerrain(float[] heightMap)
  278. {
  279. _heightMap = heightMap;
  280. }
  281. public override void DeleteTerrain()
  282. {
  283. }
  284. }
  285. public class POSCharacter : PhysicsActor
  286. {
  287. private PhysicsVector _position;
  288. public PhysicsVector _velocity;
  289. public PhysicsVector _target_velocity = PhysicsVector.Zero;
  290. private PhysicsVector _acceleration;
  291. private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
  292. private bool flying;
  293. private bool iscolliding;
  294. public POSCharacter()
  295. {
  296. _velocity = new PhysicsVector();
  297. _position = new PhysicsVector();
  298. _acceleration = new PhysicsVector();
  299. }
  300. public override int PhysicsActorType
  301. {
  302. get { return (int) ActorTypes.Agent; }
  303. set { return; }
  304. }
  305. public override PhysicsVector RotationalVelocity
  306. {
  307. get { return m_rotationalVelocity; }
  308. set { m_rotationalVelocity = value; }
  309. }
  310. public override bool SetAlwaysRun
  311. {
  312. get { return false; }
  313. set { return; }
  314. }
  315. public override bool Grabbed
  316. {
  317. set { return; }
  318. }
  319. public override bool Selected
  320. {
  321. set { return; }
  322. }
  323. public override bool IsPhysical
  324. {
  325. get { return false; }
  326. set { return; }
  327. }
  328. public override bool ThrottleUpdates
  329. {
  330. get { return false; }
  331. set { return; }
  332. }
  333. public override bool Flying
  334. {
  335. get { return flying; }
  336. set { flying = value; }
  337. }
  338. public override bool IsColliding
  339. {
  340. get { return iscolliding; }
  341. set { iscolliding = value; }
  342. }
  343. public override bool CollidingGround
  344. {
  345. get { return false; }
  346. set { return; }
  347. }
  348. public override bool CollidingObj
  349. {
  350. get { return false; }
  351. set { return; }
  352. }
  353. public override bool Stopped
  354. {
  355. get { return false; }
  356. }
  357. public override PhysicsVector Position
  358. {
  359. get { return _position; }
  360. set { _position = value; }
  361. }
  362. public override PhysicsVector Size
  363. {
  364. get { return new PhysicsVector(0.5f, 0.5f, 1.0f); }
  365. set { }
  366. }
  367. public override float Mass
  368. {
  369. get { return 0f; }
  370. }
  371. public override PhysicsVector Force
  372. {
  373. get { return PhysicsVector.Zero; }
  374. }
  375. public override PhysicsVector CenterOfMass
  376. {
  377. get { return PhysicsVector.Zero; }
  378. }
  379. public override PhysicsVector GeometricCenter
  380. {
  381. get { return PhysicsVector.Zero; }
  382. }
  383. public override PrimitiveBaseShape Shape
  384. {
  385. set { return; }
  386. }
  387. public override PhysicsVector Velocity
  388. {
  389. get { return _velocity; }
  390. set { _target_velocity = value; }
  391. }
  392. public override float CollisionScore
  393. {
  394. get { return 0f; }
  395. }
  396. public override Quaternion Orientation
  397. {
  398. get { return Quaternion.Identity; }
  399. set { }
  400. }
  401. public override PhysicsVector Acceleration
  402. {
  403. get { return _acceleration; }
  404. }
  405. public override bool Kinematic
  406. {
  407. get { return true; }
  408. set { }
  409. }
  410. public void SetAcceleration(PhysicsVector accel)
  411. {
  412. _acceleration = accel;
  413. }
  414. public override void AddForce(PhysicsVector force)
  415. {
  416. }
  417. public override void SetMomentum(PhysicsVector momentum)
  418. {
  419. }
  420. public override void CrossingFailure()
  421. {
  422. }
  423. }
  424. public class POSPrim : PhysicsActor
  425. {
  426. private PhysicsVector _position;
  427. private PhysicsVector _velocity;
  428. private PhysicsVector _acceleration;
  429. private PhysicsVector _size;
  430. private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
  431. private Quaternion _orientation;
  432. private bool iscolliding;
  433. public POSPrim()
  434. {
  435. _velocity = new PhysicsVector();
  436. _position = new PhysicsVector();
  437. _acceleration = new PhysicsVector();
  438. }
  439. public override int PhysicsActorType
  440. {
  441. get { return (int) ActorTypes.Prim; }
  442. set { return; }
  443. }
  444. public override PhysicsVector RotationalVelocity
  445. {
  446. get { return m_rotationalVelocity; }
  447. set { m_rotationalVelocity = value; }
  448. }
  449. public override bool IsPhysical
  450. {
  451. get { return false; }
  452. set { return; }
  453. }
  454. public override bool ThrottleUpdates
  455. {
  456. get { return false; }
  457. set { return; }
  458. }
  459. public override bool IsColliding
  460. {
  461. get { return iscolliding; }
  462. set { iscolliding = value; }
  463. }
  464. public override bool CollidingGround
  465. {
  466. get { return false; }
  467. set { return; }
  468. }
  469. public override bool CollidingObj
  470. {
  471. get { return false; }
  472. set { return; }
  473. }
  474. public override bool Stopped
  475. {
  476. get { return false; }
  477. }
  478. public override PhysicsVector Position
  479. {
  480. get { return _position; }
  481. set { _position = value; }
  482. }
  483. public override PhysicsVector Size
  484. {
  485. get { return _size; }
  486. set { _size = value; }
  487. }
  488. public override float Mass
  489. {
  490. get { return 0f; }
  491. }
  492. public override PhysicsVector Force
  493. {
  494. get { return PhysicsVector.Zero; }
  495. }
  496. public override PhysicsVector CenterOfMass
  497. {
  498. get { return PhysicsVector.Zero; }
  499. }
  500. public override PhysicsVector GeometricCenter
  501. {
  502. get { return PhysicsVector.Zero; }
  503. }
  504. public override PrimitiveBaseShape Shape
  505. {
  506. set { return; }
  507. }
  508. public override PhysicsVector Velocity
  509. {
  510. get { return _velocity; }
  511. set { _velocity = value; }
  512. }
  513. public override float CollisionScore
  514. {
  515. get { return 0f; }
  516. }
  517. public override Quaternion Orientation
  518. {
  519. get { return _orientation; }
  520. set { _orientation = value; }
  521. }
  522. public override PhysicsVector Acceleration
  523. {
  524. get { return _acceleration; }
  525. }
  526. public override bool Kinematic
  527. {
  528. get { return true; }
  529. set { }
  530. }
  531. public void SetAcceleration(PhysicsVector accel)
  532. {
  533. _acceleration = accel;
  534. }
  535. public override void AddForce(PhysicsVector force)
  536. {
  537. }
  538. public override void SetMomentum(PhysicsVector momentum)
  539. {
  540. }
  541. public override bool Flying
  542. {
  543. get { return false; }
  544. set { }
  545. }
  546. public override bool SetAlwaysRun
  547. {
  548. get { return false; }
  549. set { return; }
  550. }
  551. public override bool Grabbed
  552. {
  553. set { return; }
  554. }
  555. public override bool Selected
  556. {
  557. set { return; }
  558. }
  559. public override void CrossingFailure()
  560. {
  561. }
  562. }
  563. }