diff options
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/ODEPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 238 |
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) |