diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs | 642 |
1 files changed, 642 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs new file mode 100644 index 0000000..4fcf035 --- /dev/null +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs | |||
@@ -0,0 +1,642 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Reflection; | ||
4 | using System.IO; | ||
5 | using System.Diagnostics; | ||
6 | using System.Threading; | ||
7 | using log4net; | ||
8 | using Nini.Config; | ||
9 | using OpenSim.Framework; | ||
10 | using OpenSim.Region.Physics.Manager; | ||
11 | using OpenMetaverse; | ||
12 | using BulletDotNET; | ||
13 | |||
14 | namespace OpenSim.Region.Physics.BulletDotNETPlugin | ||
15 | { | ||
16 | public class BulletDotNETScene : PhysicsScene | ||
17 | { | ||
18 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
19 | |||
20 | private string m_sceneIdentifier = string.Empty; | ||
21 | |||
22 | private List<BulletDotNETCharacter> m_characters = new List<BulletDotNETCharacter>(); | ||
23 | private List<BulletDotNETPrim> m_prims = new List<BulletDotNETPrim>(); | ||
24 | private List<BulletDotNETPrim> m_activePrims = new List<BulletDotNETPrim>(); | ||
25 | private List<PhysicsActor> m_taintedActors = new List<PhysicsActor>(); | ||
26 | private btDiscreteDynamicsWorld m_world; | ||
27 | private btAxisSweep3 m_broadphase; | ||
28 | private btCollisionConfiguration m_collisionConfiguration; | ||
29 | private btConstraintSolver m_solver; | ||
30 | private btCollisionDispatcher m_dispatcher; | ||
31 | private btHeightfieldTerrainShape m_terrainShape; | ||
32 | public btRigidBody TerrainBody; | ||
33 | private btVector3 m_terrainPosition; | ||
34 | private btVector3 m_gravity; | ||
35 | public btMotionState m_terrainMotionState; | ||
36 | public btTransform m_terrainTransform; | ||
37 | public btVector3 VectorZero; | ||
38 | public btQuaternion QuatIdentity; | ||
39 | public btTransform TransZero; | ||
40 | |||
41 | public float geomDefaultDensity = 10.000006836f; | ||
42 | |||
43 | private float avPIDD = 65f; | ||
44 | private float avPIDP = 28f; | ||
45 | private float avCapRadius = 0.37f; | ||
46 | private float avStandupTensor = 2000000f; | ||
47 | private float avDensity = 80f; | ||
48 | private float avHeightFudgeFactor = 0.52f; | ||
49 | private float avMovementDivisorWalk = 1.0f; | ||
50 | private float avMovementDivisorRun = 0.75f; | ||
51 | |||
52 | private float minimumGroundFlightOffset = 3f; | ||
53 | |||
54 | public bool meshSculptedPrim = true; | ||
55 | |||
56 | public float meshSculptLOD = 32; | ||
57 | public float MeshSculptphysicalLOD = 16; | ||
58 | |||
59 | public float bodyPIDD = 35f; | ||
60 | public float bodyPIDG = 25; | ||
61 | internal int geomCrossingFailuresBeforeOutofbounds = 4; | ||
62 | |||
63 | public float bodyMotorJointMaxforceTensor = 2; | ||
64 | |||
65 | public int bodyFramesAutoDisable = 20; | ||
66 | |||
67 | public float WorldTimeStep = 10f/60f; | ||
68 | public const float WorldTimeComp = 1/60f; | ||
69 | public float gravityz = -9.8f; | ||
70 | |||
71 | private float[] _origheightmap; // Used for Fly height. Kitto Flora | ||
72 | private bool usingGImpactAlgorithm = false; | ||
73 | |||
74 | private IConfigSource m_config; | ||
75 | private readonly btVector3 worldAabbMin = new btVector3(0, 0, 0); | ||
76 | private readonly btVector3 worldAabbMax = new btVector3(Constants.RegionSize, Constants.RegionSize , 9000); | ||
77 | |||
78 | public IMesher mesher; | ||
79 | |||
80 | public BulletDotNETScene(string sceneIdentifier) | ||
81 | { | ||
82 | m_sceneIdentifier = sceneIdentifier; | ||
83 | VectorZero = new btVector3(0, 0, 0); | ||
84 | QuatIdentity = new btQuaternion(0, 0, 0, 1); | ||
85 | TransZero = new btTransform(QuatIdentity, VectorZero); | ||
86 | m_gravity = new btVector3(0, 0, gravityz); | ||
87 | _origheightmap = new float[(int)Constants.RegionSize * (int)Constants.RegionSize]; | ||
88 | } | ||
89 | |||
90 | public override void Initialise(IMesher meshmerizer, IConfigSource config) | ||
91 | { | ||
92 | mesher = meshmerizer; | ||
93 | m_config = config; | ||
94 | if (Environment.OSVersion.Platform == PlatformID.Unix) | ||
95 | { | ||
96 | m_log.Fatal("[BulletDotNET]: This configuration is not supported on *nix currently"); | ||
97 | Thread.Sleep(5000); | ||
98 | Environment.Exit(0); | ||
99 | } | ||
100 | m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax, 16000); | ||
101 | m_collisionConfiguration = new btDefaultCollisionConfiguration(); | ||
102 | m_solver = new btSequentialImpulseConstraintSolver(); | ||
103 | m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); | ||
104 | m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); | ||
105 | m_world.setGravity(m_gravity); | ||
106 | } | ||
107 | |||
108 | public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size, bool isFlying) | ||
109 | { | ||
110 | BulletDotNETCharacter chr = new BulletDotNETCharacter(avName, this, position, size, avPIDD, avPIDP, | ||
111 | avCapRadius, avStandupTensor, avDensity, | ||
112 | avHeightFudgeFactor, avMovementDivisorWalk, | ||
113 | avMovementDivisorRun); | ||
114 | m_characters.Add(chr); | ||
115 | AddPhysicsActorTaint(chr); | ||
116 | return chr; | ||
117 | } | ||
118 | |||
119 | public override void RemoveAvatar(PhysicsActor actor) | ||
120 | { | ||
121 | BulletDotNETCharacter chr = (BulletDotNETCharacter) actor; | ||
122 | |||
123 | m_characters.Remove(chr); | ||
124 | m_world.removeRigidBody(chr.Body); | ||
125 | m_world.removeCollisionObject(chr.Body); | ||
126 | |||
127 | chr.Remove(); | ||
128 | AddPhysicsActorTaint(chr); | ||
129 | //chr = null; | ||
130 | } | ||
131 | |||
132 | public override void RemovePrim(PhysicsActor prim) | ||
133 | { | ||
134 | if (prim is BulletDotNETPrim) | ||
135 | { | ||
136 | |||
137 | BulletDotNETPrim p = (BulletDotNETPrim)prim; | ||
138 | |||
139 | p.setPrimForRemoval(); | ||
140 | AddPhysicsActorTaint(prim); | ||
141 | //RemovePrimThreadLocked(p); | ||
142 | |||
143 | } | ||
144 | } | ||
145 | |||
146 | private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation, | ||
147 | IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) | ||
148 | { | ||
149 | PhysicsVector pos = new PhysicsVector(position.X, position.Y, position.Z); | ||
150 | //pos.X = position.X; | ||
151 | //pos.Y = position.Y; | ||
152 | //pos.Z = position.Z; | ||
153 | PhysicsVector siz = new PhysicsVector(); | ||
154 | siz.X = size.X; | ||
155 | siz.Y = size.Y; | ||
156 | siz.Z = size.Z; | ||
157 | Quaternion rot = rotation; | ||
158 | |||
159 | BulletDotNETPrim newPrim; | ||
160 | |||
161 | newPrim = new BulletDotNETPrim(name, this, pos, siz, rot, mesh, pbs, isphysical); | ||
162 | |||
163 | lock (m_prims) | ||
164 | m_prims.Add(newPrim); | ||
165 | |||
166 | |||
167 | return newPrim; | ||
168 | } | ||
169 | |||
170 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, PhysicsVector size, Quaternion rotation) | ||
171 | { | ||
172 | return AddPrimShape(primName, pbs, position, size, rotation, false); | ||
173 | } | ||
174 | |||
175 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, PhysicsVector size, Quaternion rotation, bool isPhysical) | ||
176 | { | ||
177 | PhysicsActor result; | ||
178 | IMesh mesh = null; | ||
179 | |||
180 | //switch (pbs.ProfileShape) | ||
181 | //{ | ||
182 | // case ProfileShape.Square: | ||
183 | // //support simple box & hollow box now; later, more shapes | ||
184 | // if (needsMeshing(pbs)) | ||
185 | // { | ||
186 | // mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); | ||
187 | // } | ||
188 | |||
189 | // break; | ||
190 | //} | ||
191 | |||
192 | if (needsMeshing(pbs)) | ||
193 | mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); | ||
194 | |||
195 | result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical); | ||
196 | |||
197 | return result; | ||
198 | } | ||
199 | |||
200 | public override void AddPhysicsActorTaint(PhysicsActor prim) | ||
201 | { | ||
202 | lock (m_taintedActors) | ||
203 | { | ||
204 | if (!m_taintedActors.Contains(prim)) | ||
205 | { | ||
206 | m_taintedActors.Add(prim); | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | internal void SetUsingGImpact() | ||
211 | { | ||
212 | if (!usingGImpactAlgorithm) | ||
213 | btGImpactCollisionAlgorithm.registerAlgorithm(m_dispatcher); | ||
214 | usingGImpactAlgorithm = true; | ||
215 | } | ||
216 | |||
217 | public override float Simulate(float timeStep) | ||
218 | { | ||
219 | lock (m_taintedActors) | ||
220 | { | ||
221 | foreach (PhysicsActor act in m_taintedActors) | ||
222 | { | ||
223 | if (act is BulletDotNETCharacter) | ||
224 | ((BulletDotNETCharacter) act).ProcessTaints(timeStep); | ||
225 | if (act is BulletDotNETPrim) | ||
226 | ((BulletDotNETPrim)act).ProcessTaints(timeStep); | ||
227 | } | ||
228 | m_taintedActors.Clear(); | ||
229 | } | ||
230 | |||
231 | lock (m_characters) | ||
232 | { | ||
233 | foreach (BulletDotNETCharacter chr in m_characters) | ||
234 | { | ||
235 | chr.Move(timeStep); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | lock (m_prims) | ||
240 | { | ||
241 | foreach (BulletDotNETPrim prim in m_prims) | ||
242 | { | ||
243 | prim.Move(timeStep); | ||
244 | } | ||
245 | } | ||
246 | float steps = m_world.stepSimulation(WorldTimeStep, 5, WorldTimeComp); | ||
247 | |||
248 | foreach (BulletDotNETCharacter chr in m_characters) | ||
249 | { | ||
250 | chr.UpdatePositionAndVelocity(); | ||
251 | } | ||
252 | |||
253 | foreach (BulletDotNETPrim prm in m_activePrims) | ||
254 | { | ||
255 | prm.UpdatePositionAndVelocity(); | ||
256 | } | ||
257 | |||
258 | return steps; | ||
259 | } | ||
260 | |||
261 | public override void GetResults() | ||
262 | { | ||
263 | |||
264 | } | ||
265 | |||
266 | public override void SetTerrain(float[] heightMap) | ||
267 | { | ||
268 | if (m_terrainShape != null) | ||
269 | DeleteTerrain(); | ||
270 | |||
271 | float hfmax = -9000; | ||
272 | float hfmin = 90000; | ||
273 | |||
274 | for (int i = 0; i <heightMap.Length;i++) | ||
275 | { | ||
276 | if (Single.IsNaN(heightMap[i]) || Single.IsInfinity(heightMap[i])) | ||
277 | { | ||
278 | heightMap[i] = 0f; | ||
279 | } | ||
280 | |||
281 | hfmin = (heightMap[i] < hfmin) ? heightMap[i] : hfmin; | ||
282 | hfmax = (heightMap[i] > hfmax) ? heightMap[i] : hfmax; | ||
283 | } | ||
284 | // store this for later reference. | ||
285 | // Note, we're storing it after we check it for anomolies above | ||
286 | _origheightmap = heightMap; | ||
287 | |||
288 | hfmin = 0; | ||
289 | hfmax = 256; | ||
290 | |||
291 | m_terrainShape = new btHeightfieldTerrainShape((int)Constants.RegionSize, (int)Constants.RegionSize, heightMap, | ||
292 | 1.0f, hfmin, hfmax, (int)btHeightfieldTerrainShape.UPAxis.Z, | ||
293 | (int)btHeightfieldTerrainShape.PHY_ScalarType.PHY_FLOAT, false); | ||
294 | float AabbCenterX = Constants.RegionSize/2f; | ||
295 | float AabbCenterY = Constants.RegionSize/2f; | ||
296 | |||
297 | float AabbCenterZ = 0; | ||
298 | float temphfmin, temphfmax; | ||
299 | |||
300 | temphfmin = hfmin; | ||
301 | temphfmax = hfmax; | ||
302 | |||
303 | if (temphfmin < 0) | ||
304 | { | ||
305 | temphfmax = 0 - temphfmin; | ||
306 | temphfmin = 0 - temphfmin; | ||
307 | } | ||
308 | else if (temphfmin > 0) | ||
309 | { | ||
310 | temphfmax = temphfmax + (0 - temphfmin); | ||
311 | //temphfmin = temphfmin + (0 - temphfmin); | ||
312 | } | ||
313 | AabbCenterZ = temphfmax/2f; | ||
314 | |||
315 | if (m_terrainPosition == null) | ||
316 | { | ||
317 | m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ); | ||
318 | } | ||
319 | else | ||
320 | { | ||
321 | try | ||
322 | { | ||
323 | m_terrainPosition.setValue(AabbCenterX, AabbCenterY, AabbCenterZ); | ||
324 | } | ||
325 | catch (ObjectDisposedException) | ||
326 | { | ||
327 | m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ); | ||
328 | } | ||
329 | } | ||
330 | if (m_terrainMotionState != null) | ||
331 | { | ||
332 | m_terrainMotionState.Dispose(); | ||
333 | m_terrainMotionState = null; | ||
334 | } | ||
335 | m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition); | ||
336 | m_terrainMotionState = new btDefaultMotionState(m_terrainTransform); | ||
337 | TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape); | ||
338 | m_world.addRigidBody(TerrainBody); | ||
339 | |||
340 | |||
341 | } | ||
342 | |||
343 | public override void SetWaterLevel(float baseheight) | ||
344 | { | ||
345 | |||
346 | } | ||
347 | |||
348 | public override void DeleteTerrain() | ||
349 | { | ||
350 | if (TerrainBody != null) | ||
351 | { | ||
352 | m_world.removeRigidBody(TerrainBody); | ||
353 | } | ||
354 | |||
355 | if (m_terrainShape != null) | ||
356 | { | ||
357 | m_terrainShape.Dispose(); | ||
358 | m_terrainShape = null; | ||
359 | } | ||
360 | |||
361 | if (m_terrainMotionState != null) | ||
362 | { | ||
363 | m_terrainMotionState.Dispose(); | ||
364 | m_terrainMotionState = null; | ||
365 | } | ||
366 | |||
367 | if (m_terrainTransform != null) | ||
368 | { | ||
369 | m_terrainTransform.Dispose(); | ||
370 | m_terrainTransform = null; | ||
371 | } | ||
372 | |||
373 | if (m_terrainPosition != null) | ||
374 | { | ||
375 | m_terrainPosition.Dispose(); | ||
376 | m_terrainPosition = null; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | public override void Dispose() | ||
381 | { | ||
382 | disposeAllBodies(); | ||
383 | m_world.Dispose(); | ||
384 | m_broadphase.Dispose(); | ||
385 | ((btDefaultCollisionConfiguration) m_collisionConfiguration).Dispose(); | ||
386 | ((btSequentialImpulseConstraintSolver) m_solver).Dispose(); | ||
387 | worldAabbMax.Dispose(); | ||
388 | worldAabbMin.Dispose(); | ||
389 | VectorZero.Dispose(); | ||
390 | QuatIdentity.Dispose(); | ||
391 | m_gravity.Dispose(); | ||
392 | VectorZero = null; | ||
393 | QuatIdentity = null; | ||
394 | } | ||
395 | |||
396 | public override Dictionary<uint, float> GetTopColliders() | ||
397 | { | ||
398 | return new Dictionary<uint, float>(); | ||
399 | } | ||
400 | |||
401 | public btDiscreteDynamicsWorld getBulletWorld() | ||
402 | { | ||
403 | return m_world; | ||
404 | } | ||
405 | |||
406 | private void disposeAllBodies() | ||
407 | { | ||
408 | lock (m_prims) | ||
409 | { | ||
410 | foreach ( BulletDotNETPrim prim in m_prims) | ||
411 | { | ||
412 | if (prim.Body != null) | ||
413 | m_world.removeRigidBody(prim.Body); | ||
414 | |||
415 | prim.Dispose(); | ||
416 | } | ||
417 | m_prims.Clear(); | ||
418 | |||
419 | foreach (BulletDotNETCharacter chr in m_characters) | ||
420 | { | ||
421 | if (chr.Body != null) | ||
422 | m_world.removeRigidBody(chr.Body); | ||
423 | chr.Dispose(); | ||
424 | } | ||
425 | m_characters.Clear(); | ||
426 | } | ||
427 | } | ||
428 | |||
429 | public override bool IsThreaded | ||
430 | { | ||
431 | get { return false; } | ||
432 | } | ||
433 | |||
434 | internal void addCollisionEventReporting(PhysicsActor bulletDotNETCharacter) | ||
435 | { | ||
436 | //TODO: FIXME: | ||
437 | } | ||
438 | |||
439 | internal void remCollisionEventReporting(PhysicsActor bulletDotNETCharacter) | ||
440 | { | ||
441 | //TODO: FIXME: | ||
442 | } | ||
443 | |||
444 | internal void AddRigidBody(btRigidBody Body) | ||
445 | { | ||
446 | m_world.addRigidBody(Body); | ||
447 | } | ||
448 | [Obsolete("bad!")] | ||
449 | internal void removeFromWorld(btRigidBody body) | ||
450 | { | ||
451 | |||
452 | m_world.removeRigidBody(body); | ||
453 | } | ||
454 | |||
455 | internal void removeFromWorld(BulletDotNETPrim prm ,btRigidBody body) | ||
456 | { | ||
457 | lock (m_prims) | ||
458 | { | ||
459 | if (m_prims.Contains(prm)) | ||
460 | { | ||
461 | m_world.removeRigidBody(body); | ||
462 | } | ||
463 | m_prims.Remove(prm); | ||
464 | } | ||
465 | |||
466 | } | ||
467 | |||
468 | internal float GetWaterLevel() | ||
469 | { | ||
470 | throw new NotImplementedException(); | ||
471 | } | ||
472 | |||
473 | // Recovered for use by fly height. Kitto Flora | ||
474 | public float GetTerrainHeightAtXY(float x, float y) | ||
475 | { | ||
476 | // Teravus: Kitto, this code causes recurring errors that stall physics permenantly unless | ||
477 | // the values are checked, so checking below. | ||
478 | // Is there any reason that we don't do this in ScenePresence? | ||
479 | // The only physics engine that benefits from it in the physics plugin is this one | ||
480 | |||
481 | if ((int)x > Constants.RegionSize || (int)y > Constants.RegionSize || | ||
482 | (int)x < 0.001f || (int)y < 0.001f) | ||
483 | return 0; | ||
484 | |||
485 | return _origheightmap[(int)y * Constants.RegionSize + (int)x]; | ||
486 | } | ||
487 | // End recovered. Kitto Flora | ||
488 | |||
489 | /// <summary> | ||
490 | /// Routine to figure out if we need to mesh this prim with our mesher | ||
491 | /// </summary> | ||
492 | /// <param name="pbs"></param> | ||
493 | /// <returns></returns> | ||
494 | public bool needsMeshing(PrimitiveBaseShape pbs) | ||
495 | { | ||
496 | // most of this is redundant now as the mesher will return null if it cant mesh a prim | ||
497 | // but we still need to check for sculptie meshing being enabled so this is the most | ||
498 | // convenient place to do it for now... | ||
499 | |||
500 | // //if (pbs.PathCurve == (byte)Primitive.PathCurve.Circle && pbs.ProfileCurve == (byte)Primitive.ProfileCurve.Circle && pbs.PathScaleY <= 0.75f) | ||
501 | // //m_log.Debug("needsMeshing: " + " pathCurve: " + pbs.PathCurve.ToString() + " profileCurve: " + pbs.ProfileCurve.ToString() + " pathScaleY: " + Primitive.UnpackPathScale(pbs.PathScaleY).ToString()); | ||
502 | int iPropertiesNotSupportedDefault = 0; | ||
503 | |||
504 | if (pbs.SculptEntry && !meshSculptedPrim) | ||
505 | { | ||
506 | #if SPAM | ||
507 | m_log.Warn("NonMesh"); | ||
508 | #endif | ||
509 | return false; | ||
510 | } | ||
511 | |||
512 | // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim | ||
513 | if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) | ||
514 | || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 | ||
515 | && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)) | ||
516 | { | ||
517 | |||
518 | if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 | ||
519 | && pbs.ProfileHollow == 0 | ||
520 | && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 | ||
521 | && pbs.PathBegin == 0 && pbs.PathEnd == 0 | ||
522 | && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 | ||
523 | && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 | ||
524 | && pbs.PathShearX == 0 && pbs.PathShearY == 0) | ||
525 | { | ||
526 | #if SPAM | ||
527 | m_log.Warn("NonMesh"); | ||
528 | #endif | ||
529 | return false; | ||
530 | } | ||
531 | } | ||
532 | |||
533 | if (pbs.ProfileHollow != 0) | ||
534 | iPropertiesNotSupportedDefault++; | ||
535 | |||
536 | if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) | ||
537 | iPropertiesNotSupportedDefault++; | ||
538 | |||
539 | if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0) | ||
540 | iPropertiesNotSupportedDefault++; | ||
541 | |||
542 | if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100)) | ||
543 | iPropertiesNotSupportedDefault++; | ||
544 | |||
545 | if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0)) | ||
546 | iPropertiesNotSupportedDefault++; | ||
547 | |||
548 | if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight) | ||
549 | iPropertiesNotSupportedDefault++; | ||
550 | |||
551 | if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X)) | ||
552 | iPropertiesNotSupportedDefault++; | ||
553 | |||
554 | if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) | ||
555 | iPropertiesNotSupportedDefault++; | ||
556 | |||
557 | // test for torus | ||
558 | if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square) | ||
559 | { | ||
560 | if (pbs.PathCurve == (byte)Extrusion.Curve1) | ||
561 | { | ||
562 | iPropertiesNotSupportedDefault++; | ||
563 | } | ||
564 | } | ||
565 | else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) | ||
566 | { | ||
567 | if (pbs.PathCurve == (byte)Extrusion.Straight) | ||
568 | { | ||
569 | iPropertiesNotSupportedDefault++; | ||
570 | } | ||
571 | |||
572 | // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits | ||
573 | else if (pbs.PathCurve == (byte)Extrusion.Curve1) | ||
574 | { | ||
575 | iPropertiesNotSupportedDefault++; | ||
576 | } | ||
577 | } | ||
578 | else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) | ||
579 | { | ||
580 | if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2) | ||
581 | { | ||
582 | iPropertiesNotSupportedDefault++; | ||
583 | } | ||
584 | } | ||
585 | else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) | ||
586 | { | ||
587 | if (pbs.PathCurve == (byte)Extrusion.Straight) | ||
588 | { | ||
589 | iPropertiesNotSupportedDefault++; | ||
590 | } | ||
591 | else if (pbs.PathCurve == (byte)Extrusion.Curve1) | ||
592 | { | ||
593 | iPropertiesNotSupportedDefault++; | ||
594 | } | ||
595 | } | ||
596 | |||
597 | |||
598 | if (iPropertiesNotSupportedDefault == 0) | ||
599 | { | ||
600 | #if SPAM | ||
601 | m_log.Warn("NonMesh"); | ||
602 | #endif | ||
603 | return false; | ||
604 | } | ||
605 | #if SPAM | ||
606 | m_log.Debug("Mesh"); | ||
607 | #endif | ||
608 | return true; | ||
609 | } | ||
610 | |||
611 | internal void addActivePrim(BulletDotNETPrim pPrim) | ||
612 | { | ||
613 | lock (m_activePrims) | ||
614 | { | ||
615 | if (!m_activePrims.Contains(pPrim)) | ||
616 | { | ||
617 | m_activePrims.Add(pPrim); | ||
618 | } | ||
619 | } | ||
620 | } | ||
621 | |||
622 | public void remActivePrim(BulletDotNETPrim pDeactivatePrim) | ||
623 | { | ||
624 | lock (m_activePrims) | ||
625 | { | ||
626 | m_activePrims.Remove(pDeactivatePrim); | ||
627 | } | ||
628 | } | ||
629 | |||
630 | internal void AddPrimToScene(BulletDotNETPrim pPrim) | ||
631 | { | ||
632 | lock (m_prims) | ||
633 | { | ||
634 | if (!m_prims.Contains(pPrim)) | ||
635 | { | ||
636 | m_prims.Add(pPrim); | ||
637 | m_world.addRigidBody(pPrim.Body); | ||
638 | } | ||
639 | } | ||
640 | } | ||
641 | } | ||
642 | } | ||