diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs | 534 |
1 files changed, 534 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs new file mode 100644 index 0000000..1ca5efe --- /dev/null +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs | |||
@@ -0,0 +1,534 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | #region References | ||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using OpenSim.Physics.Manager; | ||
32 | using Axiom.Math; | ||
33 | //Specific References for BulletXPlugin | ||
34 | using MonoXnaCompactMaths; | ||
35 | using XnaDevRu.BulletX; | ||
36 | using XnaDevRu.BulletX.Dynamics; | ||
37 | #endregion | ||
38 | |||
39 | namespace OpenSim.Region.Physics.BulletXPlugin | ||
40 | { | ||
41 | /// <summary> | ||
42 | /// This Class converts objects and types for BulletX | ||
43 | /// </summary> | ||
44 | public class BulletXConversions | ||
45 | { | ||
46 | public static MonoXnaCompactMaths.Vector3 PhysicsVectorToXnaVector3(PhysicsVector physicsVector) | ||
47 | { | ||
48 | return new MonoXnaCompactMaths.Vector3(physicsVector.X, physicsVector.Y, physicsVector.Z); | ||
49 | } | ||
50 | public static void PhysicsVectorToXnaVector3(PhysicsVector physicsVector, out MonoXnaCompactMaths.Vector3 XnaVector3) | ||
51 | { | ||
52 | XnaVector3.X = physicsVector.X; | ||
53 | XnaVector3.Y = physicsVector.Y; | ||
54 | XnaVector3.Z = physicsVector.Z; | ||
55 | } | ||
56 | public static PhysicsVector XnaVector3ToPhysicsVector(MonoXnaCompactMaths.Vector3 xnaVector3) | ||
57 | { | ||
58 | return new PhysicsVector(xnaVector3.X, xnaVector3.Y, xnaVector3.Z); | ||
59 | } | ||
60 | /*public static void XnaVector3ToPhysicsVector(MonoXnaCompactMaths.Vector3 xnaVector3, out PhysicsVector physicsVector) | ||
61 | { | ||
62 | xnaVector3.X = physicsVector.X; | ||
63 | xnaVector3.Y = physicsVector.Y; | ||
64 | xnaVector3.Z = physicsVector.Z; | ||
65 | }*/ | ||
66 | #region Axiom and Xna | ||
67 | ///// <summary> | ||
68 | ///// BTW maybe some conversions will be a simply converion that it doesn't require this class, but i don't know | ||
69 | ///// </summary> | ||
70 | ///// <param name="AxiomVector3"></param> | ||
71 | ///// <returns></returns> | ||
72 | //public static MonoXnaCompactMaths.Vector3 Vector3AxiomToXna(Axiom.Math.Vector3 AxiomVector3) | ||
73 | //{ | ||
74 | // return new MonoXnaCompactMaths.Vector3(AxiomVector3.x, AxiomVector3.y, AxiomVector3.z); | ||
75 | //} | ||
76 | #endregion | ||
77 | } | ||
78 | /// <summary> | ||
79 | /// PhysicsPlugin Class for BulletX | ||
80 | /// </summary> | ||
81 | public class BulletXPlugin : IPhysicsPlugin | ||
82 | { | ||
83 | private BulletXScene _mScene; | ||
84 | |||
85 | public BulletXPlugin() | ||
86 | { | ||
87 | } | ||
88 | public bool Init() | ||
89 | { | ||
90 | return true; | ||
91 | } | ||
92 | public PhysicsScene GetScene() | ||
93 | { | ||
94 | if (_mScene == null) | ||
95 | { | ||
96 | _mScene = new BulletXScene(); | ||
97 | } | ||
98 | return (_mScene); | ||
99 | } | ||
100 | public string GetName() | ||
101 | { | ||
102 | return ("BulletXEngine"); | ||
103 | } | ||
104 | public void Dispose() | ||
105 | { | ||
106 | } | ||
107 | } | ||
108 | /// <summary> | ||
109 | /// PhysicsScene Class for BulletX | ||
110 | /// </summary> | ||
111 | public class BulletXScene : PhysicsScene | ||
112 | { | ||
113 | public DiscreteDynamicsWorld ddWorld; | ||
114 | private CollisionDispatcher cDispatcher; | ||
115 | private OverlappingPairCache opCache; | ||
116 | private SequentialImpulseConstraintSolver sicSolver; | ||
117 | |||
118 | private const int minXY = 0; | ||
119 | private const int minZ = 0; | ||
120 | private const int maxXY = 256; | ||
121 | private const int maxZ = 4096; | ||
122 | private const int maxHandles = 32766; //Why? I don't know | ||
123 | private static float gravity = 9.8f; | ||
124 | private static float heightLevel0 = 77.0f; | ||
125 | private static float heightLevel1 = 200.0f; | ||
126 | private static float lowGravityFactor = 0.2f; | ||
127 | |||
128 | private float[] _heightmap; | ||
129 | private List<BulletXCharacter> _characters = new List<BulletXCharacter>(); | ||
130 | |||
131 | public static float Gravity { get { return gravity; } } | ||
132 | public static float HeightLevel0 { get { return heightLevel0; } } | ||
133 | public static float HeightLevel1 { get { return heightLevel1; } } | ||
134 | public static float LowGravityFactor { get { return lowGravityFactor; } } | ||
135 | |||
136 | public BulletXScene() | ||
137 | { | ||
138 | cDispatcher = new CollisionDispatcher(); | ||
139 | MonoXnaCompactMaths.Vector3 worldMinDim = new MonoXnaCompactMaths.Vector3((float)minXY, (float)minXY, (float)minZ); | ||
140 | MonoXnaCompactMaths.Vector3 worldMaxDim = new MonoXnaCompactMaths.Vector3((float)maxXY, (float)maxXY, (float)maxZ); | ||
141 | opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles); | ||
142 | sicSolver = new SequentialImpulseConstraintSolver(); | ||
143 | |||
144 | ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver); | ||
145 | ddWorld.Gravity = new MonoXnaCompactMaths.Vector3(0, 0, -gravity); | ||
146 | |||
147 | this._heightmap = new float[65536]; | ||
148 | } | ||
149 | |||
150 | public override PhysicsActor AddAvatar(PhysicsVector position) | ||
151 | { | ||
152 | PhysicsVector pos = new PhysicsVector(); | ||
153 | pos.X = position.X; | ||
154 | pos.Y = position.Y; | ||
155 | pos.Z = position.Z + 20; | ||
156 | BulletXCharacter newAv = new BulletXCharacter(this, pos); | ||
157 | this._characters.Add(newAv); | ||
158 | return newAv; | ||
159 | } | ||
160 | |||
161 | public override void RemoveAvatar(PhysicsActor actor) | ||
162 | { | ||
163 | |||
164 | } | ||
165 | |||
166 | public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size) | ||
167 | { | ||
168 | PhysicsVector pos = new PhysicsVector(); | ||
169 | pos.X = position.X; | ||
170 | pos.Y = position.Y; | ||
171 | pos.Z = position.Z; | ||
172 | PhysicsVector siz = new PhysicsVector(); | ||
173 | siz.X = size.X; | ||
174 | siz.Y = size.Y; | ||
175 | siz.Z = size.Z; | ||
176 | return new BulletXPrim(); | ||
177 | } | ||
178 | |||
179 | public override void Simulate(float timeStep) | ||
180 | { | ||
181 | foreach (BulletXCharacter actor in _characters) | ||
182 | { | ||
183 | actor.Move(timeStep); | ||
184 | |||
185 | } | ||
186 | ddWorld.StepSimulation(timeStep, 0, timeStep); | ||
187 | foreach (BulletXCharacter actor in _characters) | ||
188 | { | ||
189 | actor.ValidateHeight(this._heightmap[ | ||
190 | (int)Math.Round(actor.RigidBodyHorizontalPosition.x) * 256 | ||
191 | + (int)Math.Round(actor.RigidBodyHorizontalPosition.y)]); | ||
192 | } | ||
193 | foreach (BulletXCharacter actor in _characters) | ||
194 | { | ||
195 | actor.UpdatePosition(); | ||
196 | } | ||
197 | |||
198 | } | ||
199 | |||
200 | public override void GetResults() | ||
201 | { | ||
202 | |||
203 | } | ||
204 | |||
205 | public override bool IsThreaded | ||
206 | { | ||
207 | get | ||
208 | { | ||
209 | return (false); // for now we won't be multithreaded | ||
210 | } | ||
211 | } | ||
212 | |||
213 | public override void SetTerrain(float[] heightMap) | ||
214 | { | ||
215 | //As the same as ODE, heightmap (x,y) must be swapped for BulletX | ||
216 | for (int i = 0; i < 65536; i++) | ||
217 | { | ||
218 | // this._heightmap[i] = (double)heightMap[i]; | ||
219 | // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...) | ||
220 | int x = i & 0xff; | ||
221 | int y = i >> 8; | ||
222 | this._heightmap[i] = heightMap[x * 256 + y]; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | public override void DeleteTerrain() | ||
227 | { | ||
228 | |||
229 | } | ||
230 | } | ||
231 | /// <summary> | ||
232 | /// PhysicsActor Character Class for BulletX | ||
233 | /// </summary> | ||
234 | public class BulletXCharacter : PhysicsActor | ||
235 | { | ||
236 | private PhysicsVector _position; | ||
237 | private PhysicsVector _velocity; | ||
238 | private PhysicsVector _acceleration; | ||
239 | private bool flying; | ||
240 | private RigidBody rigidBody; | ||
241 | public Axiom.Math.Vector2 RigidBodyHorizontalPosition | ||
242 | { | ||
243 | get | ||
244 | { | ||
245 | return new Axiom.Math.Vector2(this.rigidBody.CenterOfMassPosition.X, this.rigidBody.CenterOfMassPosition.Y); | ||
246 | } | ||
247 | } | ||
248 | public BulletXCharacter(BulletXScene parent_scene, PhysicsVector pos) | ||
249 | { | ||
250 | _velocity = new PhysicsVector(); | ||
251 | _position = pos; | ||
252 | _acceleration = new PhysicsVector(); | ||
253 | float _mass = 50.0f; //This depends of avatar's dimensions | ||
254 | Matrix _startTransform = Matrix.Identity; | ||
255 | _startTransform.Translation = BulletXConversions.PhysicsVectorToXnaVector3(pos); | ||
256 | Matrix _centerOfMassOffset = Matrix.Identity; | ||
257 | CollisionShape _collisionShape = new BoxShape(new MonoXnaCompactMaths.Vector3(0.5f, 0.5f, 1.60f)); | ||
258 | DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset); | ||
259 | MonoXnaCompactMaths.Vector3 _localInertia = new MonoXnaCompactMaths.Vector3(); | ||
260 | _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0 | ||
261 | |||
262 | //The next values might change | ||
263 | float _linearDamping = 0.0f; | ||
264 | float _angularDamping = 0.0f; | ||
265 | float _friction = 0.5f; | ||
266 | float _restitution = 0.0f; | ||
267 | |||
268 | rigidBody = new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution); | ||
269 | rigidBody.ActivationState = ActivationState.DisableDeactivation; | ||
270 | |||
271 | parent_scene.ddWorld.AddRigidBody(rigidBody); | ||
272 | } | ||
273 | |||
274 | public override bool Flying | ||
275 | { | ||
276 | get | ||
277 | { | ||
278 | return flying; | ||
279 | } | ||
280 | set | ||
281 | { | ||
282 | flying = value; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | public override PhysicsVector Position | ||
287 | { | ||
288 | get | ||
289 | { | ||
290 | return _position; | ||
291 | } | ||
292 | set | ||
293 | { | ||
294 | _position = value; | ||
295 | } | ||
296 | } | ||
297 | |||
298 | public override PhysicsVector Velocity | ||
299 | { | ||
300 | get | ||
301 | { | ||
302 | return _velocity; | ||
303 | } | ||
304 | set | ||
305 | { | ||
306 | _velocity = value; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | public override bool Kinematic | ||
311 | { | ||
312 | get | ||
313 | { | ||
314 | return false; | ||
315 | } | ||
316 | set | ||
317 | { | ||
318 | |||
319 | } | ||
320 | } | ||
321 | |||
322 | public override Axiom.Math.Quaternion Orientation | ||
323 | { | ||
324 | get | ||
325 | { | ||
326 | return Axiom.Math.Quaternion.Identity; | ||
327 | } | ||
328 | set | ||
329 | { | ||
330 | |||
331 | } | ||
332 | } | ||
333 | |||
334 | public override PhysicsVector Acceleration | ||
335 | { | ||
336 | get | ||
337 | { | ||
338 | return _acceleration; | ||
339 | } | ||
340 | |||
341 | } | ||
342 | public void SetAcceleration(PhysicsVector accel) | ||
343 | { | ||
344 | this._acceleration = accel; | ||
345 | } | ||
346 | |||
347 | public override void AddForce(PhysicsVector force) | ||
348 | { | ||
349 | |||
350 | } | ||
351 | |||
352 | public override void SetMomentum(PhysicsVector momentum) | ||
353 | { | ||
354 | |||
355 | } | ||
356 | |||
357 | public void Move(float timeStep) | ||
358 | { | ||
359 | MonoXnaCompactMaths.Vector3 vec = new MonoXnaCompactMaths.Vector3(); | ||
360 | //if (this._velocity.X == 0.0f) | ||
361 | // vec.X = this.rigidBody.LinearVelocity.X; //current velocity | ||
362 | //else | ||
363 | vec.X = this._velocity.X; //overrides current velocity | ||
364 | |||
365 | //if (this._velocity.Y == 0.0f) | ||
366 | // vec.Y = this.rigidBody.LinearVelocity.Y; //current velocity | ||
367 | //else | ||
368 | vec.Y = this._velocity.Y; //overrides current velocity | ||
369 | |||
370 | float nextZVelocity; | ||
371 | //if (this._velocity.Z == 0.0f) | ||
372 | // nextZVelocity = this.rigidBody.LinearVelocity.Z; //current velocity | ||
373 | //else | ||
374 | nextZVelocity = this._velocity.Z; //overrides current velocity | ||
375 | |||
376 | if (flying) | ||
377 | { | ||
378 | //Antigravity with movement | ||
379 | if (this._position.Z <= BulletXScene.HeightLevel0) | ||
380 | { | ||
381 | vec.Z = nextZVelocity + BulletXScene.Gravity * timeStep; | ||
382 | } | ||
383 | //Lowgravity with movement | ||
384 | else if((this._position.Z > BulletXScene.HeightLevel0) | ||
385 | && (this._position.Z <= BulletXScene.HeightLevel1)) | ||
386 | { | ||
387 | vec.Z = nextZVelocity + BulletXScene.Gravity * timeStep * (1.0f - BulletXScene.LowGravityFactor); | ||
388 | } | ||
389 | //Lowgravity with... | ||
390 | else if (this._position.Z > BulletXScene.HeightLevel1) | ||
391 | { | ||
392 | if(nextZVelocity > 0) //no movement | ||
393 | vec.Z = BulletXScene.Gravity * timeStep * (1.0f - BulletXScene.LowGravityFactor); | ||
394 | else | ||
395 | vec.Z = nextZVelocity + BulletXScene.Gravity * timeStep * (1.0f - BulletXScene.LowGravityFactor); | ||
396 | |||
397 | } | ||
398 | } | ||
399 | else | ||
400 | { | ||
401 | vec.Z = nextZVelocity; | ||
402 | } | ||
403 | rigidBody.LinearVelocity = vec; | ||
404 | } | ||
405 | |||
406 | public void UpdatePosition() | ||
407 | { | ||
408 | this._position = BulletXConversions.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition); | ||
409 | } | ||
410 | |||
411 | //This validation is very basic | ||
412 | internal void ValidateHeight(float heighmapPositionValue) | ||
413 | { | ||
414 | if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue) | ||
415 | { | ||
416 | Matrix m = rigidBody.WorldTransform; | ||
417 | MonoXnaCompactMaths.Vector3 v3 = m.Translation; | ||
418 | v3.Z = heighmapPositionValue; | ||
419 | m.Translation = v3; | ||
420 | rigidBody.WorldTransform = m; | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | /// <summary> | ||
425 | /// PhysicsActor Prim Class for BulletX | ||
426 | /// </summary> | ||
427 | public class BulletXPrim : PhysicsActor | ||
428 | { | ||
429 | private PhysicsVector _position; | ||
430 | private PhysicsVector _velocity; | ||
431 | private PhysicsVector _acceleration; | ||
432 | |||
433 | public BulletXPrim() | ||
434 | { | ||
435 | _velocity = new PhysicsVector(); | ||
436 | _position = new PhysicsVector(); | ||
437 | _acceleration = new PhysicsVector(); | ||
438 | } | ||
439 | public override bool Flying | ||
440 | { | ||
441 | get | ||
442 | { | ||
443 | return false; //no flying prims for you | ||
444 | } | ||
445 | set | ||
446 | { | ||
447 | |||
448 | } | ||
449 | } | ||
450 | public override PhysicsVector Position | ||
451 | { | ||
452 | get | ||
453 | { | ||
454 | PhysicsVector pos = new PhysicsVector(); | ||
455 | // PhysicsVector vec = this._prim.Position; | ||
456 | //pos.X = vec.X; | ||
457 | //pos.Y = vec.Y; | ||
458 | //pos.Z = vec.Z; | ||
459 | return pos; | ||
460 | |||
461 | } | ||
462 | set | ||
463 | { | ||
464 | /*PhysicsVector vec = value; | ||
465 | PhysicsVector pos = new PhysicsVector(); | ||
466 | pos.X = vec.X; | ||
467 | pos.Y = vec.Y; | ||
468 | pos.Z = vec.Z; | ||
469 | this._prim.Position = pos;*/ | ||
470 | } | ||
471 | } | ||
472 | |||
473 | public override PhysicsVector Velocity | ||
474 | { | ||
475 | get | ||
476 | { | ||
477 | return _velocity; | ||
478 | } | ||
479 | set | ||
480 | { | ||
481 | _velocity = value; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | public override bool Kinematic | ||
486 | { | ||
487 | get | ||
488 | { | ||
489 | return false; | ||
490 | //return this._prim.Kinematic; | ||
491 | } | ||
492 | set | ||
493 | { | ||
494 | //this._prim.Kinematic = value; | ||
495 | } | ||
496 | } | ||
497 | |||
498 | public override Axiom.Math.Quaternion Orientation | ||
499 | { | ||
500 | get | ||
501 | { | ||
502 | Axiom.Math.Quaternion res = new Axiom.Math.Quaternion(); | ||
503 | return res; | ||
504 | } | ||
505 | set | ||
506 | { | ||
507 | |||
508 | } | ||
509 | } | ||
510 | |||
511 | public override PhysicsVector Acceleration | ||
512 | { | ||
513 | get | ||
514 | { | ||
515 | return _acceleration; | ||
516 | } | ||
517 | |||
518 | } | ||
519 | public void SetAcceleration(PhysicsVector accel) | ||
520 | { | ||
521 | this._acceleration = accel; | ||
522 | } | ||
523 | |||
524 | public override void AddForce(PhysicsVector force) | ||
525 | { | ||
526 | |||
527 | } | ||
528 | |||
529 | public override void SetMomentum(PhysicsVector momentum) | ||
530 | { | ||
531 | |||
532 | } | ||
533 | } | ||
534 | } | ||