BulletXPlugin.cs 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559
  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. #region References
  28. using System;
  29. using System.Collections.Generic;
  30. using MonoXnaCompactMaths;
  31. using OpenSim.Framework;
  32. using OpenSim.Region.Physics.Manager;
  33. using XnaDevRu.BulletX;
  34. using XnaDevRu.BulletX.Dynamics;
  35. using AxiomQuaternion = Axiom.Math.Quaternion;
  36. #endregion
  37. namespace OpenSim.Region.Physics.BulletXPlugin
  38. {
  39. /// <summary>
  40. /// BulletXConversions are called now BulletXMaths
  41. /// This Class converts objects and types for BulletX and give some operations
  42. /// </summary>
  43. public class BulletXMaths
  44. {
  45. //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  46. //Vector3
  47. public static Vector3 PhysicsVectorToXnaVector3(PhysicsVector physicsVector)
  48. {
  49. return new Vector3(physicsVector.X, physicsVector.Y, physicsVector.Z);
  50. }
  51. public static PhysicsVector XnaVector3ToPhysicsVector(Vector3 xnaVector3)
  52. {
  53. return new PhysicsVector(xnaVector3.X, xnaVector3.Y, xnaVector3.Z);
  54. }
  55. //Quaternion
  56. public static Quaternion AxiomQuaternionToXnaQuaternion(AxiomQuaternion axiomQuaternion)
  57. {
  58. return new Quaternion(axiomQuaternion.x, axiomQuaternion.y, axiomQuaternion.z, axiomQuaternion.w);
  59. }
  60. public static AxiomQuaternion XnaQuaternionToAxiomQuaternion(Quaternion xnaQuaternion)
  61. {
  62. return new AxiomQuaternion(xnaQuaternion.W, xnaQuaternion.X, xnaQuaternion.Y, xnaQuaternion.Z);
  63. }
  64. //Next methods are extracted from XnaDevRu.BulletX(See 3rd party license):
  65. //- SetRotation (class MatrixOperations)
  66. //- GetRotation (class MatrixOperations)
  67. //- GetElement (class MathHelper)
  68. //- SetElement (class MathHelper)
  69. internal static void SetRotation(ref Matrix m, Quaternion q)
  70. {
  71. float d = q.LengthSquared();
  72. float s = 2f/d;
  73. float xs = q.X*s, ys = q.Y*s, zs = q.Z*s;
  74. float wx = q.W*xs, wy = q.W*ys, wz = q.W*zs;
  75. float xx = q.X*xs, xy = q.X*ys, xz = q.X*zs;
  76. float yy = q.Y*ys, yz = q.Y*zs, zz = q.Z*zs;
  77. m = new Matrix(1 - (yy + zz), xy - wz, xz + wy, 0,
  78. xy + wz, 1 - (xx + zz), yz - wx, 0,
  79. xz - wy, yz + wx, 1 - (xx + yy), 0,
  80. m.M41, m.M42, m.M43, 1);
  81. }
  82. internal static Quaternion GetRotation(Matrix m)
  83. {
  84. Quaternion q = new Quaternion();
  85. float trace = m.M11 + m.M22 + m.M33;
  86. if (trace > 0)
  87. {
  88. float s = (float) Math.Sqrt(trace + 1);
  89. q.W = s*0.5f;
  90. s = 0.5f/s;
  91. q.X = (m.M32 - m.M23)*s;
  92. q.Y = (m.M13 - m.M31)*s;
  93. q.Z = (m.M21 - m.M12)*s;
  94. }
  95. else
  96. {
  97. int i = m.M11 < m.M22
  98. ?
  99. (m.M22 < m.M33 ? 2 : 1)
  100. :
  101. (m.M11 < m.M33 ? 2 : 0);
  102. int j = (i + 1)%3;
  103. int k = (i + 2)%3;
  104. float s = (float) Math.Sqrt(GetElement(m, i, i) - GetElement(m, j, j) - GetElement(m, k, k) + 1);
  105. SetElement(ref q, i, s*0.5f);
  106. s = 0.5f/s;
  107. q.W = (GetElement(m, k, j) - GetElement(m, j, k))*s;
  108. SetElement(ref q, j, (GetElement(m, j, i) + GetElement(m, i, j))*s);
  109. SetElement(ref q, k, (GetElement(m, k, i) + GetElement(m, i, k))*s);
  110. }
  111. return q;
  112. }
  113. internal static float SetElement(ref Quaternion q, int index, float value)
  114. {
  115. switch (index)
  116. {
  117. case 0:
  118. q.X = value;
  119. break;
  120. case 1:
  121. q.Y = value;
  122. break;
  123. case 2:
  124. q.Z = value;
  125. break;
  126. case 3:
  127. q.W = value;
  128. break;
  129. }
  130. return 0;
  131. }
  132. internal static float GetElement(Matrix mat, int row, int col)
  133. {
  134. switch (row)
  135. {
  136. case 0:
  137. switch (col)
  138. {
  139. case 0:
  140. return mat.M11;
  141. case 1:
  142. return mat.M12;
  143. case 2:
  144. return mat.M13;
  145. }
  146. break;
  147. case 1:
  148. switch (col)
  149. {
  150. case 0:
  151. return mat.M21;
  152. case 1:
  153. return mat.M22;
  154. case 2:
  155. return mat.M23;
  156. }
  157. break;
  158. case 2:
  159. switch (col)
  160. {
  161. case 0:
  162. return mat.M31;
  163. case 1:
  164. return mat.M32;
  165. case 2:
  166. return mat.M33;
  167. }
  168. break;
  169. }
  170. return 0;
  171. }
  172. }
  173. /// <summary>
  174. /// PhysicsPlugin Class for BulletX
  175. /// </summary>
  176. public class BulletXPlugin : IPhysicsPlugin
  177. {
  178. private BulletXScene _mScene;
  179. public BulletXPlugin()
  180. {
  181. }
  182. public bool Init()
  183. {
  184. return true;
  185. }
  186. public PhysicsScene GetScene()
  187. {
  188. if (_mScene == null)
  189. {
  190. _mScene = new BulletXScene();
  191. }
  192. return (_mScene);
  193. }
  194. public string GetName()
  195. {
  196. return ("modified_BulletX"); //Changed!! "BulletXEngine" To "modified_BulletX"
  197. }
  198. public void Dispose()
  199. {
  200. }
  201. }
  202. // Class to detect and debug collisions
  203. // Mainly used for debugging purposes
  204. internal class CollisionDispatcherLocal : CollisionDispatcher
  205. {
  206. private BulletXScene relatedScene;
  207. public CollisionDispatcherLocal(BulletXScene s)
  208. : base()
  209. {
  210. relatedScene = s;
  211. }
  212. public override bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
  213. {
  214. RigidBody rb;
  215. BulletXCharacter bxcA = null;
  216. BulletXPrim bxpA = null;
  217. Type t = bodyA.GetType();
  218. if (t == typeof (RigidBody))
  219. {
  220. rb = (RigidBody) bodyA;
  221. relatedScene._characters.TryGetValue(rb, out bxcA);
  222. relatedScene._prims.TryGetValue(rb, out bxpA);
  223. }
  224. // String nameA;
  225. // if (bxcA != null)
  226. // nameA = bxcA._name;
  227. // else if (bxpA != null)
  228. // nameA = bxpA._name;
  229. // else
  230. // nameA = "null";
  231. BulletXCharacter bxcB = null;
  232. BulletXPrim bxpB = null;
  233. t = bodyB.GetType();
  234. if (t == typeof (RigidBody))
  235. {
  236. rb = (RigidBody) bodyB;
  237. relatedScene._characters.TryGetValue(rb, out bxcB);
  238. relatedScene._prims.TryGetValue(rb, out bxpB);
  239. }
  240. // String nameB;
  241. // if (bxcB != null)
  242. // nameB = bxcB._name;
  243. // else if (bxpB != null)
  244. // nameB = bxpB._name;
  245. // else
  246. // nameB = "null";
  247. bool needsCollision = base.NeedsCollision(bodyA, bodyB);
  248. //m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB,
  249. //needsCollision);
  250. return needsCollision;
  251. }
  252. }
  253. /// <summary>
  254. /// PhysicsScene Class for BulletX
  255. /// </summary>
  256. public class BulletXScene : PhysicsScene
  257. {
  258. #region BulletXScene Fields
  259. public DiscreteDynamicsWorld ddWorld;
  260. private CollisionDispatcher cDispatcher;
  261. private OverlappingPairCache opCache;
  262. private SequentialImpulseConstraintSolver sicSolver;
  263. public static Object BulletXLock = new Object();
  264. private const int minXY = 0;
  265. private const int minZ = 0;
  266. private const int maxXY = (int)Constants.RegionSize;
  267. private const int maxZ = 4096;
  268. private const int maxHandles = 32766; //Why? I don't know
  269. private const float gravity = 9.8f;
  270. private const float heightLevel0 = 77.0f;
  271. private const float heightLevel1 = 200.0f;
  272. private const float lowGravityFactor = 0.2f;
  273. //OpenSim calls Simulate 10 times per seconds. So FPS = "Simulate Calls" * simulationSubSteps = 100 FPS
  274. private const int simulationSubSteps = 10;
  275. //private float[] _heightmap;
  276. private BulletXPlanet _simFlatPlanet;
  277. internal Dictionary<RigidBody, BulletXCharacter> _characters = new Dictionary<RigidBody, BulletXCharacter>();
  278. internal Dictionary<RigidBody, BulletXPrim> _prims = new Dictionary<RigidBody, BulletXPrim>();
  279. public IMesher mesher;
  280. public static float Gravity
  281. {
  282. get { return gravity; }
  283. }
  284. public static float HeightLevel0
  285. {
  286. get { return heightLevel0; }
  287. }
  288. public static float HeightLevel1
  289. {
  290. get { return heightLevel1; }
  291. }
  292. public static float LowGravityFactor
  293. {
  294. get { return lowGravityFactor; }
  295. }
  296. public static int MaxXY
  297. {
  298. get { return maxXY; }
  299. }
  300. public static int MaxZ
  301. {
  302. get { return maxZ; }
  303. }
  304. private List<RigidBody> _forgottenRigidBodies = new List<RigidBody>();
  305. internal string is_ex_message = "Can't remove rigidBody!: ";
  306. #endregion
  307. public BulletXScene()
  308. {
  309. cDispatcher = new CollisionDispatcherLocal(this);
  310. Vector3 worldMinDim = new Vector3((float) minXY, (float) minXY, (float) minZ);
  311. Vector3 worldMaxDim = new Vector3((float) maxXY, (float) maxXY, (float) maxZ);
  312. opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles);
  313. sicSolver = new SequentialImpulseConstraintSolver();
  314. lock (BulletXLock)
  315. {
  316. ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver);
  317. ddWorld.Gravity = new Vector3(0, 0, -gravity);
  318. }
  319. //this._heightmap = new float[65536];
  320. }
  321. public override void Initialise(IMesher meshmerizer)
  322. {
  323. mesher = meshmerizer;
  324. }
  325. public override void Dispose()
  326. {
  327. }
  328. public override void SetWaterLevel(float baseheight)
  329. {
  330. }
  331. public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
  332. {
  333. PhysicsVector pos = new PhysicsVector();
  334. pos.X = position.X;
  335. pos.Y = position.Y;
  336. pos.Z = position.Z + 20;
  337. BulletXCharacter newAv = null;
  338. lock (BulletXLock)
  339. {
  340. newAv = new BulletXCharacter(avName, this, pos);
  341. _characters.Add(newAv.RigidBody, newAv);
  342. }
  343. return newAv;
  344. }
  345. public override void RemoveAvatar(PhysicsActor actor)
  346. {
  347. if (actor is BulletXCharacter)
  348. {
  349. lock (BulletXLock)
  350. {
  351. try
  352. {
  353. ddWorld.RemoveRigidBody(((BulletXCharacter) actor).RigidBody);
  354. }
  355. catch (Exception ex)
  356. {
  357. BulletXMessage(is_ex_message + ex.Message, true);
  358. ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation;
  359. AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody);
  360. }
  361. _characters.Remove(((BulletXCharacter) actor).RigidBody);
  362. }
  363. GC.Collect();
  364. }
  365. }
  366. public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
  367. PhysicsVector size, AxiomQuaternion rotation)
  368. {
  369. return AddPrimShape(primName, pbs, position, size, rotation, false);
  370. }
  371. public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
  372. PhysicsVector size, AxiomQuaternion rotation, bool isPhysical)
  373. {
  374. PhysicsActor result;
  375. switch (pbs.ProfileShape)
  376. {
  377. case ProfileShape.Square:
  378. /// support simple box & hollow box now; later, more shapes
  379. if (pbs.ProfileHollow == 0)
  380. {
  381. result = AddPrim(primName, position, size, rotation, null, null, isPhysical);
  382. }
  383. else
  384. {
  385. IMesh mesh = mesher.CreateMesh(primName, pbs, size);
  386. result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
  387. }
  388. break;
  389. default:
  390. result = AddPrim(primName, position, size, rotation, null, null, isPhysical);
  391. break;
  392. }
  393. return result;
  394. }
  395. public PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation,
  396. IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
  397. {
  398. BulletXPrim newPrim = null;
  399. lock (BulletXLock)
  400. {
  401. newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs, isPhysical);
  402. _prims.Add(newPrim.RigidBody, newPrim);
  403. }
  404. return newPrim;
  405. }
  406. public override void RemovePrim(PhysicsActor prim)
  407. {
  408. if (prim is BulletXPrim)
  409. {
  410. lock (BulletXLock)
  411. {
  412. try
  413. {
  414. ddWorld.RemoveRigidBody(((BulletXPrim) prim).RigidBody);
  415. }
  416. catch (Exception ex)
  417. {
  418. BulletXMessage(is_ex_message + ex.Message, true);
  419. ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation;
  420. AddForgottenRigidBody(((BulletXPrim) prim).RigidBody);
  421. }
  422. _prims.Remove(((BulletXPrim) prim).RigidBody);
  423. }
  424. GC.Collect();
  425. }
  426. }
  427. public override void AddPhysicsActorTaint(PhysicsActor prim)
  428. {
  429. }
  430. public override float Simulate(float timeStep)
  431. {
  432. float fps = 0;
  433. lock (BulletXLock)
  434. {
  435. //Try to remove garbage
  436. RemoveForgottenRigidBodies();
  437. //End of remove
  438. MoveAllObjects(timeStep);
  439. fps = (timeStep*simulationSubSteps);
  440. ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep);
  441. //Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine.
  442. ValidateHeightForAll();
  443. //End heightmap validation.
  444. UpdateKineticsForAll();
  445. }
  446. return fps;
  447. }
  448. private void MoveAllObjects(float timeStep)
  449. {
  450. foreach (BulletXCharacter actor in _characters.Values)
  451. {
  452. actor.Move(timeStep);
  453. }
  454. }
  455. private void ValidateHeightForAll()
  456. {
  457. float _height;
  458. foreach (BulletXCharacter actor in _characters.Values)
  459. {
  460. //_height = HeightValue(actor.RigidBodyPosition);
  461. _height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition);
  462. actor.ValidateHeight(_height);
  463. //if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height);
  464. }
  465. foreach (BulletXPrim prim in _prims.Values)
  466. {
  467. //_height = HeightValue(prim.RigidBodyPosition);
  468. _height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition);
  469. prim.ValidateHeight(_height);
  470. //if (_simFlatPlanet.heightIsNotValid(prim.RigidBodyPosition, out _height)) prim.ValidateHeight(_height);
  471. }
  472. //foreach (BulletXCharacter actor in _characters)
  473. //{
  474. // actor.ValidateHeight(0);
  475. //}
  476. //foreach (BulletXPrim prim in _prims)
  477. //{
  478. // prim.ValidateHeight(0);
  479. //}
  480. }
  481. private void UpdateKineticsForAll()
  482. {
  483. //UpdatePosition > UpdateKinetics.
  484. //Not only position will be updated, also velocity cause acceleration.
  485. foreach (BulletXCharacter actor in _characters.Values)
  486. {
  487. actor.UpdateKinetics();
  488. }
  489. foreach (BulletXPrim prim in _prims.Values)
  490. {
  491. prim.UpdateKinetics();
  492. }
  493. //if(this._simFlatPlanet!=null) this._simFlatPlanet.Restore();
  494. }
  495. public override void GetResults()
  496. {
  497. }
  498. public override bool IsThreaded
  499. {
  500. get { return (false); // for now we won't be multithreaded
  501. }
  502. }
  503. public override void SetTerrain(float[] heightMap)
  504. {
  505. ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
  506. //for (int i = 0; i < 65536; i++)
  507. //{
  508. // // this._heightmap[i] = (double)heightMap[i];
  509. // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
  510. // int x = i & 0xff;
  511. // int y = i >> 8;
  512. // this._heightmap[i] = heightMap[x * 256 + y];
  513. //}
  514. //float[] swappedHeightMap = new float[65536];
  515. ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
  516. //for (int i = 0; i < 65536; i++)
  517. //{
  518. // // this._heightmap[i] = (double)heightMap[i];
  519. // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
  520. // int x = i & 0xff;
  521. // int y = i >> 8;
  522. // swappedHeightMap[i] = heightMap[x * 256 + y];
  523. //}
  524. DeleteTerrain();
  525. //There is a BulletXLock inside the constructor of BulletXPlanet
  526. //this._simFlatPlanet = new BulletXPlanet(this, swappedHeightMap);
  527. _simFlatPlanet = new BulletXPlanet(this, heightMap);
  528. //this._heightmap = heightMap;
  529. }
  530. public override void DeleteTerrain()
  531. {
  532. if (_simFlatPlanet != null)
  533. {
  534. lock (BulletXLock)
  535. {
  536. try
  537. {
  538. ddWorld.RemoveRigidBody(_simFlatPlanet.RigidBody);
  539. }
  540. catch (Exception ex)
  541. {
  542. BulletXMessage(is_ex_message + ex.Message, true);
  543. _simFlatPlanet.RigidBody.ActivationState = ActivationState.DisableSimulation;
  544. AddForgottenRigidBody(_simFlatPlanet.RigidBody);
  545. }
  546. }
  547. _simFlatPlanet = null;
  548. GC.Collect();
  549. BulletXMessage("Terrain erased!", false);
  550. }
  551. //this._heightmap = null;
  552. }
  553. internal void AddForgottenRigidBody(RigidBody forgottenRigidBody)
  554. {
  555. _forgottenRigidBodies.Add(forgottenRigidBody);
  556. }
  557. private void RemoveForgottenRigidBodies()
  558. {
  559. RigidBody forgottenRigidBody;
  560. int nRigidBodies = _forgottenRigidBodies.Count;
  561. for (int i = nRigidBodies - 1; i >= 0; i--)
  562. {
  563. forgottenRigidBody = _forgottenRigidBodies[i];
  564. try
  565. {
  566. ddWorld.RemoveRigidBody(forgottenRigidBody);
  567. _forgottenRigidBodies.Remove(forgottenRigidBody);
  568. BulletXMessage("Forgotten Rigid Body Removed", false);
  569. }
  570. catch (Exception ex)
  571. {
  572. BulletXMessage("Can't remove forgottenRigidBody!: " + ex.Message, false);
  573. }
  574. }
  575. GC.Collect();
  576. }
  577. internal static void BulletXMessage(string message, bool isWarning)
  578. {
  579. PhysicsPluginManager.PhysicsPluginMessage("[Modified BulletX]:\t" + message, isWarning);
  580. }
  581. //temp
  582. //private float HeightValue(MonoXnaCompactMaths.Vector3 position)
  583. //{
  584. // int li_x, li_y;
  585. // float height;
  586. // li_x = (int)Math.Round(position.X); if (li_x < 0) li_x = 0;
  587. // li_y = (int)Math.Round(position.Y); if (li_y < 0) li_y = 0;
  588. // height = this._heightmap[li_y * 256 + li_x];
  589. // if (height < 0) height = 0;
  590. // else if (height > maxZ) height = maxZ;
  591. // return height;
  592. //}
  593. }
  594. /// <summary>
  595. /// Generic Physics Actor for BulletX inherit from PhysicActor
  596. /// </summary>
  597. public class BulletXActor : PhysicsActor
  598. {
  599. protected bool flying = false;
  600. protected bool _physical = false;
  601. protected PhysicsVector _position;
  602. protected PhysicsVector _velocity;
  603. protected PhysicsVector _size;
  604. protected PhysicsVector _acceleration;
  605. protected AxiomQuaternion _orientation;
  606. protected PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
  607. protected RigidBody rigidBody;
  608. protected int m_PhysicsActorType;
  609. private Boolean iscolliding = false;
  610. internal string _name;
  611. public BulletXActor(String name)
  612. {
  613. _name = name;
  614. }
  615. public override bool Stopped
  616. {
  617. get { return false; }
  618. }
  619. public override PhysicsVector Position
  620. {
  621. get { return _position; }
  622. set
  623. {
  624. lock (BulletXScene.BulletXLock)
  625. {
  626. _position = value;
  627. Translate();
  628. }
  629. }
  630. }
  631. public override PhysicsVector RotationalVelocity
  632. {
  633. get { return m_rotationalVelocity; }
  634. set { m_rotationalVelocity = value; }
  635. }
  636. public override PhysicsVector Velocity
  637. {
  638. get { return _velocity; }
  639. set
  640. {
  641. lock (BulletXScene.BulletXLock)
  642. {
  643. //Static objects don' have linear velocity
  644. if (_physical)
  645. {
  646. _velocity = value;
  647. Speed();
  648. }
  649. else
  650. {
  651. _velocity = new PhysicsVector();
  652. }
  653. }
  654. }
  655. }
  656. public override float CollisionScore
  657. {
  658. get { return 0f; }
  659. }
  660. public override PhysicsVector Size
  661. {
  662. get { return _size; }
  663. set
  664. {
  665. lock (BulletXScene.BulletXLock)
  666. {
  667. _size = value;
  668. }
  669. }
  670. }
  671. public override PhysicsVector Force
  672. {
  673. get { return PhysicsVector.Zero; }
  674. }
  675. public override PhysicsVector CenterOfMass
  676. {
  677. get { return PhysicsVector.Zero; }
  678. }
  679. public override PhysicsVector GeometricCenter
  680. {
  681. get { return PhysicsVector.Zero; }
  682. }
  683. public override PrimitiveBaseShape Shape
  684. {
  685. set { return; }
  686. }
  687. public override bool SetAlwaysRun
  688. {
  689. get { return false; }
  690. set { return; }
  691. }
  692. public override PhysicsVector Acceleration
  693. {
  694. get { return _acceleration; }
  695. }
  696. public override AxiomQuaternion Orientation
  697. {
  698. get { return _orientation; }
  699. set
  700. {
  701. lock (BulletXScene.BulletXLock)
  702. {
  703. _orientation = value;
  704. ReOrient();
  705. }
  706. }
  707. }
  708. public override void link(PhysicsActor obj)
  709. {
  710. }
  711. public override void delink()
  712. {
  713. }
  714. public override void LockAngularMotion(PhysicsVector axis)
  715. {
  716. }
  717. public override float Mass
  718. {
  719. get { return ActorMass; }
  720. }
  721. public virtual float ActorMass
  722. {
  723. get { return 0; }
  724. }
  725. public override int PhysicsActorType
  726. {
  727. get { return (int) m_PhysicsActorType; }
  728. set { m_PhysicsActorType = value; }
  729. }
  730. public RigidBody RigidBody
  731. {
  732. get { return rigidBody; }
  733. }
  734. public Vector3 RigidBodyPosition
  735. {
  736. get { return rigidBody.CenterOfMassPosition; }
  737. }
  738. public override bool IsPhysical
  739. {
  740. get { return _physical; }
  741. set { _physical = value; }
  742. }
  743. public override bool Flying
  744. {
  745. get { return flying; }
  746. set { flying = value; }
  747. }
  748. public override bool ThrottleUpdates
  749. {
  750. get { return false; }
  751. set { return; }
  752. }
  753. public override bool IsColliding
  754. {
  755. get { return iscolliding; }
  756. set { iscolliding = value; }
  757. }
  758. public override bool CollidingGround
  759. {
  760. get { return false; }
  761. set { return; }
  762. }
  763. public override bool CollidingObj
  764. {
  765. get { return false; }
  766. set { return; }
  767. }
  768. public override uint LocalID
  769. {
  770. set { return; }
  771. }
  772. public override bool Grabbed
  773. {
  774. set { return; }
  775. }
  776. public override bool Selected
  777. {
  778. set { return; }
  779. }
  780. public override float Buoyancy
  781. {
  782. get { return 0f; }
  783. set { return; }
  784. }
  785. public override bool FloatOnWater
  786. {
  787. set { return; }
  788. }
  789. public virtual void SetAcceleration(PhysicsVector accel)
  790. {
  791. lock (BulletXScene.BulletXLock)
  792. {
  793. _acceleration = accel;
  794. }
  795. }
  796. public override bool Kinematic
  797. {
  798. get { return false; }
  799. set { }
  800. }
  801. public override void AddForce(PhysicsVector force)
  802. {
  803. }
  804. public override void SetMomentum(PhysicsVector momentum)
  805. {
  806. }
  807. internal virtual void ValidateHeight(float heighmapPositionValue)
  808. {
  809. }
  810. internal virtual void UpdateKinetics()
  811. {
  812. }
  813. #region Methods for updating values of RigidBody
  814. protected internal void Translate()
  815. {
  816. Translate(_position);
  817. }
  818. protected internal void Translate(PhysicsVector _newPos)
  819. {
  820. Vector3 _translation;
  821. _translation = BulletXMaths.PhysicsVectorToXnaVector3(_newPos) - rigidBody.CenterOfMassPosition;
  822. rigidBody.Translate(_translation);
  823. }
  824. protected internal void Speed()
  825. {
  826. Speed(_velocity);
  827. }
  828. protected internal void Speed(PhysicsVector _newSpeed)
  829. {
  830. Vector3 _speed;
  831. _speed = BulletXMaths.PhysicsVectorToXnaVector3(_newSpeed);
  832. rigidBody.LinearVelocity = _speed;
  833. }
  834. protected internal void ReOrient()
  835. {
  836. ReOrient(_orientation);
  837. }
  838. protected internal void ReOrient(AxiomQuaternion _newOrient)
  839. {
  840. Quaternion _newOrientation;
  841. _newOrientation = BulletXMaths.AxiomQuaternionToXnaQuaternion(_newOrient);
  842. Matrix _comTransform = rigidBody.CenterOfMassTransform;
  843. BulletXMaths.SetRotation(ref _comTransform, _newOrientation);
  844. rigidBody.CenterOfMassTransform = _comTransform;
  845. }
  846. protected internal void ReSize()
  847. {
  848. ReSize(_size);
  849. }
  850. protected internal virtual void ReSize(PhysicsVector _newSize)
  851. {
  852. }
  853. public virtual void ScheduleTerseUpdate()
  854. {
  855. base.RequestPhysicsterseUpdate();
  856. }
  857. #endregion
  858. public override void CrossingFailure()
  859. {
  860. }
  861. public override PhysicsVector PIDTarget { set { return; } }
  862. public override bool PIDActive { set { return; } }
  863. public override float PIDTau { set { return; } }
  864. }
  865. /// <summary>
  866. /// PhysicsActor Character Class for BulletX
  867. /// </summary>
  868. public class BulletXCharacter : BulletXActor
  869. {
  870. public BulletXCharacter(BulletXScene parent_scene, PhysicsVector pos)
  871. : this(String.Empty, parent_scene, pos)
  872. {
  873. }
  874. public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos)
  875. : this(avName, parent_scene, pos, new PhysicsVector(), new PhysicsVector(), new PhysicsVector(),
  876. AxiomQuaternion.Identity)
  877. {
  878. }
  879. public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
  880. PhysicsVector size, PhysicsVector acceleration, AxiomQuaternion orientation)
  881. : base(avName)
  882. {
  883. //This fields will be removed. They're temporal
  884. float _sizeX = 0.5f;
  885. float _sizeY = 0.5f;
  886. float _sizeZ = 1.6f;
  887. //.
  888. _position = pos;
  889. _velocity = velocity;
  890. _size = size;
  891. //---
  892. _size.X = _sizeX;
  893. _size.Y = _sizeY;
  894. _size.Z = _sizeZ;
  895. //.
  896. _acceleration = acceleration;
  897. _orientation = orientation;
  898. _physical = true;
  899. float _mass = 50.0f; //This depends of avatar's dimensions
  900. //For RigidBody Constructor. The next values might change
  901. float _linearDamping = 0.0f;
  902. float _angularDamping = 0.0f;
  903. float _friction = 0.5f;
  904. float _restitution = 0.0f;
  905. Matrix _startTransform = Matrix.Identity;
  906. Matrix _centerOfMassOffset = Matrix.Identity;
  907. lock (BulletXScene.BulletXLock)
  908. {
  909. _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
  910. //CollisionShape _collisionShape = new BoxShape(new MonoXnaCompactMaths.Vector3(1.0f, 1.0f, 1.60f));
  911. //For now, like ODE, collisionShape = sphere of radious = 1.0
  912. CollisionShape _collisionShape = new SphereShape(1.0f);
  913. DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
  914. Vector3 _localInertia = new Vector3();
  915. _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
  916. rigidBody =
  917. new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
  918. _friction, _restitution);
  919. //rigidBody.ActivationState = ActivationState.DisableDeactivation;
  920. //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
  921. Vector3 _vDebugTranslation;
  922. _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
  923. rigidBody.Translate(_vDebugTranslation);
  924. parent_scene.ddWorld.AddRigidBody(rigidBody);
  925. }
  926. }
  927. public override int PhysicsActorType
  928. {
  929. get { return (int) ActorTypes.Agent; }
  930. set { return; }
  931. }
  932. public override PhysicsVector Position
  933. {
  934. get { return base.Position; }
  935. set { base.Position = value; }
  936. }
  937. public override PhysicsVector Velocity
  938. {
  939. get { return base.Velocity; }
  940. set { base.Velocity = value; }
  941. }
  942. public override PhysicsVector Size
  943. {
  944. get { return base.Size; }
  945. set { base.Size = value; }
  946. }
  947. public override PhysicsVector Acceleration
  948. {
  949. get { return base.Acceleration; }
  950. }
  951. public override AxiomQuaternion Orientation
  952. {
  953. get { return base.Orientation; }
  954. set { base.Orientation = value; }
  955. }
  956. public override bool Flying
  957. {
  958. get { return base.Flying; }
  959. set { base.Flying = value; }
  960. }
  961. public override bool IsColliding
  962. {
  963. get { return base.IsColliding; }
  964. set { base.IsColliding = value; }
  965. }
  966. public override bool Kinematic
  967. {
  968. get { return base.Kinematic; }
  969. set { base.Kinematic = value; }
  970. }
  971. public override void SetAcceleration(PhysicsVector accel)
  972. {
  973. base.SetAcceleration(accel);
  974. }
  975. public override void AddForce(PhysicsVector force)
  976. {
  977. base.AddForce(force);
  978. }
  979. public override void SetMomentum(PhysicsVector momentum)
  980. {
  981. base.SetMomentum(momentum);
  982. }
  983. internal void Move(float timeStep)
  984. {
  985. Vector3 vec = new Vector3();
  986. //At this point it's supossed that:
  987. //_velocity == rigidBody.LinearVelocity
  988. vec.X = _velocity.X;
  989. vec.Y = _velocity.Y;
  990. vec.Z = _velocity.Z;
  991. if ((vec.X != 0.0f) || (vec.Y != 0.0f) || (vec.Z != 0.0f)) rigidBody.Activate();
  992. if (flying)
  993. {
  994. //Antigravity with movement
  995. if (_position.Z <= BulletXScene.HeightLevel0)
  996. {
  997. vec.Z += BulletXScene.Gravity*timeStep;
  998. }
  999. //Lowgravity with movement
  1000. else if ((_position.Z > BulletXScene.HeightLevel0)
  1001. && (_position.Z <= BulletXScene.HeightLevel1))
  1002. {
  1003. vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
  1004. }
  1005. //Lowgravity with...
  1006. else if (_position.Z > BulletXScene.HeightLevel1)
  1007. {
  1008. if (vec.Z > 0) //no movement
  1009. vec.Z = BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
  1010. else
  1011. vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
  1012. }
  1013. }
  1014. rigidBody.LinearVelocity = vec;
  1015. }
  1016. //This validation is very basic
  1017. internal override void ValidateHeight(float heighmapPositionValue)
  1018. {
  1019. if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
  1020. {
  1021. Matrix m = rigidBody.WorldTransform;
  1022. Vector3 v3 = m.Translation;
  1023. v3.Z = heighmapPositionValue + _size.Z/2.0f;
  1024. m.Translation = v3;
  1025. rigidBody.WorldTransform = m;
  1026. //When an Avie touch the ground it's vertical velocity it's reduced to ZERO
  1027. Speed(new PhysicsVector(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
  1028. }
  1029. }
  1030. internal override void UpdateKinetics()
  1031. {
  1032. _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
  1033. _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
  1034. //Orientation it seems that it will be the default.
  1035. ReOrient();
  1036. }
  1037. }
  1038. /// <summary>
  1039. /// PhysicsActor Prim Class for BulletX
  1040. /// </summary>
  1041. public class BulletXPrim : BulletXActor
  1042. {
  1043. //Density it will depends of material.
  1044. //For now all prims have the same density, all prims are made of water. Be water my friend! :D
  1045. private const float _density = 1000.0f;
  1046. private BulletXScene _parent_scene;
  1047. private PhysicsVector m_prev_position = new PhysicsVector(0, 0, 0);
  1048. private bool m_lastUpdateSent = false;
  1049. public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size,
  1050. AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
  1051. : this(
  1052. primName, parent_scene, pos, new PhysicsVector(), size, new PhysicsVector(), rotation, mesh, pbs,
  1053. isPhysical)
  1054. {
  1055. }
  1056. public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
  1057. PhysicsVector size,
  1058. PhysicsVector acceleration, AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs,
  1059. bool isPhysical)
  1060. : base(primName)
  1061. {
  1062. if ((size.X == 0) || (size.Y == 0) || (size.Z == 0)) throw new Exception("Size 0");
  1063. if (rotation.Norm == 0f) rotation = AxiomQuaternion.Identity;
  1064. _position = pos;
  1065. _physical = isPhysical;
  1066. _velocity = _physical ? velocity : new PhysicsVector();
  1067. _size = size;
  1068. _acceleration = acceleration;
  1069. _orientation = rotation;
  1070. _parent_scene = parent_scene;
  1071. CreateRigidBody(parent_scene, mesh, pos, size);
  1072. }
  1073. public override int PhysicsActorType
  1074. {
  1075. get { return (int) ActorTypes.Prim; }
  1076. set { return; }
  1077. }
  1078. public override PhysicsVector Position
  1079. {
  1080. get { return base.Position; }
  1081. set { base.Position = value; }
  1082. }
  1083. public override PhysicsVector Velocity
  1084. {
  1085. get { return base.Velocity; }
  1086. set { base.Velocity = value; }
  1087. }
  1088. public override PhysicsVector Size
  1089. {
  1090. get { return _size; }
  1091. set
  1092. {
  1093. lock (BulletXScene.BulletXLock)
  1094. {
  1095. _size = value;
  1096. ReSize();
  1097. }
  1098. }
  1099. }
  1100. public override PhysicsVector Acceleration
  1101. {
  1102. get { return base.Acceleration; }
  1103. }
  1104. public override AxiomQuaternion Orientation
  1105. {
  1106. get { return base.Orientation; }
  1107. set { base.Orientation = value; }
  1108. }
  1109. public override float ActorMass
  1110. {
  1111. get
  1112. {
  1113. //For now all prims are boxes
  1114. return (_physical ? 1 : 0)*_density*_size.X*_size.Y*_size.Z;
  1115. }
  1116. }
  1117. public override bool IsPhysical
  1118. {
  1119. get { return base.IsPhysical; }
  1120. set
  1121. {
  1122. base.IsPhysical = value;
  1123. if (value)
  1124. {
  1125. //---
  1126. PhysicsPluginManager.PhysicsPluginMessage("Physical - Recreate", true);
  1127. //---
  1128. ReCreateRigidBody(_size);
  1129. }
  1130. else
  1131. {
  1132. //---
  1133. PhysicsPluginManager.PhysicsPluginMessage("Physical - SetMassProps", true);
  1134. //---
  1135. rigidBody.SetMassProps(Mass, new Vector3());
  1136. }
  1137. }
  1138. }
  1139. public override bool Flying
  1140. {
  1141. get { return base.Flying; }
  1142. set { base.Flying = value; }
  1143. }
  1144. public override bool IsColliding
  1145. {
  1146. get { return base.IsColliding; }
  1147. set { base.IsColliding = value; }
  1148. }
  1149. public override bool Kinematic
  1150. {
  1151. get { return base.Kinematic; }
  1152. set { base.Kinematic = value; }
  1153. }
  1154. public override void SetAcceleration(PhysicsVector accel)
  1155. {
  1156. lock (BulletXScene.BulletXLock)
  1157. {
  1158. _acceleration = accel;
  1159. }
  1160. }
  1161. public override void AddForce(PhysicsVector force)
  1162. {
  1163. base.AddForce(force);
  1164. }
  1165. public override void SetMomentum(PhysicsVector momentum)
  1166. {
  1167. base.SetMomentum(momentum);
  1168. }
  1169. internal override void ValidateHeight(float heighmapPositionValue)
  1170. {
  1171. if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
  1172. {
  1173. Matrix m = rigidBody.WorldTransform;
  1174. Vector3 v3 = m.Translation;
  1175. v3.Z = heighmapPositionValue + _size.Z/2.0f;
  1176. m.Translation = v3;
  1177. rigidBody.WorldTransform = m;
  1178. //When a Prim touch the ground it's vertical velocity it's reduced to ZERO
  1179. //Static objects don't have linear velocity
  1180. if (_physical)
  1181. Speed(new PhysicsVector(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
  1182. }
  1183. }
  1184. internal override void UpdateKinetics()
  1185. {
  1186. if (_physical) //Updates properties. Prim updates its properties physically
  1187. {
  1188. _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
  1189. _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
  1190. _orientation = BulletXMaths.XnaQuaternionToAxiomQuaternion(rigidBody.Orientation);
  1191. if ((Math.Abs(m_prev_position.X - _position.X) < 0.03)
  1192. && (Math.Abs(m_prev_position.Y - _position.Y) < 0.03)
  1193. && (Math.Abs(m_prev_position.Z - _position.Z) < 0.03))
  1194. {
  1195. if (!m_lastUpdateSent)
  1196. {
  1197. _velocity = new PhysicsVector(0, 0, 0);
  1198. base.ScheduleTerseUpdate();
  1199. m_lastUpdateSent = true;
  1200. }
  1201. }
  1202. else
  1203. {
  1204. m_lastUpdateSent = false;
  1205. base.ScheduleTerseUpdate();
  1206. }
  1207. m_prev_position = _position;
  1208. }
  1209. else //Doesn't updates properties. That's a cancel
  1210. {
  1211. Translate();
  1212. //Speed(); //<- Static objects don't have linear velocity
  1213. ReOrient();
  1214. }
  1215. }
  1216. #region Methods for updating values of RigidBody
  1217. protected internal void CreateRigidBody(BulletXScene parent_scene, IMesh mesh, PhysicsVector pos,
  1218. PhysicsVector size)
  1219. {
  1220. //For RigidBody Constructor. The next values might change
  1221. float _linearDamping = 0.0f;
  1222. float _angularDamping = 0.0f;
  1223. float _friction = 1.0f;
  1224. float _restitution = 0.0f;
  1225. Matrix _startTransform = Matrix.Identity;
  1226. Matrix _centerOfMassOffset = Matrix.Identity;
  1227. lock (BulletXScene.BulletXLock)
  1228. {
  1229. _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
  1230. //For now all prims are boxes
  1231. CollisionShape _collisionShape;
  1232. if (mesh == null)
  1233. {
  1234. _collisionShape = new BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size)/2.0f);
  1235. }
  1236. else
  1237. {
  1238. int iVertexCount = mesh.getVertexList().Count;
  1239. int[] indices = mesh.getIndexListAsInt();
  1240. Vector3[] v3Vertices = new Vector3[iVertexCount];
  1241. for (int i = 0; i < iVertexCount; i++)
  1242. {
  1243. PhysicsVector v = mesh.getVertexList()[i];
  1244. if (v != null) // Note, null has special meaning. See meshing code for details
  1245. v3Vertices[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
  1246. else
  1247. v3Vertices[i] = Vector3.Zero;
  1248. }
  1249. TriangleIndexVertexArray triMesh = new TriangleIndexVertexArray(indices, v3Vertices);
  1250. _collisionShape = new TriangleMeshShape(triMesh);
  1251. }
  1252. DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
  1253. Vector3 _localInertia = new Vector3();
  1254. if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0
  1255. rigidBody =
  1256. new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
  1257. _friction, _restitution);
  1258. //rigidBody.ActivationState = ActivationState.DisableDeactivation;
  1259. //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
  1260. Vector3 _vDebugTranslation;
  1261. _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
  1262. rigidBody.Translate(_vDebugTranslation);
  1263. //---
  1264. parent_scene.ddWorld.AddRigidBody(rigidBody);
  1265. }
  1266. }
  1267. protected internal void ReCreateRigidBody(PhysicsVector size)
  1268. {
  1269. //There is a bug when trying to remove a rigidBody that is colliding with something..
  1270. try
  1271. {
  1272. _parent_scene.ddWorld.RemoveRigidBody(rigidBody);
  1273. }
  1274. catch (Exception ex)
  1275. {
  1276. BulletXScene.BulletXMessage(_parent_scene.is_ex_message + ex.Message, true);
  1277. rigidBody.ActivationState = ActivationState.DisableSimulation;
  1278. _parent_scene.AddForgottenRigidBody(rigidBody);
  1279. }
  1280. CreateRigidBody(_parent_scene, null, _position, size);
  1281. // Note, null for the meshing definitely is wrong. It's here for the moment to apease the compiler
  1282. if (_physical) Speed(); //Static objects don't have linear velocity
  1283. ReOrient();
  1284. GC.Collect();
  1285. }
  1286. protected internal override void ReSize(PhysicsVector _newSize)
  1287. {
  1288. //I wonder to know how to resize with a simple instruction in BulletX. It seems that for now there isn't
  1289. //so i have to do it manually. That's recreating rigidbody
  1290. ReCreateRigidBody(_newSize);
  1291. }
  1292. #endregion
  1293. }
  1294. /// <summary>
  1295. /// This Class manage a HeighField as a RigidBody. This is for to be added in the BulletXScene
  1296. /// </summary>
  1297. internal class BulletXPlanet
  1298. {
  1299. private PhysicsVector _staticPosition;
  1300. // private PhysicsVector _staticVelocity;
  1301. // private AxiomQuaternion _staticOrientation;
  1302. private float _mass;
  1303. private BulletXScene _parentscene;
  1304. internal float[] _heightField;
  1305. private RigidBody _flatPlanet;
  1306. internal RigidBody RigidBody
  1307. {
  1308. get { return _flatPlanet; }
  1309. }
  1310. internal BulletXPlanet(BulletXScene parent_scene, float[] heightField)
  1311. {
  1312. _staticPosition = new PhysicsVector(BulletXScene.MaxXY/2, BulletXScene.MaxXY/2, 0);
  1313. // _staticVelocity = new PhysicsVector();
  1314. // _staticOrientation = AxiomQuaternion.Identity;
  1315. _mass = 0; //No active
  1316. _parentscene = parent_scene;
  1317. _heightField = heightField;
  1318. float _linearDamping = 0.0f;
  1319. float _angularDamping = 0.0f;
  1320. float _friction = 0.5f;
  1321. float _restitution = 0.0f;
  1322. Matrix _startTransform = Matrix.Identity;
  1323. Matrix _centerOfMassOffset = Matrix.Identity;
  1324. lock (BulletXScene.BulletXLock)
  1325. {
  1326. try
  1327. {
  1328. _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(_staticPosition);
  1329. CollisionShape _collisionShape =
  1330. new HeightfieldTerrainShape(BulletXScene.MaxXY, BulletXScene.MaxXY, _heightField,
  1331. (float) BulletXScene.MaxZ, 2, true, false);
  1332. DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
  1333. Vector3 _localInertia = new Vector3();
  1334. //_collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
  1335. _flatPlanet =
  1336. new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping,
  1337. _angularDamping, _friction, _restitution);
  1338. //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
  1339. Vector3 _vDebugTranslation;
  1340. _vDebugTranslation = _startTransform.Translation - _flatPlanet.CenterOfMassPosition;
  1341. _flatPlanet.Translate(_vDebugTranslation);
  1342. parent_scene.ddWorld.AddRigidBody(_flatPlanet);
  1343. }
  1344. catch (Exception ex)
  1345. {
  1346. BulletXScene.BulletXMessage(ex.Message, true);
  1347. }
  1348. }
  1349. BulletXScene.BulletXMessage("BulletXPlanet created.", false);
  1350. }
  1351. internal float HeightValue(Vector3 position)
  1352. {
  1353. int li_x, li_y;
  1354. float height;
  1355. li_x = (int) Math.Round(position.X);
  1356. if (li_x < 0) li_x = 0;
  1357. if (li_x >= BulletXScene.MaxXY) li_x = BulletXScene.MaxXY - 1;
  1358. li_y = (int) Math.Round(position.Y);
  1359. if (li_y < 0) li_y = 0;
  1360. if (li_y >= BulletXScene.MaxXY) li_y = BulletXScene.MaxXY - 1;
  1361. height = ((HeightfieldTerrainShape) _flatPlanet.CollisionShape).getHeightFieldValue(li_x, li_y);
  1362. if (height < 0) height = 0;
  1363. else if (height > BulletXScene.MaxZ) height = BulletXScene.MaxZ;
  1364. return height;
  1365. }
  1366. }
  1367. }