diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/Manager/PhysicsActor.cs | 14 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 164 |
2 files changed, 128 insertions, 50 deletions
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 84b451f..cdb5ae2 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs | |||
@@ -99,6 +99,7 @@ namespace OpenSim.Region.Physics.Manager | |||
99 | { | 99 | { |
100 | public delegate void RequestTerseUpdate(); | 100 | public delegate void RequestTerseUpdate(); |
101 | public delegate void CollisionUpdate(EventArgs e); | 101 | public delegate void CollisionUpdate(EventArgs e); |
102 | public delegate void OutOfBounds(PhysicsVector pos); | ||
102 | 103 | ||
103 | #pragma warning disable 67 | 104 | #pragma warning disable 67 |
104 | public event PositionUpdate OnPositionUpdate; | 105 | public event PositionUpdate OnPositionUpdate; |
@@ -106,6 +107,7 @@ namespace OpenSim.Region.Physics.Manager | |||
106 | public event OrientationUpdate OnOrientationUpdate; | 107 | public event OrientationUpdate OnOrientationUpdate; |
107 | public event RequestTerseUpdate OnRequestTerseUpdate; | 108 | public event RequestTerseUpdate OnRequestTerseUpdate; |
108 | public event CollisionUpdate OnCollisionUpdate; | 109 | public event CollisionUpdate OnCollisionUpdate; |
110 | public event OutOfBounds OnOutOfBounds; | ||
109 | #pragma warning restore 67 | 111 | #pragma warning restore 67 |
110 | 112 | ||
111 | public static PhysicsActor Null | 113 | public static PhysicsActor Null |
@@ -131,6 +133,18 @@ namespace OpenSim.Region.Physics.Manager | |||
131 | } | 133 | } |
132 | 134 | ||
133 | } | 135 | } |
136 | public virtual void RaiseOutOfBounds(PhysicsVector pos) | ||
137 | { | ||
138 | // Make a temporary copy of the event to avoid possibility of | ||
139 | // a race condition if the last subscriber unsubscribes | ||
140 | // immediately after the null check and before the event is raised. | ||
141 | OutOfBounds handler = OnOutOfBounds; | ||
142 | if (handler != null) | ||
143 | { | ||
144 | OnOutOfBounds(pos); | ||
145 | } | ||
146 | |||
147 | } | ||
134 | public virtual void SendCollisionUpdate(EventArgs e) | 148 | public virtual void SendCollisionUpdate(EventArgs e) |
135 | { | 149 | { |
136 | CollisionUpdate handler = OnCollisionUpdate; | 150 | CollisionUpdate handler = OnCollisionUpdate; |
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 948b2d9..bf9daa3 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | |||
@@ -382,7 +382,25 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
382 | p = (OdePrim) prim; | 382 | p = (OdePrim) prim; |
383 | p.disableBody(); | 383 | p.disableBody(); |
384 | } | 384 | } |
385 | 385 | // we don't want to remove the main space | |
386 | if (((OdePrim)prim).m_targetSpace != space && ((OdePrim)prim).IsPhysical == false) | ||
387 | { | ||
388 | // If the geometry is in the targetspace, remove it from the target space | ||
389 | if (d.SpaceQuery(((OdePrim)prim).m_targetSpace, ((OdePrim)prim).prim_geom)) | ||
390 | { | ||
391 | d.SpaceRemove(space, ((OdePrim)prim).prim_geom); | ||
392 | } | ||
393 | |||
394 | //If there are no more geometries in the sub-space, we don't need it in the main space anymore | ||
395 | if (d.SpaceGetNumGeoms(((OdePrim)prim).m_targetSpace) == 0) | ||
396 | { | ||
397 | d.SpaceRemove(space, ((OdePrim)prim).m_targetSpace); | ||
398 | // free up memory used by the space. | ||
399 | d.SpaceDestroy(((OdePrim)prim).m_targetSpace); | ||
400 | resetSpaceArrayItemToZero(calculateSpaceArrayItemFromPos(((OdePrim)prim).Position)); | ||
401 | } | ||
402 | } | ||
403 | |||
386 | d.GeomDestroy(((OdePrim)prim).prim_geom); | 404 | d.GeomDestroy(((OdePrim)prim).prim_geom); |
387 | 405 | ||
388 | _prims.Remove((OdePrim)prim); | 406 | _prims.Remove((OdePrim)prim); |
@@ -390,20 +408,74 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
390 | } | 408 | } |
391 | } | 409 | } |
392 | } | 410 | } |
411 | public void resetSpaceArrayItemToZero(IntPtr space) | ||
412 | { | ||
413 | for (int i = 0; i < staticPrimspace.Length; i++) | ||
414 | { | ||
415 | if (staticPrimspace[i] == space) | ||
416 | staticPrimspace[i] = IntPtr.Zero; | ||
417 | } | ||
418 | } | ||
419 | public void resetSpaceArrayItemToZero(int arrayitem) | ||
420 | { | ||
421 | staticPrimspace[arrayitem] = IntPtr.Zero; | ||
422 | } | ||
393 | 423 | ||
394 | public IntPtr recalculateSpaceForGeom(IntPtr geom, PhysicsVector pos) | 424 | public IntPtr recalculateSpaceForGeom(IntPtr geom, PhysicsVector pos, IntPtr currentspace) |
395 | { | 425 | { |
396 | //Todo recalculate space the prim is in. | 426 | //Todo recalculate space the prim is in. |
427 | // Called from setting the Position and Size of an ODEPrim so | ||
428 | // it's already in locked space. | ||
397 | 429 | ||
430 | // we don't want to remove the main space | ||
431 | // we don't need to test physical here because this function should | ||
432 | // never be called if the prim is physical(active) | ||
433 | if (currentspace != space) | ||
434 | { | ||
435 | if (d.SpaceQuery(currentspace, geom)) | ||
436 | { | ||
437 | d.SpaceRemove(space, geom); | ||
438 | } | ||
398 | 439 | ||
399 | return space; | 440 | //If there are no more geometries in the sub-space, we don't need it in the main space anymore |
441 | if (d.SpaceGetNumGeoms(currentspace) == 0) | ||
442 | { | ||
443 | d.SpaceRemove(space, currentspace); | ||
444 | // free up memory used by the space. | ||
445 | d.SpaceDestroy(currentspace); | ||
446 | resetSpaceArrayItemToZero(currentspace); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | |||
451 | // The routines in the Position and Size sections do the 'inserting' into the space, | ||
452 | // so all we have to do is make sure that the space that we're putting the prim into | ||
453 | // is in the 'main' space. | ||
454 | int iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos); | ||
455 | IntPtr newspace = calculateSpaceForGeom(pos); | ||
456 | |||
457 | if (newspace == IntPtr.Zero) | ||
458 | newspace = createprimspace(iprimspaceArrItem); | ||
459 | |||
460 | return newspace; | ||
461 | } | ||
462 | |||
463 | public IntPtr createprimspace(int iprimspaceArrItem) { | ||
464 | // creating a new space for prim and inserting it into main space. | ||
465 | staticPrimspace[iprimspaceArrItem] = d.HashSpaceCreate(IntPtr.Zero); | ||
466 | d.SpaceAdd(space, staticPrimspace[iprimspaceArrItem]); | ||
467 | return staticPrimspace[iprimspaceArrItem]; | ||
400 | } | 468 | } |
401 | 469 | ||
402 | public IntPtr calculateSpaceForNewGeom(PhysicsVector pos) | 470 | public IntPtr calculateSpaceForGeom(PhysicsVector pos) |
403 | { | 471 | { |
404 | 472 | ||
405 | return space; | 473 | return space; |
406 | } | 474 | } |
475 | public int calculateSpaceArrayItemFromPos(PhysicsVector pos) | ||
476 | { | ||
477 | return 0; | ||
478 | } | ||
407 | 479 | ||
408 | private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation, | 480 | private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation, |
409 | IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) | 481 | IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) |
@@ -423,33 +495,36 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
423 | rot.y = rotation.y; | 495 | rot.y = rotation.y; |
424 | rot.z = rotation.z; | 496 | rot.z = rotation.z; |
425 | 497 | ||
426 | IntPtr targetspace = calculateSpaceForNewGeom(pos); | 498 | |
499 | int iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos); | ||
500 | IntPtr targetspace = calculateSpaceForGeom(pos); | ||
501 | |||
502 | if (targetspace == IntPtr.Zero) | ||
503 | targetspace = createprimspace(iprimspaceArrItem); | ||
504 | |||
427 | OdePrim newPrim; | 505 | OdePrim newPrim; |
428 | lock (OdeLock) | 506 | lock (OdeLock) |
429 | { | 507 | { |
430 | newPrim = new OdePrim(name, this, targetspace, pos, siz, rot, mesh, pbs, isphysical); | 508 | newPrim = new OdePrim(name, this, targetspace, pos, siz, rot, mesh, pbs, isphysical); |
431 | } | 509 | } |
432 | _prims.Add(newPrim); | 510 | _prims.Add(newPrim); |
511 | OpenSim.Framework.Console.MainLog.Instance.Verbose("PHYSICS", "Added Object"); | ||
433 | return newPrim; | 512 | return newPrim; |
434 | } | 513 | } |
435 | 514 | ||
436 | public void addActivePrim(OdePrim activatePrim) | 515 | public void addActivePrim(OdePrim activatePrim) |
437 | { | 516 | { |
438 | // adds active prim.. (ones that should be iterated over in collisions_optimized | 517 | // adds active prim.. (ones that should be iterated over in collisions_optimized |
439 | lock (OdeLock) | 518 | |
440 | { | ||
441 | _activeprims.Add(activatePrim); | 519 | _activeprims.Add(activatePrim); |
442 | } | 520 | |
443 | } | 521 | } |
444 | public void remActivePrim(OdePrim deactivatePrim) | 522 | public void remActivePrim(OdePrim deactivatePrim) |
445 | { | 523 | { |
446 | lock (OdeLock) | 524 | |
447 | { | 525 | _activeprims.Remove(deactivatePrim); |
448 | lock (_activeprims) | 526 | |
449 | { | 527 | |
450 | _activeprims.Remove(deactivatePrim); | ||
451 | } | ||
452 | } | ||
453 | } | 528 | } |
454 | public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount) | 529 | public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount) |
455 | { | 530 | { |
@@ -541,6 +616,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
541 | 616 | ||
542 | public override void Simulate(float timeStep) | 617 | public override void Simulate(float timeStep) |
543 | { | 618 | { |
619 | |||
544 | step_time += timeStep; | 620 | step_time += timeStep; |
545 | lock (OdeLock) | 621 | lock (OdeLock) |
546 | { | 622 | { |
@@ -548,21 +624,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
548 | { | 624 | { |
549 | Console.WriteLine("RENDER: frame"); | 625 | Console.WriteLine("RENDER: frame"); |
550 | } | 626 | } |
551 | foreach (OdePrim p in _prims) | 627 | |
552 | { | ||
553 | if (_characters.Count > 0 && RENDER_FLAG) | ||
554 | { | ||
555 | Vector3 rx, ry, rz; | ||
556 | p.Orientation.ToAxes(out rx, out ry, out rz); | ||
557 | Console.WriteLine("RENDER: block; " + p.Size.X + ", " + p.Size.Y + ", " + p.Size.Z + "; " + | ||
558 | " 0, 0, 1; " + //shape, size, color | ||
559 | (p.Position.X - 128.0f) + ", " + (p.Position.Y - 128.0f) + ", " + | ||
560 | (p.Position.Z - 33.0f) + "; " + // position | ||
561 | rx.x + "," + ry.x + "," + rz.x + ", " + // rotation | ||
562 | rx.y + "," + ry.y + "," + rz.y + ", " + | ||
563 | rx.z + "," + ry.z + "," + rz.z); | ||
564 | } | ||
565 | } | ||
566 | 628 | ||
567 | 629 | ||
568 | // If We're loaded down by something else, | 630 | // If We're loaded down by something else, |
@@ -570,6 +632,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
570 | // skip a few frames to catch up gracefully. | 632 | // skip a few frames to catch up gracefully. |
571 | // without shooting the physicsactors all over the place | 633 | // without shooting the physicsactors all over the place |
572 | 634 | ||
635 | |||
636 | |||
573 | if (step_time >= m_SkipFramesAtms) | 637 | if (step_time >= m_SkipFramesAtms) |
574 | { | 638 | { |
575 | // Instead of trying to catch up, it'll do one physics frame only | 639 | // Instead of trying to catch up, it'll do one physics frame only |
@@ -580,10 +644,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
580 | { | 644 | { |
581 | m_physicsiterations = 10; | 645 | m_physicsiterations = 10; |
582 | } | 646 | } |
647 | |||
583 | // Process 10 frames if the sim is running normal.. | 648 | // Process 10 frames if the sim is running normal.. |
584 | // process 5 frames if the sim is running slow | 649 | // process 5 frames if the sim is running slow |
585 | d.WorldSetQuickStepNumIterations(world, m_physicsiterations); | 650 | d.WorldSetQuickStepNumIterations(world, m_physicsiterations); |
586 | 651 | ||
652 | |||
587 | int i = 0; | 653 | int i = 0; |
588 | while (step_time > 0.0f) | 654 | while (step_time > 0.0f) |
589 | { | 655 | { |
@@ -640,11 +706,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
640 | } | 706 | } |
641 | if (timeStep < 0.2f) | 707 | if (timeStep < 0.2f) |
642 | { | 708 | { |
709 | OdePrim outofBoundsPrim = null; | ||
643 | foreach (OdePrim actor in _activeprims) | 710 | foreach (OdePrim actor in _activeprims) |
644 | { | 711 | { |
645 | if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag)) | 712 | if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag)) |
646 | { | 713 | { |
647 | actor.UpdatePositionAndVelocity(); | 714 | actor.UpdatePositionAndVelocity(); |
715 | |||
648 | } | 716 | } |
649 | } | 717 | } |
650 | } | 718 | } |
@@ -716,6 +784,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
716 | { | 784 | { |
717 | } | 785 | } |
718 | } | 786 | } |
787 | # region ODE Actors | ||
719 | 788 | ||
720 | public class OdeCharacter : PhysicsActor | 789 | public class OdeCharacter : PhysicsActor |
721 | { | 790 | { |
@@ -1185,13 +1254,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1185 | private IMesh _mesh; | 1254 | private IMesh _mesh; |
1186 | private PrimitiveBaseShape _pbs; | 1255 | private PrimitiveBaseShape _pbs; |
1187 | private OdeScene _parent_scene; | 1256 | private OdeScene _parent_scene; |
1188 | private IntPtr m_targetSpace = (IntPtr)0; | 1257 | public IntPtr m_targetSpace = (IntPtr)0; |
1189 | public IntPtr prim_geom; | 1258 | public IntPtr prim_geom; |
1190 | public IntPtr _triMeshData; | 1259 | public IntPtr _triMeshData; |
1191 | private bool iscolliding = false; | 1260 | private bool iscolliding = false; |
1192 | private bool m_isphysical = false; | 1261 | private bool m_isphysical = false; |
1193 | private bool m_throttleUpdates = false; | 1262 | private bool m_throttleUpdates = false; |
1194 | private int throttleCounter = 0; | 1263 | private int throttleCounter = 0; |
1264 | public bool outofBounds = false; | ||
1195 | 1265 | ||
1196 | public bool _zeroFlag = false; | 1266 | public bool _zeroFlag = false; |
1197 | private bool m_lastUpdateSent = false; | 1267 | private bool m_lastUpdateSent = false; |
@@ -1402,7 +1472,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1402 | 1472 | ||
1403 | public override PhysicsVector Position | 1473 | public override PhysicsVector Position |
1404 | { | 1474 | { |
1405 | get { return _position;} | 1475 | get {return _position; } |
1476 | |||
1477 | |||
1406 | set | 1478 | set |
1407 | { | 1479 | { |
1408 | _position = value; | 1480 | _position = value; |
@@ -1421,9 +1493,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1421 | else | 1493 | else |
1422 | { | 1494 | { |
1423 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 1495 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
1424 | 1496 | m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); | |
1425 | } | 1497 | } |
1426 | m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position); | 1498 | |
1427 | } | 1499 | } |
1428 | } | 1500 | } |
1429 | } | 1501 | } |
@@ -1449,6 +1521,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1449 | disableBody(); | 1521 | disableBody(); |
1450 | } | 1522 | } |
1451 | d.GeomDestroy(prim_geom); | 1523 | d.GeomDestroy(prim_geom); |
1524 | |||
1525 | // Recalculate which space this geometry should be in. | ||
1526 | m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); | ||
1452 | // Construction of new prim | 1527 | // Construction of new prim |
1453 | if (this._parent_scene.needsMeshing(_pbs)) | 1528 | if (this._parent_scene.needsMeshing(_pbs)) |
1454 | { | 1529 | { |
@@ -1478,7 +1553,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1478 | 1553 | ||
1479 | } | 1554 | } |
1480 | 1555 | ||
1481 | m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position); | 1556 | |
1482 | _parent_scene.geom_name_map[prim_geom] = oldname; | 1557 | _parent_scene.geom_name_map[prim_geom] = oldname; |
1483 | 1558 | ||
1484 | } | 1559 | } |
@@ -1639,20 +1714,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1639 | // Disables the prim's movement physics.... | 1714 | // Disables the prim's movement physics.... |
1640 | // It's a hack and will generate a console message if it fails. | 1715 | // It's a hack and will generate a console message if it fails. |
1641 | 1716 | ||
1642 | try | 1717 | |
1643 | { | ||
1644 | disableBody(); | ||
1645 | |||
1646 | } | ||
1647 | catch (System.Exception e) | ||
1648 | { | ||
1649 | if (Body != (IntPtr)0) | ||
1650 | { | ||
1651 | d.BodyDestroy(Body); | ||
1652 | Body = (IntPtr)0; | ||
1653 | |||
1654 | } | ||
1655 | } | ||
1656 | 1718 | ||
1657 | 1719 | ||
1658 | IsPhysical = false; | 1720 | IsPhysical = false; |
@@ -1662,10 +1724,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1662 | m_rotationalVelocity.X = 0; | 1724 | m_rotationalVelocity.X = 0; |
1663 | m_rotationalVelocity.Y = 0; | 1725 | m_rotationalVelocity.Y = 0; |
1664 | m_rotationalVelocity.Z = 0; | 1726 | m_rotationalVelocity.Z = 0; |
1665 | base.RequestPhysicsterseUpdate(); | 1727 | //base.RequestPhysicsterseUpdate(); |
1666 | m_throttleUpdates = false; | 1728 | m_throttleUpdates = false; |
1667 | throttleCounter = 0; | 1729 | throttleCounter = 0; |
1668 | _zeroFlag = true; | 1730 | _zeroFlag = true; |
1731 | outofBounds = true; | ||
1669 | } | 1732 | } |
1670 | 1733 | ||
1671 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) | 1734 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) |
@@ -1755,3 +1818,4 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1755 | } | 1818 | } |
1756 | } | 1819 | } |
1757 | } | 1820 | } |
1821 | #endregion \ No newline at end of file | ||