aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs238
1 files changed, 150 insertions, 88 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 6103320..527a5cc 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -16,7 +16,7 @@
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMEd. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
@@ -56,6 +56,8 @@ namespace OpenSim.Region.Physics.OdePlugin
56 public bool m_taintremove = false; 56 public bool m_taintremove = false;
57 public bool m_taintdisable = false; 57 public bool m_taintdisable = false;
58 public bool m_disabled = false; 58 public bool m_disabled = false;
59 public bool m_taintadd = false;
60 private CollisionLocker ode;
59 61
60 private bool m_taintforce = false; 62 private bool m_taintforce = false;
61 private List<PhysicsVector> m_forcelist = new List<PhysicsVector>(); 63 private List<PhysicsVector> m_forcelist = new List<PhysicsVector>();
@@ -74,6 +76,7 @@ namespace OpenSim.Region.Physics.OdePlugin
74 public int m_interpenetrationcount = 0; 76 public int m_interpenetrationcount = 0;
75 public int m_collisionscore = 0; 77 public int m_collisionscore = 0;
76 public int m_roundsUnderMotionThreshold = 0; 78 public int m_roundsUnderMotionThreshold = 0;
79 private int m_crossingfailures = 0;
77 80
78 public bool outofBounds = false; 81 public bool outofBounds = false;
79 private float m_density = 10.000006836f; // Aluminum g/cm3; 82 private float m_density = 10.000006836f; // Aluminum g/cm3;
@@ -90,9 +93,9 @@ namespace OpenSim.Region.Physics.OdePlugin
90 private int debugcounter = 0; 93 private int debugcounter = 0;
91 94
92 public OdePrim(String primName, OdeScene parent_scene, IntPtr targetSpace, PhysicsVector pos, PhysicsVector size, 95 public OdePrim(String primName, OdeScene parent_scene, IntPtr targetSpace, PhysicsVector pos, PhysicsVector size,
93 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical) 96 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
94 { 97 {
95 98 ode = dode;
96 _velocity = new PhysicsVector(); 99 _velocity = new PhysicsVector();
97 _position = pos; 100 _position = pos;
98 m_taintposition = pos; 101 m_taintposition = pos;
@@ -136,86 +139,11 @@ namespace OpenSim.Region.Physics.OdePlugin
136 m_targetSpace = _parent_scene.space; 139 m_targetSpace = _parent_scene.space;
137 } 140 }
138 m_primName = primName; 141 m_primName = primName;
139 if (mesh != null) 142 m_taintadd = true;
140 { 143 _parent_scene.AddPhysicsActorTaint(this);
141 } 144 // don't do .add() here; old geoms get recycled with the same hash
142 else 145 parent_scene.geom_name_map[prim_geom] = primName;
143 { 146 parent_scene.actor_name_map[prim_geom] = (PhysicsActor) this;
144 if (_parent_scene.needsMeshing(_pbs))
145 {
146 // Don't need to re-enable body.. it's done in SetMesh
147 mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size);
148 // createmesh returns null when it's a shape that isn't a cube.
149 }
150 }
151
152 lock (OdeScene.OdeLock)
153 {
154 if (mesh != null)
155 {
156 setMesh(parent_scene, mesh);
157 }
158 else
159 {
160 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
161 {
162 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
163 {
164 if (((_size.X / 2f) > 0f))
165 {
166
167
168 _parent_scene.waitForSpaceUnlock(m_targetSpace);
169 prim_geom = d.CreateSphere(m_targetSpace, _size.X / 2);
170 }
171 else
172 {
173 _parent_scene.waitForSpaceUnlock(m_targetSpace);
174 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
175 }
176 }
177 else
178 {
179 _parent_scene.waitForSpaceUnlock(m_targetSpace);
180 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
181 }
182 }
183 //else if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
184 //{
185 //Cyllinder
186 //if (_size.X == _size.Y)
187 //{
188 //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
189 //}
190 //else
191 //{
192 //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
193 //}
194 //}
195 else
196 {
197 _parent_scene.waitForSpaceUnlock(m_targetSpace);
198 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
199 }
200 }
201
202 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
203 d.Quaternion myrot = new d.Quaternion();
204 myrot.W = rotation.w;
205 myrot.X = rotation.x;
206 myrot.Y = rotation.y;
207 myrot.Z = rotation.z;
208 d.GeomSetQuaternion(prim_geom, ref myrot);
209
210
211 if (m_isphysical && Body == (IntPtr) 0)
212 {
213 enableBody();
214 }
215 parent_scene.geom_name_map[prim_geom] = primName;
216 parent_scene.actor_name_map[prim_geom] = (PhysicsActor) this;
217 // don't do .add() here; old geoms get recycled with the same hash
218 }
219 } 147 }
220 148
221 /// <summary> 149 /// <summary>
@@ -399,15 +327,18 @@ namespace OpenSim.Region.Physics.OdePlugin
399 327
400 public void setMesh(OdeScene parent_scene, IMesh mesh) 328 public void setMesh(OdeScene parent_scene, IMesh mesh)
401 { 329 {
330 // This sleeper is there to moderate how long it takes between
331 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
332
333 System.Threading.Thread.Sleep(10);
334
402 //Kill Body so that mesh can re-make the geom 335 //Kill Body so that mesh can re-make the geom
403 if (IsPhysical && Body != (IntPtr) 0) 336 if (IsPhysical && Body != (IntPtr) 0)
404 { 337 {
405 disableBody(); 338 disableBody();
406 } 339 }
407 340
408 // This sleeper is there to moderate how long it takes between 341
409 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
410 System.Threading.Thread.Sleep(10);
411 342
412 343
413 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory 344 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
@@ -448,6 +379,10 @@ namespace OpenSim.Region.Physics.OdePlugin
448 public void ProcessTaints(float timestep) 379 public void ProcessTaints(float timestep)
449 { 380 {
450 System.Threading.Thread.Sleep(5); 381 System.Threading.Thread.Sleep(5);
382
383 if (m_taintadd)
384 changeadd(timestep);
385
451 if (m_taintposition != _position) 386 if (m_taintposition != _position)
452 Move(timestep); 387 Move(timestep);
453 388
@@ -477,8 +412,124 @@ namespace OpenSim.Region.Physics.OdePlugin
477 changevelocity(timestep); 412 changevelocity(timestep);
478 } 413 }
479 414
480
481 415
416 public void changeadd(float timestep)
417 {
418 if (_mesh != null)
419 {
420 }
421 else
422 {
423 if (_parent_scene.needsMeshing(_pbs))
424 {
425 // Don't need to re-enable body.. it's done in SetMesh
426 _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size);
427 // createmesh returns null when it's a shape that isn't a cube.
428 }
429 }
430
431 lock (OdeScene.OdeLock)
432 {
433 if (_mesh != null)
434 {
435 setMesh(_parent_scene, _mesh);
436 }
437 else
438 {
439 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
440 {
441 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
442 {
443 if (((_size.X / 2f) > 0f))
444 {
445
446
447 _parent_scene.waitForSpaceUnlock(m_targetSpace);
448 try
449 {
450 prim_geom = d.CreateSphere(m_targetSpace, _size.X / 2);
451 }
452 catch (System.AccessViolationException)
453 {
454 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
455 return;
456 }
457 }
458 else
459 {
460 _parent_scene.waitForSpaceUnlock(m_targetSpace);
461 try
462 {
463 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
464 }
465 catch (System.AccessViolationException)
466 {
467 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
468 return;
469 }
470 }
471 }
472 else
473 {
474 _parent_scene.waitForSpaceUnlock(m_targetSpace);
475 try
476 {
477 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
478 }
479 catch (System.AccessViolationException)
480 {
481 return;
482 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
483 }
484 }
485 }
486 //else if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
487 //{
488 //Cyllinder
489 //if (_size.X == _size.Y)
490 //{
491 //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
492 //}
493 //else
494 //{
495 //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
496 //}
497 //}
498 else
499 {
500 _parent_scene.waitForSpaceUnlock(m_targetSpace);
501 try
502 {
503 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
504 }
505 catch (System.AccessViolationException)
506 {
507 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
508 return;
509 }
510 }
511 }
512
513 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
514 d.Quaternion myrot = new d.Quaternion();
515 myrot.W = _orientation.w;
516 myrot.X = _orientation.x;
517 myrot.Y = _orientation.y;
518 myrot.Z = _orientation.z;
519 d.GeomSetQuaternion(prim_geom, ref myrot);
520
521
522 if (m_isphysical && Body == (IntPtr)0)
523 {
524 enableBody();
525 }
526
527
528 }
529 m_taintadd = false;
530
531
532 }
482 public void Move(float timestep) 533 public void Move(float timestep)
483 { 534 {
484 if (m_isphysical) 535 if (m_isphysical)
@@ -941,7 +992,15 @@ namespace OpenSim.Region.Physics.OdePlugin
941 } 992 }
942 set { m_rotationalVelocity = value; } 993 set { m_rotationalVelocity = value; }
943 } 994 }
995 public override void CrossingFailure()
996 {
997 m_crossingfailures++;
998 if (m_crossingfailures >= 5)
999 {
1000 m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName);
944 1001
1002 }
1003 }
945 public void UpdatePositionAndVelocity() 1004 public void UpdatePositionAndVelocity()
946 { 1005 {
947 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! 1006 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
@@ -969,7 +1028,10 @@ namespace OpenSim.Region.Physics.OdePlugin
969 1028
970 if (l_position.X > 257f || l_position.X < -1f || l_position.Y > 257f || l_position.Y < -1f) 1029 if (l_position.X > 257f || l_position.X < -1f || l_position.Y > 257f || l_position.Y < -1f)
971 { 1030 {
972 base.RequestPhysicsterseUpdate(); 1031 if (m_crossingfailures < 5)
1032 {
1033 base.RequestPhysicsterseUpdate();
1034 }
973 } 1035 }
974 1036
975 if (l_position.Z < 0) 1037 if (l_position.Z < 0)