aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs46
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs29
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs177
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActors.cs131
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs9
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs4
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs207
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs13
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs129
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs12
13 files changed, 567 insertions, 203 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 2ce778d..8ddaa60 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -418,18 +418,57 @@ namespace OpenSim.Region.Framework.Scenes
418 418
419 if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid 419 if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid
420 { 420 {
421 // Create a set of base permissions that will not include export if the user
422 // is not allowed to change the export flag.
423 bool denyExportChange = false;
424
425 m_log.InfoFormat("[XXX]: B: {0} O: {1} E: {2}", itemUpd.BasePermissions, itemUpd.CurrentPermissions, itemUpd.EveryOnePermissions);
426
427 // If the user is not the creator or doesn't have "E" in both "B" and "O", deny setting export
428 if ((item.BasePermissions & (uint)(PermissionMask.All | PermissionMask.Export)) != (uint)(PermissionMask.All | PermissionMask.Export) || (item.CurrentPermissions & (uint)PermissionMask.Export) == 0 || item.CreatorIdAsUuid != item.Owner)
429 denyExportChange = true;
430
431 m_log.InfoFormat("[XXX]: Deny Export Update {0}", denyExportChange);
432
433 // If it is already set, force it set and also force full perm
434 // else prevent setting it. It can and should never be set unless
435 // set in base, so the condition above is valid
436 if (denyExportChange)
437 {
438 // If we are not allowed to change it, then force it to the
439 // original item's setting and if it was on, also force full perm
440 if ((item.EveryOnePermissions & (uint)PermissionMask.Export) != 0)
441 {
442 itemUpd.NextPermissions = (uint)(PermissionMask.All);
443 itemUpd.EveryOnePermissions |= (uint)PermissionMask.Export;
444 }
445 else
446 {
447 itemUpd.EveryOnePermissions &= ~(uint)PermissionMask.Export;
448 }
449 }
450 else
451 {
452 // If the new state is exportable, force full perm
453 if ((itemUpd.EveryOnePermissions & (uint)PermissionMask.Export) != 0)
454 {
455 m_log.InfoFormat("[XXX]: Force full perm");
456 itemUpd.NextPermissions = (uint)(PermissionMask.All);
457 }
458 }
459
421 if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions)) 460 if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
422 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; 461 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
423 item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions; 462 item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
463
424 if (item.EveryOnePermissions != (itemUpd.EveryOnePermissions & item.BasePermissions)) 464 if (item.EveryOnePermissions != (itemUpd.EveryOnePermissions & item.BasePermissions))
425 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; 465 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
426 item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions; 466 item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions;
467
427 if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions)) 468 if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions))
428 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup; 469 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
429
430// m_log.DebugFormat("[USER INVENTORY]: item.Flags {0}", item.Flags);
431
432 item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions; 470 item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions;
471
433 item.GroupID = itemUpd.GroupID; 472 item.GroupID = itemUpd.GroupID;
434 item.GroupOwned = itemUpd.GroupOwned; 473 item.GroupOwned = itemUpd.GroupOwned;
435 item.CreationDate = itemUpd.CreationDate; 474 item.CreationDate = itemUpd.CreationDate;
@@ -451,6 +490,7 @@ namespace OpenSim.Region.Framework.Scenes
451 item.SaleType = itemUpd.SaleType; 490 item.SaleType = itemUpd.SaleType;
452 491
453 InventoryService.UpdateItem(item); 492 InventoryService.UpdateItem(item);
493 remoteClient.SendBulkUpdateInventory(item);
454 } 494 }
455 495
456 if (UUID.Zero != transactionID) 496 if (UUID.Zero != transactionID)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 0621e2a..9e7a986 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2671,11 +2671,20 @@ namespace OpenSim.Region.Framework.Scenes
2671 2671
2672 public void AdjustChildPrimPermissions() 2672 public void AdjustChildPrimPermissions()
2673 { 2673 {
2674 uint newOwnerMask = (uint)(PermissionMask.All | PermissionMask.Export) & 0xfffffff8; // Mask folded bits
2675 uint foldedPerms = RootPart.OwnerMask & 3;
2676
2674 ForEachPart(part => 2677 ForEachPart(part =>
2675 { 2678 {
2679 newOwnerMask &= part.BaseMask;
2676 if (part != RootPart) 2680 if (part != RootPart)
2677 part.ClonePermissions(RootPart); 2681 part.ClonePermissions(RootPart);
2678 }); 2682 });
2683
2684 uint lockMask = ~(uint)PermissionMask.Move;
2685 uint lockBit = RootPart.OwnerMask & (uint)PermissionMask.Move;
2686 RootPart.OwnerMask = (RootPart.OwnerMask & lockBit) | ((newOwnerMask | foldedPerms) & lockMask);
2687 RootPart.ScheduleFullUpdate();
2679 } 2688 }
2680 2689
2681 public void UpdatePermissions(UUID AgentID, byte field, uint localID, 2690 public void UpdatePermissions(UUID AgentID, byte field, uint localID,
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 847df03..ec9e87e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -424,8 +424,8 @@ namespace OpenSim.Region.Framework.Scenes
424 private uint _category; 424 private uint _category;
425 private Int32 _creationDate; 425 private Int32 _creationDate;
426 private uint _parentID = 0; 426 private uint _parentID = 0;
427 private uint _baseMask = (uint)PermissionMask.All; 427 private uint _baseMask = (uint)(PermissionMask.All | PermissionMask.Export);
428 private uint _ownerMask = (uint)PermissionMask.All; 428 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export);
429 private uint _groupMask = (uint)PermissionMask.None; 429 private uint _groupMask = (uint)PermissionMask.None;
430 private uint _everyoneMask = (uint)PermissionMask.None; 430 private uint _everyoneMask = (uint)PermissionMask.None;
431 private uint _nextOwnerMask = (uint)PermissionMask.All; 431 private uint _nextOwnerMask = (uint)PermissionMask.All;
@@ -3876,10 +3876,10 @@ namespace OpenSim.Region.Framework.Scenes
3876 3876
3877 public void TrimPermissions() 3877 public void TrimPermissions()
3878 { 3878 {
3879 BaseMask &= (uint)PermissionMask.All; 3879 BaseMask &= (uint)(PermissionMask.All | PermissionMask.Export);
3880 OwnerMask &= (uint)PermissionMask.All; 3880 OwnerMask &= (uint)(PermissionMask.All | PermissionMask.Export);
3881 GroupMask &= (uint)PermissionMask.All; 3881 GroupMask &= (uint)PermissionMask.All;
3882 EveryoneMask &= (uint)PermissionMask.All; 3882 EveryoneMask &= (uint)(PermissionMask.All | PermissionMask.Export);
3883 NextOwnerMask &= (uint)PermissionMask.All; 3883 NextOwnerMask &= (uint)PermissionMask.All;
3884 } 3884 }
3885 3885
@@ -3982,10 +3982,22 @@ namespace OpenSim.Region.Framework.Scenes
3982 baseMask; 3982 baseMask;
3983 break; 3983 break;
3984 case 8: 3984 case 8:
3985 // Trying to set export permissions - extra checks
3986 if (set && (mask & (uint)PermissionMask.Export) != 0)
3987 {
3988 if ((OwnerMask & (uint)PermissionMask.Export) == 0 || (BaseMask & (uint)PermissionMask.Export) == 0 || (NextOwnerMask & (uint)PermissionMask.All) != (uint)PermissionMask.All)
3989 mask &= ~(uint)PermissionMask.Export;
3990 }
3985 EveryoneMask = ApplyMask(EveryoneMask, set, mask) & 3991 EveryoneMask = ApplyMask(EveryoneMask, set, mask) &
3986 baseMask; 3992 baseMask;
3987 break; 3993 break;
3988 case 16: 3994 case 16:
3995 // Force full perm if export
3996 if ((EveryoneMask & (uint)PermissionMask.Export) != 0)
3997 {
3998 NextOwnerMask = (uint)PermissionMask.All;
3999 break;
4000 }
3989 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4001 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
3990 baseMask; 4002 baseMask;
3991 // Prevent the client from creating no mod, no copy 4003 // Prevent the client from creating no mod, no copy
@@ -4743,9 +4755,12 @@ namespace OpenSim.Region.Framework.Scenes
4743 4755
4744 public void ApplyNextOwnerPermissions() 4756 public void ApplyNextOwnerPermissions()
4745 { 4757 {
4746 BaseMask &= NextOwnerMask; 4758 // Export needs to be preserved in the base and everyone
4759 // mask, but removed in the owner mask as a next owner
4760 // can never change the export status
4761 BaseMask &= NextOwnerMask | (uint)PermissionMask.Export;
4747 OwnerMask &= NextOwnerMask; 4762 OwnerMask &= NextOwnerMask;
4748 EveryoneMask &= NextOwnerMask; 4763 EveryoneMask &= NextOwnerMask | (uint)PermissionMask.Export;
4749 4764
4750 Inventory.ApplyNextOwnerPermissions(); 4765 Inventory.ApplyNextOwnerPermissions();
4751 } 4766 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
new file mode 100755
index 0000000..aa75663
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
@@ -0,0 +1,177 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33using OMV = OpenMetaverse;
34
35namespace OpenSim.Region.Physics.BulletSPlugin
36{
37public class BSActorLockAxis : BSActor
38{
39 bool TryExperimentalLockAxisCode = false;
40 BSConstraint LockAxisConstraint = null;
41
42 public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
43 : base(physicsScene, pObj,actorName)
44 {
45 m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
46 LockAxisConstraint = null;
47 }
48
49 // BSActor.isActive
50 public override bool isActive
51 {
52 get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
53 }
54
55 // Release any connections and resources used by the actor.
56 // BSActor.Dispose()
57 public override void Dispose()
58 {
59 RemoveAxisLockConstraint();
60 }
61
62 // Called when physical parameters (properties set in Bullet) need to be re-applied.
63 // Called at taint-time.
64 // BSActor.Refresh()
65 public override void Refresh()
66 {
67 m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}",
68 m_controllingPrim.LocalID, m_controllingPrim.LockedAxis, Enabled, m_controllingPrim.IsPhysicallyActive);
69 // If all the axis are free, we don't need to exist
70 if (m_controllingPrim.LockedAxis == m_controllingPrim.LockedAxisFree)
71 {
72 m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,allAxisFree,removing={1}", m_controllingPrim.LocalID, ActorName);
73 m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
74 return;
75 }
76 // If the object is physically active, add the axis locking constraint
77 if (Enabled
78 && m_controllingPrim.IsPhysicallyActive
79 && TryExperimentalLockAxisCode
80 && m_controllingPrim.LockedAxis != m_controllingPrim.LockedAxisFree)
81 {
82 if (LockAxisConstraint == null)
83 AddAxisLockConstraint();
84 }
85 else
86 {
87 RemoveAxisLockConstraint();
88 }
89 }
90
91 // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
92 // Register a prestep action to restore physical requirements before the next simulation step.
93 // Called at taint-time.
94 // BSActor.RemoveBodyDependencies()
95 public override void RemoveBodyDependencies()
96 {
97 if (LockAxisConstraint != null)
98 {
99 // If a constraint is set up, remove it from the physical scene
100 RemoveAxisLockConstraint();
101 // Schedule a call before the next simulation step to restore the constraint.
102 m_physicsScene.PostTaintObject(m_controllingPrim.LockedAxisActorName, m_controllingPrim.LocalID, delegate()
103 {
104 Refresh();
105 });
106 }
107 }
108
109 private void AddAxisLockConstraint()
110 {
111 // Lock that axis by creating a 6DOF constraint that has one end in the world and
112 // the other in the object.
113 // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817
114 // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380
115
116 // Remove any existing axis constraint (just to be sure)
117 RemoveAxisLockConstraint();
118
119 BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(m_physicsScene.World, m_controllingPrim.PhysBody,
120 // OMV.Vector3.Zero, OMV.Quaternion.Identity,
121 OMV.Vector3.Zero, OMV.Quaternion.Inverse(m_controllingPrim.RawOrientation),
122 // OMV.Vector3.Zero, m_controllingPrim.RawOrientation,
123 false /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */);
124 LockAxisConstraint = axisConstrainer;
125 m_physicsScene.Constraints.AddConstraint(LockAxisConstraint);
126
127 // The constraint is tied to the world and oriented to the prim.
128
129 // Free to move linearly in the region
130 OMV.Vector3 linearLow = OMV.Vector3.Zero;
131 OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize;
132 axisConstrainer.SetLinearLimits(linearLow, linearHigh);
133
134 // Angular with some axis locked
135 float fPI = (float)Math.PI;
136 OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI);
137 OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI);
138 if (m_controllingPrim.LockedAxis.X != 1f)
139 {
140 angularLow.X = 0f;
141 angularHigh.X = 0f;
142 }
143 if (m_controllingPrim.LockedAxis.Y != 1f)
144 {
145 angularLow.Y = 0f;
146 angularHigh.Y = 0f;
147 }
148 if (m_controllingPrim.LockedAxis.Z != 1f)
149 {
150 angularLow.Z = 0f;
151 angularHigh.Z = 0f;
152 }
153 if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh))
154 {
155 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID);
156 }
157
158 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}",
159 m_controllingPrim.LocalID, linearLow, linearHigh, angularLow, angularHigh);
160
161 // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
162 axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
163
164 axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass);
165 }
166
167 private void RemoveAxisLockConstraint()
168 {
169 if (LockAxisConstraint != null)
170 {
171 m_physicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint);
172 LockAxisConstraint = null;
173 m_physicsScene.DetailLog("{0},BSActorLockAxis.RemoveAxisLockConstraint,destroyingConstraint", m_controllingPrim.LocalID);
174 }
175 }
176}
177}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
new file mode 100755
index 0000000..5a19ba4
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
@@ -0,0 +1,131 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30
31namespace OpenSim.Region.Physics.BulletSPlugin
32{
33public class BSActorCollection
34{
35 private BSScene PhysicsScene { get; set; }
36 private Dictionary<string, BSActor> m_actors;
37
38 public BSActorCollection(BSScene physicsScene)
39 {
40 PhysicsScene = physicsScene;
41 m_actors = new Dictionary<string, BSActor>();
42 }
43 public void Add(string name, BSActor actor)
44 {
45 m_actors[name] = actor;
46 }
47 public bool RemoveAndRelease(string name)
48 {
49 bool ret = false;
50 if (m_actors.ContainsKey(name))
51 {
52 BSActor beingRemoved = m_actors[name];
53 beingRemoved.Dispose();
54 m_actors.Remove(name);
55 ret = true;
56 }
57 return ret;
58 }
59 public void Clear()
60 {
61 Release();
62 m_actors.Clear();
63 }
64 public bool HasActor(string name)
65 {
66 return m_actors.ContainsKey(name);
67 }
68 public void ForEachActor(Action<BSActor> act)
69 {
70 foreach (KeyValuePair<string, BSActor> kvp in m_actors)
71 act(kvp.Value);
72 }
73
74 public void Release()
75 {
76 ForEachActor(a => a.Dispose());
77 }
78 public void Refresh()
79 {
80 ForEachActor(a => a.Refresh());
81 }
82 public void RemoveBodyDependencies()
83 {
84 ForEachActor(a => a.RemoveBodyDependencies());
85 }
86}
87
88// =============================================================================
89/// <summary>
90/// Each physical object can have 'actors' who are pushing the object around.
91/// This can be used for hover, locking axis, making vehicles, etc.
92/// Each physical object can have multiple actors acting on it.
93///
94/// An actor usually registers itself with physics scene events (pre-step action)
95/// and modifies the parameters on the host physical object.
96/// </summary>
97public abstract class BSActor
98{
99 protected BSScene m_physicsScene { get; private set; }
100 protected BSPhysObject m_controllingPrim { get; private set; }
101 protected bool Enabled { get; set; }
102 public string ActorName { get; private set; }
103
104 public BSActor(BSScene physicsScene, BSPhysObject pObj, string actorName)
105 {
106 m_physicsScene = physicsScene;
107 m_controllingPrim = pObj;
108 ActorName = actorName;
109 Enabled = true;
110 }
111
112 // Return 'true' if activily updating the prim
113 public virtual bool isActive
114 {
115 get { return Enabled; }
116 }
117 // Turn the actor on an off.
118 public virtual void Enable(bool setEnabled)
119 {
120 Enabled = setEnabled;
121 }
122 // Release any connections and resources used by the actor.
123 public abstract void Dispose();
124 // Called when physical parameters (properties set in Bullet) need to be re-applied.
125 public abstract void Refresh();
126 // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
127 // Register a prestep action to restore physical requirements before the next simulation step.
128 public abstract void RemoveBodyDependencies();
129
130}
131}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 90c2d9c..25be416 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -61,6 +61,7 @@ public sealed class BSCharacter : BSPhysObject
61 private OMV.Vector3 _rotationalVelocity; 61 private OMV.Vector3 _rotationalVelocity;
62 private bool _kinematic; 62 private bool _kinematic;
63 private float _buoyancy; 63 private float _buoyancy;
64 private bool _isStationaryStanding; // true is standing on a stationary object
64 65
65 private BSVMotor _velocityMotor; 66 private BSVMotor _velocityMotor;
66 67
@@ -84,6 +85,7 @@ public sealed class BSCharacter : BSPhysObject
84 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 85 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
85 Friction = BSParam.AvatarStandingFriction; 86 Friction = BSParam.AvatarStandingFriction;
86 Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor; 87 Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor;
88 _isStationaryStanding = false;
87 89
88 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 90 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
89 // replace with the default values. 91 // replace with the default values.
@@ -208,6 +210,7 @@ public sealed class BSCharacter : BSPhysObject
208 // The code below uses whether the collider is static or moving to decide whether to zero motion. 210 // The code below uses whether the collider is static or moving to decide whether to zero motion.
209 211
210 _velocityMotor.Step(timeStep); 212 _velocityMotor.Step(timeStep);
213 _isStationaryStanding = false;
211 214
212 // If we're not supposed to be moving, make sure things are zero. 215 // If we're not supposed to be moving, make sure things are zero.
213 if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero) 216 if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero)
@@ -221,6 +224,7 @@ public sealed class BSCharacter : BSPhysObject
221 if (!ColliderIsMoving) 224 if (!ColliderIsMoving)
222 { 225 {
223 DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID); 226 DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
227 _isStationaryStanding = true;
224 ZeroMotion(true /* inTaintTime */); 228 ZeroMotion(true /* inTaintTime */);
225 } 229 }
226 230
@@ -882,7 +886,10 @@ public sealed class BSCharacter : BSPhysObject
882 // the world that things have changed. 886 // the world that things have changed.
883 public override void UpdateProperties(EntityProperties entprop) 887 public override void UpdateProperties(EntityProperties entprop)
884 { 888 {
885 _position = entprop.Position; 889 // Don't change position if standing on a stationary object.
890 if (!_isStationaryStanding)
891 _position = entprop.Position;
892
886 _orientation = entprop.Rotation; 893 _orientation = entprop.Rotation;
887 894
888 // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar 895 // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index b813974..42b5c49 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -85,7 +85,9 @@ public abstract class BSConstraint : IDisposable
85 { 85 {
86 bool ret = false; 86 bool ret = false;
87 if (m_enabled) 87 if (m_enabled)
88 {
88 ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high); 89 ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high);
90 }
89 return ret; 91 return ret;
90 } 92 }
91 93
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
index 476a0e5..d0949f5 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
@@ -97,14 +97,14 @@ public sealed class BSConstraint6Dof : BSConstraint
97 97
98 // A 6 Dof constraint that is fixed in the world and constrained to a on-the-fly created static object 98 // A 6 Dof constraint that is fixed in the world and constrained to a on-the-fly created static object
99 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, Vector3 frameInBloc, Quaternion frameInBrot, 99 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, Vector3 frameInBloc, Quaternion frameInBrot,
100 bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) 100 bool useLinearReferenceFrameB, bool disableCollisionsBetweenLinkedBodies)
101 : base(world) 101 : base(world)
102 { 102 {
103 m_body1 = obj1; 103 m_body1 = obj1;
104 m_body2 = obj1; // Look out for confusion down the road 104 m_body2 = obj1; // Look out for confusion down the road
105 m_constraint = PhysicsScene.PE.Create6DofConstraintFixed(m_world, m_body1, 105 m_constraint = PhysicsScene.PE.Create6DofConstraintFixed(m_world, m_body1,
106 frameInBloc, frameInBrot, 106 frameInBloc, frameInBrot,
107 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); 107 useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies);
108 m_enabled = true; 108 m_enabled = true;
109 world.physicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}", 109 world.physicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}",
110 BSScene.DetailLogZero, world.worldID, obj1.ID, obj1.AddrString); 110 BSScene.DetailLogZero, world.worldID, obj1.ID, obj1.AddrString);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 65df741..0fd1f73 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -40,13 +40,14 @@ using OpenSim.Region.Physics.Manager;
40 40
41namespace OpenSim.Region.Physics.BulletSPlugin 41namespace OpenSim.Region.Physics.BulletSPlugin
42{ 42{
43 public sealed class BSDynamics 43 public sealed class BSDynamics : BSActor
44 { 44 {
45 private static string LogHeader = "[BULLETSIM VEHICLE]"; 45 private static string LogHeader = "[BULLETSIM VEHICLE]";
46 46
47 private BSScene PhysicsScene { get; set; }
48 // the prim this dynamic controller belongs to 47 // the prim this dynamic controller belongs to
49 private BSPrim Prim { get; set; } 48 private BSPrim ControllingPrim { get; set; }
49
50 private bool m_haveRegisteredForSceneEvents;
50 51
51 // mass of the vehicle fetched each time we're calles 52 // mass of the vehicle fetched each time we're calles
52 private float m_vehicleMass; 53 private float m_vehicleMass;
@@ -129,11 +130,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
129 public bool enableAngularDeflection; 130 public bool enableAngularDeflection;
130 public bool enableAngularBanking; 131 public bool enableAngularBanking;
131 132
132 public BSDynamics(BSScene myScene, BSPrim myPrim) 133 public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName)
134 : base(myScene, myPrim, actorName)
133 { 135 {
134 PhysicsScene = myScene; 136 ControllingPrim = myPrim;
135 Prim = myPrim;
136 Type = Vehicle.TYPE_NONE; 137 Type = Vehicle.TYPE_NONE;
138 m_haveRegisteredForSceneEvents = false;
137 SetupVehicleDebugging(); 139 SetupVehicleDebugging();
138 } 140 }
139 141
@@ -155,7 +157,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
155 // Return 'true' if this vehicle is doing vehicle things 157 // Return 'true' if this vehicle is doing vehicle things
156 public bool IsActive 158 public bool IsActive
157 { 159 {
158 get { return (Type != Vehicle.TYPE_NONE && Prim.IsPhysicallyActive); } 160 get { return (Type != Vehicle.TYPE_NONE && ControllingPrim.IsPhysicallyActive); }
159 } 161 }
160 162
161 // Return 'true' if this a vehicle that should be sitting on the ground 163 // Return 'true' if this a vehicle that should be sitting on the ground
@@ -167,7 +169,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
167 #region Vehicle parameter setting 169 #region Vehicle parameter setting
168 public void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 170 public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
169 { 171 {
170 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 172 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
171 switch (pParam) 173 switch (pParam)
172 { 174 {
173 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 175 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@@ -195,7 +197,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
195 break; 197 break;
196 case Vehicle.BUOYANCY: 198 case Vehicle.BUOYANCY:
197 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); 199 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
198 m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); 200 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
199 break; 201 break;
200 case Vehicle.HOVER_EFFICIENCY: 202 case Vehicle.HOVER_EFFICIENCY:
201 m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); 203 m_VhoverEfficiency = ClampInRange(0f, pValue, 1f);
@@ -258,7 +260,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
258 260
259 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) 261 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
260 { 262 {
261 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 263 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
262 switch (pParam) 264 switch (pParam)
263 { 265 {
264 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 266 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@@ -294,7 +296,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
294 296
295 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 297 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
296 { 298 {
297 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 299 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
298 switch (pParam) 300 switch (pParam)
299 { 301 {
300 case Vehicle.REFERENCE_FRAME: 302 case Vehicle.REFERENCE_FRAME:
@@ -308,7 +310,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
308 310
309 internal void ProcessVehicleFlags(int pParam, bool remove) 311 internal void ProcessVehicleFlags(int pParam, bool remove)
310 { 312 {
311 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove); 313 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", ControllingPrim.LocalID, pParam, remove);
312 VehicleFlag parm = (VehicleFlag)pParam; 314 VehicleFlag parm = (VehicleFlag)pParam;
313 if (pParam == -1) 315 if (pParam == -1)
314 m_flags = (VehicleFlag)0; 316 m_flags = (VehicleFlag)0;
@@ -323,7 +325,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
323 325
324 public void ProcessTypeChange(Vehicle pType) 326 public void ProcessTypeChange(Vehicle pType)
325 { 327 {
326 VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType); 328 VDetailLog("{0},ProcessTypeChange,type={1}", ControllingPrim.LocalID, pType);
327 // Set Defaults For Type 329 // Set Defaults For Type
328 Type = pType; 330 Type = pType;
329 switch (pType) 331 switch (pType)
@@ -563,12 +565,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
563 m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, 565 m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale,
564 m_linearMotorDecayTimescale, m_linearFrictionTimescale, 566 m_linearMotorDecayTimescale, m_linearFrictionTimescale,
565 1f); 567 1f);
566 m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 568 m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
567 569
568 m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, 570 m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale,
569 m_angularMotorDecayTimescale, m_angularFrictionTimescale, 571 m_angularMotorDecayTimescale, m_angularFrictionTimescale,
570 1f); 572 1f);
571 m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 573 m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
572 574
573 /* Not implemented 575 /* Not implemented
574 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, 576 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
@@ -578,13 +580,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
578 m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); 580 m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
579 m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 581 m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
580 */ 582 */
583
584 if (this.Type == Vehicle.TYPE_NONE)
585 {
586 UnregisterForSceneEvents();
587 }
588 else
589 {
590 RegisterForSceneEvents();
591 }
581 } 592 }
582 #endregion // Vehicle parameter setting 593 #endregion // Vehicle parameter setting
583 594
584 public void Refresh() 595 // BSActor.Refresh()
596 public override void Refresh()
585 { 597 {
586 // If asking for a refresh, reset the physical parameters before the next simulation step. 598 // If asking for a refresh, reset the physical parameters before the next simulation step.
587 PhysicsScene.PostTaintObject("BSDynamics.Refresh", Prim.LocalID, delegate() 599 m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate()
588 { 600 {
589 SetPhysicalParameters(); 601 SetPhysicalParameters();
590 }); 602 });
@@ -597,49 +609,90 @@ namespace OpenSim.Region.Physics.BulletSPlugin
597 if (IsActive) 609 if (IsActive)
598 { 610 {
599 // Remember the mass so we don't have to fetch it every step 611 // Remember the mass so we don't have to fetch it every step
600 m_vehicleMass = Prim.TotalMass; 612 m_vehicleMass = ControllingPrim.TotalMass;
601 613
602 // Friction affects are handled by this vehicle code 614 // Friction affects are handled by this vehicle code
603 PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction); 615 m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction);
604 PhysicsScene.PE.SetRestitution(Prim.PhysBody, BSParam.VehicleRestitution); 616 m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution);
605 617
606 // Moderate angular movement introduced by Bullet. 618 // Moderate angular movement introduced by Bullet.
607 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. 619 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
608 // Maybe compute linear and angular factor and damping from params. 620 // Maybe compute linear and angular factor and damping from params.
609 PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, BSParam.VehicleAngularDamping); 621 m_physicsScene.PE.SetAngularDamping(ControllingPrim.PhysBody, BSParam.VehicleAngularDamping);
610 PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactor); 622 m_physicsScene.PE.SetLinearFactor(ControllingPrim.PhysBody, BSParam.VehicleLinearFactor);
611 PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactor); 623 m_physicsScene.PE.SetAngularFactorV(ControllingPrim.PhysBody, BSParam.VehicleAngularFactor);
612 624
613 // Vehicles report collision events so we know when it's on the ground 625 // Vehicles report collision events so we know when it's on the ground
614 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 626 m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
615 627
616 Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); 628 ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape, m_vehicleMass);
617 PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia); 629 m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
618 PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); 630 m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
619 631
620 // Set the gravity for the vehicle depending on the buoyancy 632 // Set the gravity for the vehicle depending on the buoyancy
621 // TODO: what should be done if prim and vehicle buoyancy differ? 633 // TODO: what should be done if prim and vehicle buoyancy differ?
622 m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); 634 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
623 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. 635 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
624 PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); 636 m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero);
625 637
626 VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}", 638 VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
627 Prim.LocalID, m_vehicleMass, Prim.Inertia, m_VehicleGravity, 639 ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity,
628 BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution, 640 BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution,
629 BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor 641 BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor
630 ); 642 );
631 } 643 }
632 else 644 else
633 { 645 {
634 if (Prim.PhysBody.HasPhysicalBody) 646 if (ControllingPrim.PhysBody.HasPhysicalBody)
635 PhysicsScene.PE.RemoveFromCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 647 m_physicsScene.PE.RemoveFromCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
636 } 648 }
637 } 649 }
638 650
639 public bool RemoveBodyDependencies(BSPhysObject prim) 651 // BSActor.RemoveBodyDependencies
652 public override void RemoveBodyDependencies()
640 { 653 {
641 Refresh(); 654 Refresh();
642 return IsActive; 655 }
656
657 // BSActor.Release()
658 public override void Dispose()
659 {
660 UnregisterForSceneEvents();
661 Type = Vehicle.TYPE_NONE;
662 Enabled = false;
663 return;
664 }
665
666 private void RegisterForSceneEvents()
667 {
668 if (!m_haveRegisteredForSceneEvents)
669 {
670 m_physicsScene.BeforeStep += this.Step;
671 m_physicsScene.AfterStep += this.PostStep;
672 ControllingPrim.OnPreUpdateProperty += this.PreUpdateProperty;
673 m_haveRegisteredForSceneEvents = true;
674 }
675 }
676
677 private void UnregisterForSceneEvents()
678 {
679 if (m_haveRegisteredForSceneEvents)
680 {
681 m_physicsScene.BeforeStep -= this.Step;
682 m_physicsScene.AfterStep -= this.PostStep;
683 ControllingPrim.OnPreUpdateProperty -= this.PreUpdateProperty;
684 m_haveRegisteredForSceneEvents = false;
685 }
686 }
687
688 private void PreUpdateProperty(ref EntityProperties entprop)
689 {
690 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
691 // TODO: handle physics introduced by Bullet with computed vehicle physics.
692 if (IsActive)
693 {
694 entprop.RotationalVelocity = Vector3.Zero;
695 }
643 } 696 }
644 697
645 #region Known vehicle value functions 698 #region Known vehicle value functions
@@ -686,14 +739,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
686 if (m_knownChanged != 0) 739 if (m_knownChanged != 0)
687 { 740 {
688 if ((m_knownChanged & m_knownChangedPosition) != 0) 741 if ((m_knownChanged & m_knownChangedPosition) != 0)
689 Prim.ForcePosition = m_knownPosition; 742 ControllingPrim.ForcePosition = m_knownPosition;
690 743
691 if ((m_knownChanged & m_knownChangedOrientation) != 0) 744 if ((m_knownChanged & m_knownChangedOrientation) != 0)
692 Prim.ForceOrientation = m_knownOrientation; 745 ControllingPrim.ForceOrientation = m_knownOrientation;
693 746
694 if ((m_knownChanged & m_knownChangedVelocity) != 0) 747 if ((m_knownChanged & m_knownChangedVelocity) != 0)
695 { 748 {
696 Prim.ForceVelocity = m_knownVelocity; 749 ControllingPrim.ForceVelocity = m_knownVelocity;
697 // Fake out Bullet by making it think the velocity is the same as last time. 750 // Fake out Bullet by making it think the velocity is the same as last time.
698 // Bullet does a bunch of smoothing for changing parameters. 751 // Bullet does a bunch of smoothing for changing parameters.
699 // Since the vehicle is demanding this setting, we override Bullet's smoothing 752 // Since the vehicle is demanding this setting, we override Bullet's smoothing
@@ -702,28 +755,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
702 } 755 }
703 756
704 if ((m_knownChanged & m_knownChangedForce) != 0) 757 if ((m_knownChanged & m_knownChangedForce) != 0)
705 Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/); 758 ControllingPrim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/);
706 759
707 if ((m_knownChanged & m_knownChangedForceImpulse) != 0) 760 if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
708 Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/); 761 ControllingPrim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
709 762
710 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) 763 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
711 { 764 {
712 Prim.ForceRotationalVelocity = m_knownRotationalVelocity; 765 ControllingPrim.ForceRotationalVelocity = m_knownRotationalVelocity;
713 // PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); 766 // PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
714 } 767 }
715 768
716 if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0) 769 if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0)
717 Prim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/); 770 ControllingPrim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/);
718 771
719 if ((m_knownChanged & m_knownChangedRotationalForce) != 0) 772 if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
720 { 773 {
721 Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/); 774 ControllingPrim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/);
722 } 775 }
723 776
724 // If we set one of the values (ie, the physics engine didn't do it) we must force 777 // If we set one of the values (ie, the physics engine didn't do it) we must force
725 // an UpdateProperties event to send the changes up to the simulator. 778 // an UpdateProperties event to send the changes up to the simulator.
726 PhysicsScene.PE.PushUpdate(Prim.PhysBody); 779 m_physicsScene.PE.PushUpdate(ControllingPrim.PhysBody);
727 } 780 }
728 m_knownChanged = 0; 781 m_knownChanged = 0;
729 } 782 }
@@ -736,7 +789,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
736 if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos) 789 if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos)
737 { 790 {
738 lastRememberedHeightPos = pos; 791 lastRememberedHeightPos = pos;
739 m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); 792 m_knownTerrainHeight = ControllingPrim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
740 m_knownHas |= m_knownChangedTerrainHeight; 793 m_knownHas |= m_knownChangedTerrainHeight;
741 } 794 }
742 return m_knownTerrainHeight; 795 return m_knownTerrainHeight;
@@ -748,7 +801,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
748 { 801 {
749 if ((m_knownHas & m_knownChangedWaterLevel) == 0) 802 if ((m_knownHas & m_knownChangedWaterLevel) == 0)
750 { 803 {
751 m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); 804 m_knownWaterLevel = ControllingPrim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos);
752 m_knownHas |= m_knownChangedWaterLevel; 805 m_knownHas |= m_knownChangedWaterLevel;
753 } 806 }
754 return (float)m_knownWaterLevel; 807 return (float)m_knownWaterLevel;
@@ -760,7 +813,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
760 { 813 {
761 if ((m_knownHas & m_knownChangedPosition) == 0) 814 if ((m_knownHas & m_knownChangedPosition) == 0)
762 { 815 {
763 m_knownPosition = Prim.ForcePosition; 816 m_knownPosition = ControllingPrim.ForcePosition;
764 m_knownHas |= m_knownChangedPosition; 817 m_knownHas |= m_knownChangedPosition;
765 } 818 }
766 return m_knownPosition; 819 return m_knownPosition;
@@ -779,7 +832,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
779 { 832 {
780 if ((m_knownHas & m_knownChangedOrientation) == 0) 833 if ((m_knownHas & m_knownChangedOrientation) == 0)
781 { 834 {
782 m_knownOrientation = Prim.ForceOrientation; 835 m_knownOrientation = ControllingPrim.ForceOrientation;
783 m_knownHas |= m_knownChangedOrientation; 836 m_knownHas |= m_knownChangedOrientation;
784 } 837 }
785 return m_knownOrientation; 838 return m_knownOrientation;
@@ -798,7 +851,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
798 { 851 {
799 if ((m_knownHas & m_knownChangedVelocity) == 0) 852 if ((m_knownHas & m_knownChangedVelocity) == 0)
800 { 853 {
801 m_knownVelocity = Prim.ForceVelocity; 854 m_knownVelocity = ControllingPrim.ForceVelocity;
802 m_knownHas |= m_knownChangedVelocity; 855 m_knownHas |= m_knownChangedVelocity;
803 } 856 }
804 return m_knownVelocity; 857 return m_knownVelocity;
@@ -839,7 +892,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
839 { 892 {
840 if ((m_knownHas & m_knownChangedRotationalVelocity) == 0) 893 if ((m_knownHas & m_knownChangedRotationalVelocity) == 0)
841 { 894 {
842 m_knownRotationalVelocity = Prim.ForceRotationalVelocity; 895 m_knownRotationalVelocity = ControllingPrim.ForceRotationalVelocity;
843 m_knownHas |= m_knownChangedRotationalVelocity; 896 m_knownHas |= m_knownChangedRotationalVelocity;
844 } 897 }
845 return (Vector3)m_knownRotationalVelocity; 898 return (Vector3)m_knownRotationalVelocity;
@@ -914,11 +967,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
914 // for the physics engine to note the changes so an UpdateProperties event will happen. 967 // for the physics engine to note the changes so an UpdateProperties event will happen.
915 PushKnownChanged(); 968 PushKnownChanged();
916 969
917 if (PhysicsScene.VehiclePhysicalLoggingEnabled) 970 if (m_physicsScene.VehiclePhysicalLoggingEnabled)
918 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); 971 m_physicsScene.PE.DumpRigidBody(m_physicsScene.World, ControllingPrim.PhysBody);
919 972
920 VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}", 973 VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
921 Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); 974 ControllingPrim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
922 } 975 }
923 976
924 // Called after the simulation step 977 // Called after the simulation step
@@ -926,8 +979,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
926 { 979 {
927 if (!IsActive) return; 980 if (!IsActive) return;
928 981
929 if (PhysicsScene.VehiclePhysicalLoggingEnabled) 982 if (m_physicsScene.VehiclePhysicalLoggingEnabled)
930 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); 983 m_physicsScene.PE.DumpRigidBody(m_physicsScene.World, ControllingPrim.PhysBody);
931 } 984 }
932 985
933 // Apply the effect of the linear motor and other linear motions (like hover and float). 986 // Apply the effect of the linear motor and other linear motions (like hover and float).
@@ -967,12 +1020,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
967 VehicleVelocity /= VehicleVelocity.Length(); 1020 VehicleVelocity /= VehicleVelocity.Length();
968 VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; 1021 VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
969 VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}", 1022 VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
970 Prim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity); 1023 ControllingPrim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity);
971 } 1024 }
972 else if (newVelocityLengthSq < 0.001f) 1025 else if (newVelocityLengthSq < 0.001f)
973 VehicleVelocity = Vector3.Zero; 1026 VehicleVelocity = Vector3.Zero;
974 1027
975 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity ); 1028 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.IsColliding, VehicleVelocity );
976 1029
977 } // end MoveLinear() 1030 } // end MoveLinear()
978 1031
@@ -997,7 +1050,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
997 VehicleVelocity += linearMotorVelocityW; 1050 VehicleVelocity += linearMotorVelocityW;
998 1051
999 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}", 1052 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}",
1000 Prim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity); 1053 ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity);
1001 } 1054 }
1002 1055
1003 public void ComputeLinearTerrainHeightCorrection(float pTimestep) 1056 public void ComputeLinearTerrainHeightCorrection(float pTimestep)
@@ -1011,7 +1064,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1011 newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f; 1064 newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f;
1012 VehiclePosition = newPosition; 1065 VehiclePosition = newPosition;
1013 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", 1066 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
1014 Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); 1067 ControllingPrim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
1015 } 1068 }
1016 } 1069 }
1017 1070
@@ -1050,7 +1103,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1050 pos.Z = m_VhoverTargetHeight; 1103 pos.Z = m_VhoverTargetHeight;
1051 VehiclePosition = pos; 1104 VehiclePosition = pos;
1052 1105
1053 VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos); 1106 VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", ControllingPrim.LocalID, pos);
1054 } 1107 }
1055 } 1108 }
1056 else 1109 else
@@ -1079,7 +1132,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1079 */ 1132 */
1080 1133
1081 VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}", 1134 VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}",
1082 Prim.LocalID, VehiclePosition, m_VhoverEfficiency, 1135 ControllingPrim.LocalID, VehiclePosition, m_VhoverEfficiency,
1083 m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, 1136 m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
1084 verticalError, verticalCorrection); 1137 verticalError, verticalCorrection);
1085 } 1138 }
@@ -1124,7 +1177,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1124 { 1177 {
1125 VehiclePosition = pos; 1178 VehiclePosition = pos;
1126 VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", 1179 VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
1127 Prim.LocalID, m_BlockingEndPoint, posChange, pos); 1180 ControllingPrim.LocalID, m_BlockingEndPoint, posChange, pos);
1128 } 1181 }
1129 } 1182 }
1130 return changed; 1183 return changed;
@@ -1164,7 +1217,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1164 1217
1165 // Another approach is to measure if we're going up. If going up and not colliding, 1218 // Another approach is to measure if we're going up. If going up and not colliding,
1166 // the vehicle is in the air. Fix that by pushing down. 1219 // the vehicle is in the air. Fix that by pushing down.
1167 if (!Prim.IsColliding && VehicleVelocity.Z > 0.1) 1220 if (!ControllingPrim.IsColliding && VehicleVelocity.Z > 0.1)
1168 { 1221 {
1169 // Get rid of any of the velocity vector that is pushing us up. 1222 // Get rid of any of the velocity vector that is pushing us up.
1170 float upVelocity = VehicleVelocity.Z; 1223 float upVelocity = VehicleVelocity.Z;
@@ -1186,7 +1239,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1186 } 1239 }
1187 */ 1240 */
1188 VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}", 1241 VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}",
1189 Prim.LocalID, Prim.IsColliding, upVelocity, VehicleVelocity); 1242 ControllingPrim.LocalID, ControllingPrim.IsColliding, upVelocity, VehicleVelocity);
1190 } 1243 }
1191 } 1244 }
1192 } 1245 }
@@ -1196,14 +1249,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1196 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; 1249 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
1197 1250
1198 // Hack to reduce downward force if the vehicle is probably sitting on the ground 1251 // Hack to reduce downward force if the vehicle is probably sitting on the ground
1199 if (Prim.IsColliding && IsGroundVehicle) 1252 if (ControllingPrim.IsColliding && IsGroundVehicle)
1200 appliedGravity *= BSParam.VehicleGroundGravityFudge; 1253 appliedGravity *= BSParam.VehicleGroundGravityFudge;
1201 1254
1202 VehicleAddForce(appliedGravity); 1255 VehicleAddForce(appliedGravity);
1203 1256
1204 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}", 1257 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}",
1205 Prim.LocalID, m_VehicleGravity, 1258 ControllingPrim.LocalID, m_VehicleGravity,
1206 Prim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity); 1259 ControllingPrim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
1207 } 1260 }
1208 1261
1209 // ======================================================================= 1262 // =======================================================================
@@ -1227,11 +1280,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1227 { 1280 {
1228 // The vehicle is not adding anything angular wise. 1281 // The vehicle is not adding anything angular wise.
1229 VehicleRotationalVelocity = Vector3.Zero; 1282 VehicleRotationalVelocity = Vector3.Zero;
1230 VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); 1283 VDetailLog("{0}, MoveAngular,done,zero", ControllingPrim.LocalID);
1231 } 1284 }
1232 else 1285 else
1233 { 1286 {
1234 VDetailLog("{0}, MoveAngular,done,nonZero,angVel={1}", Prim.LocalID, VehicleRotationalVelocity); 1287 VDetailLog("{0}, MoveAngular,done,nonZero,angVel={1}", ControllingPrim.LocalID, VehicleRotationalVelocity);
1235 } 1288 }
1236 1289
1237 // ================================================================== 1290 // ==================================================================
@@ -1262,7 +1315,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1262 torqueFromOffset.Z = 0; 1315 torqueFromOffset.Z = 0;
1263 1316
1264 VehicleAddAngularForce(torqueFromOffset * m_vehicleMass); 1317 VehicleAddAngularForce(torqueFromOffset * m_vehicleMass);
1265 VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); 1318 VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", ControllingPrim.LocalID, torqueFromOffset);
1266 } 1319 }
1267 1320
1268 } 1321 }
@@ -1288,7 +1341,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1288 // } 1341 // }
1289 1342
1290 VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation; 1343 VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation;
1291 VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContributionV); 1344 VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", ControllingPrim.LocalID, angularMotorContributionV);
1292 } 1345 }
1293 1346
1294 // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: 1347 // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
@@ -1334,7 +1387,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1334 VehicleRotationalVelocity += vertContributionV; 1387 VehicleRotationalVelocity += vertContributionV;
1335 1388
1336 VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}", 1389 VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}",
1337 Prim.LocalID, 1390 ControllingPrim.LocalID,
1338 differenceAxis, 1391 differenceAxis,
1339 differenceAngle, 1392 differenceAngle,
1340 correctionRotation, 1393 correctionRotation,
@@ -1433,9 +1486,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1433 VehicleRotationalVelocity += deflectContributionV * VehicleOrientation; 1486 VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
1434 1487
1435 VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", 1488 VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
1436 Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV); 1489 ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV);
1437 VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", 1490 VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}",
1438 Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); 1491 ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale);
1439 } 1492 }
1440 } 1493 }
1441 1494
@@ -1501,7 +1554,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1501 1554
1502 1555
1503 VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", 1556 VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
1504 Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV); 1557 ControllingPrim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV);
1505 } 1558 }
1506 } 1559 }
1507 1560
@@ -1540,7 +1593,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1540 if (rotq != m_rot) 1593 if (rotq != m_rot)
1541 { 1594 {
1542 VehicleOrientation = m_rot; 1595 VehicleOrientation = m_rot;
1543 VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); 1596 VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", ControllingPrim.LocalID, rotq, m_rot);
1544 } 1597 }
1545 1598
1546 } 1599 }
@@ -1554,8 +1607,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1554 // Invoke the detailed logger and output something if it's enabled. 1607 // Invoke the detailed logger and output something if it's enabled.
1555 private void VDetailLog(string msg, params Object[] args) 1608 private void VDetailLog(string msg, params Object[] args)
1556 { 1609 {
1557 if (Prim.PhysicsScene.VehicleLoggingEnabled) 1610 if (ControllingPrim.PhysicsScene.VehicleLoggingEnabled)
1558 Prim.PhysicsScene.DetailLog(msg, args); 1611 ControllingPrim.PhysicsScene.DetailLog(msg, args);
1559 } 1612 }
1560 } 1613 }
1561} 1614}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 6bb88c7..98ea833 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -78,6 +78,9 @@ public abstract class BSPhysObject : PhysicsActor
78 Name = name; // PhysicsActor also has the name of the object. Someday consolidate. 78 Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
79 TypeName = typeName; 79 TypeName = typeName;
80 80
81 // The collection of things that push me around
82 PhysicalActors = new BSActorCollection(PhysicsScene);
83
81 // Initialize variables kept in base. 84 // Initialize variables kept in base.
82 GravModifier = 1.0f; 85 GravModifier = 1.0f;
83 Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); 86 Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
@@ -109,6 +112,10 @@ public abstract class BSPhysObject : PhysicsActor
109 { 112 {
110 UnRegisterAllPreStepActions(); 113 UnRegisterAllPreStepActions();
111 UnRegisterAllPostStepActions(); 114 UnRegisterAllPostStepActions();
115 PhysicsScene.TaintedObject("BSPhysObject.Destroy", delegate()
116 {
117 PhysicalActors.Release();
118 });
112 } 119 }
113 120
114 public BSScene PhysicsScene { get; protected set; } 121 public BSScene PhysicsScene { get; protected set; }
@@ -180,7 +187,7 @@ public abstract class BSPhysObject : PhysicsActor
180 Friction = matAttrib.friction; 187 Friction = matAttrib.friction;
181 Restitution = matAttrib.restitution; 188 Restitution = matAttrib.restitution;
182 Density = matAttrib.density / BSParam.DensityScaleFactor; 189 Density = matAttrib.density / BSParam.DensityScaleFactor;
183 DetailLog("{0},{1}.SetMaterial,Mat={2},frict={3},rest={4},den={5}", LocalID, TypeName, Material, Friction, Restitution, Density); 190 // DetailLog("{0},{1}.SetMaterial,Mat={2},frict={3},rest={4},den={5}", LocalID, TypeName, Material, Friction, Restitution, Density);
184 } 191 }
185 192
186 // Stop all physical motion. 193 // Stop all physical motion.
@@ -230,6 +237,7 @@ public abstract class BSPhysObject : PhysicsActor
230 237
231 public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free. 238 public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free.
232 public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free 239 public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free
240 public readonly String LockedAxisActorName = "BSPrim.LockedAxis";
233 241
234 #region Collisions 242 #region Collisions
235 243
@@ -413,6 +421,9 @@ public abstract class BSPhysObject : PhysicsActor
413 #endregion // Collisions 421 #endregion // Collisions
414 422
415 #region Per Simulation Step actions 423 #region Per Simulation Step actions
424
425 public BSActorCollection PhysicalActors;
426
416 // There are some actions that must be performed for a physical object before each simulation step. 427 // There are some actions that must be performed for a physical object before each simulation step.
417 // These actions are optional so, rather than scanning all the physical objects and asking them 428 // These actions are optional so, rather than scanning all the physical objects and asking them
418 // if they have anything to do, a physical object registers for an event call before the step is performed. 429 // if they have anything to do, a physical object registers for an event call before the step is performed.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 6a5461a..e56276a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -72,7 +72,8 @@ public class BSPrim : BSPhysObject
72 72
73 private int CrossingFailures { get; set; } 73 private int CrossingFailures { get; set; }
74 74
75 public BSDynamics VehicleController { get; private set; } 75 public BSDynamics VehicleActor;
76 public string VehicleActorName = "BasicVehicle";
76 77
77 private BSVMotor _targetMotor; 78 private BSVMotor _targetMotor;
78 private OMV.Vector3 _PIDTarget; 79 private OMV.Vector3 _PIDTarget;
@@ -100,11 +101,12 @@ public class BSPrim : BSPhysObject
100 _isPhysical = pisPhysical; 101 _isPhysical = pisPhysical;
101 _isVolumeDetect = false; 102 _isVolumeDetect = false;
102 103
103 VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness 104 VehicleActor = new BSDynamics(PhysicsScene, this, VehicleActorName);
105 PhysicalActors.Add(VehicleActorName, VehicleActor);
104 106
105 _mass = CalculateMass(); 107 _mass = CalculateMass();
106 108
107 DetailLog("{0},BSPrim.constructor,call", LocalID); 109 // DetailLog("{0},BSPrim.constructor,call", LocalID);
108 // do the actual object creation at taint time 110 // do the actual object creation at taint time
109 PhysicsScene.TaintedObject("BSPrim.create", delegate() 111 PhysicsScene.TaintedObject("BSPrim.create", delegate()
110 { 112 {
@@ -126,7 +128,7 @@ public class BSPrim : BSPhysObject
126 // Undo any vehicle properties 128 // Undo any vehicle properties
127 this.VehicleType = (int)Vehicle.TYPE_NONE; 129 this.VehicleType = (int)Vehicle.TYPE_NONE;
128 130
129 PhysicsScene.TaintedObject("BSPrim.destroy", delegate() 131 PhysicsScene.TaintedObject("BSPrim.Destroy", delegate()
130 { 132 {
131 DetailLog("{0},BSPrim.Destroy,taint,", LocalID); 133 DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
132 // If there are physical body and shape, release my use of same. 134 // If there are physical body and shape, release my use of same.
@@ -257,98 +259,32 @@ public class BSPrim : BSPhysObject
257 }); 259 });
258 } 260 }
259 261
260 bool TryExperimentalLockAxisCode = false;
261 BSConstraint LockAxisConstraint = null;
262 public override void LockAngularMotion(OMV.Vector3 axis) 262 public override void LockAngularMotion(OMV.Vector3 axis)
263 { 263 {
264 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 264 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
265 265
266 // "1" means free, "0" means locked 266 // "1" means free, "0" means locked
267 OMV.Vector3 locking = new OMV.Vector3(1f, 1f, 1f); 267 OMV.Vector3 locking = LockedAxisFree;
268 if (axis.X != 1) locking.X = 0f; 268 if (axis.X != 1) locking.X = 0f;
269 if (axis.Y != 1) locking.Y = 0f; 269 if (axis.Y != 1) locking.Y = 0f;
270 if (axis.Z != 1) locking.Z = 0f; 270 if (axis.Z != 1) locking.Z = 0f;
271 LockedAxis = locking; 271 LockedAxis = locking;
272 272
273 if (TryExperimentalLockAxisCode && LockedAxis != LockedAxisFree) 273 if (LockedAxis != LockedAxisFree)
274 { 274 {
275 // Lock that axis by creating a 6DOF constraint that has one end in the world and
276 // the other in the object.
277 // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817
278 // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380
279
280 PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate() 275 PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
281 { 276 {
282 CleanUpLockAxisPhysicals(true /* inTaintTime */); 277 // If there is not already an axis locker, make one
283 278 if (!PhysicalActors.HasActor(LockedAxisActorName))
284 BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(PhysicsScene.World, PhysBody,
285 OMV.Vector3.Zero, OMV.Quaternion.Inverse(RawOrientation),
286 true /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */);
287 LockAxisConstraint = axisConstrainer;
288 PhysicsScene.Constraints.AddConstraint(LockAxisConstraint);
289
290 // The constraint is tied to the world and oriented to the prim.
291
292 // Free to move linearly
293 OMV.Vector3 linearLow = OMV.Vector3.Zero;
294 OMV.Vector3 linearHigh = PhysicsScene.TerrainManager.DefaultRegionSize;
295 axisConstrainer.SetLinearLimits(linearLow, linearHigh);
296
297 // Angular with some axis locked
298 float f2PI = (float)Math.PI * 2f;
299 OMV.Vector3 angularLow = new OMV.Vector3(-f2PI, -f2PI, -f2PI);
300 OMV.Vector3 angularHigh = new OMV.Vector3(f2PI, f2PI, f2PI);
301 if (LockedAxis.X != 1f)
302 {
303 angularLow.X = 0f;
304 angularHigh.X = 0f;
305 }
306 if (LockedAxis.Y != 1f)
307 {
308 angularLow.Y = 0f;
309 angularHigh.Y = 0f;
310 }
311 if (LockedAxis.Z != 1f)
312 { 279 {
313 angularLow.Z = 0f; 280 DetailLog("{0},BSPrim.LockAngularMotion,taint,registeringLockAxisActor", LocalID);
314 angularHigh.Z = 0f; 281 PhysicalActors.Add(LockedAxisActorName, new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName));
315 } 282 }
316 axisConstrainer.SetAngularLimits(angularLow, angularHigh); 283 UpdatePhysicalParameters();
317
318 DetailLog("{0},BSPrim.LockAngularMotion,create,linLow={1},linHi={2},angLow={3},angHi={4}",
319 LocalID, linearLow, linearHigh, angularLow, angularHigh);
320
321 // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
322 axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
323
324 axisConstrainer.RecomputeConstraintVariables(RawMass);
325 }); 284 });
326 } 285 }
327 else
328 {
329 // Everything seems unlocked
330 CleanUpLockAxisPhysicals(false /* inTaintTime */);
331 }
332
333 return; 286 return;
334 } 287 }
335 // Get rid of any constraint built for LockAxis
336 // Most often the constraint is removed when the constraint collection is cleaned for this prim.
337 private void CleanUpLockAxisPhysicals(bool inTaintTime)
338 {
339 if (LockAxisConstraint != null)
340 {
341 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.CleanUpLockAxisPhysicals", delegate()
342 {
343 if (LockAxisConstraint != null)
344 {
345 PhysicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint);
346 LockAxisConstraint = null;
347 DetailLog("{0},BSPrim.CleanUpLockAxisPhysicals,destroyingConstraint", LocalID);
348 }
349 });
350 }
351 }
352 288
353 public override OMV.Vector3 RawPosition 289 public override OMV.Vector3 RawPosition
354 { 290 {
@@ -604,7 +540,7 @@ public class BSPrim : BSPhysObject
604 540
605 public override int VehicleType { 541 public override int VehicleType {
606 get { 542 get {
607 return (int)VehicleController.Type; // if we are a vehicle, return that type 543 return (int)VehicleActor.Type; // if we are a vehicle, return that type
608 } 544 }
609 set { 545 set {
610 Vehicle type = (Vehicle)value; 546 Vehicle type = (Vehicle)value;
@@ -613,20 +549,8 @@ public class BSPrim : BSPhysObject
613 { 549 {
614 // Done at taint time so we're sure the physics engine is not using the variables 550 // Done at taint time so we're sure the physics engine is not using the variables
615 // Vehicle code changes the parameters for this vehicle type. 551 // Vehicle code changes the parameters for this vehicle type.
616 VehicleController.ProcessTypeChange(type); 552 VehicleActor.ProcessTypeChange(type);
617 ActivateIfPhysical(false); 553 ActivateIfPhysical(false);
618
619 // If an active vehicle, register the vehicle code to be called before each step
620 if (VehicleController.Type == Vehicle.TYPE_NONE)
621 {
622 UnRegisterPreStepAction("BSPrim.Vehicle", LocalID);
623 UnRegisterPostStepAction("BSPrim.Vehicle", LocalID);
624 }
625 else
626 {
627 RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step);
628 RegisterPostStepAction("BSPrim.Vehicle", LocalID, VehicleController.PostStep);
629 }
630 }); 554 });
631 } 555 }
632 } 556 }
@@ -634,7 +558,7 @@ public class BSPrim : BSPhysObject
634 { 558 {
635 PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() 559 PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
636 { 560 {
637 VehicleController.ProcessFloatVehicleParam((Vehicle)param, value); 561 VehicleActor.ProcessFloatVehicleParam((Vehicle)param, value);
638 ActivateIfPhysical(false); 562 ActivateIfPhysical(false);
639 }); 563 });
640 } 564 }
@@ -642,7 +566,7 @@ public class BSPrim : BSPhysObject
642 { 566 {
643 PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() 567 PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
644 { 568 {
645 VehicleController.ProcessVectorVehicleParam((Vehicle)param, value); 569 VehicleActor.ProcessVectorVehicleParam((Vehicle)param, value);
646 ActivateIfPhysical(false); 570 ActivateIfPhysical(false);
647 }); 571 });
648 } 572 }
@@ -650,7 +574,7 @@ public class BSPrim : BSPhysObject
650 { 574 {
651 PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() 575 PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
652 { 576 {
653 VehicleController.ProcessRotationVehicleParam((Vehicle)param, rotation); 577 VehicleActor.ProcessRotationVehicleParam((Vehicle)param, rotation);
654 ActivateIfPhysical(false); 578 ActivateIfPhysical(false);
655 }); 579 });
656 } 580 }
@@ -658,7 +582,7 @@ public class BSPrim : BSPhysObject
658 { 582 {
659 PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate() 583 PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
660 { 584 {
661 VehicleController.ProcessVehicleFlags(param, remove); 585 VehicleActor.ProcessVehicleFlags(param, remove);
662 }); 586 });
663 } 587 }
664 588
@@ -915,7 +839,8 @@ public class BSPrim : BSPhysObject
915 MakeDynamic(IsStatic); 839 MakeDynamic(IsStatic);
916 840
917 // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters) 841 // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
918 VehicleController.Refresh(); 842 VehicleActor.Refresh();
843 PhysicalActors.Refresh();
919 844
920 // Arrange for collision events if the simulator wants them 845 // Arrange for collision events if the simulator wants them
921 EnableCollisions(SubscribedEvents()); 846 EnableCollisions(SubscribedEvents());
@@ -1721,9 +1646,9 @@ public class BSPrim : BSPhysObject
1721 volume *= (profileEnd - profileBegin); 1646 volume *= (profileEnd - profileBegin);
1722 1647
1723 returnMass = Density * BSParam.DensityScaleFactor * volume; 1648 returnMass = Density * BSParam.DensityScaleFactor * volume;
1724 DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass);
1725 1649
1726 returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); 1650 returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
1651 // DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass);
1727 1652
1728 return returnMass; 1653 return returnMass;
1729 }// end CalculateMass 1654 }// end CalculateMass
@@ -1752,7 +1677,8 @@ public class BSPrim : BSPhysObject
1752 1677
1753 protected virtual void RemoveBodyDependencies() 1678 protected virtual void RemoveBodyDependencies()
1754 { 1679 {
1755 VehicleController.RemoveBodyDependencies(this); 1680 VehicleActor.RemoveBodyDependencies();
1681 PhysicalActors.RemoveBodyDependencies();
1756 } 1682 }
1757 1683
1758 // The physics engine says that properties have updated. Update same and inform 1684 // The physics engine says that properties have updated. Update same and inform
@@ -1761,13 +1687,6 @@ public class BSPrim : BSPhysObject
1761 { 1687 {
1762 TriggerPreUpdatePropertyAction(ref entprop); 1688 TriggerPreUpdatePropertyAction(ref entprop);
1763 1689
1764 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
1765 // TODO: handle physics introduced by Bullet with computed vehicle physics.
1766 if (VehicleController.IsActive)
1767 {
1768 entprop.RotationalVelocity = OMV.Vector3.Zero;
1769 }
1770
1771 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG 1690 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1772 1691
1773 // Assign directly to the local variables so the normal set actions do not happen 1692 // Assign directly to the local variables so the normal set actions do not happen
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index e6aefd5..9818b05 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -463,7 +463,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
463 463
464 if (!m_initialized) return null; 464 if (!m_initialized) return null;
465 465
466 DetailLog("{0},BSScene.AddPrimShape,call", localID); 466 // DetailLog("{0},BSScene.AddPrimShape,call", localID);
467 467
468 BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical); 468 BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical);
469 lock (PhysObjects) PhysObjects.Add(localID, prim); 469 lock (PhysObjects) PhysObjects.Add(localID, prim);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
index 33232bd..b040e21 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
@@ -114,9 +114,9 @@ public class BasicVehicles : OpenSimTestCase
114 // Instead the appropriate values are set and calls are made just the parts of the 114 // Instead the appropriate values are set and calls are made just the parts of the
115 // controller we want to exercise. Stepping the physics engine then applies 115 // controller we want to exercise. Stepping the physics engine then applies
116 // the actions of that one feature. 116 // the actions of that one feature.
117 TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency); 117 TestVehicle.VehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
118 TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale); 118 TestVehicle.VehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
119 TestVehicle.VehicleController.enableAngularVerticalAttraction = true; 119 TestVehicle.VehicleActor.enableAngularVerticalAttraction = true;
120 120
121 TestVehicle.IsPhysical = true; 121 TestVehicle.IsPhysical = true;
122 PhysicsScene.ProcessTaints(); 122 PhysicsScene.ProcessTaints();
@@ -124,9 +124,9 @@ public class BasicVehicles : OpenSimTestCase
124 // Step the simulator a bunch of times and vertical attraction should orient the vehicle up 124 // Step the simulator a bunch of times and vertical attraction should orient the vehicle up
125 for (int ii = 0; ii < simSteps; ii++) 125 for (int ii = 0; ii < simSteps; ii++)
126 { 126 {
127 TestVehicle.VehicleController.ForgetKnownVehicleProperties(); 127 TestVehicle.VehicleActor.ForgetKnownVehicleProperties();
128 TestVehicle.VehicleController.ComputeAngularVerticalAttraction(); 128 TestVehicle.VehicleActor.ComputeAngularVerticalAttraction();
129 TestVehicle.VehicleController.PushKnownChanged(); 129 TestVehicle.VehicleActor.PushKnownChanged();
130 130
131 PhysicsScene.Simulate(simulationTimeStep); 131 PhysicsScene.Simulate(simulationTimeStep);
132 } 132 }