diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs | 1855 |
1 files changed, 0 insertions, 1855 deletions
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs deleted file mode 100644 index df62dbc..0000000 --- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs +++ /dev/null | |||
@@ -1,1855 +0,0 @@ | |||
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 OpenSimulator 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 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using OpenMetaverse; | ||
33 | using MonoXnaCompactMaths; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Region.Physics.Manager; | ||
36 | using XnaDevRu.BulletX; | ||
37 | using XnaDevRu.BulletX.Dynamics; | ||
38 | using Nini.Config; | ||
39 | using Vector3 = MonoXnaCompactMaths.Vector3; | ||
40 | using Quaternion = MonoXnaCompactMaths.Quaternion; | ||
41 | |||
42 | #endregion | ||
43 | |||
44 | namespace OpenSim.Region.Physics.BulletXPlugin | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// BulletXConversions are called now BulletXMaths | ||
48 | /// This Class converts objects and types for BulletX and give some operations | ||
49 | /// </summary> | ||
50 | public class BulletXMaths | ||
51 | { | ||
52 | //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | //Vector3 | ||
55 | public static Vector3 PhysicsVectorToXnaVector3(OpenMetaverse.Vector3 physicsVector) | ||
56 | { | ||
57 | return new Vector3(physicsVector.X, physicsVector.Y, physicsVector.Z); | ||
58 | } | ||
59 | |||
60 | public static OpenMetaverse.Vector3 XnaVector3ToPhysicsVector(Vector3 xnaVector3) | ||
61 | { | ||
62 | return new OpenMetaverse.Vector3(xnaVector3.X, xnaVector3.Y, xnaVector3.Z); | ||
63 | } | ||
64 | |||
65 | //Quaternion | ||
66 | public static Quaternion QuaternionToXnaQuaternion(OpenMetaverse.Quaternion quaternion) | ||
67 | { | ||
68 | return new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W); | ||
69 | } | ||
70 | |||
71 | public static OpenMetaverse.Quaternion XnaQuaternionToQuaternion(Quaternion xnaQuaternion) | ||
72 | { | ||
73 | return new OpenMetaverse.Quaternion(xnaQuaternion.W, xnaQuaternion.X, xnaQuaternion.Y, xnaQuaternion.Z); | ||
74 | } | ||
75 | |||
76 | //Next methods are extracted from XnaDevRu.BulletX(See 3rd party license): | ||
77 | //- SetRotation (class MatrixOperations) | ||
78 | //- GetRotation (class MatrixOperations) | ||
79 | //- GetElement (class MathHelper) | ||
80 | //- SetElement (class MathHelper) | ||
81 | internal static void SetRotation(ref Matrix m, Quaternion q) | ||
82 | { | ||
83 | float d = q.LengthSquared(); | ||
84 | float s = 2f/d; | ||
85 | float xs = q.X*s, ys = q.Y*s, zs = q.Z*s; | ||
86 | float wx = q.W*xs, wy = q.W*ys, wz = q.W*zs; | ||
87 | float xx = q.X*xs, xy = q.X*ys, xz = q.X*zs; | ||
88 | float yy = q.Y*ys, yz = q.Y*zs, zz = q.Z*zs; | ||
89 | m = new Matrix(1 - (yy + zz), xy - wz, xz + wy, 0, | ||
90 | xy + wz, 1 - (xx + zz), yz - wx, 0, | ||
91 | xz - wy, yz + wx, 1 - (xx + yy), 0, | ||
92 | m.M41, m.M42, m.M43, 1); | ||
93 | } | ||
94 | |||
95 | internal static Quaternion GetRotation(Matrix m) | ||
96 | { | ||
97 | Quaternion q; | ||
98 | |||
99 | float trace = m.M11 + m.M22 + m.M33; | ||
100 | |||
101 | if (trace > 0) | ||
102 | { | ||
103 | float s = (float) Math.Sqrt(trace + 1); | ||
104 | q.W = s*0.5f; | ||
105 | s = 0.5f/s; | ||
106 | |||
107 | q.X = (m.M32 - m.M23)*s; | ||
108 | q.Y = (m.M13 - m.M31)*s; | ||
109 | q.Z = (m.M21 - m.M12)*s; | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | q.X = q.Y = q.Z = q.W = 0f; | ||
114 | |||
115 | int i = m.M11 < m.M22 | ||
116 | ? | ||
117 | (m.M22 < m.M33 ? 2 : 1) | ||
118 | : | ||
119 | (m.M11 < m.M33 ? 2 : 0); | ||
120 | int j = (i + 1)%3; | ||
121 | int k = (i + 2)%3; | ||
122 | |||
123 | float s = (float) Math.Sqrt(GetElement(m, i, i) - GetElement(m, j, j) - GetElement(m, k, k) + 1); | ||
124 | SetElement(ref q, i, s*0.5f); | ||
125 | s = 0.5f/s; | ||
126 | |||
127 | q.W = (GetElement(m, k, j) - GetElement(m, j, k))*s; | ||
128 | SetElement(ref q, j, (GetElement(m, j, i) + GetElement(m, i, j))*s); | ||
129 | SetElement(ref q, k, (GetElement(m, k, i) + GetElement(m, i, k))*s); | ||
130 | } | ||
131 | |||
132 | return q; | ||
133 | } | ||
134 | |||
135 | internal static float SetElement(ref Quaternion q, int index, float value) | ||
136 | { | ||
137 | switch (index) | ||
138 | { | ||
139 | case 0: | ||
140 | q.X = value; | ||
141 | break; | ||
142 | case 1: | ||
143 | q.Y = value; | ||
144 | break; | ||
145 | case 2: | ||
146 | q.Z = value; | ||
147 | break; | ||
148 | case 3: | ||
149 | q.W = value; | ||
150 | break; | ||
151 | } | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | internal static float GetElement(Matrix mat, int row, int col) | ||
157 | { | ||
158 | switch (row) | ||
159 | { | ||
160 | case 0: | ||
161 | switch (col) | ||
162 | { | ||
163 | case 0: | ||
164 | return mat.M11; | ||
165 | case 1: | ||
166 | return mat.M12; | ||
167 | case 2: | ||
168 | return mat.M13; | ||
169 | } | ||
170 | break; | ||
171 | case 1: | ||
172 | switch (col) | ||
173 | { | ||
174 | case 0: | ||
175 | return mat.M21; | ||
176 | case 1: | ||
177 | return mat.M22; | ||
178 | case 2: | ||
179 | return mat.M23; | ||
180 | } | ||
181 | break; | ||
182 | case 2: | ||
183 | switch (col) | ||
184 | { | ||
185 | case 0: | ||
186 | return mat.M31; | ||
187 | case 1: | ||
188 | return mat.M32; | ||
189 | case 2: | ||
190 | return mat.M33; | ||
191 | } | ||
192 | break; | ||
193 | } | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | /// <summary> | ||
200 | /// PhysicsPlugin Class for BulletX | ||
201 | /// </summary> | ||
202 | public class BulletXPlugin : IPhysicsPlugin | ||
203 | { | ||
204 | private BulletXScene _mScene; | ||
205 | |||
206 | public BulletXPlugin() | ||
207 | { | ||
208 | } | ||
209 | |||
210 | public bool Init() | ||
211 | { | ||
212 | return true; | ||
213 | } | ||
214 | |||
215 | public PhysicsScene GetScene(string sceneIdentifier) | ||
216 | { | ||
217 | if (_mScene == null) | ||
218 | { | ||
219 | _mScene = new BulletXScene(sceneIdentifier); | ||
220 | } | ||
221 | return (_mScene); | ||
222 | } | ||
223 | |||
224 | public string GetName() | ||
225 | { | ||
226 | return ("modified_BulletX"); //Changed!! "BulletXEngine" To "modified_BulletX" | ||
227 | } | ||
228 | |||
229 | public void Dispose() | ||
230 | { | ||
231 | } | ||
232 | } | ||
233 | |||
234 | |||
235 | // Class to detect and debug collisions | ||
236 | // Mainly used for debugging purposes | ||
237 | internal class CollisionDispatcherLocal : CollisionDispatcher | ||
238 | { | ||
239 | private BulletXScene relatedScene; | ||
240 | |||
241 | public CollisionDispatcherLocal(BulletXScene s) | ||
242 | : base() | ||
243 | { | ||
244 | relatedScene = s; | ||
245 | } | ||
246 | |||
247 | public override bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB) | ||
248 | { | ||
249 | RigidBody rb; | ||
250 | BulletXCharacter bxcA = null; | ||
251 | BulletXPrim bxpA = null; | ||
252 | Type t = bodyA.GetType(); | ||
253 | if (t == typeof (RigidBody)) | ||
254 | { | ||
255 | rb = (RigidBody) bodyA; | ||
256 | relatedScene._characters.TryGetValue(rb, out bxcA); | ||
257 | relatedScene._prims.TryGetValue(rb, out bxpA); | ||
258 | } | ||
259 | // String nameA; | ||
260 | // if (bxcA != null) | ||
261 | // nameA = bxcA._name; | ||
262 | // else if (bxpA != null) | ||
263 | // nameA = bxpA._name; | ||
264 | // else | ||
265 | // nameA = "null"; | ||
266 | |||
267 | |||
268 | |||
269 | BulletXCharacter bxcB = null; | ||
270 | BulletXPrim bxpB = null; | ||
271 | t = bodyB.GetType(); | ||
272 | if (t == typeof (RigidBody)) | ||
273 | { | ||
274 | rb = (RigidBody) bodyB; | ||
275 | relatedScene._characters.TryGetValue(rb, out bxcB); | ||
276 | relatedScene._prims.TryGetValue(rb, out bxpB); | ||
277 | } | ||
278 | |||
279 | // String nameB; | ||
280 | // if (bxcB != null) | ||
281 | // nameB = bxcB._name; | ||
282 | // else if (bxpB != null) | ||
283 | // nameB = bxpB._name; | ||
284 | // else | ||
285 | // nameB = "null"; | ||
286 | bool needsCollision;// = base.NeedsCollision(bodyA, bodyB); | ||
287 | int c1 = 3; | ||
288 | int c2 = 3; | ||
289 | |||
290 | //////////////////////////////////////////////////////// | ||
291 | //BulletX Mesh Collisions | ||
292 | //added by Jed zhu | ||
293 | //data: May 07,2005 | ||
294 | //////////////////////////////////////////////////////// | ||
295 | #region BulletXMeshCollisions Fields | ||
296 | |||
297 | |||
298 | if (bxcA != null && bxpB != null) | ||
299 | c1 = Collision(bxcA, bxpB); | ||
300 | if (bxpA != null && bxcB != null) | ||
301 | c2 = Collision(bxcB, bxpA); | ||
302 | if (c1 < 2) | ||
303 | needsCollision = (c1 > 0) ? true : false; | ||
304 | else if (c2 < 2) | ||
305 | needsCollision = (c2 > 0) ? true : false; | ||
306 | else | ||
307 | needsCollision = base.NeedsCollision(bodyA, bodyB); | ||
308 | |||
309 | |||
310 | #endregion | ||
311 | |||
312 | |||
313 | //m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB, | ||
314 | //needsCollision); | ||
315 | |||
316 | |||
317 | return needsCollision; | ||
318 | } | ||
319 | //added by jed zhu | ||
320 | //calculas the collision between the Prim and Actor | ||
321 | // | ||
322 | private int Collision(BulletXCharacter actorA, BulletXPrim primB) | ||
323 | { | ||
324 | int[] indexBase; | ||
325 | Vector3[] vertexBase; | ||
326 | Vector3 vNormal; | ||
327 | // Vector3 vP1; | ||
328 | // Vector3 vP2; | ||
329 | // Vector3 vP3; | ||
330 | IMesh mesh = primB.GetMesh(); | ||
331 | |||
332 | float fdistance; | ||
333 | if (primB == null) | ||
334 | return 3; | ||
335 | if (mesh == null) | ||
336 | return 2; | ||
337 | if (actorA == null) | ||
338 | return 3; | ||
339 | |||
340 | int iVertexCount = mesh.getVertexList().Count; | ||
341 | int iIndexCount = mesh.getIndexListAsInt().Length; | ||
342 | if (iVertexCount == 0) | ||
343 | return 3; | ||
344 | if (iIndexCount == 0) | ||
345 | return 3; | ||
346 | lock (BulletXScene.BulletXLock) | ||
347 | { | ||
348 | indexBase = mesh.getIndexListAsInt(); | ||
349 | vertexBase = new Vector3[iVertexCount]; | ||
350 | |||
351 | for (int i = 0; i < iVertexCount; i++) | ||
352 | { | ||
353 | OpenMetaverse.Vector3 v = mesh.getVertexList()[i]; | ||
354 | if (v != null) // Note, null has special meaning. See meshing code for details | ||
355 | vertexBase[i] = BulletXMaths.PhysicsVectorToXnaVector3(v); | ||
356 | else | ||
357 | vertexBase[i] = Vector3.Zero; | ||
358 | } | ||
359 | |||
360 | for (int ix = 0; ix < iIndexCount; ix += 3) | ||
361 | { | ||
362 | int ia = indexBase[ix + 0]; | ||
363 | int ib = indexBase[ix + 1]; | ||
364 | int ic = indexBase[ix + 2]; | ||
365 | // | ||
366 | Vector3 v1 = vertexBase[ib] - vertexBase[ia]; | ||
367 | Vector3 v2 = vertexBase[ic] - vertexBase[ia]; | ||
368 | |||
369 | Vector3.Cross(ref v1, ref v2, out vNormal); | ||
370 | Vector3.Normalize(ref vNormal, out vNormal); | ||
371 | |||
372 | fdistance = Vector3.Dot(vNormal, vertexBase[ia]) + 0.50f; | ||
373 | if (preCheckCollision(actorA, vNormal, fdistance) == 1) | ||
374 | { | ||
375 | if (CheckCollision(actorA, ia, ib, ic, vNormal, vertexBase) == 1) | ||
376 | { | ||
377 | //PhysicsVector v = actorA.Position; | ||
378 | //Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v); | ||
379 | //Vector3 vp = vNormal * (fdistance - Vector3.Dot(vNormal, v3) + 0.2f); | ||
380 | //actorA.Position += BulletXMaths.XnaVector3ToPhysicsVector(vp); | ||
381 | return 1; | ||
382 | } | ||
383 | } | ||
384 | } | ||
385 | } | ||
386 | |||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | //added by jed zhu | ||
391 | //return value 1: need second check | ||
392 | //return value 0: no need check | ||
393 | |||
394 | private int preCheckCollision(BulletXActor actA, Vector3 vNormal, float fDist) | ||
395 | { | ||
396 | float fstartSide; | ||
397 | OpenMetaverse.Vector3 v = actA.Position; | ||
398 | Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v); | ||
399 | |||
400 | fstartSide = Vector3.Dot(vNormal, v3) - fDist; | ||
401 | if (fstartSide > 0) return 0; | ||
402 | else return 1; | ||
403 | } | ||
404 | //added by jed zhu | ||
405 | private int CheckCollision(BulletXActor actA, int ia, int ib, int ic, Vector3 vNormal, Vector3[] vertBase) | ||
406 | { | ||
407 | Vector3 perPlaneNormal; | ||
408 | float fPerPlaneDist; | ||
409 | OpenMetaverse.Vector3 v = actA.Position; | ||
410 | Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v); | ||
411 | //check AB | ||
412 | Vector3 v1; | ||
413 | v1 = vertBase[ib] - vertBase[ia]; | ||
414 | Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal); | ||
415 | Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal); | ||
416 | |||
417 | if (Vector3.Dot((vertBase[ic] - vertBase[ia]), perPlaneNormal) < 0) | ||
418 | perPlaneNormal = -perPlaneNormal; | ||
419 | fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) - 0.50f; | ||
420 | |||
421 | |||
422 | |||
423 | if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0) | ||
424 | return 0; | ||
425 | fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) + 0.50f; | ||
426 | if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0) | ||
427 | return 0; | ||
428 | |||
429 | //check BC | ||
430 | |||
431 | v1 = vertBase[ic] - vertBase[ib]; | ||
432 | Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal); | ||
433 | Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal); | ||
434 | |||
435 | if (Vector3.Dot((vertBase[ia] - vertBase[ib]), perPlaneNormal) < 0) | ||
436 | perPlaneNormal = -perPlaneNormal; | ||
437 | fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) - 0.50f; | ||
438 | |||
439 | |||
440 | if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0) | ||
441 | return 0; | ||
442 | fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) + 0.50f; | ||
443 | if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0) | ||
444 | return 0; | ||
445 | //check CA | ||
446 | v1 = vertBase[ia] - vertBase[ic]; | ||
447 | Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal); | ||
448 | Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal); | ||
449 | |||
450 | if (Vector3.Dot((vertBase[ib] - vertBase[ic]), perPlaneNormal) < 0) | ||
451 | perPlaneNormal = -perPlaneNormal; | ||
452 | fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) - 0.50f; | ||
453 | |||
454 | |||
455 | if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0) | ||
456 | return 0; | ||
457 | fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) + 0.50f; | ||
458 | if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0) | ||
459 | return 0; | ||
460 | |||
461 | return 1; | ||
462 | |||
463 | } | ||
464 | } | ||
465 | |||
466 | /// <summary> | ||
467 | /// PhysicsScene Class for BulletX | ||
468 | /// </summary> | ||
469 | public class BulletXScene : PhysicsScene | ||
470 | { | ||
471 | #region BulletXScene Fields | ||
472 | |||
473 | public DiscreteDynamicsWorld ddWorld; | ||
474 | private CollisionDispatcher cDispatcher; | ||
475 | private OverlappingPairCache opCache; | ||
476 | private SequentialImpulseConstraintSolver sicSolver; | ||
477 | public static Object BulletXLock = new Object(); | ||
478 | |||
479 | private const int minXY = 0; | ||
480 | private const int minZ = 0; | ||
481 | private const int maxXY = (int)Constants.RegionSize; | ||
482 | private const int maxZ = 4096; | ||
483 | private const int maxHandles = 32766; //Why? I don't know | ||
484 | private const float gravity = 9.8f; | ||
485 | private const float heightLevel0 = 77.0f; | ||
486 | private const float heightLevel1 = 200.0f; | ||
487 | private const float lowGravityFactor = 0.2f; | ||
488 | //OpenSim calls Simulate 10 times per seconds. So FPS = "Simulate Calls" * simulationSubSteps = 100 FPS | ||
489 | private const int simulationSubSteps = 10; | ||
490 | //private float[] _heightmap; | ||
491 | private BulletXPlanet _simFlatPlanet; | ||
492 | internal Dictionary<RigidBody, BulletXCharacter> _characters = new Dictionary<RigidBody, BulletXCharacter>(); | ||
493 | internal Dictionary<RigidBody, BulletXPrim> _prims = new Dictionary<RigidBody, BulletXPrim>(); | ||
494 | |||
495 | public IMesher mesher; | ||
496 | // private IConfigSource m_config; | ||
497 | |||
498 | // protected internal String identifier; | ||
499 | |||
500 | public BulletXScene(String sceneIdentifier) | ||
501 | { | ||
502 | //identifier = sceneIdentifier; | ||
503 | cDispatcher = new CollisionDispatcherLocal(this); | ||
504 | Vector3 worldMinDim = new Vector3((float)minXY, (float)minXY, (float)minZ); | ||
505 | Vector3 worldMaxDim = new Vector3((float)maxXY, (float)maxXY, (float)maxZ); | ||
506 | opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles); | ||
507 | sicSolver = new SequentialImpulseConstraintSolver(); | ||
508 | |||
509 | lock (BulletXLock) | ||
510 | { | ||
511 | ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver); | ||
512 | ddWorld.Gravity = new Vector3(0, 0, -gravity); | ||
513 | } | ||
514 | //this._heightmap = new float[65536]; | ||
515 | } | ||
516 | |||
517 | public static float Gravity | ||
518 | { | ||
519 | get { return gravity; } | ||
520 | } | ||
521 | |||
522 | public static float HeightLevel0 | ||
523 | { | ||
524 | get { return heightLevel0; } | ||
525 | } | ||
526 | |||
527 | public static float HeightLevel1 | ||
528 | { | ||
529 | get { return heightLevel1; } | ||
530 | } | ||
531 | |||
532 | public static float LowGravityFactor | ||
533 | { | ||
534 | get { return lowGravityFactor; } | ||
535 | } | ||
536 | |||
537 | public static int MaxXY | ||
538 | { | ||
539 | get { return maxXY; } | ||
540 | } | ||
541 | |||
542 | public static int MaxZ | ||
543 | { | ||
544 | get { return maxZ; } | ||
545 | } | ||
546 | |||
547 | private List<RigidBody> _forgottenRigidBodies = new List<RigidBody>(); | ||
548 | internal string is_ex_message = "Can't remove rigidBody!: "; | ||
549 | |||
550 | #endregion | ||
551 | |||
552 | public BulletXScene() | ||
553 | { | ||
554 | cDispatcher = new CollisionDispatcherLocal(this); | ||
555 | Vector3 worldMinDim = new Vector3((float) minXY, (float) minXY, (float) minZ); | ||
556 | Vector3 worldMaxDim = new Vector3((float) maxXY, (float) maxXY, (float) maxZ); | ||
557 | opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles); | ||
558 | sicSolver = new SequentialImpulseConstraintSolver(); | ||
559 | |||
560 | lock (BulletXLock) | ||
561 | { | ||
562 | ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver); | ||
563 | ddWorld.Gravity = new Vector3(0, 0, -gravity); | ||
564 | } | ||
565 | //this._heightmap = new float[65536]; | ||
566 | } | ||
567 | |||
568 | public override void Initialise(IMesher meshmerizer, IConfigSource config) | ||
569 | { | ||
570 | mesher = meshmerizer; | ||
571 | // m_config = config; | ||
572 | } | ||
573 | |||
574 | public override void Dispose() | ||
575 | { | ||
576 | |||
577 | } | ||
578 | |||
579 | public override Dictionary<uint, float> GetTopColliders() | ||
580 | { | ||
581 | Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); | ||
582 | return returncolliders; | ||
583 | } | ||
584 | |||
585 | public override void SetWaterLevel(float baseheight) | ||
586 | { | ||
587 | |||
588 | } | ||
589 | |||
590 | public override PhysicsActor AddAvatar(string avName, OpenMetaverse.Vector3 position, OpenMetaverse.Vector3 size, bool isFlying) | ||
591 | { | ||
592 | OpenMetaverse.Vector3 pos = OpenMetaverse.Vector3.Zero; | ||
593 | pos.X = position.X; | ||
594 | pos.Y = position.Y; | ||
595 | pos.Z = position.Z + 20; | ||
596 | BulletXCharacter newAv = null; | ||
597 | lock (BulletXLock) | ||
598 | { | ||
599 | newAv = new BulletXCharacter(avName, this, pos); | ||
600 | _characters.Add(newAv.RigidBody, newAv); | ||
601 | } | ||
602 | newAv.Flying = isFlying; | ||
603 | return newAv; | ||
604 | } | ||
605 | |||
606 | public override void RemoveAvatar(PhysicsActor actor) | ||
607 | { | ||
608 | if (actor is BulletXCharacter) | ||
609 | { | ||
610 | lock (BulletXLock) | ||
611 | { | ||
612 | try | ||
613 | { | ||
614 | ddWorld.RemoveRigidBody(((BulletXCharacter) actor).RigidBody); | ||
615 | } | ||
616 | catch (Exception ex) | ||
617 | { | ||
618 | BulletXMessage(is_ex_message + ex.Message, true); | ||
619 | ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation; | ||
620 | AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody); | ||
621 | } | ||
622 | _characters.Remove(((BulletXCharacter) actor).RigidBody); | ||
623 | } | ||
624 | GC.Collect(); | ||
625 | } | ||
626 | } | ||
627 | |||
628 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, OpenMetaverse.Vector3 position, | ||
629 | OpenMetaverse.Vector3 size, OpenMetaverse.Quaternion rotation, bool isPhysical, uint localid) | ||
630 | { | ||
631 | PhysicsActor result; | ||
632 | |||
633 | switch (pbs.ProfileShape) | ||
634 | { | ||
635 | case ProfileShape.Square: | ||
636 | /// support simple box & hollow box now; later, more shapes | ||
637 | if (pbs.ProfileHollow == 0) | ||
638 | { | ||
639 | result = AddPrim(primName, position, size, rotation, null, null, isPhysical); | ||
640 | } | ||
641 | else | ||
642 | { | ||
643 | IMesh mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); | ||
644 | result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical); | ||
645 | } | ||
646 | break; | ||
647 | |||
648 | default: | ||
649 | result = AddPrim(primName, position, size, rotation, null, null, isPhysical); | ||
650 | break; | ||
651 | } | ||
652 | |||
653 | return result; | ||
654 | } | ||
655 | |||
656 | public PhysicsActor AddPrim(String name, OpenMetaverse.Vector3 position, OpenMetaverse.Vector3 size, OpenMetaverse.Quaternion rotation, | ||
657 | IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical) | ||
658 | { | ||
659 | BulletXPrim newPrim = null; | ||
660 | lock (BulletXLock) | ||
661 | { | ||
662 | newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs, isPhysical); | ||
663 | _prims.Add(newPrim.RigidBody, newPrim); | ||
664 | } | ||
665 | return newPrim; | ||
666 | } | ||
667 | |||
668 | public override void RemovePrim(PhysicsActor prim) | ||
669 | { | ||
670 | if (prim is BulletXPrim) | ||
671 | { | ||
672 | lock (BulletXLock) | ||
673 | { | ||
674 | try | ||
675 | { | ||
676 | ddWorld.RemoveRigidBody(((BulletXPrim) prim).RigidBody); | ||
677 | } | ||
678 | catch (Exception ex) | ||
679 | { | ||
680 | BulletXMessage(is_ex_message + ex.Message, true); | ||
681 | ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation; | ||
682 | AddForgottenRigidBody(((BulletXPrim) prim).RigidBody); | ||
683 | } | ||
684 | _prims.Remove(((BulletXPrim) prim).RigidBody); | ||
685 | } | ||
686 | GC.Collect(); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | public override void AddPhysicsActorTaint(PhysicsActor prim) | ||
691 | { | ||
692 | } | ||
693 | |||
694 | public override float Simulate(float timeStep) | ||
695 | { | ||
696 | float fps = 0; | ||
697 | lock (BulletXLock) | ||
698 | { | ||
699 | //Try to remove garbage | ||
700 | RemoveForgottenRigidBodies(); | ||
701 | //End of remove | ||
702 | MoveAPrimitives(timeStep); | ||
703 | |||
704 | |||
705 | fps = (timeStep*simulationSubSteps); | ||
706 | |||
707 | ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep); | ||
708 | //Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine. | ||
709 | ValidateHeightForAll(); | ||
710 | //End heightmap validation. | ||
711 | UpdateKineticsForAll(); | ||
712 | } | ||
713 | return fps; | ||
714 | } | ||
715 | |||
716 | private void MoveAPrimitives(float timeStep) | ||
717 | { | ||
718 | foreach (BulletXCharacter actor in _characters.Values) | ||
719 | { | ||
720 | actor.Move(timeStep); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | private void ValidateHeightForAll() | ||
725 | { | ||
726 | float _height; | ||
727 | foreach (BulletXCharacter actor in _characters.Values) | ||
728 | { | ||
729 | //_height = HeightValue(actor.RigidBodyPosition); | ||
730 | _height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition); | ||
731 | actor.ValidateHeight(_height); | ||
732 | //if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height); | ||
733 | } | ||
734 | foreach (BulletXPrim prim in _prims.Values) | ||
735 | { | ||
736 | //_height = HeightValue(prim.RigidBodyPosition); | ||
737 | _height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition); | ||
738 | prim.ValidateHeight(_height); | ||
739 | //if (_simFlatPlanet.heightIsNotValid(prim.RigidBodyPosition, out _height)) prim.ValidateHeight(_height); | ||
740 | } | ||
741 | //foreach (BulletXCharacter actor in _characters) | ||
742 | //{ | ||
743 | // actor.ValidateHeight(0); | ||
744 | //} | ||
745 | //foreach (BulletXPrim prim in _prims) | ||
746 | //{ | ||
747 | // prim.ValidateHeight(0); | ||
748 | //} | ||
749 | } | ||
750 | |||
751 | private void UpdateKineticsForAll() | ||
752 | { | ||
753 | //UpdatePosition > UpdateKinetics. | ||
754 | //Not only position will be updated, also velocity cause acceleration. | ||
755 | foreach (BulletXCharacter actor in _characters.Values) | ||
756 | { | ||
757 | actor.UpdateKinetics(); | ||
758 | } | ||
759 | foreach (BulletXPrim prim in _prims.Values) | ||
760 | { | ||
761 | prim.UpdateKinetics(); | ||
762 | } | ||
763 | //if (this._simFlatPlanet!=null) this._simFlatPlanet.Restore(); | ||
764 | } | ||
765 | |||
766 | public override void GetResults() | ||
767 | { | ||
768 | } | ||
769 | |||
770 | public override bool IsThreaded | ||
771 | { | ||
772 | get | ||
773 | { | ||
774 | return (false); // for now we won't be multithreaded | ||
775 | } | ||
776 | } | ||
777 | |||
778 | public override void SetTerrain(float[] heightMap) | ||
779 | { | ||
780 | ////As the same as ODE, heightmap (x,y) must be swapped for BulletX | ||
781 | //for (int i = 0; i < 65536; i++) | ||
782 | //{ | ||
783 | // // this._heightmap[i] = (double)heightMap[i]; | ||
784 | // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...) | ||
785 | // int x = i & 0xff; | ||
786 | // int y = i >> 8; | ||
787 | // this._heightmap[i] = heightMap[x * 256 + y]; | ||
788 | //} | ||
789 | |||
790 | //float[] swappedHeightMap = new float[65536]; | ||
791 | ////As the same as ODE, heightmap (x,y) must be swapped for BulletX | ||
792 | //for (int i = 0; i < 65536; i++) | ||
793 | //{ | ||
794 | // // this._heightmap[i] = (double)heightMap[i]; | ||
795 | // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...) | ||
796 | // int x = i & 0xff; | ||
797 | // int y = i >> 8; | ||
798 | // swappedHeightMap[i] = heightMap[x * 256 + y]; | ||
799 | //} | ||
800 | DeleteTerrain(); | ||
801 | //There is a BulletXLock inside the constructor of BulletXPlanet | ||
802 | //this._simFlatPlanet = new BulletXPlanet(this, swappedHeightMap); | ||
803 | _simFlatPlanet = new BulletXPlanet(this, heightMap); | ||
804 | //this._heightmap = heightMap; | ||
805 | } | ||
806 | |||
807 | public override void DeleteTerrain() | ||
808 | { | ||
809 | if (_simFlatPlanet != null) | ||
810 | { | ||
811 | lock (BulletXLock) | ||
812 | { | ||
813 | try | ||
814 | { | ||
815 | ddWorld.RemoveRigidBody(_simFlatPlanet.RigidBody); | ||
816 | } | ||
817 | catch (Exception ex) | ||
818 | { | ||
819 | BulletXMessage(is_ex_message + ex.Message, true); | ||
820 | _simFlatPlanet.RigidBody.ActivationState = ActivationState.DisableSimulation; | ||
821 | AddForgottenRigidBody(_simFlatPlanet.RigidBody); | ||
822 | } | ||
823 | } | ||
824 | _simFlatPlanet = null; | ||
825 | GC.Collect(); | ||
826 | BulletXMessage("Terrain erased!", false); | ||
827 | } | ||
828 | |||
829 | |||
830 | |||
831 | //this._heightmap = null; | ||
832 | } | ||
833 | |||
834 | |||
835 | |||
836 | internal void AddForgottenRigidBody(RigidBody forgottenRigidBody) | ||
837 | { | ||
838 | _forgottenRigidBodies.Add(forgottenRigidBody); | ||
839 | } | ||
840 | |||
841 | private void RemoveForgottenRigidBodies() | ||
842 | { | ||
843 | RigidBody forgottenRigidBody; | ||
844 | int nRigidBodies = _forgottenRigidBodies.Count; | ||
845 | for (int i = nRigidBodies - 1; i >= 0; i--) | ||
846 | { | ||
847 | forgottenRigidBody = _forgottenRigidBodies[i]; | ||
848 | try | ||
849 | { | ||
850 | ddWorld.RemoveRigidBody(forgottenRigidBody); | ||
851 | _forgottenRigidBodies.Remove(forgottenRigidBody); | ||
852 | BulletXMessage("Forgotten Rigid Body Removed", false); | ||
853 | } | ||
854 | catch (Exception ex) | ||
855 | { | ||
856 | BulletXMessage("Can't remove forgottenRigidBody!: " + ex.Message, false); | ||
857 | } | ||
858 | } | ||
859 | GC.Collect(); | ||
860 | } | ||
861 | |||
862 | internal static void BulletXMessage(string message, bool isWarning) | ||
863 | { | ||
864 | PhysicsPluginManager.PhysicsPluginMessage("[Modified BulletX]:\t" + message, isWarning); | ||
865 | } | ||
866 | |||
867 | //temp | ||
868 | //private float HeightValue(MonoXnaCompactMaths.Vector3 position) | ||
869 | //{ | ||
870 | // int li_x, li_y; | ||
871 | // float height; | ||
872 | // li_x = (int)Math.Round(position.X); if (li_x < 0) li_x = 0; | ||
873 | // li_y = (int)Math.Round(position.Y); if (li_y < 0) li_y = 0; | ||
874 | |||
875 | // height = this._heightmap[li_y * 256 + li_x]; | ||
876 | // if (height < 0) height = 0; | ||
877 | // else if (height > maxZ) height = maxZ; | ||
878 | |||
879 | // return height; | ||
880 | //} | ||
881 | } | ||
882 | |||
883 | /// <summary> | ||
884 | /// Generic Physics Actor for BulletX inherit from PhysicActor | ||
885 | /// </summary> | ||
886 | public class BulletXActor : PhysicsActor | ||
887 | { | ||
888 | protected bool flying = false; | ||
889 | protected bool _physical = false; | ||
890 | protected OpenMetaverse.Vector3 _position; | ||
891 | protected OpenMetaverse.Vector3 _velocity; | ||
892 | protected OpenMetaverse.Vector3 _size; | ||
893 | protected OpenMetaverse.Vector3 _acceleration; | ||
894 | protected OpenMetaverse.Quaternion _orientation; | ||
895 | protected OpenMetaverse.Vector3 m_rotationalVelocity; | ||
896 | protected RigidBody rigidBody; | ||
897 | protected int m_PhysicsActorType; | ||
898 | private Boolean iscolliding = false; | ||
899 | internal string _name; | ||
900 | |||
901 | public BulletXActor(String name) | ||
902 | { | ||
903 | _name = name; | ||
904 | } | ||
905 | |||
906 | public override bool Stopped | ||
907 | { | ||
908 | get { return false; } | ||
909 | } | ||
910 | |||
911 | public override OpenMetaverse.Vector3 Position | ||
912 | { | ||
913 | get { return _position; } | ||
914 | set | ||
915 | { | ||
916 | lock (BulletXScene.BulletXLock) | ||
917 | { | ||
918 | _position = value; | ||
919 | Translate(); | ||
920 | } | ||
921 | } | ||
922 | } | ||
923 | |||
924 | public override OpenMetaverse.Vector3 RotationalVelocity | ||
925 | { | ||
926 | get { return m_rotationalVelocity; } | ||
927 | set { m_rotationalVelocity = value; } | ||
928 | } | ||
929 | |||
930 | public override OpenMetaverse.Vector3 Velocity | ||
931 | { | ||
932 | get { return _velocity; } | ||
933 | set | ||
934 | { | ||
935 | lock (BulletXScene.BulletXLock) | ||
936 | { | ||
937 | //Static objects don' have linear velocity | ||
938 | if (_physical) | ||
939 | { | ||
940 | _velocity = value; | ||
941 | Speed(); | ||
942 | } | ||
943 | else | ||
944 | { | ||
945 | _velocity = OpenMetaverse.Vector3.Zero; | ||
946 | } | ||
947 | } | ||
948 | } | ||
949 | } | ||
950 | public override float CollisionScore | ||
951 | { | ||
952 | get { return 0f; } | ||
953 | set { } | ||
954 | } | ||
955 | public override OpenMetaverse.Vector3 Size | ||
956 | { | ||
957 | get { return _size; } | ||
958 | set | ||
959 | { | ||
960 | lock (BulletXScene.BulletXLock) | ||
961 | { | ||
962 | _size = value; | ||
963 | } | ||
964 | } | ||
965 | } | ||
966 | |||
967 | public override OpenMetaverse.Vector3 Force | ||
968 | { | ||
969 | get { return OpenMetaverse.Vector3.Zero; } | ||
970 | set { return; } | ||
971 | } | ||
972 | |||
973 | public override int VehicleType | ||
974 | { | ||
975 | get { return 0; } | ||
976 | set { return; } | ||
977 | } | ||
978 | |||
979 | public override void VehicleFloatParam(int param, float value) | ||
980 | { | ||
981 | |||
982 | } | ||
983 | |||
984 | public override void VehicleVectorParam(int param, OpenMetaverse.Vector3 value) | ||
985 | { | ||
986 | |||
987 | } | ||
988 | |||
989 | public override void VehicleRotationParam(int param, OpenMetaverse.Quaternion rotation) | ||
990 | { | ||
991 | |||
992 | } | ||
993 | |||
994 | public override void VehicleFlags(int param, bool remove) | ||
995 | { | ||
996 | |||
997 | } | ||
998 | |||
999 | public override void SetVolumeDetect(int param) | ||
1000 | { | ||
1001 | |||
1002 | } | ||
1003 | |||
1004 | public override OpenMetaverse.Vector3 CenterOfMass | ||
1005 | { | ||
1006 | get { return OpenMetaverse.Vector3.Zero; } | ||
1007 | } | ||
1008 | |||
1009 | public override OpenMetaverse.Vector3 GeometricCenter | ||
1010 | { | ||
1011 | get { return OpenMetaverse.Vector3.Zero; } | ||
1012 | } | ||
1013 | |||
1014 | public override PrimitiveBaseShape Shape | ||
1015 | { | ||
1016 | set { return; } | ||
1017 | } | ||
1018 | |||
1019 | public override bool SetAlwaysRun | ||
1020 | { | ||
1021 | get { return false; } | ||
1022 | set { return; } | ||
1023 | } | ||
1024 | |||
1025 | public override OpenMetaverse.Vector3 Acceleration | ||
1026 | { | ||
1027 | get { return _acceleration; } | ||
1028 | } | ||
1029 | |||
1030 | public override OpenMetaverse.Quaternion Orientation | ||
1031 | { | ||
1032 | get { return _orientation; } | ||
1033 | set | ||
1034 | { | ||
1035 | lock (BulletXScene.BulletXLock) | ||
1036 | { | ||
1037 | _orientation = value; | ||
1038 | ReOrient(); | ||
1039 | } | ||
1040 | } | ||
1041 | } | ||
1042 | public override void link(PhysicsActor obj) | ||
1043 | { | ||
1044 | |||
1045 | } | ||
1046 | |||
1047 | public override void delink() | ||
1048 | { | ||
1049 | |||
1050 | } | ||
1051 | |||
1052 | public override void LockAngularMotion(OpenMetaverse.Vector3 axis) | ||
1053 | { | ||
1054 | |||
1055 | } | ||
1056 | |||
1057 | public override float Mass | ||
1058 | { | ||
1059 | get { return ActorMass; } | ||
1060 | } | ||
1061 | |||
1062 | public virtual float ActorMass | ||
1063 | { | ||
1064 | get { return 0; } | ||
1065 | } | ||
1066 | |||
1067 | public override int PhysicsActorType | ||
1068 | { | ||
1069 | get { return (int) m_PhysicsActorType; } | ||
1070 | set { m_PhysicsActorType = value; } | ||
1071 | } | ||
1072 | |||
1073 | public RigidBody RigidBody | ||
1074 | { | ||
1075 | get { return rigidBody; } | ||
1076 | } | ||
1077 | |||
1078 | public Vector3 RigidBodyPosition | ||
1079 | { | ||
1080 | get { return rigidBody.CenterOfMassPosition; } | ||
1081 | } | ||
1082 | |||
1083 | public override bool IsPhysical | ||
1084 | { | ||
1085 | get { return _physical; } | ||
1086 | set { _physical = value; } | ||
1087 | } | ||
1088 | |||
1089 | public override bool Flying | ||
1090 | { | ||
1091 | get { return flying; } | ||
1092 | set { flying = value; } | ||
1093 | } | ||
1094 | |||
1095 | public override bool ThrottleUpdates | ||
1096 | { | ||
1097 | get { return false; } | ||
1098 | set { return; } | ||
1099 | } | ||
1100 | |||
1101 | public override bool IsColliding | ||
1102 | { | ||
1103 | get { return iscolliding; } | ||
1104 | set { iscolliding = value; } | ||
1105 | } | ||
1106 | |||
1107 | public override bool CollidingGround | ||
1108 | { | ||
1109 | get { return false; } | ||
1110 | set { return; } | ||
1111 | } | ||
1112 | |||
1113 | public override bool CollidingObj | ||
1114 | { | ||
1115 | get { return false; } | ||
1116 | set { return; } | ||
1117 | } | ||
1118 | |||
1119 | public override uint LocalID | ||
1120 | { | ||
1121 | set { return; } | ||
1122 | } | ||
1123 | |||
1124 | public override bool Grabbed | ||
1125 | { | ||
1126 | set { return; } | ||
1127 | } | ||
1128 | |||
1129 | public override bool Selected | ||
1130 | { | ||
1131 | set { return; } | ||
1132 | } | ||
1133 | |||
1134 | public override float Buoyancy | ||
1135 | { | ||
1136 | get { return 0f; } | ||
1137 | set { return; } | ||
1138 | } | ||
1139 | |||
1140 | public override bool FloatOnWater | ||
1141 | { | ||
1142 | set { return; } | ||
1143 | } | ||
1144 | |||
1145 | public virtual void SetAcceleration(OpenMetaverse.Vector3 accel) | ||
1146 | { | ||
1147 | lock (BulletXScene.BulletXLock) | ||
1148 | { | ||
1149 | _acceleration = accel; | ||
1150 | } | ||
1151 | } | ||
1152 | |||
1153 | public override bool Kinematic | ||
1154 | { | ||
1155 | get { return false; } | ||
1156 | set { } | ||
1157 | } | ||
1158 | |||
1159 | public override void AddForce(OpenMetaverse.Vector3 force, bool pushforce) | ||
1160 | { | ||
1161 | } | ||
1162 | public override OpenMetaverse.Vector3 Torque | ||
1163 | { | ||
1164 | get { return OpenMetaverse.Vector3.Zero; } | ||
1165 | set { return; } | ||
1166 | } | ||
1167 | public override void AddAngularForce(OpenMetaverse.Vector3 force, bool pushforce) | ||
1168 | { | ||
1169 | } | ||
1170 | |||
1171 | public override void SetMomentum(OpenMetaverse.Vector3 momentum) | ||
1172 | { | ||
1173 | } | ||
1174 | |||
1175 | internal virtual void ValidateHeight(float heighmapPositionValue) | ||
1176 | { | ||
1177 | } | ||
1178 | |||
1179 | internal virtual void UpdateKinetics() | ||
1180 | { | ||
1181 | } | ||
1182 | |||
1183 | #region Methods for updating values of RigidBody | ||
1184 | |||
1185 | protected internal void Translate() | ||
1186 | { | ||
1187 | Translate(_position); | ||
1188 | } | ||
1189 | |||
1190 | protected internal void Translate(OpenMetaverse.Vector3 _newPos) | ||
1191 | { | ||
1192 | Vector3 _translation; | ||
1193 | _translation = BulletXMaths.PhysicsVectorToXnaVector3(_newPos) - rigidBody.CenterOfMassPosition; | ||
1194 | rigidBody.Translate(_translation); | ||
1195 | } | ||
1196 | |||
1197 | protected internal void Speed() | ||
1198 | { | ||
1199 | Speed(_velocity); | ||
1200 | } | ||
1201 | |||
1202 | protected internal void Speed(OpenMetaverse.Vector3 _newSpeed) | ||
1203 | { | ||
1204 | Vector3 _speed; | ||
1205 | _speed = BulletXMaths.PhysicsVectorToXnaVector3(_newSpeed); | ||
1206 | rigidBody.LinearVelocity = _speed; | ||
1207 | } | ||
1208 | |||
1209 | protected internal void ReOrient() | ||
1210 | { | ||
1211 | ReOrient(_orientation); | ||
1212 | } | ||
1213 | |||
1214 | protected internal void ReOrient(OpenMetaverse.Quaternion _newOrient) | ||
1215 | { | ||
1216 | Quaternion _newOrientation; | ||
1217 | _newOrientation = BulletXMaths.QuaternionToXnaQuaternion(_newOrient); | ||
1218 | Matrix _comTransform = rigidBody.CenterOfMassTransform; | ||
1219 | BulletXMaths.SetRotation(ref _comTransform, _newOrientation); | ||
1220 | rigidBody.CenterOfMassTransform = _comTransform; | ||
1221 | } | ||
1222 | |||
1223 | protected internal void ReSize() | ||
1224 | { | ||
1225 | ReSize(_size); | ||
1226 | } | ||
1227 | |||
1228 | protected internal virtual void ReSize(OpenMetaverse.Vector3 _newSize) | ||
1229 | { | ||
1230 | } | ||
1231 | |||
1232 | public virtual void ScheduleTerseUpdate() | ||
1233 | { | ||
1234 | base.RequestPhysicsterseUpdate(); | ||
1235 | } | ||
1236 | |||
1237 | #endregion | ||
1238 | |||
1239 | public override void CrossingFailure() | ||
1240 | { | ||
1241 | |||
1242 | } | ||
1243 | public override OpenMetaverse.Vector3 PIDTarget { set { return; } } | ||
1244 | public override bool PIDActive { set { return; } } | ||
1245 | public override float PIDTau { set { return; } } | ||
1246 | |||
1247 | public override float PIDHoverHeight { set { return; } } | ||
1248 | public override bool PIDHoverActive { set { return; } } | ||
1249 | public override PIDHoverType PIDHoverType { set { return; } } | ||
1250 | public override float PIDHoverTau { set { return; } } | ||
1251 | |||
1252 | public override OpenMetaverse.Quaternion APIDTarget | ||
1253 | { | ||
1254 | set { return; } | ||
1255 | } | ||
1256 | |||
1257 | public override bool APIDActive | ||
1258 | { | ||
1259 | set { return; } | ||
1260 | } | ||
1261 | |||
1262 | public override float APIDStrength | ||
1263 | { | ||
1264 | set { return; } | ||
1265 | } | ||
1266 | |||
1267 | public override float APIDDamping | ||
1268 | { | ||
1269 | set { return; } | ||
1270 | } | ||
1271 | |||
1272 | |||
1273 | public override void SubscribeEvents(int ms) | ||
1274 | { | ||
1275 | |||
1276 | } | ||
1277 | public override void UnSubscribeEvents() | ||
1278 | { | ||
1279 | |||
1280 | } | ||
1281 | public override bool SubscribedEvents() | ||
1282 | { | ||
1283 | return false; | ||
1284 | } | ||
1285 | } | ||
1286 | |||
1287 | /// <summary> | ||
1288 | /// PhysicsActor Character Class for BulletX | ||
1289 | /// </summary> | ||
1290 | public class BulletXCharacter : BulletXActor | ||
1291 | { | ||
1292 | public BulletXCharacter(BulletXScene parent_scene, OpenMetaverse.Vector3 pos) | ||
1293 | : this(String.Empty, parent_scene, pos) | ||
1294 | { | ||
1295 | } | ||
1296 | |||
1297 | public BulletXCharacter(String avName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos) | ||
1298 | : this(avName, parent_scene, pos, OpenMetaverse.Vector3.Zero, OpenMetaverse.Vector3.Zero, OpenMetaverse.Vector3.Zero, | ||
1299 | OpenMetaverse.Quaternion.Identity) | ||
1300 | { | ||
1301 | } | ||
1302 | |||
1303 | public BulletXCharacter(String avName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 velocity, | ||
1304 | OpenMetaverse.Vector3 size, OpenMetaverse.Vector3 acceleration, OpenMetaverse.Quaternion orientation) | ||
1305 | : base(avName) | ||
1306 | { | ||
1307 | //This fields will be removed. They're temporal | ||
1308 | float _sizeX = 0.5f; | ||
1309 | float _sizeY = 0.5f; | ||
1310 | float _sizeZ = 1.6f; | ||
1311 | //. | ||
1312 | _position = pos; | ||
1313 | _velocity = velocity; | ||
1314 | _size = size; | ||
1315 | //--- | ||
1316 | _size.X = _sizeX; | ||
1317 | _size.Y = _sizeY; | ||
1318 | _size.Z = _sizeZ; | ||
1319 | //. | ||
1320 | _acceleration = acceleration; | ||
1321 | _orientation = orientation; | ||
1322 | _physical = true; | ||
1323 | |||
1324 | float _mass = 50.0f; //This depends of avatar's dimensions | ||
1325 | //For RigidBody Constructor. The next values might change | ||
1326 | float _linearDamping = 0.0f; | ||
1327 | float _angularDamping = 0.0f; | ||
1328 | float _friction = 0.5f; | ||
1329 | float _restitution = 0.0f; | ||
1330 | Matrix _startTransform = Matrix.Identity; | ||
1331 | Matrix _centerOfMassOffset = Matrix.Identity; | ||
1332 | lock (BulletXScene.BulletXLock) | ||
1333 | { | ||
1334 | _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos); | ||
1335 | //CollisionShape _collisionShape = new BoxShape(new MonoXnaCompactMaths.Vector3(1.0f, 1.0f, 1.60f)); | ||
1336 | //For now, like ODE, collisionShape = sphere of radious = 1.0 | ||
1337 | CollisionShape _collisionShape = new SphereShape(1.0f); | ||
1338 | DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset); | ||
1339 | Vector3 _localInertia = new Vector3(); | ||
1340 | _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0 | ||
1341 | rigidBody = | ||
1342 | new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, | ||
1343 | _friction, _restitution); | ||
1344 | //rigidBody.ActivationState = ActivationState.DisableDeactivation; | ||
1345 | //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition | ||
1346 | Vector3 _vDebugTranslation; | ||
1347 | _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition; | ||
1348 | rigidBody.Translate(_vDebugTranslation); | ||
1349 | parent_scene.ddWorld.AddRigidBody(rigidBody); | ||
1350 | } | ||
1351 | } | ||
1352 | |||
1353 | public override int PhysicsActorType | ||
1354 | { | ||
1355 | get { return (int) ActorTypes.Agent; } | ||
1356 | set { return; } | ||
1357 | } | ||
1358 | |||
1359 | public override OpenMetaverse.Vector3 Position | ||
1360 | { | ||
1361 | get { return base.Position; } | ||
1362 | set { base.Position = value; } | ||
1363 | } | ||
1364 | |||
1365 | public override OpenMetaverse.Vector3 Velocity | ||
1366 | { | ||
1367 | get { return base.Velocity; } | ||
1368 | set { base.Velocity = value; } | ||
1369 | } | ||
1370 | |||
1371 | public override OpenMetaverse.Vector3 Size | ||
1372 | { | ||
1373 | get { return base.Size; } | ||
1374 | set { base.Size = value; } | ||
1375 | } | ||
1376 | |||
1377 | public override OpenMetaverse.Vector3 Acceleration | ||
1378 | { | ||
1379 | get { return base.Acceleration; } | ||
1380 | } | ||
1381 | |||
1382 | public override OpenMetaverse.Quaternion Orientation | ||
1383 | { | ||
1384 | get { return base.Orientation; } | ||
1385 | set { base.Orientation = value; } | ||
1386 | } | ||
1387 | |||
1388 | public override bool Flying | ||
1389 | { | ||
1390 | get { return base.Flying; } | ||
1391 | set { base.Flying = value; } | ||
1392 | } | ||
1393 | |||
1394 | public override bool IsColliding | ||
1395 | { | ||
1396 | get { return base.IsColliding; } | ||
1397 | set { base.IsColliding = value; } | ||
1398 | } | ||
1399 | |||
1400 | public override bool Kinematic | ||
1401 | { | ||
1402 | get { return base.Kinematic; } | ||
1403 | set { base.Kinematic = value; } | ||
1404 | } | ||
1405 | |||
1406 | public override void SetAcceleration(OpenMetaverse.Vector3 accel) | ||
1407 | { | ||
1408 | base.SetAcceleration(accel); | ||
1409 | } | ||
1410 | |||
1411 | public override void AddForce(OpenMetaverse.Vector3 force, bool pushforce) | ||
1412 | { | ||
1413 | base.AddForce(force, pushforce); | ||
1414 | } | ||
1415 | |||
1416 | public override void SetMomentum(OpenMetaverse.Vector3 momentum) | ||
1417 | { | ||
1418 | base.SetMomentum(momentum); | ||
1419 | } | ||
1420 | |||
1421 | internal void Move(float timeStep) | ||
1422 | { | ||
1423 | Vector3 vec = new Vector3(); | ||
1424 | //At this point it's supossed that: | ||
1425 | //_velocity == rigidBody.LinearVelocity | ||
1426 | vec.X = _velocity.X; | ||
1427 | vec.Y = _velocity.Y; | ||
1428 | vec.Z = _velocity.Z; | ||
1429 | if ((vec.X != 0.0f) || (vec.Y != 0.0f) || (vec.Z != 0.0f)) rigidBody.Activate(); | ||
1430 | if (flying) | ||
1431 | { | ||
1432 | //Antigravity with movement | ||
1433 | if (_position.Z <= BulletXScene.HeightLevel0) | ||
1434 | { | ||
1435 | vec.Z += BulletXScene.Gravity*timeStep; | ||
1436 | } | ||
1437 | //Lowgravity with movement | ||
1438 | else if ((_position.Z > BulletXScene.HeightLevel0) | ||
1439 | && (_position.Z <= BulletXScene.HeightLevel1)) | ||
1440 | { | ||
1441 | vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor); | ||
1442 | } | ||
1443 | //Lowgravity with... | ||
1444 | else if (_position.Z > BulletXScene.HeightLevel1) | ||
1445 | { | ||
1446 | if (vec.Z > 0) //no movement | ||
1447 | vec.Z = BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor); | ||
1448 | else | ||
1449 | vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor); | ||
1450 | } | ||
1451 | } | ||
1452 | rigidBody.LinearVelocity = vec; | ||
1453 | } | ||
1454 | |||
1455 | //This validation is very basic | ||
1456 | internal override void ValidateHeight(float heighmapPositionValue) | ||
1457 | { | ||
1458 | if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f) | ||
1459 | { | ||
1460 | Matrix m = rigidBody.WorldTransform; | ||
1461 | Vector3 v3 = m.Translation; | ||
1462 | v3.Z = heighmapPositionValue + _size.Z/2.0f; | ||
1463 | m.Translation = v3; | ||
1464 | rigidBody.WorldTransform = m; | ||
1465 | //When an Avie touch the ground it's vertical velocity it's reduced to ZERO | ||
1466 | Speed(new OpenMetaverse.Vector3(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f)); | ||
1467 | } | ||
1468 | } | ||
1469 | |||
1470 | internal override void UpdateKinetics() | ||
1471 | { | ||
1472 | _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition); | ||
1473 | _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity); | ||
1474 | //Orientation it seems that it will be the default. | ||
1475 | ReOrient(); | ||
1476 | } | ||
1477 | } | ||
1478 | |||
1479 | /// <summary> | ||
1480 | /// PhysicsActor Prim Class for BulletX | ||
1481 | /// </summary> | ||
1482 | public class BulletXPrim : BulletXActor | ||
1483 | { | ||
1484 | //Density it will depends of material. | ||
1485 | //For now all prims have the same density, all prims are made of water. Be water my friend! :D | ||
1486 | private const float _density = 1000.0f; | ||
1487 | private BulletXScene _parent_scene; | ||
1488 | private OpenMetaverse.Vector3 m_prev_position; | ||
1489 | private bool m_lastUpdateSent = false; | ||
1490 | //added by jed zhu | ||
1491 | private IMesh _mesh; | ||
1492 | public IMesh GetMesh() { return _mesh; } | ||
1493 | |||
1494 | |||
1495 | |||
1496 | public BulletXPrim(String primName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 size, | ||
1497 | OpenMetaverse.Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical) | ||
1498 | : this( | ||
1499 | primName, parent_scene, pos, OpenMetaverse.Vector3.Zero, size, OpenMetaverse.Vector3.Zero, rotation, mesh, pbs, | ||
1500 | isPhysical) | ||
1501 | { | ||
1502 | } | ||
1503 | |||
1504 | public BulletXPrim(String primName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 velocity, | ||
1505 | OpenMetaverse.Vector3 size, | ||
1506 | OpenMetaverse.Vector3 acceleration, OpenMetaverse.Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, | ||
1507 | bool isPhysical) | ||
1508 | : base(primName) | ||
1509 | { | ||
1510 | if ((size.X == 0) || (size.Y == 0) || (size.Z == 0)) | ||
1511 | throw new Exception("Size 0"); | ||
1512 | if (OpenMetaverse.Quaternion.Normalize(rotation).Length() == 0f) | ||
1513 | rotation = OpenMetaverse.Quaternion.Identity; | ||
1514 | |||
1515 | _position = pos; | ||
1516 | _physical = isPhysical; | ||
1517 | _velocity = _physical ? velocity : OpenMetaverse.Vector3.Zero; | ||
1518 | _size = size; | ||
1519 | _acceleration = acceleration; | ||
1520 | _orientation = rotation; | ||
1521 | |||
1522 | _parent_scene = parent_scene; | ||
1523 | |||
1524 | CreateRigidBody(parent_scene, mesh, pos, size); | ||
1525 | } | ||
1526 | |||
1527 | public override int PhysicsActorType | ||
1528 | { | ||
1529 | get { return (int) ActorTypes.Prim; } | ||
1530 | set { return; } | ||
1531 | } | ||
1532 | |||
1533 | public override OpenMetaverse.Vector3 Position | ||
1534 | { | ||
1535 | get { return base.Position; } | ||
1536 | set { base.Position = value; } | ||
1537 | } | ||
1538 | |||
1539 | public override OpenMetaverse.Vector3 Velocity | ||
1540 | { | ||
1541 | get { return base.Velocity; } | ||
1542 | set { base.Velocity = value; } | ||
1543 | } | ||
1544 | |||
1545 | public override OpenMetaverse.Vector3 Size | ||
1546 | { | ||
1547 | get { return _size; } | ||
1548 | set | ||
1549 | { | ||
1550 | lock (BulletXScene.BulletXLock) | ||
1551 | { | ||
1552 | _size = value; | ||
1553 | ReSize(); | ||
1554 | } | ||
1555 | } | ||
1556 | } | ||
1557 | |||
1558 | public override OpenMetaverse.Vector3 Acceleration | ||
1559 | { | ||
1560 | get { return base.Acceleration; } | ||
1561 | } | ||
1562 | |||
1563 | public override OpenMetaverse.Quaternion Orientation | ||
1564 | { | ||
1565 | get { return base.Orientation; } | ||
1566 | set { base.Orientation = value; } | ||
1567 | } | ||
1568 | |||
1569 | public override float ActorMass | ||
1570 | { | ||
1571 | get | ||
1572 | { | ||
1573 | //For now all prims are boxes | ||
1574 | return (_physical ? 1 : 0)*_density*_size.X*_size.Y*_size.Z; | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | public override bool IsPhysical | ||
1579 | { | ||
1580 | get { return base.IsPhysical; } | ||
1581 | set | ||
1582 | { | ||
1583 | base.IsPhysical = value; | ||
1584 | if (value) | ||
1585 | { | ||
1586 | //--- | ||
1587 | PhysicsPluginManager.PhysicsPluginMessage("Physical - Recreate", true); | ||
1588 | //--- | ||
1589 | ReCreateRigidBody(_size); | ||
1590 | } | ||
1591 | else | ||
1592 | { | ||
1593 | //--- | ||
1594 | PhysicsPluginManager.PhysicsPluginMessage("Physical - SetMassProps", true); | ||
1595 | //--- | ||
1596 | rigidBody.SetMassProps(Mass, new Vector3()); | ||
1597 | } | ||
1598 | } | ||
1599 | } | ||
1600 | |||
1601 | public override bool Flying | ||
1602 | { | ||
1603 | get { return base.Flying; } | ||
1604 | set { base.Flying = value; } | ||
1605 | } | ||
1606 | |||
1607 | public override bool IsColliding | ||
1608 | { | ||
1609 | get { return base.IsColliding; } | ||
1610 | set { base.IsColliding = value; } | ||
1611 | } | ||
1612 | |||
1613 | public override bool Kinematic | ||
1614 | { | ||
1615 | get { return base.Kinematic; } | ||
1616 | set { base.Kinematic = value; } | ||
1617 | } | ||
1618 | |||
1619 | public override void SetAcceleration(OpenMetaverse.Vector3 accel) | ||
1620 | { | ||
1621 | lock (BulletXScene.BulletXLock) | ||
1622 | { | ||
1623 | _acceleration = accel; | ||
1624 | } | ||
1625 | } | ||
1626 | |||
1627 | public override void AddForce(OpenMetaverse.Vector3 force, bool pushforce) | ||
1628 | { | ||
1629 | base.AddForce(force,pushforce); | ||
1630 | } | ||
1631 | |||
1632 | public override void SetMomentum(OpenMetaverse.Vector3 momentum) | ||
1633 | { | ||
1634 | base.SetMomentum(momentum); | ||
1635 | } | ||
1636 | |||
1637 | internal override void ValidateHeight(float heighmapPositionValue) | ||
1638 | { | ||
1639 | if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f) | ||
1640 | { | ||
1641 | Matrix m = rigidBody.WorldTransform; | ||
1642 | Vector3 v3 = m.Translation; | ||
1643 | v3.Z = heighmapPositionValue + _size.Z/2.0f; | ||
1644 | m.Translation = v3; | ||
1645 | rigidBody.WorldTransform = m; | ||
1646 | //When a Prim touch the ground it's vertical velocity it's reduced to ZERO | ||
1647 | //Static objects don't have linear velocity | ||
1648 | if (_physical) | ||
1649 | Speed(new OpenMetaverse.Vector3(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f)); | ||
1650 | } | ||
1651 | } | ||
1652 | |||
1653 | internal override void UpdateKinetics() | ||
1654 | { | ||
1655 | if (_physical) //Updates properties. Prim updates its properties physically | ||
1656 | { | ||
1657 | _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition); | ||
1658 | |||
1659 | _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity); | ||
1660 | _orientation = BulletXMaths.XnaQuaternionToQuaternion(rigidBody.Orientation); | ||
1661 | |||
1662 | if ((Math.Abs(m_prev_position.X - _position.X) < 0.03) | ||
1663 | && (Math.Abs(m_prev_position.Y - _position.Y) < 0.03) | ||
1664 | && (Math.Abs(m_prev_position.Z - _position.Z) < 0.03)) | ||
1665 | { | ||
1666 | if (!m_lastUpdateSent) | ||
1667 | { | ||
1668 | _velocity = OpenMetaverse.Vector3.Zero; | ||
1669 | base.ScheduleTerseUpdate(); | ||
1670 | m_lastUpdateSent = true; | ||
1671 | } | ||
1672 | } | ||
1673 | else | ||
1674 | { | ||
1675 | m_lastUpdateSent = false; | ||
1676 | base.ScheduleTerseUpdate(); | ||
1677 | } | ||
1678 | m_prev_position = _position; | ||
1679 | } | ||
1680 | else //Doesn't updates properties. That's a cancel | ||
1681 | { | ||
1682 | Translate(); | ||
1683 | //Speed(); //<- Static objects don't have linear velocity | ||
1684 | ReOrient(); | ||
1685 | } | ||
1686 | } | ||
1687 | |||
1688 | #region Methods for updating values of RigidBody | ||
1689 | |||
1690 | protected internal void CreateRigidBody(BulletXScene parent_scene, IMesh mesh, OpenMetaverse.Vector3 pos, | ||
1691 | OpenMetaverse.Vector3 size) | ||
1692 | { | ||
1693 | //For RigidBody Constructor. The next values might change | ||
1694 | float _linearDamping = 0.0f; | ||
1695 | float _angularDamping = 0.0f; | ||
1696 | float _friction = 1.0f; | ||
1697 | float _restitution = 0.0f; | ||
1698 | Matrix _startTransform = Matrix.Identity; | ||
1699 | Matrix _centerOfMassOffset = Matrix.Identity; | ||
1700 | //added by jed zhu | ||
1701 | _mesh = mesh; | ||
1702 | |||
1703 | lock (BulletXScene.BulletXLock) | ||
1704 | { | ||
1705 | _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos); | ||
1706 | //For now all prims are boxes | ||
1707 | CollisionShape _collisionShape; | ||
1708 | if (mesh == null) | ||
1709 | { | ||
1710 | _collisionShape = new BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size)/2.0f); | ||
1711 | } | ||
1712 | else | ||
1713 | { | ||
1714 | int iVertexCount = mesh.getVertexList().Count; | ||
1715 | int[] indices = mesh.getIndexListAsInt(); | ||
1716 | Vector3[] v3Vertices = new Vector3[iVertexCount]; | ||
1717 | for (int i = 0; i < iVertexCount; i++) | ||
1718 | { | ||
1719 | OpenMetaverse.Vector3 v = mesh.getVertexList()[i]; | ||
1720 | if (v != null) // Note, null has special meaning. See meshing code for details | ||
1721 | v3Vertices[i] = BulletXMaths.PhysicsVectorToXnaVector3(v); | ||
1722 | else | ||
1723 | v3Vertices[i] = Vector3.Zero; | ||
1724 | } | ||
1725 | TriangleIndexVertexArray triMesh = new TriangleIndexVertexArray(indices, v3Vertices); | ||
1726 | |||
1727 | _collisionShape = new TriangleMeshShape(triMesh); | ||
1728 | } | ||
1729 | DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset); | ||
1730 | Vector3 _localInertia = new Vector3(); | ||
1731 | if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0 | ||
1732 | rigidBody = | ||
1733 | new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, | ||
1734 | _friction, _restitution); | ||
1735 | //rigidBody.ActivationState = ActivationState.DisableDeactivation; | ||
1736 | //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition | ||
1737 | Vector3 _vDebugTranslation; | ||
1738 | _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition; | ||
1739 | rigidBody.Translate(_vDebugTranslation); | ||
1740 | //--- | ||
1741 | parent_scene.ddWorld.AddRigidBody(rigidBody); | ||
1742 | } | ||
1743 | } | ||
1744 | |||
1745 | protected internal void ReCreateRigidBody(OpenMetaverse.Vector3 size) | ||
1746 | { | ||
1747 | //There is a bug when trying to remove a rigidBody that is colliding with something.. | ||
1748 | try | ||
1749 | { | ||
1750 | _parent_scene.ddWorld.RemoveRigidBody(rigidBody); | ||
1751 | } | ||
1752 | catch (Exception ex) | ||
1753 | { | ||
1754 | BulletXScene.BulletXMessage(_parent_scene.is_ex_message + ex.Message, true); | ||
1755 | rigidBody.ActivationState = ActivationState.DisableSimulation; | ||
1756 | _parent_scene.AddForgottenRigidBody(rigidBody); | ||
1757 | } | ||
1758 | CreateRigidBody(_parent_scene, null, _position, size); | ||
1759 | // Note, null for the meshing definitely is wrong. It's here for the moment to apease the compiler | ||
1760 | if (_physical) Speed(); //Static objects don't have linear velocity | ||
1761 | ReOrient(); | ||
1762 | GC.Collect(); | ||
1763 | } | ||
1764 | |||
1765 | protected internal override void ReSize(OpenMetaverse.Vector3 _newSize) | ||
1766 | { | ||
1767 | //I wonder to know how to resize with a simple instruction in BulletX. It seems that for now there isn't | ||
1768 | //so i have to do it manually. That's recreating rigidbody | ||
1769 | ReCreateRigidBody(_newSize); | ||
1770 | } | ||
1771 | |||
1772 | #endregion | ||
1773 | } | ||
1774 | |||
1775 | /// <summary> | ||
1776 | /// This Class manage a HeighField as a RigidBody. This is for to be added in the BulletXScene | ||
1777 | /// </summary> | ||
1778 | internal class BulletXPlanet | ||
1779 | { | ||
1780 | private OpenMetaverse.Vector3 _staticPosition; | ||
1781 | // private Vector3 _staticVelocity; | ||
1782 | // private OpenMetaverse.Quaternion _staticOrientation; | ||
1783 | private float _mass; | ||
1784 | // private BulletXScene _parentscene; | ||
1785 | internal float[] _heightField; | ||
1786 | private RigidBody _flatPlanet; | ||
1787 | |||
1788 | internal RigidBody RigidBody | ||
1789 | { | ||
1790 | get { return _flatPlanet; } | ||
1791 | } | ||
1792 | |||
1793 | internal BulletXPlanet(BulletXScene parent_scene, float[] heightField) | ||
1794 | { | ||
1795 | _staticPosition = new OpenMetaverse.Vector3(BulletXScene.MaxXY / 2, BulletXScene.MaxXY / 2, 0); | ||
1796 | // _staticVelocity = new PhysicsVector(); | ||
1797 | // _staticOrientation = OpenMetaverse.Quaternion.Identity; | ||
1798 | _mass = 0; //No active | ||
1799 | // _parentscene = parent_scene; | ||
1800 | _heightField = heightField; | ||
1801 | |||
1802 | float _linearDamping = 0.0f; | ||
1803 | float _angularDamping = 0.0f; | ||
1804 | float _friction = 0.5f; | ||
1805 | float _restitution = 0.0f; | ||
1806 | Matrix _startTransform = Matrix.Identity; | ||
1807 | Matrix _centerOfMassOffset = Matrix.Identity; | ||
1808 | |||
1809 | lock (BulletXScene.BulletXLock) | ||
1810 | { | ||
1811 | try | ||
1812 | { | ||
1813 | _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(_staticPosition); | ||
1814 | CollisionShape _collisionShape = | ||
1815 | new HeightfieldTerrainShape(BulletXScene.MaxXY, BulletXScene.MaxXY, _heightField, | ||
1816 | (float) BulletXScene.MaxZ, 2, true, false); | ||
1817 | DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset); | ||
1818 | Vector3 _localInertia = new Vector3(); | ||
1819 | //_collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0 | ||
1820 | _flatPlanet = | ||
1821 | new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, | ||
1822 | _angularDamping, _friction, _restitution); | ||
1823 | //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition | ||
1824 | Vector3 _vDebugTranslation; | ||
1825 | _vDebugTranslation = _startTransform.Translation - _flatPlanet.CenterOfMassPosition; | ||
1826 | _flatPlanet.Translate(_vDebugTranslation); | ||
1827 | parent_scene.ddWorld.AddRigidBody(_flatPlanet); | ||
1828 | } | ||
1829 | catch (Exception ex) | ||
1830 | { | ||
1831 | BulletXScene.BulletXMessage(ex.Message, true); | ||
1832 | } | ||
1833 | } | ||
1834 | BulletXScene.BulletXMessage("BulletXPlanet created.", false); | ||
1835 | } | ||
1836 | |||
1837 | internal float HeightValue(Vector3 position) | ||
1838 | { | ||
1839 | int li_x, li_y; | ||
1840 | float height; | ||
1841 | li_x = (int) Math.Round(position.X); | ||
1842 | if (li_x < 0) li_x = 0; | ||
1843 | if (li_x >= BulletXScene.MaxXY) li_x = BulletXScene.MaxXY - 1; | ||
1844 | li_y = (int) Math.Round(position.Y); | ||
1845 | if (li_y < 0) li_y = 0; | ||
1846 | if (li_y >= BulletXScene.MaxXY) li_y = BulletXScene.MaxXY - 1; | ||
1847 | |||
1848 | height = ((HeightfieldTerrainShape) _flatPlanet.CollisionShape).getHeightFieldValue(li_x, li_y); | ||
1849 | if (height < 0) height = 0; | ||
1850 | else if (height > BulletXScene.MaxZ) height = BulletXScene.MaxZ; | ||
1851 | |||
1852 | return height; | ||
1853 | } | ||
1854 | } | ||
1855 | } | ||