aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorDiva Canto2015-01-02 09:18:05 -0800
committerDiva Canto2015-01-02 09:18:05 -0800
commit63e771b593a887e043b527f1254f488b4df2ad26 (patch)
treefd0e2ff23c6c832df257260567540a51097329cb /OpenSim
parentSwitched mautil.exe with another that has a bug fix for this bug report: http... (diff)
parentFix cut-and-paste error that made StatsManager web fetch queries (diff)
downloadopensim-SC_OLD-63e771b593a887e043b527f1254f488b4df2ad26.zip
opensim-SC_OLD-63e771b593a887e043b527f1254f488b4df2ad26.tar.gz
opensim-SC_OLD-63e771b593a887e043b527f1254f488b4df2ad26.tar.bz2
opensim-SC_OLD-63e771b593a887e043b527f1254f488b4df2ad26.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/Monitoring/StatsManager.cs2
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs98
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs121
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs5
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs13
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs339
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs67
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs111
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs19
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs204
10 files changed, 869 insertions, 110 deletions
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 0bac247..3136ee8 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -307,7 +307,7 @@ namespace OpenSim.Framework.Monitoring
307 307
308 if (request.ContainsKey("cat")) pCategoryName = request["cat"].ToString(); 308 if (request.ContainsKey("cat")) pCategoryName = request["cat"].ToString();
309 if (request.ContainsKey("cont")) pContainerName = request["cat"].ToString(); 309 if (request.ContainsKey("cont")) pContainerName = request["cat"].ToString();
310 if (request.ContainsKey("stat")) pStatName = request["cat"].ToString(); 310 if (request.ContainsKey("stat")) pStatName = request["stat"].ToString();
311 311
312 string strOut = StatsManager.GetStatsAsOSDMap(pCategoryName, pContainerName, pStatName).ToString(); 312 string strOut = StatsManager.GetStatsAsOSDMap(pCategoryName, pContainerName, pStatName).ToString();
313 313
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
index 9daf9d7..ff4afbf 100755
--- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
@@ -66,6 +66,7 @@ public class ExtendedPhysics : INonSharedRegionModule
66 public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType"; 66 public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType";
67 public const string PhysFunctGetLinkType = "BulletSim.GetLinkType"; 67 public const string PhysFunctGetLinkType = "BulletSim.GetLinkType";
68 public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams"; 68 public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams";
69 public const string PhysFunctAxisLockLimits = "BulletSim.AxisLockLimits";
69 70
70 // ============================================================= 71 // =============================================================
71 72
@@ -176,6 +177,71 @@ public class ExtendedPhysics : INonSharedRegionModule
176 return ret; 177 return ret;
177 } 178 }
178 179
180 // Code for specifying params.
181 // The choice if 14700 is arbitrary and only serves to catch parameter code misuse.
182 [ScriptConstant]
183 public const int PHYS_AXIS_LOCK_LINEAR = 14700;
184 [ScriptConstant]
185 public const int PHYS_AXIS_LOCK_LINEAR_X = 14701;
186 [ScriptConstant]
187 public const int PHYS_AXIS_LIMIT_LINEAR_X = 14702;
188 [ScriptConstant]
189 public const int PHYS_AXIS_LOCK_LINEAR_Y = 14703;
190 [ScriptConstant]
191 public const int PHYS_AXIS_LIMIT_LINEAR_Y = 14704;
192 [ScriptConstant]
193 public const int PHYS_AXIS_LOCK_LINEAR_Z = 14705;
194 [ScriptConstant]
195 public const int PHYS_AXIS_LIMIT_LINEAR_Z = 14706;
196 [ScriptConstant]
197 public const int PHYS_AXIS_LOCK_ANGULAR = 14707;
198 [ScriptConstant]
199 public const int PHYS_AXIS_LOCK_ANGULAR_X = 14708;
200 [ScriptConstant]
201 public const int PHYS_AXIS_LIMIT_ANGULAR_X = 14709;
202 [ScriptConstant]
203 public const int PHYS_AXIS_LOCK_ANGULAR_Y = 14710;
204 [ScriptConstant]
205 public const int PHYS_AXIS_LIMIT_ANGULAR_Y = 14711;
206 [ScriptConstant]
207 public const int PHYS_AXIS_LOCK_ANGULAR_Z = 14712;
208 [ScriptConstant]
209 public const int PHYS_AXIS_LIMIT_ANGULAR_Z = 14713;
210 [ScriptConstant]
211 public const int PHYS_AXIS_UNLOCK_LINEAR = 14714;
212 [ScriptConstant]
213 public const int PHYS_AXIS_UNLOCK_LINEAR_X = 14715;
214 [ScriptConstant]
215 public const int PHYS_AXIS_UNLOCK_LINEAR_Y = 14716;
216 [ScriptConstant]
217 public const int PHYS_AXIS_UNLOCK_LINEAR_Z = 14717;
218 [ScriptConstant]
219 public const int PHYS_AXIS_UNLOCK_ANGULAR = 14718;
220 [ScriptConstant]
221 public const int PHYS_AXIS_UNLOCK_ANGULAR_X = 14719;
222 [ScriptConstant]
223 public const int PHYS_AXIS_UNLOCK_ANGULAR_Y = 14720;
224 [ScriptConstant]
225 public const int PHYS_AXIS_UNLOCK_ANGULAR_Z = 14721;
226 [ScriptConstant]
227 public const int PHYS_AXIS_UNLOCK = 14722;
228 // physAxisLockLimits()
229 [ScriptInvocation]
230 public int physAxisLock(UUID hostID, UUID scriptID, object[] parms)
231 {
232 int ret = -1;
233 if (!Enabled) return ret;
234
235 PhysicsActor rootPhysActor;
236 if (GetRootPhysActor(hostID, out rootPhysActor))
237 {
238 object[] parms2 = AddToBeginningOfArray(rootPhysActor, null, parms);
239 ret = MakeIntError(rootPhysActor.Extension(PhysFunctAxisLockLimits, parms2));
240 }
241
242 return ret;
243 }
244
179 [ScriptConstant] 245 [ScriptConstant]
180 public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0; 246 public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0;
181 [ScriptConstant] 247 [ScriptConstant]
@@ -187,7 +253,6 @@ public class ExtendedPhysics : INonSharedRegionModule
187 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) 253 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
188 { 254 {
189 int ret = -1; 255 int ret = -1;
190
191 if (!Enabled) return ret; 256 if (!Enabled) return ret;
192 257
193 // The part that is requesting the change. 258 // The part that is requesting the change.
@@ -259,34 +324,11 @@ public class ExtendedPhysics : INonSharedRegionModule
259 int ret = -1; 324 int ret = -1;
260 if (!Enabled) return ret; 325 if (!Enabled) return ret;
261 326
262 // The part that is requesting the change. 327 PhysicsActor rootPhysActor;
263 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); 328 if (GetRootPhysActor(hostID, out rootPhysActor))
264
265 if (requestingPart != null)
266 { 329 {
267 // The type is is always on the root of a linkset. 330 object[] parms2 = { rootPhysActor, null };
268 SceneObjectGroup containingGroup = requestingPart.ParentGroup; 331 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2));
269 SceneObjectPart rootPart = containingGroup.RootPart;
270
271 if (rootPart != null)
272 {
273 PhysicsActor rootPhysActor = rootPart.PhysActor;
274 if (rootPhysActor != null)
275 {
276 object[] parms2 = { rootPhysActor, null };
277 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2));
278 }
279 else
280 {
281 m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
282 LogHeader, rootPart.Name, hostID);
283 }
284 }
285 else
286 {
287 m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
288 LogHeader, requestingPart.Name, hostID);
289 }
290 } 332 }
291 else 333 else
292 { 334 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
index 7e61007..48cab64 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
@@ -37,12 +37,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin
37public class BSActorLockAxis : BSActor 37public class BSActorLockAxis : BSActor
38{ 38{
39 BSConstraint LockAxisConstraint = null; 39 BSConstraint LockAxisConstraint = null;
40 // The lock access flags (which axises were locked) when the contraint was built.
41 // Used to see if locking has changed since when the constraint was built.
42 OMV.Vector3 LockAxisLinearFlags;
43 OMV.Vector3 LockAxisAngularFlags;
40 44
41 public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) 45 public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
42 : base(physicsScene, pObj, actorName) 46 : base(physicsScene, pObj, actorName)
43 { 47 {
44 m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); 48 m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
45 LockAxisConstraint = null; 49 LockAxisConstraint = null;
50
51 // we place our constraint just before the simulation step to make sure the linkset is complete
52 m_physicsScene.BeforeStep += PhysicsScene_BeforeStep;
46 } 53 }
47 54
48 // BSActor.isActive 55 // BSActor.isActive
@@ -55,6 +62,7 @@ public class BSActorLockAxis : BSActor
55 // BSActor.Dispose() 62 // BSActor.Dispose()
56 public override void Dispose() 63 public override void Dispose()
57 { 64 {
65 m_physicsScene.BeforeStep -= PhysicsScene_BeforeStep;
58 RemoveAxisLockConstraint(); 66 RemoveAxisLockConstraint();
59 } 67 }
60 68
@@ -63,10 +71,18 @@ public class BSActorLockAxis : BSActor
63 // BSActor.Refresh() 71 // BSActor.Refresh()
64 public override void Refresh() 72 public override void Refresh()
65 { 73 {
66 m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}", 74 // Since the axis logging is done with a constraint, Refresh() time is good for
67 m_controllingPrim.LocalID, m_controllingPrim.LockedAngularAxis, Enabled, m_controllingPrim.IsPhysicallyActive); 75 // changing parameters but this needs to wait until the prim/linkset is physically
76 // constructed. Therefore, the constraint itself is placed at pre-step time.
77 /*
78 m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedLinear={1},lockedAngular={2},enabled={3},pActive={4}",
79 m_controllingPrim.LocalID,
80 m_controllingPrim.LockedLinearAxis,
81 m_controllingPrim.LockedAngularAxis,
82 Enabled, m_controllingPrim.IsPhysicallyActive);
68 // If all the axis are free, we don't need to exist 83 // If all the axis are free, we don't need to exist
69 if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree) 84 if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree
85 && m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree)
70 { 86 {
71 Enabled = false; 87 Enabled = false;
72 } 88 }
@@ -74,12 +90,21 @@ public class BSActorLockAxis : BSActor
74 // If the object is physically active, add the axis locking constraint 90 // If the object is physically active, add the axis locking constraint
75 if (isActive) 91 if (isActive)
76 { 92 {
93 // Check to see if the locking parameters have changed
94 if (m_controllingPrim.LockedLinearAxis != this.LockAxisLinearFlags
95 || m_controllingPrim.LockedAngularAxis != this.LockAxisAngularFlags)
96 {
97 // The locking has changed. Remove the old constraint and build a new one
98 RemoveAxisLockConstraint();
99 }
100
77 AddAxisLockConstraint(); 101 AddAxisLockConstraint();
78 } 102 }
79 else 103 else
80 { 104 {
81 RemoveAxisLockConstraint(); 105 RemoveAxisLockConstraint();
82 } 106 }
107 */
83 } 108 }
84 109
85 // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...). 110 // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
@@ -88,15 +113,35 @@ public class BSActorLockAxis : BSActor
88 // BSActor.RemoveDependencies() 113 // BSActor.RemoveDependencies()
89 public override void RemoveDependencies() 114 public override void RemoveDependencies()
90 { 115 {
91 if (LockAxisConstraint != null) 116 RemoveAxisLockConstraint();
117 // The pre-step action will restore the constraint of needed
118 }
119
120 private void PhysicsScene_BeforeStep(float timestep)
121 {
122 // If all the axis are free, we don't need to exist
123 if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree
124 && m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree)
92 { 125 {
93 // If a constraint is set up, remove it from the physical scene 126 Enabled = false;
94 RemoveAxisLockConstraint(); 127 }
95 // Schedule a call before the next simulation step to restore the constraint. 128
96 m_physicsScene.PostTaintObject("BSActorLockAxis:" + ActorName, m_controllingPrim.LocalID, delegate() 129 // If the object is physically active, add the axis locking constraint
130 if (isActive)
131 {
132 // Check to see if the locking parameters have changed
133 if (m_controllingPrim.LockedLinearAxis != this.LockAxisLinearFlags
134 || m_controllingPrim.LockedAngularAxis != this.LockAxisAngularFlags)
97 { 135 {
98 Refresh(); 136 // The locking has changed. Remove the old constraint and build a new one
99 }); 137 RemoveAxisLockConstraint();
138 }
139
140 AddAxisLockConstraint();
141 }
142 else
143 {
144 RemoveAxisLockConstraint();
100 } 145 }
101 } 146 }
102 147
@@ -118,56 +163,30 @@ public class BSActorLockAxis : BSActor
118 LockAxisConstraint = axisConstrainer; 163 LockAxisConstraint = axisConstrainer;
119 m_physicsScene.Constraints.AddConstraint(LockAxisConstraint); 164 m_physicsScene.Constraints.AddConstraint(LockAxisConstraint);
120 165
166 // Remember the clocking being inforced so we can notice if they have changed
167 LockAxisLinearFlags = m_controllingPrim.LockedLinearAxis;
168 LockAxisAngularFlags = m_controllingPrim.LockedAngularAxis;
169
121 // The constraint is tied to the world and oriented to the prim. 170 // The constraint is tied to the world and oriented to the prim.
122 171
123 // Free to move linearly in the region 172 if (!axisConstrainer.SetLinearLimits(m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh))
124 // OMV.Vector3 linearLow = OMV.Vector3.Zero;
125 // OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize;
126 OMV.Vector3 linearLow = new OMV.Vector3(-10000f, -10000f, -10000f);
127 OMV.Vector3 linearHigh = new OMV.Vector3(10000f, 10000f, 10000f);
128 if (m_controllingPrim.LockedLinearAxis.X != BSPhysObject.FreeAxis)
129 {
130 linearLow.X = m_controllingPrim.RawPosition.X;
131 linearHigh.X = m_controllingPrim.RawPosition.X;
132 }
133 if (m_controllingPrim.LockedLinearAxis.Y != BSPhysObject.FreeAxis)
134 { 173 {
135 linearLow.Y = m_controllingPrim.RawPosition.Y; 174 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetLinearLimits",
136 linearHigh.Y = m_controllingPrim.RawPosition.Y; 175 m_controllingPrim.LocalID);
137 } 176 }
138 if (m_controllingPrim.LockedLinearAxis.Z != BSPhysObject.FreeAxis)
139 {
140 linearLow.Z = m_controllingPrim.RawPosition.Z;
141 linearHigh.Z = m_controllingPrim.RawPosition.Z;
142 }
143 axisConstrainer.SetLinearLimits(linearLow, linearHigh);
144 177
145 // Angular with some axis locked 178 if (!axisConstrainer.SetAngularLimits(m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh))
146 float fPI = (float)Math.PI;
147 OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI);
148 OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI);
149 if (m_controllingPrim.LockedAngularAxis.X != BSPhysObject.FreeAxis)
150 {
151 angularLow.X = 0f;
152 angularHigh.X = 0f;
153 }
154 if (m_controllingPrim.LockedAngularAxis.Y != BSPhysObject.FreeAxis)
155 {
156 angularLow.Y = 0f;
157 angularHigh.Y = 0f;
158 }
159 if (m_controllingPrim.LockedAngularAxis.Z != BSPhysObject.FreeAxis)
160 {
161 angularLow.Z = 0f;
162 angularHigh.Z = 0f;
163 }
164 if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh))
165 { 179 {
166 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID); 180 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits",
181 m_controllingPrim.LocalID);
167 } 182 }
168 183
169 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", 184 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}",
170 m_controllingPrim.LocalID, linearLow, linearHigh, angularLow, angularHigh); 185 m_controllingPrim.LocalID,
186 m_controllingPrim.LockedLinearAxisLow,
187 m_controllingPrim.LockedLinearAxisHigh,
188 m_controllingPrim.LockedAngularAxisLow,
189 m_controllingPrim.LockedAngularAxisHigh);
171 190
172 // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. 191 // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
173 axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); 192 axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index b444446..22b3f3f 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -201,7 +201,10 @@ public sealed class BSLinksetCompound : BSLinkset
201 if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) 201 if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
202 { 202 {
203 // Find the physical instance of the child 203 // Find the physical instance of the child
204 if (LinksetRoot.PhysShape.HasPhysicalShape && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo)) 204 if (!RebuildScheduled // if rebuilding, let the rebuild do it
205 && !LinksetRoot.IsIncomplete // if waiting for assets or whatever, don't change
206 && LinksetRoot.PhysShape.HasPhysicalShape // there must be a physical shape assigned
207 && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo))
205 { 208 {
206 // It is possible that the linkset is still under construction and the child is not yet 209 // It is possible that the linkset is still under construction and the child is not yet
207 // inserted into the compound shape. A rebuild of the linkset in a pre-step action will 210 // inserted into the compound shape. A rebuild of the linkset in a pre-step action will
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 2b744a0..d20d094 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -309,11 +309,20 @@ public abstract class BSPhysObject : PhysicsActor
309 // Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass. 309 // Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass.
310 public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; } 310 public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; }
311 311
312 public OMV.Vector3 LockedLinearAxis { get; set; } // zero means locked. one means free. 312 public OMV.Vector3 LockedLinearAxis; // zero means locked. one means free.
313 public OMV.Vector3 LockedAngularAxis { get; set; } // zero means locked. one means free. 313 public OMV.Vector3 LockedAngularAxis; // zero means locked. one means free.
314 public const float FreeAxis = 1f; 314 public const float FreeAxis = 1f;
315 public const float LockedAxis = 0f;
315 public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free 316 public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free
316 317
318 // If an axis is locked (flagged above) then the limits of that axis are specified here.
319 // Linear axis limits are relative to the object's starting coordinates.
320 // Angular limits are limited to -PI to +PI
321 public OMV.Vector3 LockedLinearAxisLow;
322 public OMV.Vector3 LockedLinearAxisHigh;
323 public OMV.Vector3 LockedAngularAxisLow;
324 public OMV.Vector3 LockedAngularAxisHigh;
325
317 // Enable physical actions. Bullet will keep sleeping non-moving physical objects so 326 // Enable physical actions. Bullet will keep sleeping non-moving physical objects so
318 // they need waking up when parameters are changed. 327 // they need waking up when parameters are changed.
319 // Called in taint-time!! 328 // Called in taint-time!!
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index c88a5c2..5d359e8 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -34,6 +34,7 @@ using OMV = OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Physics.Manager; 35using OpenSim.Region.Physics.Manager;
36using OpenSim.Region.Physics.ConvexDecompositionDotNet; 36using OpenSim.Region.Physics.ConvexDecompositionDotNet;
37using OpenSim.Region.OptionalModules.Scripting; // for ExtendedPhysics
37 38
38namespace OpenSim.Region.Physics.BulletSPlugin 39namespace OpenSim.Region.Physics.BulletSPlugin
39{ 40{
@@ -95,11 +96,9 @@ public class BSPrim : BSPhysObject
95 _isPhysical = pisPhysical; 96 _isPhysical = pisPhysical;
96 _isVolumeDetect = false; 97 _isVolumeDetect = false;
97 98
98 // Add a dynamic vehicle to our set of actors that can move this prim.
99 // PhysicalActors.Add(VehicleActorName, new BSDynamics(PhysScene, this, VehicleActorName));
100
101 _mass = CalculateMass(); 99 _mass = CalculateMass();
102 100
101 DetailLog("{0},BSPrim.constructor,pbs={1}", LocalID, BSScene.PrimitiveBaseShapeToString(pbs));
103 // DetailLog("{0},BSPrim.constructor,call", LocalID); 102 // DetailLog("{0},BSPrim.constructor,call", LocalID);
104 // do the actual object creation at taint time 103 // do the actual object creation at taint time
105 PhysScene.TaintedObject(LocalID, "BSPrim.create", delegate() 104 PhysScene.TaintedObject(LocalID, "BSPrim.create", delegate()
@@ -167,6 +166,7 @@ public class BSPrim : BSPhysObject
167 public override PrimitiveBaseShape Shape { 166 public override PrimitiveBaseShape Shape {
168 set { 167 set {
169 BaseShape = value; 168 BaseShape = value;
169 DetailLog("{0},BSPrim.changeShape,pbs={1}", LocalID, BSScene.PrimitiveBaseShapeToString(BaseShape));
170 PrimAssetState = PrimAssetCondition.Unknown; 170 PrimAssetState = PrimAssetCondition.Unknown;
171 ForceBodyShapeRebuild(false); 171 ForceBodyShapeRebuild(false);
172 } 172 }
@@ -285,23 +285,21 @@ public class BSPrim : BSPhysObject
285 { 285 {
286 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 286 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
287 287
288 // "1" means free, "0" means locked 288 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
289 OMV.Vector3 locking = LockedAxisFree; 289 if (axis.X != 1)
290 if (axis.X != 1) locking.X = 0f;
291 if (axis.Y != 1) locking.Y = 0f;
292 if (axis.Z != 1) locking.Z = 0f;
293 LockedAngularAxis = locking;
294
295 EnableActor(LockedAngularAxis != LockedAxisFree, LockedAxisActorName, delegate()
296 { 290 {
297 return new BSActorLockAxis(PhysScene, this, LockedAxisActorName); 291 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
298 }); 292 }
299 293 if (axis.Y != 1)
300 // Update parameters so the new actor's Refresh() action is called at the right time.
301 PhysScene.TaintedObject(LocalID, "BSPrim.LockAngularMotion", delegate()
302 { 294 {
303 UpdatePhysicalParameters(); 295 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f);
304 }); 296 }
297 if (axis.Z != 1)
298 {
299 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f);
300 }
301
302 InitializeAxisActor();
305 303
306 return; 304 return;
307 } 305 }
@@ -533,6 +531,12 @@ public class BSPrim : BSPhysObject
533 { 531 {
534 return new BSActorSetForce(PhysScene, this, SetForceActorName); 532 return new BSActorSetForce(PhysScene, this, SetForceActorName);
535 }); 533 });
534
535 // Call update so actor Refresh() is called to start things off
536 PhysScene.TaintedObject(LocalID, "BSPrim.setForce", delegate()
537 {
538 UpdatePhysicalParameters();
539 });
536 } 540 }
537 } 541 }
538 542
@@ -766,6 +770,12 @@ public class BSPrim : BSPhysObject
766 return new BSActorSetTorque(PhysScene, this, SetTorqueActorName); 770 return new BSActorSetTorque(PhysScene, this, SetTorqueActorName);
767 }); 771 });
768 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque); 772 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque);
773
774 // Call update so actor Refresh() is called to start things off
775 PhysScene.TaintedObject(LocalID, "BSPrim.setTorque", delegate()
776 {
777 UpdatePhysicalParameters();
778 });
769 } 779 }
770 } 780 }
771 public override OMV.Vector3 Acceleration { 781 public override OMV.Vector3 Acceleration {
@@ -1138,6 +1148,12 @@ public class BSPrim : BSPhysObject
1138 { 1148 {
1139 return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName); 1149 return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName);
1140 }); 1150 });
1151
1152 // Call update so actor Refresh() is called to start things off
1153 PhysScene.TaintedObject(LocalID, "BSPrim.PIDActive", delegate()
1154 {
1155 UpdatePhysicalParameters();
1156 });
1141 } 1157 }
1142 } 1158 }
1143 1159
@@ -1164,6 +1180,12 @@ public class BSPrim : BSPhysObject
1164 { 1180 {
1165 return new BSActorHover(PhysScene, this, HoverActorName); 1181 return new BSActorHover(PhysScene, this, HoverActorName);
1166 }); 1182 });
1183
1184 // Call update so actor Refresh() is called to start things off
1185 PhysScene.TaintedObject(LocalID, "BSPrim.PIDHoverActive", delegate()
1186 {
1187 UpdatePhysicalParameters();
1188 });
1167 } 1189 }
1168 } 1190 }
1169 1191
@@ -1601,12 +1623,293 @@ public class BSPrim : BSPhysObject
1601 object ret = null; 1623 object ret = null;
1602 switch (pFunct) 1624 switch (pFunct)
1603 { 1625 {
1626 case ExtendedPhysics.PhysFunctAxisLockLimits:
1627 ret = SetAxisLockLimitsExtension(pParams);
1628 break;
1604 default: 1629 default:
1605 ret = base.Extension(pFunct, pParams); 1630 ret = base.Extension(pFunct, pParams);
1606 break; 1631 break;
1607 } 1632 }
1608 return ret; 1633 return ret;
1609 } 1634 }
1635
1636 private void InitializeAxisActor()
1637 {
1638 EnableActor(LockedAngularAxis != LockedAxisFree || LockedLinearAxis != LockedAxisFree,
1639 LockedAxisActorName, delegate()
1640 {
1641 return new BSActorLockAxis(PhysScene, this, LockedAxisActorName);
1642 });
1643
1644 // Update parameters so the new actor's Refresh() action is called at the right time.
1645 PhysScene.TaintedObject(LocalID, "BSPrim.LockAxis", delegate()
1646 {
1647 UpdatePhysicalParameters();
1648 });
1649 }
1650
1651 // Passed an array of an array of parameters, set the axis locking.
1652 // This expects an int (PHYS_AXIS_*) followed by none or two limit floats
1653 // followed by another int and floats, etc.
1654 private object SetAxisLockLimitsExtension(object[] pParams)
1655 {
1656 DetailLog("{0} SetAxisLockLimitsExtension. parmlen={1}", LocalID, pParams.GetLength(0));
1657 object ret = null;
1658 try
1659 {
1660 if (pParams.GetLength(0) > 1)
1661 {
1662 int index = 2;
1663 while (index < pParams.GetLength(0))
1664 {
1665 var funct = pParams[index];
1666 DetailLog("{0} SetAxisLockLimitsExtension. op={1}, index={2}", LocalID, funct, index);
1667 if (funct is Int32 || funct is Int64)
1668 {
1669 switch ((int)funct)
1670 {
1671 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR:
1672 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR, 0f, 0f);
1673 index += 1;
1674 break;
1675 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X:
1676 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X, 0f, 0f);
1677 index += 1;
1678 break;
1679 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X:
1680 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X, (float)pParams[index + 1], (float)pParams[index + 2]);
1681 index += 3;
1682 break;
1683 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y:
1684 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y, 0f, 0f);
1685 index += 1;
1686 break;
1687 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y:
1688 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y, (float)pParams[index + 1], (float)pParams[index + 2]);
1689 index += 3;
1690 break;
1691 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z:
1692 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z, 0f, 0f);
1693 index += 1;
1694 break;
1695 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z:
1696 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z, (float)pParams[index + 1], (float)pParams[index + 2]);
1697 index += 3;
1698 break;
1699 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR:
1700 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR, 0f, 0f);
1701 index += 1;
1702 break;
1703 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X:
1704 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
1705 index += 1;
1706 break;
1707 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X:
1708 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X, (float)pParams[index + 1], (float)pParams[index + 2]);
1709 index += 3;
1710 break;
1711 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y:
1712 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f);
1713 index += 1;
1714 break;
1715 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y:
1716 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y, (float)pParams[index + 1], (float)pParams[index + 2]);
1717 index += 3;
1718 break;
1719 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z:
1720 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f);
1721 index += 1;
1722 break;
1723 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z:
1724 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z, (float)pParams[index + 1], (float)pParams[index + 2]);
1725 index += 3;
1726 break;
1727 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR:
1728 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR, 0f, 0f);
1729 index += 1;
1730 break;
1731 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X:
1732 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X, 0f, 0f);
1733 index += 1;
1734 break;
1735 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y:
1736 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y, 0f, 0f);
1737 index += 1;
1738 break;
1739 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z:
1740 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z, 0f, 0f);
1741 index += 1;
1742 break;
1743 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR:
1744 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
1745 index += 1;
1746 break;
1747 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X:
1748 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X, 0f, 0f);
1749 index += 1;
1750 break;
1751 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y:
1752 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y, 0f, 0f);
1753 index += 1;
1754 break;
1755 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z:
1756 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z, 0f, 0f);
1757 index += 1;
1758 break;
1759 case ExtendedPhysics.PHYS_AXIS_UNLOCK:
1760 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK, 0f, 0f);
1761 index += 1;
1762 break;
1763 default:
1764 m_log.WarnFormat("{0} SetSxisLockLimitsExtension. Unknown op={1}", LogHeader, funct);
1765 index += 1;
1766 break;
1767 }
1768 }
1769 }
1770 InitializeAxisActor();
1771 ret = (object)index;
1772 }
1773 }
1774 catch (Exception e)
1775 {
1776 m_log.WarnFormat("{0} SetSxisLockLimitsExtension exception in object {1}: {2}", LogHeader, this.Name, e);
1777 ret = null;
1778 }
1779 return ret; // not implemented yet
1780 }
1781
1782 // Set the locking parameters.
1783 // If an axis is locked, the limits for the axis are set to zero,
1784 // If the axis is being constrained, the high and low value are passed and set.
1785 // When done here, LockedXXXAxis flags are set and LockedXXXAxixLow/High are set to the range.
1786 protected void ApplyAxisLimits(int funct, float low, float high)
1787 {
1788 DetailLog("{0} ApplyAxisLimits. op={1}, low={2}, high={3}", LocalID, funct, low, high);
1789 float linearMax = 23000f;
1790 float angularMax = (float)Math.PI;
1791
1792 switch ((int)funct)
1793 {
1794 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR:
1795 this.LockedLinearAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis);
1796 this.LockedLinearAxisLow = OMV.Vector3.Zero;
1797 this.LockedLinearAxisHigh = OMV.Vector3.Zero;
1798 break;
1799 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X:
1800 this.LockedLinearAxis.X = LockedAxis;
1801 this.LockedLinearAxisLow.X = 0f;
1802 this.LockedLinearAxisHigh.X = 0f;
1803 break;
1804 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X:
1805 this.LockedLinearAxis.X = LockedAxis;
1806 this.LockedLinearAxisLow.X = Util.Clip(low, -linearMax, linearMax);
1807 this.LockedLinearAxisHigh.X = Util.Clip(high, -linearMax, linearMax);
1808 break;
1809 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y:
1810 this.LockedLinearAxis.Y = LockedAxis;
1811 this.LockedLinearAxisLow.Y = 0f;
1812 this.LockedLinearAxisHigh.Y = 0f;
1813 break;
1814 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y:
1815 this.LockedLinearAxis.Y = LockedAxis;
1816 this.LockedLinearAxisLow.Y = Util.Clip(low, -linearMax, linearMax);
1817 this.LockedLinearAxisHigh.Y = Util.Clip(high, -linearMax, linearMax);
1818 break;
1819 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z:
1820 this.LockedLinearAxis.Z = LockedAxis;
1821 this.LockedLinearAxisLow.Z = 0f;
1822 this.LockedLinearAxisHigh.Z = 0f;
1823 break;
1824 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z:
1825 this.LockedLinearAxis.Z = LockedAxis;
1826 this.LockedLinearAxisLow.Z = Util.Clip(low, -linearMax, linearMax);
1827 this.LockedLinearAxisHigh.Z = Util.Clip(high, -linearMax, linearMax);
1828 break;
1829 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR:
1830 this.LockedAngularAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis);
1831 this.LockedAngularAxisLow = OMV.Vector3.Zero;
1832 this.LockedAngularAxisHigh = OMV.Vector3.Zero;
1833 break;
1834 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X:
1835 this.LockedAngularAxis.X = LockedAxis;
1836 this.LockedAngularAxisLow.X = 0;
1837 this.LockedAngularAxisHigh.X = 0;
1838 break;
1839 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X:
1840 this.LockedAngularAxis.X = LockedAxis;
1841 this.LockedAngularAxisLow.X = Util.Clip(low, -angularMax, angularMax);
1842 this.LockedAngularAxisHigh.X = Util.Clip(high, -angularMax, angularMax);
1843 break;
1844 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y:
1845 this.LockedAngularAxis.Y = LockedAxis;
1846 this.LockedAngularAxisLow.Y = 0;
1847 this.LockedAngularAxisHigh.Y = 0;
1848 break;
1849 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y:
1850 this.LockedAngularAxis.Y = LockedAxis;
1851 this.LockedAngularAxisLow.Y = Util.Clip(low, -angularMax, angularMax);
1852 this.LockedAngularAxisHigh.Y = Util.Clip(high, -angularMax, angularMax);
1853 break;
1854 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z:
1855 this.LockedAngularAxis.Z = LockedAxis;
1856 this.LockedAngularAxisLow.Z = 0;
1857 this.LockedAngularAxisHigh.Z = 0;
1858 break;
1859 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z:
1860 this.LockedAngularAxis.Z = LockedAxis;
1861 this.LockedAngularAxisLow.Z = Util.Clip(low, -angularMax, angularMax);
1862 this.LockedAngularAxisHigh.Z = Util.Clip(high, -angularMax, angularMax);
1863 break;
1864 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR:
1865 this.LockedLinearAxis = LockedAxisFree;
1866 this.LockedLinearAxisLow = new OMV.Vector3(-linearMax, -linearMax, -linearMax);
1867 this.LockedLinearAxisHigh = new OMV.Vector3(linearMax, linearMax, linearMax);
1868 break;
1869 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X:
1870 this.LockedLinearAxis.X = FreeAxis;
1871 this.LockedLinearAxisLow.X = -linearMax;
1872 this.LockedLinearAxisHigh.X = linearMax;
1873 break;
1874 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y:
1875 this.LockedLinearAxis.Y = FreeAxis;
1876 this.LockedLinearAxisLow.Y = -linearMax;
1877 this.LockedLinearAxisHigh.Y = linearMax;
1878 break;
1879 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z:
1880 this.LockedLinearAxis.Z = FreeAxis;
1881 this.LockedLinearAxisLow.Z = -linearMax;
1882 this.LockedLinearAxisHigh.Z = linearMax;
1883 break;
1884 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR:
1885 this.LockedAngularAxis = LockedAxisFree;
1886 this.LockedAngularAxisLow = new OMV.Vector3(-angularMax, -angularMax, -angularMax);
1887 this.LockedAngularAxisHigh = new OMV.Vector3(angularMax, angularMax, angularMax);
1888 break;
1889 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X:
1890 this.LockedAngularAxis.X = FreeAxis;
1891 this.LockedAngularAxisLow.X = -angularMax;
1892 this.LockedAngularAxisHigh.X = angularMax;
1893 break;
1894 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y:
1895 this.LockedAngularAxis.Y = FreeAxis;
1896 this.LockedAngularAxisLow.Y = -angularMax;
1897 this.LockedAngularAxisHigh.Y = angularMax;
1898 break;
1899 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z:
1900 this.LockedAngularAxis.Z = FreeAxis;
1901 this.LockedAngularAxisLow.Z = -angularMax;
1902 this.LockedAngularAxisHigh.Z = angularMax;
1903 break;
1904 case ExtendedPhysics.PHYS_AXIS_UNLOCK:
1905 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR, 0f, 0f);
1906 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
1907 break;
1908 default:
1909 break;
1910 }
1911 return;
1912 }
1610 #endregion // Extension 1913 #endregion // Extension
1611 1914
1612 // The physics engine says that properties have updated. Update same and inform 1915 // The physics engine says that properties have updated. Update same and inform
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 414bc92..238fcc2 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -947,6 +947,73 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
947 } 947 }
948 #endregion // Extensions 948 #endregion // Extensions
949 949
950 public static string PrimitiveBaseShapeToString(PrimitiveBaseShape pbs)
951 {
952 float pathShearX = pbs.PathShearX < 128 ? (float)pbs.PathShearX * 0.01f : (float)(pbs.PathShearX - 256) * 0.01f;
953 float pathShearY = pbs.PathShearY < 128 ? (float)pbs.PathShearY * 0.01f : (float)(pbs.PathShearY - 256) * 0.01f;
954 float pathBegin = (float)pbs.PathBegin * 2.0e-5f;
955 float pathEnd = 1.0f - (float)pbs.PathEnd * 2.0e-5f;
956 float pathScaleX = (float)(pbs.PathScaleX - 100) * 0.01f;
957 float pathScaleY = (float)(pbs.PathScaleY - 100) * 0.01f;
958
959 float profileBegin = (float)pbs.ProfileBegin * 2.0e-5f;
960 float profileEnd = 1.0f - (float)pbs.ProfileEnd * 2.0e-5f;
961 float profileHollow = (float)pbs.ProfileHollow * 2.0e-5f;
962 if (profileHollow > 0.95f)
963 profileHollow = 0.95f;
964
965 StringBuilder buff = new StringBuilder();
966 buff.Append("shape=");
967 buff.Append(((ProfileShape)pbs.ProfileShape).ToString());
968 buff.Append(",");
969 buff.Append("hollow=");
970 buff.Append(((HollowShape)pbs.HollowShape).ToString());
971 buff.Append(",");
972 buff.Append("pathCurve=");
973 buff.Append(((Extrusion)pbs.PathCurve).ToString());
974 buff.Append(",");
975 buff.Append("profCurve=");
976 buff.Append(((Extrusion)pbs.ProfileCurve).ToString());
977 buff.Append(",");
978 buff.Append("profHollow=");
979 buff.Append(profileHollow.ToString());
980 buff.Append(",");
981 buff.Append("pathBegEnd=");
982 buff.Append(pathBegin.ToString());
983 buff.Append("/");
984 buff.Append(pathEnd.ToString());
985 buff.Append(",");
986 buff.Append("profileBegEnd=");
987 buff.Append(profileBegin.ToString());
988 buff.Append("/");
989 buff.Append(profileEnd.ToString());
990 buff.Append(",");
991 buff.Append("scaleXY=");
992 buff.Append(pathScaleX.ToString());
993 buff.Append("/");
994 buff.Append(pathScaleY.ToString());
995 buff.Append(",");
996 buff.Append("shearXY=");
997 buff.Append(pathShearX.ToString());
998 buff.Append("/");
999 buff.Append(pathShearY.ToString());
1000 buff.Append(",");
1001 buff.Append("taperXY=");
1002 buff.Append(pbs.PathTaperX.ToString());
1003 buff.Append("/");
1004 buff.Append(pbs.PathTaperY.ToString());
1005 buff.Append(",");
1006 buff.Append("skew=");
1007 buff.Append(pbs.PathSkew.ToString());
1008 buff.Append(",");
1009 buff.Append("twist/Beg=");
1010 buff.Append(pbs.PathTwist.ToString());
1011 buff.Append("/");
1012 buff.Append(pbs.PathTwistBegin.ToString());
1013
1014 return buff.ToString();
1015 }
1016
950 #region Taints 1017 #region Taints
951 // The simulation execution order is: 1018 // The simulation execution order is:
952 // Simulate() 1019 // Simulate()
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
index 09f5bc4..aa04726 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
@@ -38,6 +38,76 @@ using OMV = OpenMetaverse;
38 38
39namespace OpenSim.Region.Physics.BulletSPlugin 39namespace OpenSim.Region.Physics.BulletSPlugin
40{ 40{
41// Information class that holds stats for the shape. Which values mean
42// something depends on the type of shape.
43// This information is used for debugging and stats and is not used
44// for operational things.
45public class ShapeInfoInfo
46{
47 public int Vertices { get; set; }
48 private int m_hullCount;
49 private int[] m_verticesPerHull;
50 public ShapeInfoInfo()
51 {
52 Vertices = 0;
53 m_hullCount = 0;
54 m_verticesPerHull = null;
55 }
56 public int HullCount
57 {
58 set
59 {
60 m_hullCount = value;
61 m_verticesPerHull = new int[m_hullCount];
62 Array.Clear(m_verticesPerHull, 0, m_hullCount);
63 }
64 get { return m_hullCount; }
65 }
66 public void SetVerticesPerHull(int hullNum, int vertices)
67 {
68 if (m_verticesPerHull != null && hullNum < m_verticesPerHull.Length)
69 {
70 m_verticesPerHull[hullNum] = vertices;
71 }
72 }
73 public int GetVerticesPerHull(int hullNum)
74 {
75 if (m_verticesPerHull != null && hullNum < m_verticesPerHull.Length)
76 {
77 return m_verticesPerHull[hullNum];
78 }
79 return 0;
80 }
81 public override string ToString()
82 {
83 StringBuilder buff = new StringBuilder();
84 // buff.Append("ShapeInfo=<");
85 buff.Append("<");
86 if (Vertices > 0)
87 {
88 buff.Append("verts=");
89 buff.Append(Vertices.ToString());
90 }
91
92 if (Vertices > 0 && HullCount > 0) buff.Append(",");
93
94 if (HullCount > 0)
95 {
96 buff.Append("nHulls=");
97 buff.Append(HullCount.ToString());
98 buff.Append(",");
99 buff.Append("hullVerts=");
100 for (int ii = 0; ii < HullCount; ii++)
101 {
102 if (ii != 0) buff.Append(",");
103 buff.Append(GetVerticesPerHull(ii).ToString());
104 }
105 }
106 buff.Append(">");
107 return buff.ToString();
108 }
109}
110
41public abstract class BSShape 111public abstract class BSShape
42{ 112{
43 private static string LogHeader = "[BULLETSIM SHAPE]"; 113 private static string LogHeader = "[BULLETSIM SHAPE]";
@@ -45,18 +115,21 @@ public abstract class BSShape
45 public int referenceCount { get; set; } 115 public int referenceCount { get; set; }
46 public DateTime lastReferenced { get; set; } 116 public DateTime lastReferenced { get; set; }
47 public BulletShape physShapeInfo { get; set; } 117 public BulletShape physShapeInfo { get; set; }
118 public ShapeInfoInfo shapeInfo { get; private set; }
48 119
49 public BSShape() 120 public BSShape()
50 { 121 {
51 referenceCount = 1; 122 referenceCount = 1;
52 lastReferenced = DateTime.Now; 123 lastReferenced = DateTime.Now;
53 physShapeInfo = new BulletShape(); 124 physShapeInfo = new BulletShape();
125 shapeInfo = new ShapeInfoInfo();
54 } 126 }
55 public BSShape(BulletShape pShape) 127 public BSShape(BulletShape pShape)
56 { 128 {
57 referenceCount = 1; 129 referenceCount = 1;
58 lastReferenced = DateTime.Now; 130 lastReferenced = DateTime.Now;
59 physShapeInfo = pShape; 131 physShapeInfo = pShape;
132 shapeInfo = new ShapeInfoInfo();
60 } 133 }
61 134
62 // Get another reference to this shape. 135 // Get another reference to this shape.
@@ -283,6 +356,9 @@ public class BSShapeNull : BSShape
283} 356}
284 357
285// ============================================================================================================ 358// ============================================================================================================
359// BSShapeNative is a wrapper for a Bullet 'native' shape -- cube and sphere.
360// They are odd in that they don't allocate meshes but are computated/procedural.
361// This means allocation and freeing is different than meshes.
286public class BSShapeNative : BSShape 362public class BSShapeNative : BSShape
287{ 363{
288 private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; 364 private static string LogHeader = "[BULLETSIM SHAPE NATIVE]";
@@ -361,6 +437,7 @@ public class BSShapeNative : BSShape
361} 437}
362 438
363// ============================================================================================================ 439// ============================================================================================================
440// BSShapeMesh is a simple mesh.
364public class BSShapeMesh : BSShape 441public class BSShapeMesh : BSShape
365{ 442{
366 private static string LogHeader = "[BULLETSIM SHAPE MESH]"; 443 private static string LogHeader = "[BULLETSIM SHAPE MESH]";
@@ -457,7 +534,11 @@ public class BSShapeMesh : BSShape
457 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 534 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
458 { 535 {
459 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, 536 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
460 (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) ); 537 (w, iC, i, vC, v) =>
538 {
539 shapeInfo.Vertices = vC;
540 return physicsScene.PE.CreateMeshShape(w, iC, i, vC, v);
541 });
461 } 542 }
462 543
463 // Code that uses the mesher to create the index/vertices info for a trimesh shape. 544 // Code that uses the mesher to create the index/vertices info for a trimesh shape.
@@ -545,6 +626,9 @@ public class BSShapeMesh : BSShape
545} 626}
546 627
547// ============================================================================================================ 628// ============================================================================================================
629// BSShapeHull is a physical shape representation htat is made up of many convex hulls.
630// The convex hulls are either supplied with the asset or are approximated by one of the
631// convex hull creation routines (in OpenSim or in Bullet).
548public class BSShapeHull : BSShape 632public class BSShapeHull : BSShape
549{ 633{
550#pragma warning disable 414 634#pragma warning disable 414
@@ -553,6 +637,7 @@ public class BSShapeHull : BSShape
553 637
554 public static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); 638 public static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>();
555 639
640
556 public BSShapeHull(BulletShape pShape) : base(pShape) 641 public BSShapeHull(BulletShape pShape) : base(pShape)
557 { 642 {
558 } 643 }
@@ -615,6 +700,7 @@ public class BSShapeHull : BSShape
615 // TODO: schedule aging and destruction of unused meshes. 700 // TODO: schedule aging and destruction of unused meshes.
616 } 701 }
617 } 702 }
703
618 List<ConvexResult> m_hulls; 704 List<ConvexResult> m_hulls;
619 private BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, System.UInt64 newHullKey, 705 private BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, System.UInt64 newHullKey,
620 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 706 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
@@ -647,6 +733,7 @@ public class BSShapeHull : BSShape
647 if (allHulls != null && BSParam.ShouldUseAssetHulls) 733 if (allHulls != null && BSParam.ShouldUseAssetHulls)
648 { 734 {
649 int hullCount = allHulls.Count; 735 int hullCount = allHulls.Count;
736 shapeInfo.HullCount = hullCount;
650 int totalVertices = 1; // include one for the count of the hulls 737 int totalVertices = 1; // include one for the count of the hulls
651 // Using the structure described for HACD hulls, create the memory sturcture 738 // Using the structure described for HACD hulls, create the memory sturcture
652 // to pass the hull data to the creater. 739 // to pass the hull data to the creater.
@@ -659,6 +746,7 @@ public class BSShapeHull : BSShape
659 746
660 convHulls[0] = (float)hullCount; 747 convHulls[0] = (float)hullCount;
661 int jj = 1; 748 int jj = 1;
749 int hullIndex = 0;
662 foreach (List<OMV.Vector3> hullVerts in allHulls) 750 foreach (List<OMV.Vector3> hullVerts in allHulls)
663 { 751 {
664 convHulls[jj + 0] = hullVerts.Count; 752 convHulls[jj + 0] = hullVerts.Count;
@@ -673,6 +761,8 @@ public class BSShapeHull : BSShape
673 convHulls[jj + 2] = oneVert.Z; 761 convHulls[jj + 2] = oneVert.Z;
674 jj += 3; 762 jj += 3;
675 } 763 }
764 shapeInfo.SetVerticesPerHull(hullIndex, hullVerts.Count);
765 hullIndex++;
676 } 766 }
677 767
678 // create the hull data structure in Bullet 768 // create the hull data structure in Bullet
@@ -708,6 +798,10 @@ public class BSShapeHull : BSShape
708 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape); 798 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape);
709 799
710 // Now done with the mesh shape. 800 // Now done with the mesh shape.
801 shapeInfo.HullCount = 1;
802 BSShapeMesh maybeMesh = meshShape as BSShapeMesh;
803 if (maybeMesh != null)
804 shapeInfo.SetVerticesPerHull(0, maybeMesh.shapeInfo.Vertices);
711 meshShape.Dereference(physicsScene); 805 meshShape.Dereference(physicsScene);
712 } 806 }
713 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); 807 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
@@ -857,6 +951,8 @@ public class BSShapeHull : BSShape
857} 951}
858 952
859// ============================================================================================================ 953// ============================================================================================================
954// BSShapeCompound is a wrapper for the Bullet compound shape which is built from multiple, separate
955// meshes. Used by BulletSim for complex shapes like linksets.
860public class BSShapeCompound : BSShape 956public class BSShapeCompound : BSShape
861{ 957{
862 private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; 958 private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]";
@@ -999,6 +1095,9 @@ public class BSShapeCompound : BSShape
999} 1095}
1000 1096
1001// ============================================================================================================ 1097// ============================================================================================================
1098// BSShapeConvexHull is a wrapper for a Bullet single convex hull. A BSShapeHull contains multiple convex
1099// hull shapes. This is used for simple prims that are convex and thus can be made into a simple
1100// collision shape (a single hull). More complex physical shapes will be BSShapeHull's.
1002public class BSShapeConvexHull : BSShape 1101public class BSShapeConvexHull : BSShape
1003{ 1102{
1004#pragma warning disable 414 1103#pragma warning disable 414
@@ -1098,6 +1197,9 @@ public class BSShapeConvexHull : BSShape
1098 } 1197 }
1099} 1198}
1100// ============================================================================================================ 1199// ============================================================================================================
1200// BSShapeGImpact is a wrapper for the Bullet GImpact shape which is a collision mesh shape that
1201// can handle concave as well as convex shapes. Much slower computationally but creates smoother
1202// shapes than multiple convex hull approximations.
1101public class BSShapeGImpact : BSShape 1203public class BSShapeGImpact : BSShape
1102{ 1204{
1103#pragma warning disable 414 1205#pragma warning disable 414
@@ -1151,7 +1253,11 @@ public class BSShapeGImpact : BSShape
1151 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 1253 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
1152 { 1254 {
1153 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, 1255 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
1154 (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) ); 1256 (w, iC, i, vC, v) =>
1257 {
1258 shapeInfo.Vertices = vC;
1259 return physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v);
1260 });
1155 } 1261 }
1156 1262
1157 public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim) 1263 public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim)
@@ -1206,6 +1312,7 @@ public class BSShapeGImpact : BSShape
1206} 1312}
1207 1313
1208// ============================================================================================================ 1314// ============================================================================================================
1315// BSShapeAvatar is a specialized mesh shape for avatars.
1209public class BSShapeAvatar : BSShape 1316public class BSShapeAvatar : BSShape
1210{ 1317{
1211#pragma warning disable 414 1318#pragma warning disable 414
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
index 28207a4..775bca2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
@@ -28,15 +28,16 @@
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Linq;
32using System.Text; 31using System.Text;
33 32
34using Nini.Config; 33using Nini.Config;
35 34
36using OpenSim.Framework; 35using OpenSim.Framework;
37using OpenSim.Region.Physics.BulletSPlugin; 36using OpenSim.Region.Physics.Manager;
38using OpenSim.Region.Physics.Meshing; 37using OpenSim.Region.Physics.Meshing;
39 38
39using OpenMetaverse;
40
40namespace OpenSim.Region.Physics.BulletSPlugin.Tests 41namespace OpenSim.Region.Physics.BulletSPlugin.Tests
41{ 42{
42// Utility functions for building up and tearing down the sample physics environments 43// Utility functions for building up and tearing down the sample physics environments
@@ -77,17 +78,21 @@ public static class BulletSimTestsUtil
77 bulletSimConfig.Set("VehicleLoggingEnabled","True"); 78 bulletSimConfig.Set("VehicleLoggingEnabled","True");
78 } 79 }
79 80
80 BSPlugin bsPlugin = new BSPlugin(); 81 PhysicsPluginManager physicsPluginManager;
82 physicsPluginManager = new PhysicsPluginManager();
83 physicsPluginManager.LoadPluginsFromAssemblies("Physics");
84
85 Vector3 regionExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
86
87 PhysicsScene pScene = physicsPluginManager.GetPhysicsScene(
88 "BulletSim", "Meshmerizer", openSimINI, "BSTestRegion", regionExtent);
81 89
82 BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion"); 90 BSScene bsScene = pScene as BSScene;
83 91
84 // Since the asset requestor is not initialized, any mesh or sculptie will be a cube. 92 // Since the asset requestor is not initialized, any mesh or sculptie will be a cube.
85 // In the future, add a fake asset fetcher to get meshes and sculpts. 93 // In the future, add a fake asset fetcher to get meshes and sculpts.
86 // bsScene.RequestAssetMethod = ???; 94 // bsScene.RequestAssetMethod = ???;
87 95
88 Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI);
89 bsScene.Initialise(mesher, openSimINI);
90
91 return bsScene; 96 return bsScene;
92 } 97 }
93 98
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs
new file mode 100644
index 0000000..4bec062
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs
@@ -0,0 +1,204 @@
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 copyright
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 NUnit.Framework;
34using log4net;
35
36using OpenSim.Framework;
37using OpenSim.Region.Physics.BulletSPlugin;
38using OpenSim.Region.Physics.Manager;
39using OpenSim.Tests.Common;
40
41using OpenMetaverse;
42
43namespace OpenSim.Region.Physics.BulletSPlugin.Tests
44{
45[TestFixture]
46public class HullCreation : OpenSimTestCase
47{
48 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
49 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
50
51 BSScene PhysicsScene { get; set; }
52 Vector3 ObjectInitPosition;
53 float simulationTimeStep = 0.089f;
54
55 [TestFixtureSetUp]
56 public void Init()
57 {
58
59 }
60
61 [TestFixtureTearDown]
62 public void TearDown()
63 {
64 if (PhysicsScene != null)
65 {
66 // The Dispose() will also free any physical objects in the scene
67 PhysicsScene.Dispose();
68 PhysicsScene = null;
69 }
70 }
71
72 [TestCase(7, 2, 5f, 5f, 32, 0f)] /* default hull parameters */
73 public void GeomHullConvexDecomp( int maxDepthSplit,
74 int maxDepthSplitForSimpleShapes,
75 float concavityThresholdPercent,
76 float volumeConservationThresholdPercent,
77 int maxVertices,
78 float maxSkinWidth)
79 {
80 // Setup the physics engine to use the C# version of convex decomp
81 Dictionary<string, string> engineParams = new Dictionary<string, string>();
82 engineParams.Add("MeshSculptedPrim", "true"); // ShouldMeshSculptedPrim
83 engineParams.Add("ForceSimplePrimMeshing", "false"); // ShouldForceSimplePrimMeshing
84 engineParams.Add("UseHullsForPhysicalObjects", "true"); // ShouldUseHullsForPhysicalObjects
85 engineParams.Add("ShouldRemoveZeroWidthTriangles", "true");
86 engineParams.Add("ShouldUseBulletHACD", "false");
87 engineParams.Add("ShouldUseSingleConvexHullForPrims", "true");
88 engineParams.Add("ShouldUseGImpactShapeForPrims", "false");
89 engineParams.Add("ShouldUseAssetHulls", "true");
90
91 engineParams.Add("CSHullMaxDepthSplit", maxDepthSplit.ToString());
92 engineParams.Add("CSHullMaxDepthSplitForSimpleShapes", maxDepthSplitForSimpleShapes.ToString());
93 engineParams.Add("CSHullConcavityThresholdPercent", concavityThresholdPercent.ToString());
94 engineParams.Add("CSHullVolumeConservationThresholdPercent", volumeConservationThresholdPercent.ToString());
95 engineParams.Add("CSHullMaxVertices", maxVertices.ToString());
96 engineParams.Add("CSHullMaxSkinWidth", maxSkinWidth.ToString());
97
98 PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
99
100 PrimitiveBaseShape pbs;
101 Vector3 pos;
102 Vector3 size;
103 Quaternion rot;
104 bool isPhys;
105
106 // Cylinder
107 pbs = PrimitiveBaseShape.CreateCylinder();
108 pos = new Vector3(100.0f, 100.0f, 0f);
109 pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 10f;
110 ObjectInitPosition = pos;
111 size = new Vector3(2f, 2f, 2f);
112 pbs.Scale = size;
113 rot = Quaternion.Identity;
114 isPhys = true;
115 uint cylinderLocalID = 123;
116 PhysicsScene.AddPrimShape("testCylinder", pbs, pos, size, rot, isPhys, cylinderLocalID);
117 BSPrim primTypeCylinder = (BSPrim)PhysicsScene.PhysObjects[cylinderLocalID];
118
119 // Hollow Cylinder
120 pbs = PrimitiveBaseShape.CreateCylinder();
121 pbs.ProfileHollow = (ushort)(0.70f * 50000);
122 pos = new Vector3(110.0f, 110.0f, 0f);
123 pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 10f;
124 ObjectInitPosition = pos;
125 size = new Vector3(2f, 2f, 2f);
126 pbs.Scale = size;
127 rot = Quaternion.Identity;
128 isPhys = true;
129 uint hollowCylinderLocalID = 124;
130 PhysicsScene.AddPrimShape("testHollowCylinder", pbs, pos, size, rot, isPhys, hollowCylinderLocalID);
131 BSPrim primTypeHollowCylinder = (BSPrim)PhysicsScene.PhysObjects[hollowCylinderLocalID];
132
133 // Torus
134 // ProfileCurve = Circle, PathCurve = Curve1
135 pbs = PrimitiveBaseShape.CreateSphere();
136 pbs.ProfileShape = (byte)ProfileShape.Circle;
137 pbs.PathCurve = (byte)Extrusion.Curve1;
138 pos = new Vector3(120.0f, 120.0f, 0f);
139 pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 10f;
140 ObjectInitPosition = pos;
141 size = new Vector3(2f, 4f, 4f);
142 pbs.Scale = size;
143 rot = Quaternion.Identity;
144 isPhys = true;
145 uint torusLocalID = 125;
146 PhysicsScene.AddPrimShape("testTorus", pbs, pos, size, rot, isPhys, torusLocalID);
147 BSPrim primTypeTorus = (BSPrim)PhysicsScene.PhysObjects[torusLocalID];
148
149 // The actual prim shape creation happens at taint time
150 PhysicsScene.ProcessTaints();
151
152 // Check out the created hull shapes and report their characteristics
153 ReportShapeGeom(primTypeCylinder);
154 ReportShapeGeom(primTypeHollowCylinder);
155 ReportShapeGeom(primTypeTorus);
156 }
157
158 [TestCase]
159 public void GeomHullBulletHACD()
160 {
161 // Cylinder
162 // Hollow Cylinder
163 // Torus
164 }
165
166 private void ReportShapeGeom(BSPrim prim)
167 {
168 if (prim != null)
169 {
170 if (prim.PhysShape.HasPhysicalShape)
171 {
172 BSShape physShape = prim.PhysShape;
173 string shapeType = physShape.GetType().ToString();
174 switch (shapeType)
175 {
176 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeNative":
177 BSShapeNative nShape = physShape as BSShapeNative;
178 prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType);
179 break;
180 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeMesh":
181 BSShapeMesh mShape = physShape as BSShapeMesh;
182 prim.PhysScene.DetailLog("{0}, mesh, shapeInfo={1}", prim.Name, mShape.shapeInfo);
183 break;
184 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeHull":
185 // BSShapeHull hShape = physShape as BSShapeHull;
186 // prim.PhysScene.DetailLog("{0}, hull, shapeInfo={1}", prim.Name, hShape.shapeInfo);
187 break;
188 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeConvexHull":
189 BSShapeConvexHull chShape = physShape as BSShapeConvexHull;
190 prim.PhysScene.DetailLog("{0}, convexHull, shapeInfo={1}", prim.Name, chShape.shapeInfo);
191 break;
192 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeCompound":
193 BSShapeCompound cShape = physShape as BSShapeCompound;
194 prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType);
195 break;
196 default:
197 prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType);
198 break;
199 }
200 }
201 }
202 }
203}
204} \ No newline at end of file