diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Examples/SimpleModule/ComplexObject.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 4 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 42 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 258 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEDynamics.c_comments (renamed from OpenSim/Region/Physics/OdePlugin/ODEVehicleSettings.cs) | 558 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs | 658 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 594 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 54 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 31 |
12 files changed, 1468 insertions, 751 deletions
diff --git a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs index 3809749..e951bef 100644 --- a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs +++ b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs | |||
@@ -68,11 +68,15 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
68 | 68 | ||
69 | public override void UpdateMovement() | 69 | public override void UpdateMovement() |
70 | { | 70 | { |
71 | UpdateGroupRotation(GroupRotation * m_rotationDirection); | 71 | UpdateGroupRotationR(GroupRotation * m_rotationDirection); |
72 | 72 | ||
73 | base.UpdateMovement(); | 73 | base.UpdateMovement(); |
74 | } | 74 | } |
75 | 75 | ||
76 | public ComplexObject() | ||
77 | { | ||
78 | } | ||
79 | |||
76 | public ComplexObject(Scene scene, ulong regionHandle, UUID ownerID, uint localID, Vector3 pos) | 80 | public ComplexObject(Scene scene, ulong regionHandle, UUID ownerID, uint localID, Vector3 pos) |
77 | : base(ownerID, pos, PrimitiveBaseShape.Default) | 81 | : base(ownerID, pos, PrimitiveBaseShape.Default) |
78 | { | 82 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index eb397f6..a6e137d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -2265,7 +2265,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2265 | group.ClearPartAttachmentData(); | 2265 | group.ClearPartAttachmentData(); |
2266 | } | 2266 | } |
2267 | 2267 | ||
2268 | group.UpdateGroupRotation(rot); | 2268 | group.UpdateGroupRotationR(rot); |
2269 | 2269 | ||
2270 | //group.ApplyPhysics(m_physicalPrim); | 2270 | //group.ApplyPhysics(m_physicalPrim); |
2271 | if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) | 2271 | if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d8478a2..db107a9 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2810,7 +2810,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2810 | // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); | 2810 | // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); |
2811 | m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); | 2811 | m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); |
2812 | //obj.Rotation = worldRot; | 2812 | //obj.Rotation = worldRot; |
2813 | //obj.UpdateGroupRotation(worldRot); | 2813 | //obj.UpdateGroupRotationR(worldRot); |
2814 | } | 2814 | } |
2815 | else | 2815 | else |
2816 | { | 2816 | { |
@@ -4504,7 +4504,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4504 | Quaternion q = trackedBody.RotationOffset * joint.LocalRotation; | 4504 | Quaternion q = trackedBody.RotationOffset * joint.LocalRotation; |
4505 | 4505 | ||
4506 | jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update | 4506 | jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update |
4507 | jointProxyObject.ParentGroup.UpdateGroupRotation(q); // schedules the entire group for a terse update | 4507 | jointProxyObject.ParentGroup.UpdateGroupRotationR(q); // schedules the entire group for a terse update |
4508 | } | 4508 | } |
4509 | break; | 4509 | break; |
4510 | } | 4510 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 48dea07..09116fa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -1236,7 +1236,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1236 | { | 1236 | { |
1237 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) | 1237 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) |
1238 | { | 1238 | { |
1239 | group.UpdateGroupRotation(rot); | 1239 | group.UpdateGroupRotationR(rot); |
1240 | } | 1240 | } |
1241 | } | 1241 | } |
1242 | } | 1242 | } |
@@ -1255,7 +1255,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1255 | { | 1255 | { |
1256 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) | 1256 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) |
1257 | { | 1257 | { |
1258 | group.UpdateGroupRotation(pos, rot); | 1258 | group.UpdateGroupRotationPR(pos, rot); |
1259 | } | 1259 | } |
1260 | } | 1260 | } |
1261 | } | 1261 | } |
@@ -1811,7 +1811,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1811 | 1811 | ||
1812 | if (rot != Quaternion.Identity) | 1812 | if (rot != Quaternion.Identity) |
1813 | { | 1813 | { |
1814 | copy.UpdateGroupRotation(rot); | 1814 | copy.UpdateGroupRotationR(rot); |
1815 | } | 1815 | } |
1816 | 1816 | ||
1817 | copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 0); | 1817 | copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 0); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ad5d56f..a260653 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -373,6 +373,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
373 | #region Constructors | 373 | #region Constructors |
374 | 374 | ||
375 | /// <summary> | 375 | /// <summary> |
376 | /// Constructor | ||
377 | /// </summary> | ||
378 | public SceneObjectGroup() | ||
379 | { | ||
380 | } | ||
381 | |||
382 | /// <summary> | ||
376 | /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart. | 383 | /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart. |
377 | /// The original SceneObjectPart will be used rather than a copy, preserving | 384 | /// The original SceneObjectPart will be used rather than a copy, preserving |
378 | /// its existing localID and UUID. | 385 | /// its existing localID and UUID. |
@@ -2958,8 +2965,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2958 | /// | 2965 | /// |
2959 | /// </summary> | 2966 | /// </summary> |
2960 | /// <param name="rot"></param> | 2967 | /// <param name="rot"></param> |
2961 | public void UpdateGroupRotation(Quaternion rot) | 2968 | public void UpdateGroupRotationR(Quaternion rot) |
2962 | { | 2969 | { |
2970 | |||
2963 | m_rootPart.UpdateRotation(rot); | 2971 | m_rootPart.UpdateRotation(rot); |
2964 | if (m_rootPart.PhysActor != null) | 2972 | if (m_rootPart.PhysActor != null) |
2965 | { | 2973 | { |
@@ -2976,7 +2984,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2976 | /// </summary> | 2984 | /// </summary> |
2977 | /// <param name="pos"></param> | 2985 | /// <param name="pos"></param> |
2978 | /// <param name="rot"></param> | 2986 | /// <param name="rot"></param> |
2979 | public void UpdateGroupRotation(Vector3 pos, Quaternion rot) | 2987 | public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) |
2980 | { | 2988 | { |
2981 | m_rootPart.UpdateRotation(rot); | 2989 | m_rootPart.UpdateRotation(rot); |
2982 | if (m_rootPart.PhysActor != null) | 2990 | if (m_rootPart.PhysActor != null) |
@@ -3084,22 +3092,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
3084 | int yaxis = 4; | 3092 | int yaxis = 4; |
3085 | int zaxis = 8; | 3093 | int zaxis = 8; |
3086 | 3094 | ||
3087 | setX = ((axis & xaxis) != 0) ? true : false; | 3095 | if (m_rootPart != null) |
3088 | setY = ((axis & yaxis) != 0) ? true : false; | 3096 | { |
3089 | setZ = ((axis & zaxis) != 0) ? true : false; | 3097 | setX = ((axis & xaxis) != 0) ? true : false; |
3098 | setY = ((axis & yaxis) != 0) ? true : false; | ||
3099 | setZ = ((axis & zaxis) != 0) ? true : false; | ||
3090 | 3100 | ||
3091 | float setval = (rotate10 > 0) ? 1f : 0f; | 3101 | float setval = (rotate10 > 0) ? 1f : 0f; |
3092 | 3102 | ||
3093 | if (setX) | 3103 | if (setX) |
3094 | m_rootPart.RotationAxis.X = setval; | 3104 | m_rootPart.RotationAxis.X = setval; |
3095 | if (setY) | 3105 | if (setY) |
3096 | m_rootPart.RotationAxis.Y = setval; | 3106 | m_rootPart.RotationAxis.Y = setval; |
3097 | if (setZ) | 3107 | if (setZ) |
3098 | m_rootPart.RotationAxis.Z = setval; | 3108 | m_rootPart.RotationAxis.Z = setval; |
3109 | |||
3110 | if (setX || setY || setZ) | ||
3111 | { | ||
3112 | m_rootPart.SetPhysicsAxisRotation(); | ||
3113 | } | ||
3099 | 3114 | ||
3100 | if (setX || setY || setZ) | ||
3101 | { | ||
3102 | m_rootPart.SetPhysicsAxisRotation(); | ||
3103 | } | 3115 | } |
3104 | } | 3116 | } |
3105 | 3117 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 51bb114..9819163 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -415,10 +415,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
415 | set | 415 | set |
416 | { | 416 | { |
417 | m_name = value; | 417 | m_name = value; |
418 | PhysicsActor pa = PhysActor; | 418 | if (PhysActor != null) |
419 | if (pa != null) | ||
420 | { | 419 | { |
421 | pa.SOPName = value; | 420 | PhysActor.SOPName = value; |
422 | } | 421 | } |
423 | } | 422 | } |
424 | } | 423 | } |
@@ -428,11 +427,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
428 | get { return (byte) m_material; } | 427 | get { return (byte) m_material; } |
429 | set | 428 | set |
430 | { | 429 | { |
431 | PhysicsActor pa = PhysActor; | ||
432 | m_material = (Material)value; | 430 | m_material = (Material)value; |
433 | if (pa != null) | 431 | if (PhysActor != null) |
434 | { | 432 | { |
435 | pa.SetMaterial((int)value); | 433 | PhysActor.SetMaterial((int)value); |
436 | } | 434 | } |
437 | } | 435 | } |
438 | } | 436 | } |
@@ -503,12 +501,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
503 | get | 501 | get |
504 | { | 502 | { |
505 | // If this is a linkset, we don't want the physics engine mucking up our group position here. | 503 | // If this is a linkset, we don't want the physics engine mucking up our group position here. |
506 | PhysicsActor pa = PhysActor; | 504 | if (PhysActor != null && _parentID == 0) |
507 | if (pa != null && _parentID == 0) | ||
508 | { | 505 | { |
509 | m_groupPosition.X = pa.Position.X; | 506 | m_groupPosition.X = PhysActor.Position.X; |
510 | m_groupPosition.Y = pa.Position.Y; | 507 | m_groupPosition.Y = PhysActor.Position.Y; |
511 | m_groupPosition.Z = pa.Position.Z; | 508 | m_groupPosition.Z = PhysActor.Position.Z; |
512 | } | 509 | } |
513 | 510 | ||
514 | if (IsAttachment) | 511 | if (IsAttachment) |
@@ -528,27 +525,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
528 | 525 | ||
529 | m_groupPosition = value; | 526 | m_groupPosition = value; |
530 | 527 | ||
531 | PhysicsActor pa = PhysActor; | 528 | if (PhysActor != null) |
532 | if (pa != null) | ||
533 | { | 529 | { |
534 | try | 530 | try |
535 | { | 531 | { |
536 | // Root prim actually goes at Position | 532 | // Root prim actually goes at Position |
537 | if (_parentID == 0) | 533 | if (_parentID == 0) |
538 | { | 534 | { |
539 | pa.Position = new PhysicsVector(value.X, value.Y, value.Z); | 535 | PhysActor.Position = new PhysicsVector(value.X, value.Y, value.Z); |
540 | } | 536 | } |
541 | else | 537 | else |
542 | { | 538 | { |
543 | // To move the child prim in respect to the group position and rotation we have to calculate | 539 | // To move the child prim in respect to the group position and rotation we have to calculate |
544 | Vector3 resultingposition = GetWorldPosition(); | 540 | Vector3 resultingposition = GetWorldPosition(); |
545 | pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); | 541 | PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); |
546 | Quaternion resultingrot = GetWorldRotation(); | 542 | Quaternion resultingrot = GetWorldRotation(); |
547 | pa.Orientation = resultingrot; | 543 | PhysActor.Orientation = resultingrot; |
548 | } | 544 | } |
549 | 545 | ||
550 | // Tell the physics engines that this prim changed. | 546 | // Tell the physics engines that this prim changed. |
551 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | 547 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
552 | } | 548 | } |
553 | catch (Exception e) | 549 | catch (Exception e) |
554 | { | 550 | { |
@@ -581,16 +577,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
581 | 577 | ||
582 | if (ParentGroup != null && !ParentGroup.IsDeleted) | 578 | if (ParentGroup != null && !ParentGroup.IsDeleted) |
583 | { | 579 | { |
584 | PhysicsActor pa = PhysActor; | 580 | if (_parentID != 0 && PhysActor != null) |
585 | if (_parentID != 0 && pa != null) | ||
586 | { | 581 | { |
587 | Vector3 resultingposition = GetWorldPosition(); | 582 | Vector3 resultingposition = GetWorldPosition(); |
588 | pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); | 583 | PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); |
589 | Quaternion resultingrot = GetWorldRotation(); | 584 | Quaternion resultingrot = GetWorldRotation(); |
590 | pa.Orientation = resultingrot; | 585 | PhysActor.Orientation = resultingrot; |
591 | 586 | ||
592 | // Tell the physics engines that this prim changed. | 587 | // Tell the physics engines that this prim changed. |
593 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | 588 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
594 | } | 589 | } |
595 | } | 590 | } |
596 | } | 591 | } |
@@ -600,14 +595,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
600 | { | 595 | { |
601 | get | 596 | get |
602 | { | 597 | { |
603 | PhysicsActor pa = PhysActor; | ||
604 | // We don't want the physics engine mucking up the rotations in a linkset | 598 | // We don't want the physics engine mucking up the rotations in a linkset |
605 | if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (pa != null)) | 599 | if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (PhysActor != null)) |
606 | { | 600 | { |
607 | if (pa.Orientation.X != 0 || pa.Orientation.Y != 0 | 601 | if (PhysActor.Orientation.X != 0 || PhysActor.Orientation.Y != 0 |
608 | || pa.Orientation.Z != 0 || pa.Orientation.W != 0) | 602 | || PhysActor.Orientation.Z != 0 || PhysActor.Orientation.W != 0) |
609 | { | 603 | { |
610 | m_rotationOffset = pa.Orientation; | 604 | m_rotationOffset = PhysActor.Orientation; |
611 | } | 605 | } |
612 | } | 606 | } |
613 | 607 | ||
@@ -616,28 +610,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
616 | 610 | ||
617 | set | 611 | set |
618 | { | 612 | { |
619 | PhysicsActor pa = PhysActor; | ||
620 | StoreUndoState(); | 613 | StoreUndoState(); |
621 | m_rotationOffset = value; | 614 | m_rotationOffset = value; |
622 | 615 | ||
623 | if (pa != null) | 616 | if (PhysActor != null) |
624 | { | 617 | { |
625 | try | 618 | try |
626 | { | 619 | { |
627 | // Root prim gets value directly | 620 | // Root prim gets value directly |
628 | if (_parentID == 0) | 621 | if (_parentID == 0) |
629 | { | 622 | { |
630 | pa.Orientation = value; | 623 | PhysActor.Orientation = value; |
631 | //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString()); | 624 | //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString()); |
632 | } | 625 | } |
633 | else | 626 | else |
634 | { | 627 | { |
635 | // Child prim we have to calculate it's world rotationwel | 628 | // Child prim we have to calculate it's world rotationwel |
636 | Quaternion resultingrotation = GetWorldRotation(); | 629 | Quaternion resultingrotation = GetWorldRotation(); |
637 | pa.Orientation = resultingrotation; | 630 | PhysActor.Orientation = resultingrotation; |
638 | //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString()); | 631 | //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString()); |
639 | } | 632 | } |
640 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | 633 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
641 | //} | 634 | //} |
642 | } | 635 | } |
643 | catch (Exception ex) | 636 | catch (Exception ex) |
@@ -657,14 +650,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
657 | //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0 | 650 | //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0 |
658 | //|| PhysActor.Velocity.Z != 0) | 651 | //|| PhysActor.Velocity.Z != 0) |
659 | //{ | 652 | //{ |
660 | PhysicsActor pa = PhysActor; | 653 | if (PhysActor != null) |
661 | if (pa != null) | ||
662 | { | 654 | { |
663 | if (pa.IsPhysical) | 655 | if (PhysActor.IsPhysical) |
664 | { | 656 | { |
665 | m_velocity.X = pa.Velocity.X; | 657 | m_velocity.X = PhysActor.Velocity.X; |
666 | m_velocity.Y = pa.Velocity.Y; | 658 | m_velocity.Y = PhysActor.Velocity.Y; |
667 | m_velocity.Z = pa.Velocity.Z; | 659 | m_velocity.Z = PhysActor.Velocity.Z; |
668 | } | 660 | } |
669 | } | 661 | } |
670 | 662 | ||
@@ -674,13 +666,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
674 | set | 666 | set |
675 | { | 667 | { |
676 | m_velocity = value; | 668 | m_velocity = value; |
677 | PhysicsActor pa = PhysActor; | 669 | if (PhysActor != null) |
678 | if (pa != null) | ||
679 | { | 670 | { |
680 | if (pa.IsPhysical) | 671 | if (PhysActor.IsPhysical) |
681 | { | 672 | { |
682 | pa.Velocity = new PhysicsVector(value.X, value.Y, value.Z); | 673 | PhysActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z); |
683 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | 674 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
684 | } | 675 | } |
685 | } | 676 | } |
686 | } | 677 | } |
@@ -697,10 +688,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
697 | { | 688 | { |
698 | get | 689 | get |
699 | { | 690 | { |
700 | PhysicsActor pa = PhysActor; | 691 | if ((PhysActor != null) && PhysActor.IsPhysical) |
701 | if ((pa != null) && pa.IsPhysical) | ||
702 | { | 692 | { |
703 | m_angularVelocity.FromBytes(pa.RotationalVelocity.GetBytes(), 0); | 693 | m_angularVelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(), 0); |
704 | } | 694 | } |
705 | return m_angularVelocity; | 695 | return m_angularVelocity; |
706 | } | 696 | } |
@@ -719,11 +709,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
719 | get { return m_description; } | 709 | get { return m_description; } |
720 | set | 710 | set |
721 | { | 711 | { |
722 | PhysicsActor pa = PhysActor; | ||
723 | m_description = value; | 712 | m_description = value; |
724 | if (pa != null) | 713 | if (PhysActor != null) |
725 | { | 714 | { |
726 | pa.SOPDescription = value; | 715 | PhysActor.SOPDescription = value; |
727 | } | 716 | } |
728 | } | 717 | } |
729 | } | 718 | } |
@@ -817,15 +806,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
817 | if (m_shape != null) { | 806 | if (m_shape != null) { |
818 | m_shape.Scale = value; | 807 | m_shape.Scale = value; |
819 | 808 | ||
820 | PhysicsActor pa = PhysActor; | 809 | if (PhysActor != null && m_parentGroup != null) |
821 | if (pa != null && m_parentGroup != null) | ||
822 | { | 810 | { |
823 | if (m_parentGroup.Scene != null) | 811 | if (m_parentGroup.Scene != null) |
824 | { | 812 | { |
825 | if (m_parentGroup.Scene.PhysicsScene != null) | 813 | if (m_parentGroup.Scene.PhysicsScene != null) |
826 | { | 814 | { |
827 | pa.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); | 815 | PhysActor.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); |
828 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | 816 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
829 | } | 817 | } |
830 | } | 818 | } |
831 | } | 819 | } |
@@ -1355,14 +1343,13 @@ if (m_shape != null) { | |||
1355 | RigidBody); | 1343 | RigidBody); |
1356 | 1344 | ||
1357 | // Basic Physics returns null.. joy joy joy. | 1345 | // Basic Physics returns null.. joy joy joy. |
1358 | PhysicsActor pa = PhysActor; | 1346 | if (PhysActor != null) |
1359 | if (pa != null) | ||
1360 | { | 1347 | { |
1361 | pa.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info | 1348 | PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info |
1362 | pa.SOPDescription = this.Description; | 1349 | PhysActor.SOPDescription = this.Description; |
1363 | pa.LocalID = LocalId; | 1350 | PhysActor.LocalID = LocalId; |
1364 | DoPhysicsPropertyUpdate(RigidBody, true); | 1351 | DoPhysicsPropertyUpdate(RigidBody, true); |
1365 | pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); | 1352 | PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); |
1366 | } | 1353 | } |
1367 | } | 1354 | } |
1368 | } | 1355 | } |
@@ -1576,24 +1563,23 @@ if (m_shape != null) { | |||
1576 | } | 1563 | } |
1577 | else | 1564 | else |
1578 | { | 1565 | { |
1579 | PhysicsActor pa = PhysActor; | 1566 | if (PhysActor != null) |
1580 | if (pa != null) | ||
1581 | { | 1567 | { |
1582 | if (UsePhysics != pa.IsPhysical || isNew) | 1568 | if (UsePhysics != PhysActor.IsPhysical || isNew) |
1583 | { | 1569 | { |
1584 | if (pa.IsPhysical) // implies UsePhysics==false for this block | 1570 | if (PhysActor.IsPhysical) // implies UsePhysics==false for this block |
1585 | { | 1571 | { |
1586 | if (!isNew) | 1572 | if (!isNew) |
1587 | ParentGroup.Scene.RemovePhysicalPrim(1); | 1573 | ParentGroup.Scene.RemovePhysicalPrim(1); |
1588 | 1574 | ||
1589 | pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; | 1575 | PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; |
1590 | pa.OnOutOfBounds -= PhysicsOutOfBounds; | 1576 | PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; |
1591 | pa.delink(); | 1577 | PhysActor.delink(); |
1592 | 1578 | ||
1593 | if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) | 1579 | if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) |
1594 | { | 1580 | { |
1595 | // destroy all joints connected to this now deactivated body | 1581 | // destroy all joints connected to this now deactivated body |
1596 | m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); | 1582 | m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor); |
1597 | } | 1583 | } |
1598 | 1584 | ||
1599 | // stop client-side interpolation of all joint proxy objects that have just been deleted | 1585 | // stop client-side interpolation of all joint proxy objects that have just been deleted |
@@ -1612,7 +1598,7 @@ if (m_shape != null) { | |||
1612 | //RotationalVelocity = new Vector3(0, 0, 0); | 1598 | //RotationalVelocity = new Vector3(0, 0, 0); |
1613 | } | 1599 | } |
1614 | 1600 | ||
1615 | pa.IsPhysical = UsePhysics; | 1601 | PhysActor.IsPhysical = UsePhysics; |
1616 | 1602 | ||
1617 | 1603 | ||
1618 | // If we're not what we're supposed to be in the physics scene, recreate ourselves. | 1604 | // If we're not what we're supposed to be in the physics scene, recreate ourselves. |
@@ -1626,19 +1612,19 @@ if (m_shape != null) { | |||
1626 | { | 1612 | { |
1627 | ParentGroup.Scene.AddPhysicalPrim(1); | 1613 | ParentGroup.Scene.AddPhysicalPrim(1); |
1628 | 1614 | ||
1629 | pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; | 1615 | PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; |
1630 | pa.OnOutOfBounds += PhysicsOutOfBounds; | 1616 | PhysActor.OnOutOfBounds += PhysicsOutOfBounds; |
1631 | if (_parentID != 0 && _parentID != LocalId) | 1617 | if (_parentID != 0 && _parentID != LocalId) |
1632 | { | 1618 | { |
1633 | if (ParentGroup.RootPart.PhysActor != null) | 1619 | if (ParentGroup.RootPart.PhysActor != null) |
1634 | { | 1620 | { |
1635 | pa.link(ParentGroup.RootPart.PhysActor); | 1621 | PhysActor.link(ParentGroup.RootPart.PhysActor); |
1636 | } | 1622 | } |
1637 | } | 1623 | } |
1638 | } | 1624 | } |
1639 | } | 1625 | } |
1640 | } | 1626 | } |
1641 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | 1627 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
1642 | } | 1628 | } |
1643 | } | 1629 | } |
1644 | } | 1630 | } |
@@ -1704,10 +1690,9 @@ if (m_shape != null) { | |||
1704 | 1690 | ||
1705 | public Vector3 GetGeometricCenter() | 1691 | public Vector3 GetGeometricCenter() |
1706 | { | 1692 | { |
1707 | PhysicsActor pa = PhysActor; | 1693 | if (PhysActor != null) |
1708 | if (pa != null) | ||
1709 | { | 1694 | { |
1710 | return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); | 1695 | return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); |
1711 | } | 1696 | } |
1712 | else | 1697 | else |
1713 | { | 1698 | { |
@@ -1717,10 +1702,9 @@ if (m_shape != null) { | |||
1717 | 1702 | ||
1718 | public float GetMass() | 1703 | public float GetMass() |
1719 | { | 1704 | { |
1720 | PhysicsActor pa = PhysActor; | 1705 | if (PhysActor != null) |
1721 | if (pa != null) | ||
1722 | { | 1706 | { |
1723 | return pa.Mass; | 1707 | return PhysActor.Mass; |
1724 | } | 1708 | } |
1725 | else | 1709 | else |
1726 | { | 1710 | { |
@@ -1730,9 +1714,8 @@ if (m_shape != null) { | |||
1730 | 1714 | ||
1731 | public PhysicsVector GetForce() | 1715 | public PhysicsVector GetForce() |
1732 | { | 1716 | { |
1733 | PhysicsActor pa = PhysActor; | 1717 | if (PhysActor != null) |
1734 | if (pa != null) | 1718 | return PhysActor.Force; |
1735 | return pa.Force; | ||
1736 | else | 1719 | else |
1737 | return new PhysicsVector(); | 1720 | return new PhysicsVector(); |
1738 | } | 1721 | } |
@@ -2111,15 +2094,11 @@ if (m_shape != null) { | |||
2111 | 2094 | ||
2112 | public void PhysicsRequestingTerseUpdate() | 2095 | public void PhysicsRequestingTerseUpdate() |
2113 | { | 2096 | { |
2114 | PhysicsActor pa = PhysActor; | 2097 | if (PhysActor != null) |
2115 | if (pa != null) | ||
2116 | { | 2098 | { |
2117 | Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); | 2099 | Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); |
2118 | 2100 | ||
2119 | if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | | 2101 | if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) |
2120 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | | ||
2121 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | | ||
2122 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) | ||
2123 | { | 2102 | { |
2124 | m_parentGroup.AbsolutePosition = newpos; | 2103 | m_parentGroup.AbsolutePosition = newpos; |
2125 | return; | 2104 | return; |
@@ -2315,15 +2294,14 @@ if (m_shape != null) { | |||
2315 | if (texture != null) | 2294 | if (texture != null) |
2316 | m_shape.SculptData = texture.Data; | 2295 | m_shape.SculptData = texture.Data; |
2317 | 2296 | ||
2318 | PhysicsActor pa = PhysActor; | 2297 | if (PhysActor != null) |
2319 | if (pa != null) | ||
2320 | { | 2298 | { |
2321 | // Tricks physics engine into thinking we've changed the part shape. | 2299 | // Tricks physics engine into thinking we've changed the part shape. |
2322 | PrimitiveBaseShape m_newshape = m_shape.Copy(); | 2300 | PrimitiveBaseShape m_newshape = m_shape.Copy(); |
2323 | pa.Shape = m_newshape; | 2301 | PhysActor.Shape = m_newshape; |
2324 | m_shape = m_newshape; | 2302 | m_shape = m_newshape; |
2325 | 2303 | ||
2326 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | 2304 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
2327 | } | 2305 | } |
2328 | } | 2306 | } |
2329 | } | 2307 | } |
@@ -2542,10 +2520,9 @@ if (m_shape != null) { | |||
2542 | 2520 | ||
2543 | public void SetBuoyancy(float fvalue) | 2521 | public void SetBuoyancy(float fvalue) |
2544 | { | 2522 | { |
2545 | PhysicsActor pa = PhysActor; | 2523 | if (PhysActor != null) |
2546 | if (pa != null) | ||
2547 | { | 2524 | { |
2548 | pa.Buoyancy = fvalue; | 2525 | PhysActor.Buoyancy = fvalue; |
2549 | } | 2526 | } |
2550 | } | 2527 | } |
2551 | 2528 | ||
@@ -2561,62 +2538,56 @@ if (m_shape != null) { | |||
2561 | 2538 | ||
2562 | public void SetFloatOnWater(int floatYN) | 2539 | public void SetFloatOnWater(int floatYN) |
2563 | { | 2540 | { |
2564 | PhysicsActor pa = PhysActor; | 2541 | if (PhysActor != null) |
2565 | if (pa != null) | ||
2566 | { | 2542 | { |
2567 | if (floatYN == 1) | 2543 | if (floatYN == 1) |
2568 | { | 2544 | { |
2569 | pa.FloatOnWater = true; | 2545 | PhysActor.FloatOnWater = true; |
2570 | } | 2546 | } |
2571 | else | 2547 | else |
2572 | { | 2548 | { |
2573 | pa.FloatOnWater = false; | 2549 | PhysActor.FloatOnWater = false; |
2574 | } | 2550 | } |
2575 | } | 2551 | } |
2576 | } | 2552 | } |
2577 | 2553 | ||
2578 | public void SetForce(PhysicsVector force) | 2554 | public void SetForce(PhysicsVector force) |
2579 | { | 2555 | { |
2580 | PhysicsActor pa = PhysActor; | 2556 | if (PhysActor != null) |
2581 | if (pa != null) | ||
2582 | { | 2557 | { |
2583 | pa.Force = force; | 2558 | PhysActor.Force = force; |
2584 | } | 2559 | } |
2585 | } | 2560 | } |
2586 | 2561 | ||
2587 | public void SetVehicleType(int type) | 2562 | public void SetVehicleType(int type) |
2588 | { | 2563 | { |
2589 | PhysicsActor pa = PhysActor; | 2564 | if (PhysActor != null) |
2590 | if (pa != null) | ||
2591 | { | 2565 | { |
2592 | pa.VehicleType = type; | 2566 | PhysActor.VehicleType = type; |
2593 | } | 2567 | } |
2594 | } | 2568 | } |
2595 | 2569 | ||
2596 | public void SetVehicleFloatParam(int param, float value) | 2570 | public void SetVehicleFloatParam(int param, float value) |
2597 | { | 2571 | { |
2598 | PhysicsActor pa = PhysActor; | 2572 | if (PhysActor != null) |
2599 | if (pa != null) | ||
2600 | { | 2573 | { |
2601 | pa.VehicleFloatParam(param, value); | 2574 | PhysActor.VehicleFloatParam(param, value); |
2602 | } | 2575 | } |
2603 | } | 2576 | } |
2604 | 2577 | ||
2605 | public void SetVehicleVectorParam(int param, PhysicsVector value) | 2578 | public void SetVehicleVectorParam(int param, PhysicsVector value) |
2606 | { | 2579 | { |
2607 | PhysicsActor pa = PhysActor; | 2580 | if (PhysActor != null) |
2608 | if (pa != null) | ||
2609 | { | 2581 | { |
2610 | pa.VehicleVectorParam(param, value); | 2582 | PhysActor.VehicleVectorParam(param, value); |
2611 | } | 2583 | } |
2612 | } | 2584 | } |
2613 | 2585 | ||
2614 | public void SetVehicleRotationParam(int param, Quaternion rotation) | 2586 | public void SetVehicleRotationParam(int param, Quaternion rotation) |
2615 | { | 2587 | { |
2616 | PhysicsActor pa = PhysActor; | 2588 | if (PhysActor != null) |
2617 | if (pa != null) | ||
2618 | { | 2589 | { |
2619 | pa.VehicleRotationParam(param, rotation); | 2590 | PhysActor.VehicleRotationParam(param, rotation); |
2620 | } | 2591 | } |
2621 | } | 2592 | } |
2622 | 2593 | ||
@@ -2644,11 +2615,10 @@ if (m_shape != null) { | |||
2644 | 2615 | ||
2645 | public void SetPhysicsAxisRotation() | 2616 | public void SetPhysicsAxisRotation() |
2646 | { | 2617 | { |
2647 | PhysicsActor pa = PhysActor; | 2618 | if (PhysActor != null) |
2648 | if (pa != null) | ||
2649 | { | 2619 | { |
2650 | pa.LockAngularMotion(RotationAxis); | 2620 | PhysActor.LockAngularMotion(RotationAxis); |
2651 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | 2621 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
2652 | } | 2622 | } |
2653 | } | 2623 | } |
2654 | 2624 | ||
@@ -3380,9 +3350,8 @@ if (m_shape != null) { | |||
3380 | { | 3350 | { |
3381 | IsVD = false; // Switch it of for the course of this routine | 3351 | IsVD = false; // Switch it of for the course of this routine |
3382 | VolumeDetectActive = false; // and also permanently | 3352 | VolumeDetectActive = false; // and also permanently |
3383 | PhysicsActor pa = PhysActor; | 3353 | if (PhysActor != null) |
3384 | if (pa != null) | 3354 | PhysActor.SetVolumeDetect(0); // Let physics know about it too |
3385 | pa.SetVolumeDetect(0); // Let physics know about it too | ||
3386 | } | 3355 | } |
3387 | else | 3356 | else |
3388 | { | 3357 | { |
@@ -3430,19 +3399,17 @@ if (m_shape != null) { | |||
3430 | if (IsPhantom || IsAttachment) // note: this may have been changed above in the case of joints | 3399 | if (IsPhantom || IsAttachment) // note: this may have been changed above in the case of joints |
3431 | { | 3400 | { |
3432 | AddFlag(PrimFlags.Phantom); | 3401 | AddFlag(PrimFlags.Phantom); |
3433 | PhysicsActor pa = PhysActor; | 3402 | if (PhysActor != null) |
3434 | if (pa != null) | ||
3435 | { | 3403 | { |
3436 | m_parentGroup.Scene.PhysicsScene.RemovePrim(pa); | 3404 | m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); |
3437 | /// that's not wholesome. Had to make Scene public | 3405 | /// that's not wholesome. Had to make Scene public |
3438 | pa = null; | 3406 | PhysActor = null; |
3439 | } | 3407 | } |
3440 | } | 3408 | } |
3441 | else // Not phantom | 3409 | else // Not phantom |
3442 | { | 3410 | { |
3443 | RemFlag(PrimFlags.Phantom); | 3411 | RemFlag(PrimFlags.Phantom); |
3444 | 3412 | ||
3445 | // This is NOT safe!! | ||
3446 | PhysicsActor pa = PhysActor; | 3413 | PhysicsActor pa = PhysActor; |
3447 | if (pa == null) | 3414 | if (pa == null) |
3448 | { | 3415 | { |
@@ -3455,6 +3422,7 @@ if (m_shape != null) { | |||
3455 | RotationOffset, | 3422 | RotationOffset, |
3456 | UsePhysics); | 3423 | UsePhysics); |
3457 | 3424 | ||
3425 | pa = PhysActor; | ||
3458 | if (pa != null) | 3426 | if (pa != null) |
3459 | { | 3427 | { |
3460 | pa.LocalID = LocalId; | 3428 | pa.LocalID = LocalId; |
@@ -3476,14 +3444,14 @@ if (m_shape != null) { | |||
3476 | (CollisionSound != UUID.Zero) | 3444 | (CollisionSound != UUID.Zero) |
3477 | ) | 3445 | ) |
3478 | { | 3446 | { |
3479 | pa.OnCollisionUpdate += PhysicsCollision; | 3447 | PhysActor.OnCollisionUpdate += PhysicsCollision; |
3480 | pa.SubscribeEvents(1000); | 3448 | PhysActor.SubscribeEvents(1000); |
3481 | } | 3449 | } |
3482 | } | 3450 | } |
3483 | } | 3451 | } |
3484 | else // it already has a physical representation | 3452 | else // it already has a physical representation |
3485 | { | 3453 | { |
3486 | pa.IsPhysical = UsePhysics; | 3454 | PhysActor.IsPhysical = UsePhysics; |
3487 | 3455 | ||
3488 | DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim | 3456 | DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim |
3489 | if (m_parentGroup != null) | 3457 | if (m_parentGroup != null) |
@@ -3506,10 +3474,9 @@ if (m_shape != null) { | |||
3506 | // Defensive programming calls for a check here. | 3474 | // Defensive programming calls for a check here. |
3507 | // Better would be throwing an exception that could be catched by a unit test as the internal | 3475 | // Better would be throwing an exception that could be catched by a unit test as the internal |
3508 | // logic should make sure, this Physactor is always here. | 3476 | // logic should make sure, this Physactor is always here. |
3509 | PhysicsActor pa = this.PhysActor; | 3477 | if (this.PhysActor != null) |
3510 | if (pa != null) | ||
3511 | { | 3478 | { |
3512 | pa.SetVolumeDetect(1); | 3479 | PhysActor.SetVolumeDetect(1); |
3513 | AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active | 3480 | AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active |
3514 | this.VolumeDetectActive = true; | 3481 | this.VolumeDetectActive = true; |
3515 | } | 3482 | } |
@@ -3517,11 +3484,11 @@ if (m_shape != null) { | |||
3517 | } | 3484 | } |
3518 | else | 3485 | else |
3519 | { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like | 3486 | { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like |
3520 | // (mumbles, well, at least if you have infinte CPU powers :-) ) | 3487 | // (mumbles, well, at least if you have infinte CPU powers :-)) |
3521 | PhysicsActor pa = this.PhysActor; | 3488 | PhysicsActor pa = this.PhysActor; |
3522 | if (pa != null) | 3489 | if (pa != null) |
3523 | { | 3490 | { |
3524 | pa.SetVolumeDetect(0); | 3491 | PhysActor.SetVolumeDetect(0); |
3525 | } | 3492 | } |
3526 | this.VolumeDetectActive = false; | 3493 | this.VolumeDetectActive = false; |
3527 | } | 3494 | } |
@@ -3579,11 +3546,10 @@ if (m_shape != null) { | |||
3579 | m_shape.PathTaperY = shapeBlock.PathTaperY; | 3546 | m_shape.PathTaperY = shapeBlock.PathTaperY; |
3580 | m_shape.PathTwist = shapeBlock.PathTwist; | 3547 | m_shape.PathTwist = shapeBlock.PathTwist; |
3581 | m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; | 3548 | m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; |
3582 | PhysicsActor pa = PhysActor; | 3549 | if (PhysActor != null) |
3583 | if (pa != null) | ||
3584 | { | 3550 | { |
3585 | pa.Shape = m_shape; | 3551 | PhysActor.Shape = m_shape; |
3586 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | 3552 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
3587 | } | 3553 | } |
3588 | 3554 | ||
3589 | // This is what makes vehicle trailers work | 3555 | // This is what makes vehicle trailers work |
@@ -3684,21 +3650,19 @@ if (m_shape != null) { | |||
3684 | ) | 3650 | ) |
3685 | { | 3651 | { |
3686 | // subscribe to physics updates. | 3652 | // subscribe to physics updates. |
3687 | PhysicsActor pa = PhysActor; | 3653 | if (PhysActor != null) |
3688 | if (pa != null) | ||
3689 | { | 3654 | { |
3690 | pa.OnCollisionUpdate += PhysicsCollision; | 3655 | PhysActor.OnCollisionUpdate += PhysicsCollision; |
3691 | pa.SubscribeEvents(1000); | 3656 | PhysActor.SubscribeEvents(1000); |
3692 | 3657 | ||
3693 | } | 3658 | } |
3694 | } | 3659 | } |
3695 | else | 3660 | else |
3696 | { | 3661 | { |
3697 | PhysicsActor pa = PhysActor; | 3662 | if (PhysActor != null) |
3698 | if (pa != null) | ||
3699 | { | 3663 | { |
3700 | pa.UnSubscribeEvents(); | 3664 | PhysActor.UnSubscribeEvents(); |
3701 | pa.OnCollisionUpdate -= PhysicsCollision; | 3665 | PhysActor.OnCollisionUpdate -= PhysicsCollision; |
3702 | } | 3666 | } |
3703 | } | 3667 | } |
3704 | 3668 | ||
@@ -3801,8 +3765,6 @@ if (m_shape != null) { | |||
3801 | lPos = AbsolutePosition; | 3765 | lPos = AbsolutePosition; |
3802 | } | 3766 | } |
3803 | 3767 | ||
3804 | // Causes this thread to dig into the Client Thread Data. | ||
3805 | // Remember your locking here! | ||
3806 | remoteClient.SendPrimTerseUpdate(m_regionHandle, | 3768 | remoteClient.SendPrimTerseUpdate(m_regionHandle, |
3807 | (ushort)(m_parentGroup.GetTimeDilation() * | 3769 | (ushort)(m_parentGroup.GetTimeDilation() * |
3808 | (float)ushort.MaxValue), LocalId, lPos, | 3770 | (float)ushort.MaxValue), LocalId, lPos, |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index bf13607..e74b18e 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs | |||
@@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
70 | grp1.Rotation = (Quaternion.CreateFromEulers(90 * Utils.DEG_TO_RAD, 0, 0)); | 70 | grp1.Rotation = (Quaternion.CreateFromEulers(90 * Utils.DEG_TO_RAD, 0, 0)); |
71 | 71 | ||
72 | // <180,0,0> | 72 | // <180,0,0> |
73 | grp2.UpdateGroupRotation(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); | 73 | grp2.UpdateGroupRotationR(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); |
74 | 74 | ||
75 | // Required for linking | 75 | // Required for linking |
76 | grp1.RootPart.UpdateFlag = 0; | 76 | grp1.RootPart.UpdateFlag = 0; |
@@ -154,13 +154,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
154 | grp1.Rotation = (Quaternion.CreateFromEulers(90 * Utils.DEG_TO_RAD, 0, 0)); | 154 | grp1.Rotation = (Quaternion.CreateFromEulers(90 * Utils.DEG_TO_RAD, 0, 0)); |
155 | 155 | ||
156 | // <180,0,0> | 156 | // <180,0,0> |
157 | grp2.UpdateGroupRotation(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); | 157 | grp2.UpdateGroupRotationR(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); |
158 | 158 | ||
159 | // <270,0,0> | 159 | // <270,0,0> |
160 | grp3.Rotation = (Quaternion.CreateFromEulers(270 * Utils.DEG_TO_RAD, 0, 0)); | 160 | grp3.Rotation = (Quaternion.CreateFromEulers(270 * Utils.DEG_TO_RAD, 0, 0)); |
161 | 161 | ||
162 | // <0,90,0> | 162 | // <0,90,0> |
163 | grp4.UpdateGroupRotation(Quaternion.CreateFromEulers(0, 90 * Utils.DEG_TO_RAD, 0)); | 163 | grp4.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 90 * Utils.DEG_TO_RAD, 0)); |
164 | 164 | ||
165 | // Required for linking | 165 | // Required for linking |
166 | grp1.RootPart.UpdateFlag = 0; | 166 | grp1.RootPart.UpdateFlag = 0; |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEVehicleSettings.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.c_comments index a547c3e..1060aa6 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEVehicleSettings.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.c_comments | |||
@@ -1,4 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces | ||
3 | * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: | ||
4 | * ODEPrim.cs contains methods dealing with Prim editing, Prim | ||
5 | * characteristics and Kinetic motion. | ||
6 | * ODEDynamics.cs contains methods dealing with Prim Physical motion | ||
7 | * (dynamics) and the associated settings. Old Linear and angular | ||
8 | * motors for dynamic motion have been replace with MoveLinear() | ||
9 | * and MoveAngular(); 'Physical' is used only to switch ODE dynamic | ||
10 | * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to | ||
11 | * switch between 'VEHICLE' parameter use and general dynamics | ||
12 | * settings use. | ||
13 | * | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 14 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 15 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 16 | * |
@@ -37,10 +49,10 @@ using OpenSim.Region.Physics.Manager; | |||
37 | 49 | ||
38 | namespace OpenSim.Region.Physics.OdePlugin | 50 | namespace OpenSim.Region.Physics.OdePlugin |
39 | { | 51 | { |
40 | public class ODEVehicleSettings | 52 | public class ODEDynamics |
41 | { | 53 | { |
42 | public Vehicle Type | 54 | public Vehicle Type |
43 | { | 55 | { |
44 | get { return m_type; } | 56 | get { return m_type; } |
45 | } | 57 | } |
46 | 58 | ||
@@ -49,49 +61,71 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
49 | get { return m_body; } | 61 | get { return m_body; } |
50 | } | 62 | } |
51 | 63 | ||
52 | private int frcount = 0; | 64 | private int frcount = 0; // Used to limit dynamics debug output to |
53 | // private float frmod = 3.0f; | 65 | // every 100th frame |
54 | 66 | ||
55 | private Vehicle m_type = Vehicle.TYPE_NONE; | ||
56 | // private OdeScene m_parentScene = null; | 67 | // private OdeScene m_parentScene = null; |
57 | private IntPtr m_body = IntPtr.Zero; | 68 | private IntPtr m_body = IntPtr.Zero; |
58 | private IntPtr m_jointGroup = IntPtr.Zero; | 69 | private IntPtr m_jointGroup = IntPtr.Zero; |
59 | private IntPtr m_aMotor = IntPtr.Zero; | 70 | private IntPtr m_aMotor = IntPtr.Zero; |
60 | private IntPtr m_lMotor1 = IntPtr.Zero; | 71 | |
61 | // private IntPtr m_lMotor2 = IntPtr.Zero; | ||
62 | // private IntPtr m_lMotor3 = IntPtr.Zero; | ||
63 | 72 | ||
64 | // Vehicle properties | 73 | // Vehicle properties |
65 | // private Quaternion m_referenceFrame = Quaternion.Identity; | 74 | private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind |
66 | private Vector3 m_angularFrictionTimescale = Vector3.Zero; | 75 | // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier |
67 | private Vector3 m_angularMotorDirection = Vector3.Zero; | 76 | private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: |
68 | private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero; | 77 | // HOVER_TERRAIN_ONLY |
78 | // HOVER_GLOBAL_HEIGHT | ||
79 | // NO_DEFLECTION_UP | ||
80 | // HOVER_WATER_ONLY | ||
81 | // HOVER_UP_ONLY | ||
82 | // LIMIT_MOTOR_UP | ||
83 | // LIMIT_ROLL_ONLY | ||
84 | |||
85 | // Linear properties | ||
86 | private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time | ||
87 | private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL | ||
88 | private Vector3 m_dir = Vector3.Zero; // velocity applied to body | ||
69 | private Vector3 m_linearFrictionTimescale = Vector3.Zero; | 89 | private Vector3 m_linearFrictionTimescale = Vector3.Zero; |
70 | private Vector3 m_linearMotorDirection = Vector3.Zero; | 90 | private float m_linearMotorDecayTimescale = 0; |
71 | private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; | 91 | private float m_linearMotorTimescale = 0; |
92 | private Vector3 m_lastLinearVelocityVector = Vector3.Zero; | ||
93 | // private bool m_LinearMotorSetLastFrame = false; | ||
72 | // private Vector3 m_linearMotorOffset = Vector3.Zero; | 94 | // private Vector3 m_linearMotorOffset = Vector3.Zero; |
73 | // private float m_angularDeflectionEfficiency = 0; | 95 | |
74 | // private float m_angularDeflectionTimescale = 0; | 96 | //Angular properties |
97 | private Vector3 m_angularMotorDirection = Vector3.Zero; | ||
98 | private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero; | ||
99 | private Vector3 m_angularFrictionTimescale = Vector3.Zero; | ||
75 | private float m_angularMotorDecayTimescale = 0; | 100 | private float m_angularMotorDecayTimescale = 0; |
76 | private float m_angularMotorTimescale = 0; | 101 | private float m_angularMotorTimescale = 0; |
102 | private Vector3 m_lastAngularVelocityVector = Vector3.Zero; | ||
103 | |||
104 | //Deflection properties | ||
105 | // private float m_angularDeflectionEfficiency = 0; | ||
106 | // private float m_angularDeflectionTimescale = 0; | ||
107 | // private float m_linearDeflectionEfficiency = 0; | ||
108 | // private float m_linearDeflectionTimescale = 0; | ||
109 | |||
110 | //Banking properties | ||
77 | // private float m_bankingEfficiency = 0; | 111 | // private float m_bankingEfficiency = 0; |
78 | // private float m_bankingMix = 0; | 112 | // private float m_bankingMix = 0; |
79 | // private float m_bankingTimescale = 0; | 113 | // private float m_bankingTimescale = 0; |
80 | // private float m_buoyancy = 0; | 114 | |
81 | // private float m_hoverHeight = 0; | 115 | //Hover and Buoyancy properties |
82 | // private float m_hoverEfficiency = 0; | 116 | private float m_VhoverHeight = 0f; |
83 | // private float m_hoverTimescale = 0; | 117 | private float m_VhoverEfficiency = 0f; |
84 | // private float m_linearDeflectionEfficiency = 0; | 118 | private float m_VhoverTimescale = 0f; |
85 | // private float m_linearDeflectionTimescale = 0; | 119 | private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height |
86 | private float m_linearMotorDecayTimescale = 0; | 120 | private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. |
87 | private float m_linearMotorTimescale = 0; | 121 | // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) |
122 | // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. | ||
123 | // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. | ||
124 | |||
125 | //Attractor properties | ||
88 | private float m_verticalAttractionEfficiency = 0; | 126 | private float m_verticalAttractionEfficiency = 0; |
89 | private float m_verticalAttractionTimescale = 0; | 127 | private float m_verticalAttractionTimescale = 0; |
90 | private Vector3 m_lastLinearVelocityVector = Vector3.Zero; | 128 | |
91 | private Vector3 m_lastAngularVelocityVector = Vector3.Zero; | ||
92 | private VehicleFlag m_flags = (VehicleFlag) 0; | ||
93 | |||
94 | // private bool m_LinearMotorSetLastFrame = false; | ||
95 | 129 | ||
96 | 130 | ||
97 | 131 | ||
@@ -129,17 +163,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
129 | // m_bankingTimescale = pValue; | 163 | // m_bankingTimescale = pValue; |
130 | break; | 164 | break; |
131 | case Vehicle.BUOYANCY: | 165 | case Vehicle.BUOYANCY: |
132 | // m_buoyancy = pValue; | 166 | if (pValue < -1f) pValue = -1f; |
167 | if (pValue > 1f) pValue = 1f; | ||
168 | m_VehicleBuoyancy = pValue; | ||
133 | break; | 169 | break; |
134 | case Vehicle.HOVER_EFFICIENCY: | 170 | case Vehicle.HOVER_EFFICIENCY: |
135 | // m_hoverEfficiency = pValue; | 171 | if (pValue < 0f) pValue = 0f; |
172 | if (pValue > 1f) pValue = 1f; | ||
173 | m_VhoverEfficiency = pValue; | ||
136 | break; | 174 | break; |
137 | case Vehicle.HOVER_HEIGHT: | 175 | case Vehicle.HOVER_HEIGHT: |
138 | // m_hoverHeight = pValue; | 176 | m_VhoverHeight = pValue; |
139 | break; | 177 | break; |
140 | case Vehicle.HOVER_TIMESCALE: | 178 | case Vehicle.HOVER_TIMESCALE: |
141 | if (pValue < 0.01f) pValue = 0.01f; | 179 | if (pValue < 0.01f) pValue = 0.01f; |
142 | // m_hoverTimescale = pValue; | 180 | m_VhoverTimescale = pValue; |
143 | break; | 181 | break; |
144 | case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: | 182 | case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: |
145 | if (pValue < 0.01f) pValue = 0.01f; | 183 | if (pValue < 0.01f) pValue = 0.01f; |
@@ -158,7 +196,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
158 | m_linearMotorTimescale = pValue; | 196 | m_linearMotorTimescale = pValue; |
159 | break; | 197 | break; |
160 | case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: | 198 | case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: |
161 | if (pValue < 0.01f) pValue = 0.01f; | 199 | if (pValue < 0.0f) pValue = 0.0f; |
200 | if (pValue > 1.0f) pValue = 1.0f; | ||
162 | m_verticalAttractionEfficiency = pValue; | 201 | m_verticalAttractionEfficiency = pValue; |
163 | break; | 202 | break; |
164 | case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: | 203 | case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: |
@@ -187,8 +226,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
187 | break; | 226 | break; |
188 | 227 | ||
189 | } | 228 | } |
190 | Reset(); | 229 | |
191 | } | 230 | }//end ProcessFloatVehicleParam |
192 | 231 | ||
193 | internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue) | 232 | internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue) |
194 | { | 233 | { |
@@ -212,8 +251,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
212 | // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); | 251 | // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); |
213 | break; | 252 | break; |
214 | } | 253 | } |
215 | Reset(); | 254 | |
216 | } | 255 | }//end ProcessVectorVehicleParam |
217 | 256 | ||
218 | internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) | 257 | internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) |
219 | { | 258 | { |
@@ -223,113 +262,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
223 | // m_referenceFrame = pValue; | 262 | // m_referenceFrame = pValue; |
224 | break; | 263 | break; |
225 | } | 264 | } |
226 | Reset(); | ||
227 | } | ||
228 | |||
229 | internal void ProcessTypeChange(Vehicle pType) | ||
230 | { | ||
231 | if (m_type == Vehicle.TYPE_NONE && pType != Vehicle.TYPE_NONE) | ||
232 | { | ||
233 | // Activate whatever it is | ||
234 | SetDefaultsForType(pType); | ||
235 | Reset(); | ||
236 | } | ||
237 | else if (m_type != Vehicle.TYPE_NONE && pType != Vehicle.TYPE_NONE) | ||
238 | { | ||
239 | // Set properties | ||
240 | SetDefaultsForType(pType); | ||
241 | // then reset | ||
242 | Reset(); | ||
243 | } | ||
244 | else if (m_type != Vehicle.TYPE_NONE && pType == Vehicle.TYPE_NONE) | ||
245 | { | ||
246 | m_type = pType; | ||
247 | Destroy(); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | internal void Disable() | ||
252 | { | ||
253 | if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) | ||
254 | return; | ||
255 | |||
256 | if (m_aMotor != IntPtr.Zero) | ||
257 | { | ||
258 | |||
259 | } | ||
260 | |||
261 | } | ||
262 | |||
263 | internal void Enable(IntPtr pBody, OdeScene pParentScene) | ||
264 | { | ||
265 | if (m_type == Vehicle.TYPE_NONE) | ||
266 | return; | ||
267 | |||
268 | m_body = pBody; | ||
269 | // m_parentScene = pParentScene; | ||
270 | if (m_jointGroup == IntPtr.Zero) | ||
271 | m_jointGroup = d.JointGroupCreate(3); | ||
272 | |||
273 | if (pBody != IntPtr.Zero) | ||
274 | { | ||
275 | |||
276 | if (m_lMotor1 == IntPtr.Zero) | ||
277 | { | ||
278 | d.BodySetAutoDisableFlag(Body, false); | ||
279 | m_lMotor1 = d.JointCreateLMotor(pParentScene.world, m_jointGroup); | ||
280 | d.JointSetLMotorNumAxes(m_lMotor1, 1); | ||
281 | d.JointAttach(m_lMotor1, Body, IntPtr.Zero); | ||
282 | } | ||
283 | |||
284 | if (m_aMotor == IntPtr.Zero) | ||
285 | { | ||
286 | m_aMotor = d.JointCreateAMotor(pParentScene.world, m_jointGroup); | ||
287 | d.JointSetAMotorNumAxes(m_aMotor, 3); | ||
288 | d.JointAttach(m_aMotor, Body, IntPtr.Zero); | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | |||
293 | internal void Reset() | ||
294 | { | ||
295 | if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) | ||
296 | return; | ||
297 | 265 | ||
298 | } | 266 | }//end ProcessRotationVehicleParam |
299 | 267 | ||
300 | internal void Destroy() | 268 | internal void ProcessTypeChange(Vehicle pType) |
301 | { | ||
302 | if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) | ||
303 | return; | ||
304 | if (m_aMotor != IntPtr.Zero) | ||
305 | { | ||
306 | d.JointDestroy(m_aMotor); | ||
307 | } | ||
308 | if (m_lMotor1 != IntPtr.Zero) | ||
309 | { | ||
310 | d.JointDestroy(m_lMotor1); | ||
311 | } | ||
312 | |||
313 | } | ||
314 | |||
315 | internal void Step(float pTimestep) | ||
316 | { | ||
317 | if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) | ||
318 | return; | ||
319 | frcount++; | ||
320 | if (frcount > 100) | ||
321 | frcount = 0; | ||
322 | |||
323 | VerticalAttractor(pTimestep); | ||
324 | LinearMotor(pTimestep); | ||
325 | |||
326 | |||
327 | AngularMotor(pTimestep); | ||
328 | |||
329 | } | ||
330 | |||
331 | private void SetDefaultsForType(Vehicle pType) | ||
332 | { | 269 | { |
270 | Console.WriteLine("ProcessTypeChange to " + pType); | ||
271 | |||
272 | // Set Defaults For Type | ||
333 | m_type = pType; | 273 | m_type = pType; |
334 | switch (pType) | 274 | switch (pType) |
335 | { | 275 | { |
@@ -342,10 +282,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
342 | m_angularMotorDirection = Vector3.Zero; | 282 | m_angularMotorDirection = Vector3.Zero; |
343 | m_angularMotorTimescale = 1000; | 283 | m_angularMotorTimescale = 1000; |
344 | m_angularMotorDecayTimescale = 120; | 284 | m_angularMotorDecayTimescale = 120; |
345 | // m_hoverHeight = 0; | 285 | m_VhoverHeight = 0; |
346 | // m_hoverEfficiency = 10; | 286 | m_VhoverEfficiency = 1; |
347 | // m_hoverTimescale = 10; | 287 | m_VhoverTimescale = 10; |
348 | // m_buoyancy = 0; | 288 | m_VehicleBuoyancy = 0; |
349 | // m_linearDeflectionEfficiency = 1; | 289 | // m_linearDeflectionEfficiency = 1; |
350 | // m_linearDeflectionTimescale = 1; | 290 | // m_linearDeflectionTimescale = 1; |
351 | // m_angularDeflectionEfficiency = 1; | 291 | // m_angularDeflectionEfficiency = 1; |
@@ -368,10 +308,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
368 | m_angularMotorDirection = Vector3.Zero; | 308 | m_angularMotorDirection = Vector3.Zero; |
369 | m_angularMotorTimescale = 1; | 309 | m_angularMotorTimescale = 1; |
370 | m_angularMotorDecayTimescale = 0.8f; | 310 | m_angularMotorDecayTimescale = 0.8f; |
371 | // m_hoverHeight = 0; | 311 | m_VhoverHeight = 0; |
372 | // // m_hoverEfficiency = 0; | 312 | m_VhoverEfficiency = 0; |
373 | // // m_hoverTimescale = 1000; | 313 | m_VhoverTimescale = 1000; |
374 | // // m_buoyancy = 0; | 314 | m_VehicleBuoyancy = 0; |
375 | // // m_linearDeflectionEfficiency = 1; | 315 | // // m_linearDeflectionEfficiency = 1; |
376 | // // m_linearDeflectionTimescale = 2; | 316 | // // m_linearDeflectionTimescale = 2; |
377 | // // m_angularDeflectionEfficiency = 0; | 317 | // // m_angularDeflectionEfficiency = 0; |
@@ -395,10 +335,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
395 | m_angularMotorDirection = Vector3.Zero; | 335 | m_angularMotorDirection = Vector3.Zero; |
396 | m_angularMotorTimescale = 4; | 336 | m_angularMotorTimescale = 4; |
397 | m_angularMotorDecayTimescale = 4; | 337 | m_angularMotorDecayTimescale = 4; |
398 | // m_hoverHeight = 0; | 338 | m_VhoverHeight = 0; |
399 | // m_hoverEfficiency = 0.5f; | 339 | m_VhoverEfficiency = 0.5f; |
400 | // m_hoverTimescale = 2; | 340 | m_VhoverTimescale = 2; |
401 | // m_buoyancy = 1; | 341 | m_VehicleBuoyancy = 1; |
402 | // m_linearDeflectionEfficiency = 0.5f; | 342 | // m_linearDeflectionEfficiency = 0.5f; |
403 | // m_linearDeflectionTimescale = 3; | 343 | // m_linearDeflectionTimescale = 3; |
404 | // m_angularDeflectionEfficiency = 0.5f; | 344 | // m_angularDeflectionEfficiency = 0.5f; |
@@ -409,8 +349,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
409 | // m_bankingMix = 0.8f; | 349 | // m_bankingMix = 0.8f; |
410 | // m_bankingTimescale = 1; | 350 | // m_bankingTimescale = 1; |
411 | // m_referenceFrame = Quaternion.Identity; | 351 | // m_referenceFrame = Quaternion.Identity; |
412 | m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); | 352 | m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | |
413 | m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_UP_ONLY | | 353 | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); |
354 | m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | | ||
414 | VehicleFlag.LIMIT_MOTOR_UP); | 355 | VehicleFlag.LIMIT_MOTOR_UP); |
415 | break; | 356 | break; |
416 | case Vehicle.TYPE_AIRPLANE: | 357 | case Vehicle.TYPE_AIRPLANE: |
@@ -422,10 +363,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
422 | m_angularMotorDirection = Vector3.Zero; | 363 | m_angularMotorDirection = Vector3.Zero; |
423 | m_angularMotorTimescale = 4; | 364 | m_angularMotorTimescale = 4; |
424 | m_angularMotorDecayTimescale = 4; | 365 | m_angularMotorDecayTimescale = 4; |
425 | // m_hoverHeight = 0; | 366 | m_VhoverHeight = 0; |
426 | // m_hoverEfficiency = 0.5f; | 367 | m_VhoverEfficiency = 0.5f; |
427 | // m_hoverTimescale = 1000; | 368 | m_VhoverTimescale = 1000; |
428 | // m_buoyancy = 0; | 369 | m_VehicleBuoyancy = 0; |
429 | // m_linearDeflectionEfficiency = 0.5f; | 370 | // m_linearDeflectionEfficiency = 0.5f; |
430 | // m_linearDeflectionTimescale = 3; | 371 | // m_linearDeflectionTimescale = 3; |
431 | // m_angularDeflectionEfficiency = 1; | 372 | // m_angularDeflectionEfficiency = 1; |
@@ -449,10 +390,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
449 | m_angularMotorDirection = Vector3.Zero; | 390 | m_angularMotorDirection = Vector3.Zero; |
450 | m_angularMotorTimescale = 6; | 391 | m_angularMotorTimescale = 6; |
451 | m_angularMotorDecayTimescale = 10; | 392 | m_angularMotorDecayTimescale = 10; |
452 | // m_hoverHeight = 5; | 393 | m_VhoverHeight = 5; |
453 | // m_hoverEfficiency = 0.8f; | 394 | m_VhoverEfficiency = 0.8f; |
454 | // m_hoverTimescale = 10; | 395 | m_VhoverTimescale = 10; |
455 | // m_buoyancy = 1; | 396 | m_VehicleBuoyancy = 1; |
456 | // m_linearDeflectionEfficiency = 0; | 397 | // m_linearDeflectionEfficiency = 0; |
457 | // m_linearDeflectionTimescale = 5; | 398 | // m_linearDeflectionTimescale = 5; |
458 | // m_angularDeflectionEfficiency = 0; | 399 | // m_angularDeflectionEfficiency = 0; |
@@ -463,106 +404,165 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
463 | // m_bankingMix = 0.7f; | 404 | // m_bankingMix = 0.7f; |
464 | // m_bankingTimescale = 5; | 405 | // m_bankingTimescale = 5; |
465 | // m_referenceFrame = Quaternion.Identity; | 406 | // m_referenceFrame = Quaternion.Identity; |
466 | m_flags = (VehicleFlag)0; | 407 | m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | |
408 | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); | ||
409 | m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); | ||
467 | break; | 410 | break; |
468 | 411 | ||
469 | } | 412 | } |
470 | } | 413 | }//end SetDefaultsForType |
471 | |||
472 | private void VerticalAttractor(float pTimestep) | ||
473 | { | ||
474 | // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air. | ||
475 | // The amotor needs a few seconds to stabilize so without it, the avatar shoots up sky high when you | ||
476 | // change appearance and when you enter the simulator | ||
477 | // After this routine is done, the amotor stabilizes much quicker | ||
478 | d.Mass objMass; | ||
479 | d.BodyGetMass(Body, out objMass); | ||
480 | //d.BodyGetS | ||
481 | 414 | ||
482 | d.Vector3 feet; | 415 | internal void Enable(IntPtr pBody, OdeScene pParentScene) |
483 | d.Vector3 head; | 416 | { |
484 | d.BodyGetRelPointPos(m_body, 0.0f, 0.0f, -1.0f, out feet); | 417 | //Console.WriteLine("Enable m_type=" + m_type + " m_VehicleBuoyancy=" + m_VehicleBuoyancy); |
485 | d.BodyGetRelPointPos(m_body, 0.0f, 0.0f, 1.0f, out head); | 418 | if (m_type == Vehicle.TYPE_NONE) |
486 | float posture = head.Z - feet.Z; | 419 | return; |
487 | 420 | ||
488 | //Console.WriteLine(String.Format("head: <{0},{1},{2}>, feet:<{3},{4},{5}> diff:<{6},{7},{8}>", head.X, head.Y, head.Z, feet.X, | 421 | m_body = pBody; |
489 | // feet.Y, feet.Z, head.X - feet.X, head.Y - feet.Y, head.Z - feet.Z)); | 422 | //KF: This used to set up the linear and angular joints |
490 | //Console.WriteLine(String.Format("diff:<{0},{1},{2}>",head.X - feet.X, head.Y - feet.Y, head.Z - feet.Z)); | ||
491 | |||
492 | // restoring force proportional to lack of posture: | ||
493 | float servo = (2.5f - posture) * (objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep)) * objMass.mass; | ||
494 | d.BodyAddForceAtRelPos(m_body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f); | ||
495 | d.BodyAddForceAtRelPos(m_body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f); | ||
496 | //d.BodyAddTorque(m_body, (head.X - feet.X) * servo, (head.Y - feet.Y) * servo, (head.Z - feet.Z) * servo); | ||
497 | //d.Matrix3 bodyrotation = d.BodyGetRotation(Body); | ||
498 | //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22); | ||
499 | } | 423 | } |
500 | 424 | ||
501 | private void LinearMotor(float pTimestep) | 425 | internal void Step(float pTimestep, OdeScene pParentScene) |
502 | { | 426 | { |
427 | if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) | ||
428 | return; | ||
429 | frcount++; // used to limit debug comment output | ||
430 | if (frcount > 100) | ||
431 | frcount = 0; | ||
503 | 432 | ||
504 | if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) | 433 | MoveLinear(pTimestep, pParentScene); |
434 | MoveAngular(pTimestep); | ||
435 | }// end Step | ||
436 | |||
437 | private void MoveLinear(float pTimestep, OdeScene _pParentScene) | ||
438 | { | ||
439 | if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant | ||
505 | { | 440 | { |
506 | 441 | if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); | |
507 | Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); | ||
508 | m_lastLinearVelocityVector += (addAmount*10); | ||
509 | 442 | ||
443 | // add drive to body | ||
444 | Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); | ||
445 | m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? | ||
446 | |||
510 | // This will work temporarily, but we really need to compare speed on an axis | 447 | // This will work temporarily, but we really need to compare speed on an axis |
448 | // KF: Limit body velocity to applied velocity? | ||
511 | if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) | 449 | if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) |
512 | m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; | 450 | m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; |
513 | if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) | 451 | if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) |
514 | m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; | 452 | m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; |
515 | if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) | 453 | if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) |
516 | m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; | 454 | m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; |
517 | //Console.WriteLine("add: " + addAmount); | 455 | |
518 | 456 | // decay applied velocity | |
519 | Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); | 457 | Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); |
520 | //Console.WriteLine("decay: " + decayfraction); | 458 | //Console.WriteLine("decay: " + decayfraction); |
521 | |||
522 | m_linearMotorDirection -= m_linearMotorDirection * decayfraction; | 459 | m_linearMotorDirection -= m_linearMotorDirection * decayfraction; |
523 | //Console.WriteLine("actual: " + m_linearMotorDirection); | 460 | //Console.WriteLine("actual: " + m_linearMotorDirection); |
524 | } | 461 | } |
525 | 462 | else | |
526 | //System.Console.WriteLine(m_linearMotorDirection + " " + m_lastLinearVelocityVector); | 463 | { // requested is not significant |
527 | 464 | // if what remains of applied is small, zero it. | |
528 | SetLinearMotorProperties(); | 465 | if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) |
529 | 466 | m_lastLinearVelocityVector = Vector3.Zero; | |
467 | } | ||
468 | |||
469 | |||
470 | // convert requested object velocity to world-referenced vector | ||
471 | m_dir = m_lastLinearVelocityVector; | ||
472 | d.Quaternion rot = d.BodyGetQuaternion(Body); | ||
473 | Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object | ||
474 | m_dir *= rotq; // apply obj rotation to velocity vector | ||
475 | |||
476 | // add Gravity andBuoyancy | ||
477 | // KF: So far I have found no good method to combine a script-requested | ||
478 | // .Z velocity and gravity. Therefore only 0g will used script-requested | ||
479 | // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. | ||
480 | Vector3 grav = Vector3.Zero; | ||
481 | if(m_VehicleBuoyancy < 1.0f) | ||
482 | { | ||
483 | // There is some gravity, make a gravity force vector | ||
484 | // that is applied after object velocity. | ||
485 | d.Mass objMass; | ||
486 | d.BodyGetMass(Body, out objMass); | ||
487 | // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; | ||
488 | grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); | ||
489 | // Preserve the current Z velocity | ||
490 | d.Vector3 vel_now = d.BodyGetLinearVel(Body); | ||
491 | m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity | ||
492 | } // else its 1.0, no gravity. | ||
493 | |||
494 | // Check if hovering | ||
495 | if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) | ||
496 | { | ||
497 | // We should hover, get the target height | ||
498 | d.Vector3 pos = d.BodyGetPosition(Body); | ||
499 | if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY) | ||
500 | { | ||
501 | m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; | ||
502 | } | ||
503 | else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY) | ||
504 | { | ||
505 | m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; | ||
506 | } | ||
507 | else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT) | ||
508 | { | ||
509 | m_VhoverTargetHeight = m_VhoverHeight; | ||
510 | } | ||
511 | |||
512 | if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY) | ||
513 | { | ||
514 | // If body is aready heigher, use its height as target height | ||
515 | if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; | ||
516 | } | ||
517 | |||
518 | // m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped | ||
519 | // m_VhoverTimescale = 0f; // time to acheive height | ||
520 | // pTimestep is time since last frame,in secs | ||
521 | float herr0 = pos.Z - m_VhoverTargetHeight; | ||
522 | //if(frcount == 0) Console.WriteLine("herr0=" + herr0); | ||
523 | // Replace Vertical speed with correction figure if significant | ||
524 | if(Math.Abs(herr0) > 0.01f ) | ||
525 | { | ||
526 | d.Mass objMass; | ||
527 | d.BodyGetMass(Body, out objMass); | ||
528 | m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale); | ||
529 | // m_VhoverEfficiency is not yet implemented | ||
530 | } | ||
531 | else | ||
532 | { | ||
533 | m_dir.Z = 0f; | ||
534 | } | ||
535 | } | ||
536 | |||
537 | // Apply velocity | ||
538 | d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z); | ||
539 | //if(frcount == 0) Console.WriteLine("Move " + Body + ":"+ m_dir.X + " " + m_dir.Y + " " + m_dir.Z); | ||
540 | // apply gravity force | ||
541 | d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); | ||
542 | //if(frcount == 0) Console.WriteLine("Force " + Body + ":" + grav.X + " " + grav.Y + " " + grav.Z); | ||
543 | |||
544 | |||
545 | // apply friction | ||
530 | Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); | 546 | Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); |
531 | m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; | 547 | m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; |
532 | 548 | } // end MoveLinear() | |
533 | //m_linearMotorDirection *= decayamount; | 549 | |
534 | 550 | private void MoveAngular(float pTimestep) | |
535 | } | ||
536 | |||
537 | private void SetLinearMotorProperties() | ||
538 | { | ||
539 | Vector3 dirNorm = m_lastLinearVelocityVector; | ||
540 | dirNorm.Normalize(); | ||
541 | |||
542 | d.Mass objMass; | ||
543 | d.BodyGetMass(Body, out objMass); | ||
544 | d.Quaternion rot = d.BodyGetQuaternion(Body); | ||
545 | Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); | ||
546 | dirNorm *= rotq; | ||
547 | if (m_lMotor1 != IntPtr.Zero) | ||
548 | { | ||
549 | |||
550 | d.JointSetLMotorAxis(m_lMotor1, 0, 1, dirNorm.X, dirNorm.Y, dirNorm.Z); | ||
551 | d.JointSetLMotorParam(m_lMotor1, (int)dParam.Vel, m_lastLinearVelocityVector.Length()); | ||
552 | |||
553 | d.JointSetLMotorParam(m_lMotor1, (int)dParam.FMax, 35f * objMass.mass); | ||
554 | } | ||
555 | |||
556 | } | ||
557 | |||
558 | private void AngularMotor(float pTimestep) | ||
559 | { | 551 | { |
552 | |||
553 | // m_angularMotorDirection is the latest value from the script, and is decayed here | ||
554 | // m_angularMotorDirectionLASTSET is the latest value from the script | ||
555 | // m_lastAngularVelocityVector is what is being applied to the Body, varied up and down here | ||
556 | |||
560 | if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) | 557 | if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) |
561 | { | 558 | { |
562 | 559 | if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); | |
560 | // ramp up to new value | ||
563 | Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep); | 561 | Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep); |
564 | m_lastAngularVelocityVector += (addAmount * 10); | 562 | m_lastAngularVelocityVector += (addAmount * 10f); |
563 | //if(frcount == 0) Console.WriteLine("add: " + addAmount); | ||
565 | 564 | ||
565 | // limit applied value to what was set by script | ||
566 | // This will work temporarily, but we really need to compare speed on an axis | 566 | // This will work temporarily, but we really need to compare speed on an axis |
567 | if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X)) | 567 | if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X)) |
568 | m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X; | 568 | m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X; |
@@ -570,57 +570,61 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
570 | m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y; | 570 | m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y; |
571 | if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z)) | 571 | if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z)) |
572 | m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z; | 572 | m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z; |
573 | //Console.WriteLine("add: " + addAmount); | ||
574 | 573 | ||
574 | // decay the requested value | ||
575 | Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep))); | 575 | Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep))); |
576 | //Console.WriteLine("decay: " + decayfraction); | 576 | //Console.WriteLine("decay: " + decayfraction); |
577 | |||
578 | m_angularMotorDirection -= m_angularMotorDirection * decayfraction; | 577 | m_angularMotorDirection -= m_angularMotorDirection * decayfraction; |
579 | //Console.WriteLine("actual: " + m_linearMotorDirection); | 578 | //Console.WriteLine("actual: " + m_linearMotorDirection); |
580 | } | 579 | } |
581 | 580 | // KF: m_lastAngularVelocityVector is rotational speed in rad/sec ? | |
582 | //System.Console.WriteLine(m_linearMotorDirection + " " + m_lastLinearVelocityVector); | 581 | |
583 | 582 | // Vertical attractor section | |
584 | SetAngularMotorProperties(); | 583 | |
585 | 584 | // d.Mass objMass; | |
585 | // d.BodyGetMass(Body, out objMass); | ||
586 | // float servo = 100f * objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep); | ||
587 | float servo = 0.1f * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep); | ||
588 | // get present body rotation | ||
589 | d.Quaternion rot = d.BodyGetQuaternion(Body); | ||
590 | Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); | ||
591 | // make a vector pointing up | ||
592 | Vector3 verterr = Vector3.Zero; | ||
593 | verterr.Z = 1.0f; | ||
594 | // rotate it to Body Angle | ||
595 | verterr = verterr * rotq; | ||
596 | // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. | ||
597 | // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go | ||
598 | // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. | ||
599 | if (verterr.Z < 0.0f) | ||
600 | { | ||
601 | verterr.X = 2.0f - verterr.X; | ||
602 | verterr.Y = 2.0f - verterr.Y; | ||
603 | } | ||
604 | // Error is 0 (no error) to +/- 2 (max error) | ||
605 | // scale it by servo | ||
606 | verterr = verterr * servo; | ||
607 | |||
608 | // rotate to object frame | ||
609 | // verterr = verterr * rotq; | ||
610 | |||
611 | // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so | ||
612 | // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. | ||
613 | m_lastAngularVelocityVector.X += verterr.Y; | ||
614 | m_lastAngularVelocityVector.Y -= verterr.X; | ||
615 | /* | ||
616 | if(frcount == 0) | ||
617 | { | ||
618 | // Console.WriteLine("AngleMotor " + m_lastAngularVelocityVector); | ||
619 | Console.WriteLine(String.Format("VA Body:{0} servo:{1} err:<{2},{3},{4}> VAE:{5}", | ||
620 | Body, servo, verterr.X, verterr.Y, verterr.Z, m_verticalAttractionEfficiency)); | ||
621 | } | ||
622 | */ | ||
623 | d.BodySetAngularVel (Body, m_lastAngularVelocityVector.X, m_lastAngularVelocityVector.Y, m_lastAngularVelocityVector.Z); | ||
624 | // apply friction | ||
586 | Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); | 625 | Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); |
587 | m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount; | 626 | m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount; |
588 | 627 | ||
589 | //m_linearMotorDirection *= decayamount; | 628 | } //end MoveAngular |
590 | |||
591 | } | ||
592 | private void SetAngularMotorProperties() | ||
593 | { | ||
594 | |||
595 | |||
596 | |||
597 | d.Mass objMass; | ||
598 | d.BodyGetMass(Body, out objMass); | ||
599 | //d.Quaternion rot = d.BodyGetQuaternion(Body); | ||
600 | //Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); | ||
601 | Vector3 axis0 = Vector3.UnitX; | ||
602 | Vector3 axis1 = Vector3.UnitY; | ||
603 | Vector3 axis2 = Vector3.UnitZ; | ||
604 | //axis0 *= rotq; | ||
605 | //axis1 *= rotq; | ||
606 | //axis2 *= rotq; | ||
607 | |||
608 | |||
609 | |||
610 | if (m_aMotor != IntPtr.Zero) | ||
611 | { | ||
612 | d.JointSetAMotorAxis(m_aMotor, 0, 1, axis0.X, axis0.Y, axis0.Z); | ||
613 | d.JointSetAMotorAxis(m_aMotor, 1, 1, axis1.X, axis1.Y, axis1.Z); | ||
614 | d.JointSetAMotorAxis(m_aMotor, 2, 1, axis2.X, axis2.Y, axis2.Z); | ||
615 | d.JointSetAMotorParam(m_aMotor, (int)dParam.FMax, 30*objMass.mass); | ||
616 | d.JointSetAMotorParam(m_aMotor, (int)dParam.FMax2, 30*objMass.mass); | ||
617 | d.JointSetAMotorParam(m_aMotor, (int)dParam.FMax3, 30 * objMass.mass); | ||
618 | d.JointSetAMotorParam(m_aMotor, (int)dParam.Vel, m_lastAngularVelocityVector.X); | ||
619 | d.JointSetAMotorParam(m_aMotor, (int)dParam.Vel2, m_lastAngularVelocityVector.Y); | ||
620 | d.JointSetAMotorParam(m_aMotor, (int)dParam.Vel3, m_lastAngularVelocityVector.Z); | ||
621 | |||
622 | } | ||
623 | } | ||
624 | |||
625 | } | 629 | } |
626 | } | 630 | } |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs new file mode 100644 index 0000000..467eba0 --- /dev/null +++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs | |||
@@ -0,0 +1,658 @@ | |||
1 | /* | ||
2 | * Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces | ||
3 | * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: | ||
4 | * ODEPrim.cs contains methods dealing with Prim editing, Prim | ||
5 | * characteristics and Kinetic motion. | ||
6 | * ODEDynamics.cs contains methods dealing with Prim Physical motion | ||
7 | * (dynamics) and the associated settings. Old Linear and angular | ||
8 | * motors for dynamic motion have been replace with MoveLinear() | ||
9 | * and MoveAngular(); 'Physical' is used only to switch ODE dynamic | ||
10 | * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to | ||
11 | * switch between 'VEHICLE' parameter use and general dynamics | ||
12 | * settings use. | ||
13 | * | ||
14 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
15 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
16 | * | ||
17 | * Redistribution and use in source and binary forms, with or without | ||
18 | * modification, are permitted provided that the following conditions are met: | ||
19 | * * Redistributions of source code must retain the above copyright | ||
20 | * notice, this list of conditions and the following disclaimer. | ||
21 | * * Redistributions in binary form must reproduce the above copyright | ||
22 | * notice, this list of conditions and the following disclaimer in the | ||
23 | * documentation and/or other materials provided with the distribution. | ||
24 | * * Neither the name of the OpenSimulator Project nor the | ||
25 | * names of its contributors may be used to endorse or promote products | ||
26 | * derived from this software without specific prior written permission. | ||
27 | * | ||
28 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
29 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
30 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
31 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
32 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
33 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
34 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
35 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | ||
39 | |||
40 | using System; | ||
41 | using System.Collections.Generic; | ||
42 | using System.Reflection; | ||
43 | using System.Runtime.InteropServices; | ||
44 | using log4net; | ||
45 | using OpenMetaverse; | ||
46 | using Ode.NET; | ||
47 | using OpenSim.Framework; | ||
48 | using OpenSim.Region.Physics.Manager; | ||
49 | |||
50 | namespace OpenSim.Region.Physics.OdePlugin | ||
51 | { | ||
52 | public class ODEDynamics | ||
53 | { | ||
54 | public Vehicle Type | ||
55 | { | ||
56 | get { return m_type; } | ||
57 | } | ||
58 | |||
59 | public IntPtr Body | ||
60 | { | ||
61 | get { return m_body; } | ||
62 | } | ||
63 | |||
64 | private int frcount = 0; // Used to limit dynamics debug output to | ||
65 | // every 100th frame | ||
66 | |||
67 | // private OdeScene m_parentScene = null; | ||
68 | private IntPtr m_body = IntPtr.Zero; | ||
69 | private IntPtr m_jointGroup = IntPtr.Zero; | ||
70 | private IntPtr m_aMotor = IntPtr.Zero; | ||
71 | |||
72 | |||
73 | // Vehicle properties | ||
74 | private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind | ||
75 | // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier | ||
76 | private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: | ||
77 | // HOVER_TERRAIN_ONLY | ||
78 | // HOVER_GLOBAL_HEIGHT | ||
79 | // NO_DEFLECTION_UP | ||
80 | // HOVER_WATER_ONLY | ||
81 | // HOVER_UP_ONLY | ||
82 | // LIMIT_MOTOR_UP | ||
83 | // LIMIT_ROLL_ONLY | ||
84 | |||
85 | // Linear properties | ||
86 | private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time | ||
87 | private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL | ||
88 | private Vector3 m_dir = Vector3.Zero; // velocity applied to body | ||
89 | private Vector3 m_linearFrictionTimescale = Vector3.Zero; | ||
90 | private float m_linearMotorDecayTimescale = 0; | ||
91 | private float m_linearMotorTimescale = 0; | ||
92 | private Vector3 m_lastLinearVelocityVector = Vector3.Zero; | ||
93 | // private bool m_LinearMotorSetLastFrame = false; | ||
94 | // private Vector3 m_linearMotorOffset = Vector3.Zero; | ||
95 | |||
96 | //Angular properties | ||
97 | private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor | ||
98 | private int m_angularMotorApply = 0; // application frame counter | ||
99 | private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity | ||
100 | private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate | ||
101 | private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate | ||
102 | private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate | ||
103 | private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body | ||
104 | // private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body | ||
105 | |||
106 | //Deflection properties | ||
107 | // private float m_angularDeflectionEfficiency = 0; | ||
108 | // private float m_angularDeflectionTimescale = 0; | ||
109 | // private float m_linearDeflectionEfficiency = 0; | ||
110 | // private float m_linearDeflectionTimescale = 0; | ||
111 | |||
112 | //Banking properties | ||
113 | // private float m_bankingEfficiency = 0; | ||
114 | // private float m_bankingMix = 0; | ||
115 | // private float m_bankingTimescale = 0; | ||
116 | |||
117 | //Hover and Buoyancy properties | ||
118 | private float m_VhoverHeight = 0f; | ||
119 | private float m_VhoverEfficiency = 0f; | ||
120 | private float m_VhoverTimescale = 0f; | ||
121 | private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height | ||
122 | private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. | ||
123 | // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) | ||
124 | // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. | ||
125 | // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. | ||
126 | |||
127 | //Attractor properties | ||
128 | private float m_verticalAttractionEfficiency = 1.0f; // damped | ||
129 | private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. | ||
130 | |||
131 | |||
132 | |||
133 | |||
134 | |||
135 | internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) | ||
136 | { | ||
137 | switch (pParam) | ||
138 | { | ||
139 | case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: | ||
140 | if (pValue < 0.01f) pValue = 0.01f; | ||
141 | // m_angularDeflectionEfficiency = pValue; | ||
142 | break; | ||
143 | case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: | ||
144 | if (pValue < 0.01f) pValue = 0.01f; | ||
145 | // m_angularDeflectionTimescale = pValue; | ||
146 | break; | ||
147 | case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: | ||
148 | if (pValue < 0.01f) pValue = 0.01f; | ||
149 | m_angularMotorDecayTimescale = pValue; | ||
150 | break; | ||
151 | case Vehicle.ANGULAR_MOTOR_TIMESCALE: | ||
152 | if (pValue < 0.01f) pValue = 0.01f; | ||
153 | m_angularMotorTimescale = pValue; | ||
154 | break; | ||
155 | case Vehicle.BANKING_EFFICIENCY: | ||
156 | if (pValue < 0.01f) pValue = 0.01f; | ||
157 | // m_bankingEfficiency = pValue; | ||
158 | break; | ||
159 | case Vehicle.BANKING_MIX: | ||
160 | if (pValue < 0.01f) pValue = 0.01f; | ||
161 | // m_bankingMix = pValue; | ||
162 | break; | ||
163 | case Vehicle.BANKING_TIMESCALE: | ||
164 | if (pValue < 0.01f) pValue = 0.01f; | ||
165 | // m_bankingTimescale = pValue; | ||
166 | break; | ||
167 | case Vehicle.BUOYANCY: | ||
168 | if (pValue < -1f) pValue = -1f; | ||
169 | if (pValue > 1f) pValue = 1f; | ||
170 | m_VehicleBuoyancy = pValue; | ||
171 | break; | ||
172 | case Vehicle.HOVER_EFFICIENCY: | ||
173 | if (pValue < 0f) pValue = 0f; | ||
174 | if (pValue > 1f) pValue = 1f; | ||
175 | m_VhoverEfficiency = pValue; | ||
176 | break; | ||
177 | case Vehicle.HOVER_HEIGHT: | ||
178 | m_VhoverHeight = pValue; | ||
179 | break; | ||
180 | case Vehicle.HOVER_TIMESCALE: | ||
181 | if (pValue < 0.01f) pValue = 0.01f; | ||
182 | m_VhoverTimescale = pValue; | ||
183 | break; | ||
184 | case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: | ||
185 | if (pValue < 0.01f) pValue = 0.01f; | ||
186 | // m_linearDeflectionEfficiency = pValue; | ||
187 | break; | ||
188 | case Vehicle.LINEAR_DEFLECTION_TIMESCALE: | ||
189 | if (pValue < 0.01f) pValue = 0.01f; | ||
190 | // m_linearDeflectionTimescale = pValue; | ||
191 | break; | ||
192 | case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: | ||
193 | if (pValue < 0.01f) pValue = 0.01f; | ||
194 | m_linearMotorDecayTimescale = pValue; | ||
195 | break; | ||
196 | case Vehicle.LINEAR_MOTOR_TIMESCALE: | ||
197 | if (pValue < 0.01f) pValue = 0.01f; | ||
198 | m_linearMotorTimescale = pValue; | ||
199 | break; | ||
200 | case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: | ||
201 | if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable | ||
202 | if (pValue > 1.0f) pValue = 1.0f; | ||
203 | m_verticalAttractionEfficiency = pValue; | ||
204 | break; | ||
205 | case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: | ||
206 | if (pValue < 0.01f) pValue = 0.01f; | ||
207 | m_verticalAttractionTimescale = pValue; | ||
208 | break; | ||
209 | |||
210 | // These are vector properties but the engine lets you use a single float value to | ||
211 | // set all of the components to the same value | ||
212 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: | ||
213 | m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); | ||
214 | break; | ||
215 | case Vehicle.ANGULAR_MOTOR_DIRECTION: | ||
216 | m_angularMotorDirection = new Vector3(pValue, pValue, pValue); | ||
217 | m_angularMotorApply = 10; | ||
218 | break; | ||
219 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | ||
220 | m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); | ||
221 | break; | ||
222 | case Vehicle.LINEAR_MOTOR_DIRECTION: | ||
223 | m_linearMotorDirection = new Vector3(pValue, pValue, pValue); | ||
224 | m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); | ||
225 | break; | ||
226 | case Vehicle.LINEAR_MOTOR_OFFSET: | ||
227 | // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); | ||
228 | break; | ||
229 | |||
230 | } | ||
231 | |||
232 | }//end ProcessFloatVehicleParam | ||
233 | |||
234 | internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue) | ||
235 | { | ||
236 | switch (pParam) | ||
237 | { | ||
238 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: | ||
239 | m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); | ||
240 | break; | ||
241 | case Vehicle.ANGULAR_MOTOR_DIRECTION: | ||
242 | m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); | ||
243 | // Limit requested angular speed to 2 rps= 4 pi rads/sec | ||
244 | if(m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f; | ||
245 | if(m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f; | ||
246 | if(m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f; | ||
247 | if(m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f; | ||
248 | if(m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f; | ||
249 | if(m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f; | ||
250 | m_angularMotorApply = 10; | ||
251 | break; | ||
252 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | ||
253 | m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); | ||
254 | break; | ||
255 | case Vehicle.LINEAR_MOTOR_DIRECTION: | ||
256 | m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); | ||
257 | m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); | ||
258 | break; | ||
259 | case Vehicle.LINEAR_MOTOR_OFFSET: | ||
260 | // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | }//end ProcessVectorVehicleParam | ||
265 | |||
266 | internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) | ||
267 | { | ||
268 | switch (pParam) | ||
269 | { | ||
270 | case Vehicle.REFERENCE_FRAME: | ||
271 | // m_referenceFrame = pValue; | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | }//end ProcessRotationVehicleParam | ||
276 | |||
277 | internal void ProcessTypeChange(Vehicle pType) | ||
278 | { | ||
279 | // Set Defaults For Type | ||
280 | m_type = pType; | ||
281 | switch (pType) | ||
282 | { | ||
283 | case Vehicle.TYPE_SLED: | ||
284 | m_linearFrictionTimescale = new Vector3(30, 1, 1000); | ||
285 | m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); | ||
286 | m_linearMotorDirection = Vector3.Zero; | ||
287 | m_linearMotorTimescale = 1000; | ||
288 | m_linearMotorDecayTimescale = 120; | ||
289 | m_angularMotorDirection = Vector3.Zero; | ||
290 | m_angularMotorTimescale = 1000; | ||
291 | m_angularMotorDecayTimescale = 120; | ||
292 | m_VhoverHeight = 0; | ||
293 | m_VhoverEfficiency = 1; | ||
294 | m_VhoverTimescale = 10; | ||
295 | m_VehicleBuoyancy = 0; | ||
296 | // m_linearDeflectionEfficiency = 1; | ||
297 | // m_linearDeflectionTimescale = 1; | ||
298 | // m_angularDeflectionEfficiency = 1; | ||
299 | // m_angularDeflectionTimescale = 1000; | ||
300 | // m_bankingEfficiency = 0; | ||
301 | // m_bankingMix = 1; | ||
302 | // m_bankingTimescale = 10; | ||
303 | // m_referenceFrame = Quaternion.Identity; | ||
304 | m_flags &= | ||
305 | ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | ||
306 | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); | ||
307 | m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); | ||
308 | break; | ||
309 | case Vehicle.TYPE_CAR: | ||
310 | m_linearFrictionTimescale = new Vector3(100, 2, 1000); | ||
311 | m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); | ||
312 | m_linearMotorDirection = Vector3.Zero; | ||
313 | m_linearMotorTimescale = 1; | ||
314 | m_linearMotorDecayTimescale = 60; | ||
315 | m_angularMotorDirection = Vector3.Zero; | ||
316 | m_angularMotorTimescale = 1; | ||
317 | m_angularMotorDecayTimescale = 0.8f; | ||
318 | m_VhoverHeight = 0; | ||
319 | m_VhoverEfficiency = 0; | ||
320 | m_VhoverTimescale = 1000; | ||
321 | m_VehicleBuoyancy = 0; | ||
322 | // // m_linearDeflectionEfficiency = 1; | ||
323 | // // m_linearDeflectionTimescale = 2; | ||
324 | // // m_angularDeflectionEfficiency = 0; | ||
325 | // m_angularDeflectionTimescale = 10; | ||
326 | m_verticalAttractionEfficiency = 1f; | ||
327 | m_verticalAttractionTimescale = 10f; | ||
328 | // m_bankingEfficiency = -0.2f; | ||
329 | // m_bankingMix = 1; | ||
330 | // m_bankingTimescale = 1; | ||
331 | // m_referenceFrame = Quaternion.Identity; | ||
332 | m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); | ||
333 | m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY | | ||
334 | VehicleFlag.LIMIT_MOTOR_UP); | ||
335 | break; | ||
336 | case Vehicle.TYPE_BOAT: | ||
337 | m_linearFrictionTimescale = new Vector3(10, 3, 2); | ||
338 | m_angularFrictionTimescale = new Vector3(10,10,10); | ||
339 | m_linearMotorDirection = Vector3.Zero; | ||
340 | m_linearMotorTimescale = 5; | ||
341 | m_linearMotorDecayTimescale = 60; | ||
342 | m_angularMotorDirection = Vector3.Zero; | ||
343 | m_angularMotorTimescale = 4; | ||
344 | m_angularMotorDecayTimescale = 4; | ||
345 | m_VhoverHeight = 0; | ||
346 | m_VhoverEfficiency = 0.5f; | ||
347 | m_VhoverTimescale = 2; | ||
348 | m_VehicleBuoyancy = 1; | ||
349 | // m_linearDeflectionEfficiency = 0.5f; | ||
350 | // m_linearDeflectionTimescale = 3; | ||
351 | // m_angularDeflectionEfficiency = 0.5f; | ||
352 | // m_angularDeflectionTimescale = 5; | ||
353 | m_verticalAttractionEfficiency = 0.5f; | ||
354 | m_verticalAttractionTimescale = 5f; | ||
355 | // m_bankingEfficiency = -0.3f; | ||
356 | // m_bankingMix = 0.8f; | ||
357 | // m_bankingTimescale = 1; | ||
358 | // m_referenceFrame = Quaternion.Identity; | ||
359 | m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | | ||
360 | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); | ||
361 | m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | | ||
362 | VehicleFlag.LIMIT_MOTOR_UP); | ||
363 | break; | ||
364 | case Vehicle.TYPE_AIRPLANE: | ||
365 | m_linearFrictionTimescale = new Vector3(200, 10, 5); | ||
366 | m_angularFrictionTimescale = new Vector3(20, 20, 20); | ||
367 | m_linearMotorDirection = Vector3.Zero; | ||
368 | m_linearMotorTimescale = 2; | ||
369 | m_linearMotorDecayTimescale = 60; | ||
370 | m_angularMotorDirection = Vector3.Zero; | ||
371 | m_angularMotorTimescale = 4; | ||
372 | m_angularMotorDecayTimescale = 4; | ||
373 | m_VhoverHeight = 0; | ||
374 | m_VhoverEfficiency = 0.5f; | ||
375 | m_VhoverTimescale = 1000; | ||
376 | m_VehicleBuoyancy = 0; | ||
377 | // m_linearDeflectionEfficiency = 0.5f; | ||
378 | // m_linearDeflectionTimescale = 3; | ||
379 | // m_angularDeflectionEfficiency = 1; | ||
380 | // m_angularDeflectionTimescale = 2; | ||
381 | m_verticalAttractionEfficiency = 0.9f; | ||
382 | m_verticalAttractionTimescale = 2f; | ||
383 | // m_bankingEfficiency = 1; | ||
384 | // m_bankingMix = 0.7f; | ||
385 | // m_bankingTimescale = 2; | ||
386 | // m_referenceFrame = Quaternion.Identity; | ||
387 | m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | ||
388 | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); | ||
389 | m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); | ||
390 | break; | ||
391 | case Vehicle.TYPE_BALLOON: | ||
392 | m_linearFrictionTimescale = new Vector3(5, 5, 5); | ||
393 | m_angularFrictionTimescale = new Vector3(10, 10, 10); | ||
394 | m_linearMotorDirection = Vector3.Zero; | ||
395 | m_linearMotorTimescale = 5; | ||
396 | m_linearMotorDecayTimescale = 60; | ||
397 | m_angularMotorDirection = Vector3.Zero; | ||
398 | m_angularMotorTimescale = 6; | ||
399 | m_angularMotorDecayTimescale = 10; | ||
400 | m_VhoverHeight = 5; | ||
401 | m_VhoverEfficiency = 0.8f; | ||
402 | m_VhoverTimescale = 10; | ||
403 | m_VehicleBuoyancy = 1; | ||
404 | // m_linearDeflectionEfficiency = 0; | ||
405 | // m_linearDeflectionTimescale = 5; | ||
406 | // m_angularDeflectionEfficiency = 0; | ||
407 | // m_angularDeflectionTimescale = 5; | ||
408 | m_verticalAttractionEfficiency = 1f; | ||
409 | m_verticalAttractionTimescale = 100f; | ||
410 | // m_bankingEfficiency = 0; | ||
411 | // m_bankingMix = 0.7f; | ||
412 | // m_bankingTimescale = 5; | ||
413 | // m_referenceFrame = Quaternion.Identity; | ||
414 | m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | ||
415 | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); | ||
416 | m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); | ||
417 | break; | ||
418 | |||
419 | } | ||
420 | }//end SetDefaultsForType | ||
421 | |||
422 | internal void Enable(IntPtr pBody, OdeScene pParentScene) | ||
423 | { | ||
424 | if (m_type == Vehicle.TYPE_NONE) | ||
425 | return; | ||
426 | |||
427 | m_body = pBody; | ||
428 | } | ||
429 | |||
430 | internal void Step(float pTimestep, OdeScene pParentScene) | ||
431 | { | ||
432 | if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) | ||
433 | return; | ||
434 | frcount++; // used to limit debug comment output | ||
435 | if (frcount > 100) | ||
436 | frcount = 0; | ||
437 | |||
438 | MoveLinear(pTimestep, pParentScene); | ||
439 | MoveAngular(pTimestep); | ||
440 | }// end Step | ||
441 | |||
442 | private void MoveLinear(float pTimestep, OdeScene _pParentScene) | ||
443 | { | ||
444 | if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant | ||
445 | { | ||
446 | if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); | ||
447 | |||
448 | // add drive to body | ||
449 | Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); | ||
450 | m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? | ||
451 | |||
452 | // This will work temporarily, but we really need to compare speed on an axis | ||
453 | // KF: Limit body velocity to applied velocity? | ||
454 | if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) | ||
455 | m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; | ||
456 | if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) | ||
457 | m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; | ||
458 | if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) | ||
459 | m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; | ||
460 | |||
461 | // decay applied velocity | ||
462 | Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); | ||
463 | //Console.WriteLine("decay: " + decayfraction); | ||
464 | m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; | ||
465 | //Console.WriteLine("actual: " + m_linearMotorDirection); | ||
466 | } | ||
467 | else | ||
468 | { // requested is not significant | ||
469 | // if what remains of applied is small, zero it. | ||
470 | if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) | ||
471 | m_lastLinearVelocityVector = Vector3.Zero; | ||
472 | } | ||
473 | |||
474 | |||
475 | // convert requested object velocity to world-referenced vector | ||
476 | m_dir = m_lastLinearVelocityVector; | ||
477 | d.Quaternion rot = d.BodyGetQuaternion(Body); | ||
478 | Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object | ||
479 | m_dir *= rotq; // apply obj rotation to velocity vector | ||
480 | |||
481 | // add Gravity andBuoyancy | ||
482 | // KF: So far I have found no good method to combine a script-requested | ||
483 | // .Z velocity and gravity. Therefore only 0g will used script-requested | ||
484 | // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. | ||
485 | Vector3 grav = Vector3.Zero; | ||
486 | if(m_VehicleBuoyancy < 1.0f) | ||
487 | { | ||
488 | // There is some gravity, make a gravity force vector | ||
489 | // that is applied after object velocity. | ||
490 | d.Mass objMass; | ||
491 | d.BodyGetMass(Body, out objMass); | ||
492 | // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; | ||
493 | grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); | ||
494 | // Preserve the current Z velocity | ||
495 | d.Vector3 vel_now = d.BodyGetLinearVel(Body); | ||
496 | m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity | ||
497 | } // else its 1.0, no gravity. | ||
498 | |||
499 | // Check if hovering | ||
500 | if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) | ||
501 | { | ||
502 | // We should hover, get the target height | ||
503 | d.Vector3 pos = d.BodyGetPosition(Body); | ||
504 | if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY) | ||
505 | { | ||
506 | m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; | ||
507 | } | ||
508 | else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY) | ||
509 | { | ||
510 | m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; | ||
511 | } | ||
512 | else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT) | ||
513 | { | ||
514 | m_VhoverTargetHeight = m_VhoverHeight; | ||
515 | } | ||
516 | |||
517 | if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY) | ||
518 | { | ||
519 | // If body is aready heigher, use its height as target height | ||
520 | if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; | ||
521 | } | ||
522 | |||
523 | // m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped | ||
524 | // m_VhoverTimescale = 0f; // time to acheive height | ||
525 | // pTimestep is time since last frame,in secs | ||
526 | float herr0 = pos.Z - m_VhoverTargetHeight; | ||
527 | // Replace Vertical speed with correction figure if significant | ||
528 | if(Math.Abs(herr0) > 0.01f ) | ||
529 | { | ||
530 | d.Mass objMass; | ||
531 | d.BodyGetMass(Body, out objMass); | ||
532 | m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale); | ||
533 | //KF: m_VhoverEfficiency is not yet implemented | ||
534 | } | ||
535 | else | ||
536 | { | ||
537 | m_dir.Z = 0f; | ||
538 | } | ||
539 | } | ||
540 | |||
541 | // Apply velocity | ||
542 | d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z); | ||
543 | // apply gravity force | ||
544 | d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); | ||
545 | |||
546 | |||
547 | // apply friction | ||
548 | Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); | ||
549 | m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; | ||
550 | } // end MoveLinear() | ||
551 | |||
552 | private void MoveAngular(float pTimestep) | ||
553 | { | ||
554 | /* | ||
555 | private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor | ||
556 | private int m_angularMotorApply = 0; // application frame counter | ||
557 | private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down) | ||
558 | private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate | ||
559 | private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate | ||
560 | private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate | ||
561 | private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body | ||
562 | */ | ||
563 | |||
564 | // Get what the body is doing, this includes 'external' influences | ||
565 | d.Vector3 angularVelocity = d.BodyGetAngularVel(Body); | ||
566 | // Vector3 angularVelocity = Vector3.Zero; | ||
567 | |||
568 | if (m_angularMotorApply > 0) | ||
569 | { | ||
570 | // ramp up to new value | ||
571 | // current velocity += error / ( time to get there / step interval ) | ||
572 | // requested speed - last motor speed | ||
573 | m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); | ||
574 | m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); | ||
575 | m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); | ||
576 | |||
577 | m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected | ||
578 | // velocity may still be acheived. | ||
579 | } | ||
580 | else | ||
581 | { | ||
582 | // no motor recently applied, keep the body velocity | ||
583 | /* m_angularMotorVelocity.X = angularVelocity.X; | ||
584 | m_angularMotorVelocity.Y = angularVelocity.Y; | ||
585 | m_angularMotorVelocity.Z = angularVelocity.Z; */ | ||
586 | |||
587 | // and decay the velocity | ||
588 | m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); | ||
589 | } // end motor section | ||
590 | |||
591 | |||
592 | // Vertical attractor section | ||
593 | Vector3 vertattr = Vector3.Zero; | ||
594 | |||
595 | if(m_verticalAttractionTimescale < 300) | ||
596 | { | ||
597 | float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); | ||
598 | // get present body rotation | ||
599 | d.Quaternion rot = d.BodyGetQuaternion(Body); | ||
600 | Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); | ||
601 | // make a vector pointing up | ||
602 | Vector3 verterr = Vector3.Zero; | ||
603 | verterr.Z = 1.0f; | ||
604 | // rotate it to Body Angle | ||
605 | verterr = verterr * rotq; | ||
606 | // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. | ||
607 | // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go | ||
608 | // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. | ||
609 | if (verterr.Z < 0.0f) | ||
610 | { | ||
611 | verterr.X = 2.0f - verterr.X; | ||
612 | verterr.Y = 2.0f - verterr.Y; | ||
613 | } | ||
614 | // Error is 0 (no error) to +/- 2 (max error) | ||
615 | // scale it by VAservo | ||
616 | verterr = verterr * VAservo; | ||
617 | //if(frcount == 0) Console.WriteLine("VAerr=" + verterr); | ||
618 | |||
619 | // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so | ||
620 | // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. | ||
621 | vertattr.X = verterr.Y; | ||
622 | vertattr.Y = - verterr.X; | ||
623 | vertattr.Z = 0f; | ||
624 | |||
625 | // scaling appears better usingsquare-law | ||
626 | float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); | ||
627 | vertattr.X += bounce * angularVelocity.X; | ||
628 | vertattr.Y += bounce * angularVelocity.Y; | ||
629 | |||
630 | } // else vertical attractor is off | ||
631 | |||
632 | // m_lastVertAttractor = vertattr; | ||
633 | |||
634 | // Bank section tba | ||
635 | // Deflection section tba | ||
636 | |||
637 | // Sum velocities | ||
638 | m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection | ||
639 | |||
640 | if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) | ||
641 | { | ||
642 | if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); | ||
643 | } | ||
644 | else | ||
645 | { | ||
646 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. | ||
647 | } | ||
648 | |||
649 | // apply friction | ||
650 | Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); | ||
651 | m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; | ||
652 | |||
653 | // Apply to the body | ||
654 | d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); | ||
655 | |||
656 | } //end MoveAngular | ||
657 | } | ||
658 | } | ||
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 032b5df..86ed3bd 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | |||
@@ -1,4 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces | ||
3 | * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: | ||
4 | * ODEPrim.cs contains methods dealing with Prim editing, Prim | ||
5 | * characteristics and Kinetic motion. | ||
6 | * ODEDynamics.cs contains methods dealing with Prim Physical motion | ||
7 | * (dynamics) and the associated settings. Old Linear and angular | ||
8 | * motors for dynamic motion have been replace with MoveLinear() | ||
9 | * and MoveAngular(); 'Physical' is used only to switch ODE dynamic | ||
10 | * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to | ||
11 | * switch between 'VEHICLE' parameter use and general dynamics | ||
12 | * settings use. | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 13 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 14 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 15 | * |
@@ -72,6 +83,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
72 | private float PID_G = 25f; | 83 | private float PID_G = 25f; |
73 | private bool m_usePID = false; | 84 | private bool m_usePID = false; |
74 | 85 | ||
86 | // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), | ||
87 | // and are for non-VEHICLES only. | ||
88 | |||
75 | private float m_PIDHoverHeight = 0f; | 89 | private float m_PIDHoverHeight = 0f; |
76 | private float m_PIDHoverTau = 0f; | 90 | private float m_PIDHoverTau = 0f; |
77 | private bool m_useHoverPID = false; | 91 | private bool m_useHoverPID = false; |
@@ -79,6 +93,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
79 | private float m_targetHoverHeight = 0f; | 93 | private float m_targetHoverHeight = 0f; |
80 | private float m_groundHeight = 0f; | 94 | private float m_groundHeight = 0f; |
81 | private float m_waterHeight = 0f; | 95 | private float m_waterHeight = 0f; |
96 | private float m_buoyancy = 0f; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. | ||
82 | 97 | ||
83 | // private float m_tensor = 5f; | 98 | // private float m_tensor = 5f; |
84 | private int body_autodisable_frames = 20; | 99 | private int body_autodisable_frames = 20; |
@@ -146,8 +161,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
146 | public int m_roundsUnderMotionThreshold = 0; | 161 | public int m_roundsUnderMotionThreshold = 0; |
147 | private int m_crossingfailures = 0; | 162 | private int m_crossingfailures = 0; |
148 | 163 | ||
149 | public float m_buoyancy = 0f; | ||
150 | |||
151 | public bool outofBounds = false; | 164 | public bool outofBounds = false; |
152 | private float m_density = 10.000006836f; // Aluminum g/cm3; | 165 | private float m_density = 10.000006836f; // Aluminum g/cm3; |
153 | 166 | ||
@@ -155,7 +168,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
155 | private bool m_lastUpdateSent = false; | 168 | private bool m_lastUpdateSent = false; |
156 | 169 | ||
157 | public IntPtr Body = (IntPtr) 0; | 170 | public IntPtr Body = (IntPtr) 0; |
158 | private String m_primName; | 171 | public String m_primName; |
172 | // private String m_primName; | ||
159 | private PhysicsVector _target_velocity; | 173 | private PhysicsVector _target_velocity; |
160 | public d.Mass pMass; | 174 | public d.Mass pMass; |
161 | 175 | ||
@@ -166,7 +180,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
166 | 180 | ||
167 | public volatile bool childPrim = false; | 181 | public volatile bool childPrim = false; |
168 | 182 | ||
169 | private ODEVehicleSettings m_vehicle; | 183 | private ODEDynamics m_vehicle; |
170 | 184 | ||
171 | internal int m_material = (int)Material.Wood; | 185 | internal int m_material = (int)Material.Wood; |
172 | 186 | ||
@@ -174,7 +188,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
174 | Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) | 188 | Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) |
175 | { | 189 | { |
176 | _target_velocity = new PhysicsVector(0, 0, 0); | 190 | _target_velocity = new PhysicsVector(0, 0, 0); |
177 | m_vehicle = new ODEVehicleSettings(); | 191 | m_vehicle = new ODEDynamics(); |
178 | //gc = GCHandle.Alloc(prim_geom, GCHandleType.Pinned); | 192 | //gc = GCHandle.Alloc(prim_geom, GCHandleType.Pinned); |
179 | ode = dode; | 193 | ode = dode; |
180 | _velocity = new PhysicsVector(); | 194 | _velocity = new PhysicsVector(); |
@@ -259,11 +273,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
259 | m_localID = value; } | 273 | m_localID = value; } |
260 | } | 274 | } |
261 | 275 | ||
262 | public override int GetHashCode() | ||
263 | { | ||
264 | return (int)m_localID; | ||
265 | } | ||
266 | |||
267 | public override bool Grabbed | 276 | public override bool Grabbed |
268 | { | 277 | { |
269 | set { return; } | 278 | set { return; } |
@@ -272,6 +281,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
272 | public override bool Selected | 281 | public override bool Selected |
273 | { | 282 | { |
274 | set { | 283 | set { |
284 | |||
285 | |||
275 | // This only makes the object not collidable if the object | 286 | // This only makes the object not collidable if the object |
276 | // is physical or the object is modified somehow *IN THE FUTURE* | 287 | // is physical or the object is modified somehow *IN THE FUTURE* |
277 | // without this, if an avatar selects prim, they can walk right | 288 | // without this, if an avatar selects prim, they can walk right |
@@ -287,6 +298,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
287 | m_taintselected = value; | 298 | m_taintselected = value; |
288 | m_isSelected = value; | 299 | m_isSelected = value; |
289 | } | 300 | } |
301 | if(m_isSelected) disableBodySoft(); | ||
290 | } | 302 | } |
291 | } | 303 | } |
292 | 304 | ||
@@ -294,6 +306,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
294 | { | 306 | { |
295 | prev_geom = prim_geom; | 307 | prev_geom = prim_geom; |
296 | prim_geom = geom; | 308 | prim_geom = geom; |
309 | //Console.WriteLine("SetGeom to " + prim_geom + " for " + m_primName); | ||
297 | if (prim_geom != IntPtr.Zero) | 310 | if (prim_geom != IntPtr.Zero) |
298 | { | 311 | { |
299 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 312 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
@@ -305,6 +318,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
305 | if (_parent != null && _parent is OdePrim) | 318 | if (_parent != null && _parent is OdePrim) |
306 | { | 319 | { |
307 | OdePrim parent = (OdePrim)_parent; | 320 | OdePrim parent = (OdePrim)_parent; |
321 | //Console.WriteLine("SetGeom calls ChildSetGeom"); | ||
308 | parent.ChildSetGeom(this); | 322 | parent.ChildSetGeom(this); |
309 | } | 323 | } |
310 | } | 324 | } |
@@ -320,7 +334,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
320 | if (m_isphysical && Body != IntPtr.Zero) | 334 | if (m_isphysical && Body != IntPtr.Zero) |
321 | { | 335 | { |
322 | d.BodyEnable(Body); | 336 | d.BodyEnable(Body); |
323 | m_vehicle.Enable(Body, _parent_scene); | 337 | if (m_vehicle.Type != Vehicle.TYPE_NONE) |
338 | m_vehicle.Enable(Body, _parent_scene); | ||
324 | } | 339 | } |
325 | 340 | ||
326 | m_disabled = false; | 341 | m_disabled = false; |
@@ -334,7 +349,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
334 | if (m_isphysical && Body != IntPtr.Zero) | 349 | if (m_isphysical && Body != IntPtr.Zero) |
335 | { | 350 | { |
336 | d.BodyDisable(Body); | 351 | d.BodyDisable(Body); |
337 | m_vehicle.Disable(); | ||
338 | } | 352 | } |
339 | } | 353 | } |
340 | 354 | ||
@@ -364,6 +378,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
364 | 378 | ||
365 | d.BodySetAutoDisableFlag(Body, true); | 379 | d.BodySetAutoDisableFlag(Body, true); |
366 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | 380 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); |
381 | |||
382 | // disconnect from world gravity so we can apply buoyancy | ||
383 | d.BodySetGravityMode (Body, false); | ||
367 | 384 | ||
368 | m_interpenetrationcount = 0; | 385 | m_interpenetrationcount = 0; |
369 | m_collisionscore = 0; | 386 | m_collisionscore = 0; |
@@ -710,13 +727,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
710 | break; | 727 | break; |
711 | } | 728 | } |
712 | } | 729 | } |
713 | |||
714 | |||
715 | |||
716 | |||
717 | |||
718 | return returnMass; | 730 | return returnMass; |
719 | } | 731 | }// end CalculateMass |
720 | 732 | ||
721 | #endregion | 733 | #endregion |
722 | 734 | ||
@@ -742,7 +754,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
742 | if (Body != IntPtr.Zero) | 754 | if (Body != IntPtr.Zero) |
743 | { | 755 | { |
744 | _parent_scene.remActivePrim(this); | 756 | _parent_scene.remActivePrim(this); |
745 | m_vehicle.Destroy(); | ||
746 | m_collisionCategories &= ~CollisionCategories.Body; | 757 | m_collisionCategories &= ~CollisionCategories.Body; |
747 | m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); | 758 | m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); |
748 | 759 | ||
@@ -833,6 +844,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
833 | { | 844 | { |
834 | if (prim_geom == IntPtr.Zero) | 845 | if (prim_geom == IntPtr.Zero) |
835 | { | 846 | { |
847 | //Console.WriteLine(" setMesh 1"); | ||
836 | SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); | 848 | SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); |
837 | } | 849 | } |
838 | } | 850 | } |
@@ -854,19 +866,35 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
854 | 866 | ||
855 | public void ProcessTaints(float timestep) | 867 | public void ProcessTaints(float timestep) |
856 | { | 868 | { |
869 | //Console.WriteLine("ProcessTaints for " + m_primName ); | ||
857 | if (m_taintadd) | 870 | if (m_taintadd) |
858 | { | 871 | { |
859 | changeadd(timestep); | 872 | changeadd(timestep); |
860 | } | 873 | } |
874 | |||
861 | if (prim_geom != IntPtr.Zero) | 875 | if (prim_geom != IntPtr.Zero) |
862 | { | 876 | { |
863 | if (!_position.IsIdentical(m_taintposition,0f)) | 877 | if (!_position.IsIdentical(m_taintposition,0f)) |
864 | changemove(timestep); | 878 | changemove(timestep); |
865 | 879 | ||
866 | if (m_taintrot != _orientation) | 880 | if (m_taintrot != _orientation) |
867 | rotate(timestep); | 881 | { |
882 | if(childPrim && IsPhysical) // For physical child prim... | ||
883 | { | ||
884 | rotate(timestep); | ||
885 | // KF: ODE will also rotate the parent prim! | ||
886 | // so rotate the root back to where it was | ||
887 | OdePrim parent = (OdePrim)_parent; | ||
888 | parent.rotate(timestep); | ||
889 | } | ||
890 | else | ||
891 | { | ||
892 | //Just rotate the prim | ||
893 | rotate(timestep); | ||
894 | } | ||
895 | } | ||
868 | // | 896 | // |
869 | 897 | ||
870 | if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) | 898 | if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) |
871 | changePhysicsStatus(timestep); | 899 | changePhysicsStatus(timestep); |
872 | // | 900 | // |
@@ -905,8 +933,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
905 | 933 | ||
906 | if (!m_angularlock.IsIdentical(m_taintAngularLock,0)) | 934 | if (!m_angularlock.IsIdentical(m_taintAngularLock,0)) |
907 | changeAngularLock(timestep); | 935 | changeAngularLock(timestep); |
908 | 936 | ||
909 | |||
910 | } | 937 | } |
911 | else | 938 | else |
912 | { | 939 | { |
@@ -938,11 +965,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
938 | Amotor = IntPtr.Zero; | 965 | Amotor = IntPtr.Zero; |
939 | } | 966 | } |
940 | } | 967 | } |
941 | |||
942 | if (m_vehicle.Type != Vehicle.TYPE_NONE) | ||
943 | { | ||
944 | m_vehicle.Reset(); | ||
945 | } | ||
946 | } | 968 | } |
947 | } | 969 | } |
948 | // Store this for later in case we get turned into a separate body | 970 | // Store this for later in case we get turned into a separate body |
@@ -960,7 +982,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
960 | { | 982 | { |
961 | OdePrim obj = (OdePrim)m_taintparent; | 983 | OdePrim obj = (OdePrim)m_taintparent; |
962 | //obj.disableBody(); | 984 | //obj.disableBody(); |
963 | 985 | //Console.WriteLine("changelink calls ParentPrim"); | |
964 | obj.ParentPrim(this); | 986 | obj.ParentPrim(this); |
965 | 987 | ||
966 | /* | 988 | /* |
@@ -978,6 +1000,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
978 | // destroy link | 1000 | // destroy link |
979 | else if (_parent != null && m_taintparent == null) | 1001 | else if (_parent != null && m_taintparent == null) |
980 | { | 1002 | { |
1003 | //Console.WriteLine(" changelink B"); | ||
1004 | |||
981 | if (_parent is OdePrim) | 1005 | if (_parent is OdePrim) |
982 | { | 1006 | { |
983 | OdePrim obj = (OdePrim)_parent; | 1007 | OdePrim obj = (OdePrim)_parent; |
@@ -994,7 +1018,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
994 | m_linkJoint = (IntPtr)0; | 1018 | m_linkJoint = (IntPtr)0; |
995 | */ | 1019 | */ |
996 | } | 1020 | } |
997 | 1021 | ||
998 | _parent = m_taintparent; | 1022 | _parent = m_taintparent; |
999 | m_taintPhysics = m_isphysical; | 1023 | m_taintPhysics = m_isphysical; |
1000 | } | 1024 | } |
@@ -1003,6 +1027,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1003 | // prim is the child | 1027 | // prim is the child |
1004 | public void ParentPrim(OdePrim prim) | 1028 | public void ParentPrim(OdePrim prim) |
1005 | { | 1029 | { |
1030 | //Console.WriteLine("ParentPrim " + m_primName); | ||
1006 | if (this.m_localID != prim.m_localID) | 1031 | if (this.m_localID != prim.m_localID) |
1007 | { | 1032 | { |
1008 | if (Body == IntPtr.Zero) | 1033 | if (Body == IntPtr.Zero) |
@@ -1016,6 +1041,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1016 | { | 1041 | { |
1017 | if (!childrenPrim.Contains(prim)) | 1042 | if (!childrenPrim.Contains(prim)) |
1018 | { | 1043 | { |
1044 | //Console.WriteLine("childrenPrim.Add " + prim); | ||
1019 | childrenPrim.Add(prim); | 1045 | childrenPrim.Add(prim); |
1020 | 1046 | ||
1021 | foreach (OdePrim prm in childrenPrim) | 1047 | foreach (OdePrim prm in childrenPrim) |
@@ -1039,6 +1065,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1039 | } | 1065 | } |
1040 | foreach (OdePrim prm in childrenPrim) | 1066 | foreach (OdePrim prm in childrenPrim) |
1041 | { | 1067 | { |
1068 | |||
1042 | prm.m_collisionCategories |= CollisionCategories.Body; | 1069 | prm.m_collisionCategories |= CollisionCategories.Body; |
1043 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1070 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
1044 | 1071 | ||
@@ -1047,7 +1074,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1047 | m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); | 1074 | m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); |
1048 | continue; | 1075 | continue; |
1049 | } | 1076 | } |
1050 | 1077 | //Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + m_primName); | |
1051 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); | 1078 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); |
1052 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); | 1079 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); |
1053 | 1080 | ||
@@ -1092,11 +1119,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1092 | prm.Body = Body; | 1119 | prm.Body = Body; |
1093 | _parent_scene.addActivePrim(prm); | 1120 | _parent_scene.addActivePrim(prm); |
1094 | } | 1121 | } |
1095 | |||
1096 | m_collisionCategories |= CollisionCategories.Body; | 1122 | m_collisionCategories |= CollisionCategories.Body; |
1097 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1123 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
1098 | 1124 | ||
1125 | //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + m_primName); | ||
1099 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1126 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
1127 | //Console.WriteLine(" Post GeomSetCategoryBits 2"); | ||
1100 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1128 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1101 | 1129 | ||
1102 | 1130 | ||
@@ -1132,7 +1160,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1132 | createAMotor(m_angularlock); | 1160 | createAMotor(m_angularlock); |
1133 | } | 1161 | } |
1134 | d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); | 1162 | d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); |
1135 | m_vehicle.Enable(Body, _parent_scene); | 1163 | if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); |
1136 | _parent_scene.addActivePrim(this); | 1164 | _parent_scene.addActivePrim(this); |
1137 | } | 1165 | } |
1138 | } | 1166 | } |
@@ -1169,6 +1197,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1169 | { | 1197 | { |
1170 | foreach (OdePrim prm in childrenPrim) | 1198 | foreach (OdePrim prm in childrenPrim) |
1171 | { | 1199 | { |
1200 | //Console.WriteLine("ChildSetGeom calls ParentPrim"); | ||
1172 | ParentPrim(prm); | 1201 | ParentPrim(prm); |
1173 | } | 1202 | } |
1174 | } | 1203 | } |
@@ -1195,6 +1224,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1195 | 1224 | ||
1196 | lock (childrenPrim) | 1225 | lock (childrenPrim) |
1197 | { | 1226 | { |
1227 | //Console.WriteLine("childrenPrim.Remove " + odePrim); | ||
1198 | childrenPrim.Remove(odePrim); | 1228 | childrenPrim.Remove(odePrim); |
1199 | } | 1229 | } |
1200 | 1230 | ||
@@ -1212,6 +1242,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1212 | { | 1242 | { |
1213 | foreach (OdePrim prm in childrenPrim) | 1243 | foreach (OdePrim prm in childrenPrim) |
1214 | { | 1244 | { |
1245 | //Console.WriteLine("ChildDelink calls ParentPrim"); | ||
1215 | ParentPrim(prm); | 1246 | ParentPrim(prm); |
1216 | } | 1247 | } |
1217 | } | 1248 | } |
@@ -1296,7 +1327,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1296 | 1327 | ||
1297 | resetCollisionAccounting(); | 1328 | resetCollisionAccounting(); |
1298 | m_isSelected = m_taintselected; | 1329 | m_isSelected = m_taintselected; |
1299 | } | 1330 | }//end changeSelectedStatus |
1300 | 1331 | ||
1301 | public void ResetTaints() | 1332 | public void ResetTaints() |
1302 | { | 1333 | { |
@@ -1313,6 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1313 | 1344 | ||
1314 | public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) | 1345 | public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) |
1315 | { | 1346 | { |
1347 | //Console.WriteLine("CreateGeom:"); | ||
1316 | if (_mesh != null) | 1348 | if (_mesh != null) |
1317 | { | 1349 | { |
1318 | setMesh(_parent_scene, _mesh); | 1350 | setMesh(_parent_scene, _mesh); |
@@ -1328,6 +1360,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1328 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1360 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1329 | try | 1361 | try |
1330 | { | 1362 | { |
1363 | //Console.WriteLine(" CreateGeom 1"); | ||
1331 | SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); | 1364 | SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); |
1332 | } | 1365 | } |
1333 | catch (AccessViolationException) | 1366 | catch (AccessViolationException) |
@@ -1342,6 +1375,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1342 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1375 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1343 | try | 1376 | try |
1344 | { | 1377 | { |
1378 | //Console.WriteLine(" CreateGeom 2"); | ||
1345 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); | 1379 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); |
1346 | } | 1380 | } |
1347 | catch (AccessViolationException) | 1381 | catch (AccessViolationException) |
@@ -1357,6 +1391,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1357 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1391 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1358 | try | 1392 | try |
1359 | { | 1393 | { |
1394 | //Console.WriteLine(" CreateGeom 3"); | ||
1360 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); | 1395 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); |
1361 | } | 1396 | } |
1362 | catch (AccessViolationException) | 1397 | catch (AccessViolationException) |
@@ -1373,6 +1408,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1373 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1408 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1374 | try | 1409 | try |
1375 | { | 1410 | { |
1411 | //Console.WriteLine(" CreateGeom 4"); | ||
1376 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); | 1412 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); |
1377 | } | 1413 | } |
1378 | catch (AccessViolationException) | 1414 | catch (AccessViolationException) |
@@ -1409,6 +1445,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1409 | 1445 | ||
1410 | lock (_parent_scene.OdeLock) | 1446 | lock (_parent_scene.OdeLock) |
1411 | { | 1447 | { |
1448 | //Console.WriteLine("changeadd 1"); | ||
1412 | CreateGeom(m_targetSpace, _mesh); | 1449 | CreateGeom(m_targetSpace, _mesh); |
1413 | 1450 | ||
1414 | if (prim_geom != IntPtr.Zero) | 1451 | if (prim_geom != IntPtr.Zero) |
@@ -1464,6 +1501,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1464 | OdePrim odParent = (OdePrim)_parent; | 1501 | OdePrim odParent = (OdePrim)_parent; |
1465 | if (Body != (IntPtr)0 && odParent.Body != (IntPtr)0 && Body != odParent.Body) | 1502 | if (Body != (IntPtr)0 && odParent.Body != (IntPtr)0 && Body != odParent.Body) |
1466 | { | 1503 | { |
1504 | // KF: Fixed Joints were removed? Anyway - this Console.WriteLine does not show up, so routine is not used?? | ||
1505 | Console.WriteLine(" JointCreateFixed"); | ||
1467 | m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); | 1506 | m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); |
1468 | d.JointAttach(m_linkJoint, Body, odParent.Body); | 1507 | d.JointAttach(m_linkJoint, Body, odParent.Body); |
1469 | d.JointSetFixed(m_linkJoint); | 1508 | d.JointSetFixed(m_linkJoint); |
@@ -1517,239 +1556,236 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1517 | float fz = 0; | 1556 | float fz = 0; |
1518 | 1557 | ||
1519 | 1558 | ||
1520 | if (IsPhysical && Body != IntPtr.Zero && !m_isSelected) | 1559 | if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. |
1521 | { | 1560 | { |
1522 | if (d.BodyIsEnabled(Body) && !m_angularlock.IsIdentical(PhysicsVector.Zero, 0.003f)) | 1561 | if (m_vehicle.Type != Vehicle.TYPE_NONE) |
1523 | { | 1562 | { |
1524 | d.Vector3 avel2 = d.BodyGetAngularVel(Body); | 1563 | // 'VEHICLES' are dealt with in ODEDynamics.cs |
1525 | if (m_angularlock.X == 1) | 1564 | m_vehicle.Step(timestep, _parent_scene); |
1526 | avel2.X = 0; | 1565 | } |
1527 | if (m_angularlock.Y == 1) | 1566 | else |
1528 | avel2.Y = 0; | 1567 | { |
1529 | if (m_angularlock.Z == 1) | 1568 | // NON-'VEHICLES' are dealt with here |
1530 | avel2.Z = 0; | 1569 | if (d.BodyIsEnabled(Body) && !m_angularlock.IsIdentical(PhysicsVector.Zero, 0.003f)) |
1531 | d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); | 1570 | { |
1532 | } | 1571 | d.Vector3 avel2 = d.BodyGetAngularVel(Body); |
1533 | //float PID_P = 900.0f; | 1572 | if (m_angularlock.X == 1) |
1534 | 1573 | avel2.X = 0; | |
1535 | float m_mass = CalculateMass(); | 1574 | if (m_angularlock.Y == 1) |
1536 | 1575 | avel2.Y = 0; | |
1537 | fz = 0f; | 1576 | if (m_angularlock.Z == 1) |
1577 | avel2.Z = 0; | ||
1578 | d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); | ||
1579 | } | ||
1580 | //float PID_P = 900.0f; | ||
1581 | |||
1582 | float m_mass = CalculateMass(); | ||
1583 | |||
1584 | // fz = 0f; | ||
1538 | //m_log.Info(m_collisionFlags.ToString()); | 1585 | //m_log.Info(m_collisionFlags.ToString()); |
1539 | 1586 | ||
1540 | if (m_buoyancy != 0) | 1587 | |
1541 | { | 1588 | //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. |
1542 | if (m_buoyancy > 0) | 1589 | // would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ?? |
1543 | { | 1590 | // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up |
1544 | fz = (((-1 * _parent_scene.gravityz) * m_buoyancy) * m_mass); | 1591 | // gravityz multiplier = 1 - m_buoyancy |
1545 | 1592 | fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; | |
1546 | //d.Vector3 l_velocity = d.BodyGetLinearVel(Body); | 1593 | |
1547 | //m_log.Info("Using Buoyancy: " + buoyancy + " G: " + (_parent_scene.gravityz * m_buoyancy) + "mass:" + m_mass + " Pos: " + Position.ToString()); | 1594 | if (m_usePID) |
1548 | } | 1595 | { |
1549 | else | 1596 | // KF - this is for object move? eg. llSetPos() ? |
1550 | { | 1597 | //if (!d.BodyIsEnabled(Body)) |
1551 | fz = (-1 * (((-1 * _parent_scene.gravityz) * (-1 * m_buoyancy)) * m_mass)); | 1598 | //d.BodySetForce(Body, 0f, 0f, 0f); |
1552 | } | 1599 | // If we're using the PID controller, then we have no gravity |
1553 | } | 1600 | //fz = (-1 * _parent_scene.gravityz) * m_mass; //KF: ?? Prims have no global gravity,so simply... |
1554 | 1601 | fz = 0f; | |
1555 | if (m_usePID) | 1602 | |
1556 | { | 1603 | // no lock; for now it's only called from within Simulate() |
1604 | |||
1605 | // If the PID Controller isn't active then we set our force | ||
1606 | // calculating base velocity to the current position | ||
1607 | |||
1608 | if ((m_PIDTau < 1) && (m_PIDTau != 0)) | ||
1609 | { | ||
1610 | //PID_G = PID_G / m_PIDTau; | ||
1611 | m_PIDTau = 1; | ||
1612 | } | ||
1613 | |||
1614 | if ((PID_G - m_PIDTau) <= 0) | ||
1615 | { | ||
1616 | PID_G = m_PIDTau + 1; | ||
1617 | } | ||
1618 | //PidStatus = true; | ||
1619 | |||
1620 | // PhysicsVector vec = new PhysicsVector(); | ||
1621 | d.Vector3 vel = d.BodyGetLinearVel(Body); | ||
1622 | |||
1623 | d.Vector3 pos = d.BodyGetPosition(Body); | ||
1624 | _target_velocity = | ||
1625 | new PhysicsVector( | ||
1626 | (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep), | ||
1627 | (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep), | ||
1628 | (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep) | ||
1629 | ); | ||
1630 | |||
1631 | // if velocity is zero, use position control; otherwise, velocity control | ||
1632 | |||
1633 | if (_target_velocity.IsIdentical(PhysicsVector.Zero,0.1f)) | ||
1634 | { | ||
1635 | // keep track of where we stopped. No more slippin' & slidin' | ||
1636 | |||
1637 | // We only want to deactivate the PID Controller if we think we want to have our surrogate | ||
1638 | // react to the physics scene by moving it's position. | ||
1639 | // Avatar to Avatar collisions | ||
1640 | // Prim to avatar collisions | ||
1641 | |||
1642 | //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); | ||
1643 | //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2); | ||
1644 | //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; | ||
1645 | d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); | ||
1646 | d.BodySetLinearVel(Body, 0, 0, 0); | ||
1647 | d.BodyAddForce(Body, 0, 0, fz); | ||
1648 | return; | ||
1649 | } | ||
1650 | else | ||
1651 | { | ||
1652 | _zeroFlag = false; | ||
1653 | |||
1654 | // We're flying and colliding with something | ||
1655 | fx = ((_target_velocity.X) - vel.X) * (PID_D); | ||
1656 | fy = ((_target_velocity.Y) - vel.Y) * (PID_D); | ||
1657 | |||
1658 | // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; | ||
1659 | |||
1660 | fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); | ||
1661 | } | ||
1662 | } // end if (m_usePID) | ||
1663 | |||
1664 | // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller | ||
1665 | if (m_useHoverPID && !m_usePID) | ||
1666 | { | ||
1667 | // If we're using the PID controller, then we have no gravity | ||
1668 | fz = (-1 * _parent_scene.gravityz) * m_mass; | ||
1669 | |||
1670 | // no lock; for now it's only called from within Simulate() | ||
1671 | |||
1672 | // If the PID Controller isn't active then we set our force | ||
1673 | // calculating base velocity to the current position | ||
1674 | |||
1675 | if ((m_PIDTau < 1)) | ||
1676 | { | ||
1677 | PID_G = PID_G / m_PIDTau; | ||
1678 | } | ||
1679 | |||
1680 | if ((PID_G - m_PIDTau) <= 0) | ||
1681 | { | ||
1682 | PID_G = m_PIDTau + 1; | ||
1683 | } | ||
1557 | 1684 | ||
1558 | //if (!d.BodyIsEnabled(Body)) | ||
1559 | //d.BodySetForce(Body, 0f, 0f, 0f); | ||
1560 | // If we're using the PID controller, then we have no gravity | ||
1561 | fz = (-1 * _parent_scene.gravityz) * m_mass; | ||
1562 | 1685 | ||
1563 | // no lock; for now it's only called from within Simulate() | 1686 | // Where are we, and where are we headed? |
1687 | d.Vector3 pos = d.BodyGetPosition(Body); | ||
1688 | d.Vector3 vel = d.BodyGetLinearVel(Body); | ||
1689 | |||
1690 | |||
1691 | // Non-Vehicles have a limited set of Hover options. | ||
1692 | // determine what our target height really is based on HoverType | ||
1693 | switch (m_PIDHoverType) | ||
1694 | { | ||
1695 | case PIDHoverType.Ground: | ||
1696 | m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); | ||
1697 | m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; | ||
1698 | break; | ||
1699 | case PIDHoverType.GroundAndWater: | ||
1700 | m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); | ||
1701 | m_waterHeight = _parent_scene.GetWaterLevel(); | ||
1702 | if (m_groundHeight > m_waterHeight) | ||
1703 | { | ||
1704 | m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; | ||
1705 | } | ||
1706 | else | ||
1707 | { | ||
1708 | m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; | ||
1709 | } | ||
1710 | break; | ||
1711 | |||
1712 | } // end switch (m_PIDHoverType) | ||
1713 | |||
1714 | |||
1715 | _target_velocity = | ||
1716 | new PhysicsVector(0.0f, 0.0f, | ||
1717 | (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep) | ||
1718 | ); | ||
1719 | |||
1720 | // if velocity is zero, use position control; otherwise, velocity control | ||
1721 | |||
1722 | if (_target_velocity.IsIdentical(PhysicsVector.Zero, 0.1f)) | ||
1723 | { | ||
1724 | // keep track of where we stopped. No more slippin' & slidin' | ||
1725 | |||
1726 | // We only want to deactivate the PID Controller if we think we want to have our surrogate | ||
1727 | // react to the physics scene by moving it's position. | ||
1728 | // Avatar to Avatar collisions | ||
1729 | // Prim to avatar collisions | ||
1730 | |||
1731 | d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); | ||
1732 | d.BodySetLinearVel(Body, vel.X, vel.Y, 0); | ||
1733 | d.BodyAddForce(Body, 0, 0, fz); | ||
1734 | return; | ||
1735 | } | ||
1736 | else | ||
1737 | { | ||
1738 | _zeroFlag = false; | ||
1739 | |||
1740 | // We're flying and colliding with something | ||
1741 | fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); | ||
1742 | } | ||
1743 | } | ||
1744 | |||
1745 | fx *= m_mass; | ||
1746 | fy *= m_mass; | ||
1747 | //fz *= m_mass; | ||
1748 | |||
1749 | fx += m_force.X; | ||
1750 | fy += m_force.Y; | ||
1751 | fz += m_force.Z; | ||
1752 | |||
1753 | //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); | ||
1754 | if (fx != 0 || fy != 0 || fz != 0) | ||
1755 | { | ||
1756 | //m_taintdisable = true; | ||
1757 | //base.RaiseOutOfBounds(Position); | ||
1758 | //d.BodySetLinearVel(Body, fx, fy, 0f); | ||
1759 | if (!d.BodyIsEnabled(Body)) | ||
1760 | { | ||
1761 | // A physical body at rest on a surface will auto-disable after a while, | ||
1762 | // this appears to re-enable it incase the surface it is upon vanishes, | ||
1763 | // and the body should fall again. | ||
1764 | d.BodySetLinearVel(Body, 0f, 0f, 0f); | ||
1765 | d.BodySetForce(Body, 0, 0, 0); | ||
1766 | enableBodySoft(); | ||
1767 | } | ||
1768 | |||
1769 | // 35x10 = 350n times the mass per second applied maximum. | ||
1770 | float nmax = 35f * m_mass; | ||
1771 | float nmin = -35f * m_mass; | ||
1564 | 1772 | ||
1565 | // If the PID Controller isn't active then we set our force | ||
1566 | // calculating base velocity to the current position | ||
1567 | |||
1568 | if ((m_PIDTau < 1) && (m_PIDTau != 0)) | ||
1569 | { | ||
1570 | //PID_G = PID_G / m_PIDTau; | ||
1571 | m_PIDTau = 1; | ||
1572 | } | ||
1573 | |||
1574 | if ((PID_G - m_PIDTau) <= 0) | ||
1575 | { | ||
1576 | PID_G = m_PIDTau + 1; | ||
1577 | } | ||
1578 | //PidStatus = true; | ||
1579 | |||
1580 | // PhysicsVector vec = new PhysicsVector(); | ||
1581 | d.Vector3 vel = d.BodyGetLinearVel(Body); | ||
1582 | |||
1583 | d.Vector3 pos = d.BodyGetPosition(Body); | ||
1584 | _target_velocity = | ||
1585 | new PhysicsVector( | ||
1586 | (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep), | ||
1587 | (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep), | ||
1588 | (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep) | ||
1589 | ); | ||
1590 | |||
1591 | // if velocity is zero, use position control; otherwise, velocity control | ||
1592 | |||
1593 | if (_target_velocity.IsIdentical(PhysicsVector.Zero,0.1f)) | ||
1594 | { | ||
1595 | // keep track of where we stopped. No more slippin' & slidin' | ||
1596 | |||
1597 | // We only want to deactivate the PID Controller if we think we want to have our surrogate | ||
1598 | // react to the physics scene by moving it's position. | ||
1599 | // Avatar to Avatar collisions | ||
1600 | // Prim to avatar collisions | ||
1601 | |||
1602 | //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); | ||
1603 | //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2); | ||
1604 | //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; | ||
1605 | d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); | ||
1606 | d.BodySetLinearVel(Body, 0, 0, 0); | ||
1607 | d.BodyAddForce(Body, 0, 0, fz); | ||
1608 | return; | ||
1609 | } | ||
1610 | else | ||
1611 | { | ||
1612 | _zeroFlag = false; | ||
1613 | |||
1614 | // We're flying and colliding with something | ||
1615 | fx = ((_target_velocity.X) - vel.X) * (PID_D); | ||
1616 | fy = ((_target_velocity.Y) - vel.Y) * (PID_D); | ||
1617 | |||
1618 | // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; | ||
1619 | |||
1620 | fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); | ||
1621 | } | ||
1622 | } | ||
1623 | |||
1624 | // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller | ||
1625 | if (m_useHoverPID && !m_usePID) | ||
1626 | { | ||
1627 | // If we're using the PID controller, then we have no gravity | ||
1628 | fz = (-1 * _parent_scene.gravityz) * m_mass; | ||
1629 | |||
1630 | // no lock; for now it's only called from within Simulate() | ||
1631 | |||
1632 | // If the PID Controller isn't active then we set our force | ||
1633 | // calculating base velocity to the current position | ||
1634 | |||
1635 | if ((m_PIDTau < 1)) | ||
1636 | { | ||
1637 | PID_G = PID_G / m_PIDTau; | ||
1638 | } | ||
1639 | |||
1640 | if ((PID_G - m_PIDTau) <= 0) | ||
1641 | { | ||
1642 | PID_G = m_PIDTau + 1; | ||
1643 | } | ||
1644 | 1773 | ||
1645 | 1774 | if (fx > nmax) | |
1646 | // Where are we, and where are we headed? | 1775 | fx = nmax; |
1647 | d.Vector3 pos = d.BodyGetPosition(Body); | 1776 | if (fx < nmin) |
1648 | d.Vector3 vel = d.BodyGetLinearVel(Body); | 1777 | fx = nmin; |
1649 | 1778 | if (fy > nmax) | |
1650 | // determine what our target height really is based on HoverType | 1779 | fy = nmax; |
1651 | switch (m_PIDHoverType) | 1780 | if (fy < nmin) |
1652 | { | 1781 | fy = nmin; |
1653 | case PIDHoverType.Absolute: | 1782 | d.BodyAddForce(Body, fx, fy, fz); |
1654 | m_targetHoverHeight = m_PIDHoverHeight; | 1783 | } |
1655 | break; | 1784 | } |
1656 | case PIDHoverType.Ground: | ||
1657 | m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); | ||
1658 | m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; | ||
1659 | break; | ||
1660 | case PIDHoverType.GroundAndWater: | ||
1661 | m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); | ||
1662 | m_waterHeight = _parent_scene.GetWaterLevel(); | ||
1663 | if (m_groundHeight > m_waterHeight) | ||
1664 | { | ||
1665 | m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; | ||
1666 | } | ||
1667 | else | ||
1668 | { | ||
1669 | m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; | ||
1670 | } | ||
1671 | break; | ||
1672 | case PIDHoverType.Water: | ||
1673 | m_waterHeight = _parent_scene.GetWaterLevel(); | ||
1674 | m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; | ||
1675 | break; | ||
1676 | } | ||
1677 | |||
1678 | |||
1679 | _target_velocity = | ||
1680 | new PhysicsVector(0.0f, 0.0f, | ||
1681 | (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep) | ||
1682 | ); | ||
1683 | |||
1684 | // if velocity is zero, use position control; otherwise, velocity control | ||
1685 | |||
1686 | if (_target_velocity.IsIdentical(PhysicsVector.Zero, 0.1f)) | ||
1687 | { | ||
1688 | // keep track of where we stopped. No more slippin' & slidin' | ||
1689 | |||
1690 | // We only want to deactivate the PID Controller if we think we want to have our surrogate | ||
1691 | // react to the physics scene by moving it's position. | ||
1692 | // Avatar to Avatar collisions | ||
1693 | // Prim to avatar collisions | ||
1694 | |||
1695 | d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); | ||
1696 | d.BodySetLinearVel(Body, vel.X, vel.Y, 0); | ||
1697 | d.BodyAddForce(Body, 0, 0, fz); | ||
1698 | return; | ||
1699 | } | ||
1700 | else | ||
1701 | { | ||
1702 | _zeroFlag = false; | ||
1703 | |||
1704 | // We're flying and colliding with something | ||
1705 | fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); | ||
1706 | } | ||
1707 | } | ||
1708 | |||
1709 | fx *= m_mass; | ||
1710 | fy *= m_mass; | ||
1711 | //fz *= m_mass; | ||
1712 | |||
1713 | fx += m_force.X; | ||
1714 | fy += m_force.Y; | ||
1715 | fz += m_force.Z; | ||
1716 | |||
1717 | //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); | ||
1718 | if (fx != 0 || fy != 0 || fz != 0) | ||
1719 | { | ||
1720 | //m_taintdisable = true; | ||
1721 | //base.RaiseOutOfBounds(Position); | ||
1722 | //d.BodySetLinearVel(Body, fx, fy, 0f); | ||
1723 | if (!d.BodyIsEnabled(Body)) | ||
1724 | { | ||
1725 | d.BodySetLinearVel(Body, 0f, 0f, 0f); | ||
1726 | d.BodySetForce(Body, 0, 0, 0); | ||
1727 | enableBodySoft(); | ||
1728 | } | ||
1729 | |||
1730 | // 35x10 = 350n times the mass per second applied maximum. | ||
1731 | float nmax = 35f * m_mass; | ||
1732 | float nmin = -35f * m_mass; | ||
1733 | |||
1734 | |||
1735 | if (fx > nmax) | ||
1736 | fx = nmax; | ||
1737 | if (fx < nmin) | ||
1738 | fx = nmin; | ||
1739 | if (fy > nmax) | ||
1740 | fy = nmax; | ||
1741 | if (fy < nmin) | ||
1742 | fy = nmin; | ||
1743 | d.BodyAddForce(Body, fx, fy, fz); | ||
1744 | } | ||
1745 | if (m_vehicle.Body == IntPtr.Zero && m_vehicle.Type != Vehicle.TYPE_NONE) | ||
1746 | m_vehicle.Enable(Body, _parent_scene); | ||
1747 | |||
1748 | m_vehicle.Step(timestep); | ||
1749 | } | 1785 | } |
1750 | else | 1786 | else |
1751 | { | 1787 | { // is not physical, or is not a body or is selected |
1752 | // _zeroPosition = d.BodyGetPosition(Body); | 1788 | // _zeroPosition = d.BodyGetPosition(Body); |
1753 | return; | 1789 | return; |
1754 | } | 1790 | } |
1755 | } | 1791 | } |
@@ -1763,14 +1799,22 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1763 | myrot.Y = _orientation.Y; | 1799 | myrot.Y = _orientation.Y; |
1764 | myrot.Z = _orientation.Z; | 1800 | myrot.Z = _orientation.Z; |
1765 | myrot.W = _orientation.W; | 1801 | myrot.W = _orientation.W; |
1766 | d.GeomSetQuaternion(prim_geom, ref myrot); | 1802 | if (Body != IntPtr.Zero) |
1767 | if (m_isphysical && Body != IntPtr.Zero) | ||
1768 | { | 1803 | { |
1804 | // KF: If this is a root prim do BodySet | ||
1769 | d.BodySetQuaternion(Body, ref myrot); | 1805 | d.BodySetQuaternion(Body, ref myrot); |
1770 | if (!m_angularlock.IsIdentical(new PhysicsVector(1, 1, 1), 0)) | 1806 | if (m_isphysical) |
1771 | createAMotor(m_angularlock); | 1807 | { |
1808 | if (!m_angularlock.IsIdentical(new PhysicsVector(1, 1, 1), 0)) | ||
1809 | createAMotor(m_angularlock); | ||
1810 | } | ||
1811 | } | ||
1812 | else | ||
1813 | { | ||
1814 | // daughter prim, do Geom set | ||
1815 | d.GeomSetQuaternion(prim_geom, ref myrot); | ||
1772 | } | 1816 | } |
1773 | 1817 | ||
1774 | resetCollisionAccounting(); | 1818 | resetCollisionAccounting(); |
1775 | m_taintrot = _orientation; | 1819 | m_taintrot = _orientation; |
1776 | } | 1820 | } |
@@ -1832,7 +1876,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1832 | m_log.Error("[PHYSICS]: PrimGeom dead"); | 1876 | m_log.Error("[PHYSICS]: PrimGeom dead"); |
1833 | } | 1877 | } |
1834 | } | 1878 | } |
1835 | 1879 | //Console.WriteLine("changePhysicsStatus for " + m_primName ); | |
1836 | changeadd(2f); | 1880 | changeadd(2f); |
1837 | } | 1881 | } |
1838 | if (childPrim) | 1882 | if (childPrim) |
@@ -1910,7 +1954,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1910 | mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); | 1954 | mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); |
1911 | 1955 | ||
1912 | //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); | 1956 | //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); |
1913 | 1957 | //Console.WriteLine("changesize 1"); | |
1914 | CreateGeom(m_targetSpace, mesh); | 1958 | CreateGeom(m_targetSpace, mesh); |
1915 | 1959 | ||
1916 | 1960 | ||
@@ -1918,6 +1962,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1918 | else | 1962 | else |
1919 | { | 1963 | { |
1920 | _mesh = null; | 1964 | _mesh = null; |
1965 | //Console.WriteLine("changesize 2"); | ||
1921 | CreateGeom(m_targetSpace, _mesh); | 1966 | CreateGeom(m_targetSpace, _mesh); |
1922 | } | 1967 | } |
1923 | 1968 | ||
@@ -2024,6 +2069,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2024 | else | 2069 | else |
2025 | { | 2070 | { |
2026 | _mesh = null; | 2071 | _mesh = null; |
2072 | //Console.WriteLine("changeshape"); | ||
2027 | CreateGeom(m_targetSpace, null); | 2073 | CreateGeom(m_targetSpace, null); |
2028 | } | 2074 | } |
2029 | 2075 | ||
@@ -2365,7 +2411,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2365 | set | 2411 | set |
2366 | { | 2412 | { |
2367 | if (QuaternionIsFinite(value)) | 2413 | if (QuaternionIsFinite(value)) |
2414 | { | ||
2368 | _orientation = value; | 2415 | _orientation = value; |
2416 | } | ||
2369 | else | 2417 | else |
2370 | m_log.Warn("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object"); | 2418 | m_log.Warn("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object"); |
2371 | 2419 | ||
@@ -2584,12 +2632,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2584 | //outofBounds = true; | 2632 | //outofBounds = true; |
2585 | } | 2633 | } |
2586 | 2634 | ||
2635 | float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); | ||
2636 | //Console.WriteLine("Adiff " + m_primName + " = " + Adiff); | ||
2587 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) | 2637 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) |
2588 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) | 2638 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) |
2589 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) | 2639 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) |
2590 | && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.01)) | 2640 | // && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.01)) |
2641 | && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.0001)) // KF 0.01 is far to large | ||
2591 | { | 2642 | { |
2592 | _zeroFlag = true; | 2643 | _zeroFlag = true; |
2644 | //Console.WriteLine("ZFT 2"); | ||
2593 | m_throttleUpdates = false; | 2645 | m_throttleUpdates = false; |
2594 | } | 2646 | } |
2595 | else | 2647 | else |
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 94223d8..b7afa27 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | |||
@@ -238,7 +238,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
238 | private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); | 238 | private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); |
239 | private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>(); | 239 | private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>(); |
240 | private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); | 240 | private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); |
241 | private readonly HashSet<OdePrim> _taintedPrim = new HashSet<OdePrim>(); | 241 | private readonly HashSet<OdePrim> _taintedPrimH = new HashSet<OdePrim>(); |
242 | private readonly List<OdePrim> _taintedPrimL = new List<OdePrim>(); | ||
242 | private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>(); | 243 | private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>(); |
243 | private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); | 244 | private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); |
244 | private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); | 245 | private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); |
@@ -2112,6 +2113,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2112 | /// <param name="prim"></param> | 2113 | /// <param name="prim"></param> |
2113 | public void RemovePrimThreadLocked(OdePrim prim) | 2114 | public void RemovePrimThreadLocked(OdePrim prim) |
2114 | { | 2115 | { |
2116 | //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); | ||
2115 | lock (prim) | 2117 | lock (prim) |
2116 | { | 2118 | { |
2117 | remCollisionEventReporting(prim); | 2119 | remCollisionEventReporting(prim); |
@@ -2559,11 +2561,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2559 | if (prim is OdePrim) | 2561 | if (prim is OdePrim) |
2560 | { | 2562 | { |
2561 | OdePrim taintedprim = ((OdePrim) prim); | 2563 | OdePrim taintedprim = ((OdePrim) prim); |
2562 | lock (_taintedPrim) | 2564 | lock (_taintedPrimH) |
2563 | { | 2565 | { |
2564 | if (!(_taintedPrim.Contains(taintedprim))) | 2566 | if (!(_taintedPrimH.Contains(taintedprim))) |
2565 | _taintedPrim.Add(taintedprim); | 2567 | { |
2566 | } | 2568 | //Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.m_primName); |
2569 | _taintedPrimH.Add(taintedprim); // HashSet for searching | ||
2570 | _taintedPrimL.Add(taintedprim); // List for ordered readout | ||
2571 | } | ||
2572 | } | ||
2567 | return; | 2573 | return; |
2568 | } | 2574 | } |
2569 | else if (prim is OdeCharacter) | 2575 | else if (prim is OdeCharacter) |
@@ -2599,7 +2605,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2599 | float fps = 0; | 2605 | float fps = 0; |
2600 | //m_log.Info(timeStep.ToString()); | 2606 | //m_log.Info(timeStep.ToString()); |
2601 | step_time += timeStep; | 2607 | step_time += timeStep; |
2602 | 2608 | ||
2603 | // If We're loaded down by something else, | 2609 | // If We're loaded down by something else, |
2604 | // or debugging with the Visual Studio project on pause | 2610 | // or debugging with the Visual Studio project on pause |
2605 | // skip a few frames to catch up gracefully. | 2611 | // skip a few frames to catch up gracefully. |
@@ -2679,16 +2685,20 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2679 | // Modify other objects in the scene. | 2685 | // Modify other objects in the scene. |
2680 | processedtaints = false; | 2686 | processedtaints = false; |
2681 | 2687 | ||
2682 | lock (_taintedPrim) | 2688 | lock (_taintedPrimL) |
2683 | { | 2689 | { |
2684 | foreach (OdePrim prim in _taintedPrim) | 2690 | foreach (OdePrim prim in _taintedPrimL) |
2685 | { | 2691 | { |
2692 | |||
2693 | |||
2686 | if (prim.m_taintremove) | 2694 | if (prim.m_taintremove) |
2687 | { | 2695 | { |
2696 | //Console.WriteLine("Simulate calls RemovePrimThreadLocked"); | ||
2688 | RemovePrimThreadLocked(prim); | 2697 | RemovePrimThreadLocked(prim); |
2689 | } | 2698 | } |
2690 | else | 2699 | else |
2691 | { | 2700 | { |
2701 | //Console.WriteLine("Simulate calls ProcessTaints"); | ||
2692 | prim.ProcessTaints(timeStep); | 2702 | prim.ProcessTaints(timeStep); |
2693 | } | 2703 | } |
2694 | processedtaints = true; | 2704 | processedtaints = true; |
@@ -2878,7 +2888,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2878 | } | 2888 | } |
2879 | 2889 | ||
2880 | if (processedtaints) | 2890 | if (processedtaints) |
2881 | _taintedPrim.Clear(); | 2891 | //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); |
2892 | _taintedPrimH.Clear(); | ||
2893 | _taintedPrimL.Clear(); | ||
2882 | } | 2894 | } |
2883 | 2895 | ||
2884 | // Move characters | 2896 | // Move characters |
@@ -3488,7 +3500,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3488 | { | 3500 | { |
3489 | if (geom == localGround) | 3501 | if (geom == localGround) |
3490 | { | 3502 | { |
3491 | //localHeightfield = TerrainHeightFieldHeights[geom]; | 3503 | localHeightfield = TerrainHeightFieldHeights[geom]; |
3492 | proceed = true; | 3504 | proceed = true; |
3493 | } | 3505 | } |
3494 | else | 3506 | else |
@@ -3510,7 +3522,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3510 | // memory corruption | 3522 | // memory corruption |
3511 | if (TerrainHeightFieldHeights.ContainsKey(g)) | 3523 | if (TerrainHeightFieldHeights.ContainsKey(g)) |
3512 | { | 3524 | { |
3513 | //float[] removingHeightField = TerrainHeightFieldHeights[g]; | 3525 | float[] removingHeightField = TerrainHeightFieldHeights[g]; |
3514 | TerrainHeightFieldHeights.Remove(g); | 3526 | TerrainHeightFieldHeights.Remove(g); |
3515 | 3527 | ||
3516 | if (RegionTerrain.ContainsKey(g)) | 3528 | if (RegionTerrain.ContainsKey(g)) |
@@ -3519,17 +3531,27 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3519 | } | 3531 | } |
3520 | 3532 | ||
3521 | d.GeomDestroy(g); | 3533 | d.GeomDestroy(g); |
3522 | //removingHeightField = new float[0]; | 3534 | removingHeightField = new float[0]; |
3523 | } | 3535 | |
3536 | |||
3537 | |||
3538 | } | ||
3539 | |||
3524 | } | 3540 | } |
3541 | |||
3525 | } | 3542 | } |
3526 | else | 3543 | else |
3527 | { | 3544 | { |
3528 | m_log.Warn("[PHYSICS]: Couldn't proceed with UnCombine. Region has inconsistant data."); | 3545 | m_log.Warn("[PHYSICS]: Couldn't proceed with UnCombine. Region has inconsistant data."); |
3546 | |||
3529 | } | 3547 | } |
3530 | } | 3548 | |
3549 | } | ||
3550 | |||
3531 | } | 3551 | } |
3532 | } | 3552 | } |
3553 | |||
3554 | |||
3533 | 3555 | ||
3534 | public override void SetWaterLevel(float baseheight) | 3556 | public override void SetWaterLevel(float baseheight) |
3535 | { | 3557 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 4c52b11..c41f2a5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -96,17 +96,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
96 | m_localID = localID; | 96 | m_localID = localID; |
97 | m_itemID = itemID; | 97 | m_itemID = itemID; |
98 | 98 | ||
99 | m_ScriptDelayFactor = m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); | 99 | m_ScriptDelayFactor = |
100 | m_ScriptDistanceFactor = m_ScriptEngine.Config.GetFloat("ScriptDistanceLimitFactor", 1.0f); | 100 | m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); |
101 | m_MinTimerInterval = m_ScriptEngine.Config.GetFloat("MinTimerInterval", 0.5f); | 101 | m_ScriptDistanceFactor = |
102 | m_automaticLinkPermission = m_ScriptEngine.Config.GetBoolean("AutomaticLinkPermission", false); | 102 | m_ScriptEngine.Config.GetFloat("ScriptDistanceLimitFactor", 1.0f); |
103 | m_scriptConsoleChannel = m_ScriptEngine.Config.GetInt("ScriptConsoleChannel", 0); | 103 | m_MinTimerInterval = |
104 | m_scriptConsoleChannelEnabled = (m_scriptConsoleChannel != 0); | 104 | m_ScriptEngine.Config.GetFloat("MinTimerInterval", 0.5f); |
105 | m_notecardLineReadCharsMax = m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); | 105 | m_automaticLinkPermission = |
106 | m_ScriptEngine.Config.GetBoolean("AutomaticLinkPermission", false); | ||
107 | m_notecardLineReadCharsMax = | ||
108 | m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); | ||
106 | if (m_notecardLineReadCharsMax > 65535) | 109 | if (m_notecardLineReadCharsMax > 65535) |
107 | m_notecardLineReadCharsMax = 65535; | 110 | m_notecardLineReadCharsMax = 65535; |
108 | 111 | ||
109 | m_TransferModule = m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); | 112 | m_TransferModule = |
113 | m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); | ||
110 | m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); | 114 | m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); |
111 | if (m_UrlModule != null) | 115 | if (m_UrlModule != null) |
112 | { | 116 | { |
@@ -1969,7 +1973,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1969 | { | 1973 | { |
1970 | part.UpdateRotation(rot); | 1974 | part.UpdateRotation(rot); |
1971 | // Update rotation does not move the object in the physics scene if it's a linkset. | 1975 | // Update rotation does not move the object in the physics scene if it's a linkset. |
1972 | part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; | 1976 | |
1977 | //KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type | ||
1978 | // part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; | ||
1973 | } | 1979 | } |
1974 | 1980 | ||
1975 | /// <summary> | 1981 | /// <summary> |
@@ -6747,15 +6753,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6747 | // try to let this work as in SL... | 6753 | // try to let this work as in SL... |
6748 | if (part.ParentID == 0) | 6754 | if (part.ParentID == 0) |
6749 | { | 6755 | { |
6750 | // special case: If we are root, rotate | 6756 | // special case: If we are root, rotate complete SOG to new rotation |
6751 | // complete SOG to new rotation | ||
6752 | SetRot(part, Rot2Quaternion(q)); | 6757 | SetRot(part, Rot2Quaternion(q)); |
6753 | } | 6758 | } |
6754 | else | 6759 | else |
6755 | { | 6760 | { |
6756 | // we are a child. The rotation values | 6761 | // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. |
6757 | // will be set to the one of root modified | ||
6758 | // by rot, as in SL. Don't ask. | ||
6759 | SceneObjectGroup group = part.ParentGroup; | 6762 | SceneObjectGroup group = part.ParentGroup; |
6760 | if (group != null) // a bit paranoid, maybe | 6763 | if (group != null) // a bit paranoid, maybe |
6761 | { | 6764 | { |