diff options
Diffstat (limited to 'OpenSim')
12 files changed, 353 insertions, 96 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 17da0d9..456c8cc 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1568,8 +1568,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1568 | // Here's where you get them. | 1568 | // Here's where you get them. |
1569 | m_AgentControlFlags = flags; | 1569 | m_AgentControlFlags = flags; |
1570 | m_headrotation = agentData.HeadRotation; | 1570 | m_headrotation = agentData.HeadRotation; |
1571 | byte oldState = State; | ||
1571 | State = agentData.State; | 1572 | State = agentData.State; |
1572 | 1573 | ||
1574 | // We need to send this back to the client in order to stop the edit beams | ||
1575 | if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None) | ||
1576 | ControllingClient.SendAgentTerseUpdate(this); | ||
1577 | |||
1578 | |||
1573 | PhysicsActor actor = PhysicsActor; | 1579 | PhysicsActor actor = PhysicsActor; |
1574 | if (actor == null) | 1580 | if (actor == null) |
1575 | { | 1581 | { |
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs index 0cbc5f9..d1d318c 100755 --- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs | |||
@@ -49,10 +49,20 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
50 | private static string LogHeader = "[EXTENDED PHYSICS]"; | 50 | private static string LogHeader = "[EXTENDED PHYSICS]"; |
51 | 51 | ||
52 | // ============================================================= | ||
52 | // Since BulletSim is a plugin, this these values aren't defined easily in one place. | 53 | // Since BulletSim is a plugin, this these values aren't defined easily in one place. |
53 | // This table must coorespond to an identical table in BSScene. | 54 | // This table must correspond to an identical table in BSScene. |
55 | |||
56 | // Per scene functions. See BSScene. | ||
57 | |||
58 | // Per avatar functions. See BSCharacter. | ||
59 | |||
60 | // Per prim functions. See BSPrim. | ||
61 | public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType"; | ||
54 | public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType"; | 62 | public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType"; |
55 | 63 | ||
64 | // ============================================================= | ||
65 | |||
56 | private IConfig Configuration { get; set; } | 66 | private IConfig Configuration { get; set; } |
57 | private bool Enabled { get; set; } | 67 | private bool Enabled { get; set; } |
58 | private Scene BaseScene { get; set; } | 68 | private Scene BaseScene { get; set; } |
@@ -123,6 +133,7 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
123 | 133 | ||
124 | // Register as LSL functions all the [ScriptInvocation] marked methods. | 134 | // Register as LSL functions all the [ScriptInvocation] marked methods. |
125 | Comms.RegisterScriptInvocations(this); | 135 | Comms.RegisterScriptInvocations(this); |
136 | Comms.RegisterConstants(this); | ||
126 | 137 | ||
127 | // When an object is modified, we might need to update its extended physics parameters | 138 | // When an object is modified, we might need to update its extended physics parameters |
128 | BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; | 139 | BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; |
@@ -136,7 +147,6 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
136 | 147 | ||
137 | private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) | 148 | private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) |
138 | { | 149 | { |
139 | throw new NotImplementedException(); | ||
140 | } | 150 | } |
141 | 151 | ||
142 | // Event generated when some property of a prim changes. | 152 | // Event generated when some property of a prim changes. |
@@ -168,9 +178,11 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
168 | public static int PHYS_LINKSET_TYPE_MANUAL = 2; | 178 | public static int PHYS_LINKSET_TYPE_MANUAL = 2; |
169 | 179 | ||
170 | [ScriptInvocation] | 180 | [ScriptInvocation] |
171 | public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) | 181 | public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) |
172 | { | 182 | { |
173 | if (!Enabled) return; | 183 | int ret = -1; |
184 | |||
185 | if (!Enabled) return ret; | ||
174 | 186 | ||
175 | // The part that is requesting the change. | 187 | // The part that is requesting the change. |
176 | SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); | 188 | SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); |
@@ -186,7 +198,7 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
186 | Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; | 198 | Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; |
187 | if (rootPhysActor != null) | 199 | if (rootPhysActor != null) |
188 | { | 200 | { |
189 | rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); | 201 | ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); |
190 | } | 202 | } |
191 | else | 203 | else |
192 | { | 204 | { |
@@ -204,6 +216,49 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
204 | { | 216 | { |
205 | m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); | 217 | m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); |
206 | } | 218 | } |
219 | return ret; | ||
220 | } | ||
221 | |||
222 | [ScriptInvocation] | ||
223 | public int physGetLinksetType(UUID hostID, UUID scriptID) | ||
224 | { | ||
225 | int ret = -1; | ||
226 | |||
227 | if (!Enabled) return ret; | ||
228 | |||
229 | // The part that is requesting the change. | ||
230 | SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); | ||
231 | |||
232 | if (requestingPart != null) | ||
233 | { | ||
234 | // The type is is always on the root of a linkset. | ||
235 | SceneObjectGroup containingGroup = requestingPart.ParentGroup; | ||
236 | SceneObjectPart rootPart = containingGroup.RootPart; | ||
237 | |||
238 | if (rootPart != null) | ||
239 | { | ||
240 | Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; | ||
241 | if (rootPhysActor != null) | ||
242 | { | ||
243 | ret = (int)rootPhysActor.Extension(PhysFunctGetLinksetType); | ||
244 | } | ||
245 | else | ||
246 | { | ||
247 | m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}", | ||
248 | LogHeader, rootPart.Name, hostID); | ||
249 | } | ||
250 | } | ||
251 | else | ||
252 | { | ||
253 | m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}", | ||
254 | LogHeader, requestingPart.Name, hostID); | ||
255 | } | ||
256 | } | ||
257 | else | ||
258 | { | ||
259 | m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); | ||
260 | } | ||
261 | return ret; | ||
207 | } | 262 | } |
208 | } | 263 | } |
209 | } | 264 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 7f94666..3afd52e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -70,6 +70,17 @@ public abstract class BSLinkset | |||
70 | return ret; | 70 | return ret; |
71 | } | 71 | } |
72 | 72 | ||
73 | public class BSLinkInfo | ||
74 | { | ||
75 | public BSPrimLinkable member; | ||
76 | public BSLinkInfo(BSPrimLinkable pMember) | ||
77 | { | ||
78 | member = pMember; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | public LinksetImplementation LinksetImpl { get; protected set; } | ||
83 | |||
73 | public BSPrimLinkable LinksetRoot { get; protected set; } | 84 | public BSPrimLinkable LinksetRoot { get; protected set; } |
74 | 85 | ||
75 | protected BSScene m_physicsScene { get; private set; } | 86 | protected BSScene m_physicsScene { get; private set; } |
@@ -78,7 +89,8 @@ public abstract class BSLinkset | |||
78 | public int LinksetID { get; private set; } | 89 | public int LinksetID { get; private set; } |
79 | 90 | ||
80 | // The children under the root in this linkset. | 91 | // The children under the root in this linkset. |
81 | protected HashSet<BSPrimLinkable> m_children; | 92 | // protected HashSet<BSPrimLinkable> m_children; |
93 | protected Dictionary<BSPrimLinkable, BSLinkInfo> m_children; | ||
82 | 94 | ||
83 | // We lock the diddling of linkset classes to prevent any badness. | 95 | // We lock the diddling of linkset classes to prevent any badness. |
84 | // This locks the modification of the instances of this class. Changes | 96 | // This locks the modification of the instances of this class. Changes |
@@ -109,7 +121,7 @@ public abstract class BSLinkset | |||
109 | m_nextLinksetID = 1; | 121 | m_nextLinksetID = 1; |
110 | m_physicsScene = scene; | 122 | m_physicsScene = scene; |
111 | LinksetRoot = parent; | 123 | LinksetRoot = parent; |
112 | m_children = new HashSet<BSPrimLinkable>(); | 124 | m_children = new Dictionary<BSPrimLinkable, BSLinkInfo>(); |
113 | LinksetMass = parent.RawMass; | 125 | LinksetMass = parent.RawMass; |
114 | Rebuilding = false; | 126 | Rebuilding = false; |
115 | 127 | ||
@@ -170,17 +182,7 @@ public abstract class BSLinkset | |||
170 | bool ret = false; | 182 | bool ret = false; |
171 | lock (m_linksetActivityLock) | 183 | lock (m_linksetActivityLock) |
172 | { | 184 | { |
173 | ret = m_children.Contains(child); | 185 | ret = m_children.ContainsKey(child); |
174 | /* Safer version but the above should work | ||
175 | foreach (BSPrimLinkable bp in m_children) | ||
176 | { | ||
177 | if (child.LocalID == bp.LocalID) | ||
178 | { | ||
179 | ret = true; | ||
180 | break; | ||
181 | } | ||
182 | } | ||
183 | */ | ||
184 | } | 186 | } |
185 | return ret; | 187 | return ret; |
186 | } | 188 | } |
@@ -194,7 +196,24 @@ public abstract class BSLinkset | |||
194 | lock (m_linksetActivityLock) | 196 | lock (m_linksetActivityLock) |
195 | { | 197 | { |
196 | action(LinksetRoot); | 198 | action(LinksetRoot); |
197 | foreach (BSPrimLinkable po in m_children) | 199 | foreach (BSPrimLinkable po in m_children.Keys) |
200 | { | ||
201 | if (action(po)) | ||
202 | break; | ||
203 | } | ||
204 | } | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | // Perform an action on each member of the linkset including root prim. | ||
209 | // Depends on the action on whether this should be done at taint time. | ||
210 | public delegate bool ForEachLinkInfoAction(BSLinkInfo obj); | ||
211 | public virtual bool ForEachLinkInfo(ForEachLinkInfoAction action) | ||
212 | { | ||
213 | bool ret = false; | ||
214 | lock (m_linksetActivityLock) | ||
215 | { | ||
216 | foreach (BSLinkInfo po in m_children.Values) | ||
198 | { | 217 | { |
199 | if (action(po)) | 218 | if (action(po)) |
200 | break; | 219 | break; |
@@ -364,7 +383,7 @@ public abstract class BSLinkset | |||
364 | { | 383 | { |
365 | lock (m_linksetActivityLock) | 384 | lock (m_linksetActivityLock) |
366 | { | 385 | { |
367 | foreach (BSPrimLinkable bp in m_children) | 386 | foreach (BSPrimLinkable bp in m_children.Keys) |
368 | { | 387 | { |
369 | mass += bp.RawMass; | 388 | mass += bp.RawMass; |
370 | } | 389 | } |
@@ -382,7 +401,7 @@ public abstract class BSLinkset | |||
382 | com = LinksetRoot.Position * LinksetRoot.RawMass; | 401 | com = LinksetRoot.Position * LinksetRoot.RawMass; |
383 | float totalMass = LinksetRoot.RawMass; | 402 | float totalMass = LinksetRoot.RawMass; |
384 | 403 | ||
385 | foreach (BSPrimLinkable bp in m_children) | 404 | foreach (BSPrimLinkable bp in m_children.Keys) |
386 | { | 405 | { |
387 | com += bp.Position * bp.RawMass; | 406 | com += bp.Position * bp.RawMass; |
388 | totalMass += bp.RawMass; | 407 | totalMass += bp.RawMass; |
@@ -401,7 +420,7 @@ public abstract class BSLinkset | |||
401 | { | 420 | { |
402 | com = LinksetRoot.Position; | 421 | com = LinksetRoot.Position; |
403 | 422 | ||
404 | foreach (BSPrimLinkable bp in m_children) | 423 | foreach (BSPrimLinkable bp in m_children.Keys) |
405 | { | 424 | { |
406 | com += bp.Position; | 425 | com += bp.Position; |
407 | } | 426 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 6359046..085d195 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -42,6 +42,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
42 | public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) | 42 | public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) |
43 | : base(scene, parent) | 43 | : base(scene, parent) |
44 | { | 44 | { |
45 | LinksetImpl = LinksetImplementation.Compound; | ||
45 | } | 46 | } |
46 | 47 | ||
47 | // ================================================================ | 48 | // ================================================================ |
@@ -257,7 +258,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
257 | { | 258 | { |
258 | if (!HasChild(child)) | 259 | if (!HasChild(child)) |
259 | { | 260 | { |
260 | m_children.Add(child); | 261 | m_children.Add(child, new BSLinkInfo(child)); |
261 | 262 | ||
262 | DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); | 263 | DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); |
263 | 264 | ||
@@ -353,7 +354,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
353 | 354 | ||
354 | // Add the shapes of all the components of the linkset | 355 | // Add the shapes of all the components of the linkset |
355 | int memberIndex = 1; | 356 | int memberIndex = 1; |
356 | ForEachMember(delegate(BSPrimLinkable cPrim) | 357 | ForEachMember((cPrim) => |
357 | { | 358 | { |
358 | if (IsRoot(cPrim)) | 359 | if (IsRoot(cPrim)) |
359 | { | 360 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index f17d698..4bac222 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | |||
@@ -36,8 +36,78 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
36 | { | 36 | { |
37 | // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; | 37 | // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; |
38 | 38 | ||
39 | public class BSLinkInfoConstraint : BSLinkInfo | ||
40 | { | ||
41 | public ConstraintType constraintType; | ||
42 | public BSConstraint constraint; | ||
43 | public OMV.Vector3 linearLimitLow; | ||
44 | public OMV.Vector3 linearLimitHigh; | ||
45 | public OMV.Vector3 angularLimitLow; | ||
46 | public OMV.Vector3 angularLimitHigh; | ||
47 | public bool useFrameOffset; | ||
48 | public bool enableTransMotor; | ||
49 | public float transMotorMaxVel; | ||
50 | public float transMotorMaxForce; | ||
51 | public float cfm; | ||
52 | public float erp; | ||
53 | public float solverIterations; | ||
54 | |||
55 | public BSLinkInfoConstraint(BSPrimLinkable pMember) | ||
56 | : base(pMember) | ||
57 | { | ||
58 | constraint = null; | ||
59 | ResetToFixedConstraint(); | ||
60 | } | ||
61 | |||
62 | // Set all the parameters for this constraint to a fixed, non-movable constraint. | ||
63 | public void ResetToFixedConstraint() | ||
64 | { | ||
65 | constraintType = ConstraintType.D6_CONSTRAINT_TYPE; | ||
66 | linearLimitLow = OMV.Vector3.Zero; | ||
67 | linearLimitHigh = OMV.Vector3.Zero; | ||
68 | angularLimitLow = OMV.Vector3.Zero; | ||
69 | angularLimitHigh = OMV.Vector3.Zero; | ||
70 | useFrameOffset = BSParam.LinkConstraintUseFrameOffset; | ||
71 | enableTransMotor = BSParam.LinkConstraintEnableTransMotor; | ||
72 | transMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel; | ||
73 | transMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce; | ||
74 | cfm = BSParam.LinkConstraintCFM; | ||
75 | erp = BSParam.LinkConstraintERP; | ||
76 | solverIterations = BSParam.LinkConstraintSolverIterations; | ||
77 | } | ||
78 | |||
79 | // Given a constraint, apply the current constraint parameters to same. | ||
80 | public void SetConstraintParameters(BSConstraint constrain) | ||
81 | { | ||
82 | switch (constraintType) | ||
83 | { | ||
84 | case ConstraintType.D6_CONSTRAINT_TYPE: | ||
85 | BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; | ||
86 | if (constrain6dof != null) | ||
87 | { | ||
88 | // zero linear and angular limits makes the objects unable to move in relation to each other | ||
89 | constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh); | ||
90 | constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh); | ||
91 | |||
92 | // tweek the constraint to increase stability | ||
93 | constrain6dof.UseFrameOffset(useFrameOffset); | ||
94 | constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce); | ||
95 | constrain6dof.SetCFMAndERP(cfm, erp); | ||
96 | if (solverIterations != 0f) | ||
97 | { | ||
98 | constrain6dof.SetSolverIterations(solverIterations); | ||
99 | } | ||
100 | } | ||
101 | break; | ||
102 | default: | ||
103 | break; | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | |||
39 | public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) | 108 | public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) |
40 | { | 109 | { |
110 | LinksetImpl = LinksetImplementation.Constraint; | ||
41 | } | 111 | } |
42 | 112 | ||
43 | // When physical properties are changed the linkset needs to recalculate | 113 | // When physical properties are changed the linkset needs to recalculate |
@@ -142,7 +212,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
142 | { | 212 | { |
143 | if (!HasChild(child)) | 213 | if (!HasChild(child)) |
144 | { | 214 | { |
145 | m_children.Add(child); | 215 | m_children.Add(child, new BSLinkInfoConstraint(child)); |
146 | 216 | ||
147 | DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); | 217 | DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); |
148 | 218 | ||
@@ -190,73 +260,74 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
190 | } | 260 | } |
191 | 261 | ||
192 | // Create a static constraint between the two passed objects | 262 | // Create a static constraint between the two passed objects |
193 | private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) | 263 | private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li) |
194 | { | 264 | { |
265 | BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint; | ||
266 | if (liConstraint == null) | ||
267 | return null; | ||
268 | |||
195 | // Zero motion for children so they don't interpolate | 269 | // Zero motion for children so they don't interpolate |
196 | childPrim.ZeroMotion(true); | 270 | li.member.ZeroMotion(true); |
197 | |||
198 | // Relative position normalized to the root prim | ||
199 | // Essentually a vector pointing from center of rootPrim to center of childPrim | ||
200 | OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position; | ||
201 | |||
202 | // real world coordinate of midpoint between the two objects | ||
203 | OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); | ||
204 | |||
205 | DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", | ||
206 | rootPrim.LocalID, | ||
207 | rootPrim.LocalID, rootPrim.PhysBody.AddrString, | ||
208 | childPrim.LocalID, childPrim.PhysBody.AddrString, | ||
209 | rootPrim.Position, childPrim.Position, midPoint); | ||
210 | |||
211 | // create a constraint that allows no freedom of movement between the two objects | ||
212 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | ||
213 | |||
214 | BSConstraint6Dof constrain = new BSConstraint6Dof( | ||
215 | m_physicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true ); | ||
216 | // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); | ||
217 | |||
218 | /* NOTE: below is an attempt to build constraint with full frame computation, etc. | ||
219 | * Using the midpoint is easier since it lets the Bullet code manipulate the transforms | ||
220 | * of the objects. | ||
221 | * Code left for future programmers. | ||
222 | // ================================================================================== | ||
223 | // relative position normalized to the root prim | ||
224 | OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); | ||
225 | OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; | ||
226 | |||
227 | // relative rotation of the child to the parent | ||
228 | OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; | ||
229 | OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); | ||
230 | |||
231 | DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); | ||
232 | BS6DofConstraint constrain = new BS6DofConstraint( | ||
233 | PhysicsScene.World, rootPrim.Body, childPrim.Body, | ||
234 | OMV.Vector3.Zero, | ||
235 | OMV.Quaternion.Inverse(rootPrim.Orientation), | ||
236 | OMV.Vector3.Zero, | ||
237 | OMV.Quaternion.Inverse(childPrim.Orientation), | ||
238 | true, | ||
239 | true | ||
240 | ); | ||
241 | // ================================================================================== | ||
242 | */ | ||
243 | 271 | ||
244 | m_physicsScene.Constraints.AddConstraint(constrain); | 272 | BSConstraint constrain = null; |
245 | 273 | ||
246 | // zero linear and angular limits makes the objects unable to move in relation to each other | 274 | switch (liConstraint.constraintType) |
247 | constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||
248 | constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||
249 | |||
250 | // tweek the constraint to increase stability | ||
251 | constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset); | ||
252 | constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor, | ||
253 | BSParam.LinkConstraintTransMotorMaxVel, | ||
254 | BSParam.LinkConstraintTransMotorMaxForce); | ||
255 | constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); | ||
256 | if (BSParam.LinkConstraintSolverIterations != 0f) | ||
257 | { | 275 | { |
258 | constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); | 276 | case ConstraintType.D6_CONSTRAINT_TYPE: |
277 | // Relative position normalized to the root prim | ||
278 | // Essentually a vector pointing from center of rootPrim to center of li.member | ||
279 | OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position; | ||
280 | |||
281 | // real world coordinate of midpoint between the two objects | ||
282 | OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); | ||
283 | |||
284 | DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", | ||
285 | rootPrim.LocalID, | ||
286 | rootPrim.LocalID, rootPrim.PhysBody.AddrString, | ||
287 | liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString, | ||
288 | rootPrim.Position, liConstraint.member.Position, midPoint); | ||
289 | |||
290 | // create a constraint that allows no freedom of movement between the two objects | ||
291 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | ||
292 | |||
293 | constrain = new BSConstraint6Dof( | ||
294 | m_physicsScene.World, rootPrim.PhysBody, liConstraint.member.PhysBody, midPoint, true, true ); | ||
295 | |||
296 | /* NOTE: below is an attempt to build constraint with full frame computation, etc. | ||
297 | * Using the midpoint is easier since it lets the Bullet code manipulate the transforms | ||
298 | * of the objects. | ||
299 | * Code left for future programmers. | ||
300 | // ================================================================================== | ||
301 | // relative position normalized to the root prim | ||
302 | OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); | ||
303 | OMV.Vector3 childRelativePosition = (liConstraint.member.Position - rootPrim.Position) * invThisOrientation; | ||
304 | |||
305 | // relative rotation of the child to the parent | ||
306 | OMV.Quaternion childRelativeRotation = invThisOrientation * liConstraint.member.Orientation; | ||
307 | OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); | ||
308 | |||
309 | DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, liConstraint.member.LocalID); | ||
310 | constrain = new BS6DofConstraint( | ||
311 | PhysicsScene.World, rootPrim.Body, liConstraint.member.Body, | ||
312 | OMV.Vector3.Zero, | ||
313 | OMV.Quaternion.Inverse(rootPrim.Orientation), | ||
314 | OMV.Vector3.Zero, | ||
315 | OMV.Quaternion.Inverse(liConstraint.member.Orientation), | ||
316 | true, | ||
317 | true | ||
318 | ); | ||
319 | // ================================================================================== | ||
320 | */ | ||
321 | |||
322 | break; | ||
323 | default: | ||
324 | break; | ||
259 | } | 325 | } |
326 | |||
327 | liConstraint.SetConstraintParameters(constrain); | ||
328 | |||
329 | m_physicsScene.Constraints.AddConstraint(constrain); | ||
330 | |||
260 | return constrain; | 331 | return constrain; |
261 | } | 332 | } |
262 | 333 | ||
@@ -317,23 +388,24 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
317 | return; // Note the 'finally' clause at the botton which will get executed. | 388 | return; // Note the 'finally' clause at the botton which will get executed. |
318 | } | 389 | } |
319 | 390 | ||
320 | foreach (BSPrimLinkable child in m_children) | 391 | ForEachLinkInfo((li) => |
321 | { | 392 | { |
322 | // A child in the linkset physically shows the mass of the whole linkset. | 393 | // A child in the linkset physically shows the mass of the whole linkset. |
323 | // This allows Bullet to apply enough force on the child to move the whole linkset. | 394 | // This allows Bullet to apply enough force on the child to move the whole linkset. |
324 | // (Also do the mass stuff before recomputing the constraint so mass is not zero.) | 395 | // (Also do the mass stuff before recomputing the constraint so mass is not zero.) |
325 | child.UpdatePhysicalMassProperties(linksetMass, true); | 396 | li.member.UpdatePhysicalMassProperties(linksetMass, true); |
326 | 397 | ||
327 | BSConstraint constrain; | 398 | BSConstraint constrain; |
328 | if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) | 399 | if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, li.member.PhysBody, out constrain)) |
329 | { | 400 | { |
330 | // If constraint doesn't exist yet, create it. | 401 | // If constraint doesn't exist yet, create it. |
331 | constrain = BuildConstraint(LinksetRoot, child); | 402 | constrain = BuildConstraint(LinksetRoot, li); |
332 | } | 403 | } |
333 | constrain.RecomputeConstraintVariables(linksetMass); | 404 | constrain.RecomputeConstraintVariables(linksetMass); |
334 | 405 | ||
335 | // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG | 406 | // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG |
336 | } | 407 | return false; // 'false' says to keep processing other members |
408 | }); | ||
337 | } | 409 | } |
338 | finally | 410 | finally |
339 | { | 411 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index e92a1d2..a0b6abc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -1541,6 +1541,50 @@ public class BSPrim : BSPhysObject | |||
1541 | PhysicalActors.RemoveDependencies(); | 1541 | PhysicalActors.RemoveDependencies(); |
1542 | } | 1542 | } |
1543 | 1543 | ||
1544 | #region Extension | ||
1545 | public override object Extension(string pFunct, params object[] pParams) | ||
1546 | { | ||
1547 | object ret = null; | ||
1548 | switch (pFunct) | ||
1549 | { | ||
1550 | case BSScene.PhysFunctGetLinksetType: | ||
1551 | { | ||
1552 | BSPrimLinkable myHandle = this as BSPrimLinkable; | ||
1553 | if (myHandle != null) | ||
1554 | { | ||
1555 | ret = (object)myHandle.LinksetType; | ||
1556 | } | ||
1557 | m_log.DebugFormat("{0} Extension.physGetLinksetType, type={1}", LogHeader, ret); | ||
1558 | break; | ||
1559 | } | ||
1560 | case BSScene.PhysFunctSetLinksetType: | ||
1561 | { | ||
1562 | if (pParams.Length > 0) | ||
1563 | { | ||
1564 | BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[0]; | ||
1565 | BSPrimLinkable myHandle = this as BSPrimLinkable; | ||
1566 | if (myHandle != null && myHandle.Linkset.IsRoot(myHandle)) | ||
1567 | { | ||
1568 | PhysScene.TaintedObject("BSPrim.PhysFunctSetLinksetType", delegate() | ||
1569 | { | ||
1570 | // Cause the linkset type to change | ||
1571 | m_log.DebugFormat("{0} Extension.physSetLinksetType, oldType={1}, newType={2}", | ||
1572 | LogHeader, myHandle.Linkset.LinksetImpl, linksetType); | ||
1573 | myHandle.ConvertLinkset(linksetType); | ||
1574 | }); | ||
1575 | } | ||
1576 | ret = (object)(int)linksetType; | ||
1577 | } | ||
1578 | break; | ||
1579 | } | ||
1580 | default: | ||
1581 | ret = base.Extension(pFunct, pParams); | ||
1582 | break; | ||
1583 | } | ||
1584 | return ret; | ||
1585 | } | ||
1586 | #endregion // Extension | ||
1587 | |||
1544 | // The physics engine says that properties have updated. Update same and inform | 1588 | // The physics engine says that properties have updated. Update same and inform |
1545 | // the world that things have changed. | 1589 | // the world that things have changed. |
1546 | // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims. | 1590 | // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims. |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 2f392da..7179a6d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs | |||
@@ -233,5 +233,46 @@ public class BSPrimLinkable : BSPrimDisplaced | |||
233 | base.HasSomeCollision = value; | 233 | base.HasSomeCollision = value; |
234 | } | 234 | } |
235 | } | 235 | } |
236 | |||
237 | // Convert the existing linkset of this prim into a new type. | ||
238 | public bool ConvertLinkset(BSLinkset.LinksetImplementation newType) | ||
239 | { | ||
240 | bool ret = false; | ||
241 | if (LinksetType != newType) | ||
242 | { | ||
243 | // Set the implementation type first so the call to BSLinkset.Factory gets the new type. | ||
244 | this.LinksetType = newType; | ||
245 | |||
246 | BSLinkset oldLinkset = this.Linkset; | ||
247 | BSLinkset newLinkset = BSLinkset.Factory(PhysScene, this); | ||
248 | |||
249 | this.Linkset = newLinkset; | ||
250 | |||
251 | // Pick up any physical dependencies this linkset might have in the physics engine. | ||
252 | oldLinkset.RemoveDependencies(this); | ||
253 | |||
254 | // Create a list of the children (mainly because can't interate through a list that's changing) | ||
255 | List<BSPrimLinkable> children = new List<BSPrimLinkable>(); | ||
256 | oldLinkset.ForEachMember((child) => | ||
257 | { | ||
258 | if (!oldLinkset.IsRoot(child)) | ||
259 | children.Add(child); | ||
260 | return false; // 'false' says to continue to next member | ||
261 | }); | ||
262 | |||
263 | // Remove the children from the old linkset and add to the new (will be a new instance from the factory) | ||
264 | foreach (BSPrimLinkable child in children) | ||
265 | { | ||
266 | oldLinkset.RemoveMeFromLinkset(child); | ||
267 | newLinkset.AddMeToLinkset(child); | ||
268 | child.Linkset = newLinkset; | ||
269 | } | ||
270 | |||
271 | // Force the shape and linkset to get reconstructed | ||
272 | newLinkset.Refresh(this); | ||
273 | this.ForceBodyShapeRebuild(true /* inTaintTime */); | ||
274 | } | ||
275 | return ret; | ||
276 | } | ||
236 | } | 277 | } |
237 | } | 278 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 41aca3b..79ac5a5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -862,6 +862,23 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
862 | 862 | ||
863 | public override bool IsThreaded { get { return false; } } | 863 | public override bool IsThreaded { get { return false; } } |
864 | 864 | ||
865 | #region Extensions | ||
866 | // ============================================================= | ||
867 | // Per scene functions. See below. | ||
868 | |||
869 | // Per avatar functions. See BSCharacter. | ||
870 | |||
871 | // Per prim functions. See BSPrim. | ||
872 | public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType"; | ||
873 | public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType"; | ||
874 | // ============================================================= | ||
875 | |||
876 | public override object Extension(string pFunct, params object[] pParams) | ||
877 | { | ||
878 | return base.Extension(pFunct, pParams); | ||
879 | } | ||
880 | #endregion // Extensions | ||
881 | |||
865 | #region Taints | 882 | #region Taints |
866 | // The simulation execution order is: | 883 | // The simulation execution order is: |
867 | // Simulate() | 884 | // Simulate() |
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 2500f27..1750853 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs | |||
@@ -317,7 +317,8 @@ namespace OpenSim.Region.Physics.Manager | |||
317 | // Extendable interface for new, physics engine specific operations | 317 | // Extendable interface for new, physics engine specific operations |
318 | public virtual object Extension(string pFunct, params object[] pParams) | 318 | public virtual object Extension(string pFunct, params object[] pParams) |
319 | { | 319 | { |
320 | throw new NotImplementedException(); | 320 | // A NOP of the physics engine does not implement this feature |
321 | return null; | ||
321 | } | 322 | } |
322 | } | 323 | } |
323 | 324 | ||
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 07a1d36..c93206d 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs | |||
@@ -338,7 +338,8 @@ namespace OpenSim.Region.Physics.Manager | |||
338 | // Extendable interface for new, physics engine specific operations | 338 | // Extendable interface for new, physics engine specific operations |
339 | public virtual object Extension(string pFunct, params object[] pParams) | 339 | public virtual object Extension(string pFunct, params object[] pParams) |
340 | { | 340 | { |
341 | throw new NotImplementedException(); | 341 | // A NOP if the extension thing is not implemented by the physics engine |
342 | return null; | ||
342 | } | 343 | } |
343 | } | 344 | } |
344 | } | 345 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 21bae27..92dd813 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs | |||
@@ -319,7 +319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
319 | 319 | ||
320 | object[] convertedParms = new object[parms.Length]; | 320 | object[] convertedParms = new object[parms.Length]; |
321 | for (int i = 0; i < parms.Length; i++) | 321 | for (int i = 0; i < parms.Length; i++) |
322 | convertedParms[i] = ConvertFromLSL(parms[i],signature[i], fname); | 322 | convertedParms[i] = ConvertFromLSL(parms[i], signature[i], fname); |
323 | 323 | ||
324 | // now call the function, the contract with the function is that it will always return | 324 | // now call the function, the contract with the function is that it will always return |
325 | // non-null but don't trust it completely | 325 | // non-null but don't trust it completely |
@@ -444,7 +444,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
444 | } | 444 | } |
445 | } | 445 | } |
446 | 446 | ||
447 | MODError(String.Format("{1}: parameter type mismatch; expecting {0}",type.Name, fname)); | 447 | MODError(String.Format("{0}: parameter type mismatch; expecting {1}, type(parm)={2}", fname, type.Name, lslparm.GetType())); |
448 | return null; | 448 | return null; |
449 | } | 449 | } |
450 | 450 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 9e32f40..6aa717d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs | |||
@@ -937,7 +937,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
937 | { | 937 | { |
938 | string retval = null; | 938 | string retval = null; |
939 | if (value is int) | 939 | if (value is int) |
940 | retval = ((int)value).ToString(); | 940 | retval = String.Format("new LSL_Types.LSLInteger({0})",((int)value).ToString()); |
941 | else if (value is float) | 941 | else if (value is float) |
942 | retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString()); | 942 | retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString()); |
943 | else if (value is string) | 943 | else if (value is string) |