aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletXPlugin
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs58
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs1855
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs197
3 files changed, 0 insertions, 2110 deletions
diff --git a/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs
deleted file mode 100644
index 6383f26..0000000
--- a/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs
+++ /dev/null
@@ -1,58 +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
28using System.Reflection;
29using System.Runtime.InteropServices;
30
31// Information about this assembly is defined by the following
32// attributes.
33//
34// change them to the information which is associated with the assembly
35// you compile.
36
37[assembly : AssemblyTitle("BulletXPlugin")]
38[assembly : AssemblyDescription("")]
39[assembly : AssemblyConfiguration("")]
40[assembly : AssemblyCompany("http://opensimulator.org")]
41[assembly : AssemblyProduct("BulletXPlugin")]
42[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
43[assembly : AssemblyTrademark("")]
44[assembly : AssemblyCulture("")]
45
46// This sets the default COM visibility of types in the assembly to invisible.
47// If you need to expose a type to COM, use [ComVisible(true)] on that type.
48
49[assembly : ComVisible(false)]
50
51// The assembly version has following format :
52//
53// Major.Minor.Build.Revision
54//
55// You can specify all values by your own or you can build default build and revision
56// numbers with the '*' character (the default):
57
58[assembly : AssemblyVersion("0.6.5.*")]
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
30using System;
31using System.Collections.Generic;
32using OpenMetaverse;
33using MonoXnaCompactMaths;
34using OpenSim.Framework;
35using OpenSim.Region.Physics.Manager;
36using XnaDevRu.BulletX;
37using XnaDevRu.BulletX.Dynamics;
38using Nini.Config;
39using Vector3 = MonoXnaCompactMaths.Vector3;
40using Quaternion = MonoXnaCompactMaths.Quaternion;
41
42#endregion
43
44namespace 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}
diff --git a/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs b/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
deleted file mode 100644
index 637cf6e..0000000
--- a/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
+++ /dev/null
@@ -1,197 +0,0 @@
1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/*
23 This file contains a class TriangleIndexVertexArray. I tried using the class with the same name
24 from the BulletX implementation and found it unusable for the purpose of using triangle meshes
25 within BulletX as the implementation was painfully incomplete.
26 The attempt to derive from the original class failed as viable members were hidden.
27 Fiddling around with BulletX itself was not my intention.
28 So I copied the class to the BulletX-plugin and modified it.
29 If you want to fiddle around with it it's up to you to move all this to BulletX.
30 If someone someday implements the missing functionality in BulletX, feel free to remove this class.
31 It's just an ugly hack.
32*/
33
34using System;
35using System.Collections.Generic;
36using MonoXnaCompactMaths;
37using XnaDevRu.BulletX;
38
39namespace OpenSim.Region.Physics.BulletXPlugin
40{
41 /// <summary>
42 /// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
43 /// instead of the number of indices, we pass the number of triangles
44 /// </summary>
45 public struct IndexedMesh
46 {
47 private int _numTriangles;
48 private int[] _triangleIndexBase;
49 private int _triangleIndexStride;
50 private int _numVertices;
51 private Vector3[] _vertexBase;
52 private int _vertexStride;
53
54 public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices,
55 Vector3[] vertexBase, int vertexStride)
56 {
57 _numTriangles = numTriangleIndices;
58 _triangleIndexBase = triangleIndexBase;
59 _triangleIndexStride = triangleIndexStride;
60 _vertexBase = vertexBase;
61 _numVertices = numVertices;
62 _vertexStride = vertexStride;
63 }
64
65 public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase)
66 {
67 _numTriangles = triangleIndexBase.Length;
68 _triangleIndexBase = triangleIndexBase;
69 _triangleIndexStride = 32;
70 _vertexBase = vertexBase;
71 _numVertices = vertexBase.Length;
72 _vertexStride = 24;
73 }
74
75 public int TriangleCount
76 {
77 get { return _numTriangles; }
78 set { _numTriangles = value; }
79 }
80
81 public int[] TriangleIndexBase
82 {
83 get { return _triangleIndexBase; }
84 set { _triangleIndexBase = value; }
85 }
86
87 public int TriangleIndexStride
88 {
89 get { return _triangleIndexStride; }
90 set { _triangleIndexStride = value; }
91 }
92
93 public int VertexCount
94 {
95 get { return _numVertices; }
96 set { _numVertices = value; }
97 }
98
99 public Vector3[] VertexBase
100 {
101 get { return _vertexBase; }
102 set { _vertexBase = value; }
103 }
104
105 public int VertexStride
106 {
107 get { return _vertexStride; }
108 set { _vertexStride = value; }
109 }
110 }
111
112 /// <summary>
113 /// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
114 /// Additional meshes can be added using addIndexedMesh
115 /// </summary>
116 public class TriangleIndexVertexArray : StridingMeshInterface
117 {
118 private List<IndexedMesh> _indexedMeshes = new List<IndexedMesh>();
119
120 public TriangleIndexVertexArray()
121 {
122 }
123
124 public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride,
125 int numVertices, Vector3[] vertexBase, int vertexStride)
126 {
127 IndexedMesh mesh = new IndexedMesh();
128 mesh.TriangleCount = numTriangleIndices;
129 mesh.TriangleIndexBase = triangleIndexBase;
130 mesh.TriangleIndexStride = triangleIndexStride;
131 mesh.VertexBase = vertexBase;
132 mesh.VertexCount = numVertices;
133 mesh.VertexStride = vertexStride;
134
135 AddIndexedMesh(mesh);
136 }
137
138 public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase)
139 : this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24)
140 {
141 }
142
143 public void AddIndexedMesh(IndexedMesh indexedMesh)
144 {
145 _indexedMeshes.Add(indexedMesh);
146 }
147
148 public override void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces,
149 int subpart)
150 {
151 throw new Exception("The method or operation is not implemented.");
152 }
153
154 public override void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies,
155 out int numfaces, int subpart)
156 {
157 IndexedMesh m = _indexedMeshes[0];
158 Vector3[] vertexBase = m.VertexBase;
159 verts = new List<Vector3>();
160 foreach (Vector3 v in vertexBase)
161 {
162 verts.Add(v);
163 }
164 int[] indexBase = m.TriangleIndexBase;
165 indicies = new List<int>();
166 foreach (int i in indexBase)
167 {
168 indicies.Add(i);
169 }
170 numfaces = vertexBase.GetLength(0);
171 }
172
173 public override void UnLockVertexBase(int subpart)
174 {
175 throw new Exception("The method or operation is not implemented.");
176 }
177
178 public override void UnLockReadOnlyVertexBase(int subpart)
179 {
180 }
181
182 public override int SubPartsCount()
183 {
184 return _indexedMeshes.Count;
185 }
186
187 public override void PreallocateVertices(int numverts)
188 {
189 throw new Exception("The method or operation is not implemented.");
190 }
191
192 public override void PreallocateIndices(int numindices)
193 {
194 throw new Exception("The method or operation is not implemented.");
195 }
196 }
197}