aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/PhysicsModules/BasicPhysics/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsActor.cs19
-rw-r--r--OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsPrim.cs19
-rw-r--r--OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsScene.cs8
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs30
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs318
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs106
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs4
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs2
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActors.cs0
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs141
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs323
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs0
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs10
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs4
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs1
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSParam.cs238
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs123
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs157
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs1
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs7
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSScene.cs329
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs7
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs10
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs24
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs1
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs10
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs112
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs6
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs2
-rwxr-xr-xOpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs124
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/CTri.cs26
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Concavity.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexBuilder.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexDecomposition.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexResult.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullClasses.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullTriangle.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullUtils.cs79
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Plane.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/PlaneTri.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Quaternion.cs18
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/SplitPlane.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/VertexLookup.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float2.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3x3.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4x4.cs170
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int3.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int4.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/HelperTypes.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Mesh.cs87
-rw-r--r--OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs43
-rw-r--r--OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/PrimMesher.cs6
-rw-r--r--OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/SculptMap.cs60
-rw-r--r--OpenSim/Region/PhysicsModules/Meshing/Properties/AssemblyInfo.cs14
-rw-r--r--OpenSim/Region/PhysicsModules/Meshing/ZeroMesher.cs25
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/ODEApi.cs2025
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs33
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs11
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/ODEModule.cs89
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs720
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/ODERayCastRequestManager.cs97
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/OdePhysicsJoint.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/OdeScene.cs980
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/Tests/ODETestClass.cs18
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/drawstuff.cs98
-rw-r--r--OpenSim/Region/PhysicsModules/POS/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/POS/POSCharacter.cs11
-rw-r--r--OpenSim/Region/PhysicsModules/POS/POSPrim.cs5
-rw-r--r--OpenSim/Region/PhysicsModules/POS/POSScene.cs8
-rw-r--r--OpenSim/Region/PhysicsModules/SharedBase/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/SharedBase/IMesher.cs31
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/SharedBase/IPhysicsParameters.cs0
-rw-r--r--OpenSim/Region/PhysicsModules/SharedBase/NullPhysicsScene.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs311
-rw-r--r--OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs85
-rw-r--r--OpenSim/Region/PhysicsModules/SharedBase/PhysicsVector.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/SharedBase/VehicleConstants.cs47
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs2024
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs2036
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs1205
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs946
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs112
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs4256
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs689
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs2824
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODESitAvatar.cs356
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/Properties/AssemblyInfo.cs61
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/HelperTypes.cs340
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs636
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs1602
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs1707
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/Properties/AssemblyInfo.cs36
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMap.cs238
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMesh.cs220
116 files changed, 24079 insertions, 2664 deletions
diff --git a/OpenSim/Region/PhysicsModules/BasicPhysics/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/BasicPhysics/AssemblyInfo.cs
index 1765ae0..68d6eb9 100644
--- a/OpenSim/Region/PhysicsModules/BasicPhysics/AssemblyInfo.cs
+++ b/OpenSim/Region/PhysicsModules/BasicPhysics/AssemblyInfo.cs
@@ -56,7 +56,7 @@ using Mono.Addins;
56// You can specify all values by your own or you can build default build and revision 56// You can specify all values by your own or you can build default build and revision
57// numbers with the '*' character (the default): 57// numbers with the '*' character (the default):
58 58
59[assembly : AssemblyVersion("0.8.2.*")] 59[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
60 60
61[assembly: Addin("OpenSim.Region.PhysicsModule.BasicPhysics", OpenSim.VersionInfo.VersionNumber)] 61[assembly: Addin("OpenSim.Region.PhysicsModule.BasicPhysics", OpenSim.VersionInfo.VersionNumber)]
62[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] 62[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
diff --git a/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsActor.cs b/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsActor.cs
index e7b30ba..67d9207 100644
--- a/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsActor.cs
+++ b/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsActor.cs
@@ -211,7 +211,7 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics
211 { 211 {
212 } 212 }
213 213
214 public override void LockAngularMotion(Vector3 axis) 214 public override void LockAngularMotion(byte axislocks)
215 { 215 {
216 } 216 }
217 217
@@ -254,6 +254,7 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics
254 254
255 public override bool PIDHoverActive 255 public override bool PIDHoverActive
256 { 256 {
257 get { return false; }
257 set { return; } 258 set { return; }
258 } 259 }
259 260
@@ -267,23 +268,23 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics
267 set { return; } 268 set { return; }
268 } 269 }
269 270
270 public override Quaternion APIDTarget 271 public override Quaternion APIDTarget
271 { 272 {
272 set { return; } 273 set { return; }
273 } 274 }
274 275
275 public override bool APIDActive 276 public override bool APIDActive
276 { 277 {
277 set { return; } 278 set { return; }
278 } 279 }
279 280
280 public override float APIDStrength 281 public override float APIDStrength
281 { 282 {
282 set { return; } 283 set { return; }
283 } 284 }
284 285
285 public override float APIDDamping 286 public override float APIDDamping
286 { 287 {
287 set { return; } 288 set { return; }
288 } 289 }
289 290
diff --git a/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsPrim.cs b/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsPrim.cs
index 5383f1b..58c2581 100644
--- a/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsPrim.cs
+++ b/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsPrim.cs
@@ -224,7 +224,7 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics
224 { 224 {
225 } 225 }
226 226
227 public override void LockAngularMotion(Vector3 axis) 227 public override void LockAngularMotion(byte axislocks)
228 { 228 {
229 } 229 }
230 230
@@ -267,6 +267,7 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics
267 267
268 public override bool PIDHoverActive 268 public override bool PIDHoverActive
269 { 269 {
270 get { return false; }
270 set { return; } 271 set { return; }
271 } 272 }
272 273
@@ -280,23 +281,23 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics
280 set { return; } 281 set { return; }
281 } 282 }
282 283
283 public override Quaternion APIDTarget 284 public override Quaternion APIDTarget
284 { 285 {
285 set { return; } 286 set { return; }
286 } 287 }
287 288
288 public override bool APIDActive 289 public override bool APIDActive
289 { 290 {
290 set { return; } 291 set { return; }
291 } 292 }
292 293
293 public override float APIDStrength 294 public override float APIDStrength
294 { 295 {
295 set { return; } 296 set { return; }
296 } 297 }
297 298
298 public override float APIDDamping 299 public override float APIDDamping
299 { 300 {
300 set { return; } 301 set { return; }
301 } 302 }
302 303
diff --git a/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsScene.cs b/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsScene.cs
index 20b337a..2a1ae45 100644
--- a/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsScene.cs
+++ b/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsScene.cs
@@ -61,6 +61,11 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics
61 get { return "basicphysics"; } 61 get { return "basicphysics"; }
62 } 62 }
63 63
64 public string Version
65 {
66 get { return "1.0"; }
67 }
68
64 public Type ReplaceableInterface 69 public Type ReplaceableInterface
65 { 70 {
66 get { return null; } 71 get { return null; }
@@ -90,6 +95,7 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics
90 95
91 EngineType = Name; 96 EngineType = Name;
92 PhysicsSceneName = EngineType + "/" + scene.RegionInfo.RegionName; 97 PhysicsSceneName = EngineType + "/" + scene.RegionInfo.RegionName;
98 EngineName = Name + " " + Version;
93 99
94 scene.RegisterModuleInterface<PhysicsScene>(this); 100 scene.RegisterModuleInterface<PhysicsScene>(this);
95 m_regionExtent = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, scene.RegionInfo.RegionSizeZ); 101 m_regionExtent = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, scene.RegionInfo.RegionSizeZ);
@@ -220,7 +226,7 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics
220 actor.Velocity = actorVelocity; 226 actor.Velocity = actorVelocity;
221 } 227 }
222 228
223 return fps; 229 return 1.0f;
224 } 230 }
225 231
226 public override void GetResults() 232 public override void GetResults()
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs b/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs
index c4a923c..840e453 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs
@@ -155,8 +155,8 @@ public BSAPIUnman(string paramName, BSScene physScene)
155 155
156// Initialization and simulation 156// Initialization and simulation
157public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, 157public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms,
158 int maxCollisions, ref CollisionDesc[] collisionArray, 158 int maxCollisions, ref CollisionDesc[] collisionArray,
159 int maxUpdates, ref EntityProperties[] updateArray 159 int maxUpdates, ref EntityProperties[] updateArray
160 ) 160 )
161{ 161{
162 // Pin down the memory that will be used to pass object collisions and updates back from unmanaged code 162 // Pin down the memory that will be used to pass object collisions and updates back from unmanaged code
@@ -1405,6 +1405,19 @@ public override float GetMargin(BulletShape shape)
1405} 1405}
1406 1406
1407// ===================================================================================== 1407// =====================================================================================
1408// Raycast
1409public override SweepHit ConvexSweepTest2(BulletWorld world, BulletBody sweepObject, Vector3 from, Vector3 to, float margin) {
1410 BulletWorldUnman worldu = world as BulletWorldUnman;
1411 BulletBodyUnman bodyu = sweepObject as BulletBodyUnman;
1412 return BSAPICPP.ConvexSweepTest2(worldu.ptr, bodyu.ptr, from, to, margin);
1413}
1414
1415public override RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask) {
1416 BulletWorldUnman worldu = world as BulletWorldUnman;
1417 return BSAPICPP.RayTest2(worldu.ptr, from, to, filterGroup, filterMask);
1418}
1419
1420// =====================================================================================
1408// Debugging 1421// Debugging
1409public override void DumpRigidBody(BulletWorld world, BulletBody collisionObject) 1422public override void DumpRigidBody(BulletWorld world, BulletBody collisionObject)
1410{ 1423{
@@ -1472,8 +1485,8 @@ public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg
1472// Initialization and simulation 1485// Initialization and simulation
1473[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1486[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1474public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, 1487public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
1475 int maxCollisions, IntPtr collisionArray, 1488 int maxCollisions, IntPtr collisionArray,
1476 int maxUpdates, IntPtr updateArray, 1489 int maxUpdates, IntPtr updateArray,
1477 DebugLogCallback logRoutine); 1490 DebugLogCallback logRoutine);
1478 1491
1479[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1492[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@@ -2084,6 +2097,15 @@ public static extern void SetMargin2(IntPtr shape, float val);
2084[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 2097[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
2085public static extern float GetMargin2(IntPtr shape); 2098public static extern float GetMargin2(IntPtr shape);
2086 2099
2100
2101// =====================================================================================
2102// Raycast
2103[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
2104public static extern SweepHit ConvexSweepTest2(IntPtr sim, IntPtr obj, Vector3 from, Vector3 to, float margin);
2105
2106[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
2107public static extern RaycastHit RayTest2(IntPtr sim, Vector3 from, Vector3 to, uint filterGroup, uint filterMask);
2108
2087// ===================================================================================== 2109// =====================================================================================
2088// Debugging 2110// Debugging
2089[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 2111[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs b/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs
index 887311d..7d58728 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs
@@ -815,161 +815,161 @@ private sealed class BulletConstraintXNA : BulletConstraint
815 public override bool SliderSetLimits(BulletConstraint pConstraint, int lowerUpper, int linAng, float val) 815 public override bool SliderSetLimits(BulletConstraint pConstraint, int lowerUpper, int linAng, float val)
816 { 816 {
817 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint; 817 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
818 switch (lowerUpper) 818 switch (lowerUpper)
819 { 819 {
820 case SLIDER_LOWER_LIMIT: 820 case SLIDER_LOWER_LIMIT:
821 switch (linAng) 821 switch (linAng)
822 { 822 {
823 case SLIDER_LINEAR: 823 case SLIDER_LINEAR:
824 constraint.SetLowerLinLimit(val); 824 constraint.SetLowerLinLimit(val);
825 break; 825 break;
826 case SLIDER_ANGULAR: 826 case SLIDER_ANGULAR:
827 constraint.SetLowerAngLimit(val); 827 constraint.SetLowerAngLimit(val);
828 break; 828 break;
829 } 829 }
830 break; 830 break;
831 case SLIDER_UPPER_LIMIT: 831 case SLIDER_UPPER_LIMIT:
832 switch (linAng) 832 switch (linAng)
833 { 833 {
834 case SLIDER_LINEAR: 834 case SLIDER_LINEAR:
835 constraint.SetUpperLinLimit(val); 835 constraint.SetUpperLinLimit(val);
836 break; 836 break;
837 case SLIDER_ANGULAR: 837 case SLIDER_ANGULAR:
838 constraint.SetUpperAngLimit(val); 838 constraint.SetUpperAngLimit(val);
839 break; 839 break;
840 } 840 }
841 break; 841 break;
842 } 842 }
843 return true; 843 return true;
844 } 844 }
845 public override bool SliderSet(BulletConstraint pConstraint, int softRestDamp, int dirLimOrtho, int linAng, float val) 845 public override bool SliderSet(BulletConstraint pConstraint, int softRestDamp, int dirLimOrtho, int linAng, float val)
846 { 846 {
847 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint; 847 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
848 switch (softRestDamp) 848 switch (softRestDamp)
849 { 849 {
850 case SLIDER_SET_SOFTNESS: 850 case SLIDER_SET_SOFTNESS:
851 switch (dirLimOrtho) 851 switch (dirLimOrtho)
852 { 852 {
853 case SLIDER_SET_DIRECTION: 853 case SLIDER_SET_DIRECTION:
854 switch (linAng) 854 switch (linAng)
855 { 855 {
856 case SLIDER_LINEAR: constraint.SetSoftnessDirLin(val); break; 856 case SLIDER_LINEAR: constraint.SetSoftnessDirLin(val); break;
857 case SLIDER_ANGULAR: constraint.SetSoftnessDirAng(val); break; 857 case SLIDER_ANGULAR: constraint.SetSoftnessDirAng(val); break;
858 } 858 }
859 break; 859 break;
860 case SLIDER_SET_LIMIT: 860 case SLIDER_SET_LIMIT:
861 switch (linAng) 861 switch (linAng)
862 { 862 {
863 case SLIDER_LINEAR: constraint.SetSoftnessLimLin(val); break; 863 case SLIDER_LINEAR: constraint.SetSoftnessLimLin(val); break;
864 case SLIDER_ANGULAR: constraint.SetSoftnessLimAng(val); break; 864 case SLIDER_ANGULAR: constraint.SetSoftnessLimAng(val); break;
865 } 865 }
866 break; 866 break;
867 case SLIDER_SET_ORTHO: 867 case SLIDER_SET_ORTHO:
868 switch (linAng) 868 switch (linAng)
869 { 869 {
870 case SLIDER_LINEAR: constraint.SetSoftnessOrthoLin(val); break; 870 case SLIDER_LINEAR: constraint.SetSoftnessOrthoLin(val); break;
871 case SLIDER_ANGULAR: constraint.SetSoftnessOrthoAng(val); break; 871 case SLIDER_ANGULAR: constraint.SetSoftnessOrthoAng(val); break;
872 } 872 }
873 break; 873 break;
874 } 874 }
875 break; 875 break;
876 case SLIDER_SET_RESTITUTION: 876 case SLIDER_SET_RESTITUTION:
877 switch (dirLimOrtho) 877 switch (dirLimOrtho)
878 { 878 {
879 case SLIDER_SET_DIRECTION: 879 case SLIDER_SET_DIRECTION:
880 switch (linAng) 880 switch (linAng)
881 { 881 {
882 case SLIDER_LINEAR: constraint.SetRestitutionDirLin(val); break; 882 case SLIDER_LINEAR: constraint.SetRestitutionDirLin(val); break;
883 case SLIDER_ANGULAR: constraint.SetRestitutionDirAng(val); break; 883 case SLIDER_ANGULAR: constraint.SetRestitutionDirAng(val); break;
884 } 884 }
885 break; 885 break;
886 case SLIDER_SET_LIMIT: 886 case SLIDER_SET_LIMIT:
887 switch (linAng) 887 switch (linAng)
888 { 888 {
889 case SLIDER_LINEAR: constraint.SetRestitutionLimLin(val); break; 889 case SLIDER_LINEAR: constraint.SetRestitutionLimLin(val); break;
890 case SLIDER_ANGULAR: constraint.SetRestitutionLimAng(val); break; 890 case SLIDER_ANGULAR: constraint.SetRestitutionLimAng(val); break;
891 } 891 }
892 break; 892 break;
893 case SLIDER_SET_ORTHO: 893 case SLIDER_SET_ORTHO:
894 switch (linAng) 894 switch (linAng)
895 { 895 {
896 case SLIDER_LINEAR: constraint.SetRestitutionOrthoLin(val); break; 896 case SLIDER_LINEAR: constraint.SetRestitutionOrthoLin(val); break;
897 case SLIDER_ANGULAR: constraint.SetRestitutionOrthoAng(val); break; 897 case SLIDER_ANGULAR: constraint.SetRestitutionOrthoAng(val); break;
898 } 898 }
899 break; 899 break;
900 } 900 }
901 break; 901 break;
902 case SLIDER_SET_DAMPING: 902 case SLIDER_SET_DAMPING:
903 switch (dirLimOrtho) 903 switch (dirLimOrtho)
904 { 904 {
905 case SLIDER_SET_DIRECTION: 905 case SLIDER_SET_DIRECTION:
906 switch (linAng) 906 switch (linAng)
907 { 907 {
908 case SLIDER_LINEAR: constraint.SetDampingDirLin(val); break; 908 case SLIDER_LINEAR: constraint.SetDampingDirLin(val); break;
909 case SLIDER_ANGULAR: constraint.SetDampingDirAng(val); break; 909 case SLIDER_ANGULAR: constraint.SetDampingDirAng(val); break;
910 } 910 }
911 break; 911 break;
912 case SLIDER_SET_LIMIT: 912 case SLIDER_SET_LIMIT:
913 switch (linAng) 913 switch (linAng)
914 { 914 {
915 case SLIDER_LINEAR: constraint.SetDampingLimLin(val); break; 915 case SLIDER_LINEAR: constraint.SetDampingLimLin(val); break;
916 case SLIDER_ANGULAR: constraint.SetDampingLimAng(val); break; 916 case SLIDER_ANGULAR: constraint.SetDampingLimAng(val); break;
917 } 917 }
918 break; 918 break;
919 case SLIDER_SET_ORTHO: 919 case SLIDER_SET_ORTHO:
920 switch (linAng) 920 switch (linAng)
921 { 921 {
922 case SLIDER_LINEAR: constraint.SetDampingOrthoLin(val); break; 922 case SLIDER_LINEAR: constraint.SetDampingOrthoLin(val); break;
923 case SLIDER_ANGULAR: constraint.SetDampingOrthoAng(val); break; 923 case SLIDER_ANGULAR: constraint.SetDampingOrthoAng(val); break;
924 } 924 }
925 break; 925 break;
926 } 926 }
927 break; 927 break;
928 } 928 }
929 return true; 929 return true;
930 } 930 }
931 public override bool SliderMotorEnable(BulletConstraint pConstraint, int linAng, float numericTrueFalse) 931 public override bool SliderMotorEnable(BulletConstraint pConstraint, int linAng, float numericTrueFalse)
932 { 932 {
933 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint; 933 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
934 switch (linAng) 934 switch (linAng)
935 { 935 {
936 case SLIDER_LINEAR: 936 case SLIDER_LINEAR:
937 constraint.SetPoweredLinMotor(numericTrueFalse == 0.0 ? false : true); 937 constraint.SetPoweredLinMotor(numericTrueFalse == 0.0 ? false : true);
938 break; 938 break;
939 case SLIDER_ANGULAR: 939 case SLIDER_ANGULAR:
940 constraint.SetPoweredAngMotor(numericTrueFalse == 0.0 ? false : true); 940 constraint.SetPoweredAngMotor(numericTrueFalse == 0.0 ? false : true);
941 break; 941 break;
942 } 942 }
943 return true; 943 return true;
944 } 944 }
945 public override bool SliderMotor(BulletConstraint pConstraint, int forceVel, int linAng, float val) 945 public override bool SliderMotor(BulletConstraint pConstraint, int forceVel, int linAng, float val)
946 { 946 {
947 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint; 947 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
948 switch (forceVel) 948 switch (forceVel)
949 { 949 {
950 case SLIDER_MOTOR_VELOCITY: 950 case SLIDER_MOTOR_VELOCITY:
951 switch (linAng) 951 switch (linAng)
952 { 952 {
953 case SLIDER_LINEAR: 953 case SLIDER_LINEAR:
954 constraint.SetTargetLinMotorVelocity(val); 954 constraint.SetTargetLinMotorVelocity(val);
955 break; 955 break;
956 case SLIDER_ANGULAR: 956 case SLIDER_ANGULAR:
957 constraint.SetTargetAngMotorVelocity(val); 957 constraint.SetTargetAngMotorVelocity(val);
958 break; 958 break;
959 } 959 }
960 break; 960 break;
961 case SLIDER_MAX_MOTOR_FORCE: 961 case SLIDER_MAX_MOTOR_FORCE:
962 switch (linAng) 962 switch (linAng)
963 { 963 {
964 case SLIDER_LINEAR: 964 case SLIDER_LINEAR:
965 constraint.SetMaxLinMotorForce(val); 965 constraint.SetMaxLinMotorForce(val);
966 break; 966 break;
967 case SLIDER_ANGULAR: 967 case SLIDER_ANGULAR:
968 constraint.SetMaxAngMotorForce(val); 968 constraint.SetMaxAngMotorForce(val);
969 break; 969 break;
970 } 970 }
971 break; 971 break;
972 } 972 }
973 return true; 973 return true;
974 } 974 }
975 975
@@ -1197,20 +1197,20 @@ private sealed class BulletConstraintXNA : BulletConstraint
1197 }; 1197 };
1198 /* 1198 /*
1199 m_mass = mass; 1199 m_mass = mass;
1200 m_motionState =motionState; 1200 m_motionState =motionState;
1201 m_collisionShape = collisionShape; 1201 m_collisionShape = collisionShape;
1202 m_localInertia = localInertia; 1202 m_localInertia = localInertia;
1203 m_linearDamping = 0f; 1203 m_linearDamping = 0f;
1204 m_angularDamping = 0f; 1204 m_angularDamping = 0f;
1205 m_friction = 0.5f; 1205 m_friction = 0.5f;
1206 m_restitution = 0f; 1206 m_restitution = 0f;
1207 m_linearSleepingThreshold = 0.8f; 1207 m_linearSleepingThreshold = 0.8f;
1208 m_angularSleepingThreshold = 1f; 1208 m_angularSleepingThreshold = 1f;
1209 m_additionalDamping = false; 1209 m_additionalDamping = false;
1210 m_additionalDampingFactor = 0.005f; 1210 m_additionalDampingFactor = 0.005f;
1211 m_additionalLinearDampingThresholdSqr = 0.01f; 1211 m_additionalLinearDampingThresholdSqr = 0.01f;
1212 m_additionalAngularDampingThresholdSqr = 0.01f; 1212 m_additionalAngularDampingThresholdSqr = 0.01f;
1213 m_additionalAngularDampingFactor = 0.01f; 1213 m_additionalAngularDampingFactor = 0.01f;
1214 m_startWorldTransform = IndexedMatrix.Identity; 1214 m_startWorldTransform = IndexedMatrix.Identity;
1215 */ 1215 */
1216 body.SetUserPointer(pLocalID); 1216 body.SetUserPointer(pLocalID);
@@ -2172,7 +2172,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
2172 } 2172 }
2173 2173
2174 public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, 2174 public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
2175 float scaleFactor, float collisionMargin) 2175 float scaleFactor, float collisionMargin)
2176 { 2176 {
2177 const int upAxis = 2; 2177 const int upAxis = 2;
2178 HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)size.X, (int)size.Y, 2178 HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)size.X, (int)size.Y,
@@ -2459,6 +2459,14 @@ private sealed class BulletConstraintXNA : BulletConstraint
2459 } 2459 }
2460 return false; 2460 return false;
2461 } 2461 }
2462
2463 public override SweepHit ConvexSweepTest2(BulletWorld world, BulletBody obj, Vector3 from, Vector3 to, float margin) {
2464 return new SweepHit();
2465 }
2466
2467 public override RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask) {
2468 return new RaycastHit();
2469 }
2462} 2470}
2463 2471
2464 2472
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs
index 0191893..40c6b98 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs
@@ -47,10 +47,9 @@ public class BSActorAvatarMove : BSActor
47 // The amount the step up is applying. Used to smooth stair walking. 47 // The amount the step up is applying. Used to smooth stair walking.
48 float m_lastStepUp; 48 float m_lastStepUp;
49 49
50 // Jumping happens over several frames. If use applies up force while colliding, start the 50 // There are times the velocity is set but we don't want to inforce stationary until the
51 // jump and allow the jump to continue for this number of frames. 51 // real velocity drops.
52 int m_jumpFrames = 0; 52 bool m_waitingForLowVelocityForStationary = false;
53 float m_jumpVelocity = 0f;
54 53
55 public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) 54 public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName)
56 : base(physicsScene, pObj, actorName) 55 : base(physicsScene, pObj, actorName)
@@ -109,19 +108,23 @@ public class BSActorAvatarMove : BSActor
109 { 108 {
110 if (m_velocityMotor != null) 109 if (m_velocityMotor != null)
111 { 110 {
112// if (targ == OMV.Vector3.Zero)
113// Util.PrintCallStack();
114//
115// Console.WriteLine("SetVelocityAndTarget, {0} {1}", vel, targ);
116 m_velocityMotor.Reset(); 111 m_velocityMotor.Reset();
117 m_velocityMotor.SetTarget(targ); 112 m_velocityMotor.SetTarget(targ);
118 m_velocityMotor.SetCurrent(vel); 113 m_velocityMotor.SetCurrent(vel);
119 m_velocityMotor.Enabled = true; 114 m_velocityMotor.Enabled = true;
115 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}",
116 m_controllingPrim.LocalID, vel, targ);
117 m_waitingForLowVelocityForStationary = false;
120 } 118 }
121 }); 119 });
122 } 120 }
123 121
124 // If a hover motor has not been created, create one and start the hovering. 122 public void SuppressStationayCheckUntilLowVelocity()
123 {
124 m_waitingForLowVelocityForStationary = true;
125 }
126
127 // If a movement motor has not been created, create one and start the movement
125 private void ActivateAvatarMove() 128 private void ActivateAvatarMove()
126 { 129 {
127 if (m_velocityMotor == null) 130 if (m_velocityMotor == null)
@@ -133,13 +136,14 @@ public class BSActorAvatarMove : BSActor
133 1f // efficiency 136 1f // efficiency
134 ); 137 );
135 m_velocityMotor.ErrorZeroThreshold = BSParam.AvatarStopZeroThreshold; 138 m_velocityMotor.ErrorZeroThreshold = BSParam.AvatarStopZeroThreshold;
136 // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. 139 // m_velocityMotor.PhysicsScene = m_controllingPrim.PhysScene; // DEBUG DEBUG so motor will output detail log messages.
137 SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); 140 SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
138 141
139 m_physicsScene.BeforeStep += Mover; 142 m_physicsScene.BeforeStep += Mover;
140 m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty; 143 m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty;
141 144
142 m_walkingUpStairs = 0; 145 m_walkingUpStairs = 0;
146 m_waitingForLowVelocityForStationary = false;
143 } 147 }
144 } 148 }
145 149
@@ -153,7 +157,7 @@ public class BSActorAvatarMove : BSActor
153 } 157 }
154 } 158 }
155 159
156 // Called just before the simulation step. Update the vertical position for hoverness. 160 // Called just before the simulation step.
157 private void Mover(float timeStep) 161 private void Mover(float timeStep)
158 { 162 {
159 // Don't do movement while the object is selected. 163 // Don't do movement while the object is selected.
@@ -187,12 +191,28 @@ public class BSActorAvatarMove : BSActor
187 191
188 if (m_controllingPrim.IsColliding) 192 if (m_controllingPrim.IsColliding)
189 { 193 {
190 // If we are colliding with a stationary object, presume we're standing and don't move around 194 // if colliding with something stationary and we're not doing volume detect .
191 if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect) 195 if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect)
192 { 196 {
193 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); 197 if (m_waitingForLowVelocityForStationary)
194 m_controllingPrim.IsStationary = true; 198 {
195 m_controllingPrim.ZeroMotion(true /* inTaintTime */); 199 // if waiting for velocity to drop and it has finally dropped, we can be stationary
200 if (m_controllingPrim.RawVelocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared)
201 {
202 m_waitingForLowVelocityForStationary = false;
203 }
204 }
205 if (!m_waitingForLowVelocityForStationary)
206 {
207 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
208 m_controllingPrim.IsStationary = true;
209 m_controllingPrim.ZeroMotion(true /* inTaintTime */);
210 }
211 else
212 {
213 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,waitingForLowVel,rawvel={1}",
214 m_controllingPrim.LocalID, m_controllingPrim.RawVelocity.Length());
215 }
196 } 216 }
197 217
198 // Standing has more friction on the ground 218 // Standing has more friction on the ground
@@ -222,8 +242,8 @@ public class BSActorAvatarMove : BSActor
222 } 242 }
223 } 243 }
224 244
225 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", 245 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2},isStationary={3}",
226 m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding); 246 m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding,m_controllingPrim.IsStationary);
227 } 247 }
228 else 248 else
229 { 249 {
@@ -237,50 +257,24 @@ public class BSActorAvatarMove : BSActor
237 m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction); 257 m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
238 } 258 }
239 259
240 if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding) 260 // 'm_velocityMotor is used for walking, flying, and jumping and will thus have the correct values
241 { 261 // for Z. But in come cases it must be over-ridden. Like when falling or jumping.
242 stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
243 }
244 262
245 // Colliding and not flying with an upward force. The avatar must be trying to jump. 263 float realVelocityZ = m_controllingPrim.RawVelocity.Z;
246 if (!m_controllingPrim.Flying && m_controllingPrim.IsColliding && stepVelocity.Z > 0)
247 {
248 // We allow the upward force to happen for this many frames.
249 m_jumpFrames = BSParam.AvatarJumpFrames;
250 m_jumpVelocity = stepVelocity.Z;
251 }
252 264
253 // The case where the avatar is not colliding and is not flying is special. 265 // If not flying and falling, we over-ride the stepping motor so we can fall to the ground
254 // The avatar is either falling or jumping and the user can be applying force to the avatar 266 if (!m_controllingPrim.Flying && realVelocityZ < 0)
255 // (force in some direction or force up or down).
256 // If the avatar has negative Z velocity and is not colliding, presume we're falling and keep the velocity.
257 // If the user is trying to apply upward force but we're not colliding, assume the avatar
258 // is trying to jump and don't apply the upward force if not touching the ground any more.
259 if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
260 { 267 {
261 // If upward velocity is being applied, this must be a jump and only allow that to go on so long 268 // Can't fall faster than this
262 if (m_jumpFrames > 0) 269 if (realVelocityZ < BSParam.AvatarTerminalVelocity)
263 { 270 {
264 // Since not touching the ground, only apply upward force for so long. 271 realVelocityZ = BSParam.AvatarTerminalVelocity;
265 m_jumpFrames--;
266 stepVelocity.Z = m_jumpVelocity;
267 } 272 }
268 else 273
269 { 274 stepVelocity.Z = realVelocityZ;
270
271 // Since we're not affected by anything, the avatar must be falling and we do not want that to be too fast.
272 if (m_controllingPrim.RawVelocity.Z < BSParam.AvatarTerminalVelocity)
273 {
274
275 stepVelocity.Z = BSParam.AvatarTerminalVelocity;
276 }
277 else
278 {
279 stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
280 }
281 }
282 // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
283 } 275 }
276 // m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,DEBUG,motorCurrent={1},realZ={2},flying={3},collid={4},jFrames={5}",
277 // m_controllingPrim.LocalID, m_velocityMotor.CurrentValue, realVelocityZ, m_controllingPrim.Flying, m_controllingPrim.IsColliding, m_jumpFrames);
284 278
285 //Alicia: Maintain minimum height when flying. 279 //Alicia: Maintain minimum height when flying.
286 // SL has a flying effect that keeps the avatar flying above the ground by some margin 280 // SL has a flying effect that keeps the avatar flying above the ground by some margin
@@ -291,6 +285,8 @@ public class BSActorAvatarMove : BSActor
291 285
292 if( m_controllingPrim.Position.Z < hover_height) 286 if( m_controllingPrim.Position.Z < hover_height)
293 { 287 {
288 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,addingUpforceForGroundMargin,height={1},hoverHeight={2}",
289 m_controllingPrim.LocalID, m_controllingPrim.Position.Z, hover_height);
294 stepVelocity.Z += BSParam.AvatarFlyingGroundUpForce; 290 stepVelocity.Z += BSParam.AvatarFlyingGroundUpForce;
295 } 291 }
296 } 292 }
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs
index 7ff171e..7ff171e 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs
index 78c1b6a..78c1b6a 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs
index 3db8f2c..f2019ae 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs
@@ -205,13 +205,13 @@ public class BSActorMoveToTarget : BSActor
205 addedForce = correctionVector / timeStep; 205 addedForce = correctionVector / timeStep;
206 // Remove the existing velocity (only the moveToTarget force counts) 206 // Remove the existing velocity (only the moveToTarget force counts)
207 addedForce -= m_controllingPrim.RawVelocity; 207 addedForce -= m_controllingPrim.RawVelocity;
208 // Overcome gravity. 208 // Overcome gravity.
209 addedForce -= m_controllingPrim.Gravity; 209 addedForce -= m_controllingPrim.Gravity;
210 210
211 // Add enough force to overcome the mass of the object 211 // Add enough force to overcome the mass of the object
212 addedForce *= m_controllingPrim.Mass; 212 addedForce *= m_controllingPrim.Mass;
213 213
214 m_controllingPrim.AddForce(addedForce, false /* pushForce */, true /* inTaintTime */); 214 m_controllingPrim.AddForce(true /* inTaintTime */, addedForce);
215 } 215 }
216 m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover3,move,fromPos={1},addedForce={2}", 216 m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover3,move,fromPos={1},addedForce={2}",
217 m_controllingPrim.LocalID, origPosition, addedForce); 217 m_controllingPrim.LocalID, origPosition, addedForce);
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs
index ecb4b7f..ecb4b7f 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs
index a1cf4db..0261bcb 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs
@@ -127,7 +127,7 @@ public class BSActorSetTorque : BSActor
127 m_physicsScene.DetailLog("{0},BSActorSetTorque,preStep,force={1}", m_controllingPrim.LocalID, m_controllingPrim.RawTorque); 127 m_physicsScene.DetailLog("{0},BSActorSetTorque,preStep,force={1}", m_controllingPrim.LocalID, m_controllingPrim.RawTorque);
128 if (m_controllingPrim.PhysBody.HasPhysicalBody) 128 if (m_controllingPrim.PhysBody.HasPhysicalBody)
129 { 129 {
130 m_controllingPrim.AddAngularForce(m_controllingPrim.RawTorque, false, true); 130 m_controllingPrim.AddAngularForce(true /* inTaintTime */, m_controllingPrim.RawTorque);
131 m_controllingPrim.ActivateIfPhysical(false); 131 m_controllingPrim.ActivateIfPhysical(false);
132 } 132 }
133 133
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActors.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActors.cs
index 851347b..851347b 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActors.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActors.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs
index 7756b10..a288048 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs
@@ -36,16 +36,16 @@ namespace OpenSim.Region.PhysicsModule.BulletS {
36 // Constraint type values as defined by Bullet 36 // Constraint type values as defined by Bullet
37public enum ConstraintType : int 37public enum ConstraintType : int
38{ 38{
39 POINT2POINT_CONSTRAINT_TYPE = 3, 39 POINT2POINT_CONSTRAINT_TYPE = 3,
40 HINGE_CONSTRAINT_TYPE, 40 HINGE_CONSTRAINT_TYPE,
41 CONETWIST_CONSTRAINT_TYPE, 41 CONETWIST_CONSTRAINT_TYPE,
42 D6_CONSTRAINT_TYPE, 42 D6_CONSTRAINT_TYPE,
43 SLIDER_CONSTRAINT_TYPE, 43 SLIDER_CONSTRAINT_TYPE,
44 CONTACT_CONSTRAINT_TYPE, 44 CONTACT_CONSTRAINT_TYPE,
45 D6_SPRING_CONSTRAINT_TYPE, 45 D6_SPRING_CONSTRAINT_TYPE,
46 GEAR_CONSTRAINT_TYPE, // added in Bullet 2.82 46 GEAR_CONSTRAINT_TYPE, // added in Bullet 2.82
47 FIXED_CONSTRAINT_TYPE, // added in Bullet 2.82 47 FIXED_CONSTRAINT_TYPE, // added in Bullet 2.82
48 MAX_CONSTRAINT_TYPE, // last type defined by Bullet 48 MAX_CONSTRAINT_TYPE, // last type defined by Bullet
49 // 49 //
50 BS_FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving 50 BS_FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving
51} 51}
@@ -54,25 +54,25 @@ public enum ConstraintType : int
54[StructLayout(LayoutKind.Sequential)] 54[StructLayout(LayoutKind.Sequential)]
55public struct ConvexHull 55public struct ConvexHull
56{ 56{
57 Vector3 Offset; 57 Vector3 Offset;
58 int VertexCount; 58 int VertexCount;
59 Vector3[] Vertices; 59 Vector3[] Vertices;
60} 60}
61public enum BSPhysicsShapeType 61public enum BSPhysicsShapeType
62{ 62{
63 SHAPE_UNKNOWN = 0, 63 SHAPE_UNKNOWN = 0,
64 SHAPE_CAPSULE = 1, 64 SHAPE_CAPSULE = 1,
65 SHAPE_BOX = 2, 65 SHAPE_BOX = 2,
66 SHAPE_CONE = 3, 66 SHAPE_CONE = 3,
67 SHAPE_CYLINDER = 4, 67 SHAPE_CYLINDER = 4,
68 SHAPE_SPHERE = 5, 68 SHAPE_SPHERE = 5,
69 SHAPE_MESH = 6, 69 SHAPE_MESH = 6,
70 SHAPE_HULL = 7, 70 SHAPE_HULL = 7,
71 // following defined by BulletSim 71 // following defined by BulletSim
72 SHAPE_GROUNDPLANE = 20, 72 SHAPE_GROUNDPLANE = 20,
73 SHAPE_TERRAIN = 21, 73 SHAPE_TERRAIN = 21,
74 SHAPE_COMPOUND = 22, 74 SHAPE_COMPOUND = 22,
75 SHAPE_HEIGHTMAP = 23, 75 SHAPE_HEIGHTMAP = 23,
76 SHAPE_AVATAR = 24, 76 SHAPE_AVATAR = 24,
77 SHAPE_CONVEXHULL= 25, 77 SHAPE_CONVEXHULL= 25,
78 SHAPE_GIMPACT = 26, 78 SHAPE_GIMPACT = 26,
@@ -121,6 +121,14 @@ public struct SweepHit
121 public float Fraction; 121 public float Fraction;
122 public Vector3 Normal; 122 public Vector3 Normal;
123 public Vector3 Point; 123 public Vector3 Point;
124
125 public bool hasHit()
126 {
127 float sum = Fraction
128 + Normal.X + Normal.Y + Normal.Z
129 + Point.X + Point.Y + Point.Z;
130 return (sum != 0) || (ID != 0);
131 }
124} 132}
125[StructLayout(LayoutKind.Sequential)] 133[StructLayout(LayoutKind.Sequential)]
126public struct RaycastHit 134public struct RaycastHit
@@ -128,6 +136,13 @@ public struct RaycastHit
128 public UInt32 ID; 136 public UInt32 ID;
129 public float Fraction; 137 public float Fraction;
130 public Vector3 Normal; 138 public Vector3 Normal;
139 public Vector3 Point;
140
141 public bool hasHit()
142 {
143 float sum = Normal.X + Normal.Y + Normal.Z + Point.X + Point.Y + Point.Z;
144 return (sum != 0);
145 }
131} 146}
132[StructLayout(LayoutKind.Sequential)] 147[StructLayout(LayoutKind.Sequential)]
133public struct CollisionDesc 148public struct CollisionDesc
@@ -180,16 +195,16 @@ public struct ConfigurationParameters
180 public float collisionMargin; 195 public float collisionMargin;
181 public float gravity; 196 public float gravity;
182 197
183 public float maxPersistantManifoldPoolSize; 198 public float maxPersistantManifoldPoolSize;
184 public float maxCollisionAlgorithmPoolSize; 199 public float maxCollisionAlgorithmPoolSize;
185 public float shouldDisableContactPoolDynamicAllocation; 200 public float shouldDisableContactPoolDynamicAllocation;
186 public float shouldForceUpdateAllAabbs; 201 public float shouldForceUpdateAllAabbs;
187 public float shouldRandomizeSolverOrder; 202 public float shouldRandomizeSolverOrder;
188 public float shouldSplitSimulationIslands; 203 public float shouldSplitSimulationIslands;
189 public float shouldEnableFrictionCaching; 204 public float shouldEnableFrictionCaching;
190 public float numberOfSolverIterations; 205 public float numberOfSolverIterations;
191 public float useSingleSidedMeshes; 206 public float useSingleSidedMeshes;
192 public float globalContactBreakingThreshold; 207 public float globalContactBreakingThreshold;
193 208
194 public float physicsLoggingFrames; 209 public float physicsLoggingFrames;
195 210
@@ -202,30 +217,30 @@ public struct ConfigurationParameters
202public struct HACDParams 217public struct HACDParams
203{ 218{
204 // usual default values 219 // usual default values
205 public float maxVerticesPerHull; // 100 220 public float maxVerticesPerHull; // 100
206 public float minClusters; // 2 221 public float minClusters; // 2
207 public float compacityWeight; // 0.1 222 public float compacityWeight; // 0.1
208 public float volumeWeight; // 0.0 223 public float volumeWeight; // 0.0
209 public float concavity; // 100 224 public float concavity; // 100
210 public float addExtraDistPoints; // false 225 public float addExtraDistPoints; // false
211 public float addNeighboursDistPoints; // false 226 public float addNeighboursDistPoints; // false
212 public float addFacesPoints; // false 227 public float addFacesPoints; // false
213 public float shouldAdjustCollisionMargin; // false 228 public float shouldAdjustCollisionMargin; // false
214 // VHACD 229 // VHACD
215 public float whichHACD; // zero if Bullet HACD, non-zero says VHACD 230 public float whichHACD; // zero if Bullet HACD, non-zero says VHACD
216 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html 231 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html
217 public float vHACDresolution; // 100,000 max number of voxels generated during voxelization stage 232 public float vHACDresolution; // 100,000 max number of voxels generated during voxelization stage
218 public float vHACDdepth; // 20 max number of clipping stages 233 public float vHACDdepth; // 20 max number of clipping stages
219 public float vHACDconcavity; // 0.0025 maximum concavity 234 public float vHACDconcavity; // 0.0025 maximum concavity
220 public float vHACDplaneDownsampling; // 4 granularity of search for best clipping plane 235 public float vHACDplaneDownsampling; // 4 granularity of search for best clipping plane
221 public float vHACDconvexHullDownsampling; // 4 precision of hull gen process 236 public float vHACDconvexHullDownsampling; // 4 precision of hull gen process
222 public float vHACDalpha; // 0.05 bias toward clipping along symmetry planes 237 public float vHACDalpha; // 0.05 bias toward clipping along symmetry planes
223 public float vHACDbeta; // 0.05 bias toward clipping along revolution axis 238 public float vHACDbeta; // 0.05 bias toward clipping along revolution axis
224 public float vHACDgamma; // 0.00125 max concavity when merging 239 public float vHACDgamma; // 0.00125 max concavity when merging
225 public float vHACDpca; // 0 on/off normalizing mesh before decomp 240 public float vHACDpca; // 0 on/off normalizing mesh before decomp
226 public float vHACDmode; // 0 0:voxel based, 1: tetrahedron based 241 public float vHACDmode; // 0 0:voxel based, 1: tetrahedron based
227 public float vHACDmaxNumVerticesPerCH; // 64 max triangles per convex hull 242 public float vHACDmaxNumVerticesPerCH; // 64 max triangles per convex hull
228 public float vHACDminVolumePerCH; // 0.0001 sampling of generated convex hulls 243 public float vHACDminVolumePerCH; // 0.0001 sampling of generated convex hulls
229} 244}
230 245
231// The states a bullet collision object can have 246// The states a bullet collision object can have
@@ -322,8 +337,8 @@ public abstract string BulletEngineVersion { get; protected set;}
322 337
323// Initialization and simulation 338// Initialization and simulation
324public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, 339public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms,
325 int maxCollisions, ref CollisionDesc[] collisionArray, 340 int maxCollisions, ref CollisionDesc[] collisionArray,
326 int maxUpdates, ref EntityProperties[] updateArray 341 int maxUpdates, ref EntityProperties[] updateArray
327 ); 342 );
328 343
329public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, 344public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep,
@@ -398,7 +413,7 @@ public abstract void DestroyObject(BulletWorld sim, BulletBody obj);
398public abstract BulletShape CreateGroundPlaneShape(UInt32 id, float height, float collisionMargin); 413public abstract BulletShape CreateGroundPlaneShape(UInt32 id, float height, float collisionMargin);
399 414
400public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, 415public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
401 float scaleFactor, float collisionMargin); 416 float scaleFactor, float collisionMargin);
402 417
403// ===================================================================================== 418// =====================================================================================
404// Constraint creation and helper routines 419// Constraint creation and helper routines
@@ -742,6 +757,12 @@ public abstract void SetMargin(BulletShape shape, float val);
742public abstract float GetMargin(BulletShape shape); 757public abstract float GetMargin(BulletShape shape);
743 758
744// ===================================================================================== 759// =====================================================================================
760// Raycast
761public abstract SweepHit ConvexSweepTest2(BulletWorld world, BulletBody obj, Vector3 from, Vector3 to, float margin);
762
763public abstract RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask);
764
765// =====================================================================================
745// Debugging 766// Debugging
746public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) { } 767public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) { }
747 768
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
index 83fc3a6..d182c34 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
@@ -40,7 +40,6 @@ public sealed class BSCharacter : BSPhysObject
40 private static readonly string LogHeader = "[BULLETS CHAR]"; 40 private static readonly string LogHeader = "[BULLETS CHAR]";
41 41
42 // private bool _stopped; 42 // private bool _stopped;
43 private OMV.Vector3 _size;
44 private bool _grabbed; 43 private bool _grabbed;
45 private bool _selected; 44 private bool _selected;
46 private float _mass; 45 private float _mass;
@@ -53,19 +52,21 @@ public sealed class BSCharacter : BSPhysObject
53 private bool _setAlwaysRun; 52 private bool _setAlwaysRun;
54 private bool _throttleUpdates; 53 private bool _throttleUpdates;
55 private bool _floatOnWater; 54 private bool _floatOnWater;
56 private OMV.Vector3 _rotationalVelocity;
57 private bool _kinematic; 55 private bool _kinematic;
58 private float _buoyancy; 56 private float _buoyancy;
59 57
58 private OMV.Vector3 _size;
59 private float _footOffset;
60
60 private BSActorAvatarMove m_moveActor; 61 private BSActorAvatarMove m_moveActor;
61 private const string AvatarMoveActorName = "BSCharacter.AvatarMove"; 62 private const string AvatarMoveActorName = "BSCharacter.AvatarMove";
62 63
63 private OMV.Vector3 _PIDTarget; 64 private OMV.Vector3 _PIDTarget;
64 private float _PIDTau; 65 private float _PIDTau;
65 66
66// public override OMV.Vector3 RawVelocity 67// public override OMV.Vector3 RawVelocity
67// { get { return base.RawVelocity; } 68// { get { return base.RawVelocity; }
68// set { 69// set {
69// if (value != base.RawVelocity) 70// if (value != base.RawVelocity)
70// Util.PrintCallStack(); 71// Util.PrintCallStack();
71// Console.WriteLine("Set rawvel to {0}", value); 72// Console.WriteLine("Set rawvel to {0}", value);
@@ -76,12 +77,12 @@ public sealed class BSCharacter : BSPhysObject
76 public override bool IsIncomplete { get { return false; } } 77 public override bool IsIncomplete { get { return false; } }
77 78
78 public BSCharacter( 79 public BSCharacter(
79 uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, bool isFlying) 80 uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, float footOffset, bool isFlying)
80 81
81 : base(parent_scene, localID, avName, "BSCharacter") 82 : base(parent_scene, localID, avName, "BSCharacter")
82 { 83 {
83 _physicsActorType = (int)ActorTypes.Agent; 84 _physicsActorType = (int)ActorTypes.Agent;
84 RawPosition = pos; 85 RawPosition = pos;
85 86
86 _flying = isFlying; 87 _flying = isFlying;
87 RawOrientation = OMV.Quaternion.Identity; 88 RawOrientation = OMV.Quaternion.Identity;
@@ -89,22 +90,15 @@ public sealed class BSCharacter : BSPhysObject
89 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 90 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
90 Friction = BSParam.AvatarStandingFriction; 91 Friction = BSParam.AvatarStandingFriction;
91 Density = BSParam.AvatarDensity; 92 Density = BSParam.AvatarDensity;
93 _isPhysical = true;
92 94
93 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 95 // Adjustments for zero X and Y made in Size()
94 // replace with the default values. 96 // This also computes avatar scale, volume, and mass
95 _size = size; 97 SetAvatarSize(size, footOffset, true /* initializing */);
96 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
97 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
98
99 // The dimensions of the physical capsule are kept in the scale.
100 // Physics creates a unit capsule which is scaled by the physics engine.
101 Scale = ComputeAvatarScale(_size);
102 // set _avatarVolume and _mass based on capsule size, _density and Scale
103 ComputeAvatarVolumeAndMass();
104 98
105 DetailLog( 99 DetailLog(
106 "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}", 100 "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}",
107 LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos, vel); 101 LocalID, Size, Scale, Density, _avatarVolume, RawMass, pos, vel);
108 102
109 // do actual creation in taint time 103 // do actual creation in taint time
110 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate() 104 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
@@ -208,45 +202,68 @@ public sealed class BSCharacter : BSPhysObject
208 public override OMV.Vector3 Size { 202 public override OMV.Vector3 Size {
209 get 203 get
210 { 204 {
211 // Avatar capsule size is kept in the scale parameter.
212 return _size; 205 return _size;
213 } 206 }
214 207
215 set { 208 set {
216 // This is how much the avatar size is changing. Positive means getting bigger. 209 setAvatarSize(value, _footOffset);
217 // The avatar altitude must be adjusted for this change. 210 }
218 float heightChange = value.Z - _size.Z; 211 }
212
213 // OpenSim 0.9 introduces a common avatar size computation
214 public override void setAvatarSize(OMV.Vector3 size, float feetOffset)
215 {
216 SetAvatarSize(size, feetOffset, false /* initializing */);
217 }
219 218
220 _size = value; 219 // Internal version that, if initializing, doesn't do all the updating of the physics engine
220 public void SetAvatarSize(OMV.Vector3 size, float feetOffset, bool initializing)
221 {
222 OMV.Vector3 newSize = size;
223 if (newSize.IsFinite())
224 {
221 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 225 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
222 // replace with the default values. 226 // replace with the default values.
223 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; 227 if (newSize.X == 0f) newSize.X = BSParam.AvatarCapsuleDepth;
224 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; 228 if (newSize.Y == 0f) newSize.Y = BSParam.AvatarCapsuleWidth;
225 229
226 Scale = ComputeAvatarScale(_size); 230 if (newSize.X < 0.01f) newSize.X = 0.01f;
227 ComputeAvatarVolumeAndMass(); 231 if (newSize.Y < 0.01f) newSize.Y = 0.01f;
228 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", 232 if (newSize.Z < 0.01f) newSize.Z = BSParam.AvatarCapsuleHeight;
229 LocalID, _size, Scale, Density, _avatarVolume, RawMass); 233 }
234 else
235 {
236 newSize = new OMV.Vector3(BSParam.AvatarCapsuleDepth, BSParam.AvatarCapsuleWidth, BSParam.AvatarCapsuleHeight);
237 }
230 238
231 PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate() 239 // This is how much the avatar size is changing. Positive means getting bigger.
232 { 240 // The avatar altitude must be adjusted for this change.
233 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape) 241 float heightChange = newSize.Z - Size.Z;
234 {
235 PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
236 UpdatePhysicalMassProperties(RawMass, true);
237 242
238 // Adjust the avatar's position to account for the increase/decrease in size 243 _size = newSize;
239 ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f);
240 244
241 // Make sure this change appears as a property update event 245 Scale = ComputeAvatarScale(Size);
242 PhysScene.PE.PushUpdate(PhysBody); 246 ComputeAvatarVolumeAndMass();
243 } 247 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
244 }); 248 LocalID, _size, Scale, Density, _avatarVolume, RawMass);
245 249
246 } 250 PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate()
251 {
252 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
253 {
254 PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
255 UpdatePhysicalMassProperties(RawMass, true);
256
257 // Adjust the avatar's position to account for the increase/decrease in size
258 ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f);
259
260 // Make sure this change appears as a property update event
261 PhysScene.PE.PushUpdate(PhysBody);
262 }
263 });
247 } 264 }
248 265
249 public override PrimitiveBaseShape Shape 266 public override PrimitiveBaseShape Shape
250 { 267 {
251 set { BaseShape = value; } 268 set { BaseShape = value; }
252 } 269 }
@@ -273,7 +290,7 @@ public sealed class BSCharacter : BSPhysObject
273 { 290 {
274 RawVelocity = OMV.Vector3.Zero; 291 RawVelocity = OMV.Vector3.Zero;
275 _acceleration = OMV.Vector3.Zero; 292 _acceleration = OMV.Vector3.Zero;
276 _rotationalVelocity = OMV.Vector3.Zero; 293 RawRotationalVelocity = OMV.Vector3.Zero;
277 294
278 // Zero some other properties directly into the physics engine 295 // Zero some other properties directly into the physics engine
279 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate() 296 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
@@ -285,7 +302,7 @@ public sealed class BSCharacter : BSPhysObject
285 302
286 public override void ZeroAngularMotion(bool inTaintTime) 303 public override void ZeroAngularMotion(bool inTaintTime)
287 { 304 {
288 _rotationalVelocity = OMV.Vector3.Zero; 305 RawRotationalVelocity = OMV.Vector3.Zero;
289 306
290 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate() 307 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
291 { 308 {
@@ -300,7 +317,7 @@ public sealed class BSCharacter : BSPhysObject
300 } 317 }
301 318
302 319
303 public override void LockAngularMotion(OMV.Vector3 axis) { return; } 320 public override void LockAngularMotion(byte axislocks) { return; }
304 321
305 public override OMV.Vector3 Position { 322 public override OMV.Vector3 Position {
306 get { 323 get {
@@ -333,7 +350,6 @@ public sealed class BSCharacter : BSPhysObject
333 } 350 }
334 } 351 }
335 352
336
337 // Check that the current position is sane and, if not, modify the position to make it so. 353 // Check that the current position is sane and, if not, modify the position to make it so.
338 // Check for being below terrain or on water. 354 // Check for being below terrain or on water.
339 // Returns 'true' of the position was made sane by some action. 355 // Returns 'true' of the position was made sane by some action.
@@ -433,6 +449,7 @@ public sealed class BSCharacter : BSPhysObject
433 public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } 449 public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } }
434 public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } 450 public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }
435 451
452 // PhysicsActor.TargetVelocity
436 // Sets the target in the motor. This starts the changing of the avatar's velocity. 453 // Sets the target in the motor. This starts the changing of the avatar's velocity.
437 public override OMV.Vector3 TargetVelocity 454 public override OMV.Vector3 TargetVelocity
438 { 455 {
@@ -443,43 +460,51 @@ public sealed class BSCharacter : BSPhysObject
443 set 460 set
444 { 461 {
445 DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); 462 DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value);
446 m_targetVelocity = value;
447 OMV.Vector3 targetVel = value; 463 OMV.Vector3 targetVel = value;
448 if (_setAlwaysRun && !_flying) 464 if (!_flying)
449 targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 1f); 465 {
466 if (_setAlwaysRun)
467 targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 1f);
468 else
469 if (BSParam.AvatarWalkVelocityFactor != 1f)
470 targetVel *= new OMV.Vector3(BSParam.AvatarWalkVelocityFactor, BSParam.AvatarWalkVelocityFactor, 1f);
471 }
472 base.m_targetVelocity = targetVel;
450 473
451 if (m_moveActor != null) 474 if (m_moveActor != null)
452 m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */); 475 m_moveActor.SetVelocityAndTarget(RawVelocity, base.m_targetVelocity, false /* inTaintTime */);
453 } 476 }
454 } 477 }
455 // Directly setting velocity means this is what the user really wants now. 478 // Directly setting velocity means this is what the user really wants now.
456 public override OMV.Vector3 Velocity { 479 public override OMV.Vector3 Velocity {
457 get { return RawVelocity; } 480 get { return RawVelocity; }
458 set { 481 set {
459 RawVelocity = value; 482 if (m_moveActor != null)
460 OMV.Vector3 vel = RawVelocity;
461
462 DetailLog("{0}: set Velocity = {1}", LocalID, value);
463
464 PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate()
465 { 483 {
466 if (m_moveActor != null) 484 // m_moveActor.SetVelocityAndTarget(OMV.Vector3.Zero, OMV.Vector3.Zero, false /* inTaintTime */);
467 m_moveActor.SetVelocityAndTarget(vel, vel, true /* inTaintTime */); 485 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false /* inTaintTime */);
486 }
487 base.Velocity = value;
488 }
489 }
468 490
469 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, vel); 491 // SetMomentum just sets the velocity without a target. We need to stop the movement actor if a character.
470 ForceVelocity = vel; 492 public override void SetMomentum(OMV.Vector3 momentum)
471 }); 493 {
494 if (m_moveActor != null)
495 {
496 // m_moveActor.SetVelocityAndTarget(OMV.Vector3.Zero, OMV.Vector3.Zero, false /* inTaintTime */);
497 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false /* inTaintTime */);
472 } 498 }
499 base.SetMomentum(momentum);
473 } 500 }
474 501
475 public override OMV.Vector3 ForceVelocity { 502 public override OMV.Vector3 ForceVelocity {
476 get { return RawVelocity; } 503 get { return RawVelocity; }
477 set { 504 set {
478 PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); 505 DetailLog("{0},BSCharacter.ForceVelocity.set={1}", LocalID, value);
479// Util.PrintCallStack();
480 DetailLog("{0}: set ForceVelocity = {1}", LocalID, value);
481 506
482 RawVelocity = value; 507 RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
483 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); 508 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
484 PhysScene.PE.Activate(PhysBody, true); 509 PhysScene.PE.Activate(PhysBody, true);
485 } 510 }
@@ -600,14 +625,6 @@ public sealed class BSCharacter : BSPhysObject
600 }); 625 });
601 } 626 }
602 } 627 }
603 public override OMV.Vector3 RotationalVelocity {
604 get { return _rotationalVelocity; }
605 set { _rotationalVelocity = value; }
606 }
607 public override OMV.Vector3 ForceRotationalVelocity {
608 get { return _rotationalVelocity; }
609 set { _rotationalVelocity = value; }
610 }
611 public override bool Kinematic { 628 public override bool Kinematic {
612 get { return _kinematic; } 629 get { return _kinematic; }
613 set { _kinematic = value; } 630 set { _kinematic = value; }
@@ -626,8 +643,6 @@ public sealed class BSCharacter : BSPhysObject
626 public override float ForceBuoyancy { 643 public override float ForceBuoyancy {
627 get { return _buoyancy; } 644 get { return _buoyancy; }
628 set { 645 set {
629 PhysScene.AssertInTaintTime("BSCharacter.ForceBuoyancy");
630
631 _buoyancy = value; 646 _buoyancy = value;
632 DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 647 DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
633 // Buoyancy is faked by changing the gravity applied to the object 648 // Buoyancy is faked by changing the gravity applied to the object
@@ -652,14 +667,24 @@ public sealed class BSCharacter : BSPhysObject
652 public override void AddForce(OMV.Vector3 force, bool pushforce) 667 public override void AddForce(OMV.Vector3 force, bool pushforce)
653 { 668 {
654 // Since this force is being applied in only one step, make this a force per second. 669 // Since this force is being applied in only one step, make this a force per second.
655 OMV.Vector3 addForce = force / PhysScene.LastTimeStep; 670 OMV.Vector3 addForce = force;
656 AddForce(addForce, pushforce, false); 671
672 // The interaction of this force with the simulator rate and collision occurance is tricky.
673 // ODE multiplies the force by 100
674 // ubODE multiplies the force by 5.3
675 // BulletSim, after much in-world testing, thinks it gets a similar effect by multiplying mass*0.315f
676 // This number could be a feature of friction or timing, but it seems to move avatars the same as ubODE
677 addForce *= Mass * BSParam.AvatarAddForcePushFactor;
678
679 DetailLog("{0},BSCharacter.addForce,call,force={1},addForce={2},push={3},mass={4}", LocalID, force, addForce, pushforce, Mass);
680 AddForce(false, addForce);
657 } 681 }
658 public override void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 682
683 public override void AddForce(bool inTaintTime, OMV.Vector3 force) {
659 if (force.IsFinite()) 684 if (force.IsFinite())
660 { 685 {
661 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); 686 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
662 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); 687 // DetailLog("{0},BSCharacter.addForce,call,force={1},push={2},inTaint={3}", LocalID, addForce, pushforce, inTaintTime);
663 688
664 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate() 689 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate()
665 { 690 {
@@ -667,7 +692,15 @@ public sealed class BSCharacter : BSPhysObject
667 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); 692 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
668 if (PhysBody.HasPhysicalBody) 693 if (PhysBody.HasPhysicalBody)
669 { 694 {
695 // Bullet adds this central force to the total force for this tick.
696 // Deep down in Bullet:
697 // linearVelocity += totalForce / mass * timeStep;
670 PhysScene.PE.ApplyCentralForce(PhysBody, addForce); 698 PhysScene.PE.ApplyCentralForce(PhysBody, addForce);
699 PhysScene.PE.Activate(PhysBody, true);
700 }
701 if (m_moveActor != null)
702 {
703 m_moveActor.SuppressStationayCheckUntilLowVelocity();
671 } 704 }
672 }); 705 });
673 } 706 }
@@ -678,65 +711,74 @@ public sealed class BSCharacter : BSPhysObject
678 } 711 }
679 } 712 }
680 713
681 public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 714 public override void AddAngularForce(bool inTaintTime, OMV.Vector3 force) {
682 }
683 public override void SetMomentum(OMV.Vector3 momentum) {
684 } 715 }
685 716
717 // The avatar's physical shape (whether capsule or cube) is unit sized. BulletSim sets
718 // the scale of that unit shape to create the avatars full size.
686 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) 719 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
687 { 720 {
688 OMV.Vector3 newScale = size; 721 OMV.Vector3 newScale = size;
689 722
690 // Bullet's capsule total height is the "passed height + radius * 2"; 723 if (BSParam.AvatarUseBefore09SizeComputation)
691 // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1) 724 {
692 // The number we pass in for 'scaling' is the multiplier to get that base
693 // shape to be the size desired.
694 // So, when creating the scale for the avatar height, we take the passed height
695 // (size.Z) and remove the caps.
696 // An oddity of the Bullet capsule implementation is that it presumes the Y
697 // dimension is the radius of the capsule. Even though some of the code allows
698 // for a asymmetrical capsule, other parts of the code presume it is cylindrical.
699 725
700 // Scale is multiplier of radius with one of "0.5" 726 // Bullet's capsule total height is the "passed height + radius * 2";
727 // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1)
728 // The number we pass in for 'scaling' is the multiplier to get that base
729 // shape to be the size desired.
730 // So, when creating the scale for the avatar height, we take the passed height
731 // (size.Z) and remove the caps.
732 // An oddity of the Bullet capsule implementation is that it presumes the Y
733 // dimension is the radius of the capsule. Even though some of the code allows
734 // for a asymmetrical capsule, other parts of the code presume it is cylindrical.
701 735
702 float heightAdjust = BSParam.AvatarHeightMidFudge; 736 // Scale is multiplier of radius with one of "0.5"
703 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f) 737
704 { 738 float heightAdjust = BSParam.AvatarHeightMidFudge;
705 const float AVATAR_LOW = 1.1f; 739 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
706 const float AVATAR_MID = 1.775f; // 1.87f
707 const float AVATAR_HI = 2.45f;
708 // An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
709 float midHeightOffset = size.Z - AVATAR_MID;
710 if (midHeightOffset < 0f)
711 { 740 {
712 // Small avatar. Add the adjustment based on the distance from midheight 741 const float AVATAR_LOW = 1.1f;
713 heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge; 742 const float AVATAR_MID = 1.775f; // 1.87f
743 const float AVATAR_HI = 2.45f;
744 // An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
745 float midHeightOffset = size.Z - AVATAR_MID;
746 if (midHeightOffset < 0f)
747 {
748 // Small avatar. Add the adjustment based on the distance from midheight
749 heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge;
750 }
751 else
752 {
753 // Large avatar. Add the adjustment based on the distance from midheight
754 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
755 }
756 }
757 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
758 {
759 newScale.X = size.X / 2f;
760 newScale.Y = size.Y / 2f;
761 // The total scale height is the central cylindar plus the caps on the two ends.
762 newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f;
714 } 763 }
715 else 764 else
716 { 765 {
717 // Large avatar. Add the adjustment based on the distance from midheight 766 newScale.Z = size.Z + heightAdjust;
718 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
719 } 767 }
720 } 768 // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);
721 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule) 769
722 { 770 // If smaller than the endcaps, just fake like we're almost that small
723 newScale.X = size.X / 2f; 771 if (newScale.Z < 0)
724 newScale.Y = size.Y / 2f; 772 newScale.Z = 0.1f;
725 // The total scale height is the central cylindar plus the caps on the two ends. 773
726 newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f; 774 DetailLog("{0},BSCharacter.ComputeAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
775 LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
727 } 776 }
728 else 777 else
729 { 778 {
730 newScale.Z = size.Z + heightAdjust; 779 newScale.Z = size.Z + _footOffset;
780 DetailLog("{0},BSCharacter.ComputeAvatarScale,using newScale={1}, footOffset={2}", LocalID, newScale, _footOffset);
731 } 781 }
732 // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);
733
734 // If smaller than the endcaps, just fake like we're almost that small
735 if (newScale.Z < 0)
736 newScale.Z = 0.1f;
737
738 DetailLog("{0},BSCharacter.ComputerAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
739 LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
740 782
741 return newScale; 783 return newScale;
742 } 784 }
@@ -744,17 +786,24 @@ public sealed class BSCharacter : BSPhysObject
744 // set _avatarVolume and _mass based on capsule size, _density and Scale 786 // set _avatarVolume and _mass based on capsule size, _density and Scale
745 private void ComputeAvatarVolumeAndMass() 787 private void ComputeAvatarVolumeAndMass()
746 { 788 {
747 _avatarVolume = (float)( 789 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
748 Math.PI 790 {
749 * Size.X / 2f 791 _avatarVolume = (float)(
750 * Size.Y / 2f // the area of capsule cylinder 792 Math.PI
751 * Size.Z // times height of capsule cylinder 793 * Size.X / 2f
752 + 1.33333333f 794 * Size.Y / 2f // the area of capsule cylinder
753 * Math.PI 795 * Size.Z // times height of capsule cylinder
754 * Size.X / 2f 796 + 1.33333333f
755 * Math.Min(Size.X, Size.Y) / 2 797 * Math.PI
756 * Size.Y / 2f // plus the volume of the capsule end caps 798 * Size.X / 2f
757 ); 799 * Math.Min(Size.X, Size.Y) / 2
800 * Size.Y / 2f // plus the volume of the capsule end caps
801 );
802 }
803 else
804 {
805 _avatarVolume = Size.X * Size.Y * Size.Z;
806 }
758 _mass = Density * BSParam.DensityScaleFactor * _avatarVolume; 807 _mass = Density * BSParam.DensityScaleFactor * _avatarVolume;
759 } 808 }
760 809
@@ -773,7 +822,7 @@ public sealed class BSCharacter : BSPhysObject
773 // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many 822 // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many
774 // extra updates. 823 // extra updates.
775 // 824 //
776 // XXX: Contrary to the above comment, setting an update threshold here above 0.4 actually introduces jitter to 825 // XXX: Contrary to the above comment, setting an update threshold here above 0.4 actually introduces jitter to
777 // avatar movement rather than removes it. The larger the threshold, the bigger the jitter. 826 // avatar movement rather than removes it. The larger the threshold, the bigger the jitter.
778 // This is most noticeable in level flight and can be seen with 827 // This is most noticeable in level flight and can be seen with
779 // the "show updates" option in a viewer. With an update threshold, the RawVelocity cycles between a lower 828 // the "show updates" option in a viewer. With an update threshold, the RawVelocity cycles between a lower
@@ -787,7 +836,7 @@ public sealed class BSCharacter : BSPhysObject
787 RawVelocity = entprop.Velocity; 836 RawVelocity = entprop.Velocity;
788 837
789 _acceleration = entprop.Acceleration; 838 _acceleration = entprop.Acceleration;
790 _rotationalVelocity = entprop.RotationalVelocity; 839 RawRotationalVelocity = entprop.RotationalVelocity;
791 840
792 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 841 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
793 if (PositionSanityCheck(true)) 842 if (PositionSanityCheck(true))
@@ -807,7 +856,7 @@ public sealed class BSCharacter : BSPhysObject
807 // PhysScene.PostUpdate(this); 856 // PhysScene.PostUpdate(this);
808 857
809 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 858 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
810 LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity); 859 LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, RawRotationalVelocity);
811 } 860 }
812} 861}
813} 862}
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs
index e42e868..e42e868 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs
index 4bcde2b..4bcde2b 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs
index 5746ac1..5746ac1 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs
index e7566a8..e7566a8 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs
index d20538d..d20538d 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs
index 83d42af..83d42af 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs
index 563a1b1..563a1b1 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs b/OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs
index 0fc5577..c4ccdbe 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs
@@ -125,8 +125,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS
125 125
126 // Just some recomputed constants: 126 // Just some recomputed constants:
127#pragma warning disable 414 127#pragma warning disable 414
128 static readonly float TwoPI = ((float)Math.PI) * 2f; 128 static readonly float TwoPI = ((float)Math.PI) * 2f;
129 static readonly float FourPI = ((float)Math.PI) * 4f; 129 static readonly float FourPI = ((float)Math.PI) * 4f;
130 static readonly float PIOverFour = ((float)Math.PI) / 4f; 130 static readonly float PIOverFour = ((float)Math.PI) / 4f;
131 static readonly float PIOverTwo = ((float)Math.PI) / 2f; 131 static readonly float PIOverTwo = ((float)Math.PI) / 2f;
132#pragma warning restore 414 132#pragma warning restore 414
@@ -768,7 +768,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
768 } 768 }
769 769
770 if ((m_knownChanged & m_knownChangedForce) != 0) 770 if ((m_knownChanged & m_knownChangedForce) != 0)
771 ControllingPrim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/); 771 ControllingPrim.AddForce(false /* inTaintTime */, (Vector3)m_knownForce);
772 772
773 if ((m_knownChanged & m_knownChangedForceImpulse) != 0) 773 if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
774 ControllingPrim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/); 774 ControllingPrim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
@@ -784,7 +784,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
784 784
785 if ((m_knownChanged & m_knownChangedRotationalForce) != 0) 785 if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
786 { 786 {
787 ControllingPrim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/); 787 ControllingPrim.AddAngularForce(true /* inTaintTime */, (Vector3)m_knownRotationalForce);
788 } 788 }
789 789
790 // If we set one of the values (ie, the physics engine didn't do it) we must force 790 // If we set one of the values (ie, the physics engine didn't do it) we must force
@@ -1595,7 +1595,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1595 // in that direction. 1595 // in that direction.
1596 // TODO: implement reference frame. 1596 // TODO: implement reference frame.
1597 public void ComputeAngularDeflection() 1597 public void ComputeAngularDeflection()
1598 { 1598 {
1599 1599
1600 if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) 1600 if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
1601 { 1601 {
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs b/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs
index 8312239..13c1361 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs
@@ -257,7 +257,7 @@ public abstract class BSLinkset
257 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have 257 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have
258 // anything to add for the collision and it should be passed through normal processing. 258 // anything to add for the collision and it should be passed through normal processing.
259 // Default processing for a linkset. 259 // Default processing for a linkset.
260 public virtual bool HandleCollide(uint collidingWith, BSPhysObject collidee, 260 public virtual bool HandleCollide(BSPhysObject collider, BSPhysObject collidee,
261 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 261 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
262 { 262 {
263 bool ret = false; 263 bool ret = false;
@@ -319,7 +319,7 @@ public abstract class BSLinkset
319 public virtual bool AllPartsComplete 319 public virtual bool AllPartsComplete
320 { 320 {
321 get { 321 get {
322 bool ret = true; 322 bool ret = true;
323 this.ForEachMember((member) => 323 this.ForEachMember((member) =>
324 { 324 {
325 if ((!member.IsInitialized) || member.IsIncomplete || member.PrimAssetState == BSPhysObject.PrimAssetCondition.Waiting) 325 if ((!member.IsInitialized) || member.IsIncomplete || member.PrimAssetState == BSPhysObject.PrimAssetCondition.Waiting)
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs
index 953ddee..dc390b2 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs
@@ -450,6 +450,7 @@ public sealed class BSLinksetCompound : BSLinkset
450 m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody); 450 m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody);
451 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}", 451 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}",
452 LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape); 452 LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape);
453 m_physicsScene.PE.ResetBroadphasePool(m_physicsScene.World); // DEBUG DEBUG
453 454
454 // With all of the linkset packed into the root prim, it has the mass of everyone. 455 // With all of the linkset packed into the root prim, it has the mass of everyone.
455 LinksetMass = ComputeLinksetMass(); 456 LinksetMass = ComputeLinksetMass();
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs
index c4b4c86..c4b4c86 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs b/OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs
index 0e44d03..0e44d03 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs b/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
index 2faf2d4..2faf2d4 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
index c296008..495f752 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
@@ -90,8 +90,8 @@ public static class BSParam
90 public static float DeactivationTime { get; private set; } 90 public static float DeactivationTime { get; private set; }
91 public static float LinearSleepingThreshold { get; private set; } 91 public static float LinearSleepingThreshold { get; private set; }
92 public static float AngularSleepingThreshold { get; private set; } 92 public static float AngularSleepingThreshold { get; private set; }
93 public static float CcdMotionThreshold { get; private set; } 93 public static float CcdMotionThreshold { get; private set; }
94 public static float CcdSweptSphereRadius { get; private set; } 94 public static float CcdSweptSphereRadius { get; private set; }
95 public static float ContactProcessingThreshold { get; private set; } 95 public static float ContactProcessingThreshold { get; private set; }
96 96
97 public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed 97 public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed
@@ -119,14 +119,14 @@ public static class BSParam
119 public static float Gravity { get; private set; } 119 public static float Gravity { get; private set; }
120 120
121 // Physics Engine operation 121 // Physics Engine operation
122 public static float MaxPersistantManifoldPoolSize { get; private set; } 122 public static float MaxPersistantManifoldPoolSize { get; private set; }
123 public static float MaxCollisionAlgorithmPoolSize { get; private set; } 123 public static float MaxCollisionAlgorithmPoolSize { get; private set; }
124 public static bool ShouldDisableContactPoolDynamicAllocation { get; private set; } 124 public static bool ShouldDisableContactPoolDynamicAllocation { get; private set; }
125 public static bool ShouldForceUpdateAllAabbs { get; private set; } 125 public static bool ShouldForceUpdateAllAabbs { get; private set; }
126 public static bool ShouldRandomizeSolverOrder { get; private set; } 126 public static bool ShouldRandomizeSolverOrder { get; private set; }
127 public static bool ShouldSplitSimulationIslands { get; private set; } 127 public static bool ShouldSplitSimulationIslands { get; private set; }
128 public static bool ShouldEnableFrictionCaching { get; private set; } 128 public static bool ShouldEnableFrictionCaching { get; private set; }
129 public static float NumberOfSolverIterations { get; private set; } 129 public static float NumberOfSolverIterations { get; private set; }
130 public static bool UseSingleSidedMeshes { get; private set; } 130 public static bool UseSingleSidedMeshes { get; private set; }
131 public static float GlobalContactBreakingThreshold { get; private set; } 131 public static float GlobalContactBreakingThreshold { get; private set; }
132 public static float PhysicsUnmanLoggingFrames { get; private set; } 132 public static float PhysicsUnmanLoggingFrames { get; private set; }
@@ -135,6 +135,7 @@ public static class BSParam
135 public static bool AvatarToAvatarCollisionsByDefault { get; private set; } 135 public static bool AvatarToAvatarCollisionsByDefault { get; private set; }
136 public static float AvatarFriction { get; private set; } 136 public static float AvatarFriction { get; private set; }
137 public static float AvatarStandingFriction { get; private set; } 137 public static float AvatarStandingFriction { get; private set; }
138 public static float AvatarWalkVelocityFactor { get; private set; }
138 public static float AvatarAlwaysRunFactor { get; private set; } 139 public static float AvatarAlwaysRunFactor { get; private set; }
139 public static float AvatarDensity { get; private set; } 140 public static float AvatarDensity { get; private set; }
140 public static float AvatarRestitution { get; private set; } 141 public static float AvatarRestitution { get; private set; }
@@ -142,23 +143,26 @@ public static class BSParam
142 public static float AvatarCapsuleWidth { get; private set; } 143 public static float AvatarCapsuleWidth { get; private set; }
143 public static float AvatarCapsuleDepth { get; private set; } 144 public static float AvatarCapsuleDepth { get; private set; }
144 public static float AvatarCapsuleHeight { get; private set; } 145 public static float AvatarCapsuleHeight { get; private set; }
146 public static bool AvatarUseBefore09SizeComputation { get; private set; }
145 public static float AvatarHeightLowFudge { get; private set; } 147 public static float AvatarHeightLowFudge { get; private set; }
146 public static float AvatarHeightMidFudge { get; private set; } 148 public static float AvatarHeightMidFudge { get; private set; }
147 public static float AvatarHeightHighFudge { get; private set; } 149 public static float AvatarHeightHighFudge { get; private set; }
148 public static float AvatarFlyingGroundMargin { get; private set; } 150 public static float AvatarFlyingGroundMargin { get; private set; }
149 public static float AvatarFlyingGroundUpForce { get; private set; } 151 public static float AvatarFlyingGroundUpForce { get; private set; }
150 public static float AvatarTerminalVelocity { get; private set; } 152 public static float AvatarTerminalVelocity { get; private set; }
151 public static float AvatarContactProcessingThreshold { get; private set; } 153 public static float AvatarContactProcessingThreshold { get; private set; }
154 public static float AvatarAddForcePushFactor { get; private set; }
152 public static float AvatarStopZeroThreshold { get; private set; } 155 public static float AvatarStopZeroThreshold { get; private set; }
153 public static int AvatarJumpFrames { get; private set; } 156 public static float AvatarStopZeroThresholdSquared { get; private set; }
154 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; } 157 public static int AvatarJumpFrames { get; private set; }
155 public static float AvatarStepHeight { get; private set; } 158 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
156 public static float AvatarStepAngle { get; private set; } 159 public static float AvatarStepHeight { get; private set; }
157 public static float AvatarStepGroundFudge { get; private set; } 160 public static float AvatarStepAngle { get; private set; }
158 public static float AvatarStepApproachFactor { get; private set; } 161 public static float AvatarStepGroundFudge { get; private set; }
159 public static float AvatarStepForceFactor { get; private set; } 162 public static float AvatarStepApproachFactor { get; private set; }
160 public static float AvatarStepUpCorrectionFactor { get; private set; } 163 public static float AvatarStepForceFactor { get; private set; }
161 public static int AvatarStepSmoothingSteps { get; private set; } 164 public static float AvatarStepUpCorrectionFactor { get; private set; }
165 public static int AvatarStepSmoothingSteps { get; private set; }
162 166
163 // Vehicle parameters 167 // Vehicle parameters
164 public static float VehicleMaxLinearVelocity { get; private set; } 168 public static float VehicleMaxLinearVelocity { get; private set; }
@@ -190,31 +194,31 @@ public static class BSParam
190 public static float CSHullVolumeConservationThresholdPercent { get; private set; } 194 public static float CSHullVolumeConservationThresholdPercent { get; private set; }
191 public static int CSHullMaxVertices { get; private set; } 195 public static int CSHullMaxVertices { get; private set; }
192 public static float CSHullMaxSkinWidth { get; private set; } 196 public static float CSHullMaxSkinWidth { get; private set; }
193 public static float BHullMaxVerticesPerHull { get; private set; } // 100 197 public static float BHullMaxVerticesPerHull { get; private set; } // 100
194 public static float BHullMinClusters { get; private set; } // 2 198 public static float BHullMinClusters { get; private set; } // 2
195 public static float BHullCompacityWeight { get; private set; } // 0.1 199 public static float BHullCompacityWeight { get; private set; } // 0.1
196 public static float BHullVolumeWeight { get; private set; } // 0.0 200 public static float BHullVolumeWeight { get; private set; } // 0.0
197 public static float BHullConcavity { get; private set; } // 100 201 public static float BHullConcavity { get; private set; } // 100
198 public static bool BHullAddExtraDistPoints { get; private set; } // false 202 public static bool BHullAddExtraDistPoints { get; private set; } // false
199 public static bool BHullAddNeighboursDistPoints { get; private set; } // false 203 public static bool BHullAddNeighboursDistPoints { get; private set; } // false
200 public static bool BHullAddFacesPoints { get; private set; } // false 204 public static bool BHullAddFacesPoints { get; private set; } // false
201 public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false 205 public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false
202 public static float WhichHACD { get; private set; } // zero if Bullet HACD, non-zero says VHACD 206 public static float WhichHACD { get; private set; } // zero if Bullet HACD, non-zero says VHACD
203 // Parameters for VHACD 2.0: http://code.google.com/p/v-hacd 207 // Parameters for VHACD 2.0: http://code.google.com/p/v-hacd
204 // To enable, set both ShouldUseBulletHACD=true and WhichHACD=1 208 // To enable, set both ShouldUseBulletHACD=true and WhichHACD=1
205 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html 209 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html
206 public static float VHACDresolution { get; private set; } // 100,000 max number of voxels generated during voxelization stage 210 public static float VHACDresolution { get; private set; } // 100,000 max number of voxels generated during voxelization stage
207 public static float VHACDdepth { get; private set; } // 20 max number of clipping stages 211 public static float VHACDdepth { get; private set; } // 20 max number of clipping stages
208 public static float VHACDconcavity { get; private set; } // 0.0025 maximum concavity 212 public static float VHACDconcavity { get; private set; } // 0.0025 maximum concavity
209 public static float VHACDplaneDownsampling { get; private set; } // 4 granularity of search for best clipping plane 213 public static float VHACDplaneDownsampling { get; private set; } // 4 granularity of search for best clipping plane
210 public static float VHACDconvexHullDownsampling { get; private set; } // 4 precision of hull gen process 214 public static float VHACDconvexHullDownsampling { get; private set; } // 4 precision of hull gen process
211 public static float VHACDalpha { get; private set; } // 0.05 bias toward clipping along symmetry planes 215 public static float VHACDalpha { get; private set; } // 0.05 bias toward clipping along symmetry planes
212 public static float VHACDbeta { get; private set; } // 0.05 bias toward clipping along revolution axis 216 public static float VHACDbeta { get; private set; } // 0.05 bias toward clipping along revolution axis
213 public static float VHACDgamma { get; private set; } // 0.00125 max concavity when merging 217 public static float VHACDgamma { get; private set; } // 0.00125 max concavity when merging
214 public static float VHACDpca { get; private set; } // 0 on/off normalizing mesh before decomp 218 public static float VHACDpca { get; private set; } // 0 on/off normalizing mesh before decomp
215 public static float VHACDmode { get; private set; } // 0 0:voxel based, 1: tetrahedron based 219 public static float VHACDmode { get; private set; } // 0 0:voxel based, 1: tetrahedron based
216 public static float VHACDmaxNumVerticesPerCH { get; private set; } // 64 max triangles per convex hull 220 public static float VHACDmaxNumVerticesPerCH { get; private set; } // 64 max triangles per convex hull
217 public static float VHACDminVolumePerCH { get; private set; } // 0.0001 sampling of generated convex hulls 221 public static float VHACDminVolumePerCH { get; private set; } // 0.0001 sampling of generated convex hulls
218 222
219 // Linkset implementation parameters 223 // Linkset implementation parameters
220 public static float LinksetImplementation { get; private set; } 224 public static float LinksetImplementation { get; private set; }
@@ -227,9 +231,13 @@ public static class BSParam
227 public static float LinkConstraintCFM { get; private set; } 231 public static float LinkConstraintCFM { get; private set; }
228 public static float LinkConstraintSolverIterations { get; private set; } 232 public static float LinkConstraintSolverIterations { get; private set; }
229 233
234 public static bool UseBulletRaycast { get; private set; }
235
230 public static float PID_D { get; private set; } // derivative 236 public static float PID_D { get; private set; } // derivative
231 public static float PID_P { get; private set; } // proportional 237 public static float PID_P { get; private set; } // proportional
232 238
239 public static float DebugNumber { get; private set; } // A console setable number used for debugging
240
233 // Various constants that come from that other virtual world that shall not be named. 241 // Various constants that come from that other virtual world that shall not be named.
234 public const float MinGravityZ = -1f; 242 public const float MinGravityZ = -1f;
235 public const float MaxGravityZ = 28f; 243 public const float MaxGravityZ = 28f;
@@ -574,7 +582,7 @@ public static class BSParam
574 (s,v) => { ContactProcessingThreshold = v;}, 582 (s,v) => { ContactProcessingThreshold = v;},
575 (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ), 583 (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ),
576 584
577 new ParameterDefn<float>("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", 585 new ParameterDefn<float>("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
578 (float)BSTerrainPhys.TerrainImplementation.Heightmap ), 586 (float)BSTerrainPhys.TerrainImplementation.Heightmap ),
579 new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , 587 new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" ,
580 2 ), 588 2 ),
@@ -597,11 +605,13 @@ public static class BSParam
597 0.2f ), 605 0.2f ),
598 new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", 606 new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
599 0.95f ), 607 0.95f ),
608 new ParameterDefn<float>("AvatarWalkVelocityFactor", "Speed multiplier if avatar is walking",
609 1.0f ),
600 new ParameterDefn<float>("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run", 610 new ParameterDefn<float>("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run",
601 1.3f ), 611 1.3f ),
602 // For historical reasons, density is reported * 100 612 // For historical reasons, density is reported * 100
603 new ParameterDefn<float>("AvatarDensity", "Density of an avatar. Changed on avatar recreation. Scaled times 100.", 613 new ParameterDefn<float>("AvatarDensity", "Density of an avatar. Changed on avatar recreation. Scaled times 100.",
604 3500f) , // 3.5 * 100 614 350f) , // 3.5 * 100
605 new ParameterDefn<float>("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 615 new ParameterDefn<float>("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
606 0f ), 616 0f ),
607 new ParameterDefn<int>("AvatarShape", "Code for avatar physical shape: 0:capsule, 1:cube, 2:ovoid, 2:mesh", 617 new ParameterDefn<int>("AvatarShape", "Code for avatar physical shape: 0:capsule, 1:cube, 2:ovoid, 2:mesh",
@@ -612,6 +622,8 @@ public static class BSParam
612 0.45f ), 622 0.45f ),
613 new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar", 623 new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar",
614 1.5f ), 624 1.5f ),
625 new ParameterDefn<bool>("AvatarUseBefore09SizeComputation", "Use the old fudge method of computing avatar capsule size",
626 true ),
615 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", 627 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground",
616 0f ), 628 0f ),
617 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", 629 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground",
@@ -624,27 +636,31 @@ public static class BSParam
624 2.0f ), 636 2.0f ),
625 new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar", 637 new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar",
626 -54.0f ), 638 -54.0f ),
627 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 639 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
628 0.1f ),
629 new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
630 0.1f ), 640 0.1f ),
631 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", 641 new ParameterDefn<float>("AvatarAddForcePushFactor", "BSCharacter.AddForce is multiplied by this and mass to be like other physics engines",
642 0.315f ),
643 new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
644 0.45f,
645 (s) => { return (float)AvatarStopZeroThreshold; },
646 (s,v) => { AvatarStopZeroThreshold = v; AvatarStopZeroThresholdSquared = v * v; } ),
647 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
632 1.0f ), 648 1.0f ),
633 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.", 649 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.",
634 4 ), 650 4 ),
635 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction", 651 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction",
636 0.999f ) , 652 0.999f ) ,
637 new ParameterDefn<float>("AvatarStepAngle", "The angle (in radians) for a vertical surface to be considered a step", 653 new ParameterDefn<float>("AvatarStepAngle", "The angle (in radians) for a vertical surface to be considered a step",
638 0.3f ) , 654 0.3f ) ,
639 new ParameterDefn<float>("AvatarStepGroundFudge", "Fudge factor subtracted from avatar base when comparing collision height", 655 new ParameterDefn<float>("AvatarStepGroundFudge", "Fudge factor subtracted from avatar base when comparing collision height",
640 0.1f ) , 656 0.1f ) ,
641 new ParameterDefn<float>("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", 657 new ParameterDefn<float>("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)",
642 2f ), 658 2f ),
643 new ParameterDefn<float>("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", 659 new ParameterDefn<float>("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step",
644 0f ), 660 0f ),
645 new ParameterDefn<float>("AvatarStepUpCorrectionFactor", "Multiplied by height of step collision to create up movement at step", 661 new ParameterDefn<float>("AvatarStepUpCorrectionFactor", "Multiplied by height of step collision to create up movement at step",
646 0.8f ), 662 0.8f ),
647 new ParameterDefn<int>("AvatarStepSmoothingSteps", "Number of frames after a step collision that we continue walking up stairs", 663 new ParameterDefn<int>("AvatarStepSmoothingSteps", "Number of frames after a step collision that we continue walking up stairs",
648 1 ), 664 1 ),
649 665
650 new ParameterDefn<float>("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", 666 new ParameterDefn<float>("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle",
@@ -688,130 +704,136 @@ public static class BSParam
688 new ParameterDefn<bool>("VehicleEnableAngularBanking", "Turn on/off vehicle angular banking effect", 704 new ParameterDefn<bool>("VehicleEnableAngularBanking", "Turn on/off vehicle angular banking effect",
689 true ), 705 true ),
690 706
691 new ParameterDefn<float>("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 707 new ParameterDefn<float>("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
692 0f, 708 0f,
693 (s) => { return MaxPersistantManifoldPoolSize; }, 709 (s) => { return MaxPersistantManifoldPoolSize; },
694 (s,v) => { MaxPersistantManifoldPoolSize = v; s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), 710 (s,v) => { MaxPersistantManifoldPoolSize = v; s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ),
695 new ParameterDefn<float>("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", 711 new ParameterDefn<float>("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
696 0f, 712 0f,
697 (s) => { return MaxCollisionAlgorithmPoolSize; }, 713 (s) => { return MaxCollisionAlgorithmPoolSize; },
698 (s,v) => { MaxCollisionAlgorithmPoolSize = v; s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), 714 (s,v) => { MaxCollisionAlgorithmPoolSize = v; s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ),
699 new ParameterDefn<bool>("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", 715 new ParameterDefn<bool>("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
700 false, 716 false,
701 (s) => { return ShouldDisableContactPoolDynamicAllocation; }, 717 (s) => { return ShouldDisableContactPoolDynamicAllocation; },
702 (s,v) => { ShouldDisableContactPoolDynamicAllocation = v; 718 (s,v) => { ShouldDisableContactPoolDynamicAllocation = v;
703 s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = NumericBool(v); } ), 719 s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = NumericBool(v); } ),
704 new ParameterDefn<bool>("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", 720 new ParameterDefn<bool>("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
705 false, 721 false,
706 (s) => { return ShouldForceUpdateAllAabbs; }, 722 (s) => { return ShouldForceUpdateAllAabbs; },
707 (s,v) => { ShouldForceUpdateAllAabbs = v; s.UnmanagedParams[0].shouldForceUpdateAllAabbs = NumericBool(v); } ), 723 (s,v) => { ShouldForceUpdateAllAabbs = v; s.UnmanagedParams[0].shouldForceUpdateAllAabbs = NumericBool(v); } ),
708 new ParameterDefn<bool>("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", 724 new ParameterDefn<bool>("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction",
709 true, 725 true,
710 (s) => { return ShouldRandomizeSolverOrder; }, 726 (s) => { return ShouldRandomizeSolverOrder; },
711 (s,v) => { ShouldRandomizeSolverOrder = v; s.UnmanagedParams[0].shouldRandomizeSolverOrder = NumericBool(v); } ), 727 (s,v) => { ShouldRandomizeSolverOrder = v; s.UnmanagedParams[0].shouldRandomizeSolverOrder = NumericBool(v); } ),
712 new ParameterDefn<bool>("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", 728 new ParameterDefn<bool>("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands",
713 true, 729 true,
714 (s) => { return ShouldSplitSimulationIslands; }, 730 (s) => { return ShouldSplitSimulationIslands; },
715 (s,v) => { ShouldSplitSimulationIslands = v; s.UnmanagedParams[0].shouldSplitSimulationIslands = NumericBool(v); } ), 731 (s,v) => { ShouldSplitSimulationIslands = v; s.UnmanagedParams[0].shouldSplitSimulationIslands = NumericBool(v); } ),
716 new ParameterDefn<bool>("ShouldEnableFrictionCaching", "Enable friction computation caching", 732 new ParameterDefn<bool>("ShouldEnableFrictionCaching", "Enable friction computation caching",
717 true, 733 true,
718 (s) => { return ShouldEnableFrictionCaching; }, 734 (s) => { return ShouldEnableFrictionCaching; },
719 (s,v) => { ShouldEnableFrictionCaching = v; s.UnmanagedParams[0].shouldEnableFrictionCaching = NumericBool(v); } ), 735 (s,v) => { ShouldEnableFrictionCaching = v; s.UnmanagedParams[0].shouldEnableFrictionCaching = NumericBool(v); } ),
720 new ParameterDefn<float>("NumberOfSolverIterations", "Number of internal iterations (0 means default)", 736 new ParameterDefn<float>("NumberOfSolverIterations", "Number of internal iterations (0 means default)",
721 0f, // zero says use Bullet default 737 0f, // zero says use Bullet default
722 (s) => { return NumberOfSolverIterations; }, 738 (s) => { return NumberOfSolverIterations; },
723 (s,v) => { NumberOfSolverIterations = v; s.UnmanagedParams[0].numberOfSolverIterations = v; } ), 739 (s,v) => { NumberOfSolverIterations = v; s.UnmanagedParams[0].numberOfSolverIterations = v; } ),
724 new ParameterDefn<bool>("UseSingleSidedMeshes", "Whether to compute collisions based on single sided meshes.", 740 new ParameterDefn<bool>("UseSingleSidedMeshes", "Whether to compute collisions based on single sided meshes.",
725 true, 741 true,
726 (s) => { return UseSingleSidedMeshes; }, 742 (s) => { return UseSingleSidedMeshes; },
727 (s,v) => { UseSingleSidedMeshes = v; s.UnmanagedParams[0].useSingleSidedMeshes = NumericBool(v); } ), 743 (s,v) => { UseSingleSidedMeshes = v; s.UnmanagedParams[0].useSingleSidedMeshes = NumericBool(v); } ),
728 new ParameterDefn<float>("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))", 744 new ParameterDefn<float>("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))",
729 0f, 745 0f,
730 (s) => { return GlobalContactBreakingThreshold; }, 746 (s) => { return GlobalContactBreakingThreshold; },
731 (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), 747 (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ),
732 new ParameterDefn<float>("PhysicsUnmanLoggingFrames", "If non-zero, frames between output of detailed unmanaged physics statistics", 748 new ParameterDefn<float>("PhysicsUnmanLoggingFrames", "If non-zero, frames between output of detailed unmanaged physics statistics",
733 0f, 749 0f,
734 (s) => { return PhysicsUnmanLoggingFrames; }, 750 (s) => { return PhysicsUnmanLoggingFrames; },
735 (s,v) => { PhysicsUnmanLoggingFrames = v; s.UnmanagedParams[0].physicsLoggingFrames = v; } ), 751 (s,v) => { PhysicsUnmanLoggingFrames = v; s.UnmanagedParams[0].physicsLoggingFrames = v; } ),
736 752
737 new ParameterDefn<int>("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy", 753 new ParameterDefn<int>("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy",
738 7 ), 754 7 ),
739 new ParameterDefn<int>("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes", 755 new ParameterDefn<int>("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes",
740 2 ), 756 2 ),
741 new ParameterDefn<float>("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)", 757 new ParameterDefn<float>("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)",
742 5f ), 758 5f ),
743 new ParameterDefn<float>("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)", 759 new ParameterDefn<float>("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)",
744 5f ), 760 5f ),
745 new ParameterDefn<int>("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.", 761 new ParameterDefn<int>("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.",
746 32 ), 762 32 ),
747 new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.", 763 new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.",
748 0f ), 764 0f ),
749 765
750 new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull", 766 new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull",
751 200f ), 767 200f ),
752 new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh", 768 new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh",
753 10f ), 769 10f ),
754 new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls", 770 new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls",
755 20f ), 771 20f ),
756 new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull", 772 new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull",
757 0.1f ), 773 0.1f ),
758 new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be", 774 new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be",
759 10f ), 775 10f ),
760 new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors", 776 new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors",
761 true ), 777 true ),
762 new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls", 778 new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls",
763 true ), 779 true ),
764 new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces", 780 new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces",
765 true ), 781 true ),
766 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin", 782 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin",
767 false ), 783 false ),
768 784
769 new ParameterDefn<float>("WhichHACD", "zero if Bullet HACD, non-zero says VHACD", 785 new ParameterDefn<float>("WhichHACD", "zero if Bullet HACD, non-zero says VHACD",
770 0f ), 786 0f ),
771 new ParameterDefn<float>("VHACDresolution", "max number of voxels generated during voxelization stage", 787 new ParameterDefn<float>("VHACDresolution", "max number of voxels generated during voxelization stage",
772 100000f ), 788 100000f ),
773 new ParameterDefn<float>("VHACDdepth", "max number of clipping stages", 789 new ParameterDefn<float>("VHACDdepth", "max number of clipping stages",
774 20f ), 790 20f ),
775 new ParameterDefn<float>("VHACDconcavity", "maximum concavity", 791 new ParameterDefn<float>("VHACDconcavity", "maximum concavity",
776 0.0025f ), 792 0.0025f ),
777 new ParameterDefn<float>("VHACDplaneDownsampling", "granularity of search for best clipping plane", 793 new ParameterDefn<float>("VHACDplaneDownsampling", "granularity of search for best clipping plane",
778 4f ), 794 4f ),
779 new ParameterDefn<float>("VHACDconvexHullDownsampling", "precision of hull gen process", 795 new ParameterDefn<float>("VHACDconvexHullDownsampling", "precision of hull gen process",
780 4f ), 796 4f ),
781 new ParameterDefn<float>("VHACDalpha", "bias toward clipping along symmetry planes", 797 new ParameterDefn<float>("VHACDalpha", "bias toward clipping along symmetry planes",
782 0.05f ), 798 0.05f ),
783 new ParameterDefn<float>("VHACDbeta", "bias toward clipping along revolution axis", 799 new ParameterDefn<float>("VHACDbeta", "bias toward clipping along revolution axis",
784 0.05f ), 800 0.05f ),
785 new ParameterDefn<float>("VHACDgamma", "max concavity when merging", 801 new ParameterDefn<float>("VHACDgamma", "max concavity when merging",
786 0.00125f ), 802 0.00125f ),
787 new ParameterDefn<float>("VHACDpca", "on/off normalizing mesh before decomp", 803 new ParameterDefn<float>("VHACDpca", "on/off normalizing mesh before decomp",
788 0f ), 804 0f ),
789 new ParameterDefn<float>("VHACDmode", "0:voxel based, 1: tetrahedron based", 805 new ParameterDefn<float>("VHACDmode", "0:voxel based, 1: tetrahedron based",
790 0f ), 806 0f ),
791 new ParameterDefn<float>("VHACDmaxNumVerticesPerCH", "max triangles per convex hull", 807 new ParameterDefn<float>("VHACDmaxNumVerticesPerCH", "max triangles per convex hull",
792 64f ), 808 64f ),
793 new ParameterDefn<float>("VHACDminVolumePerCH", "sampling of generated convex hulls", 809 new ParameterDefn<float>("VHACDminVolumePerCH", "sampling of generated convex hulls",
794 0.0001f ), 810 0.0001f ),
795 811
796 new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", 812 new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
797 (float)BSLinkset.LinksetImplementation.Compound ), 813 (float)BSLinkset.LinksetImplementation.Compound ),
798 new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same", 814 new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same",
799 true ), 815 true ),
800 new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", 816 new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
801 false ), 817 false ),
802 new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", 818 new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
803 true ), 819 true ),
804 new ParameterDefn<float>("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", 820 new ParameterDefn<float>("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints",
805 5.0f ), 821 5.0f ),
806 new ParameterDefn<float>("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", 822 new ParameterDefn<float>("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints",
807 0.1f ), 823 0.1f ),
808 new ParameterDefn<float>("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", 824 new ParameterDefn<float>("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
809 0.1f ), 825 0.1f ),
810 new ParameterDefn<float>("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", 826 new ParameterDefn<float>("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
811 0.1f ), 827 0.1f ),
812 new ParameterDefn<float>("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", 828 new ParameterDefn<float>("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
813 40 ), 829 40 ),
814 830
831 new ParameterDefn<bool>("UseBulletRaycast", "If 'true', use the raycast function of the Bullet physics engine",
832 true ),
833
834 new ParameterDefn<float>("DebugNumber", "A console setable number sometimes used for debugging",
835 1.0f ),
836
815 new ParameterDefn<int>("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)", 837 new ParameterDefn<int>("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)",
816 0, 838 0,
817 (s) => { return s.PhysicsMetricDumpFrames; }, 839 (s) => { return s.PhysicsMetricDumpFrames; },
@@ -819,7 +841,7 @@ public static class BSParam
819 new ParameterDefn<float>("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool", 841 new ParameterDefn<float>("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool",
820 0f, 842 0f,
821 (s) => { return 0f; }, 843 (s) => { return 0f; },
822 (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v, false /* inTaintTime */); } ), 844 (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v); } ),
823 new ParameterDefn<float>("ResetConstraintSolver", "Setting this is any value resets the constraint solver", 845 new ParameterDefn<float>("ResetConstraintSolver", "Setting this is any value resets the constraint solver",
824 0f, 846 0f,
825 (s) => { return 0f; }, 847 (s) => { return 0f; },
@@ -905,10 +927,10 @@ public static class BSParam
905 // ===================================================================== 927 // =====================================================================
906 // There are parameters that, when set, cause things to happen in the physics engine. 928 // There are parameters that, when set, cause things to happen in the physics engine.
907 // This causes the broadphase collision cache to be cleared. 929 // This causes the broadphase collision cache to be cleared.
908 private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v, bool inTaintTime) 930 private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v)
909 { 931 {
910 BSScene physScene = pPhysScene; 932 BSScene physScene = pPhysScene;
911 physScene.TaintedObject(inTaintTime, "BSParam.ResetBroadphasePoolTainted", delegate() 933 physScene.TaintedObject(BSScene.DetailLogZero, "BSParam.ResetBroadphasePoolTainted", delegate()
912 { 934 {
913 physScene.PE.ResetBroadphasePool(physScene.World); 935 physScene.PE.ResetBroadphasePool(physScene.World);
914 }); 936 });
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs
index da3fc18..6aa24d5 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs
@@ -230,34 +230,97 @@ public abstract class BSPhysObject : PhysicsActor
230 // Update the physical location and motion of the object. Called with data from Bullet. 230 // Update the physical location and motion of the object. Called with data from Bullet.
231 public abstract void UpdateProperties(EntityProperties entprop); 231 public abstract void UpdateProperties(EntityProperties entprop);
232 232
233 // The position value as known by BulletSim. Does not effect the physics engine.
233 public virtual OMV.Vector3 RawPosition { get; set; } 234 public virtual OMV.Vector3 RawPosition { get; set; }
235 // Set position in BulletSim and the physics engined to a value immediately. Must be called at taint time.
234 public abstract OMV.Vector3 ForcePosition { get; set; } 236 public abstract OMV.Vector3 ForcePosition { get; set; }
235 237
238 // The orientation value as known by BulletSim. Does not effect the physics engine.
236 public virtual OMV.Quaternion RawOrientation { get; set; } 239 public virtual OMV.Quaternion RawOrientation { get; set; }
240 // Set orientation in BulletSim and the physics engine to a value immediately. Must be called at taint time.
237 public abstract OMV.Quaternion ForceOrientation { get; set; } 241 public abstract OMV.Quaternion ForceOrientation { get; set; }
238 242
243 // The velocity value as known by BulletSim. Does not effect the physics engine.
239 public virtual OMV.Vector3 RawVelocity { get; set; } 244 public virtual OMV.Vector3 RawVelocity { get; set; }
245 // Set velocity in BulletSim and the physics engined to a value immediately. Must be called at taint time.
240 public abstract OMV.Vector3 ForceVelocity { get; set; } 246 public abstract OMV.Vector3 ForceVelocity { get; set; }
241 247
248 // The rotational velocity value as known by BulletSim. Does not effect the physics engine.
249 public OMV.Vector3 RawRotationalVelocity { get; set; }
250
251 // RawForce is a constant force applied to object (see Force { set; } )
242 public OMV.Vector3 RawForce { get; set; } 252 public OMV.Vector3 RawForce { get; set; }
243 public OMV.Vector3 RawTorque { get; set; } 253 public OMV.Vector3 RawTorque { get; set; }
254
244 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) 255 public override void AddAngularForce(OMV.Vector3 force, bool pushforce)
245 { 256 {
246 AddAngularForce(force, pushforce, false); 257 AddAngularForce(false, force);
247 } 258 }
248 public abstract void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime); 259 public abstract void AddAngularForce(bool inTaintTime, OMV.Vector3 force);
249 public abstract void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime); 260 public abstract void AddForce(bool inTaintTime, OMV.Vector3 force);
250 261
251 public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } 262 // PhysicsActor.Velocity
263 public override OMV.Vector3 Velocity
264 {
265 get { return RawVelocity; }
266 set
267 {
268 // This sets the velocity now. BSCharacter will override to clear target velocity
269 // before calling this.
270 RawVelocity = value;
271 PhysScene.TaintedObject(LocalID, TypeName + ".SetVelocity", delegate () {
272 // DetailLog("{0},BSPhysObject.Velocity.set,vel={1}", LocalID, RawVelocity);
273 ForceVelocity = RawVelocity;
274 });
275 }
276 }
277
278 // PhysicsActor.SetMomentum
279 // All the physics engines use this as a way of forcing the velocity to something.
280 // BSCharacter overrides this so it can set the target velocity to zero before calling this.
281 public override void SetMomentum(OMV.Vector3 momentum)
282 {
283 this.Velocity = momentum;
284 }
285
286 public override OMV.Vector3 RotationalVelocity {
287 get {
288 return RawRotationalVelocity;
289 }
290 set {
291 RawRotationalVelocity = value;
292 Util.ClampV(RawRotationalVelocity, BSParam.MaxAngularVelocity);
293 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
294 PhysScene.TaintedObject(LocalID, TypeName + ".setRotationalVelocity", delegate()
295 {
296 ForceRotationalVelocity = RawRotationalVelocity;
297 });
298 }
299 }
300 public OMV.Vector3 ForceRotationalVelocity {
301 get {
302 return RawRotationalVelocity;
303 }
304 set {
305 RawRotationalVelocity = Util.ClampV(value, BSParam.MaxAngularVelocity);
306 if (PhysBody.HasPhysicalBody)
307 {
308 DetailLog("{0},{1}.ForceRotationalVel,taint,rotvel={2}", LocalID, TypeName, RawRotationalVelocity);
309 PhysScene.PE.SetAngularVelocity(PhysBody, RawRotationalVelocity);
310 // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
311 ActivateIfPhysical(false);
312 }
313 }
314 }
252 315
253 public abstract float ForceBuoyancy { get; set; } 316 public abstract float ForceBuoyancy { get; set; }
254 317
255 public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } 318 public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
256 319
257 public override bool PIDActive 320 public override bool PIDActive
258 { 321 {
259 get { return MoveToTargetActive; } 322 get { return MoveToTargetActive; }
260 set { MoveToTargetActive = value; } 323 set { MoveToTargetActive = value; }
261 } 324 }
262 325
263 public override OMV.Vector3 PIDTarget { set { MoveToTargetTarget = value; } } 326 public override OMV.Vector3 PIDTarget { set { MoveToTargetTarget = value; } }
@@ -268,7 +331,7 @@ public abstract class BSPhysObject : PhysicsActor
268 public float MoveToTargetTau { get; set; } 331 public float MoveToTargetTau { get; set; }
269 332
270 // Used for llSetHoverHeight and maybe vehicle height. Hover Height will override MoveTo target's Z 333 // Used for llSetHoverHeight and maybe vehicle height. Hover Height will override MoveTo target's Z
271 public override bool PIDHoverActive { set { HoverActive = value; } } 334 public override bool PIDHoverActive {get {return HoverActive;} set { HoverActive = value; } }
272 public override float PIDHoverHeight { set { HoverHeight = value; } } 335 public override float PIDHoverHeight { set { HoverHeight = value; } }
273 public override PIDHoverType PIDHoverType { set { HoverType = value; } } 336 public override PIDHoverType PIDHoverType { set { HoverType = value; } }
274 public override float PIDHoverTau { set { HoverTau = value; } } 337 public override float PIDHoverTau { set { HoverTau = value; } }
@@ -452,18 +515,24 @@ public abstract class BSPhysObject : PhysicsActor
452 private long CollisionsLastTickStep = -1; 515 private long CollisionsLastTickStep = -1;
453 516
454 // The simulation step is telling this object about a collision. 517 // The simulation step is telling this object about a collision.
518 // I'm the 'collider', the thing I'm colliding with is the 'collidee'.
455 // Return 'true' if a collision was processed and should be sent up. 519 // Return 'true' if a collision was processed and should be sent up.
456 // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision. 520 // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision.
457 // Called at taint time from within the Step() function 521 // Called at taint time from within the Step() function
458 public delegate bool CollideCall(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth); 522 public virtual bool Collide(BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
459 public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
460 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
461 { 523 {
462 bool ret = false; 524 bool ret = false;
463 525
526 // if 'collidee' is null, that means it is terrain
527 uint collideeLocalID = (collidee == null) ? BSScene.TERRAIN_ID : collidee.LocalID;
528 // All terrain goes by the TERRAIN_ID id when passed up as a collision
529 if (collideeLocalID <= PhysScene.TerrainManager.HighestTerrainID) {
530 collideeLocalID = BSScene.TERRAIN_ID;
531 }
532
464 // The following lines make IsColliding(), CollidingGround() and CollidingObj work 533 // The following lines make IsColliding(), CollidingGround() and CollidingObj work
465 CollidingStep = PhysScene.SimulationStep; 534 CollidingStep = PhysScene.SimulationStep;
466 if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID) 535 if (collideeLocalID == BSScene.TERRAIN_ID)
467 { 536 {
468 CollidingGroundStep = PhysScene.SimulationStep; 537 CollidingGroundStep = PhysScene.SimulationStep;
469 } 538 }
@@ -474,10 +543,13 @@ public abstract class BSPhysObject : PhysicsActor
474 543
475 CollisionAccumulation++; 544 CollisionAccumulation++;
476 545
477 // For movement tests, remember if we are colliding with an object that is moving. 546 // For movement tests, if the collider is me, remember if we are colliding with an object that is moving.
478 ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; 547 // Here the 'collider'/'collidee' thing gets messed up. In the larger context, when something is checking
548 // if the thing it is colliding with is moving, for instance, it asks if the its collider is moving.
549 ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero || collidee.RotationalVelocity != OMV.Vector3.Zero) : false;
479 ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false; 550 ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false;
480 551
552
481 // Make a collection of the collisions that happened the last simulation tick. 553 // Make a collection of the collisions that happened the last simulation tick.
482 // This is different than the collection created for sending up to the simulator as it is cleared every tick. 554 // This is different than the collection created for sending up to the simulator as it is cleared every tick.
483 if (CollisionsLastTickStep != PhysScene.SimulationStep) 555 if (CollisionsLastTickStep != PhysScene.SimulationStep)
@@ -485,16 +557,29 @@ public abstract class BSPhysObject : PhysicsActor
485 CollisionsLastTick = new CollisionEventUpdate(); 557 CollisionsLastTick = new CollisionEventUpdate();
486 CollisionsLastTickStep = PhysScene.SimulationStep; 558 CollisionsLastTickStep = PhysScene.SimulationStep;
487 } 559 }
488 CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 560 CollisionsLastTick.AddCollider(collideeLocalID, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
489 561
490 // If someone has subscribed for collision events log the collision so it will be reported up 562 // If someone has subscribed for collision events log the collision so it will be reported up
491 if (SubscribedEvents()) { 563 if (SubscribedEvents()) {
564 ContactPoint newContact = new ContactPoint(contactPoint, contactNormal, pentrationDepth);
565
566 // Collision sound requires a velocity to know it should happen. This is a lot of computation for a little used feature.
567 OMV.Vector3 relvel = OMV.Vector3.Zero;
568 if (IsPhysical)
569 relvel = RawVelocity;
570 if (collidee != null && collidee.IsPhysical)
571 relvel -= collidee.RawVelocity;
572 newContact.RelativeSpeed = -OMV.Vector3.Dot(relvel, contactNormal);
573 // DetailLog("{0},{1}.Collision.AddCollider,vel={2},contee.vel={3},relvel={4},relspeed={5}",
574 // LocalID, TypeName, RawVelocity, (collidee == null ? OMV.Vector3.Zero : collidee.RawVelocity), relvel, newContact.RelativeSpeed);
575
492 lock (PhysScene.CollisionLock) 576 lock (PhysScene.CollisionLock)
493 { 577 {
494 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 578 CollisionCollection.AddCollider(collideeLocalID, newContact);
495 } 579 }
496 DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}", 580 DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},speed={6},colliderMoving={7}",
497 LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); 581 LocalID, TypeName, collideeLocalID, contactPoint, contactNormal, pentrationDepth,
582 newContact.RelativeSpeed, ColliderIsMoving);
498 583
499 ret = true; 584 ret = true;
500 } 585 }
@@ -555,7 +640,11 @@ public abstract class BSPhysObject : PhysicsActor
555 PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate() 640 PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate()
556 { 641 {
557 if (PhysBody.HasPhysicalBody) 642 if (PhysBody.HasPhysicalBody)
643 {
558 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 644 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
645 DetailLog("{0},{1}.SubscribeEvents,setting collision. ms={2}, collisionFlags={3:x}",
646 LocalID, TypeName, SubscribedEventsMs, CurrentCollisionFlags);
647 }
559 }); 648 });
560 } 649 }
561 else 650 else
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs
index 6f27ac7..f085d70 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs
@@ -33,7 +33,7 @@ using log4net;
33using OMV = OpenMetaverse; 33using OMV = OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.PhysicsModules.SharedBase; 35using OpenSim.Region.PhysicsModules.SharedBase;
36using OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet; 36using OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet;
37 37
38namespace OpenSim.Region.PhysicsModule.BulletS 38namespace OpenSim.Region.PhysicsModule.BulletS
39{ 39{
@@ -59,7 +59,6 @@ public class BSPrim : BSPhysObject
59 private bool _setAlwaysRun; 59 private bool _setAlwaysRun;
60 private bool _throttleUpdates; 60 private bool _throttleUpdates;
61 private bool _floatOnWater; 61 private bool _floatOnWater;
62 private OMV.Vector3 _rotationalVelocity;
63 private bool _kinematic; 62 private bool _kinematic;
64 private float _buoyancy; 63 private float _buoyancy;
65 64
@@ -90,7 +89,7 @@ public class BSPrim : BSPhysObject
90 RawOrientation = rotation; 89 RawOrientation = rotation;
91 _buoyancy = 0f; 90 _buoyancy = 0f;
92 RawVelocity = OMV.Vector3.Zero; 91 RawVelocity = OMV.Vector3.Zero;
93 _rotationalVelocity = OMV.Vector3.Zero; 92 RawRotationalVelocity = OMV.Vector3.Zero;
94 BaseShape = pbs; 93 BaseShape = pbs;
95 _isPhysical = pisPhysical; 94 _isPhysical = pisPhysical;
96 _isVolumeDetect = false; 95 _isVolumeDetect = false;
@@ -256,7 +255,7 @@ public class BSPrim : BSPhysObject
256 { 255 {
257 RawVelocity = OMV.Vector3.Zero; 256 RawVelocity = OMV.Vector3.Zero;
258 _acceleration = OMV.Vector3.Zero; 257 _acceleration = OMV.Vector3.Zero;
259 _rotationalVelocity = OMV.Vector3.Zero; 258 RawRotationalVelocity = OMV.Vector3.Zero;
260 259
261 // Zero some other properties in the physics engine 260 // Zero some other properties in the physics engine
262 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate() 261 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
@@ -267,33 +266,33 @@ public class BSPrim : BSPhysObject
267 } 266 }
268 public override void ZeroAngularMotion(bool inTaintTime) 267 public override void ZeroAngularMotion(bool inTaintTime)
269 { 268 {
270 _rotationalVelocity = OMV.Vector3.Zero; 269 RawRotationalVelocity = OMV.Vector3.Zero;
271 // Zero some other properties in the physics engine 270 // Zero some other properties in the physics engine
272 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate() 271 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
273 { 272 {
274 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); 273 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
275 if (PhysBody.HasPhysicalBody) 274 if (PhysBody.HasPhysicalBody)
276 { 275 {
277 PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); 276 PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, RawRotationalVelocity);
278 PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); 277 PhysScene.PE.SetAngularVelocity(PhysBody, RawRotationalVelocity);
279 } 278 }
280 }); 279 });
281 } 280 }
282 281
283 public override void LockAngularMotion(OMV.Vector3 axis) 282 public override void LockAngularMotion(byte axislocks)
284 { 283 {
285 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 284 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axislocks);
286 285
287 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f); 286 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
288 if (axis.X != 1) 287 if ((axislocks & 0x02) != 0)
289 { 288 {
290 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f); 289 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
291 } 290 }
292 if (axis.Y != 1) 291 if ((axislocks & 0x04) != 0)
293 { 292 {
294 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f); 293 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f);
295 } 294 }
296 if (axis.Z != 1) 295 if ((axislocks & 0x08) != 0)
297 { 296 {
298 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f); 297 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f);
299 } 298 }
@@ -394,7 +393,7 @@ public class BSPrim : BSPhysObject
394 // Apply upforce and overcome gravity. 393 // Apply upforce and overcome gravity.
395 OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity; 394 OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity;
396 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, RawPosition, upForce, correctionForce); 395 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, RawPosition, upForce, correctionForce);
397 AddForce(correctionForce, false, inTaintTime); 396 AddForce(inTaintTime, correctionForce);
398 ret = true; 397 ret = true;
399 } 398 }
400 } 399 }
@@ -426,9 +425,9 @@ public class BSPrim : BSPhysObject
426 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity); 425 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity);
427 ret = true; 426 ret = true;
428 } 427 }
429 if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared) 428 if (RawRotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared)
430 { 429 {
431 _rotationalVelocity = Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); 430 RawRotationalVelocity = Util.ClampV(RawRotationalVelocity, BSParam.MaxAngularVelocity);
432 ret = true; 431 ret = true;
433 } 432 }
434 433
@@ -647,6 +646,59 @@ public class BSPrim : BSPhysObject
647 }); 646 });
648 } 647 }
649 648
649 public override void SetVehicle(object pvdata)
650 {
651 PhysScene.TaintedObject(LocalID, "BSPrim.SetVehicle", delegate ()
652 {
653 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
654 if (vehicleActor != null && (pvdata is VehicleData) )
655 {
656 VehicleData vdata = (VehicleData)pvdata;
657 // vehicleActor.ProcessSetVehicle((VehicleData)vdata);
658
659 vehicleActor.ProcessTypeChange(vdata.m_type);
660 vehicleActor.ProcessVehicleFlags(-1, false);
661 vehicleActor.ProcessVehicleFlags((int)vdata.m_flags, false);
662
663 // Linear properties
664 vehicleActor.ProcessVectorVehicleParam(Vehicle.LINEAR_MOTOR_DIRECTION, vdata.m_linearMotorDirection);
665 vehicleActor.ProcessVectorVehicleParam(Vehicle.LINEAR_FRICTION_TIMESCALE, vdata.m_linearFrictionTimescale);
666 vehicleActor.ProcessFloatVehicleParam(Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE, vdata.m_linearMotorDecayTimescale);
667 vehicleActor.ProcessFloatVehicleParam(Vehicle.LINEAR_MOTOR_TIMESCALE, vdata.m_linearMotorTimescale);
668 vehicleActor.ProcessVectorVehicleParam(Vehicle.LINEAR_MOTOR_OFFSET, vdata.m_linearMotorOffset);
669
670 //Angular properties
671 vehicleActor.ProcessVectorVehicleParam(Vehicle.ANGULAR_MOTOR_DIRECTION, vdata.m_angularMotorDirection);
672 vehicleActor.ProcessFloatVehicleParam(Vehicle.ANGULAR_MOTOR_TIMESCALE, vdata.m_angularMotorTimescale);
673 vehicleActor.ProcessFloatVehicleParam(Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE, vdata.m_angularMotorDecayTimescale);
674 vehicleActor.ProcessVectorVehicleParam(Vehicle.ANGULAR_FRICTION_TIMESCALE, vdata.m_angularFrictionTimescale);
675
676 //Deflection properties
677 vehicleActor.ProcessFloatVehicleParam(Vehicle.ANGULAR_DEFLECTION_EFFICIENCY, vdata.m_angularDeflectionEfficiency);
678 vehicleActor.ProcessFloatVehicleParam(Vehicle.ANGULAR_DEFLECTION_TIMESCALE, vdata.m_angularDeflectionTimescale);
679 vehicleActor.ProcessFloatVehicleParam(Vehicle.LINEAR_DEFLECTION_EFFICIENCY, vdata.m_linearDeflectionEfficiency);
680 vehicleActor.ProcessFloatVehicleParam(Vehicle.LINEAR_DEFLECTION_TIMESCALE, vdata.m_linearDeflectionTimescale);
681
682 //Banking properties
683 vehicleActor.ProcessFloatVehicleParam(Vehicle.BANKING_EFFICIENCY, vdata.m_bankingEfficiency);
684 vehicleActor.ProcessFloatVehicleParam(Vehicle.BANKING_MIX, vdata.m_bankingMix);
685 vehicleActor.ProcessFloatVehicleParam(Vehicle.BANKING_TIMESCALE, vdata.m_bankingTimescale);
686
687 //Hover and Buoyancy properties
688 vehicleActor.ProcessFloatVehicleParam(Vehicle.HOVER_HEIGHT, vdata.m_VhoverHeight);
689 vehicleActor.ProcessFloatVehicleParam(Vehicle.HOVER_EFFICIENCY, vdata.m_VhoverEfficiency);
690 vehicleActor.ProcessFloatVehicleParam(Vehicle.HOVER_TIMESCALE, vdata.m_VhoverTimescale);
691 vehicleActor.ProcessFloatVehicleParam(Vehicle.BUOYANCY, vdata.m_VehicleBuoyancy);
692
693 //Attractor properties
694 vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, vdata.m_verticalAttractionEfficiency);
695 vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, vdata.m_verticalAttractionTimescale);
696
697 vehicleActor.ProcessRotationVehicleParam(Vehicle.REFERENCE_FRAME, vdata.m_referenceFrame);
698 }
699 });
700 }
701
650 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more 702 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
651 public override void SetVolumeDetect(int param) { 703 public override void SetVolumeDetect(int param) {
652 bool newValue = (param != 0); 704 bool newValue = (param != 0);
@@ -735,22 +787,9 @@ public class BSPrim : BSPhysObject
735 } 787 }
736 } 788 }
737 } 789 }
738 public override OMV.Vector3 Velocity {
739 get { return RawVelocity; }
740 set {
741 RawVelocity = value;
742 PhysScene.TaintedObject(LocalID, "BSPrim.setVelocity", delegate()
743 {
744 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
745 ForceVelocity = RawVelocity;
746 });
747 }
748 }
749 public override OMV.Vector3 ForceVelocity { 790 public override OMV.Vector3 ForceVelocity {
750 get { return RawVelocity; } 791 get { return RawVelocity; }
751 set { 792 set {
752 PhysScene.AssertInTaintTime("BSPrim.ForceVelocity");
753
754 RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); 793 RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
755 if (PhysBody.HasPhysicalBody) 794 if (PhysBody.HasPhysicalBody)
756 { 795 {
@@ -955,7 +994,7 @@ public class BSPrim : BSPhysObject
955 // For good measure, make sure the transform is set through to the motion state 994 // For good measure, make sure the transform is set through to the motion state
956 ForcePosition = RawPosition; 995 ForcePosition = RawPosition;
957 ForceVelocity = RawVelocity; 996 ForceVelocity = RawVelocity;
958 ForceRotationalVelocity = _rotationalVelocity; 997 ForceRotationalVelocity = RawRotationalVelocity;
959 998
960 // A dynamic object has mass 999 // A dynamic object has mass
961 UpdatePhysicalMassProperties(RawMass, false); 1000 UpdatePhysicalMassProperties(RawMass, false);
@@ -1075,35 +1114,6 @@ public class BSPrim : BSPhysObject
1075 }); 1114 });
1076 } 1115 }
1077 } 1116 }
1078 public override OMV.Vector3 RotationalVelocity {
1079 get {
1080 return _rotationalVelocity;
1081 }
1082 set {
1083 _rotationalVelocity = value;
1084 Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity);
1085 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
1086 PhysScene.TaintedObject(LocalID, "BSPrim.setRotationalVelocity", delegate()
1087 {
1088 ForceRotationalVelocity = _rotationalVelocity;
1089 });
1090 }
1091 }
1092 public override OMV.Vector3 ForceRotationalVelocity {
1093 get {
1094 return _rotationalVelocity;
1095 }
1096 set {
1097 _rotationalVelocity = Util.ClampV(value, BSParam.MaxAngularVelocity);
1098 if (PhysBody.HasPhysicalBody)
1099 {
1100 DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
1101 PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
1102 // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
1103 ActivateIfPhysical(false);
1104 }
1105 }
1106 }
1107 public override bool Kinematic { 1117 public override bool Kinematic {
1108 get { return _kinematic; } 1118 get { return _kinematic; }
1109 set { _kinematic = value; 1119 set { _kinematic = value;
@@ -1132,14 +1142,14 @@ public class BSPrim : BSPhysObject
1132 } 1142 }
1133 } 1143 }
1134 1144
1135 public override bool PIDActive 1145 public override bool PIDActive
1136 { 1146 {
1137 get 1147 get
1138 { 1148 {
1139 return MoveToTargetActive; 1149 return MoveToTargetActive;
1140 } 1150 }
1141 1151
1142 set 1152 set
1143 { 1153 {
1144 MoveToTargetActive = value; 1154 MoveToTargetActive = value;
1145 1155
@@ -1167,12 +1177,16 @@ public class BSPrim : BSPhysObject
1167 // if the actor exists, tell it to refresh its values. 1177 // if the actor exists, tell it to refresh its values.
1168 actor.Refresh(); 1178 actor.Refresh();
1169 } 1179 }
1170 1180
1171 } 1181 }
1172 } 1182 }
1173 // Used for llSetHoverHeight and maybe vehicle height 1183 // Used for llSetHoverHeight and maybe vehicle height
1174 // Hover Height will override MoveTo target's Z 1184 // Hover Height will override MoveTo target's Z
1175 public override bool PIDHoverActive { 1185 public override bool PIDHoverActive {
1186 get
1187 {
1188 return base.HoverActive;
1189 }
1176 set { 1190 set {
1177 base.HoverActive = value; 1191 base.HoverActive = value;
1178 EnableActor(HoverActive, HoverActorName, delegate() 1192 EnableActor(HoverActive, HoverActorName, delegate()
@@ -1192,14 +1206,18 @@ public class BSPrim : BSPhysObject
1192 // Per documentation, max force is limited. 1206 // Per documentation, max force is limited.
1193 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); 1207 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
1194 1208
1195 // Since this force is being applied in only one step, make this a force per second. 1209 // Push forces seem to be scaled differently (follow pattern in ubODE)
1196 addForce /= PhysScene.LastTimeStep; 1210 if (!pushforce) {
1197 AddForce(addForce, pushforce, false /* inTaintTime */); 1211 // Since this force is being applied in only one step, make this a force per second.
1212 addForce /= PhysScene.LastTimeStep;
1213 }
1214
1215 AddForce(false /* inTaintTime */, addForce);
1198 } 1216 }
1199 1217
1200 // Applying a force just adds this to the total force on the object. 1218 // Applying a force just adds this to the total force on the object.
1201 // This added force will only last the next simulation tick. 1219 // This added force will only last the next simulation tick.
1202 public override void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 1220 public override void AddForce(bool inTaintTime, OMV.Vector3 force) {
1203 // for an object, doesn't matter if force is a pushforce or not 1221 // for an object, doesn't matter if force is a pushforce or not
1204 if (IsPhysicallyActive) 1222 if (IsPhysicallyActive)
1205 { 1223 {
@@ -1258,7 +1276,7 @@ public class BSPrim : BSPhysObject
1258 } 1276 }
1259 1277
1260 // BSPhysObject.AddAngularForce() 1278 // BSPhysObject.AddAngularForce()
1261 public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) 1279 public override void AddAngularForce(bool inTaintTime, OMV.Vector3 force)
1262 { 1280 {
1263 if (force.IsFinite()) 1281 if (force.IsFinite())
1264 { 1282 {
@@ -1297,9 +1315,6 @@ public class BSPrim : BSPhysObject
1297 }); 1315 });
1298 } 1316 }
1299 1317
1300 public override void SetMomentum(OMV.Vector3 momentum) {
1301 // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
1302 }
1303 #region Mass Calculation 1318 #region Mass Calculation
1304 1319
1305 private float CalculateMass() 1320 private float CalculateMass()
@@ -1869,7 +1884,7 @@ public class BSPrim : BSPhysObject
1869 if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold)) 1884 if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
1870 RawVelocity = entprop.Velocity; 1885 RawVelocity = entprop.Velocity;
1871 _acceleration = entprop.Acceleration; 1886 _acceleration = entprop.Acceleration;
1872 _rotationalVelocity = entprop.RotationalVelocity; 1887 RawRotationalVelocity = entprop.RotationalVelocity;
1873 1888
1874 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG 1889 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1875 1890
@@ -1878,7 +1893,7 @@ public class BSPrim : BSPhysObject
1878 { 1893 {
1879 entprop.Position = RawPosition; 1894 entprop.Position = RawPosition;
1880 entprop.Velocity = RawVelocity; 1895 entprop.Velocity = RawVelocity;
1881 entprop.RotationalVelocity = _rotationalVelocity; 1896 entprop.RotationalVelocity = RawRotationalVelocity;
1882 entprop.Acceleration = _acceleration; 1897 entprop.Acceleration = _acceleration;
1883 } 1898 }
1884 1899
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs
index d8ed56b..3f90fc5 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs
@@ -81,7 +81,6 @@ public class BSPrimDisplaced : BSPrim
81 // Called at taint time. 81 // Called at taint time.
82 public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) 82 public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement)
83 { 83 {
84 PhysScene.AssertInTaintTime("BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement");
85 Vector3 comDisp; 84 Vector3 comDisp;
86 if (UserSetCenterOfMassDisplacement.HasValue) 85 if (UserSetCenterOfMassDisplacement.HasValue)
87 comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; 86 comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement;
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs
index 55b5da0..563dcfa 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs
@@ -203,15 +203,14 @@ public class BSPrimLinkable : BSPrimDisplaced
203 // Called after a simulation step to post a collision with this object. 203 // Called after a simulation step to post a collision with this object.
204 // This returns 'true' if the collision has been queued and the SendCollisions call must 204 // This returns 'true' if the collision has been queued and the SendCollisions call must
205 // be made at the end of the simulation step. 205 // be made at the end of the simulation step.
206 public override bool Collide(uint collidingWith, BSPhysObject collidee, 206 public override bool Collide(BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
207 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
208 { 207 {
209 bool ret = false; 208 bool ret = false;
210 // Ask the linkset if it wants to handle the collision 209 // Ask the linkset if it wants to handle the collision
211 if (!Linkset.HandleCollide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth)) 210 if (!Linkset.HandleCollide(this, collidee, contactPoint, contactNormal, pentrationDepth))
212 { 211 {
213 // The linkset didn't handle it so pass the collision through normal processing 212 // The linkset didn't handle it so pass the collision through normal processing
214 ret = base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth); 213 ret = base.Collide(collidee, contactPoint, contactNormal, pentrationDepth);
215 } 214 }
216 return ret; 215 return ret;
217 } 216 }
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
index 452ce55..163efaa 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
@@ -124,9 +124,10 @@ namespace OpenSim.Region.PhysicsModule.BulletS
124 // True if initialized and ready to do simulation steps 124 // True if initialized and ready to do simulation steps
125 private bool m_initialized = false; 125 private bool m_initialized = false;
126 126
127 // Flag which is true when processing taints. 127 // Object locked whenever execution is inside the physics engine
128 // Not guaranteed to be correct all the time (don't depend on this) but good for debugging. 128 public Object PhysicsEngineLock = new object();
129 public bool InTaintTime { get; private set; } 129 // Flag that is true when the simulator is active and shouldn't be touched
130 public bool InSimulationTime { get; private set; }
130 131
131 // Pinned memory used to pass step information between managed and unmanaged 132 // Pinned memory used to pass step information between managed and unmanaged
132 internal int m_maxCollisionsPerFrame; 133 internal int m_maxCollisionsPerFrame;
@@ -212,6 +213,11 @@ namespace OpenSim.Region.PhysicsModule.BulletS
212 get { return "BulletSim"; } 213 get { return "BulletSim"; }
213 } 214 }
214 215
216 public string Version
217 {
218 get { return "1.0"; }
219 }
220
215 public Type ReplaceableInterface 221 public Type ReplaceableInterface
216 { 222 {
217 get { return null; } 223 get { return null; }
@@ -245,6 +251,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
245 EngineType = Name; 251 EngineType = Name;
246 RegionName = scene.RegionInfo.RegionName; 252 RegionName = scene.RegionInfo.RegionName;
247 PhysicsSceneName = EngineType + "/" + RegionName; 253 PhysicsSceneName = EngineType + "/" + RegionName;
254 EngineName = Name + " " + Version;
248 255
249 scene.RegisterModuleInterface<PhysicsScene>(this); 256 scene.RegisterModuleInterface<PhysicsScene>(this);
250 Vector3 extent = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, scene.RegionInfo.RegionSizeZ); 257 Vector3 extent = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, scene.RegionInfo.RegionSizeZ);
@@ -338,19 +345,19 @@ namespace OpenSim.Region.PhysicsModule.BulletS
338 // Put some informational messages into the log file. 345 // Put some informational messages into the log file.
339 m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation); 346 m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation);
340 347
341 InTaintTime = false; 348 InSimulationTime = false;
342 m_initialized = true; 349 m_initialized = true;
343 350
344 // If the physics engine runs on its own thread, start same. 351 // If the physics engine runs on its own thread, start same.
345 if (BSParam.UseSeparatePhysicsThread) 352 if (BSParam.UseSeparatePhysicsThread)
346 { 353 {
347 // The physics simulation should happen independently of the heartbeat loop 354 // The physics simulation should happen independently of the heartbeat loop
348 m_physicsThread 355 m_physicsThread
349 = WorkManager.StartThread( 356 = WorkManager.StartThread(
350 BulletSPluginPhysicsThread, 357 BulletSPluginPhysicsThread,
351 string.Format("{0} ({1})", BulletEngineName, RegionName), 358 string.Format("{0} ({1})", BulletEngineName, RegionName),
352 ThreadPriority.Normal, 359 ThreadPriority.Normal,
353 true, 360 true,
354 true); 361 true);
355 } 362 }
356 } 363 }
@@ -523,13 +530,13 @@ namespace OpenSim.Region.PhysicsModule.BulletS
523 return null; 530 return null;
524 } 531 }
525 532
526 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) 533 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float footOffset, bool isFlying)
527 { 534 {
528 // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName); 535 // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName);
529 536
530 if (!m_initialized) return null; 537 if (!m_initialized) return null;
531 538
532 BSCharacter actor = new BSCharacter(localID, avName, this, position, velocity, size, isFlying); 539 BSCharacter actor = new BSCharacter(localID, avName, this, position, Vector3.Zero, size, footOffset, isFlying);
533 lock (PhysObjects) 540 lock (PhysObjects)
534 PhysObjects.Add(localID, actor); 541 PhysObjects.Add(localID, actor);
535 542
@@ -651,49 +658,57 @@ namespace OpenSim.Region.PhysicsModule.BulletS
651 658
652 int beforeTime = Util.EnvironmentTickCount(); 659 int beforeTime = Util.EnvironmentTickCount();
653 int simTime = 0; 660 int simTime = 0;
661 int numTaints = 0;
662 int numSubSteps = 0;
654 663
655 int numTaints = _taintOperations.Count; 664 lock (PhysicsEngineLock)
656 InTaintTime = true; // Only used for debugging so locking is not necessary. 665 {
666 InSimulationTime = true;
667 // update the prim states while we know the physics engine is not busy
668 numTaints += ProcessTaints();
657 669
658 // update the prim states while we know the physics engine is not busy 670 // Some of the physical objects requre individual, pre-step calls
659 ProcessTaints(); 671 // (vehicles and avatar movement, in particular)
672 TriggerPreStepEvent(timeStep);
660 673
661 // Some of the physical objects requre individual, pre-step calls 674 // the prestep actions might have added taints
662 // (vehicles and avatar movement, in particular) 675 numTaints += ProcessTaints();
663 TriggerPreStepEvent(timeStep);
664 676
665 // the prestep actions might have added taints 677 // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
666 numTaints += _taintOperations.Count; 678 // Only enable this in a limited test world with few objects.
667 ProcessTaints(); 679 if (m_physicsPhysicalDumpEnabled)
680 PE.DumpAllInfo(World);
668 681
669 InTaintTime = false; // Only used for debugging so locking is not necessary. 682 // step the physical world one interval
683 m_simulationStep++;
684 try
685 {
686 numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
687 }
688 catch (Exception e)
689 {
690 m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
691 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
692 DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
693 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
694 updatedEntityCount = 0;
695 collidersCount = 0;
696 }
670 697
671 // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. 698 // Make the physics engine dump useful statistics periodically
672 // Only enable this in a limited test world with few objects. 699 if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0))
673 if (m_physicsPhysicalDumpEnabled) 700 PE.DumpPhysicsStatistics(World);
674 PE.DumpAllInfo(World);
675 701
676 // step the physical world one interval 702 InSimulationTime = false;
677 m_simulationStep++;
678 int numSubSteps = 0;
679 try
680 {
681 numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
682 703
683 } 704 // Some actors want to know when the simulation step is complete.
684 catch (Exception e) 705 TriggerPostStepEvent(timeStep);
685 { 706
686 m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}", 707 // In case there were any parameter updates that happened during the simulation step
687 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e); 708 numTaints += ProcessTaints();
688 DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
689 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
690 updatedEntityCount = 0;
691 collidersCount = 0;
692 }
693 709
694 // Make the physics engine dump useful statistics periodically 710 InSimulationTime = false;
695 if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0)) 711 }
696 PE.DumpPhysicsStatistics(World);
697 712
698 // Get a value for 'now' so all the collision and update routines don't have to get their own. 713 // Get a value for 'now' so all the collision and update routines don't have to get their own.
699 SimulationNowTime = Util.EnvironmentTickCount(); 714 SimulationNowTime = Util.EnvironmentTickCount();
@@ -743,9 +758,6 @@ namespace OpenSim.Region.PhysicsModule.BulletS
743 } 758 }
744 } 759 }
745 760
746 // Some actors want to know when the simulation step is complete.
747 TriggerPostStepEvent(timeStep);
748
749 simTime = Util.EnvironmentTickCountSubtract(beforeTime); 761 simTime = Util.EnvironmentTickCountSubtract(beforeTime);
750 if (PhysicsLogging.Enabled) 762 if (PhysicsLogging.Enabled)
751 { 763 {
@@ -762,7 +774,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS
762 // The physics engine returns the number of milliseconds it simulated this call. 774 // The physics engine returns the number of milliseconds it simulated this call.
763 // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. 775 // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
764 // Multiply by a fixed nominal frame rate to give a rate similar to the simulator (usually 55). 776 // Multiply by a fixed nominal frame rate to give a rate similar to the simulator (usually 55).
765 m_simulatedTime += (float)numSubSteps * m_fixedTimeStep * 1000f * NominalFrameRate; 777// m_simulatedTime += (float)numSubSteps * m_fixedTimeStep * 1000f * NominalFrameRate;
778 m_simulatedTime += (float)numSubSteps * m_fixedTimeStep;
766 } 779 }
767 780
768 // Called by a BSPhysObject to note that it has changed properties and this information 781 // Called by a BSPhysObject to note that it has changed properties and this information
@@ -849,7 +862,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
849 862
850 // Return the framerate simulated to give the above returned results. 863 // Return the framerate simulated to give the above returned results.
851 // (Race condition here but this is just bookkeeping so rare mistakes do not merit a lock). 864 // (Race condition here but this is just bookkeeping so rare mistakes do not merit a lock).
852 float simTime = m_simulatedTime; 865 float simTime = m_simulatedTime / timeStep;
853 m_simulatedTime = 0f; 866 m_simulatedTime = 0f;
854 return simTime; 867 return simTime;
855 } 868 }
@@ -879,7 +892,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
879 892
880 if (collider.IsInitialized) 893 if (collider.IsInitialized)
881 { 894 {
882 if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) 895 if (collider.Collide(collidee, collidePoint, collideNormal, penetration))
883 { 896 {
884 // If a collision was 'good', remember to send it to the simulator 897 // If a collision was 'good', remember to send it to the simulator
885 lock (CollisionLock) 898 lock (CollisionLock)
@@ -948,26 +961,150 @@ namespace OpenSim.Region.PhysicsModule.BulletS
948 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); 961 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
949 } 962 }
950 963
951 // Although no one seems to check this, I do support combining. 964 #endregion // Terrain
952 public override bool SupportsCombining() 965
966 #region Raycast
967
968 public override bool SupportsRayCast()
953 { 969 {
954 return TerrainManager.SupportsCombining(); 970 return BSParam.UseBulletRaycast;
955 } 971 }
956 // This call says I am a child to region zero in a mega-region. 'pScene' is that 972
957 // of region zero, 'offset' is my offset from regions zero's origin, and 973 public override bool SupportsRaycastWorldFiltered()
958 // 'extents' is the largest XY that is handled in my region.
959 public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
960 { 974 {
961 TerrainManager.Combine(pScene, offset, extents); 975 return BSParam.UseBulletRaycast;
962 } 976 }
963 977
964 // Unhook all the combining that I know about. 978
965 public override void UnCombine(PhysicsScene pScene) 979 /// <summary>
980 /// Queue a raycast against the physics scene.
981 /// The provided callback method will be called when the raycast is complete
982 ///
983 /// Many physics engines don't support collision testing at the same time as
984 /// manipulating the physics scene, so we queue the request up and callback
985 /// a custom method when the raycast is complete.
986 /// This allows physics engines that give an immediate result to callback immediately
987 /// and ones that don't, to callback when it gets a result back.
988 /// public delegate void RayCallback(List<ContactResult> list);
989 ///
990 /// ODE for example will not allow you to change the scene while collision testing or
991 /// it asserts, 'opteration not valid for locked space'. This includes adding a ray to the scene.
992 ///
993 /// This is named RayCastWorld to not conflict with modrex's Raycast method.
994 /// </summary>
995 /// <param name="position">Origin of the ray</param>
996 /// <param name="direction">Direction of the ray</param>
997 /// <param name="length">Length of ray in meters</param>
998 /// <param name="retMethod">Method to call when the raycast is complete</param>
999 public override void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
966 { 1000 {
967 TerrainManager.UnCombine(pScene); 1001 if (retMethod != null)
1002 {
1003 if (BSParam.UseBulletRaycast)
1004 {
1005 Vector3 posFrom = position;
1006 Vector3 posTo = Vector3.Normalize(direction) * length + position;
1007
1008 TaintedObject(DetailLogZero, "BSScene.RaycastWorld1", delegate ()
1009 {
1010 RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, 0xffff, 0xffff);
1011 retMethod(true, hitInfo.Point, hitInfo.ID, hitInfo.Fraction, hitInfo.Normal);
1012 });
1013 }
1014 else
1015 {
1016 retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero);
1017 }
1018 }
968 } 1019 }
969 1020
970 #endregion // Terrain 1021 public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
1022 {
1023 if (retMethod != null)
1024 {
1025 if (BSParam.UseBulletRaycast)
1026 {
1027 List<ContactResult> hitInfo = RaycastWorld(position, direction, length, count);
1028 retMethod(hitInfo);
1029 }
1030 else
1031 {
1032 retMethod(new List<ContactResult>());
1033 }
1034 }
1035 }
1036
1037 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int count)
1038 {
1039 return (List<ContactResult>)RaycastWorld(position, direction, length, count, RayFilterFlags.All);
1040 }
1041
1042 public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayFilterFlags filter)
1043 {
1044 List<ContactResult> ret = new List<ContactResult>();
1045 if (BSParam.UseBulletRaycast)
1046 {
1047 uint collisionFilter = 0;
1048 uint collisionMask = 0;
1049 if ((filter & RayFilterFlags.land) != 0)
1050 {
1051 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Terrain].group;
1052 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Terrain].mask;
1053 }
1054 if ((filter & RayFilterFlags.agent) != 0)
1055 {
1056 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Avatar].group;
1057 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Avatar].mask;
1058 }
1059 if ((filter & RayFilterFlags.nonphysical) != 0)
1060 {
1061 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Static].group;
1062 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Static].mask;
1063 }
1064 if ((filter & RayFilterFlags.physical) != 0)
1065 {
1066 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Dynamic].group;
1067 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Dynamic].mask;
1068 }
1069 // if ((filter & RayFilterFlags.phantom) != 0)
1070 // {
1071 // collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].group;
1072 // collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].mask;
1073 // }
1074 if ((filter & RayFilterFlags.volumedtc) != 0)
1075 {
1076 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].group;
1077 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].mask;
1078 }
1079 DetailLog("{0},RaycastWorld,pos={1},dir={2},len={3},count={4},filter={5},filter={6},mask={7}",
1080 DetailLogZero, position, direction, length, count, filter, collisionFilter, collisionMask);
1081 // NOTE: locking ensures the physics engine is not executing.
1082 // The caller might have to wait for the physics engine to finish.
1083 lock (PhysicsEngineLock)
1084 {
1085 Vector3 posFrom = position;
1086 Vector3 posTo = Vector3.Normalize(direction) * length + position;
1087 DetailLog("{0},RaycastWorld,RayTest2,from={1},to={2}",
1088 DetailLogZero, posFrom, posTo);
1089 RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, collisionFilter, collisionMask);
1090 if (hitInfo.hasHit())
1091 {
1092 ContactResult result = new ContactResult();
1093 result.Pos = hitInfo.Point;
1094 result.Normal = hitInfo.Normal;
1095 result.ConsumerID = hitInfo.ID;
1096 result.Depth = hitInfo.Fraction;
1097 ret.Add(result);
1098 DetailLog("{0},RaycastWorld,hit,pos={1},norm={2},depth={3},id={4}",
1099 DetailLogZero, result.Pos, result.Normal, result.Depth, result.ConsumerID);
1100 }
1101 }
1102 }
1103 return ret;
1104 }
1105
1106 #endregion Raycast
1107
971 1108
972 public override Dictionary<uint, float> GetTopColliders() 1109 public override Dictionary<uint, float> GetTopColliders()
973 { 1110 {
@@ -1081,32 +1218,35 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1081 // Calls to the PhysicsActors can't directly call into the physics engine 1218 // Calls to the PhysicsActors can't directly call into the physics engine
1082 // because it might be busy. We delay changes to a known time. 1219 // because it might be busy. We delay changes to a known time.
1083 // We rely on C#'s closure to save and restore the context for the delegate. 1220 // We rely on C#'s closure to save and restore the context for the delegate.
1084 public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback) 1221 // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed.
1222 // public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
1223 // {
1224 // TaintedObject(BSScene.DetailLogZero, pIdent, pCallback);
1225 // }
1226 // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed.
1227 public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
1085 { 1228 {
1086 TaintedObject(false /*inTaintTime*/, pOriginator, pIdent, pCallback); 1229 TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1087 } 1230 }
1088 public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback) 1231 public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback)
1089 { 1232 {
1090 TaintedObject(false /*inTaintTime*/, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); 1233 TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1091 }
1092 public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
1093 {
1094 TaintedObject(inTaintTime, BSScene.DetailLogZero, pIdent, pCallback);
1095 }
1096 public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
1097 {
1098 TaintedObject(inTaintTime, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1099 } 1234 }
1100 // Sometimes a potentially tainted operation can be used in and out of taint time. 1235 // Sometimes a potentially tainted operation can be used in and out of taint time.
1101 // This routine executes the command immediately if in taint-time otherwise it is queued. 1236 // This routine executes the command immediately if in taint-time otherwise it is queued.
1102 public void TaintedObject(bool inTaintTime, string pOriginator, string pIdent, TaintCallback pCallback) 1237 public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback)
1103 { 1238 {
1104 if (!m_initialized) return; 1239 if (!m_initialized) return;
1105 1240
1106 if (inTaintTime) 1241 if (Monitor.TryEnter(PhysicsEngineLock))
1242 {
1243 // If we can get exclusive access to the physics engine, just do the operation
1107 pCallback(); 1244 pCallback();
1245 Monitor.Exit(PhysicsEngineLock);
1246 }
1108 else 1247 else
1109 { 1248 {
1249 // The physics engine is busy, queue the operation
1110 lock (_taintLock) 1250 lock (_taintLock)
1111 { 1251 {
1112 _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback)); 1252 _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
@@ -1133,14 +1273,21 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1133 // When someone tries to change a property on a BSPrim or BSCharacter, the object queues 1273 // When someone tries to change a property on a BSPrim or BSCharacter, the object queues
1134 // a callback into itself to do the actual property change. That callback is called 1274 // a callback into itself to do the actual property change. That callback is called
1135 // here just before the physics engine is called to step the simulation. 1275 // here just before the physics engine is called to step the simulation.
1136 public void ProcessTaints() 1276 // Returns the number of taints processed
1277 // NOTE: Called while PhysicsEngineLock is locked
1278 public int ProcessTaints()
1137 { 1279 {
1138 ProcessRegularTaints(); 1280 int ret = 0;
1139 ProcessPostTaintTaints(); 1281 ret += ProcessRegularTaints();
1282 ret += ProcessPostTaintTaints();
1283 return ret;
1140 } 1284 }
1141 1285
1142 private void ProcessRegularTaints() 1286 // Returns the number of taints processed
1287 // NOTE: Called while PhysicsEngineLock is locked
1288 private int ProcessRegularTaints()
1143 { 1289 {
1290 int ret = 0;
1144 if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process 1291 if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process
1145 { 1292 {
1146 // swizzle a new list into the list location so we can process what's there 1293 // swizzle a new list into the list location so we can process what's there
@@ -1157,6 +1304,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1157 { 1304 {
1158 DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG 1305 DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG
1159 tcbe.callback(); 1306 tcbe.callback();
1307 ret++;
1160 } 1308 }
1161 catch (Exception e) 1309 catch (Exception e)
1162 { 1310 {
@@ -1165,6 +1313,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1165 } 1313 }
1166 oldList.Clear(); 1314 oldList.Clear();
1167 } 1315 }
1316 return ret;
1168 } 1317 }
1169 1318
1170 // Schedule an update to happen after all the regular taints are processed. 1319 // Schedule an update to happen after all the regular taints are processed.
@@ -1183,8 +1332,11 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1183 } 1332 }
1184 1333
1185 // Taints that happen after the normal taint processing but before the simulation step. 1334 // Taints that happen after the normal taint processing but before the simulation step.
1186 private void ProcessPostTaintTaints() 1335 // Returns the number of taints processed
1336 // NOTE: Called while PhysicsEngineLock is locked
1337 private int ProcessPostTaintTaints()
1187 { 1338 {
1339 int ret = 0;
1188 if (m_initialized && _postTaintOperations.Count > 0) 1340 if (m_initialized && _postTaintOperations.Count > 0)
1189 { 1341 {
1190 Dictionary<string, TaintCallbackEntry> oldList; 1342 Dictionary<string, TaintCallbackEntry> oldList;
@@ -1200,6 +1352,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1200 { 1352 {
1201 DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG 1353 DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG
1202 kvp.Value.callback(); 1354 kvp.Value.callback();
1355 ret++;
1203 } 1356 }
1204 catch (Exception e) 1357 catch (Exception e)
1205 { 1358 {
@@ -1208,20 +1361,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1208 } 1361 }
1209 oldList.Clear(); 1362 oldList.Clear();
1210 } 1363 }
1364 return ret;
1211 } 1365 }
1212
1213 // Only used for debugging. Does not change state of anything so locking is not necessary.
1214 public bool AssertInTaintTime(string whereFrom)
1215 {
1216 if (!InTaintTime)
1217 {
1218 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
1219 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
1220 // Util.PrintCallStack(DetailLog);
1221 }
1222 return InTaintTime;
1223 }
1224
1225 #endregion // Taints 1366 #endregion // Taints
1226 1367
1227 #region IPhysicsParameters 1368 #region IPhysicsParameters
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs
index b100273..86bf23f 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs
@@ -30,7 +30,6 @@ using System.Text;
30using OMV = OpenMetaverse; 30using OMV = OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.PhysicsModules.SharedBase; 32using OpenSim.Region.PhysicsModules.SharedBase;
33using OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet;
34 33
35namespace OpenSim.Region.PhysicsModule.BulletS 34namespace OpenSim.Region.PhysicsModule.BulletS
36{ 35{
@@ -76,8 +75,6 @@ public sealed class BSShapeCollection : IDisposable
76 // Called at taint-time. 75 // Called at taint-time.
77 public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback) 76 public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback)
78 { 77 {
79 m_physicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape");
80
81 bool ret = false; 78 bool ret = false;
82 79
83 // This lock could probably be pushed down lower but building shouldn't take long 80 // This lock could probably be pushed down lower but building shouldn't take long
@@ -230,6 +227,8 @@ public sealed class BSShapeCollection : IDisposable
230 ret = CreateGeomMeshOrHull(prim, shapeCallback); 227 ret = CreateGeomMeshOrHull(prim, shapeCallback);
231 } 228 }
232 229
230 m_physicsScene.PE.ResetBroadphasePool(m_physicsScene.World); // DEBUG DEBUG
231
233 return ret; 232 return ret;
234 } 233 }
235 234
@@ -345,8 +344,6 @@ public sealed class BSShapeCollection : IDisposable
345 if (!body.HasPhysicalBody) 344 if (!body.HasPhysicalBody)
346 return; 345 return;
347 346
348 m_physicsScene.AssertInTaintTime("BSShapeCollection.DereferenceBody");
349
350 lock (m_collectionActivityLock) 347 lock (m_collectionActivityLock)
351 { 348 {
352 if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.ID, body); 349 if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.ID, body);
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs b/OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs
index 086a412..e791b27 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs
@@ -31,8 +31,8 @@ using System.Text;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.PhysicsModules.SharedBase; 33using OpenSim.Region.PhysicsModules.SharedBase;
34using OpenSim.Region.PhysicsModules.Meshing; 34using OpenSim.Region.PhysicsModule.Meshing;
35using OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet; 35using OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet;
36 36
37using OMV = OpenMetaverse; 37using OMV = OpenMetaverse;
38 38
@@ -555,7 +555,9 @@ public class BSShapeMesh : BSShape
555 { 555 {
556 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, 556 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
557 false, // say it is not physical so a bounding box is not built 557 false, // say it is not physical so a bounding box is not built
558 false // do not cache the mesh and do not use previously built versions 558 false, // do not cache the mesh and do not use previously built versions
559 false,
560 false
559 ); 561 );
560 } 562 }
561 563
@@ -712,7 +714,7 @@ public class BSShapeHull : BSShape
712 lock (physicsScene.mesher) 714 lock (physicsScene.mesher)
713 { 715 {
714 // Pass true for physicalness as this prevents the creation of bounding box which is not needed 716 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
715 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); 717 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
716 718
717 // If we should use the asset's hull info, fetch it out of the locked mesher 719 // If we should use the asset's hull info, fetch it out of the locked mesher
718 if (meshData != null && BSParam.ShouldUseAssetHulls) 720 if (meshData != null && BSParam.ShouldUseAssetHulls)
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
index 42fc11b..f72ad28 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
@@ -141,14 +141,30 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
141 } 141 }
142 142
143 // The passed position is relative to the base of the region. 143 // The passed position is relative to the base of the region.
144 // There are many assumptions herein that the heightmap increment is 1.
144 public override float GetTerrainHeightAtXYZ(Vector3 pos) 145 public override float GetTerrainHeightAtXYZ(Vector3 pos)
145 { 146 {
146 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; 147 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
147 148
148 int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; 149 try {
149 try 150 int baseX = (int)pos.X;
150 { 151 int baseY = (int)pos.Y;
151 ret = m_mapInfo.heightMap[mapIndex]; 152 int maxX = (int)m_mapInfo.sizeX;
153 int maxY = (int)m_mapInfo.sizeY;
154 float diffX = pos.X - (float)baseX;
155 float diffY = pos.Y - (float)baseY;
156
157 float mapHeight1 = m_mapInfo.heightMap[baseY * maxY + baseX];
158 float mapHeight2 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + baseX];
159 float mapHeight3 = m_mapInfo.heightMap[baseY * maxY + Math.Min(baseX + 1, maxX - 1)];
160 float mapHeight4 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + Math.Min(baseX + 1, maxX - 1)];
161
162 float Xrise = (mapHeight4 - mapHeight3) * diffX;
163 float Yrise = (mapHeight2 - mapHeight1) * diffY;
164
165 ret = mapHeight1 + ((Xrise + Yrise) / 2f);
166 // m_physicsScene.DetailLog("{0},BSTerrainHeightMap,GetTerrainHeightAtXYZ,pos={1},{2}/{3}/{4}/{5},ret={6}",
167 // BSScene.DetailLogZero, pos, mapHeight1, mapHeight2, mapHeight3, mapHeight4, ret);
152 } 168 }
153 catch 169 catch
154 { 170 {
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs
index d11baa6..d11baa6 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs
index cd59b65..cd59b65 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs b/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs
index 3329395..308769b 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs
@@ -100,6 +100,7 @@ public class BulletBody
100 } 100 }
101} 101}
102 102
103// Handle to btCollisionObject - a shape that can be added to a btRidgidBody
103public class BulletShape 104public class BulletShape
104{ 105{
105 public BulletShape() 106 public BulletShape()
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt b/OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt
index 0453376..0453376 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt
+++ b/OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt
diff --git a/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs b/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
index 2ba3c5a..ab5d4849 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
136 136
137 return; 137 return;
138 } 138 }
139 139
140 // Register as LSL functions all the [ScriptInvocation] marked methods. 140 // Register as LSL functions all the [ScriptInvocation] marked methods.
141 Comms.RegisterScriptInvocations(this); 141 Comms.RegisterScriptInvocations(this);
142 Comms.RegisterConstants(this); 142 Comms.RegisterConstants(this);
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs
index 698be39..91ce468 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs
@@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices; 3using System.Runtime.InteropServices;
4using Mono.Addins; 4using Mono.Addins;
5 5
6// General Information about an assembly is controlled through the following 6// General Information about an assembly is controlled through the following
7// set of attributes. Change these attribute values to modify the information 7// set of attributes. Change these attribute values to modify the information
8// associated with an assembly. 8// associated with an assembly.
9[assembly: AssemblyTitle("OpenSim.Region.Physics.BulletSPlugin")] 9[assembly: AssemblyTitle("OpenSim.Region.Physics.BulletSPlugin")]
@@ -15,8 +15,8 @@ using Mono.Addins;
15[assembly: AssemblyTrademark("")] 15[assembly: AssemblyTrademark("")]
16[assembly: AssemblyCulture("")] 16[assembly: AssemblyCulture("")]
17 17
18// Setting ComVisible to false makes the types in this assembly not visible 18// Setting ComVisible to false makes the types in this assembly not visible
19// to COM components. If you need to access a type in this assembly from 19// to COM components. If you need to access a type in this assembly from
20// COM, set the ComVisible attribute to true on that type. 20// COM, set the ComVisible attribute to true on that type.
21[assembly: ComVisible(false)] 21[assembly: ComVisible(false)]
22 22
@@ -26,11 +26,11 @@ using Mono.Addins;
26// Version information for an assembly consists of the following four values: 26// Version information for an assembly consists of the following four values:
27// 27//
28// Major Version 28// Major Version
29// Minor Version 29// Minor Version
30// Build Number 30// Build Number
31// Revision 31// Revision
32// 32//
33[assembly: AssemblyVersion("0.8.3.*")] 33[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
34 34
35[assembly: Addin("OpenSim.Region.PhysicsModule.BulletS", OpenSim.VersionInfo.VersionNumber)] 35[assembly: Addin("OpenSim.Region.PhysicsModule.BulletS", OpenSim.VersionInfo.VersionNumber)]
36[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] 36[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs
index 35eba29..35eba29 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs
index 0be1f4c..14d0bdc 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs
@@ -1,56 +1,56 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq; 30using System.Linq;
31using System.Text; 31using System.Text;
32 32
33using NUnit.Framework; 33using NUnit.Framework;
34using log4net; 34using log4net;
35 35
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37 37
38namespace OpenSim.Region.PhysicsModule.BulletS.Tests 38namespace OpenSim.Region.PhysicsModule.BulletS.Tests
39{ 39{
40[TestFixture] 40[TestFixture]
41public class BulletSimTests : OpenSimTestCase 41public class BulletSimTests : OpenSimTestCase
42{ 42{
43 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 43 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
44 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 44 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
45 45
46 [TestFixtureSetUp] 46 [TestFixtureSetUp]
47 public void Init() 47 public void Init()
48 { 48 {
49 } 49 }
50 50
51 [TestFixtureTearDown] 51 [TestFixtureTearDown]
52 public void TearDown() 52 public void TearDown()
53 { 53 {
54 } 54 }
55} 55}
56} 56}
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs
index 4eeea4d..3e8c1cd 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs
@@ -34,7 +34,7 @@ using Nini.Config;
34 34
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.PhysicsModules.SharedBase; 36using OpenSim.Region.PhysicsModules.SharedBase;
37using OpenSim.Region.PhysicsModules.Meshing; 37using OpenSim.Region.PhysicsModule.Meshing;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39 39
40using OpenMetaverse; 40using OpenMetaverse;
@@ -80,13 +80,13 @@ public static class BulletSimTestsUtil
80 } 80 }
81 81
82 Vector3 regionExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); 82 Vector3 regionExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
83 83
84 RegionInfo info = new RegionInfo(); 84 RegionInfo info = new RegionInfo();
85 info.RegionName = "BSTestRegion"; 85 info.RegionName = "BSTestRegion";
86 info.RegionSizeX = info.RegionSizeY = info.RegionSizeZ = Constants.RegionSize; 86 info.RegionSizeX = info.RegionSizeY = info.RegionSizeZ = Constants.RegionSize;
87 OpenSim.Region.Framework.Scenes.Scene scene = new OpenSim.Region.Framework.Scenes.Scene(info); 87 OpenSim.Region.Framework.Scenes.Scene scene = new OpenSim.Region.Framework.Scenes.Scene(info);
88 88
89 IMesher mesher = new OpenSim.Region.PhysicsModules.Meshing.Meshmerizer(); 89 IMesher mesher = new OpenSim.Region.PhysicsModule.Meshing.Meshmerizer();
90 INonSharedRegionModule mod = mesher as INonSharedRegionModule; 90 INonSharedRegionModule mod = mesher as INonSharedRegionModule;
91 mod.Initialise(openSimINI); 91 mod.Initialise(openSimINI);
92 mod.AddRegion(scene); 92 mod.AddRegion(scene);
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs
index c0cf19a..c2be568 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs
@@ -146,7 +146,7 @@ public class HullCreation : OpenSimTestCase
146 uint torusLocalID = 125; 146 uint torusLocalID = 125;
147 PhysicsScene.AddPrimShape("testTorus", pbs, pos, size, rot, isPhys, torusLocalID); 147 PhysicsScene.AddPrimShape("testTorus", pbs, pos, size, rot, isPhys, torusLocalID);
148 BSPrim primTypeTorus = (BSPrim)PhysicsScene.PhysObjects[torusLocalID]; 148 BSPrim primTypeTorus = (BSPrim)PhysicsScene.PhysObjects[torusLocalID];
149 149
150 // The actual prim shape creation happens at taint time 150 // The actual prim shape creation happens at taint time
151 PhysicsScene.ProcessTaints(); 151 PhysicsScene.ProcessTaints();
152 152
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs
new file mode 100755
index 0000000..bfa95c1
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs
@@ -0,0 +1,124 @@
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.PhysicsModule.BulletS;
38using OpenSim.Region.PhysicsModules.SharedBase;
39using OpenSim.Tests.Common;
40
41using OpenMetaverse;
42
43namespace OpenSim.Region.PhysicsModule.BulletS.Tests
44{
45 [TestFixture]
46 public class BulletSimRaycast : 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 BSPrim _targetSphere { get; set; }
53 Vector3 _targetSpherePosition { get; set; }
54 float _simulationTimeStep = 0.089f;
55
56 uint _targetLocalID = 123;
57
58 [TestFixtureSetUp]
59 public void Init()
60 {
61 Dictionary<string, string> engineParams = new Dictionary<string, string>();
62 engineParams.Add("UseBulletRaycast", "true");
63 _physicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
64
65 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere();
66 Vector3 pos = new Vector3(100.0f, 100.0f, 50f);
67 _targetSpherePosition = pos;
68 Vector3 size = new Vector3(10f, 10f, 10f);
69 pbs.Scale = size;
70 Quaternion rot = Quaternion.Identity;
71 bool isPhys = false;
72
73 _physicsScene.AddPrimShape("TargetSphere", pbs, pos, size, rot, isPhys, _targetLocalID);
74 _targetSphere = (BSPrim)_physicsScene.PhysObjects[_targetLocalID];
75 // The actual prim shape creation happens at taint time
76 _physicsScene.ProcessTaints();
77
78 }
79
80 [TestFixtureTearDown]
81 public void TearDown()
82 {
83 if (_physicsScene != null)
84 {
85 // The Dispose() will also free any physical objects in the scene
86 _physicsScene.Dispose();
87 _physicsScene = null;
88 }
89 }
90
91 // There is a 10x10x10 sphere at <100,100,50>
92 // Shoot rays around the sphere and verify it hits and doesn't hit
93 // TestCase parameters are <x,y,z> of start and <x,y,z> of end and expected result
94 [TestCase(100f, 50f, 50f, 100f, 150f, 50f, true, "Pass through sphere from front")]
95 [TestCase(50f, 100f, 50f, 150f, 100f, 50f, true, "Pass through sphere from side")]
96 [TestCase(50f, 50f, 50f, 150f, 150f, 50f, true, "Pass through sphere diaginally")]
97 [TestCase(100f, 100f, 100f, 100f, 100f, 20f, true, "Pass through sphere from above")]
98 [TestCase(20f, 20f, 50f, 80f, 80f, 50f, false, "Not reach sphere")]
99 [TestCase(50f, 50f, 65f, 150f, 150f, 65f, false, "Passed over sphere")]
100 public void RaycastAroundObject(float fromX, float fromY, float fromZ, float toX, float toY, float toZ, bool expected, string msg) {
101 Vector3 fromPos = new Vector3(fromX, fromY, fromZ);
102 Vector3 toPos = new Vector3(toX, toY, toZ);
103 Vector3 direction = toPos - fromPos;
104 float len = Vector3.Distance(fromPos, toPos);
105
106 List<ContactResult> results = _physicsScene.RaycastWorld(fromPos, direction, len, 1);
107
108 if (expected) {
109 // The test coordinates should generate a hit
110 Assert.True(results.Count != 0, msg + ": Did not return a hit but expected to.");
111 Assert.True(results.Count == 1, msg + ": Raycast returned not just one hit result.");
112 Assert.True(results[0].ConsumerID == _targetLocalID, msg + ": Raycast returned a collision object other than the target");
113 }
114 else
115 {
116 // The test coordinates should not generate a hit
117 if (results.Count > 0)
118 {
119 Assert.False(results.Count > 0, msg + ": Returned a hit at " + results[0].Pos.ToString());
120 }
121 }
122 }
123 }
124} \ No newline at end of file
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/CTri.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/CTri.cs
index 7ad689e..bd1f75e 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/CTri.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/CTri.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -28,7 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30 30
31namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 31namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
32{ 32{
33 public class Wpoint 33 public class Wpoint
34 { 34 {
@@ -246,13 +246,13 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
246 } 246 }
247 247
248 private static float DistToPt(float3 p, float4 plane) 248 private static float DistToPt(float3 p, float4 plane)
249 { 249 {
250 float x = p.x; 250 float x = p.x;
251 float y = p.y; 251 float y = p.y;
252 float z = p.z; 252 float z = p.z;
253 float d = x*plane.x + y*plane.y + z*plane.z + plane.w; 253 float d = x*plane.x + y*plane.y + z*plane.z + plane.w;
254 return d; 254 return d;
255 } 255 }
256 256
257 private static void intersect(float3 p1, float3 p2, ref float3 split, float4 plane) 257 private static void intersect(float3 p1, float3 p2, ref float3 split, float4 plane)
258 { 258 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Concavity.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Concavity.cs
index 4140d25..0d22d71 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Concavity.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Concavity.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -29,7 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Text; 30using System.Text;
31 31
32namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 32namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
33{ 33{
34 public static class Concavity 34 public static class Concavity
35 { 35 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexBuilder.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexBuilder.cs
index 70c3a2b..810e95d 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexBuilder.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexBuilder.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -29,7 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; 30using System.Diagnostics;
31 31
32namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 32namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
33{ 33{
34 public class DecompDesc 34 public class DecompDesc
35 { 35 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexDecomposition.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexDecomposition.cs
index 5046bce..a382f9d 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexDecomposition.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexDecomposition.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -29,7 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; 30using System.Diagnostics;
31 31
32namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 32namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
33{ 33{
34 public delegate void ConvexDecompositionCallback(ConvexResult result); 34 public delegate void ConvexDecompositionCallback(ConvexResult result);
35 35
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexResult.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexResult.cs
index 44e3e50..300fed3 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexResult.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/ConvexResult.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -28,7 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30 30
31namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 31namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
32{ 32{
33 public class ConvexResult 33 public class ConvexResult
34 { 34 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullClasses.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullClasses.cs
index 8a0164e..73fb252 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullClasses.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullClasses.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -28,7 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30 30
31namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 31namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
32{ 32{
33 public class HullResult 33 public class HullResult
34 { 34 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullTriangle.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullTriangle.cs
index d3f0052..6e73fd5 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullTriangle.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullTriangle.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -29,7 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; 30using System.Diagnostics;
31 31
32namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 32namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
33{ 33{
34 public class HullTriangle : int3 34 public class HullTriangle : int3
35 { 35 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullUtils.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullUtils.cs
index 3903254..cf7161a 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullUtils.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/HullUtils.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -29,7 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; 30using System.Diagnostics;
31 31
32namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 32namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
33{ 33{
34 public static class HullUtils 34 public static class HullUtils
35 { 35 {
@@ -763,7 +763,7 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
763 } 763 }
764 else if ((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == (0)) 764 else if ((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == (0))
765 { 765 {
766 // both endpoints coplanar 766 // both endpoints coplanar
767 // must check a 3rd point to see if UNDER 767 // must check a 3rd point to see if UNDER
768 int e2 = e1 + 1; 768 int e2 = e1 + 1;
769 if (e2 >= convex.edges.Count || convex.edges[e2].p != currentplane) 769 if (e2 >= convex.edges.Count || convex.edges[e2].p != currentplane)
@@ -792,7 +792,7 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
792 } 792 }
793 else if (vertflag[edge0.v].planetest == (1) && vertflag[edge1.v].planetest == (2)) 793 else if (vertflag[edge0.v].planetest == (1) && vertflag[edge1.v].planetest == (2))
794 { 794 {
795 // first is under 2nd is over 795 // first is under 2nd is over
796 796
797 edgeflag[e0].undermap = (short)under_edge_count; 797 edgeflag[e0].undermap = (short)under_edge_count;
798 tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; 798 tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap;
@@ -815,7 +815,7 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
815 vout = vertcountunder++; 815 vout = vertcountunder++;
816 } 816 }
817 under_edge_count++; 817 under_edge_count++;
818 /// hmmm something to think about: i might be able to output this edge regarless of 818 /// hmmm something to think about: i might be able to output this edge regarless of
819 // wheter or not we know v-in yet. ok i;ll try this now: 819 // wheter or not we know v-in yet. ok i;ll try this now:
820 tmpunderedges[under_edge_count].v = (byte)vout; 820 tmpunderedges[under_edge_count].v = (byte)vout;
821 tmpunderedges[under_edge_count].p = (byte)underplanescount; 821 tmpunderedges[under_edge_count].p = (byte)underplanescount;
@@ -834,7 +834,7 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
834 } 834 }
835 else if (vertflag[edge0.v].planetest == (0) && vertflag[edge1.v].planetest == (2)) 835 else if (vertflag[edge0.v].planetest == (0) && vertflag[edge1.v].planetest == (2))
836 { 836 {
837 // first is coplanar 2nd is over 837 // first is coplanar 2nd is over
838 838
839 edgeflag[e0].undermap = -1; 839 edgeflag[e0].undermap = -1;
840 vout = vertflag[edge0.v].undermap; 840 vout = vertflag[edge0.v].undermap;
@@ -858,7 +858,7 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
858 } 858 }
859 else if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (1)) 859 else if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (1))
860 { 860 {
861 // first is over next is under 861 // first is over next is under
862 // new vertex!!! 862 // new vertex!!!
863 Debug.Assert(vin == -1); 863 Debug.Assert(vin == -1);
864 if (e0 < edge0.ea) 864 if (e0 < edge0.ea)
@@ -901,7 +901,7 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
901 } 901 }
902 else if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (0)) 902 else if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (0))
903 { 903 {
904 // first is over next is coplanar 904 // first is over next is coplanar
905 905
906 edgeflag[e0].undermap = -1; 906 edgeflag[e0].undermap = -1;
907 vin = vertflag[edge1.v].undermap; 907 vin = vertflag[edge1.v].undermap;
@@ -1074,14 +1074,27 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
1074 public static int maxdirfiltered(List<float3> p, int count, float3 dir, byte[] allow) 1074 public static int maxdirfiltered(List<float3> p, int count, float3 dir, byte[] allow)
1075 { 1075 {
1076 //Debug.Assert(count != 0); 1076 //Debug.Assert(count != 0);
1077 int m = 0; 1077 int m = -1;
1078 float currDotm = float3.dot(p[0], dir); 1078 float currDotm = 0;
1079 float currDoti; 1079 float currDoti;
1080 1080
1081 while (allow[m] == 0) 1081 for (int i = 0; i < count; i++)
1082 m++; 1082 {
1083 if (allow[i] != 0)
1084 {
1085 currDotm = float3.dot(p[i], dir);
1086 m = i;
1087 break;
1088 }
1089 }
1083 1090
1084 for (int i = 1; i < count; i++) 1091 if(m == -1)
1092 {
1093 Debug.Assert(false);
1094 return m;
1095 }
1096
1097 for (int i = m + 1; i < count; i++)
1085 { 1098 {
1086 if (allow[i] != 0) 1099 if (allow[i] != 0)
1087 { 1100 {
@@ -1093,7 +1106,8 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
1093 } 1106 }
1094 } 1107 }
1095 } 1108 }
1096 //Debug.Assert(m != -1); 1109
1110// Debug.Assert(m != -1);
1097 return m; 1111 return m;
1098 } 1112 }
1099 1113
@@ -1112,8 +1126,8 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
1112 { 1126 {
1113 int mb; 1127 int mb;
1114 { 1128 {
1115 float s = (float)Math.Sin((3.14159264f / 180.0f) * (x)); 1129 float s = (float)Math.Sin(0.01745329f * x);
1116 float c = (float)Math.Cos((3.14159264f / 180.0f) * (x)); 1130 float c = (float)Math.Cos(0.01745329f * x);
1117 mb = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow); 1131 mb = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow);
1118 } 1132 }
1119 if (ma == m && mb == m) 1133 if (ma == m && mb == m)
@@ -1126,8 +1140,8 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
1126 int mc = ma; 1140 int mc = ma;
1127 for (float xx = x - 40.0f; xx <= x; xx += 5.0f) 1141 for (float xx = x - 40.0f; xx <= x; xx += 5.0f)
1128 { 1142 {
1129 float s = (float)Math.Sin((3.14159264f / 180.0f) * (xx)); 1143 float s = (float)Math.Sin(0.01745329f * xx);
1130 float c = (float)Math.Cos((3.14159264f / 180.0f) * (xx)); 1144 float c = (float)Math.Cos(0.01745329f * xx);
1131 int md = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow); 1145 int md = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow);
1132 if (mc == m && md == m) 1146 if (mc == m && md == m)
1133 { 1147 {
@@ -1176,7 +1190,7 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
1176 Debug.Assert(!(p0 == p1 || p0 == p2 || p0 == p3 || p1 == p2 || p1 == p3 || p2 == p3)); 1190 Debug.Assert(!(p0 == p1 || p0 == p2 || p0 == p3 || p1 == p2 || p1 == p3 || p2 == p3));
1177 if (float3.dot(verts[p3] - verts[p0], float3.cross(verts[p1] - verts[p0], verts[p2] - verts[p0])) < 0) 1191 if (float3.dot(verts[p3] - verts[p0], float3.cross(verts[p1] - verts[p0], verts[p2] - verts[p0])) < 0)
1178 { 1192 {
1179 Swap(ref p2, ref p3); 1193 return new int4(p0, p1, p3, p2);
1180 } 1194 }
1181 return new int4(p0, p1, p2, p3); 1195 return new int4(p0, p1, p2, p3);
1182 } 1196 }
@@ -1207,12 +1221,12 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
1207 int j; 1221 int j;
1208 float3 bmin = new float3(verts[0]); 1222 float3 bmin = new float3(verts[0]);
1209 float3 bmax = new float3(verts[0]); 1223 float3 bmax = new float3(verts[0]);
1210 List<int> isextreme = new List<int>(verts.Count); 1224 byte[] isextreme = new byte[verts.Count];
1211 byte[] allow = new byte[verts.Count]; 1225 byte[] allow = new byte[verts.Count];
1212 for (j = 0; j < verts.Count; j++) 1226 for (j = 0; j < verts.Count; j++)
1213 { 1227 {
1214 allow[j] = 1; 1228 allow[j] = 1;
1215 isextreme.Add(0); 1229 isextreme[j] = 0;
1216 bmin = float3.VectorMin(bmin, verts[j]); 1230 bmin = float3.VectorMin(bmin, verts[j]);
1217 bmax = float3.VectorMax(bmax, verts[j]); 1231 bmax = float3.VectorMax(bmax, verts[j]);
1218 } 1232 }
@@ -1526,6 +1540,19 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
1526 } 1540 }
1527 } 1541 }
1528 1542
1543 public static bool ComputeHull(List<float3> vertices, out List<int> indices)
1544 {
1545 List<HullTriangle> tris = new List<HullTriangle>();
1546
1547 bool ret = calchull(vertices, out indices, 0, tris);
1548 if (ret == false)
1549 {
1550 indices = new List<int>();
1551 return false;
1552 }
1553 return true;
1554 }
1555
1529 private static bool CleanupVertices(List<float3> svertices, out List<float3> vertices, float normalepsilon, out float3 scale) 1556 private static bool CleanupVertices(List<float3> svertices, out List<float3> vertices, float normalepsilon, out float3 scale)
1530 { 1557 {
1531 const float EPSILON = 0.000001f; 1558 const float EPSILON = 0.000001f;
@@ -1609,7 +1636,7 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
1609 addPoint(ref vcount, vertices, x2, y2, z2); 1636 addPoint(ref vcount, vertices, x2, y2, z2);
1610 addPoint(ref vcount, vertices, x1, y2, z2); 1637 addPoint(ref vcount, vertices, x1, y2, z2);
1611 1638
1612 return true; // return cube 1639 return true; // return cube
1613 } 1640 }
1614 else 1641 else
1615 { 1642 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Plane.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Plane.cs
index da9ae0c..0f10e5f 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Plane.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Plane.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,7 +27,7 @@
27 27
28using System; 28using System;
29 29
30namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 30namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
31{ 31{
32 public class Plane 32 public class Plane
33 { 33 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/PlaneTri.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/PlaneTri.cs
index 42f7a22..5915c29 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/PlaneTri.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/PlaneTri.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -29,7 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; 30using System.Diagnostics;
31 31
32namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 32namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
33{ 33{
34 public enum PlaneTriResult : int 34 public enum PlaneTriResult : int
35 { 35 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs
index b9cd6f5..9b418d6 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs
@@ -2,7 +2,7 @@
2using System.Runtime.CompilerServices; 2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices; 3using System.Runtime.InteropServices;
4 4
5// General Information about an assembly is controlled through the following 5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information 6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly. 7// associated with an assembly.
8[assembly: AssemblyTitle("ConvexDecompositionDotNet")] 8[assembly: AssemblyTitle("ConvexDecompositionDotNet")]
@@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
14[assembly: AssemblyTrademark("")] 14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")] 15[assembly: AssemblyCulture("")]
16 16
17// Setting ComVisible to false makes the types in this assembly not visible 17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from 18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type. 19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)] 20[assembly: ComVisible(false)]
21 21
@@ -25,12 +25,12 @@ using System.Runtime.InteropServices;
25// Version information for an assembly consists of the following four values: 25// Version information for an assembly consists of the following four values:
26// 26//
27// Major Version 27// Major Version
28// Minor Version 28// Minor Version
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32// You can specify all the values or you can default the Build and Revision Numbers 32// You can specify all the values or you can default the Build and Revision Numbers
33// by using the '*' as shown below: 33// by using the '*' as shown below:
34// [assembly: AssemblyVersion("1.0.*")] 34// [assembly: AssemblyVersion("1.0.*")]
35[assembly: AssemblyVersion("0.8.3.*")] 35[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
36 36
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Quaternion.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Quaternion.cs
index 045f620..571677d 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Quaternion.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/Quaternion.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,7 +27,7 @@
27 27
28using System; 28using System;
29 29
30namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 30namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
31{ 31{
32 public class Quaternion : float4 32 public class Quaternion : float4
33 { 33 {
@@ -126,9 +126,9 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
126 } 126 }
127 127
128 public static Quaternion operator *(Quaternion a, float b) 128 public static Quaternion operator *(Quaternion a, float b)
129 { 129 {
130 return new Quaternion(a.x *b, a.y *b, a.z *b, a.w *b); 130 return new Quaternion(a.x *b, a.y *b, a.z *b, a.w *b);
131 } 131 }
132 132
133 public static Quaternion normalize(Quaternion a) 133 public static Quaternion normalize(Quaternion a)
134 { 134 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/SplitPlane.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/SplitPlane.cs
index 9f56bc5..d8c10c7 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/SplitPlane.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/SplitPlane.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -28,7 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30 30
31namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 31namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
32{ 32{
33 public class Rect3d 33 public class Rect3d
34 { 34 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/VertexLookup.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/VertexLookup.cs
index bfe11e5..915bec6 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/VertexLookup.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/VertexLookup.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -28,7 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30 30
31namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 31namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
32{ 32{
33 public class VertexPool 33 public class VertexPool
34 { 34 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float2.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float2.cs
index e7358c1..c2c8940 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float2.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float2.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,7 +27,7 @@
27 27
28using System; 28using System;
29 29
30namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 30namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
31{ 31{
32 public class float2 32 public class float2
33 { 33 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3.cs
index fde9b32..1ea003b 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,7 +27,7 @@
27 27
28using System; 28using System;
29 29
30namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 30namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
31{ 31{
32 public class float3 : IEquatable<float3> 32 public class float3 : IEquatable<float3>
33 { 33 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3x3.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3x3.cs
index c420fde..4b6cd5d 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3x3.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float3x3.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -29,7 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; 30using System.Diagnostics;
31 31
32namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 32namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
33{ 33{
34 public class float3x3 34 public class float3x3
35 { 35 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4.cs
index b2b6fd3..1f2ab02 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,7 +27,7 @@
27 27
28using System; 28using System;
29 29
30namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 30namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
31{ 31{
32 public class float4 32 public class float4
33 { 33 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4x4.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4x4.cs
index 087eba7..85a8cf1 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4x4.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/float4x4.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -30,7 +30,7 @@ using System.Collections.Generic;
30using System.Linq; 30using System.Linq;
31using System.Text; 31using System.Text;
32 32
33namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 33namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
34{ 34{
35 public class float4x4 35 public class float4x4
36 { 36 {
@@ -127,88 +127,88 @@ namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet
127 } 127 }
128 128
129 public static float4x4 Inverse(float4x4 m) 129 public static float4x4 Inverse(float4x4 m)
130 { 130 {
131 float4x4 d = new float4x4(); 131 float4x4 d = new float4x4();
132 //float dst = d.x.x; 132 //float dst = d.x.x;
133 float[] tmp = new float[12]; // temp array for pairs 133 float[] tmp = new float[12]; // temp array for pairs
134 float[] src = new float[16]; // array of transpose source matrix 134 float[] src = new float[16]; // array of transpose source matrix
135 float det; // determinant 135 float det; // determinant
136 // transpose matrix 136 // transpose matrix
137 for (int i = 0; i < 4; i++) 137 for (int i = 0; i < 4; i++)
138 { 138 {
139 src[i] = m[i].x; 139 src[i] = m[i].x;
140 src[i + 4] = m[i].y; 140 src[i + 4] = m[i].y;
141 src[i + 8] = m[i].z; 141 src[i + 8] = m[i].z;
142 src[i + 12] = m[i].w; 142 src[i + 12] = m[i].w;
143 } 143 }
144 // calculate pairs for first 8 elements (cofactors) 144 // calculate pairs for first 8 elements (cofactors)
145 tmp[0] = src[10] * src[15]; 145 tmp[0] = src[10] * src[15];
146 tmp[1] = src[11] * src[14]; 146 tmp[1] = src[11] * src[14];
147 tmp[2] = src[9] * src[15]; 147 tmp[2] = src[9] * src[15];
148 tmp[3] = src[11] * src[13]; 148 tmp[3] = src[11] * src[13];
149 tmp[4] = src[9] * src[14]; 149 tmp[4] = src[9] * src[14];
150 tmp[5] = src[10] * src[13]; 150 tmp[5] = src[10] * src[13];
151 tmp[6] = src[8] * src[15]; 151 tmp[6] = src[8] * src[15];
152 tmp[7] = src[11] * src[12]; 152 tmp[7] = src[11] * src[12];
153 tmp[8] = src[8] * src[14]; 153 tmp[8] = src[8] * src[14];
154 tmp[9] = src[10] * src[12]; 154 tmp[9] = src[10] * src[12];
155 tmp[10] = src[8] * src[13]; 155 tmp[10] = src[8] * src[13];
156 tmp[11] = src[9] * src[12]; 156 tmp[11] = src[9] * src[12];
157 // calculate first 8 elements (cofactors) 157 // calculate first 8 elements (cofactors)
158 d.x.x = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]; 158 d.x.x = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7];
159 d.x.x -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]; 159 d.x.x -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7];
160 d.x.y = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]; 160 d.x.y = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7];
161 d.x.y -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]; 161 d.x.y -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7];
162 d.x.z = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]; 162 d.x.z = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7];
163 d.x.z -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]; 163 d.x.z -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7];
164 d.x.w = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]; 164 d.x.w = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6];
165 d.x.w -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]; 165 d.x.w -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6];
166 d.y.x = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]; 166 d.y.x = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3];
167 d.y.x -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]; 167 d.y.x -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3];
168 d.y.y = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]; 168 d.y.y = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3];
169 d.y.y -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]; 169 d.y.y -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3];
170 d.y.z = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]; 170 d.y.z = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3];
171 d.y.z -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]; 171 d.y.z -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3];
172 d.y.w = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]; 172 d.y.w = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2];
173 d.y.w -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]; 173 d.y.w -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2];
174 // calculate pairs for second 8 elements (cofactors) 174 // calculate pairs for second 8 elements (cofactors)
175 tmp[0] = src[2]*src[7]; 175 tmp[0] = src[2]*src[7];
176 tmp[1] = src[3]*src[6]; 176 tmp[1] = src[3]*src[6];
177 tmp[2] = src[1]*src[7]; 177 tmp[2] = src[1]*src[7];
178 tmp[3] = src[3]*src[5]; 178 tmp[3] = src[3]*src[5];
179 tmp[4] = src[1]*src[6]; 179 tmp[4] = src[1]*src[6];
180 tmp[5] = src[2]*src[5]; 180 tmp[5] = src[2]*src[5];
181 tmp[6] = src[0]*src[7]; 181 tmp[6] = src[0]*src[7];
182 tmp[7] = src[3]*src[4]; 182 tmp[7] = src[3]*src[4];
183 tmp[8] = src[0]*src[6]; 183 tmp[8] = src[0]*src[6];
184 tmp[9] = src[2]*src[4]; 184 tmp[9] = src[2]*src[4];
185 tmp[10] = src[0]*src[5]; 185 tmp[10] = src[0]*src[5];
186 tmp[11] = src[1]*src[4]; 186 tmp[11] = src[1]*src[4];
187 // calculate second 8 elements (cofactors) 187 // calculate second 8 elements (cofactors)
188 d.z.x = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15]; 188 d.z.x = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15];
189 d.z.x -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15]; 189 d.z.x -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15];
190 d.z.y = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15]; 190 d.z.y = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15];
191 d.z.y -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15]; 191 d.z.y -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15];
192 d.z.z = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15]; 192 d.z.z = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15];
193 d.z.z -= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15]; 193 d.z.z -= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15];
194 d.z.w = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14]; 194 d.z.w = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14];
195 d.z.w-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14]; 195 d.z.w-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14];
196 d.w.x = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9]; 196 d.w.x = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9];
197 d.w.x-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10]; 197 d.w.x-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10];
198 d.w.y = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10]; 198 d.w.y = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10];
199 d.w.y-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8]; 199 d.w.y-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8];
200 d.w.z = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8]; 200 d.w.z = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8];
201 d.w.z-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9]; 201 d.w.z-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9];
202 d.w.w = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9]; 202 d.w.w = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9];
203 d.w.w-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8]; 203 d.w.w-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8];
204 // calculate determinant 204 // calculate determinant
205 det = src[0] * d.x.x + src[1] * d.x.y + src[2] * d.x.z + src[3] * d.x.w; 205 det = src[0] * d.x.x + src[1] * d.x.y + src[2] * d.x.z + src[3] * d.x.w;
206 // calculate matrix inverse 206 // calculate matrix inverse
207 det = 1/det; 207 det = 1/det;
208 for (int j = 0; j < 4; j++) 208 for (int j = 0; j < 4; j++)
209 d[j] *= det; 209 d[j] *= det;
210 return d; 210 return d;
211 } 211 }
212 212
213 public static float4x4 MatrixRigidInverse(float4x4 m) 213 public static float4x4 MatrixRigidInverse(float4x4 m)
214 { 214 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int3.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int3.cs
index 90624eb..e7bb6e7 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int3.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int3.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,7 +27,7 @@
27 27
28using System; 28using System;
29 29
30namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 30namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
31{ 31{
32 public class int3 32 public class int3
33 { 33 {
diff --git a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int4.cs b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int4.cs
index e9320c0..9950be2 100644
--- a/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int4.cs
+++ b/OpenSim/Region/PhysicsModules/ConvexDecompositionDotNet/int4.cs
@@ -1,21 +1,21 @@
1/* The MIT License 1/* The MIT License
2 * 2 *
3 * Copyright (c) 2010 Intel Corporation. 3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Based on the convexdecomposition library from 6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax. 7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights 11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is 13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions: 14 * furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice shall be included in 16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software. 17 * all copies or substantial portions of the Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,7 +27,7 @@
27 27
28using System; 28using System;
29 29
30namespace OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet 30namespace OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet
31{ 31{
32 public class int4 32 public class int4
33 { 33 {
diff --git a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/HelperTypes.cs b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/HelperTypes.cs
index 34a925d..a0e3b7f 100644
--- a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/HelperTypes.cs
+++ b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/HelperTypes.cs
@@ -31,7 +31,7 @@ using System.Diagnostics;
31using System.Globalization; 31using System.Globalization;
32using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Region.PhysicsModules.SharedBase; 33using OpenSim.Region.PhysicsModules.SharedBase;
34using OpenSim.Region.PhysicsModules.Meshing; 34using OpenSim.Region.PhysicsModule.Meshing;
35 35
36public class Vertex : IComparable<Vertex> 36public class Vertex : IComparable<Vertex>
37{ 37{
diff --git a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Mesh.cs b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Mesh.cs
index bf397ee..42ba37e 100644
--- a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Mesh.cs
+++ b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Mesh.cs
@@ -33,7 +33,7 @@ using OpenSim.Region.PhysicsModules.SharedBase;
33using PrimMesher; 33using PrimMesher;
34using OpenMetaverse; 34using OpenMetaverse;
35 35
36namespace OpenSim.Region.PhysicsModules.Meshing 36namespace OpenSim.Region.PhysicsModule.Meshing
37{ 37{
38 public class Mesh : IMesh 38 public class Mesh : IMesh
39 { 39 {
@@ -46,11 +46,36 @@ namespace OpenSim.Region.PhysicsModules.Meshing
46 IntPtr m_indicesPtr = IntPtr.Zero; 46 IntPtr m_indicesPtr = IntPtr.Zero;
47 int m_indexCount = 0; 47 int m_indexCount = 0;
48 public float[] m_normals; 48 public float[] m_normals;
49 Vector3 _centroid;
50 int _centroidDiv;
51
52 private class vertexcomp : IEqualityComparer<Vertex>
53 {
54 public bool Equals(Vertex v1, Vertex v2)
55 {
56 if (v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z)
57 return true;
58 else
59 return false;
60 }
61 public int GetHashCode(Vertex v)
62 {
63 int a = v.X.GetHashCode();
64 int b = v.Y.GetHashCode();
65 int c = v.Z.GetHashCode();
66 return (a << 16) ^ (b << 8) ^ c;
67 }
68
69 }
49 70
50 public Mesh() 71 public Mesh()
51 { 72 {
52 m_vertices = new Dictionary<Vertex, int>(); 73 vertexcomp vcomp = new vertexcomp();
74
75 m_vertices = new Dictionary<Vertex, int>(vcomp);
53 m_triangles = new List<Triangle>(); 76 m_triangles = new List<Triangle>();
77 _centroid = Vector3.Zero;
78 _centroidDiv = 0;
54 } 79 }
55 80
56 public Mesh Clone() 81 public Mesh Clone()
@@ -61,7 +86,8 @@ namespace OpenSim.Region.PhysicsModules.Meshing
61 { 86 {
62 result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); 87 result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
63 } 88 }
64 89 result._centroid = _centroid;
90 result._centroidDiv = _centroidDiv;
65 return result; 91 return result;
66 } 92 }
67 93
@@ -71,15 +97,63 @@ namespace OpenSim.Region.PhysicsModules.Meshing
71 throw new NotSupportedException("Attempt to Add to a pinned Mesh"); 97 throw new NotSupportedException("Attempt to Add to a pinned Mesh");
72 // If a vertex of the triangle is not yet in the vertices list, 98 // If a vertex of the triangle is not yet in the vertices list,
73 // add it and set its index to the current index count 99 // add it and set its index to the current index count
100 // vertex == seems broken
101 // skip colapsed triangles
102 if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z)
103 || (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z)
104 || (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z == triangle.v3.Z)
105 )
106 {
107 return;
108 }
109
110 if (m_vertices.Count == 0)
111 {
112 _centroidDiv = 0;
113 _centroid = Vector3.Zero;
114 }
115
74 if (!m_vertices.ContainsKey(triangle.v1)) 116 if (!m_vertices.ContainsKey(triangle.v1))
117 {
75 m_vertices[triangle.v1] = m_vertices.Count; 118 m_vertices[triangle.v1] = m_vertices.Count;
119 _centroid.X += triangle.v1.X;
120 _centroid.Y += triangle.v1.Y;
121 _centroid.Z += triangle.v1.Z;
122 _centroidDiv++;
123 }
76 if (!m_vertices.ContainsKey(triangle.v2)) 124 if (!m_vertices.ContainsKey(triangle.v2))
125 {
77 m_vertices[triangle.v2] = m_vertices.Count; 126 m_vertices[triangle.v2] = m_vertices.Count;
127 _centroid.X += triangle.v2.X;
128 _centroid.Y += triangle.v2.Y;
129 _centroid.Z += triangle.v2.Z;
130 _centroidDiv++;
131 }
78 if (!m_vertices.ContainsKey(triangle.v3)) 132 if (!m_vertices.ContainsKey(triangle.v3))
133 {
79 m_vertices[triangle.v3] = m_vertices.Count; 134 m_vertices[triangle.v3] = m_vertices.Count;
135 _centroid.X += triangle.v3.X;
136 _centroid.Y += triangle.v3.Y;
137 _centroid.Z += triangle.v3.Z;
138 _centroidDiv++;
139 }
80 m_triangles.Add(triangle); 140 m_triangles.Add(triangle);
81 } 141 }
82 142
143 public Vector3 GetCentroid()
144 {
145 if (_centroidDiv > 0)
146 return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv);
147 else
148 return Vector3.Zero;
149 }
150
151 // not functional
152 public Vector3 GetOBB()
153 {
154 return new Vector3(0.5f, 0.5f, 0.5f);
155 }
156
83 public void CalcNormals() 157 public void CalcNormals()
84 { 158 {
85 int iTriangles = m_triangles.Count; 159 int iTriangles = m_triangles.Count;
@@ -185,6 +259,7 @@ namespace OpenSim.Region.PhysicsModules.Meshing
185 public void getVertexListAsPtrToFloatArray(out IntPtr vertices, out int vertexStride, out int vertexCount) 259 public void getVertexListAsPtrToFloatArray(out IntPtr vertices, out int vertexStride, out int vertexCount)
186 { 260 {
187 // A vertex is 3 floats 261 // A vertex is 3 floats
262
188 vertexStride = 3 * sizeof(float); 263 vertexStride = 3 * sizeof(float);
189 264
190 // If there isn't an unmanaged array allocated yet, do it now 265 // If there isn't an unmanaged array allocated yet, do it now
@@ -224,7 +299,7 @@ namespace OpenSim.Region.PhysicsModules.Meshing
224 { 299 {
225 if (m_pinnedIndex.IsAllocated) 300 if (m_pinnedIndex.IsAllocated)
226 return (int[])(m_pinnedIndex.Target); 301 return (int[])(m_pinnedIndex.Target);
227 302
228 int[] result = getIndexListAsInt(); 303 int[] result = getIndexListAsInt();
229 m_pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned); 304 m_pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
230 // Inform the garbage collector of this unmanaged allocation so it can schedule 305 // Inform the garbage collector of this unmanaged allocation so it can schedule
@@ -282,7 +357,7 @@ namespace OpenSim.Region.PhysicsModules.Meshing
282 { 357 {
283 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) 358 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
284 throw new NotSupportedException("Attempt to Append to a pinned Mesh"); 359 throw new NotSupportedException("Attempt to Append to a pinned Mesh");
285 360
286 if (!(newMesh is Mesh)) 361 if (!(newMesh is Mesh))
287 return; 362 return;
288 363
@@ -295,7 +370,7 @@ namespace OpenSim.Region.PhysicsModules.Meshing
295 { 370 {
296 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) 371 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
297 throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh"); 372 throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh");
298 373
299 foreach (Vertex v in m_vertices.Keys) 374 foreach (Vertex v in m_vertices.Keys)
300 { 375 {
301 if (v == null) 376 if (v == null)
diff --git a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs
index 3a944d1..0d4b6b9 100644
--- a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs
+++ b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs
@@ -44,7 +44,7 @@ using log4net;
44using Nini.Config; 44using Nini.Config;
45using Mono.Addins; 45using Mono.Addins;
46 46
47namespace OpenSim.Region.PhysicsModules.Meshing 47namespace OpenSim.Region.PhysicsModule.Meshing
48{ 48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "Meshmerizer")] 49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "Meshmerizer")]
50 public class Meshmerizer : IMesher, INonSharedRegionModule 50 public class Meshmerizer : IMesher, INonSharedRegionModule
@@ -66,7 +66,7 @@ namespace OpenSim.Region.PhysicsModules.Meshing
66 66
67 private bool cacheSculptMaps = true; 67 private bool cacheSculptMaps = true;
68 private string decodedSculptMapPath = null; 68 private string decodedSculptMapPath = null;
69 private bool useMeshiesPhysicsMesh = false; 69 private bool useMeshiesPhysicsMesh = true;
70 70
71 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 71 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
72 72
@@ -99,7 +99,7 @@ namespace OpenSim.Region.PhysicsModules.Meshing
99 99
100 IConfig mesh_config = source.Configs["Mesh"]; 100 IConfig mesh_config = source.Configs["Mesh"];
101 101
102 decodedSculptMapPath = "../caches/" + config.GetString("DecodedSculptMapPath", "j2kDecodeCache"); 102 decodedSculptMapPath = config.GetString("DecodedSculptMapPath", "j2kDecodeCache");
103 cacheSculptMaps = config.GetBoolean("CacheSculptMaps", cacheSculptMaps); 103 cacheSculptMaps = config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
104 if (mesh_config != null) 104 if (mesh_config != null)
105 { 105 {
@@ -247,13 +247,13 @@ namespace OpenSim.Region.PhysicsModules.Meshing
247 private void AddSubMesh(OSDMap subMeshData, Vector3 size, List<Coord> coords, List<Face> faces) 247 private void AddSubMesh(OSDMap subMeshData, Vector3 size, List<Coord> coords, List<Face> faces)
248 { 248 {
249 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap)); 249 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap));
250 250
251 // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level 251 // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level
252 // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no 252 // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no
253 // geometry for this submesh. 253 // geometry for this submesh.
254 if (subMeshData.ContainsKey("NoGeometry") && ((OSDBoolean)subMeshData["NoGeometry"])) 254 if (subMeshData.ContainsKey("NoGeometry") && ((OSDBoolean)subMeshData["NoGeometry"]))
255 return; 255 return;
256 256
257 OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshData["PositionDomain"])["Max"].AsVector3(); 257 OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshData["PositionDomain"])["Max"].AsVector3();
258 OpenMetaverse.Vector3 posMin = ((OSDMap)subMeshData["PositionDomain"])["Min"].AsVector3(); 258 OpenMetaverse.Vector3 posMin = ((OSDMap)subMeshData["PositionDomain"])["Min"].AsVector3();
259 ushort faceIndexOffset = (ushort)coords.Count; 259 ushort faceIndexOffset = (ushort)coords.Count;
@@ -264,15 +264,15 @@ namespace OpenSim.Region.PhysicsModules.Meshing
264 ushort uX = Utils.BytesToUInt16(posBytes, i); 264 ushort uX = Utils.BytesToUInt16(posBytes, i);
265 ushort uY = Utils.BytesToUInt16(posBytes, i + 2); 265 ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
266 ushort uZ = Utils.BytesToUInt16(posBytes, i + 4); 266 ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);
267 267
268 Coord c = new Coord( 268 Coord c = new Coord(
269 Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X, 269 Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X,
270 Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y, 270 Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y,
271 Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z); 271 Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z);
272 272
273 coords.Add(c); 273 coords.Add(c);
274 } 274 }
275 275
276 byte[] triangleBytes = subMeshData["TriangleList"].AsBinary(); 276 byte[] triangleBytes = subMeshData["TriangleList"].AsBinary();
277 for (int i = 0; i < triangleBytes.Length; i += 6) 277 for (int i = 0; i < triangleBytes.Length; i += 6)
278 { 278 {
@@ -436,9 +436,9 @@ namespace OpenSim.Region.PhysicsModules.Meshing
436 int convexSize = convexBlock["size"].AsInteger(); 436 int convexSize = convexBlock["size"].AsInteger();
437 437
438 byte[] convexBytes = new byte[convexSize]; 438 byte[] convexBytes = new byte[convexSize];
439 439
440 System.Buffer.BlockCopy(primShape.SculptData, convexOffset, convexBytes, 0, convexSize); 440 System.Buffer.BlockCopy(primShape.SculptData, convexOffset, convexBytes, 0, convexSize);
441 441
442 try 442 try
443 { 443 {
444 convexBlockOsd = DecompressOsd(convexBytes); 444 convexBlockOsd = DecompressOsd(convexBytes);
@@ -449,7 +449,7 @@ namespace OpenSim.Region.PhysicsModules.Meshing
449 //return false; 449 //return false;
450 } 450 }
451 } 451 }
452 452
453 if (convexBlockOsd != null && convexBlockOsd is OSDMap) 453 if (convexBlockOsd != null && convexBlockOsd is OSDMap)
454 { 454 {
455 convexBlock = convexBlockOsd as OSDMap; 455 convexBlock = convexBlockOsd as OSDMap;
@@ -762,7 +762,7 @@ namespace OpenSim.Region.PhysicsModules.Meshing
762 { 762 {
763 PrimMesh primMesh; 763 PrimMesh primMesh;
764 coords = new List<Coord>(); 764 coords = new List<Coord>();
765 faces = new List<Face>(); 765 faces = new List<Face>();
766 766
767 float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f; 767 float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
768 float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f; 768 float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
@@ -947,11 +947,21 @@ namespace OpenSim.Region.PhysicsModules.Meshing
947 return CreateMesh(primName, primShape, size, lod, false, true); 947 return CreateMesh(primName, primShape, size, lod, false, true);
948 } 948 }
949 949
950 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde)
951 {
952 return CreateMesh(primName, primShape, size, lod, false);
953 }
954
950 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) 955 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical)
951 { 956 {
952 return CreateMesh(primName, primShape, size, lod, isPhysical, true); 957 return CreateMesh(primName, primShape, size, lod, isPhysical, true);
953 } 958 }
954 959
960 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde)
961 {
962 return CreateMesh(primName, primShape, size, lod, isPhysical, true);
963 }
964
955 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) 965 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache)
956 { 966 {
957#if SPAM 967#if SPAM
@@ -984,7 +994,7 @@ namespace OpenSim.Region.PhysicsModules.Meshing
984 if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) 994 if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh)
985 { 995 {
986#if SPAM 996#if SPAM
987 m_log.Debug("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " + 997 m_log.Debug("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " +
988 minSizeForComplexMesh.ToString() + " - creating simple bounding box"); 998 minSizeForComplexMesh.ToString() + " - creating simple bounding box");
989#endif 999#endif
990 mesh = CreateBoundingBoxMesh(mesh); 1000 mesh = CreateBoundingBoxMesh(mesh);
@@ -1005,6 +1015,13 @@ namespace OpenSim.Region.PhysicsModules.Meshing
1005 1015
1006 return mesh; 1016 return mesh;
1007 } 1017 }
1018 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
1019 {
1020 return null;
1021 }
1008 1022
1023 public void ReleaseMesh(IMesh imesh) { }
1024 public void ExpireReleaseMeshs() { }
1025 public void ExpireFileCache() { }
1009 } 1026 }
1010} 1027}
diff --git a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/PrimMesher.cs b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/PrimMesher.cs
index 4049ee1..fd2b1ea 100644
--- a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/PrimMesher.cs
+++ b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/PrimMesher.cs
@@ -445,7 +445,7 @@ namespace PrimMesher
445 new Angle(1.0f, 1.0f, 0.0f) 445 new Angle(1.0f, 1.0f, 0.0f)
446 }; 446 };
447 447
448 private static Coord[] normals4 = 448 private static Coord[] normals4 =
449 { 449 {
450 new Coord(0.5f, 0.5f, 0.0f).Normalize(), 450 new Coord(0.5f, 0.5f, 0.0f).Normalize(),
451 new Coord(-0.5f, 0.5f, 0.0f).Normalize(), 451 new Coord(-0.5f, 0.5f, 0.0f).Normalize(),
@@ -2066,7 +2066,7 @@ namespace PrimMesher
2066 /// DEPRICATED - use Extrude(PathType.Linear) instead 2066 /// DEPRICATED - use Extrude(PathType.Linear) instead
2067 /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. 2067 /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
2068 /// </summary> 2068 /// </summary>
2069 /// 2069 ///
2070 public void ExtrudeLinear() 2070 public void ExtrudeLinear()
2071 { 2071 {
2072 this.Extrude(PathType.Linear); 2072 this.Extrude(PathType.Linear);
@@ -2077,7 +2077,7 @@ namespace PrimMesher
2077 /// DEPRICATED - use Extrude(PathType.Circular) instead 2077 /// DEPRICATED - use Extrude(PathType.Circular) instead
2078 /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring. 2078 /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring.
2079 /// </summary> 2079 /// </summary>
2080 /// 2080 ///
2081 public void ExtrudeCircular() 2081 public void ExtrudeCircular()
2082 { 2082 {
2083 this.Extrude(PathType.Circular); 2083 this.Extrude(PathType.Circular);
diff --git a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/SculptMap.cs b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/SculptMap.cs
index 740424e..01d11f4 100644
--- a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/SculptMap.cs
+++ b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/SculptMap.cs
@@ -58,28 +58,24 @@ namespace PrimMesher
58 if (bmW == 0 || bmH == 0) 58 if (bmW == 0 || bmH == 0)
59 throw new Exception("SculptMap: bitmap has no data"); 59 throw new Exception("SculptMap: bitmap has no data");
60 60
61 int numLodPixels = lod * 2 * lod * 2; // (32 * 2)^2 = 64^2 pixels for default sculpt map image 61 int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
62 62
63 bool smallMap = bmW * bmH <= numLodPixels;
63 bool needsScaling = false; 64 bool needsScaling = false;
64 65
65 bool smallMap = bmW * bmH <= lod * lod;
66
67 width = bmW; 66 width = bmW;
68 height = bmH; 67 height = bmH;
69 while (width * height > numLodPixels) 68 while (width * height > numLodPixels * 4)
70 { 69 {
71 width >>= 1; 70 width >>= 1;
72 height >>= 1; 71 height >>= 1;
73 needsScaling = true; 72 needsScaling = true;
74 } 73 }
75 74
76
77
78 try 75 try
79 { 76 {
80 if (needsScaling) 77 if (needsScaling)
81 bm = ScaleImage(bm, width, height, 78 bm = ScaleImage(bm, width, height);
82 System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
83 } 79 }
84 80
85 catch (Exception e) 81 catch (Exception e)
@@ -87,7 +83,7 @@ namespace PrimMesher
87 throw new Exception("Exception in ScaleImage(): e: " + e.ToString()); 83 throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
88 } 84 }
89 85
90 if (width * height > lod * lod) 86 if (width * height > numLodPixels)
91 { 87 {
92 width >>= 1; 88 width >>= 1;
93 height >>= 1; 89 height >>= 1;
@@ -144,15 +140,17 @@ namespace PrimMesher
144 int rowNdx, colNdx; 140 int rowNdx, colNdx;
145 int smNdx = 0; 141 int smNdx = 0;
146 142
143
147 for (rowNdx = 0; rowNdx < numRows; rowNdx++) 144 for (rowNdx = 0; rowNdx < numRows; rowNdx++)
148 { 145 {
149 List<Coord> row = new List<Coord>(numCols); 146 List<Coord> row = new List<Coord>(numCols);
150 for (colNdx = 0; colNdx < numCols; colNdx++) 147 for (colNdx = 0; colNdx < numCols; colNdx++)
151 { 148 {
149
152 if (mirror) 150 if (mirror)
153 row.Add(new Coord(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f)); 151 row.Add(new Coord(-((float)redBytes[smNdx] * pixScale - 0.5f), ((float)greenBytes[smNdx] * pixScale - 0.5f), (float)blueBytes[smNdx] * pixScale - 0.5f));
154 else 152 else
155 row.Add(new Coord(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f)); 153 row.Add(new Coord((float)redBytes[smNdx] * pixScale - 0.5f, (float)greenBytes[smNdx] * pixScale - 0.5f, (float)blueBytes[smNdx] * pixScale - 0.5f));
156 154
157 ++smNdx; 155 ++smNdx;
158 } 156 }
@@ -161,23 +159,39 @@ namespace PrimMesher
161 return rows; 159 return rows;
162 } 160 }
163 161
164 private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight, 162 private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight)
165 System.Drawing.Drawing2D.InterpolationMode interpMode)
166 { 163 {
167 Bitmap scaledImage = new Bitmap(srcImage, destWidth, destHeight);
168 scaledImage.SetResolution(96.0f, 96.0f);
169 164
170 Graphics grPhoto = Graphics.FromImage(scaledImage); 165 Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
171 grPhoto.InterpolationMode = interpMode;
172 166
173 grPhoto.DrawImage(srcImage, 167 Color c;
174 new Rectangle(0, 0, destWidth, destHeight), 168 float xscale = srcImage.Width / destWidth;
175 new Rectangle(0, 0, srcImage.Width, srcImage.Height), 169 float yscale = srcImage.Height / destHeight;
176 GraphicsUnit.Pixel);
177 170
178 grPhoto.Dispose(); 171 float sy = 0.5f;
172 for (int y = 0; y < destHeight; y++)
173 {
174 float sx = 0.5f;
175 for (int x = 0; x < destWidth; x++)
176 {
177 try
178 {
179 c = srcImage.GetPixel((int)(sx), (int)(sy));
180 scaledImage.SetPixel(x, y, Color.FromArgb(c.R, c.G, c.B));
181 }
182 catch (IndexOutOfRangeException)
183 {
184 }
185
186 sx += xscale;
187 }
188 sy += yscale;
189 }
190 srcImage.Dispose();
179 return scaledImage; 191 return scaledImage;
180 } 192 }
193
194 }
195
181 } 196 }
182}
183#endif 197#endif
diff --git a/OpenSim/Region/PhysicsModules/Meshing/Properties/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/Meshing/Properties/AssemblyInfo.cs
index b4bdb5a..5c257e6 100644
--- a/OpenSim/Region/PhysicsModules/Meshing/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/PhysicsModules/Meshing/Properties/AssemblyInfo.cs
@@ -3,10 +3,10 @@ using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices; 3using System.Runtime.InteropServices;
4using Mono.Addins; 4using Mono.Addins;
5 5
6// General Information about an assembly is controlled through the following 6// General Information about an assembly is controlled through the following
7// set of attributes. Change these attribute values to modify the information 7// set of attributes. Change these attribute values to modify the information
8// associated with an assembly. 8// associated with an assembly.
9[assembly: AssemblyTitle("OpenSim.Region.PhysicsModules.Meshing")] 9[assembly: AssemblyTitle("OpenSim.Region.PhysicsModule.Meshing")]
10[assembly: AssemblyDescription("")] 10[assembly: AssemblyDescription("")]
11[assembly: AssemblyConfiguration("")] 11[assembly: AssemblyConfiguration("")]
12[assembly: AssemblyCompany("http://opensimulator.org")] 12[assembly: AssemblyCompany("http://opensimulator.org")]
@@ -15,8 +15,8 @@ using Mono.Addins;
15[assembly: AssemblyTrademark("")] 15[assembly: AssemblyTrademark("")]
16[assembly: AssemblyCulture("")] 16[assembly: AssemblyCulture("")]
17 17
18// Setting ComVisible to false makes the types in this assembly not visible 18// Setting ComVisible to false makes the types in this assembly not visible
19// to COM components. If you need to access a type in this assembly from 19// to COM components. If you need to access a type in this assembly from
20// COM, set the ComVisible attribute to true on that type. 20// COM, set the ComVisible attribute to true on that type.
21[assembly: ComVisible(false)] 21[assembly: ComVisible(false)]
22 22
@@ -26,11 +26,11 @@ using Mono.Addins;
26// Version information for an assembly consists of the following four values: 26// Version information for an assembly consists of the following four values:
27// 27//
28// Major Version 28// Major Version
29// Minor Version 29// Minor Version
30// Build Number 30// Build Number
31// Revision 31// Revision
32// 32//
33[assembly: AssemblyVersion("0.8.3.*")] 33[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
34 34
35[assembly: Addin("OpenSim.Region.PhysicsModules.Meshing", OpenSim.VersionInfo.VersionNumber)] 35[assembly: Addin("OpenSim.Region.PhysicsModule.Meshing", OpenSim.VersionInfo.VersionNumber)]
36[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] 36[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
diff --git a/OpenSim/Region/PhysicsModules/Meshing/ZeroMesher.cs b/OpenSim/Region/PhysicsModules/Meshing/ZeroMesher.cs
index 0a3b3a4..dbf4f7e 100644
--- a/OpenSim/Region/PhysicsModules/Meshing/ZeroMesher.cs
+++ b/OpenSim/Region/PhysicsModules/Meshing/ZeroMesher.cs
@@ -47,7 +47,7 @@ using log4net;
47 * it's always availabe and thus the default in case of configuration errors 47 * it's always availabe and thus the default in case of configuration errors
48*/ 48*/
49 49
50namespace OpenSim.Region.PhysicsModules.Meshing 50namespace OpenSim.Region.PhysicsModule.Meshing
51{ 51{
52 52
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ZeroMesher")] 53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ZeroMesher")]
@@ -110,23 +110,36 @@ namespace OpenSim.Region.PhysicsModules.Meshing
110 #region IMesher 110 #region IMesher
111 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 111 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
112 { 112 {
113 return CreateMesh(primName, primShape, size, lod, false, false); 113 return CreateMesh(primName, primShape, size, lod, false);
114 } 114 }
115 115
116 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) 116 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde)
117 {
118 return CreateMesh(primName, primShape, size, lod, false);
119 }
120
121 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex,bool forOde)
117 { 122 {
118 return CreateMesh(primName, primShape, size, lod, false, false); 123 return CreateMesh(primName, primShape, size, lod, false);
119 } 124 }
120 125
121 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) 126 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical)
122 { 127 {
123 // Remove the reference to the encoded JPEG2000 data so it can be GCed 128 // Remove the reference to the encoded JPEG2000 data so it can be GCed
124 primShape.SculptData = OpenMetaverse.Utils.EmptyBytes; 129 primShape.SculptData = OpenMetaverse.Utils.EmptyBytes;
125 130
126 return null; 131 return null;
127 } 132 }
128 #endregion
129 133
134 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
135 {
136 return null;
137 }
130 138
139 public void ReleaseMesh(IMesh mesh) { }
140 public void ExpireReleaseMeshs() { }
141 public void ExpireFileCache() { }
142
143 #endregion
131 } 144 }
132} 145}
diff --git a/OpenSim/Region/PhysicsModules/Ode/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/Ode/AssemblyInfo.cs
index 7869739..3691d96 100644
--- a/OpenSim/Region/PhysicsModules/Ode/AssemblyInfo.cs
+++ b/OpenSim/Region/PhysicsModules/Ode/AssemblyInfo.cs
@@ -56,7 +56,7 @@ using Mono.Addins;
56// You can specify all values by your own or you can build default build and revision 56// You can specify all values by your own or you can build default build and revision
57// numbers with the '*' character (the default): 57// numbers with the '*' character (the default):
58 58
59[assembly : AssemblyVersion("0.8.2.*")] 59[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
60 60
61[assembly: Addin("OpenSim.Region.PhysicsModule.ODE", OpenSim.VersionInfo.VersionNumber)] 61[assembly: Addin("OpenSim.Region.PhysicsModule.ODE", OpenSim.VersionInfo.VersionNumber)]
62[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] 62[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEApi.cs b/OpenSim/Region/PhysicsModules/Ode/ODEApi.cs
new file mode 100644
index 0000000..c851b12
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/Ode/ODEApi.cs
@@ -0,0 +1,2025 @@
1/*
2 * based on:
3 * Ode.NET - .NET bindings for ODE
4 * Jason Perkins (starkos@industriousone.com)
5 * Licensed under the New BSD
6 * Part of the OpenDynamicsEngine
7Open Dynamics Engine
8Copyright (c) 2001-2007, Russell L. Smith.
9All rights reserved.
10
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions
13are met:
14
15Redistributions of source code must retain the above copyright notice,
16this list of conditions and the following disclaimer.
17
18Redistributions in binary form must reproduce the above copyright notice,
19this list of conditions and the following disclaimer in the documentation
20and/or other materials provided with the distribution.
21
22Neither the names of ODE's copyright owner nor the names of its
23contributors may be used to endorse or promote products derived from
24this software without specific prior written permission.
25
26THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
32TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 * changes by opensim team;
39 * changes by Aurora team http://www.aurora-sim.org/
40 * changes by Ubit Umarov
41 */
42
43using System;
44using System.Runtime.InteropServices;
45using System.Security;
46using OMV = OpenMetaverse;
47
48namespace OpenSim.Region.PhysicsModule.ODE
49{
50//#if dDOUBLE
51// don't see much use in double precision with time steps of 20ms and 10 iterations used on opensim
52// at least we save same memory and memory access time, FPU performance on intel usually is similar
53// using dReal = System.Double;
54//#else
55 using dReal = System.Single;
56//#endif
57
58 public static class d
59 {
60 public static dReal Infinity = dReal.MaxValue;
61 public static int NTotalBodies = 0;
62 public static int NTotalGeoms = 0;
63
64 public const uint CONTACTS_UNIMPORTANT = 0x80000000;
65
66 #region Flags and Enumerations
67
68 [Flags]
69 public enum AllocateODEDataFlags : uint
70 {
71 BasicData = 0,
72 CollisionData = 0x00000001,
73 All = ~0u
74 }
75
76 [Flags]
77 public enum IniteODEFlags : uint
78 {
79 dInitFlagManualThreadCleanup = 0x00000001
80 }
81
82 [Flags]
83 public enum ContactFlags : int
84 {
85 Mu2 = 0x001,
86 FDir1 = 0x002,
87 Bounce = 0x004,
88 SoftERP = 0x008,
89 SoftCFM = 0x010,
90 Motion1 = 0x020,
91 Motion2 = 0x040,
92 MotionN = 0x080,
93 Slip1 = 0x100,
94 Slip2 = 0x200,
95 Approx0 = 0x0000,
96 Approx1_1 = 0x1000,
97 Approx1_2 = 0x2000,
98 Approx1 = 0x3000
99 }
100
101 public enum GeomClassID : int
102 {
103 SphereClass,
104 BoxClass,
105 CapsuleClass,
106 CylinderClass,
107 PlaneClass,
108 RayClass,
109 ConvexClass,
110 GeomTransformClass,
111 TriMeshClass,
112 HeightfieldClass,
113 FirstSpaceClass,
114 SimpleSpaceClass = FirstSpaceClass,
115 HashSpaceClass,
116 QuadTreeSpaceClass,
117 LastSpaceClass = QuadTreeSpaceClass,
118 ubtTerrainClass,
119 FirstUserClass,
120 LastUserClass = FirstUserClass + MaxUserClasses - 1,
121 NumClasses,
122 MaxUserClasses = 5
123 }
124
125 public enum JointType : int
126 {
127 None,
128 Ball,
129 Hinge,
130 Slider,
131 Contact,
132 Universal,
133 Hinge2,
134 Fixed,
135 Null,
136 AMotor,
137 LMotor,
138 Plane2D
139 }
140
141 public enum JointParam : int
142 {
143 LoStop,
144 HiStop,
145 Vel,
146 FMax,
147 FudgeFactor,
148 Bounce,
149 CFM,
150 StopERP,
151 StopCFM,
152 SuspensionERP,
153 SuspensionCFM,
154 LoStop2 = 256,
155 HiStop2,
156 Vel2,
157 FMax2,
158 FudgeFactor2,
159 Bounce2,
160 CFM2,
161 StopERP2,
162 StopCFM2,
163 SuspensionERP2,
164 SuspensionCFM2,
165 LoStop3 = 512,
166 HiStop3,
167 Vel3,
168 FMax3,
169 FudgeFactor3,
170 Bounce3,
171 CFM3,
172 StopERP3,
173 StopCFM3,
174 SuspensionERP3,
175 SuspensionCFM3
176 }
177
178 public enum dSweepAndPruneAxis : int
179 {
180 XYZ = ((0)|(1<<2)|(2<<4)),
181 XZY = ((0)|(2<<2)|(1<<4)),
182 YXZ = ((1)|(0<<2)|(2<<4)),
183 YZX = ((1)|(2<<2)|(0<<4)),
184 ZXY = ((2)|(0<<2)|(1<<4)),
185 ZYX = ((2)|(1<<2)|(0<<4))
186 }
187
188 #endregion
189
190 #region Callbacks
191
192 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
193 public delegate int AABBTestFn(IntPtr o1, IntPtr o2, ref AABB aabb);
194
195 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
196 public delegate int ColliderFn(IntPtr o1, IntPtr o2, int flags, out ContactGeom contact, int skip);
197
198 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
199 public delegate void GetAABBFn(IntPtr geom, out AABB aabb);
200
201 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
202 public delegate ColliderFn GetColliderFnFn(int num);
203
204 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
205 public delegate void GeomDtorFn(IntPtr o);
206
207 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
208 public delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z);
209
210 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
211 public delegate dReal OSTerrainGetHeight(IntPtr p_user_data, int x, int z);
212
213 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
214 public delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2);
215
216 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
217 public delegate int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex);
218
219 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
220 public delegate int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount);
221
222 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
223 public delegate int TriRayCallback(IntPtr trimesh, IntPtr ray, int triangleIndex, dReal u, dReal v);
224
225 #endregion
226
227 #region Structs
228
229 [StructLayout(LayoutKind.Sequential)]
230 public struct AABB
231 {
232 public dReal MinX, MaxX;
233 public dReal MinY, MaxY;
234 public dReal MinZ, MaxZ;
235 }
236
237
238 [StructLayout(LayoutKind.Sequential)]
239 public struct Contact
240 {
241 public SurfaceParameters surface;
242 public ContactGeom geom;
243 public Vector3 fdir1;
244 public static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(Contact));
245 }
246
247
248 [StructLayout(LayoutKind.Sequential)]
249 public struct ContactGeom
250 {
251
252 public Vector3 pos;
253 public Vector3 normal;
254 public dReal depth;
255 public IntPtr g1;
256 public IntPtr g2;
257 public int side1;
258 public int side2;
259 public static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(ContactGeom));
260 }
261
262 [StructLayout(LayoutKind.Sequential)]
263 public struct GeomClass
264 {
265 public int bytes;
266 public GetColliderFnFn collider;
267 public GetAABBFn aabb;
268 public AABBTestFn aabb_test;
269 public GeomDtorFn dtor;
270 }
271
272
273 [StructLayout(LayoutKind.Sequential)]
274 public struct JointFeedback
275 {
276 public Vector3 f1;
277 public Vector3 t1;
278 public Vector3 f2;
279 public Vector3 t2;
280 }
281
282
283 [StructLayout(LayoutKind.Sequential)]
284 public struct Mass
285 {
286 public dReal mass;
287 public Vector4 c;
288 public Matrix3 I;
289 }
290
291
292 [StructLayout(LayoutKind.Sequential)]
293 public struct Matrix3
294 {
295 public Matrix3(dReal m00, dReal m10, dReal m20, dReal m01, dReal m11, dReal m21, dReal m02, dReal m12, dReal m22)
296 {
297 M00 = m00; M10 = m10; M20 = m20; _m30 = 0.0f;
298 M01 = m01; M11 = m11; M21 = m21; _m31 = 0.0f;
299 M02 = m02; M12 = m12; M22 = m22; _m32 = 0.0f;
300 }
301 public dReal M00, M10, M20;
302 private dReal _m30;
303 public dReal M01, M11, M21;
304 private dReal _m31;
305 public dReal M02, M12, M22;
306 private dReal _m32;
307 }
308
309 [StructLayout(LayoutKind.Sequential)]
310 public struct Matrix4
311 {
312 public Matrix4(dReal m00, dReal m10, dReal m20, dReal m30,
313 dReal m01, dReal m11, dReal m21, dReal m31,
314 dReal m02, dReal m12, dReal m22, dReal m32,
315 dReal m03, dReal m13, dReal m23, dReal m33)
316 {
317 M00 = m00; M10 = m10; M20 = m20; M30 = m30;
318 M01 = m01; M11 = m11; M21 = m21; M31 = m31;
319 M02 = m02; M12 = m12; M22 = m22; M32 = m32;
320 M03 = m03; M13 = m13; M23 = m23; M33 = m33;
321 }
322 public dReal M00, M10, M20, M30;
323 public dReal M01, M11, M21, M31;
324 public dReal M02, M12, M22, M32;
325 public dReal M03, M13, M23, M33;
326 }
327
328 [StructLayout(LayoutKind.Sequential)]
329 public struct Quaternion
330 {
331 public dReal W, X, Y, Z;
332 }
333
334
335 [StructLayout(LayoutKind.Sequential)]
336 public struct SurfaceParameters
337 {
338 public ContactFlags mode;
339 public dReal mu;
340 public dReal mu2;
341 public dReal bounce;
342 public dReal bounce_vel;
343 public dReal soft_erp;
344 public dReal soft_cfm;
345 public dReal motion1;
346 public dReal motion2;
347 public dReal motionN;
348 public dReal slip1;
349 public dReal slip2;
350 }
351
352
353 [StructLayout(LayoutKind.Sequential)]
354 public struct Vector3
355 {
356 public Vector3(dReal x, dReal y, dReal z)
357 {
358 X = x; Y = y; Z = z; _w = 0.0f;
359 }
360 public dReal X, Y, Z;
361 private dReal _w;
362 }
363
364
365 [StructLayout(LayoutKind.Sequential)]
366 public struct Vector4
367 {
368 public Vector4(dReal x, dReal y, dReal z, dReal w)
369 {
370 X = x; Y = y; Z = z; W = w;
371 }
372 public dReal X, Y, Z, W;
373 }
374
375 #endregion
376
377 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAllocateODEDataForThread"), SuppressUnmanagedCodeSecurity]
378 public static extern int AllocateODEDataForThread(uint ODEInitFlags);
379
380 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAreConnected"), SuppressUnmanagedCodeSecurity]
381 public static extern bool AreConnected(IntPtr b1, IntPtr b2);
382
383 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAreConnectedExcluding"), SuppressUnmanagedCodeSecurity]
384 public static extern bool AreConnectedExcluding(IntPtr b1, IntPtr b2, JointType joint_type);
385
386 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForce"), SuppressUnmanagedCodeSecurity]
387 public static extern void BodyAddForce(IntPtr body, dReal fx, dReal fy, dReal fz);
388
389 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForceAtPos"), SuppressUnmanagedCodeSecurity]
390 public static extern void BodyAddForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
391
392 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForceAtRelPos"), SuppressUnmanagedCodeSecurity]
393 public static extern void BodyAddForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
394
395 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForce"), SuppressUnmanagedCodeSecurity]
396 public static extern void BodyAddRelForce(IntPtr body, dReal fx, dReal fy, dReal fz);
397
398 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForceAtPos"), SuppressUnmanagedCodeSecurity]
399 public static extern void BodyAddRelForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
400
401 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForceAtRelPos"), SuppressUnmanagedCodeSecurity]
402 public static extern void BodyAddRelForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
403
404 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelTorque"), SuppressUnmanagedCodeSecurity]
405 public static extern void BodyAddRelTorque(IntPtr body, dReal fx, dReal fy, dReal fz);
406
407 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddTorque"), SuppressUnmanagedCodeSecurity]
408 public static extern void BodyAddTorque(IntPtr body, dReal fx, dReal fy, dReal fz);
409
410 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity]
411 public static extern void BodyCopyPosition(IntPtr body, out Vector3 pos);
412
413 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity]
414 public static extern void BodyCopyPosition(IntPtr body, out dReal X);
415
416 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity]
417 public static extern void BodyCopyQuaternion(IntPtr body, out Quaternion quat);
418
419 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity]
420 public static extern void BodyCopyQuaternion(IntPtr body, out dReal X);
421
422 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity]
423 public static extern void BodyCopyRotation(IntPtr body, out Matrix3 R);
424
425 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity]
426 public static extern void BodyCopyRotation(IntPtr body, out dReal M00);
427
428 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCreate"), SuppressUnmanagedCodeSecurity]
429 public static extern IntPtr BodyiCreate(IntPtr world);
430 public static IntPtr BodyCreate(IntPtr world)
431 {
432 NTotalBodies++;
433 return BodyiCreate(world);
434 }
435
436 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyDestroy"), SuppressUnmanagedCodeSecurity]
437 public static extern void BodyiDestroy(IntPtr body);
438 public static void BodyDestroy(IntPtr body)
439 {
440 NTotalBodies--;
441 BodyiDestroy(body);
442 }
443
444 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyDisable"), SuppressUnmanagedCodeSecurity]
445 public static extern void BodyDisable(IntPtr body);
446
447 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyEnable"), SuppressUnmanagedCodeSecurity]
448 public static extern void BodyEnable(IntPtr body);
449
450 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity]
451 public static extern dReal BodyGetAutoDisableAngularThreshold(IntPtr body);
452
453 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity]
454 public static extern bool BodyGetAutoDisableFlag(IntPtr body);
455
456 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableDefaults"), SuppressUnmanagedCodeSecurity]
457 public static extern void BodyGetAutoDisableDefaults(IntPtr body);
458
459 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity]
460 public static extern dReal BodyGetAutoDisableLinearThreshold(IntPtr body);
461
462 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity]
463 public static extern int BodyGetAutoDisableSteps(IntPtr body);
464
465 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableTime"), SuppressUnmanagedCodeSecurity]
466 public static extern dReal BodyGetAutoDisableTime(IntPtr body);
467
468 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularVel"), SuppressUnmanagedCodeSecurity]
469 public extern unsafe static Vector3* BodyGetAngularVelUnsafe(IntPtr body);
470 public static Vector3 BodyGetAngularVel(IntPtr body)
471 {
472 unsafe { return *(BodyGetAngularVelUnsafe(body)); }
473 }
474
475 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetData"), SuppressUnmanagedCodeSecurity]
476 public static extern IntPtr BodyGetData(IntPtr body);
477
478 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFiniteRotationMode"), SuppressUnmanagedCodeSecurity]
479 public static extern int BodyGetFiniteRotationMode(IntPtr body);
480
481 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFiniteRotationAxis"), SuppressUnmanagedCodeSecurity]
482 public static extern void BodyGetFiniteRotationAxis(IntPtr body, out Vector3 result);
483
484 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetForce"), SuppressUnmanagedCodeSecurity]
485 public extern unsafe static Vector3* BodyGetForceUnsafe(IntPtr body);
486 public static Vector3 BodyGetForce(IntPtr body)
487 {
488 unsafe { return *(BodyGetForceUnsafe(body)); }
489 }
490
491 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetGravityMode"), SuppressUnmanagedCodeSecurity]
492 public static extern bool BodyGetGravityMode(IntPtr body);
493
494 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetGyroscopicMode"), SuppressUnmanagedCodeSecurity]
495 public static extern int BodyGetGyroscopicMode(IntPtr body);
496
497 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetJoint"), SuppressUnmanagedCodeSecurity]
498 public static extern IntPtr BodyGetJoint(IntPtr body, int index);
499
500 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearVel"), SuppressUnmanagedCodeSecurity]
501 public extern unsafe static Vector3* BodyGetLinearVelUnsafe(IntPtr body);
502 public static Vector3 BodyGetLinearVel(IntPtr body)
503 {
504 unsafe { return *(BodyGetLinearVelUnsafe(body)); }
505 }
506
507 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetMass"), SuppressUnmanagedCodeSecurity]
508 public static extern void BodyGetMass(IntPtr body, out Mass mass);
509
510 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetNumJoints"), SuppressUnmanagedCodeSecurity]
511 public static extern int BodyGetNumJoints(IntPtr body);
512
513 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPointVel"), SuppressUnmanagedCodeSecurity]
514 public static extern void BodyGetPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
515
516 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPosition"), SuppressUnmanagedCodeSecurity]
517 public extern unsafe static Vector3* BodyGetPositionUnsafe(IntPtr body);
518 public static Vector3 BodyGetPosition(IntPtr body)
519 {
520 unsafe { return *(BodyGetPositionUnsafe(body)); }
521 }
522
523 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPosRelPoint"), SuppressUnmanagedCodeSecurity]
524 public static extern void BodyGetPosRelPoint(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
525
526 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetQuaternion"), SuppressUnmanagedCodeSecurity]
527 public extern unsafe static Quaternion* BodyGetQuaternionUnsafe(IntPtr body);
528 public static Quaternion BodyGetQuaternion(IntPtr body)
529 {
530 unsafe { return *(BodyGetQuaternionUnsafe(body)); }
531 }
532
533 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRelPointPos"), SuppressUnmanagedCodeSecurity]
534 public static extern void BodyGetRelPointPos(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
535
536 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRelPointVel"), SuppressUnmanagedCodeSecurity]
537 public static extern void BodyGetRelPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
538
539 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRotation"), SuppressUnmanagedCodeSecurity]
540 public extern unsafe static Matrix3* BodyGetRotationUnsafe(IntPtr body);
541 public static Matrix3 BodyGetRotation(IntPtr body)
542 {
543 unsafe { return *(BodyGetRotationUnsafe(body)); }
544 }
545
546 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetTorque"), SuppressUnmanagedCodeSecurity]
547 public extern unsafe static Vector3* BodyGetTorqueUnsafe(IntPtr body);
548 public static Vector3 BodyGetTorque(IntPtr body)
549 {
550 unsafe { return *(BodyGetTorqueUnsafe(body)); }
551 }
552
553 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetWorld"), SuppressUnmanagedCodeSecurity]
554 public static extern IntPtr BodyGetWorld(IntPtr body);
555
556 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFirstGeom"), SuppressUnmanagedCodeSecurity]
557 public static extern IntPtr BodyGetFirstGeom(IntPtr body);
558
559 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetNextGeom"), SuppressUnmanagedCodeSecurity]
560 public static extern IntPtr dBodyGetNextGeom(IntPtr Geom);
561
562
563 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyIsEnabled"), SuppressUnmanagedCodeSecurity]
564 public static extern bool BodyIsEnabled(IntPtr body);
565
566 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularVel"), SuppressUnmanagedCodeSecurity]
567 public static extern void BodySetAngularVel(IntPtr body, dReal x, dReal y, dReal z);
568
569 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity]
570 public static extern void BodySetAutoDisableAngularThreshold(IntPtr body, dReal angular_threshold);
571
572 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableDefaults"), SuppressUnmanagedCodeSecurity]
573 public static extern void BodySetAutoDisableDefaults(IntPtr body);
574
575 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableFlag"), SuppressUnmanagedCodeSecurity]
576 public static extern void BodySetAutoDisableFlag(IntPtr body, bool do_auto_disable);
577
578 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity]
579 public static extern void BodySetAutoDisableLinearThreshold(IntPtr body, dReal linear_threshold);
580
581 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableSteps"), SuppressUnmanagedCodeSecurity]
582 public static extern void BodySetAutoDisableSteps(IntPtr body, int steps);
583
584 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableTime"), SuppressUnmanagedCodeSecurity]
585 public static extern void BodySetAutoDisableTime(IntPtr body, dReal time);
586
587 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetData"), SuppressUnmanagedCodeSecurity]
588 public static extern void BodySetData(IntPtr body, IntPtr data);
589
590 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetFiniteRotationMode"), SuppressUnmanagedCodeSecurity]
591 public static extern void BodySetFiniteRotationMode(IntPtr body, int mode);
592
593 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetFiniteRotationAxis"), SuppressUnmanagedCodeSecurity]
594 public static extern void BodySetFiniteRotationAxis(IntPtr body, dReal x, dReal y, dReal z);
595
596 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearDamping"), SuppressUnmanagedCodeSecurity]
597 public static extern void BodySetLinearDamping(IntPtr body, dReal scale);
598
599 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDamping"), SuppressUnmanagedCodeSecurity]
600 public static extern void BodySetAngularDamping(IntPtr body, dReal scale);
601
602 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearDamping"), SuppressUnmanagedCodeSecurity]
603 public static extern dReal BodyGetLinearDamping(IntPtr body);
604
605 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularDamping"), SuppressUnmanagedCodeSecurity]
606 public static extern dReal BodyGetAngularDamping(IntPtr body);
607
608 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDamping"), SuppressUnmanagedCodeSecurity]
609 public static extern void BodySetDamping(IntPtr body, dReal linear_scale, dReal angular_scale);
610
611 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity]
612 public static extern void BodySetAngularDampingThreshold(IntPtr body, dReal threshold);
613
614 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity]
615 public static extern void BodySetLinearDampingThreshold(IntPtr body, dReal threshold);
616
617 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity]
618 public static extern dReal BodyGetLinearDampingThreshold(IntPtr body);
619
620 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity]
621 public static extern dReal BodyGetAngularDampingThreshold(IntPtr body);
622
623 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetForce"), SuppressUnmanagedCodeSecurity]
624 public static extern void BodySetForce(IntPtr body, dReal x, dReal y, dReal z);
625
626 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetGravityMode"), SuppressUnmanagedCodeSecurity]
627 public static extern void BodySetGravityMode(IntPtr body, bool mode);
628
629 /// <summary>
630 /// Sets the Gyroscopic term status on the body specified.
631 /// </summary>
632 /// <param name="body">Pointer to body</param>
633 /// <param name="enabled">NonZero enabled, Zero disabled</param>
634 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetGyroscopicMode"), SuppressUnmanagedCodeSecurity]
635 public static extern void dBodySetGyroscopicMode(IntPtr body, int enabled);
636
637 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearVel"), SuppressUnmanagedCodeSecurity]
638 public static extern void BodySetLinearVel(IntPtr body, dReal x, dReal y, dReal z);
639
640 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetMass"), SuppressUnmanagedCodeSecurity]
641 public static extern void BodySetMass(IntPtr body, ref Mass mass);
642
643 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetPosition"), SuppressUnmanagedCodeSecurity]
644 public static extern void BodySetPosition(IntPtr body, dReal x, dReal y, dReal z);
645
646 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity]
647 public static extern void BodySetQuaternion(IntPtr body, ref Quaternion q);
648
649 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity]
650 public static extern void BodySetQuaternion(IntPtr body, ref dReal w);
651
652 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity]
653 public static extern void BodySetRotation(IntPtr body, ref Matrix3 R);
654
655 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity]
656 public static extern void BodySetRotation(IntPtr body, ref dReal M00);
657
658 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetTorque"), SuppressUnmanagedCodeSecurity]
659 public static extern void BodySetTorque(IntPtr body, dReal x, dReal y, dReal z);
660
661 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyVectorFromWorld"), SuppressUnmanagedCodeSecurity]
662 public static extern void BodyVectorFromWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
663
664 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyVectorToWorld"), SuppressUnmanagedCodeSecurity]
665 public static extern void BodyVectorToWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
666
667 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBoxBox"), SuppressUnmanagedCodeSecurity]
668 public static extern void BoxBox(ref Vector3 p1, ref Matrix3 R1,
669 ref Vector3 side1, ref Vector3 p2,
670 ref Matrix3 R2, ref Vector3 side2,
671 ref Vector3 normal, out dReal depth, out int return_code,
672 int maxc, out ContactGeom contact, int skip);
673
674 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBoxTouchesBox"), SuppressUnmanagedCodeSecurity]
675 public static extern void BoxTouchesBox(ref Vector3 _p1, ref Matrix3 R1,
676 ref Vector3 side1, ref Vector3 _p2,
677 ref Matrix3 R2, ref Vector3 side2);
678
679 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCleanupODEAllDataForThread"), SuppressUnmanagedCodeSecurity]
680 public static extern void CleanupODEAllDataForThread();
681
682 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dClosestLineSegmentPoints"), SuppressUnmanagedCodeSecurity]
683 public static extern void ClosestLineSegmentPoints(ref Vector3 a1, ref Vector3 a2,
684 ref Vector3 b1, ref Vector3 b2,
685 ref Vector3 cp1, ref Vector3 cp2);
686
687 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCloseODE"), SuppressUnmanagedCodeSecurity]
688 public static extern void CloseODE();
689
690 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCollide"), SuppressUnmanagedCodeSecurity]
691 public static extern int Collide(IntPtr o1, IntPtr o2, int flags, [In, Out] ContactGeom[] contact, int skip);
692 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCollide"), SuppressUnmanagedCodeSecurity]
693 public static extern int CollidePtr(IntPtr o1, IntPtr o2, int flags, IntPtr contactgeomarray, int skip);
694
695 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dConnectingJoint"), SuppressUnmanagedCodeSecurity]
696 public static extern IntPtr ConnectingJoint(IntPtr j1, IntPtr j2);
697
698 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateBox"), SuppressUnmanagedCodeSecurity]
699 public static extern IntPtr CreateiBox(IntPtr space, dReal lx, dReal ly, dReal lz);
700 public static IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz)
701 {
702 NTotalGeoms++;
703 return CreateiBox(space, lx, ly, lz);
704 }
705
706 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCapsule"), SuppressUnmanagedCodeSecurity]
707 public static extern IntPtr CreateiCapsule(IntPtr space, dReal radius, dReal length);
708 public static IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length)
709 {
710 NTotalGeoms++;
711 return CreateiCapsule(space, radius, length);
712 }
713
714 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateConvex"), SuppressUnmanagedCodeSecurity]
715 public static extern IntPtr CreateiConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
716 public static IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons)
717 {
718 NTotalGeoms++;
719 return CreateiConvex(space, planes, planeCount, points, pointCount, polygons);
720 }
721
722 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCylinder"), SuppressUnmanagedCodeSecurity]
723 public static extern IntPtr CreateiCylinder(IntPtr space, dReal radius, dReal length);
724 public static IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length)
725 {
726 NTotalGeoms++;
727 return CreateiCylinder(space, radius, length);
728 }
729
730 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateHeightfield"), SuppressUnmanagedCodeSecurity]
731 public static extern IntPtr CreateiHeightfield(IntPtr space, IntPtr data, int bPlaceable);
732 public static IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable)
733 {
734 NTotalGeoms++;
735 return CreateiHeightfield(space, data, bPlaceable);
736 }
737
738 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateOSTerrain"), SuppressUnmanagedCodeSecurity]
739 public static extern IntPtr CreateiOSTerrain(IntPtr space, IntPtr data, int bPlaceable);
740 public static IntPtr CreateOSTerrain(IntPtr space, IntPtr data, int bPlaceable)
741 {
742 NTotalGeoms++;
743 return CreateiOSTerrain(space, data, bPlaceable);
744 }
745
746
747
748
749
750 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity]
751 public static extern IntPtr CreateiGeom(int classnum);
752 public static IntPtr CreateGeom(int classnum)
753 {
754 NTotalGeoms++;
755 return CreateiGeom(classnum);
756 }
757
758 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomClass"), SuppressUnmanagedCodeSecurity]
759 public static extern int CreateGeomClass(ref GeomClass classptr);
760
761 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomTransform"), SuppressUnmanagedCodeSecurity]
762 public static extern IntPtr CreateGeomTransform(IntPtr space);
763
764 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreatePlane"), SuppressUnmanagedCodeSecurity]
765 public static extern IntPtr CreateiPlane(IntPtr space, dReal a, dReal b, dReal c, dReal d);
766 public static IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d)
767 {
768 NTotalGeoms++;
769 return CreateiPlane(space, a, b, c, d);
770 }
771
772 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateRay"), SuppressUnmanagedCodeSecurity]
773 public static extern IntPtr CreateiRay(IntPtr space, dReal length);
774 public static IntPtr CreateRay(IntPtr space, dReal length)
775 {
776 NTotalGeoms++;
777 return CreateiRay(space, length);
778 }
779
780 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateSphere"), SuppressUnmanagedCodeSecurity]
781 public static extern IntPtr CreateiSphere(IntPtr space, dReal radius);
782 public static IntPtr CreateSphere(IntPtr space, dReal radius)
783 {
784 NTotalGeoms++;
785 return CreateiSphere(space, radius);
786 }
787
788 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateTriMesh"), SuppressUnmanagedCodeSecurity]
789 public static extern IntPtr CreateiTriMesh(IntPtr space, IntPtr data,
790 TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback);
791 public static IntPtr CreateTriMesh(IntPtr space, IntPtr data,
792 TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback)
793 {
794 NTotalGeoms++;
795 return CreateiTriMesh(space, data, callback, arrayCallback, rayCallback);
796 }
797 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity]
798 public static extern dReal Dot(ref dReal X0, ref dReal X1, int n);
799
800 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity]
801 public static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q);
802
803 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dFactorCholesky"), SuppressUnmanagedCodeSecurity]
804 public static extern int FactorCholesky(ref dReal A00, int n);
805
806 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dFactorLDLT"), SuppressUnmanagedCodeSecurity]
807 public static extern void FactorLDLT(ref dReal A, out dReal d, int n, int nskip);
808
809 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity]
810 public static extern void GeomBoxGetLengths(IntPtr geom, out Vector3 len);
811
812 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity]
813 public static extern void GeomBoxGetLengths(IntPtr geom, out dReal x);
814
815 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxPointDepth"), SuppressUnmanagedCodeSecurity]
816 public static extern dReal GeomBoxPointDepth(IntPtr geom, dReal x, dReal y, dReal z);
817
818 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxSetLengths"), SuppressUnmanagedCodeSecurity]
819 public static extern void GeomBoxSetLengths(IntPtr geom, dReal x, dReal y, dReal z);
820
821 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsuleGetParams"), SuppressUnmanagedCodeSecurity]
822 public static extern void GeomCapsuleGetParams(IntPtr geom, out dReal radius, out dReal length);
823
824 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsulePointDepth"), SuppressUnmanagedCodeSecurity]
825 public static extern dReal GeomCapsulePointDepth(IntPtr geom, dReal x, dReal y, dReal z);
826
827 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsuleSetParams"), SuppressUnmanagedCodeSecurity]
828 public static extern void GeomCapsuleSetParams(IntPtr geom, dReal radius, dReal length);
829
830 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomClearOffset"), SuppressUnmanagedCodeSecurity]
831 public static extern void GeomClearOffset(IntPtr geom);
832
833 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity]
834 public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref Vector3 pos);
835
836 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity]
837 public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref dReal X);
838
839 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity]
840 public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref Quaternion Q);
841
842 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity]
843 public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref dReal X);
844
845 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity]
846 public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref Matrix3 R);
847
848 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity]
849 public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref dReal M00);
850
851 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity]
852 public static extern void GeomCopyPosition(IntPtr geom, out Vector3 pos);
853
854 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity]
855 public static extern void GeomCopyPosition(IntPtr geom, out dReal X);
856
857 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity]
858 public static extern void GeomCopyRotation(IntPtr geom, out Matrix3 R);
859
860 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity]
861 public static extern void GeomCopyRotation(IntPtr geom, out dReal M00);
862
863 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCylinderGetParams"), SuppressUnmanagedCodeSecurity]
864 public static extern void GeomCylinderGetParams(IntPtr geom, out dReal radius, out dReal length);
865
866 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCylinderSetParams"), SuppressUnmanagedCodeSecurity]
867 public static extern void GeomCylinderSetParams(IntPtr geom, dReal radius, dReal length);
868
869 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDestroy"), SuppressUnmanagedCodeSecurity]
870 public static extern void GeomiDestroy(IntPtr geom);
871 public static void GeomDestroy(IntPtr geom)
872 {
873 NTotalGeoms--;
874 GeomiDestroy(geom);
875 }
876
877
878 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDisable"), SuppressUnmanagedCodeSecurity]
879 public static extern void GeomDisable(IntPtr geom);
880
881 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomEnable"), SuppressUnmanagedCodeSecurity]
882 public static extern void GeomEnable(IntPtr geom);
883
884 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity]
885 public static extern void GeomGetAABB(IntPtr geom, out AABB aabb);
886
887 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity]
888 public static extern void GeomGetAABB(IntPtr geom, out dReal minX);
889
890 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetBody"), SuppressUnmanagedCodeSecurity]
891 public static extern IntPtr GeomGetBody(IntPtr geom);
892
893 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity]
894 public static extern uint GeomGetCategoryBits(IntPtr geom);
895
896 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity]
897 public static extern IntPtr GeomGetClassData(IntPtr geom);
898
899 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity]
900 public static extern uint GeomGetCollideBits(IntPtr geom);
901
902 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity]
903 public static extern GeomClassID GeomGetClass(IntPtr geom);
904
905 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetData"), SuppressUnmanagedCodeSecurity]
906 public static extern IntPtr GeomGetData(IntPtr geom);
907
908 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetPosition"), SuppressUnmanagedCodeSecurity]
909 public extern unsafe static Vector3* GeomGetOffsetPositionUnsafe(IntPtr geom);
910 public static Vector3 GeomGetOffsetPosition(IntPtr geom)
911 {
912 unsafe { return *(GeomGetOffsetPositionUnsafe(geom)); }
913 }
914
915 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetRotation"), SuppressUnmanagedCodeSecurity]
916 public extern unsafe static Matrix3* GeomGetOffsetRotationUnsafe(IntPtr geom);
917 public static Matrix3 GeomGetOffsetRotation(IntPtr geom)
918 {
919 unsafe { return *(GeomGetOffsetRotationUnsafe(geom)); }
920 }
921
922 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetPosition"), SuppressUnmanagedCodeSecurity]
923 public extern unsafe static Vector3* GeomGetPositionUnsafe(IntPtr geom);
924 public static Vector3 GeomGetPosition(IntPtr geom)
925 {
926 unsafe { return *(GeomGetPositionUnsafe(geom)); }
927 }
928 public static OMV.Vector3 GeomGetPositionOMV(IntPtr geom)
929 {
930 Vector3 vtmp = GeomGetPosition(geom);
931 return new OMV.Vector3(vtmp.X, vtmp.Y, vtmp.Z);
932 }
933
934 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
935 public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q);
936 public static OMV.Quaternion GeomGetQuaternionOMV(IntPtr geom)
937 {
938 Quaternion qtmp;
939 GeomCopyQuaternion(geom, out qtmp);
940 return new OMV.Quaternion(qtmp.X, qtmp.Y, qtmp.Z, qtmp.W);
941 }
942
943 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
944 public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X);
945
946 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetRotation"), SuppressUnmanagedCodeSecurity]
947 public extern unsafe static Matrix3* GeomGetRotationUnsafe(IntPtr geom);
948 public static Matrix3 GeomGetRotation(IntPtr geom)
949 {
950 unsafe { return *(GeomGetRotationUnsafe(geom)); }
951 }
952
953 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetSpace"), SuppressUnmanagedCodeSecurity]
954 public static extern IntPtr GeomGetSpace(IntPtr geom);
955
956 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity]
957 public static extern void GeomHeightfieldDataBuildByte(IntPtr d, byte[] pHeightData, int bCopyHeightData,
958 dReal width, dReal depth, int widthSamples, int depthSamples,
959 dReal scale, dReal offset, dReal thickness, int bWrap);
960
961 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity]
962 public static extern void GeomHeightfieldDataBuildByte(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
963 dReal width, dReal depth, int widthSamples, int depthSamples,
964 dReal scale, dReal offset, dReal thickness, int bWrap);
965
966 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildCallback"), SuppressUnmanagedCodeSecurity]
967 public static extern void GeomHeightfieldDataBuildCallback(IntPtr d, IntPtr pUserData, HeightfieldGetHeight pCallback,
968 dReal width, dReal depth, int widthSamples, int depthSamples,
969 dReal scale, dReal offset, dReal thickness, int bWrap);
970
971 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity]
972 public static extern void GeomHeightfieldDataBuildShort(IntPtr d, ushort[] pHeightData, int bCopyHeightData,
973 dReal width, dReal depth, int widthSamples, int depthSamples,
974 dReal scale, dReal offset, dReal thickness, int bWrap);
975
976 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity]
977 public static extern void GeomHeightfieldDataBuildShort(IntPtr d, short[] pHeightData, int bCopyHeightData,
978 dReal width, dReal depth, int widthSamples, int depthSamples,
979 dReal scale, dReal offset, dReal thickness, int bWrap);
980
981 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity]
982 public static extern void GeomHeightfieldDataBuildShort(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
983 dReal width, dReal depth, int widthSamples, int depthSamples,
984 dReal scale, dReal offset, dReal thickness, int bWrap);
985
986 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity]
987 public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, float[] pHeightData, int bCopyHeightData,
988 dReal width, dReal depth, int widthSamples, int depthSamples,
989 dReal scale, dReal offset, dReal thickness, int bWrap);
990
991 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity]
992 public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
993 dReal width, dReal depth, int widthSamples, int depthSamples,
994 dReal scale, dReal offset, dReal thickness, int bWrap);
995
996
997
998 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity]
999 public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData,
1000 dReal width, dReal depth, int widthSamples, int depthSamples,
1001 dReal scale, dReal offset, dReal thickness, int bWrap);
1002
1003 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity]
1004 public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
1005 dReal width, dReal depth, int widthSamples, int depthSamples,
1006 dReal scale, dReal offset, dReal thickness, int bWrap);
1007
1008 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataCreate"), SuppressUnmanagedCodeSecurity]
1009 public static extern IntPtr GeomHeightfieldDataCreate();
1010
1011 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataDestroy"), SuppressUnmanagedCodeSecurity]
1012 public static extern void GeomHeightfieldDataDestroy(IntPtr d);
1013
1014 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataSetBounds"), SuppressUnmanagedCodeSecurity]
1015 public static extern void GeomHeightfieldDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight);
1016
1017 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldGetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1018 public static extern IntPtr GeomHeightfieldGetHeightfieldData(IntPtr g);
1019
1020 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldSetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1021 public static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d);
1022
1023
1024 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataBuild"), SuppressUnmanagedCodeSecurity]
1025 public static extern void GeomOSTerrainDataBuild(IntPtr d, float[] pHeightData, int bCopyHeightData,
1026 dReal sampleSize, int widthSamples, int depthSamples,
1027 dReal offset, dReal thickness, int bWrap);
1028
1029 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataBuild"), SuppressUnmanagedCodeSecurity]
1030 public static extern void GeomOSTerrainDataBuild(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
1031 dReal sampleSize, int widthSamples, int depthSamples,
1032 dReal thickness, int bWrap);
1033
1034 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataCreate"), SuppressUnmanagedCodeSecurity]
1035 public static extern IntPtr GeomOSTerrainDataCreate();
1036
1037 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataDestroy"), SuppressUnmanagedCodeSecurity]
1038 public static extern void GeomOSTerrainDataDestroy(IntPtr d);
1039
1040 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataSetBounds"), SuppressUnmanagedCodeSecurity]
1041 public static extern void GeomOSTerrainDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight);
1042
1043 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainGetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1044 public static extern IntPtr GeomOSTerrainGetHeightfieldData(IntPtr g);
1045
1046 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainSetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1047 public static extern void GeomOSTerrainSetHeightfieldData(IntPtr g, IntPtr d);
1048
1049
1050 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsEnabled"), SuppressUnmanagedCodeSecurity]
1051 public static extern bool GeomIsEnabled(IntPtr geom);
1052
1053 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsOffset"), SuppressUnmanagedCodeSecurity]
1054 public static extern bool GeomIsOffset(IntPtr geom);
1055
1056 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsSpace"), SuppressUnmanagedCodeSecurity]
1057 public static extern bool GeomIsSpace(IntPtr geom);
1058
1059 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity]
1060 public static extern void GeomPlaneGetParams(IntPtr geom, ref Vector4 result);
1061
1062 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity]
1063 public static extern void GeomPlaneGetParams(IntPtr geom, ref dReal A);
1064
1065 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlanePointDepth"), SuppressUnmanagedCodeSecurity]
1066 public static extern dReal GeomPlanePointDepth(IntPtr geom, dReal x, dReal y, dReal z);
1067
1068 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneSetParams"), SuppressUnmanagedCodeSecurity]
1069 public static extern void GeomPlaneSetParams(IntPtr plane, dReal a, dReal b, dReal c, dReal d);
1070
1071 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity]
1072 public static extern void GeomRayGet(IntPtr ray, ref Vector3 start, ref Vector3 dir);
1073
1074 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity]
1075 public static extern void GeomRayGet(IntPtr ray, ref dReal startX, ref dReal dirX);
1076
1077 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetClosestHit"), SuppressUnmanagedCodeSecurity]
1078 public static extern int GeomRayGetClosestHit(IntPtr ray);
1079
1080 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetLength"), SuppressUnmanagedCodeSecurity]
1081 public static extern dReal GeomRayGetLength(IntPtr ray);
1082
1083 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetParams"), SuppressUnmanagedCodeSecurity]
1084 public static extern dReal GeomRayGetParams(IntPtr g, out int firstContact, out int backfaceCull);
1085
1086 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySet"), SuppressUnmanagedCodeSecurity]
1087 public static extern void GeomRaySet(IntPtr ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz);
1088
1089 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetClosestHit"), SuppressUnmanagedCodeSecurity]
1090 public static extern void GeomRaySetClosestHit(IntPtr ray, int closestHit);
1091
1092 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetLength"), SuppressUnmanagedCodeSecurity]
1093 public static extern void GeomRaySetLength(IntPtr ray, dReal length);
1094
1095 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetParams"), SuppressUnmanagedCodeSecurity]
1096 public static extern void GeomRaySetParams(IntPtr ray, int firstContact, int backfaceCull);
1097
1098 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetBody"), SuppressUnmanagedCodeSecurity]
1099 public static extern void GeomSetBody(IntPtr geom, IntPtr body);
1100
1101 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity]
1102 public static extern void GeomSetCategoryBits(IntPtr geom, uint bits);
1103
1104 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity]
1105 public static extern void GeomSetCollideBits(IntPtr geom, uint bits);
1106
1107 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity]
1108 public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
1109
1110 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetData"), SuppressUnmanagedCodeSecurity]
1111 public static extern void GeomSetData(IntPtr geom, IntPtr data);
1112
1113 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetPosition"), SuppressUnmanagedCodeSecurity]
1114 public static extern void GeomSetOffsetPosition(IntPtr geom, dReal x, dReal y, dReal z);
1115
1116 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity]
1117 public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref Quaternion Q);
1118
1119 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity]
1120 public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref dReal X);
1121
1122 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity]
1123 public static extern void GeomSetOffsetRotation(IntPtr geom, ref Matrix3 R);
1124
1125 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity]
1126 public static extern void GeomSetOffsetRotation(IntPtr geom, ref dReal M00);
1127
1128 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldPosition"), SuppressUnmanagedCodeSecurity]
1129 public static extern void GeomSetOffsetWorldPosition(IntPtr geom, dReal x, dReal y, dReal z);
1130
1131 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity]
1132 public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref Quaternion Q);
1133
1134 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity]
1135 public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref dReal X);
1136
1137 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity]
1138 public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref Matrix3 R);
1139
1140 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity]
1141 public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref dReal M00);
1142
1143 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetPosition"), SuppressUnmanagedCodeSecurity]
1144 public static extern void GeomSetPosition(IntPtr geom, dReal x, dReal y, dReal z);
1145
1146 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity]
1147 public static extern void GeomSetQuaternion(IntPtr geom, ref Quaternion quat);
1148
1149 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity]
1150 public static extern void GeomSetQuaternion(IntPtr geom, ref dReal w);
1151
1152 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity]
1153 public static extern void GeomSetRotation(IntPtr geom, ref Matrix3 R);
1154
1155 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity]
1156 public static extern void GeomSetRotation(IntPtr geom, ref dReal M00);
1157
1158 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSphereGetRadius"), SuppressUnmanagedCodeSecurity]
1159 public static extern dReal GeomSphereGetRadius(IntPtr geom);
1160
1161 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSpherePointDepth"), SuppressUnmanagedCodeSecurity]
1162 public static extern dReal GeomSpherePointDepth(IntPtr geom, dReal x, dReal y, dReal z);
1163
1164 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSphereSetRadius"), SuppressUnmanagedCodeSecurity]
1165 public static extern void GeomSphereSetRadius(IntPtr geom, dReal radius);
1166
1167 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetCleanup"), SuppressUnmanagedCodeSecurity]
1168 public static extern int GeomTransformGetCleanup(IntPtr geom);
1169
1170 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetGeom"), SuppressUnmanagedCodeSecurity]
1171 public static extern IntPtr GeomTransformGetGeom(IntPtr geom);
1172
1173 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetInfo"), SuppressUnmanagedCodeSecurity]
1174 public static extern int GeomTransformGetInfo(IntPtr geom);
1175
1176 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetCleanup"), SuppressUnmanagedCodeSecurity]
1177 public static extern void GeomTransformSetCleanup(IntPtr geom, int mode);
1178
1179 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetGeom"), SuppressUnmanagedCodeSecurity]
1180 public static extern void GeomTransformSetGeom(IntPtr geom, IntPtr obj);
1181
1182 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetInfo"), SuppressUnmanagedCodeSecurity]
1183 public static extern void GeomTransformSetInfo(IntPtr geom, int info);
1184
1185 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity]
1186 public static extern void GeomTriMeshDataBuildDouble(IntPtr d,
1187 double[] vertices, int vertexStride, int vertexCount,
1188 int[] indices, int indexCount, int triStride);
1189
1190 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity]
1191 public static extern void GeomTriMeshDataBuildDouble(IntPtr d,
1192 IntPtr vertices, int vertexStride, int vertexCount,
1193 IntPtr indices, int indexCount, int triStride);
1194
1195 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity]
1196 public static extern void GeomTriMeshDataBuildDouble1(IntPtr d,
1197 double[] vertices, int vertexStride, int vertexCount,
1198 int[] indices, int indexCount, int triStride,
1199 double[] normals);
1200
1201 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity]
1202 public static extern void GeomTriMeshDataBuildDouble(IntPtr d,
1203 IntPtr vertices, int vertexStride, int vertexCount,
1204 IntPtr indices, int indexCount, int triStride,
1205 IntPtr normals);
1206
1207 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity]
1208 public static extern void GeomTriMeshDataBuildSingle(IntPtr d,
1209 dReal[] vertices, int vertexStride, int vertexCount,
1210 int[] indices, int indexCount, int triStride);
1211
1212 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity]
1213 public static extern void GeomTriMeshDataBuildSingle(IntPtr d,
1214 IntPtr vertices, int vertexStride, int vertexCount,
1215 IntPtr indices, int indexCount, int triStride);
1216
1217 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity]
1218 public static extern void GeomTriMeshDataBuildSingle1(IntPtr d,
1219 dReal[] vertices, int vertexStride, int vertexCount,
1220 int[] indices, int indexCount, int triStride,
1221 dReal[] normals);
1222
1223 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity]
1224 public static extern void GeomTriMeshDataBuildSingle1(IntPtr d,
1225 IntPtr vertices, int vertexStride, int vertexCount,
1226 IntPtr indices, int indexCount, int triStride,
1227 IntPtr normals);
1228
1229 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity]
1230 public static extern void GeomTriMeshDataBuildSimple(IntPtr d,
1231 float[] vertices, int vertexStride, int vertexCount,
1232 int[] indices, int indexCount, int triStride);
1233
1234 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity]
1235 public static extern void GeomTriMeshDataBuildSimple(IntPtr d,
1236 IntPtr vertices, int vertexStride, int vertexCount,
1237 IntPtr indices, int indexCount, int triStride);
1238
1239 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity]
1240 public static extern void GeomTriMeshDataBuildSimple1(IntPtr d,
1241 float[] vertices, int vertexStride, int vertexCount,
1242 int[] indices, int indexCount, int triStride,
1243 float[] normals);
1244
1245 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity]
1246 public static extern void GeomTriMeshDataBuildSimple1(IntPtr d,
1247 IntPtr vertices, int vertexStride, int vertexCount,
1248 IntPtr indices, int indexCount, int triStride,
1249 IntPtr normals);
1250
1251 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshClearTCCache"), SuppressUnmanagedCodeSecurity]
1252 public static extern void GeomTriMeshClearTCCache(IntPtr g);
1253
1254 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataCreate"), SuppressUnmanagedCodeSecurity]
1255 public static extern IntPtr GeomTriMeshDataCreate();
1256
1257 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataDestroy"), SuppressUnmanagedCodeSecurity]
1258 public static extern void GeomTriMeshDataDestroy(IntPtr d);
1259
1260 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataGet"), SuppressUnmanagedCodeSecurity]
1261 public static extern IntPtr GeomTriMeshDataGet(IntPtr d, int data_id);
1262
1263 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataPreprocess"), SuppressUnmanagedCodeSecurity]
1264 public static extern void GeomTriMeshDataPreprocess(IntPtr d);
1265
1266 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataSet"), SuppressUnmanagedCodeSecurity]
1267 public static extern void GeomTriMeshDataSet(IntPtr d, int data_id, IntPtr in_data);
1268
1269 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataUpdate"), SuppressUnmanagedCodeSecurity]
1270 public static extern void GeomTriMeshDataUpdate(IntPtr d);
1271
1272 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshEnableTC"), SuppressUnmanagedCodeSecurity]
1273 public static extern void GeomTriMeshEnableTC(IntPtr g, int geomClass, bool enable);
1274
1275 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetArrayCallback"), SuppressUnmanagedCodeSecurity]
1276 public static extern TriArrayCallback GeomTriMeshGetArrayCallback(IntPtr g);
1277
1278 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetCallback"), SuppressUnmanagedCodeSecurity]
1279 public static extern TriCallback GeomTriMeshGetCallback(IntPtr g);
1280
1281 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetData"), SuppressUnmanagedCodeSecurity]
1282 public static extern IntPtr GeomTriMeshGetData(IntPtr g);
1283
1284 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetLastTransform"), SuppressUnmanagedCodeSecurity]
1285 public extern unsafe static Matrix4* GeomTriMeshGetLastTransformUnsafe(IntPtr geom);
1286 public static Matrix4 GeomTriMeshGetLastTransform(IntPtr geom)
1287 {
1288 unsafe { return *(GeomTriMeshGetLastTransformUnsafe(geom)); }
1289 }
1290
1291 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetPoint"), SuppressUnmanagedCodeSecurity]
1292 public extern static void GeomTriMeshGetPoint(IntPtr g, int index, dReal u, dReal v, ref Vector3 outVec);
1293
1294 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetRayCallback"), SuppressUnmanagedCodeSecurity]
1295 public static extern TriRayCallback GeomTriMeshGetRayCallback(IntPtr g);
1296
1297 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriangle"), SuppressUnmanagedCodeSecurity]
1298 public extern static void GeomTriMeshGetTriangle(IntPtr g, int index, ref Vector3 v0, ref Vector3 v1, ref Vector3 v2);
1299
1300 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriangleCount"), SuppressUnmanagedCodeSecurity]
1301 public extern static int GeomTriMeshGetTriangleCount(IntPtr g);
1302
1303 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriMeshDataID"), SuppressUnmanagedCodeSecurity]
1304 public static extern IntPtr GeomTriMeshGetTriMeshDataID(IntPtr g);
1305
1306 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshIsTCEnabled"), SuppressUnmanagedCodeSecurity]
1307 public static extern bool GeomTriMeshIsTCEnabled(IntPtr g, int geomClass);
1308
1309 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetArrayCallback"), SuppressUnmanagedCodeSecurity]
1310 public static extern void GeomTriMeshSetArrayCallback(IntPtr g, TriArrayCallback arrayCallback);
1311
1312 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetCallback"), SuppressUnmanagedCodeSecurity]
1313 public static extern void GeomTriMeshSetCallback(IntPtr g, TriCallback callback);
1314
1315 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetData"), SuppressUnmanagedCodeSecurity]
1316 public static extern void GeomTriMeshSetData(IntPtr g, IntPtr data);
1317
1318 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity]
1319 public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref Matrix4 last_trans);
1320
1321 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity]
1322 public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref dReal M00);
1323
1324 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetRayCallback"), SuppressUnmanagedCodeSecurity]
1325 public static extern void GeomTriMeshSetRayCallback(IntPtr g, TriRayCallback callback);
1326
1327 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGetConfiguration"), SuppressUnmanagedCodeSecurity]
1328 public static extern IntPtr iGetConfiguration();
1329
1330 public static string GetConfiguration()
1331 {
1332 IntPtr ptr = iGetConfiguration();
1333 string s = Marshal.PtrToStringAnsi(ptr);
1334 return s;
1335 }
1336
1337 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceCreate"), SuppressUnmanagedCodeSecurity]
1338 public static extern IntPtr HashSpaceCreate(IntPtr space);
1339
1340 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceGetLevels"), SuppressUnmanagedCodeSecurity]
1341 public static extern void HashSpaceGetLevels(IntPtr space, out int minlevel, out int maxlevel);
1342
1343 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceSetLevels"), SuppressUnmanagedCodeSecurity]
1344 public static extern void HashSpaceSetLevels(IntPtr space, int minlevel, int maxlevel);
1345
1346 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInfiniteAABB"), SuppressUnmanagedCodeSecurity]
1347 public static extern void InfiniteAABB(IntPtr geom, out AABB aabb);
1348
1349 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInitODE"), SuppressUnmanagedCodeSecurity]
1350 public static extern void InitODE();
1351
1352 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInitODE2"), SuppressUnmanagedCodeSecurity]
1353 public static extern int InitODE2(uint ODEInitFlags);
1354
1355 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dIsPositiveDefinite"), SuppressUnmanagedCodeSecurity]
1356 public static extern int IsPositiveDefinite(ref dReal A, int n);
1357
1358 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInvertPDMatrix"), SuppressUnmanagedCodeSecurity]
1359 public static extern int InvertPDMatrix(ref dReal A, out dReal Ainv, int n);
1360
1361 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddAMotorTorques"), SuppressUnmanagedCodeSecurity]
1362 public static extern void JointAddAMotorTorques(IntPtr joint, dReal torque1, dReal torque2, dReal torque3);
1363
1364 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddHingeTorque"), SuppressUnmanagedCodeSecurity]
1365 public static extern void JointAddHingeTorque(IntPtr joint, dReal torque);
1366
1367 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddHinge2Torque"), SuppressUnmanagedCodeSecurity]
1368 public static extern void JointAddHinge2Torques(IntPtr joint, dReal torque1, dReal torque2);
1369
1370 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddPRTorque"), SuppressUnmanagedCodeSecurity]
1371 public static extern void JointAddPRTorque(IntPtr joint, dReal torque);
1372
1373 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddUniversalTorque"), SuppressUnmanagedCodeSecurity]
1374 public static extern void JointAddUniversalTorques(IntPtr joint, dReal torque1, dReal torque2);
1375
1376 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddSliderForce"), SuppressUnmanagedCodeSecurity]
1377 public static extern void JointAddSliderForce(IntPtr joint, dReal force);
1378
1379 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAttach"), SuppressUnmanagedCodeSecurity]
1380 public static extern void JointAttach(IntPtr joint, IntPtr body1, IntPtr body2);
1381
1382 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateAMotor"), SuppressUnmanagedCodeSecurity]
1383 public static extern IntPtr JointCreateAMotor(IntPtr world, IntPtr group);
1384
1385 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateBall"), SuppressUnmanagedCodeSecurity]
1386 public static extern IntPtr JointCreateBall(IntPtr world, IntPtr group);
1387
1388 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateContact"), SuppressUnmanagedCodeSecurity]
1389 public static extern IntPtr JointCreateContact(IntPtr world, IntPtr group, ref Contact contact);
1390 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateContact"), SuppressUnmanagedCodeSecurity]
1391 public static extern IntPtr JointCreateContactPtr(IntPtr world, IntPtr group, IntPtr contact);
1392
1393 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateFixed"), SuppressUnmanagedCodeSecurity]
1394 public static extern IntPtr JointCreateFixed(IntPtr world, IntPtr group);
1395
1396 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateHinge"), SuppressUnmanagedCodeSecurity]
1397 public static extern IntPtr JointCreateHinge(IntPtr world, IntPtr group);
1398
1399 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateHinge2"), SuppressUnmanagedCodeSecurity]
1400 public static extern IntPtr JointCreateHinge2(IntPtr world, IntPtr group);
1401
1402 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateLMotor"), SuppressUnmanagedCodeSecurity]
1403 public static extern IntPtr JointCreateLMotor(IntPtr world, IntPtr group);
1404
1405 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateNull"), SuppressUnmanagedCodeSecurity]
1406 public static extern IntPtr JointCreateNull(IntPtr world, IntPtr group);
1407
1408 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreatePR"), SuppressUnmanagedCodeSecurity]
1409 public static extern IntPtr JointCreatePR(IntPtr world, IntPtr group);
1410
1411 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreatePlane2D"), SuppressUnmanagedCodeSecurity]
1412 public static extern IntPtr JointCreatePlane2D(IntPtr world, IntPtr group);
1413
1414 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateSlider"), SuppressUnmanagedCodeSecurity]
1415 public static extern IntPtr JointCreateSlider(IntPtr world, IntPtr group);
1416
1417 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateUniversal"), SuppressUnmanagedCodeSecurity]
1418 public static extern IntPtr JointCreateUniversal(IntPtr world, IntPtr group);
1419
1420 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointDestroy"), SuppressUnmanagedCodeSecurity]
1421 public static extern void JointDestroy(IntPtr j);
1422
1423 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAngle"), SuppressUnmanagedCodeSecurity]
1424 public static extern dReal JointGetAMotorAngle(IntPtr j, int anum);
1425
1426 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAngleRate"), SuppressUnmanagedCodeSecurity]
1427 public static extern dReal JointGetAMotorAngleRate(IntPtr j, int anum);
1428
1429 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAxis"), SuppressUnmanagedCodeSecurity]
1430 public static extern void JointGetAMotorAxis(IntPtr j, int anum, out Vector3 result);
1431
1432 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAxisRel"), SuppressUnmanagedCodeSecurity]
1433 public static extern int JointGetAMotorAxisRel(IntPtr j, int anum);
1434
1435 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorMode"), SuppressUnmanagedCodeSecurity]
1436 public static extern int JointGetAMotorMode(IntPtr j);
1437
1438 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorNumAxes"), SuppressUnmanagedCodeSecurity]
1439 public static extern int JointGetAMotorNumAxes(IntPtr j);
1440
1441 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorParam"), SuppressUnmanagedCodeSecurity]
1442 public static extern dReal JointGetAMotorParam(IntPtr j, int parameter);
1443
1444 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBallAnchor"), SuppressUnmanagedCodeSecurity]
1445 public static extern void JointGetBallAnchor(IntPtr j, out Vector3 result);
1446
1447 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBallAnchor2"), SuppressUnmanagedCodeSecurity]
1448 public static extern void JointGetBallAnchor2(IntPtr j, out Vector3 result);
1449
1450 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBody"), SuppressUnmanagedCodeSecurity]
1451 public static extern IntPtr JointGetBody(IntPtr j);
1452
1453 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetData"), SuppressUnmanagedCodeSecurity]
1454 public static extern IntPtr JointGetData(IntPtr j);
1455
1456 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetFeedback"), SuppressUnmanagedCodeSecurity]
1457 public extern unsafe static JointFeedback* JointGetFeedbackUnsafe(IntPtr j);
1458 public static JointFeedback JointGetFeedback(IntPtr j)
1459 {
1460 unsafe { return *(JointGetFeedbackUnsafe(j)); }
1461 }
1462
1463 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAnchor"), SuppressUnmanagedCodeSecurity]
1464 public static extern void JointGetHingeAnchor(IntPtr j, out Vector3 result);
1465
1466 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAngle"), SuppressUnmanagedCodeSecurity]
1467 public static extern dReal JointGetHingeAngle(IntPtr j);
1468
1469 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAngleRate"), SuppressUnmanagedCodeSecurity]
1470 public static extern dReal JointGetHingeAngleRate(IntPtr j);
1471
1472 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAxis"), SuppressUnmanagedCodeSecurity]
1473 public static extern void JointGetHingeAxis(IntPtr j, out Vector3 result);
1474
1475 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeParam"), SuppressUnmanagedCodeSecurity]
1476 public static extern dReal JointGetHingeParam(IntPtr j, int parameter);
1477
1478 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle1"), SuppressUnmanagedCodeSecurity]
1479 public static extern dReal JointGetHinge2Angle1(IntPtr j);
1480
1481 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle1Rate"), SuppressUnmanagedCodeSecurity]
1482 public static extern dReal JointGetHinge2Angle1Rate(IntPtr j);
1483
1484 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle2Rate"), SuppressUnmanagedCodeSecurity]
1485 public static extern dReal JointGetHinge2Angle2Rate(IntPtr j);
1486
1487 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAnchor2"), SuppressUnmanagedCodeSecurity]
1488 public static extern void JointGetHingeAnchor2(IntPtr j, out Vector3 result);
1489
1490 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Anchor"), SuppressUnmanagedCodeSecurity]
1491 public static extern void JointGetHinge2Anchor(IntPtr j, out Vector3 result);
1492
1493 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Anchor2"), SuppressUnmanagedCodeSecurity]
1494 public static extern void JointGetHinge2Anchor2(IntPtr j, out Vector3 result);
1495
1496 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Axis1"), SuppressUnmanagedCodeSecurity]
1497 public static extern void JointGetHinge2Axis1(IntPtr j, out Vector3 result);
1498
1499 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Axis2"), SuppressUnmanagedCodeSecurity]
1500 public static extern void JointGetHinge2Axis2(IntPtr j, out Vector3 result);
1501
1502 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Param"), SuppressUnmanagedCodeSecurity]
1503 public static extern dReal JointGetHinge2Param(IntPtr j, int parameter);
1504
1505 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorAxis"), SuppressUnmanagedCodeSecurity]
1506 public static extern void JointGetLMotorAxis(IntPtr j, int anum, out Vector3 result);
1507
1508 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorNumAxes"), SuppressUnmanagedCodeSecurity]
1509 public static extern int JointGetLMotorNumAxes(IntPtr j);
1510
1511 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorParam"), SuppressUnmanagedCodeSecurity]
1512 public static extern dReal JointGetLMotorParam(IntPtr j, int parameter);
1513
1514 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAnchor"), SuppressUnmanagedCodeSecurity]
1515 public static extern void JointGetPRAnchor(IntPtr j, out Vector3 result);
1516
1517 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAxis1"), SuppressUnmanagedCodeSecurity]
1518 public static extern void JointGetPRAxis1(IntPtr j, out Vector3 result);
1519
1520 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAxis2"), SuppressUnmanagedCodeSecurity]
1521 public static extern void JointGetPRAxis2(IntPtr j, out Vector3 result);
1522
1523 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRParam"), SuppressUnmanagedCodeSecurity]
1524 public static extern dReal JointGetPRParam(IntPtr j, int parameter);
1525
1526 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRPosition"), SuppressUnmanagedCodeSecurity]
1527 public static extern dReal JointGetPRPosition(IntPtr j);
1528
1529 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRPositionRate"), SuppressUnmanagedCodeSecurity]
1530 public static extern dReal JointGetPRPositionRate(IntPtr j);
1531
1532 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderAxis"), SuppressUnmanagedCodeSecurity]
1533 public static extern void JointGetSliderAxis(IntPtr j, out Vector3 result);
1534
1535 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderParam"), SuppressUnmanagedCodeSecurity]
1536 public static extern dReal JointGetSliderParam(IntPtr j, int parameter);
1537
1538 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderPosition"), SuppressUnmanagedCodeSecurity]
1539 public static extern dReal JointGetSliderPosition(IntPtr j);
1540
1541 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderPositionRate"), SuppressUnmanagedCodeSecurity]
1542 public static extern dReal JointGetSliderPositionRate(IntPtr j);
1543
1544 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetType"), SuppressUnmanagedCodeSecurity]
1545 public static extern JointType JointGetType(IntPtr j);
1546
1547 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAnchor"), SuppressUnmanagedCodeSecurity]
1548 public static extern void JointGetUniversalAnchor(IntPtr j, out Vector3 result);
1549
1550 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAnchor2"), SuppressUnmanagedCodeSecurity]
1551 public static extern void JointGetUniversalAnchor2(IntPtr j, out Vector3 result);
1552
1553 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle1"), SuppressUnmanagedCodeSecurity]
1554 public static extern dReal JointGetUniversalAngle1(IntPtr j);
1555
1556 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle1Rate"), SuppressUnmanagedCodeSecurity]
1557 public static extern dReal JointGetUniversalAngle1Rate(IntPtr j);
1558
1559 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle2"), SuppressUnmanagedCodeSecurity]
1560 public static extern dReal JointGetUniversalAngle2(IntPtr j);
1561
1562 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle2Rate"), SuppressUnmanagedCodeSecurity]
1563 public static extern dReal JointGetUniversalAngle2Rate(IntPtr j);
1564
1565 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngles"), SuppressUnmanagedCodeSecurity]
1566 public static extern void JointGetUniversalAngles(IntPtr j, out dReal angle1, out dReal angle2);
1567
1568 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAxis1"), SuppressUnmanagedCodeSecurity]
1569 public static extern void JointGetUniversalAxis1(IntPtr j, out Vector3 result);
1570
1571 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAxis2"), SuppressUnmanagedCodeSecurity]
1572 public static extern void JointGetUniversalAxis2(IntPtr j, out Vector3 result);
1573
1574 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalParam"), SuppressUnmanagedCodeSecurity]
1575 public static extern dReal JointGetUniversalParam(IntPtr j, int parameter);
1576
1577 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupCreate"), SuppressUnmanagedCodeSecurity]
1578 public static extern IntPtr JointGroupCreate(int max_size);
1579
1580 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupDestroy"), SuppressUnmanagedCodeSecurity]
1581 public static extern void JointGroupDestroy(IntPtr group);
1582
1583 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupEmpty"), SuppressUnmanagedCodeSecurity]
1584 public static extern void JointGroupEmpty(IntPtr group);
1585
1586 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorAngle"), SuppressUnmanagedCodeSecurity]
1587 public static extern void JointSetAMotorAngle(IntPtr j, int anum, dReal angle);
1588
1589 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorAxis"), SuppressUnmanagedCodeSecurity]
1590 public static extern void JointSetAMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z);
1591
1592 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorMode"), SuppressUnmanagedCodeSecurity]
1593 public static extern void JointSetAMotorMode(IntPtr j, int mode);
1594
1595 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorNumAxes"), SuppressUnmanagedCodeSecurity]
1596 public static extern void JointSetAMotorNumAxes(IntPtr group, int num);
1597
1598 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorParam"), SuppressUnmanagedCodeSecurity]
1599 public static extern void JointSetAMotorParam(IntPtr group, int parameter, dReal value);
1600
1601 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetBallAnchor"), SuppressUnmanagedCodeSecurity]
1602 public static extern void JointSetBallAnchor(IntPtr j, dReal x, dReal y, dReal z);
1603
1604 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetBallAnchor2"), SuppressUnmanagedCodeSecurity]
1605 public static extern void JointSetBallAnchor2(IntPtr j, dReal x, dReal y, dReal z);
1606
1607 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetData"), SuppressUnmanagedCodeSecurity]
1608 public static extern void JointSetData(IntPtr j, IntPtr data);
1609
1610 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetFeedback"), SuppressUnmanagedCodeSecurity]
1611 public static extern void JointSetFeedback(IntPtr j, out JointFeedback feedback);
1612
1613 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetFixed"), SuppressUnmanagedCodeSecurity]
1614 public static extern void JointSetFixed(IntPtr j);
1615
1616 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAnchor"), SuppressUnmanagedCodeSecurity]
1617 public static extern void JointSetHingeAnchor(IntPtr j, dReal x, dReal y, dReal z);
1618
1619 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAnchorDelta"), SuppressUnmanagedCodeSecurity]
1620 public static extern void JointSetHingeAnchorDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
1621
1622 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAxis"), SuppressUnmanagedCodeSecurity]
1623 public static extern void JointSetHingeAxis(IntPtr j, dReal x, dReal y, dReal z);
1624
1625 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeParam"), SuppressUnmanagedCodeSecurity]
1626 public static extern void JointSetHingeParam(IntPtr j, int parameter, dReal value);
1627
1628 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Anchor"), SuppressUnmanagedCodeSecurity]
1629 public static extern void JointSetHinge2Anchor(IntPtr j, dReal x, dReal y, dReal z);
1630
1631 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Axis1"), SuppressUnmanagedCodeSecurity]
1632 public static extern void JointSetHinge2Axis1(IntPtr j, dReal x, dReal y, dReal z);
1633
1634 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Axis2"), SuppressUnmanagedCodeSecurity]
1635 public static extern void JointSetHinge2Axis2(IntPtr j, dReal x, dReal y, dReal z);
1636
1637 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Param"), SuppressUnmanagedCodeSecurity]
1638 public static extern void JointSetHinge2Param(IntPtr j, int parameter, dReal value);
1639
1640 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorAxis"), SuppressUnmanagedCodeSecurity]
1641 public static extern void JointSetLMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z);
1642
1643 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorNumAxes"), SuppressUnmanagedCodeSecurity]
1644 public static extern void JointSetLMotorNumAxes(IntPtr j, int num);
1645
1646 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorParam"), SuppressUnmanagedCodeSecurity]
1647 public static extern void JointSetLMotorParam(IntPtr j, int parameter, dReal value);
1648
1649 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DAngleParam"), SuppressUnmanagedCodeSecurity]
1650 public static extern void JointSetPlane2DAngleParam(IntPtr j, int parameter, dReal value);
1651
1652 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DXParam"), SuppressUnmanagedCodeSecurity]
1653 public static extern void JointSetPlane2DXParam(IntPtr j, int parameter, dReal value);
1654
1655 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DYParam"), SuppressUnmanagedCodeSecurity]
1656 public static extern void JointSetPlane2DYParam(IntPtr j, int parameter, dReal value);
1657
1658 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAnchor"), SuppressUnmanagedCodeSecurity]
1659 public static extern void JointSetPRAnchor(IntPtr j, dReal x, dReal y, dReal z);
1660
1661 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAxis1"), SuppressUnmanagedCodeSecurity]
1662 public static extern void JointSetPRAxis1(IntPtr j, dReal x, dReal y, dReal z);
1663
1664 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAxis2"), SuppressUnmanagedCodeSecurity]
1665 public static extern void JointSetPRAxis2(IntPtr j, dReal x, dReal y, dReal z);
1666
1667 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRParam"), SuppressUnmanagedCodeSecurity]
1668 public static extern void JointSetPRParam(IntPtr j, int parameter, dReal value);
1669
1670 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderAxis"), SuppressUnmanagedCodeSecurity]
1671 public static extern void JointSetSliderAxis(IntPtr j, dReal x, dReal y, dReal z);
1672
1673 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderAxisDelta"), SuppressUnmanagedCodeSecurity]
1674 public static extern void JointSetSliderAxisDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
1675
1676 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderParam"), SuppressUnmanagedCodeSecurity]
1677 public static extern void JointSetSliderParam(IntPtr j, int parameter, dReal value);
1678
1679 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAnchor"), SuppressUnmanagedCodeSecurity]
1680 public static extern void JointSetUniversalAnchor(IntPtr j, dReal x, dReal y, dReal z);
1681
1682 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAxis1"), SuppressUnmanagedCodeSecurity]
1683 public static extern void JointSetUniversalAxis1(IntPtr j, dReal x, dReal y, dReal z);
1684
1685 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAxis2"), SuppressUnmanagedCodeSecurity]
1686 public static extern void JointSetUniversalAxis2(IntPtr j, dReal x, dReal y, dReal z);
1687
1688 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalParam"), SuppressUnmanagedCodeSecurity]
1689 public static extern void JointSetUniversalParam(IntPtr j, int parameter, dReal value);
1690
1691 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dLDLTAddTL"), SuppressUnmanagedCodeSecurity]
1692 public static extern void LDLTAddTL(ref dReal L, ref dReal d, ref dReal a, int n, int nskip);
1693
1694 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassAdd"), SuppressUnmanagedCodeSecurity]
1695 public static extern void MassAdd(ref Mass a, ref Mass b);
1696
1697 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassAdjust"), SuppressUnmanagedCodeSecurity]
1698 public static extern void MassAdjust(ref Mass m, dReal newmass);
1699
1700 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassCheck"), SuppressUnmanagedCodeSecurity]
1701 public static extern bool MassCheck(ref Mass m);
1702
1703 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity]
1704 public static extern void MassRotate(ref Mass mass, ref Matrix3 R);
1705
1706 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity]
1707 public static extern void MassRotate(ref Mass mass, ref dReal M00);
1708
1709 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetBox"), SuppressUnmanagedCodeSecurity]
1710 public static extern void MassSetBox(out Mass mass, dReal density, dReal lx, dReal ly, dReal lz);
1711
1712 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetBoxTotal"), SuppressUnmanagedCodeSecurity]
1713 public static extern void MassSetBoxTotal(out Mass mass, dReal total_mass, dReal lx, dReal ly, dReal lz);
1714
1715 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCapsule"), SuppressUnmanagedCodeSecurity]
1716 public static extern void MassSetCapsule(out Mass mass, dReal density, int direction, dReal radius, dReal length);
1717
1718 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCapsuleTotal"), SuppressUnmanagedCodeSecurity]
1719 public static extern void MassSetCapsuleTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length);
1720
1721 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCylinder"), SuppressUnmanagedCodeSecurity]
1722 public static extern void MassSetCylinder(out Mass mass, dReal density, int direction, dReal radius, dReal length);
1723
1724 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCylinderTotal"), SuppressUnmanagedCodeSecurity]
1725 public static extern void MassSetCylinderTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length);
1726
1727 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetParameters"), SuppressUnmanagedCodeSecurity]
1728 public static extern void MassSetParameters(out Mass mass, dReal themass,
1729 dReal cgx, dReal cgy, dReal cgz,
1730 dReal i11, dReal i22, dReal i33,
1731 dReal i12, dReal i13, dReal i23);
1732
1733 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetSphere"), SuppressUnmanagedCodeSecurity]
1734 public static extern void MassSetSphere(out Mass mass, dReal density, dReal radius);
1735
1736 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetSphereTotal"), SuppressUnmanagedCodeSecurity]
1737 public static extern void dMassSetSphereTotal(out Mass mass, dReal total_mass, dReal radius);
1738
1739 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetTrimesh"), SuppressUnmanagedCodeSecurity]
1740 public static extern void MassSetTrimesh(out Mass mass, dReal density, IntPtr g);
1741
1742 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetZero"), SuppressUnmanagedCodeSecurity]
1743 public static extern void MassSetZero(out Mass mass);
1744
1745 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassTranslate"), SuppressUnmanagedCodeSecurity]
1746 public static extern void MassTranslate(ref Mass mass, dReal x, dReal y, dReal z);
1747
1748 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply0"), SuppressUnmanagedCodeSecurity]
1749 public static extern void Multiply0(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r);
1750
1751 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply0"), SuppressUnmanagedCodeSecurity]
1752 private static extern void MultiplyiM3V3(out Vector3 vout, ref Matrix3 matrix, ref Vector3 vect,int p, int q, int r);
1753 public static void MultiplyM3V3(out Vector3 outvector, ref Matrix3 matrix, ref Vector3 invector)
1754 {
1755 MultiplyiM3V3(out outvector, ref matrix, ref invector, 3, 3, 1);
1756 }
1757
1758 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply1"), SuppressUnmanagedCodeSecurity]
1759 public static extern void Multiply1(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r);
1760
1761 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply2"), SuppressUnmanagedCodeSecurity]
1762 public static extern void Multiply2(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r);
1763
1764 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQFromAxisAndAngle"), SuppressUnmanagedCodeSecurity]
1765 public static extern void QFromAxisAndAngle(out Quaternion q, dReal ax, dReal ay, dReal az, dReal angle);
1766
1767 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQfromR"), SuppressUnmanagedCodeSecurity]
1768 public static extern void QfromR(out Quaternion q, ref Matrix3 R);
1769
1770 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply0"), SuppressUnmanagedCodeSecurity]
1771 public static extern void QMultiply0(out Quaternion qa, ref Quaternion qb, ref Quaternion qc);
1772
1773 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply1"), SuppressUnmanagedCodeSecurity]
1774 public static extern void QMultiply1(out Quaternion qa, ref Quaternion qb, ref Quaternion qc);
1775
1776 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply2"), SuppressUnmanagedCodeSecurity]
1777 public static extern void QMultiply2(out Quaternion qa, ref Quaternion qb, ref Quaternion qc);
1778
1779 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply3"), SuppressUnmanagedCodeSecurity]
1780 public static extern void QMultiply3(out Quaternion qa, ref Quaternion qb, ref Quaternion qc);
1781
1782 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQSetIdentity"), SuppressUnmanagedCodeSecurity]
1783 public static extern void QSetIdentity(out Quaternion q);
1784
1785 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity]
1786 public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref Vector3 center, ref Vector3 extents, int depth);
1787
1788 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity]
1789 public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref dReal centerX, ref dReal extentsX, int depth);
1790
1791 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRandReal"), SuppressUnmanagedCodeSecurity]
1792 public static extern dReal RandReal();
1793
1794 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFrom2Axes"), SuppressUnmanagedCodeSecurity]
1795 public static extern void RFrom2Axes(out Matrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz);
1796
1797 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromAxisAndAngle"), SuppressUnmanagedCodeSecurity]
1798 public static extern void RFromAxisAndAngle(out Matrix3 R, dReal x, dReal y, dReal z, dReal angle);
1799
1800 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromEulerAngles"), SuppressUnmanagedCodeSecurity]
1801 public static extern void RFromEulerAngles(out Matrix3 R, dReal phi, dReal theta, dReal psi);
1802
1803 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRfromQ"), SuppressUnmanagedCodeSecurity]
1804 public static extern void RfromQ(out Matrix3 R, ref Quaternion q);
1805
1806 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromZAxis"), SuppressUnmanagedCodeSecurity]
1807 public static extern void RFromZAxis(out Matrix3 R, dReal ax, dReal ay, dReal az);
1808
1809 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRSetIdentity"), SuppressUnmanagedCodeSecurity]
1810 public static extern void RSetIdentity(out Matrix3 R);
1811
1812 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSetValue"), SuppressUnmanagedCodeSecurity]
1813 public static extern void SetValue(out dReal a, int n);
1814
1815 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSetZero"), SuppressUnmanagedCodeSecurity]
1816 public static extern void SetZero(out dReal a, int n);
1817
1818 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSimpleSpaceCreate"), SuppressUnmanagedCodeSecurity]
1819 public static extern IntPtr SimpleSpaceCreate(IntPtr space);
1820
1821 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveCholesky"), SuppressUnmanagedCodeSecurity]
1822 public static extern void SolveCholesky(ref dReal L, out dReal b, int n);
1823
1824 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveL1"), SuppressUnmanagedCodeSecurity]
1825 public static extern void SolveL1(ref dReal L, out dReal b, int n, int nskip);
1826
1827 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveL1T"), SuppressUnmanagedCodeSecurity]
1828 public static extern void SolveL1T(ref dReal L, out dReal b, int n, int nskip);
1829
1830 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveLDLT"), SuppressUnmanagedCodeSecurity]
1831 public static extern void SolveLDLT(ref dReal L, ref dReal d, out dReal b, int n, int nskip);
1832
1833 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceAdd"), SuppressUnmanagedCodeSecurity]
1834 public static extern void SpaceAdd(IntPtr space, IntPtr geom);
1835
1836 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceLockQuery"), SuppressUnmanagedCodeSecurity]
1837 public static extern bool SpaceLockQuery(IntPtr space);
1838
1839 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceClean"), SuppressUnmanagedCodeSecurity]
1840 public static extern void SpaceClean(IntPtr space);
1841
1842 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceCollide"), SuppressUnmanagedCodeSecurity]
1843 public static extern void SpaceCollide(IntPtr space, IntPtr data, NearCallback callback);
1844
1845 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceCollide2"), SuppressUnmanagedCodeSecurity]
1846 public static extern void SpaceCollide2(IntPtr space1, IntPtr space2, IntPtr data, NearCallback callback);
1847
1848 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceDestroy"), SuppressUnmanagedCodeSecurity]
1849 public static extern void SpaceDestroy(IntPtr space);
1850
1851 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetCleanup"), SuppressUnmanagedCodeSecurity]
1852 public static extern bool SpaceGetCleanup(IntPtr space);
1853
1854 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetNumGeoms"), SuppressUnmanagedCodeSecurity]
1855 public static extern int SpaceGetNumGeoms(IntPtr space);
1856
1857 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetGeom"), SuppressUnmanagedCodeSecurity]
1858 public static extern IntPtr SpaceGetGeom(IntPtr space, int i);
1859
1860 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetSublevel"), SuppressUnmanagedCodeSecurity]
1861 public static extern int SpaceGetSublevel(IntPtr space);
1862
1863 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceQuery"), SuppressUnmanagedCodeSecurity]
1864 public static extern bool SpaceQuery(IntPtr space, IntPtr geom);
1865
1866 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceRemove"), SuppressUnmanagedCodeSecurity]
1867 public static extern void SpaceRemove(IntPtr space, IntPtr geom);
1868
1869 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetCleanup"), SuppressUnmanagedCodeSecurity]
1870 public static extern void SpaceSetCleanup(IntPtr space, bool mode);
1871
1872 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity]
1873 public static extern void SpaceSetSublevel(IntPtr space, int sublevel);
1874
1875 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSweepAndPruneSpaceCreate"), SuppressUnmanagedCodeSecurity]
1876 public static extern IntPtr SweepAndPruneSpaceCreate(IntPtr space, int AxisOrder);
1877
1878 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dVectorScale"), SuppressUnmanagedCodeSecurity]
1879 public static extern void VectorScale(out dReal a, ref dReal d, int n);
1880
1881 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldCreate"), SuppressUnmanagedCodeSecurity]
1882 public static extern IntPtr WorldCreate();
1883
1884 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldDestroy"), SuppressUnmanagedCodeSecurity]
1885 public static extern void WorldDestroy(IntPtr world);
1886
1887 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableAverageSamplesCount"), SuppressUnmanagedCodeSecurity]
1888 public static extern int WorldGetAutoDisableAverageSamplesCount(IntPtr world);
1889
1890 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity]
1891 public static extern dReal WorldGetAutoDisableAngularThreshold(IntPtr world);
1892
1893 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity]
1894 public static extern bool WorldGetAutoDisableFlag(IntPtr world);
1895
1896 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity]
1897 public static extern dReal WorldGetAutoDisableLinearThreshold(IntPtr world);
1898
1899 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity]
1900 public static extern int WorldGetAutoDisableSteps(IntPtr world);
1901
1902 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableTime"), SuppressUnmanagedCodeSecurity]
1903 public static extern dReal WorldGetAutoDisableTime(IntPtr world);
1904
1905 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity]
1906 public static extern int WorldGetAutoEnableDepthSF1(IntPtr world);
1907
1908 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetCFM"), SuppressUnmanagedCodeSecurity]
1909 public static extern dReal WorldGetCFM(IntPtr world);
1910
1911 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetERP"), SuppressUnmanagedCodeSecurity]
1912 public static extern dReal WorldGetERP(IntPtr world);
1913
1914 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity]
1915 public static extern void WorldGetGravity(IntPtr world, out Vector3 gravity);
1916
1917 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity]
1918 public static extern void WorldGetGravity(IntPtr world, out dReal X);
1919
1920 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity]
1921 public static extern dReal WorldGetContactMaxCorrectingVel(IntPtr world);
1922
1923 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity]
1924 public static extern dReal WorldGetContactSurfaceLayer(IntPtr world);
1925
1926 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAngularDamping"), SuppressUnmanagedCodeSecurity]
1927 public static extern dReal WorldGetAngularDamping(IntPtr world);
1928
1929 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity]
1930 public static extern dReal WorldGetAngularDampingThreshold(IntPtr world);
1931
1932 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetLinearDamping"), SuppressUnmanagedCodeSecurity]
1933 public static extern dReal WorldGetLinearDamping(IntPtr world);
1934
1935 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity]
1936 public static extern dReal WorldGetLinearDampingThreshold(IntPtr world);
1937
1938 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity]
1939 public static extern int WorldGetQuickStepNumIterations(IntPtr world);
1940
1941 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetQuickStepW"), SuppressUnmanagedCodeSecurity]
1942 public static extern dReal WorldGetQuickStepW(IntPtr world);
1943
1944 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetMaxAngularSpeed"), SuppressUnmanagedCodeSecurity]
1945 public static extern dReal WorldGetMaxAngularSpeed(IntPtr world);
1946
1947 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity]
1948 public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out Vector3 force);
1949
1950 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity]
1951 public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out dReal forceX);
1952
1953 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldQuickStep"), SuppressUnmanagedCodeSecurity]
1954 public static extern void WorldQuickStep(IntPtr world, dReal stepsize);
1955
1956 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAngularDamping"), SuppressUnmanagedCodeSecurity]
1957 public static extern void WorldSetAngularDamping(IntPtr world, dReal scale);
1958
1959 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity]
1960 public static extern void WorldSetAngularDampingThreshold(IntPtr world, dReal threshold);
1961
1962 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity]
1963 public static extern void WorldSetAutoDisableAngularThreshold(IntPtr world, dReal angular_threshold);
1964
1965 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableAverageSamplesCount"), SuppressUnmanagedCodeSecurity]
1966 public static extern void WorldSetAutoDisableAverageSamplesCount(IntPtr world, int average_samples_count);
1967
1968 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableFlag"), SuppressUnmanagedCodeSecurity]
1969 public static extern void WorldSetAutoDisableFlag(IntPtr world, bool do_auto_disable);
1970
1971 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity]
1972 public static extern void WorldSetAutoDisableLinearThreshold(IntPtr world, dReal linear_threshold);
1973
1974 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableSteps"), SuppressUnmanagedCodeSecurity]
1975 public static extern void WorldSetAutoDisableSteps(IntPtr world, int steps);
1976
1977 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableTime"), SuppressUnmanagedCodeSecurity]
1978 public static extern void WorldSetAutoDisableTime(IntPtr world, dReal time);
1979
1980 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity]
1981 public static extern void WorldSetAutoEnableDepthSF1(IntPtr world, int autoEnableDepth);
1982
1983 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetCFM"), SuppressUnmanagedCodeSecurity]
1984 public static extern void WorldSetCFM(IntPtr world, dReal cfm);
1985
1986 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity]
1987 public static extern void WorldSetContactMaxCorrectingVel(IntPtr world, dReal vel);
1988
1989 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity]
1990 public static extern void WorldSetContactSurfaceLayer(IntPtr world, dReal depth);
1991
1992 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetDamping"), SuppressUnmanagedCodeSecurity]
1993 public static extern void WorldSetDamping(IntPtr world, dReal linear_scale, dReal angular_scale);
1994
1995 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetERP"), SuppressUnmanagedCodeSecurity]
1996 public static extern void WorldSetERP(IntPtr world, dReal erp);
1997
1998 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetGravity"), SuppressUnmanagedCodeSecurity]
1999 public static extern void WorldSetGravity(IntPtr world, dReal x, dReal y, dReal z);
2000
2001 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetLinearDamping"), SuppressUnmanagedCodeSecurity]
2002 public static extern void WorldSetLinearDamping(IntPtr world, dReal scale);
2003
2004 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity]
2005 public static extern void WorldSetLinearDampingThreshold(IntPtr world, dReal threshold);
2006
2007 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity]
2008 public static extern void WorldSetQuickStepNumIterations(IntPtr world, int num);
2009
2010 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetQuickStepW"), SuppressUnmanagedCodeSecurity]
2011 public static extern void WorldSetQuickStepW(IntPtr world, dReal over_relaxation);
2012
2013 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetMaxAngularSpeed"), SuppressUnmanagedCodeSecurity]
2014 public static extern void WorldSetMaxAngularSpeed(IntPtr world, dReal max_speed);
2015
2016 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldStep"), SuppressUnmanagedCodeSecurity]
2017 public static extern void WorldStep(IntPtr world, dReal stepsize);
2018
2019 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldStepFast1"), SuppressUnmanagedCodeSecurity]
2020 public static extern void WorldStepFast1(IntPtr world, dReal stepsize, int maxiterations);
2021
2022 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldExportDIF"), SuppressUnmanagedCodeSecurity]
2023 public static extern void WorldExportDIF(IntPtr world, string filename, bool append, string prefix);
2024 }
2025}
diff --git a/OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs b/OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs
index b35c299..98bfd1c 100644
--- a/OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs
+++ b/OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs
@@ -29,7 +29,6 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using OpenMetaverse; 31using OpenMetaverse;
32using Ode.NET;
33using OpenSim.Framework; 32using OpenSim.Framework;
34using OpenSim.Region.PhysicsModules.SharedBase; 33using OpenSim.Region.PhysicsModules.SharedBase;
35using log4net; 34using log4net;
@@ -150,7 +149,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
150 /// Collision geometry 149 /// Collision geometry
151 /// </summary> 150 /// </summary>
152 internal IntPtr Shell { get; private set; } 151 internal IntPtr Shell { get; private set; }
153 152
154 private IntPtr Amotor = IntPtr.Zero; 153 private IntPtr Amotor = IntPtr.Zero;
155 private d.Mass ShellMass; 154 private d.Mass ShellMass;
156 155
@@ -238,7 +237,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
238 m_tainted_isPhysical = true; // new tainted status: need to create ODE information 237 m_tainted_isPhysical = true; // new tainted status: need to create ODE information
239 238
240 _parent_scene.AddPhysicsActorTaint(this); 239 _parent_scene.AddPhysicsActorTaint(this);
241 240
242 Name = avName; 241 Name = avName;
243 } 242 }
244 243
@@ -280,7 +279,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
280 279
281 public override bool IsPhysical 280 public override bool IsPhysical
282 { 281 {
283 get { return false; } 282 get { return m_isPhysical; }
284 set { return; } 283 set { return; }
285 } 284 }
286 285
@@ -462,7 +461,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
462 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; 461 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
463 } 462 }
464 463
465 m_taintPosition = value; 464 m_taintPosition = value;
466 _parent_scene.AddPhysicsActorTaint(this); 465 _parent_scene.AddPhysicsActorTaint(this);
467 } 466 }
468 else 467 else
@@ -595,7 +594,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
595 594
596 public override void delink() {} 595 public override void delink() {}
597 596
598 public override void LockAngularMotion(Vector3 axis) {} 597 public override void LockAngularMotion(byte axislocks) {}
599 598
600// This code is very useful. Written by DanX0r. We're just not using it right now. 599// This code is very useful. Written by DanX0r. We're just not using it right now.
601// Commented out to prevent a warning. 600// Commented out to prevent a warning.
@@ -797,7 +796,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
797 internal void Move(List<OdeCharacter> defects) 796 internal void Move(List<OdeCharacter> defects)
798 { 797 {
799 // no lock; for now it's only called from within Simulate() 798 // no lock; for now it's only called from within Simulate()
800 799
801 // If the PID Controller isn't active then we set our force 800 // If the PID Controller isn't active then we set our force
802 // calculating base velocity to the current position 801 // calculating base velocity to the current position
803 802
@@ -812,7 +811,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
812 811
813 d.Vector3 localpos = d.BodyGetPosition(Body); 812 d.Vector3 localpos = d.BodyGetPosition(Body);
814 Vector3 localPos = new Vector3(localpos.X, localpos.Y, localpos.Z); 813 Vector3 localPos = new Vector3(localpos.X, localpos.Y, localpos.Z);
815 814
816 if (!localPos.IsFinite()) 815 if (!localPos.IsFinite())
817 { 816 {
818 m_log.WarnFormat( 817 m_log.WarnFormat(
@@ -1105,8 +1104,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
1105// lock (OdeScene.UniversalColliderSyncObject) 1104// lock (OdeScene.UniversalColliderSyncObject)
1106 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); 1105 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
1107 1106
1108 d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); 1107 d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories);
1109 d.GeomSetCollideBits(Shell, (int)m_collisionFlags); 1108 d.GeomSetCollideBits(Shell, (uint)m_collisionFlags);
1110 1109
1111 d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH); 1110 d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH);
1112 Body = d.BodyCreate(_parent_scene.world); 1111 Body = d.BodyCreate(_parent_scene.world);
@@ -1249,18 +1248,18 @@ namespace OpenSim.Region.PhysicsModule.ODE
1249 } 1248 }
1250 1249
1251 public override Vector3 PIDTarget { set { return; } } 1250 public override Vector3 PIDTarget { set { return; } }
1252 public override bool PIDActive 1251 public override bool PIDActive
1253 { 1252 {
1254 get { return false; } 1253 get { return false; }
1255 set { return; } 1254 set { return; }
1256 } 1255 }
1257 public override float PIDTau { set { return; } } 1256 public override float PIDTau { set { return; } }
1258 1257
1259 public override float PIDHoverHeight { set { return; } } 1258 public override float PIDHoverHeight { set { return; } }
1260 public override bool PIDHoverActive { set { return; } } 1259 public override bool PIDHoverActive {get {return false;} set { return; } }
1261 public override PIDHoverType PIDHoverType { set { return; } } 1260 public override PIDHoverType PIDHoverType { set { return; } }
1262 public override float PIDHoverTau { set { return; } } 1261 public override float PIDHoverTau { set { return; } }
1263 1262
1264 public override Quaternion APIDTarget{ set { return; } } 1263 public override Quaternion APIDTarget{ set { return; } }
1265 1264
1266 public override bool APIDActive{ set { return; } } 1265 public override bool APIDActive{ set { return; } }
@@ -1291,7 +1290,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1291 m_eventsubscription = 0; 1290 m_eventsubscription = 0;
1292 } 1291 }
1293 1292
1294 internal void AddCollisionEvent(uint CollidedWith, ContactPoint contact) 1293 public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
1295 { 1294 {
1296 if (m_eventsubscription > 0) 1295 if (m_eventsubscription > 0)
1297 { 1296 {
@@ -1370,7 +1369,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1370// m_log.DebugFormat( 1369// m_log.DebugFormat(
1371// "[ODE CHARACTER]: Changing capsule size from {0} to {1} for {2}", 1370// "[ODE CHARACTER]: Changing capsule size from {0} to {1} for {2}",
1372// CAPSULE_LENGTH, m_tainted_CAPSULE_LENGTH, Name); 1371// CAPSULE_LENGTH, m_tainted_CAPSULE_LENGTH, Name);
1373 1372
1374 m_pidControllerActive = true; 1373 m_pidControllerActive = true;
1375 1374
1376 // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() 1375 // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs b/OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs
index 8f8e2bd..7e95d7f 100644
--- a/OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs
+++ b/OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs
@@ -44,10 +44,10 @@ using System.Reflection;
44using System.Runtime.InteropServices; 44using System.Runtime.InteropServices;
45using log4net; 45using log4net;
46using OpenMetaverse; 46using OpenMetaverse;
47using Ode.NET;
48using OpenSim.Framework; 47using OpenSim.Framework;
49using OpenSim.Region.PhysicsModules.SharedBase; 48using OpenSim.Region.PhysicsModules.SharedBase;
50 49
50
51namespace OpenSim.Region.PhysicsModule.ODE 51namespace OpenSim.Region.PhysicsModule.ODE
52{ 52{
53 public class ODEDynamics 53 public class ODEDynamics
@@ -607,6 +607,13 @@ namespace OpenSim.Region.PhysicsModule.ODE
607 m_body = pBody; 607 m_body = pBody;
608 } 608 }
609 609
610 internal void Stop()
611 {
612 m_lastLinearVelocityVector = Vector3.Zero;
613 m_lastAngularVelocity = Vector3.Zero;
614 m_lastPositionVector = d.BodyGetPosition(Body);
615 }
616
610 internal void Step(float pTimestep, OdeScene pParentScene) 617 internal void Step(float pTimestep, OdeScene pParentScene)
611 { 618 {
612 if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) 619 if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
@@ -907,7 +914,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
907 914
908 // Sum velocities 915 // Sum velocities
909 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection 916 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection
910 917
911 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 918 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
912 { 919 {
913 m_lastAngularVelocity.X = 0; 920 m_lastAngularVelocity.X = 0;
diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEModule.cs b/OpenSim/Region/PhysicsModules/Ode/ODEModule.cs
new file mode 100644
index 0000000..22fc84d
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/Ode/ODEModule.cs
@@ -0,0 +1,89 @@
1using System;
2using System.Reflection;
3using log4net;
4using Nini.Config;
5using Mono.Addins;
6using OpenSim.Framework;
7using OpenSim.Region.Framework.Scenes;
8using OpenSim.Region.Framework.Interfaces;
9
10namespace OpenSim.Region.PhysicsModule.ODE
11{
12 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ODEPhysicsScene")]
13 public class OdeModule : INonSharedRegionModule
14 {
15 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
16
17 private bool m_Enabled = false;
18 private IConfigSource m_config;
19 private OdeScene m_scene;
20
21 #region INonSharedRegionModule
22
23 public string Name
24 {
25 get { return "OpenDynamicsEngine"; }
26 }
27
28 public string Version
29 {
30 get { return "1.0"; }
31 }
32
33 public Type ReplaceableInterface
34 {
35 get { return null; }
36 }
37
38 public void Initialise(IConfigSource source)
39 {
40 IConfig config = source.Configs["Startup"];
41 if (config != null)
42 {
43 string physics = config.GetString("physics", string.Empty);
44 if (physics == Name)
45 {
46 m_config = source;
47 m_Enabled = true;
48 }
49 }
50 }
51
52 public void Close()
53 {
54 }
55
56 public void AddRegion(Scene scene)
57 {
58 if (!m_Enabled)
59 return;
60
61 if (Util.IsWindows())
62 Util.LoadArchSpecificWindowsDll("ode.dll");
63
64 // Initializing ODE only when a scene is created allows alternative ODE plugins to co-habit (according to
65 // http://opensimulator.org/mantis/view.php?id=2750).
66 d.InitODE();
67
68 m_scene = new OdeScene(scene, m_config, Name, Version);
69 }
70
71 public void RemoveRegion(Scene scene)
72 {
73 if (!m_Enabled || m_scene == null)
74 return;
75
76 m_scene.Dispose();
77 m_scene = null;
78 }
79
80 public void RegionLoaded(Scene scene)
81 {
82 if (!m_Enabled || m_scene == null)
83 return;
84
85 m_scene.RegionLoaded();
86 }
87 #endregion
88 }
89}
diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs b/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs
index 0b9c45f..8934330 100644
--- a/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs
+++ b/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs
@@ -33,7 +33,7 @@
33 * ODEDynamics.cs contains methods dealing with Prim Physical motion 33 * ODEDynamics.cs contains methods dealing with Prim Physical motion
34 * (dynamics) and the associated settings. Old Linear and angular 34 * (dynamics) and the associated settings. Old Linear and angular
35 * motors for dynamic motion have been replace with MoveLinear() 35 * motors for dynamic motion have been replace with MoveLinear()
36 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic 36 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic
37 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to 37 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
38 * switch between 'VEHICLE' parameter use and general dynamics 38 * switch between 'VEHICLE' parameter use and general dynamics
39 * settings use. 39 * settings use.
@@ -48,7 +48,6 @@ using System.Runtime.InteropServices;
48using System.Threading; 48using System.Threading;
49using log4net; 49using log4net;
50using OpenMetaverse; 50using OpenMetaverse;
51using Ode.NET;
52using OpenSim.Framework; 51using OpenSim.Framework;
53using OpenSim.Region.PhysicsModules.SharedBase; 52using OpenSim.Region.PhysicsModules.SharedBase;
54 53
@@ -83,8 +82,15 @@ namespace OpenSim.Region.PhysicsModule.ODE
83 set 82 set
84 { 83 {
85 m_isphysical = value; 84 m_isphysical = value;
86 if (!m_isphysical) // Zero the remembered last velocity 85 if (!m_isphysical)
86 {
87 _zeroFlag = true; // Zero the remembered last velocity
87 m_lastVelocity = Vector3.Zero; 88 m_lastVelocity = Vector3.Zero;
89 _acceleration = Vector3.Zero;
90 _velocity = Vector3.Zero;
91 m_taintVelocity = Vector3.Zero;
92 m_rotationalVelocity = Vector3.Zero;
93 }
88 } 94 }
89 } 95 }
90 96
@@ -104,10 +110,12 @@ namespace OpenSim.Region.PhysicsModule.ODE
104 private Vector3 m_taintVelocity; 110 private Vector3 m_taintVelocity;
105 private Vector3 m_taintTorque; 111 private Vector3 m_taintTorque;
106 private Quaternion m_taintrot; 112 private Quaternion m_taintrot;
107 private Vector3 m_angularlock = Vector3.One; 113
108 private Vector3 m_taintAngularLock = Vector3.One;
109 private IntPtr Amotor = IntPtr.Zero; 114 private IntPtr Amotor = IntPtr.Zero;
110 115
116 private byte m_taintAngularLock = 0;
117 private byte m_angularlock = 0;
118
111 private bool m_assetFailed = false; 119 private bool m_assetFailed = false;
112 120
113 private Vector3 m_PIDTarget; 121 private Vector3 m_PIDTarget;
@@ -125,7 +133,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
125 private float m_targetHoverHeight; 133 private float m_targetHoverHeight;
126 private float m_groundHeight; 134 private float m_groundHeight;
127 private float m_waterHeight; 135 private float m_waterHeight;
128 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. 136 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
129 137
130 // private float m_tensor = 5f; 138 // private float m_tensor = 5f;
131 private int body_autodisable_frames = 20; 139 private int body_autodisable_frames = 20;
@@ -162,7 +170,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
162 170
163 private PrimitiveBaseShape _pbs; 171 private PrimitiveBaseShape _pbs;
164 private OdeScene _parent_scene; 172 private OdeScene _parent_scene;
165 173
166 /// <summary> 174 /// <summary>
167 /// The physics space which contains prim geometries 175 /// The physics space which contains prim geometries
168 /// </summary> 176 /// </summary>
@@ -195,7 +203,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
195 public int m_interpenetrationcount { get; private set; } 203 public int m_interpenetrationcount { get; private set; }
196 internal float m_collisionscore; 204 internal float m_collisionscore;
197 public int m_roundsUnderMotionThreshold { get; private set; } 205 public int m_roundsUnderMotionThreshold { get; private set; }
198 private int m_crossingfailures;
199 206
200 public bool outofBounds { get; private set; } 207 public bool outofBounds { get; private set; }
201 private float m_density = 10.000006836f; // Aluminum g/cm3; 208 private float m_density = 10.000006836f; // Aluminum g/cm3;
@@ -350,12 +357,12 @@ namespace OpenSim.Region.PhysicsModule.ODE
350 if (m_assetFailed) 357 if (m_assetFailed)
351 { 358 {
352 d.GeomSetCategoryBits(prim_geom, 0); 359 d.GeomSetCategoryBits(prim_geom, 0);
353 d.GeomSetCollideBits(prim_geom, BadMeshAssetCollideBits); 360 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
354 } 361 }
355 else 362 else
356 { 363 {
357 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 364 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
358 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 365 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
359 } 366 }
360 367
361 _parent_scene.geom_name_map[prim_geom] = Name; 368 _parent_scene.geom_name_map[prim_geom] = Name;
@@ -423,7 +430,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
423 if (m_assetFailed) 430 if (m_assetFailed)
424 { 431 {
425 d.GeomSetCategoryBits(prim_geom, 0); 432 d.GeomSetCategoryBits(prim_geom, 0);
426 d.GeomSetCollideBits(prim_geom, BadMeshAssetCollideBits); 433 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
427 } 434 }
428 else 435 else
429 { 436 {
@@ -431,12 +438,12 @@ namespace OpenSim.Region.PhysicsModule.ODE
431 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 438 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
432 } 439 }
433 440
434 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 441 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
435 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 442 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
436 443
437 d.BodySetAutoDisableFlag(Body, true); 444 d.BodySetAutoDisableFlag(Body, true);
438 d.BodySetAutoDisableSteps(Body, body_autodisable_frames); 445 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
439 446
440 // disconnect from world gravity so we can apply buoyancy 447 // disconnect from world gravity so we can apply buoyancy
441 d.BodySetGravityMode (Body, false); 448 d.BodySetGravityMode (Body, false);
442 449
@@ -445,7 +452,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
445 m_disabled = false; 452 m_disabled = false;
446 453
447 // The body doesn't already have a finite rotation mode set here 454 // The body doesn't already have a finite rotation mode set here
448 if ((!m_angularlock.ApproxEquals(Vector3.One, 0.0f)) && _parent == null) 455 if (m_angularlock != 0 && _parent == null)
449 { 456 {
450 createAMotor(m_angularlock); 457 createAMotor(m_angularlock);
451 } 458 }
@@ -467,8 +474,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
467 474
468 float returnMass = 0; 475 float returnMass = 0;
469 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; 476 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
470 float hollowVolume = hollowAmount * hollowAmount; 477 float hollowVolume = hollowAmount * hollowAmount;
471 478
472 switch (_pbs.ProfileShape) 479 switch (_pbs.ProfileShape)
473 { 480 {
474 case ProfileShape.Square: 481 case ProfileShape.Square:
@@ -504,16 +511,16 @@ namespace OpenSim.Region.PhysicsModule.ODE
504 511
505 else if (_pbs.PathCurve == (byte)Extrusion.Curve1) 512 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
506 { 513 {
507 //a tube 514 //a tube
508 515
509 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); 516 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
510 tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY); 517 tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY);
511 volume -= volume*tmp*tmp; 518 volume -= volume*tmp*tmp;
512 519
513 if (hollowAmount > 0.0) 520 if (hollowAmount > 0.0)
514 { 521 {
515 hollowVolume *= hollowAmount; 522 hollowVolume *= hollowAmount;
516 523
517 switch (_pbs.HollowShape) 524 switch (_pbs.HollowShape)
518 { 525 {
519 case HollowShape.Square: 526 case HollowShape.Square:
@@ -572,7 +579,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
572 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); 579 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
573 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); 580 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
574 volume *= (1.0f - tmp * tmp); 581 volume *= (1.0f - tmp * tmp);
575 582
576 if (hollowAmount > 0.0) 583 if (hollowAmount > 0.0)
577 { 584 {
578 585
@@ -816,8 +823,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
816 } 823 }
817 else 824 else
818 { 825 {
819 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 826 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
820 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 827 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
821 } 828 }
822 829
823 d.BodyDestroy(Body); 830 d.BodyDestroy(Body);
@@ -838,7 +845,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
838 else 845 else
839 { 846 {
840 _parent_scene.DeactivatePrim(this); 847 _parent_scene.DeactivatePrim(this);
841 848
842 m_collisionCategories &= ~CollisionCategories.Body; 849 m_collisionCategories &= ~CollisionCategories.Body;
843 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 850 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
844 851
@@ -850,8 +857,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
850 else 857 else
851 { 858 {
852 859
853 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 860 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
854 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 861 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
855 } 862 }
856 863
857 Body = IntPtr.Zero; 864 Body = IntPtr.Zero;
@@ -909,7 +916,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
909 else 916 else
910 { 917 {
911 _triMeshData = d.GeomTriMeshDataCreate(); 918 _triMeshData = d.GeomTriMeshDataCreate();
912 919
913 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 920 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
914 d.GeomTriMeshDataPreprocess(_triMeshData); 921 d.GeomTriMeshDataPreprocess(_triMeshData);
915 m_MeshToTriMeshMap[mesh] = _triMeshData; 922 m_MeshToTriMeshMap[mesh] = _triMeshData;
@@ -919,7 +926,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
919// _parent_scene.waitForSpaceUnlock(m_targetSpace); 926// _parent_scene.waitForSpaceUnlock(m_targetSpace);
920 try 927 try
921 { 928 {
922 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); 929 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null));
923 } 930 }
924 catch (AccessViolationException) 931 catch (AccessViolationException)
925 { 932 {
@@ -967,7 +974,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
967 rotate(); 974 rotate();
968 } 975 }
969 } 976 }
970 977
971 if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent)) 978 if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent))
972 changePhysicsStatus(); 979 changePhysicsStatus();
973 980
@@ -1001,7 +1008,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1001 if (m_taintCollidesWater != m_collidesWater) 1008 if (m_taintCollidesWater != m_collidesWater)
1002 changefloatonwater(); 1009 changefloatonwater();
1003 1010
1004 if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f)) 1011 if (m_taintAngularLock != m_angularlock)
1005 changeAngularLock(); 1012 changeAngularLock();
1006 } 1013 }
1007 1014
@@ -1017,10 +1024,8 @@ Console.WriteLine("ZProcessTaints for " + Name);
1017 //If we have a parent then we're not authorative here 1024 //If we have a parent then we're not authorative here
1018 if (_parent == null) 1025 if (_parent == null)
1019 { 1026 {
1020 if (!m_taintAngularLock.ApproxEquals(Vector3.One, 0f)) 1027 if (m_taintAngularLock != 0)
1021 { 1028 {
1022 //d.BodySetFiniteRotationMode(Body, 0);
1023 //d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z);
1024 createAMotor(m_taintAngularLock); 1029 createAMotor(m_taintAngularLock);
1025 } 1030 }
1026 else 1031 else
@@ -1034,7 +1039,6 @@ Console.WriteLine("ZProcessTaints for " + Name);
1034 } 1039 }
1035 } 1040 }
1036 1041
1037 // Store this for later in case we get turned into a separate body
1038 m_angularlock = m_taintAngularLock; 1042 m_angularlock = m_taintAngularLock;
1039 } 1043 }
1040 1044
@@ -1070,7 +1074,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1070 else if (_parent != null && m_taintparent == null) 1074 else if (_parent != null && m_taintparent == null)
1071 { 1075 {
1072//Console.WriteLine(" changelink B"); 1076//Console.WriteLine(" changelink B");
1073 1077
1074 if (_parent is OdePrim) 1078 if (_parent is OdePrim)
1075 { 1079 {
1076 OdePrim obj = (OdePrim)_parent; 1080 OdePrim obj = (OdePrim)_parent;
@@ -1078,16 +1082,16 @@ Console.WriteLine("ZProcessTaints for " + Name);
1078 childPrim = false; 1082 childPrim = false;
1079 //_parent = null; 1083 //_parent = null;
1080 } 1084 }
1081 1085
1082 /* 1086 /*
1083 if (Body != (IntPtr)0 && _linkJointGroup != (IntPtr)0) 1087 if (Body != (IntPtr)0 && _linkJointGroup != (IntPtr)0)
1084 d.JointGroupDestroy(_linkJointGroup); 1088 d.JointGroupDestroy(_linkJointGroup);
1085 1089
1086 _linkJointGroup = (IntPtr)0; 1090 _linkJointGroup = (IntPtr)0;
1087 m_linkJoint = (IntPtr)0; 1091 m_linkJoint = (IntPtr)0;
1088 */ 1092 */
1089 } 1093 }
1090 1094
1091 _parent = m_taintparent; 1095 _parent = m_taintparent;
1092 m_taintPhysics = IsPhysical; 1096 m_taintPhysics = IsPhysical;
1093 } 1097 }
@@ -1145,12 +1149,12 @@ Console.WriteLine("ZProcessTaints for " + Name);
1145 if (prm.m_assetFailed) 1149 if (prm.m_assetFailed)
1146 { 1150 {
1147 d.GeomSetCategoryBits(prm.prim_geom, 0); 1151 d.GeomSetCategoryBits(prm.prim_geom, 0);
1148 d.GeomSetCollideBits(prm.prim_geom, prm.BadMeshAssetCollideBits); 1152 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.BadMeshAssetCollideBits);
1149 } 1153 }
1150 else 1154 else
1151 { 1155 {
1152 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); 1156 d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
1153 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); 1157 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
1154 } 1158 }
1155 1159
1156 d.Quaternion quat = new d.Quaternion(); 1160 d.Quaternion quat = new d.Quaternion();
@@ -1194,14 +1198,14 @@ Console.WriteLine("ZProcessTaints for " + Name);
1194 if (m_assetFailed) 1198 if (m_assetFailed)
1195 { 1199 {
1196 d.GeomSetCategoryBits(prim_geom, 0); 1200 d.GeomSetCategoryBits(prim_geom, 0);
1197 d.GeomSetCollideBits(prim_geom, BadMeshAssetCollideBits); 1201 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
1198 } 1202 }
1199 else 1203 else
1200 { 1204 {
1201 //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name); 1205 //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name);
1202 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1206 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1203 //Console.WriteLine(" Post GeomSetCategoryBits 2"); 1207 //Console.WriteLine(" Post GeomSetCategoryBits 2");
1204 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1208 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1205 } 1209 }
1206 1210
1207 d.Quaternion quat2 = new d.Quaternion(); 1211 d.Quaternion quat2 = new d.Quaternion();
@@ -1230,7 +1234,8 @@ Console.WriteLine("ZProcessTaints for " + Name);
1230 m_disabled = false; 1234 m_disabled = false;
1231 1235
1232 // The body doesn't already have a finite rotation mode set here 1236 // The body doesn't already have a finite rotation mode set here
1233 if ((!m_angularlock.ApproxEquals(Vector3.One, 0f)) && _parent == null) 1237 // or remove
1238 if (_parent == null)
1234 { 1239 {
1235 createAMotor(m_angularlock); 1240 createAMotor(m_angularlock);
1236 } 1241 }
@@ -1340,7 +1345,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1340 // in between the disabling and the collision properties setting 1345 // in between the disabling and the collision properties setting
1341 // which would wake the physical body up from a soft disabling and potentially cause it to fall 1346 // which would wake the physical body up from a soft disabling and potentially cause it to fall
1342 // through the ground. 1347 // through the ground.
1343 1348
1344 // NOTE FOR JOINTS: this doesn't always work for jointed assemblies because if you select 1349 // NOTE FOR JOINTS: this doesn't always work for jointed assemblies because if you select
1345 // just one part of the assembly, the rest of the assembly is non-selected and still simulating, 1350 // just one part of the assembly, the rest of the assembly is non-selected and still simulating,
1346 // so that causes the selected part to wake up and continue moving. 1351 // so that causes the selected part to wake up and continue moving.
@@ -1354,7 +1359,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1354 // e.g. we select 100 prims that are connected by joints. non-atomically, the first 50 are 1359 // e.g. we select 100 prims that are connected by joints. non-atomically, the first 50 are
1355 // selected and disabled. then, due to a thread switch, the selection processing is 1360 // selected and disabled. then, due to a thread switch, the selection processing is
1356 // interrupted and the physics engine continues to simulate, so the last 50 items, whose 1361 // interrupted and the physics engine continues to simulate, so the last 50 items, whose
1357 // selection was not yet processed, continues to simulate. this wakes up ALL of the 1362 // selection was not yet processed, continues to simulate. this wakes up ALL of the
1358 // first 50 again. then the last 50 are disabled. then the first 50, which were just woken 1363 // first 50 again. then the last 50 are disabled. then the first 50, which were just woken
1359 // up, start simulating again, which in turn wakes up the last 50. 1364 // up, start simulating again, which in turn wakes up the last 50.
1360 1365
@@ -1370,8 +1375,8 @@ Console.WriteLine("ZProcessTaints for " + Name);
1370 } 1375 }
1371 else 1376 else
1372 { 1377 {
1373 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1378 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1374 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1379 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1375 } 1380 }
1376 1381
1377 if (IsPhysical) 1382 if (IsPhysical)
@@ -1396,12 +1401,12 @@ Console.WriteLine("ZProcessTaints for " + Name);
1396 if (m_assetFailed) 1401 if (m_assetFailed)
1397 { 1402 {
1398 d.GeomSetCategoryBits(prim_geom, 0); 1403 d.GeomSetCategoryBits(prim_geom, 0);
1399 d.GeomSetCollideBits(prim_geom, BadMeshAssetCollideBits); 1404 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
1400 } 1405 }
1401 else 1406 else
1402 { 1407 {
1403 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1408 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1404 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1409 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1405 } 1410 }
1406 1411
1407 if (IsPhysical) 1412 if (IsPhysical)
@@ -1560,7 +1565,7 @@ Console.WriteLine("CreateGeom:");
1560 private void changeadd() 1565 private void changeadd()
1561 { 1566 {
1562// m_log.DebugFormat("[ODE PRIM]: Adding prim {0}", Name); 1567// m_log.DebugFormat("[ODE PRIM]: Adding prim {0}", Name);
1563 1568
1564 int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); 1569 int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
1565 IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position); 1570 IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position);
1566 1571
@@ -1686,6 +1691,9 @@ Console.WriteLine(" JointCreateFixed");
1686 float fy = 0; 1691 float fy = 0;
1687 float fz = 0; 1692 float fz = 0;
1688 1693
1694 if (outofBounds)
1695 return;
1696
1689 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. 1697 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
1690 { 1698 {
1691 if (m_vehicle.Type != Vehicle.TYPE_NONE) 1699 if (m_vehicle.Type != Vehicle.TYPE_NONE)
@@ -1697,31 +1705,16 @@ Console.WriteLine(" JointCreateFixed");
1697 { 1705 {
1698//Console.WriteLine("Move " + Name); 1706//Console.WriteLine("Move " + Name);
1699 if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 1707 if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
1700 // NON-'VEHICLES' are dealt with here
1701// if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
1702// {
1703// d.Vector3 avel2 = d.BodyGetAngularVel(Body);
1704// /*
1705// if (m_angularlock.X == 1)
1706// avel2.X = 0;
1707// if (m_angularlock.Y == 1)
1708// avel2.Y = 0;
1709// if (m_angularlock.Z == 1)
1710// avel2.Z = 0;
1711// d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z);
1712// */
1713// }
1714 //float PID_P = 900.0f;
1715 1708
1716 float m_mass = CalculateMass(); 1709 float m_mass = CalculateMass();
1717 1710
1718// fz = 0f; 1711// fz = 0f;
1719 //m_log.Info(m_collisionFlags.ToString()); 1712 //m_log.Info(m_collisionFlags.ToString());
1720 1713
1721 1714
1722 //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. 1715 //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
1723 // would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ?? 1716 // would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ??
1724 // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up 1717 // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up
1725 // gravityz multiplier = 1 - m_buoyancy 1718 // gravityz multiplier = 1 - m_buoyancy
1726 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; 1719 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass;
1727 1720
@@ -1736,7 +1729,7 @@ Console.WriteLine(" JointCreateFixed");
1736 fz = 0f; 1729 fz = 0f;
1737 1730
1738 // no lock; for now it's only called from within Simulate() 1731 // no lock; for now it's only called from within Simulate()
1739 1732
1740 // If the PID Controller isn't active then we set our force 1733 // If the PID Controller isn't active then we set our force
1741 // calculating base velocity to the current position 1734 // calculating base velocity to the current position
1742 1735
@@ -1745,7 +1738,7 @@ Console.WriteLine(" JointCreateFixed");
1745 //PID_G = PID_G / m_PIDTau; 1738 //PID_G = PID_G / m_PIDTau;
1746 m_PIDTau = 1; 1739 m_PIDTau = 1;
1747 } 1740 }
1748 1741
1749 if ((PID_G - m_PIDTau) <= 0) 1742 if ((PID_G - m_PIDTau) <= 0)
1750 { 1743 {
1751 PID_G = m_PIDTau + 1; 1744 PID_G = m_PIDTau + 1;
@@ -1768,7 +1761,7 @@ Console.WriteLine(" JointCreateFixed");
1768 if (_target_velocity.ApproxEquals(Vector3.Zero,0.1f)) 1761 if (_target_velocity.ApproxEquals(Vector3.Zero,0.1f))
1769 { 1762 {
1770 // keep track of where we stopped. No more slippin' & slidin' 1763 // keep track of where we stopped. No more slippin' & slidin'
1771 1764
1772 // We only want to deactivate the PID Controller if we think we want to have our surrogate 1765 // We only want to deactivate the PID Controller if we think we want to have our surrogate
1773 // react to the physics scene by moving it's position. 1766 // react to the physics scene by moving it's position.
1774 // Avatar to Avatar collisions 1767 // Avatar to Avatar collisions
@@ -1789,7 +1782,7 @@ Console.WriteLine(" JointCreateFixed");
1789 // We're flying and colliding with something 1782 // We're flying and colliding with something
1790 fx = ((_target_velocity.X) - vel.X) * (PID_D); 1783 fx = ((_target_velocity.X) - vel.X) * (PID_D);
1791 fy = ((_target_velocity.Y) - vel.Y) * (PID_D); 1784 fy = ((_target_velocity.Y) - vel.Y) * (PID_D);
1792 1785
1793 // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; 1786 // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
1794 1787
1795 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); 1788 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
@@ -1800,7 +1793,7 @@ Console.WriteLine(" JointCreateFixed");
1800 if (m_useHoverPID && !PIDActive) 1793 if (m_useHoverPID && !PIDActive)
1801 { 1794 {
1802//Console.WriteLine("Hover " + Name); 1795//Console.WriteLine("Hover " + Name);
1803 1796
1804 // If we're using the PID controller, then we have no gravity 1797 // If we're using the PID controller, then we have no gravity
1805 fz = (-1 * _parent_scene.gravityz) * m_mass; 1798 fz = (-1 * _parent_scene.gravityz) * m_mass;
1806 1799
@@ -1857,7 +1850,7 @@ Console.WriteLine(" JointCreateFixed");
1857 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) 1850 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
1858 { 1851 {
1859 // keep track of where we stopped. No more slippin' & slidin' 1852 // keep track of where we stopped. No more slippin' & slidin'
1860 1853
1861 // We only want to deactivate the PID Controller if we think we want to have our surrogate 1854 // We only want to deactivate the PID Controller if we think we want to have our surrogate
1862 // react to the physics scene by moving it's position. 1855 // react to the physics scene by moving it's position.
1863 // Avatar to Avatar collisions 1856 // Avatar to Avatar collisions
@@ -1895,7 +1888,7 @@ Console.WriteLine(" JointCreateFixed");
1895 { 1888 {
1896 // A physical body at rest on a surface will auto-disable after a while, 1889 // A physical body at rest on a surface will auto-disable after a while,
1897 // this appears to re-enable it incase the surface it is upon vanishes, 1890 // this appears to re-enable it incase the surface it is upon vanishes,
1898 // and the body should fall again. 1891 // and the body should fall again.
1899 d.BodySetLinearVel(Body, 0f, 0f, 0f); 1892 d.BodySetLinearVel(Body, 0f, 0f, 0f);
1900 d.BodySetForce(Body, 0, 0, 0); 1893 d.BodySetForce(Body, 0, 0, 0);
1901 enableBodySoft(); 1894 enableBodySoft();
@@ -1904,7 +1897,7 @@ Console.WriteLine(" JointCreateFixed");
1904 // 35x10 = 350n times the mass per second applied maximum. 1897 // 35x10 = 350n times the mass per second applied maximum.
1905 float nmax = 35f * m_mass; 1898 float nmax = 35f * m_mass;
1906 float nmin = -35f * m_mass; 1899 float nmin = -35f * m_mass;
1907 1900
1908 if (fx > nmax) 1901 if (fx > nmax)
1909 fx = nmax; 1902 fx = nmax;
1910 if (fx < nmin) 1903 if (fx < nmin)
@@ -1923,7 +1916,7 @@ Console.WriteLine(" JointCreateFixed");
1923 // _zeroPosition = d.BodyGetPosition(Body); 1916 // _zeroPosition = d.BodyGetPosition(Body);
1924 return; 1917 return;
1925//Console.WriteLine("Nothing " + Name); 1918//Console.WriteLine("Nothing " + Name);
1926 1919
1927 } 1920 }
1928 } 1921 }
1929 1922
@@ -1940,8 +1933,8 @@ Console.WriteLine(" JointCreateFixed");
1940 d.BodySetQuaternion(Body, ref myrot); 1933 d.BodySetQuaternion(Body, ref myrot);
1941 if (IsPhysical) 1934 if (IsPhysical)
1942 { 1935 {
1943 if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) 1936 // create or remove locks
1944 createAMotor(m_angularlock); 1937 createAMotor(m_angularlock);
1945 } 1938 }
1946 } 1939 }
1947 else 1940 else
@@ -1949,7 +1942,7 @@ Console.WriteLine(" JointCreateFixed");
1949 // daughter prim, do Geom set 1942 // daughter prim, do Geom set
1950 d.GeomSetQuaternion(prim_geom, ref myrot); 1943 d.GeomSetQuaternion(prim_geom, ref myrot);
1951 } 1944 }
1952 1945
1953 resetCollisionAccounting(); 1946 resetCollisionAccounting();
1954 m_taintrot = _orientation; 1947 m_taintrot = _orientation;
1955 } 1948 }
@@ -2087,7 +2080,7 @@ Console.WriteLine(" JointCreateFixed");
2087 else 2080 else
2088 m_assetFailed = false; 2081 m_assetFailed = false;
2089 } 2082 }
2090 2083
2091 } 2084 }
2092 2085
2093 CreateGeom(m_targetSpace, mesh); 2086 CreateGeom(m_targetSpace, mesh);
@@ -2140,10 +2133,10 @@ Console.WriteLine(" JointCreateFixed");
2140 } 2133 }
2141 2134
2142 if (m_assetFailed) 2135 if (m_assetFailed)
2143 d.GeomSetCollideBits(prim_geom, BadMeshAssetCollideBits); 2136 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
2144 else 2137 else
2145 2138
2146 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 2139 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
2147 } 2140 }
2148 /// <summary> 2141 /// <summary>
2149 /// Change prim in response to a shape taint. 2142 /// Change prim in response to a shape taint.
@@ -2319,7 +2312,7 @@ Console.WriteLine(" JointCreateFixed");
2319 } 2312 }
2320 d.BodyEnable(Body); 2313 d.BodyEnable(Body);
2321 d.BodyAddTorque(Body, iforce.X, iforce.Y, iforce.Z); 2314 d.BodyAddTorque(Body, iforce.X, iforce.Y, iforce.Z);
2322 2315
2323 } 2316 }
2324 m_angularforcelist.Clear(); 2317 m_angularforcelist.Clear();
2325 } 2318 }
@@ -2349,7 +2342,7 @@ Console.WriteLine(" JointCreateFixed");
2349 d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); 2342 d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z);
2350 } 2343 }
2351 } 2344 }
2352 2345
2353 //resetCollisionAccounting(); 2346 //resetCollisionAccounting();
2354 } 2347 }
2355 2348
@@ -2659,16 +2652,46 @@ Console.WriteLine(" JointCreateFixed");
2659 2652
2660 public override void CrossingFailure() 2653 public override void CrossingFailure()
2661 { 2654 {
2662 m_crossingfailures++; 2655 /*
2663 if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds) 2656 m_crossingfailures++;
2664 { 2657 if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds)
2665 base.RaiseOutOfBounds(_position); 2658 {
2666 return; 2659 base.RaiseOutOfBounds(_position);
2667 } 2660 return;
2668 else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds) 2661 }
2662 else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds)
2663 {
2664 m_log.Warn("[PHYSICS]: Too many crossing failures for: " + Name);
2665 }
2666 */
2667
2668 d.AllocateODEDataForThread(0U);
2669
2670 _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f);
2671 _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f);
2672 _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f);
2673
2674 m_lastposition = _position;
2675 _velocity.X = 0;
2676 _velocity.Y = 0;
2677 _velocity.Z = 0;
2678
2679 m_lastVelocity = _velocity;
2680
2681 if (Body != IntPtr.Zero)
2669 { 2682 {
2670 m_log.Warn("[PHYSICS]: Too many crossing failures for: " + Name); 2683 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
2684 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
2671 } 2685 }
2686
2687 if(m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
2688 m_vehicle.Stop(); // this also updates vehicle last position from the body position
2689
2690 enableBodySoft();
2691
2692 outofBounds = false;
2693 base.RequestPhysicsterseUpdate();
2694
2672 } 2695 }
2673 2696
2674 public override float Buoyancy 2697 public override float Buoyancy
@@ -2687,32 +2710,23 @@ Console.WriteLine(" JointCreateFixed");
2687 m_taintparent = null; 2710 m_taintparent = null;
2688 } 2711 }
2689 2712
2690 public override void LockAngularMotion(Vector3 axis) 2713 public override void LockAngularMotion(byte axislocks)
2691 { 2714 {
2692 // reverse the zero/non zero values for ODE. 2715 // m_log.DebugFormat("[axislocks]: {0}", axislocks);
2693 if (axis.IsFinite()) 2716 m_taintAngularLock = axislocks;
2694 {
2695 axis.X = (axis.X > 0) ? 1f : 0f;
2696 axis.Y = (axis.Y > 0) ? 1f : 0f;
2697 axis.Z = (axis.Z > 0) ? 1f : 0f;
2698 m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z);
2699 m_taintAngularLock = axis;
2700 }
2701 else
2702 {
2703 m_log.WarnFormat("[PHYSICS]: Got NaN locking axis from Scene on Object {0}", Name);
2704 }
2705 } 2717 }
2706 2718
2707 internal void UpdatePositionAndVelocity() 2719 internal void UpdatePositionAndVelocity()
2708 { 2720 {
2709 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! 2721 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
2722 if (outofBounds)
2723 return;
2710 if (_parent == null) 2724 if (_parent == null)
2711 { 2725 {
2712 Vector3 pv = Vector3.Zero; 2726 Vector3 pv = Vector3.Zero;
2713 bool lastZeroFlag = _zeroFlag; 2727 bool lastZeroFlag = _zeroFlag;
2714 float m_minvelocity = 0; 2728 float m_minvelocity = 0;
2715 if (Body != (IntPtr)0) // FIXME -> or if it is a joint 2729 if (Body != IntPtr.Zero) // FIXME -> or if it is a joint
2716 { 2730 {
2717 d.Vector3 vec = d.BodyGetPosition(Body); 2731 d.Vector3 vec = d.BodyGetPosition(Body);
2718 d.Quaternion ori = d.BodyGetQuaternion(Body); 2732 d.Quaternion ori = d.BodyGetQuaternion(Body);
@@ -2723,12 +2737,6 @@ Console.WriteLine(" JointCreateFixed");
2723 Vector3 l_position = Vector3.Zero; 2737 Vector3 l_position = Vector3.Zero;
2724 Quaternion l_orientation = Quaternion.Identity; 2738 Quaternion l_orientation = Quaternion.Identity;
2725 2739
2726 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
2727 //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
2728 //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
2729 //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
2730 //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
2731
2732 m_lastposition = _position; 2740 m_lastposition = _position;
2733 m_lastorientation = _orientation; 2741 m_lastorientation = _orientation;
2734 2742
@@ -2740,26 +2748,6 @@ Console.WriteLine(" JointCreateFixed");
2740 l_orientation.Z = ori.Z; 2748 l_orientation.Z = ori.Z;
2741 l_orientation.W = ori.W; 2749 l_orientation.W = ori.W;
2742 2750
2743 if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f)
2744 {
2745 //base.RaiseOutOfBounds(l_position);
2746
2747 if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds)
2748 {
2749 _position = l_position;
2750 //_parent_scene.remActivePrim(this);
2751 if (_parent == null)
2752 base.RequestPhysicsterseUpdate();
2753 return;
2754 }
2755 else
2756 {
2757 if (_parent == null)
2758 base.RaiseOutOfBounds(l_position);
2759 return;
2760 }
2761 }
2762
2763 if (l_position.Z < 0) 2751 if (l_position.Z < 0)
2764 { 2752 {
2765 // This is so prim that get lost underground don't fall forever and suck up 2753 // This is so prim that get lost underground don't fall forever and suck up
@@ -2769,8 +2757,6 @@ Console.WriteLine(" JointCreateFixed");
2769 // It's a hack and will generate a console message if it fails. 2757 // It's a hack and will generate a console message if it fails.
2770 2758
2771 //IsPhysical = false; 2759 //IsPhysical = false;
2772 if (_parent == null)
2773 base.RaiseOutOfBounds(_position);
2774 2760
2775 _acceleration.X = 0; 2761 _acceleration.X = 0;
2776 _acceleration.Y = 0; 2762 _acceleration.Y = 0;
@@ -2784,16 +2770,65 @@ Console.WriteLine(" JointCreateFixed");
2784 m_rotationalVelocity.Z = 0; 2770 m_rotationalVelocity.Z = 0;
2785 2771
2786 if (_parent == null) 2772 if (_parent == null)
2773 base.RaiseOutOfBounds(_position);
2774
2775 if (_parent == null)
2787 base.RequestPhysicsterseUpdate(); 2776 base.RequestPhysicsterseUpdate();
2788 2777
2789 m_throttleUpdates = false; 2778 m_throttleUpdates = false;
2790 throttleCounter = 0; 2779 throttleCounter = 0;
2791 _zeroFlag = true; 2780 _zeroFlag = true;
2792 //outofBounds = true; 2781 //outofBounds = true;
2782 return;
2783 }
2784
2785 if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f)
2786 {
2787 //base.RaiseOutOfBounds(l_position);
2788 /*
2789 if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds)
2790 {
2791 _position = l_position;
2792 //_parent_scene.remActivePrim(this);
2793 if (_parent == null)
2794 base.RequestPhysicsterseUpdate();
2795 return;
2796 }
2797 else
2798 {
2799 if (_parent == null)
2800 base.RaiseOutOfBounds(l_position);
2801 return;
2802 }
2803 */
2804 outofBounds = true;
2805 // part near the border on outside
2806 if (l_position.X < 0)
2807 Util.Clamp(l_position.X, -0.1f, -2f);
2808 else
2809 Util.Clamp(l_position.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
2810 if (l_position.Y < 0)
2811 Util.Clamp(l_position.Y, -0.1f, -2f);
2812 else
2813 Util.Clamp(l_position.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
2814
2815 d.BodySetPosition(Body, l_position.X, l_position.Y, l_position.Z);
2816
2817 // stop it
2818 d.BodySetAngularVel(Body, 0, 0, 0);
2819 d.BodySetLinearVel(Body, 0, 0, 0);
2820 disableBodySoft();
2821
2822 _position = l_position;
2823 // tell framework to fix it
2824 if (_parent == null)
2825 base.RequestPhysicsterseUpdate();
2826 return;
2793 } 2827 }
2794 2828
2829
2795 //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); 2830 //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation));
2796//Console.WriteLine("Adiff " + Name + " = " + Adiff); 2831 //Console.WriteLine("Adiff " + Name + " = " + Adiff);
2797 if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) 2832 if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
2798 && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) 2833 && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
2799 && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) 2834 && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02)
@@ -2864,12 +2899,12 @@ Console.WriteLine(" JointCreateFixed");
2864 _acceleration = ((_velocity - m_lastVelocity) / 0.1f); 2899 _acceleration = ((_velocity - m_lastVelocity) / 0.1f);
2865 _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f); 2900 _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f);
2866 //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString()); 2901 //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString());
2867 2902
2868 // Note here that linearvelocity is affecting angular velocity... so I'm guessing this is a vehicle specific thing... 2903 // Note here that linearvelocity is affecting angular velocity... so I'm guessing this is a vehicle specific thing...
2869 // it does make sense to do this for tiny little instabilities with physical prim, however 0.5m/frame is fairly large. 2904 // it does make sense to do this for tiny little instabilities with physical prim, however 0.5m/frame is fairly large.
2870 // reducing this to 0.02m/frame seems to help the angular rubberbanding quite a bit, however, to make sure it doesn't affect elevators and vehicles 2905 // reducing this to 0.02m/frame seems to help the angular rubberbanding quite a bit, however, to make sure it doesn't affect elevators and vehicles
2871 // adding these logical exclusion situations to maintain this where I think it was intended to be. 2906 // adding these logical exclusion situations to maintain this where I think it was intended to be.
2872 if (m_throttleUpdates || PIDActive || (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) || (Amotor != IntPtr.Zero)) 2907 if (m_throttleUpdates || PIDActive || (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) || (Amotor != IntPtr.Zero))
2873 { 2908 {
2874 m_minvelocity = 0.5f; 2909 m_minvelocity = 0.5f;
2875 } 2910 }
@@ -2938,8 +2973,8 @@ Console.WriteLine(" JointCreateFixed");
2938 { 2973 {
2939 } 2974 }
2940 2975
2941 public override Vector3 PIDTarget 2976 public override Vector3 PIDTarget
2942 { 2977 {
2943 set 2978 set
2944 { 2979 {
2945 if (value.IsFinite()) 2980 if (value.IsFinite())
@@ -2948,16 +2983,17 @@ Console.WriteLine(" JointCreateFixed");
2948 } 2983 }
2949 else 2984 else
2950 m_log.WarnFormat("[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name); 2985 m_log.WarnFormat("[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name);
2951 } 2986 }
2952 } 2987 }
2988
2953 public override bool PIDActive { get; set; } 2989 public override bool PIDActive { get; set; }
2954 public override float PIDTau { set { m_PIDTau = value; } } 2990 public override float PIDTau { set { m_PIDTau = value; } }
2955 2991
2956 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } 2992 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
2957 public override bool PIDHoverActive { set { m_useHoverPID = value; } } 2993 public override bool PIDHoverActive { get { return m_useHoverPID;} set { m_useHoverPID = value; } }
2958 public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } 2994 public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } }
2959 public override float PIDHoverTau { set { m_PIDHoverTau = value; } } 2995 public override float PIDHoverTau { set { m_PIDHoverTau = value; } }
2960 2996
2961 public override Quaternion APIDTarget{ set { return; } } 2997 public override Quaternion APIDTarget{ set { return; } }
2962 2998
2963 public override bool APIDActive{ set { return; } } 2999 public override bool APIDActive{ set { return; } }
@@ -2966,7 +3002,7 @@ Console.WriteLine(" JointCreateFixed");
2966 3002
2967 public override float APIDDamping{ set { return; } } 3003 public override float APIDDamping{ set { return; } }
2968 3004
2969 private void createAMotor(Vector3 axis) 3005 private void createAMotor(byte axislock)
2970 { 3006 {
2971 if (Body == IntPtr.Zero) 3007 if (Body == IntPtr.Zero)
2972 return; 3008 return;
@@ -2977,150 +3013,105 @@ Console.WriteLine(" JointCreateFixed");
2977 Amotor = IntPtr.Zero; 3013 Amotor = IntPtr.Zero;
2978 } 3014 }
2979 3015
2980 float axisnum = 3; 3016 if(axislock == 0)
2981 3017 return;
2982 axisnum = (axisnum - (axis.X + axis.Y + axis.Z));
2983
2984 // PhysicsVector totalSize = new PhysicsVector(_size.X, _size.Y, _size.Z);
2985
2986
2987 // Inverse Inertia Matrix, set the X, Y, and/r Z inertia to 0 then invert it again.
2988 d.Mass objMass;
2989 d.MassSetZero(out objMass);
2990 DMassCopy(ref pMass, ref objMass);
2991
2992 //m_log.DebugFormat("1-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22);
2993
2994 Matrix4 dMassMat = FromDMass(objMass);
2995
2996 Matrix4 mathmat = Inverse(dMassMat);
2997
2998 /*
2999 //m_log.DebugFormat("2-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", mathmat[0, 0], mathmat[0, 1], mathmat[0, 2], mathmat[1, 0], mathmat[1, 1], mathmat[1, 2], mathmat[2, 0], mathmat[2, 1], mathmat[2, 2]);
3000
3001 mathmat = Inverse(mathmat);
3002
3003
3004 objMass = FromMatrix4(mathmat, ref objMass);
3005 //m_log.DebugFormat("3-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22);
3006
3007 mathmat = Inverse(mathmat);
3008 */
3009 if (axis.X == 0)
3010 {
3011 mathmat.M33 = 50.0000001f;
3012 //objMass.I.M22 = 0;
3013 }
3014 if (axis.Y == 0)
3015 {
3016 mathmat.M22 = 50.0000001f;
3017 //objMass.I.M11 = 0;
3018 }
3019 if (axis.Z == 0)
3020 {
3021 mathmat.M11 = 50.0000001f;
3022 //objMass.I.M00 = 0;
3023 }
3024
3025
3026 3018
3027 mathmat = Inverse(mathmat); 3019 int axisnum = 0;
3028 objMass = FromMatrix4(mathmat, ref objMass); 3020 bool axisX = false;
3029 //m_log.DebugFormat("4-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); 3021 bool axisY = false;
3030 3022 bool axisZ = false;
3031 //return; 3023 if((axislock & 0x02) != 0)
3032 if (d.MassCheck(ref objMass)) 3024 {
3033 { 3025 axisnum++;
3034 d.BodySetMass(Body, ref objMass); 3026 axisX = true;
3035 } 3027 }
3036 else 3028 if((axislock & 0x04) != 0)
3037 { 3029 {
3038 //m_log.Debug("[PHYSICS]: Mass invalid, ignoring"); 3030 axisnum++;
3039 } 3031 axisY = true;
3032 }
3033 if((axislock & 0x08) != 0)
3034 {
3035 axisnum++;
3036 axisZ = true;
3037 }
3040 3038
3041 if (axisnum <= 0) 3039 if(axisnum == 0)
3042 return; 3040 return;
3043 // int dAMotorEuler = 1; 3041 // stop it
3042 d.BodySetTorque(Body, 0, 0, 0);
3043 d.BodySetAngularVel(Body, 0, 0, 0);
3044 3044
3045 Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); 3045 Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
3046 d.JointAttach(Amotor, Body, IntPtr.Zero); 3046 d.JointAttach(Amotor, Body, IntPtr.Zero);
3047
3047 d.JointSetAMotorMode(Amotor, 0); 3048 d.JointSetAMotorMode(Amotor, 0);
3048 3049
3049 d.JointSetAMotorNumAxes(Amotor,(int)axisnum); 3050 d.JointSetAMotorNumAxes(Amotor, axisnum);
3050 int i = 0;
3051 3051
3052 if (axis.X == 0) 3052 // get current orientation to lock
3053 {
3054 d.JointSetAMotorAxis(Amotor, i, 0, 1, 0, 0);
3055 i++;
3056 }
3057 3053
3058 if (axis.Y == 0) 3054 d.Quaternion dcur = d.BodyGetQuaternion(Body);
3059 { 3055 Quaternion curr; // crap convertion between identical things
3060 d.JointSetAMotorAxis(Amotor, i, 0, 0, 1, 0); 3056 curr.X = dcur.X;
3061 i++; 3057 curr.Y = dcur.Y;
3062 } 3058 curr.Z = dcur.Z;
3059 curr.W = dcur.W;
3060 Vector3 ax;
3063 3061
3064 if (axis.Z == 0) 3062 int i = 0;
3065 { 3063 int j = 0;
3066 d.JointSetAMotorAxis(Amotor, i, 0, 0, 0, 1); 3064 if (axisX)
3065 {
3066 ax = (new Vector3(1, 0, 0)) * curr; // rotate world X to current local X
3067 d.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z);
3068 d.JointSetAMotorAngle(Amotor, 0, 0);
3069 d.JointSetAMotorParam(Amotor, (int)d.JointParam.LoStop, 0f);
3070 d.JointSetAMotorParam(Amotor, (int)d.JointParam.HiStop, 0f);
3071 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
3072 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f);
3073 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f);
3074 d.JointSetAMotorParam(Amotor, (int)d.JointParam.CFM, 0f);
3075 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f);
3076 d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f);
3077 d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f);
3078 i++;
3079 j = 256; // move to next axis set
3080 }
3081
3082 if (axisY)
3083 {
3084 ax = (new Vector3(0, 1, 0)) * curr;
3085 d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z);
3086 d.JointSetAMotorAngle(Amotor, i, 0);
3087 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f);
3088 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f);
3089 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0);
3090 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
3091 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
3092 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f);
3093 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
3094 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
3095 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
3067 i++; 3096 i++;
3097 j += 256;
3068 } 3098 }
3069 3099
3070 for (int j = 0; j < (int)axisnum; j++) 3100 if (axisZ)
3071 { 3101 {
3072 //d.JointSetAMotorAngle(Amotor, j, 0); 3102 ax = (new Vector3(0, 0, 1)) * curr;
3103 d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z);
3104 d.JointSetAMotorAngle(Amotor, i, 0);
3105 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f);
3106 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f);
3107 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0);
3108 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
3109 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
3110 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f);
3111 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
3112 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
3113 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
3073 } 3114 }
3074
3075 //d.JointSetAMotorAngle(Amotor, 1, 0);
3076 //d.JointSetAMotorAngle(Amotor, 2, 0);
3077
3078 // These lowstops and high stops are effectively (no wiggle room)
3079 d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0f);
3080 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f);
3081 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0f);
3082 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0f);
3083 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f);
3084 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0f);
3085 //d.JointSetAMotorParam(Amotor, (int) dParam.Vel, 9000f);
3086 d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f);
3087 d.JointSetAMotorParam(Amotor, (int)dParam.FMax, Mass * 50f);//
3088 }
3089
3090 private Matrix4 FromDMass(d.Mass pMass)
3091 {
3092 Matrix4 obj;
3093 obj.M11 = pMass.I.M00;
3094 obj.M12 = pMass.I.M01;
3095 obj.M13 = pMass.I.M02;
3096 obj.M14 = 0;
3097 obj.M21 = pMass.I.M10;
3098 obj.M22 = pMass.I.M11;
3099 obj.M23 = pMass.I.M12;
3100 obj.M24 = 0;
3101 obj.M31 = pMass.I.M20;
3102 obj.M32 = pMass.I.M21;
3103 obj.M33 = pMass.I.M22;
3104 obj.M34 = 0;
3105 obj.M41 = 0;
3106 obj.M42 = 0;
3107 obj.M43 = 0;
3108 obj.M44 = 1;
3109 return obj;
3110 }
3111
3112 private d.Mass FromMatrix4(Matrix4 pMat, ref d.Mass obj)
3113 {
3114 obj.I.M00 = pMat[0, 0];
3115 obj.I.M01 = pMat[0, 1];
3116 obj.I.M02 = pMat[0, 2];
3117 obj.I.M10 = pMat[1, 0];
3118 obj.I.M11 = pMat[1, 1];
3119 obj.I.M12 = pMat[1, 2];
3120 obj.I.M20 = pMat[2, 0];
3121 obj.I.M21 = pMat[2, 1];
3122 obj.I.M22 = pMat[2, 2];
3123 return obj;
3124 } 3115 }
3125 3116
3126 public override void SubscribeEvents(int ms) 3117 public override void SubscribeEvents(int ms)
@@ -3135,7 +3126,7 @@ Console.WriteLine(" JointCreateFixed");
3135 m_eventsubscription = 0; 3126 m_eventsubscription = 0;
3136 } 3127 }
3137 3128
3138 public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) 3129 public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
3139 { 3130 {
3140 CollisionEventsThisFrame.AddCollider(CollidedWith, contact); 3131 CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
3141 } 3132 }
@@ -3165,173 +3156,6 @@ Console.WriteLine(" JointCreateFixed");
3165 return false; 3156 return false;
3166 } 3157 }
3167 3158
3168 public static Matrix4 Inverse(Matrix4 pMat)
3169 {
3170 if (determinant3x3(pMat) == 0)
3171 {
3172 return Matrix4.Identity; // should probably throw an error. singluar matrix inverse not possible
3173 }
3174
3175 return (Adjoint(pMat) / determinant3x3(pMat));
3176 }
3177
3178 public static Matrix4 Adjoint(Matrix4 pMat)
3179 {
3180 Matrix4 adjointMatrix = new Matrix4();
3181 for (int i=0; i<4; i++)
3182 {
3183 for (int j=0; j<4; j++)
3184 {
3185 Matrix4SetValue(ref adjointMatrix, i, j, (float)(Math.Pow(-1, i + j) * (determinant3x3(Minor(pMat, i, j)))));
3186 }
3187 }
3188
3189 adjointMatrix = Transpose(adjointMatrix);
3190 return adjointMatrix;
3191 }
3192
3193 public static Matrix4 Minor(Matrix4 matrix, int iRow, int iCol)
3194 {
3195 Matrix4 minor = new Matrix4();
3196 int m = 0, n = 0;
3197 for (int i = 0; i < 4; i++)
3198 {
3199 if (i == iRow)
3200 continue;
3201 n = 0;
3202 for (int j = 0; j < 4; j++)
3203 {
3204 if (j == iCol)
3205 continue;
3206 Matrix4SetValue(ref minor, m,n, matrix[i, j]);
3207 n++;
3208 }
3209 m++;
3210 }
3211
3212 return minor;
3213 }
3214
3215 public static Matrix4 Transpose(Matrix4 pMat)
3216 {
3217 Matrix4 transposeMatrix = new Matrix4();
3218 for (int i = 0; i < 4; i++)
3219 for (int j = 0; j < 4; j++)
3220 Matrix4SetValue(ref transposeMatrix, i, j, pMat[j, i]);
3221 return transposeMatrix;
3222 }
3223
3224 public static void Matrix4SetValue(ref Matrix4 pMat, int r, int c, float val)
3225 {
3226 switch (r)
3227 {
3228 case 0:
3229 switch (c)
3230 {
3231 case 0:
3232 pMat.M11 = val;
3233 break;
3234 case 1:
3235 pMat.M12 = val;
3236 break;
3237 case 2:
3238 pMat.M13 = val;
3239 break;
3240 case 3:
3241 pMat.M14 = val;
3242 break;
3243 }
3244
3245 break;
3246 case 1:
3247 switch (c)
3248 {
3249 case 0:
3250 pMat.M21 = val;
3251 break;
3252 case 1:
3253 pMat.M22 = val;
3254 break;
3255 case 2:
3256 pMat.M23 = val;
3257 break;
3258 case 3:
3259 pMat.M24 = val;
3260 break;
3261 }
3262
3263 break;
3264 case 2:
3265 switch (c)
3266 {
3267 case 0:
3268 pMat.M31 = val;
3269 break;
3270 case 1:
3271 pMat.M32 = val;
3272 break;
3273 case 2:
3274 pMat.M33 = val;
3275 break;
3276 case 3:
3277 pMat.M34 = val;
3278 break;
3279 }
3280
3281 break;
3282 case 3:
3283 switch (c)
3284 {
3285 case 0:
3286 pMat.M41 = val;
3287 break;
3288 case 1:
3289 pMat.M42 = val;
3290 break;
3291 case 2:
3292 pMat.M43 = val;
3293 break;
3294 case 3:
3295 pMat.M44 = val;
3296 break;
3297 }
3298
3299 break;
3300 }
3301 }
3302
3303 private static float determinant3x3(Matrix4 pMat)
3304 {
3305 float det = 0;
3306 float diag1 = pMat[0, 0]*pMat[1, 1]*pMat[2, 2];
3307 float diag2 = pMat[0, 1]*pMat[2, 1]*pMat[2, 0];
3308 float diag3 = pMat[0, 2]*pMat[1, 0]*pMat[2, 1];
3309 float diag4 = pMat[2, 0]*pMat[1, 1]*pMat[0, 2];
3310 float diag5 = pMat[2, 1]*pMat[1, 2]*pMat[0, 0];
3311 float diag6 = pMat[2, 2]*pMat[1, 0]*pMat[0, 1];
3312
3313 det = diag1 + diag2 + diag3 - (diag4 + diag5 + diag6);
3314 return det;
3315 }
3316
3317 private static void DMassCopy(ref d.Mass src, ref d.Mass dst)
3318 {
3319 dst.c.W = src.c.W;
3320 dst.c.X = src.c.X;
3321 dst.c.Y = src.c.Y;
3322 dst.c.Z = src.c.Z;
3323 dst.mass = src.mass;
3324 dst.I.M00 = src.I.M00;
3325 dst.I.M01 = src.I.M01;
3326 dst.I.M02 = src.I.M02;
3327 dst.I.M10 = src.I.M10;
3328 dst.I.M11 = src.I.M11;
3329 dst.I.M12 = src.I.M12;
3330 dst.I.M20 = src.I.M20;
3331 dst.I.M21 = src.I.M21;
3332 dst.I.M22 = src.I.M22;
3333 }
3334
3335 public override void SetMaterial(int pMaterial) 3159 public override void SetMaterial(int pMaterial)
3336 { 3160 {
3337 m_material = pMaterial; 3161 m_material = pMaterial;
@@ -3365,7 +3189,7 @@ Console.WriteLine(" JointCreateFixed");
3365// m_assetFailed = false; 3189// m_assetFailed = false;
3366 3190
3367// m_log.DebugFormat( 3191// m_log.DebugFormat(
3368// "[ODE PRIM]: Received mesh/sculpt data asset {0} with {1} bytes for {2} at {3} in {4}", 3192// "[ODE PRIM]: Received mesh/sculpt data asset {0} with {1} bytes for {2} at {3} in {4}",
3369// _pbs.SculptTexture, _pbs.SculptData.Length, Name, _position, _parent_scene.Name); 3193// _pbs.SculptTexture, _pbs.SculptData.Length, Name, _position, _parent_scene.Name);
3370 3194
3371 m_taintshape = true; 3195 m_taintshape = true;
@@ -3377,6 +3201,6 @@ Console.WriteLine(" JointCreateFixed");
3377 "[ODE PRIM]: Could not get mesh/sculpt asset {0} for {1} at {2} in {3}", 3201 "[ODE PRIM]: Could not get mesh/sculpt asset {0} for {1} at {2} in {3}",
3378 _pbs.SculptTexture, Name, _position, _parent_scene.PhysicsSceneName); 3202 _pbs.SculptTexture, Name, _position, _parent_scene.PhysicsSceneName);
3379 } 3203 }
3380 } 3204 }
3381 } 3205 }
3382} \ No newline at end of file 3206} \ No newline at end of file
diff --git a/OpenSim/Region/PhysicsModules/Ode/ODERayCastRequestManager.cs b/OpenSim/Region/PhysicsModules/Ode/ODERayCastRequestManager.cs
index 8d610f7..78dd7de 100644
--- a/OpenSim/Region/PhysicsModules/Ode/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/PhysicsModules/Ode/ODERayCastRequestManager.cs
@@ -32,7 +32,6 @@ using System.Runtime.InteropServices;
32using System.Text; 32using System.Text;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenSim.Region.PhysicsModules.SharedBase; 34using OpenSim.Region.PhysicsModules.SharedBase;
35using Ode.NET;
36using log4net; 35using log4net;
37 36
38namespace OpenSim.Region.PhysicsModule.ODE 37namespace OpenSim.Region.PhysicsModule.ODE
@@ -76,7 +75,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
76 { 75 {
77 m_scene = pScene; 76 m_scene = pScene;
78 nearCallback = near; 77 nearCallback = near;
79 78
80 } 79 }
81 80
82 /// <summary> 81 /// <summary>
@@ -137,7 +136,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
137 ODERayCastRequest[] reqs = m_PendingRequests.ToArray(); 136 ODERayCastRequest[] reqs = m_PendingRequests.ToArray();
138 for (int i = 0; i < reqs.Length; i++) 137 for (int i = 0; i < reqs.Length; i++)
139 { 138 {
140 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast 139 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
141 RayCast(reqs[i]); // if there isn't anyone to send results 140 RayCast(reqs[i]); // if there isn't anyone to send results
142 } 141 }
143 142
@@ -152,7 +151,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
152 ODERayRequest[] reqs = m_PendingRayRequests.ToArray(); 151 ODERayRequest[] reqs = m_PendingRayRequests.ToArray();
153 for (int i = 0; i < reqs.Length; i++) 152 for (int i = 0; i < reqs.Length; i++)
154 { 153 {
155 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast 154 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
156 RayCast(reqs[i]); // if there isn't anyone to send results 155 RayCast(reqs[i]); // if there isn't anyone to send results
157 } 156 }
158 157
@@ -176,11 +175,11 @@ namespace OpenSim.Region.PhysicsModule.ODE
176 // this value may still be too large, depending on machine configuration 175 // this value may still be too large, depending on machine configuration
177 // of maximum stack 176 // of maximum stack
178 float len = req.length; 177 float len = req.length;
179 if (len > 250f) 178 if (len > 100f)
180 len = 250f; 179 len = 100f;
181 180
182 // Create the ray 181 // Create the ray
183 IntPtr ray = d.CreateRay(m_scene.space, req.length); 182 IntPtr ray = d.CreateRay(m_scene.space, len);
184 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); 183 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
185 184
186 // Collide test 185 // Collide test
@@ -225,8 +224,13 @@ namespace OpenSim.Region.PhysicsModule.ODE
225 /// <param name="req"></param> 224 /// <param name="req"></param>
226 private void RayCast(ODERayRequest req) 225 private void RayCast(ODERayRequest req)
227 { 226 {
227 // limit ray length or collisions will take all avaiable stack space
228 float len = req.length;
229 if (len > 100f)
230 len = 100f;
231
228 // Create the ray 232 // Create the ray
229 IntPtr ray = d.CreateRay(m_scene.space, req.length); 233 IntPtr ray = d.CreateRay(m_scene.space, len);
230 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); 234 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
231 235
232 // Collide test 236 // Collide test
@@ -243,83 +247,22 @@ namespace OpenSim.Region.PhysicsModule.ODE
243 req.callbackMethod(m_contactResults); 247 req.callbackMethod(m_contactResults);
244 } 248 }
245 } 249 }
246 250
247 // This is the standard Near. Uses space AABBs to speed up detection. 251 // This is the standard Near. Uses space AABBs to speed up detection.
248 private void near(IntPtr space, IntPtr g1, IntPtr g2) 252 private void near(IntPtr space, IntPtr g1, IntPtr g2)
249 { 253 {
250 254
251 //Don't test against heightfield Geom, or you'll be sorry!
252
253 /*
254 terminate called after throwing an instance of 'std::bad_alloc'
255 what(): std::bad_alloc
256 Stacktrace:
257
258 at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004>
259 at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff>
260 at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280>
261 at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff
262 fffff>
263 at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004>
264 at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff>
265 at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) <
266 0x00114>
267 at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb>
268 at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6>
269 at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042>
270 at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e>
271 at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019>
272 at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff>
273
274 Native stacktrace:
275
276 mono [0x80d2a42]
277 [0xb7f5840c]
278 /lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018]
279 /usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988]
280 /usr/lib/libstdc++.so.6 [0xb45fa865]
281 /usr/lib/libstdc++.so.6 [0xb45fa8a2]
282 /usr/lib/libstdc++.so.6 [0xb45fa9da]
283 /usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033]
284 /usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d]
285 libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4]
286 libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b]
287 libode.so(dCollide+0x102) [0xb46571b2]
288 [0x95cfdec9]
289 [0x8ea07fe1]
290 [0xab260146]
291 libode.so [0xb465a5c4]
292 libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5]
293 libode.so(dSpaceCollide2+0x177) [0xb465ac67]
294 [0x95cf978e]
295 [0x8ea07945]
296 [0x95cf2bbc]
297 [0xab2787e7]
298 [0xab419fb3]
299 [0xab416657]
300 [0xab415bda]
301 [0xb609b08e]
302 mono(mono_runtime_delegate_invoke+0x34) [0x8192534]
303 mono [0x81a2f0f]
304 mono [0x81d28b6]
305 mono [0x81ea2c6]
306 /lib/i686/cmov/libpthread.so.0 [0xb7e744c0]
307 /lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de]
308 */
309
310 // Exclude heightfield geom
311
312 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) 255 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
313 return; 256 return;
314 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass) 257// if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
315 return; 258// return;
316 259
317 // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. 260 // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
318 if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) 261 if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
319 { 262 {
320 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) 263 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
321 return; 264 return;
322 265
323 // Separating static prim geometry spaces. 266 // Separating static prim geometry spaces.
324 // We'll be calling near recursivly if one 267 // We'll be calling near recursivly if one
325 // of them is a space to find all of the 268 // of them is a space to find all of the
@@ -347,13 +290,13 @@ namespace OpenSim.Region.PhysicsModule.ODE
347 int count = 0; 290 int count = 0;
348 try 291 try
349 { 292 {
350 293
351 if (g1 == g2) 294 if (g1 == g2)
352 return; // Can't collide with yourself 295 return; // Can't collide with yourself
353 296
354 lock (contacts) 297 lock (contacts)
355 { 298 {
356 count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf); 299 count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.unmanagedSizeOf);
357 } 300 }
358 } 301 }
359 catch (SEHException) 302 catch (SEHException)
@@ -383,7 +326,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
383 if (p1 is OdePrim) 326 if (p1 is OdePrim)
384 { 327 {
385 ContactResult collisionresult = new ContactResult(); 328 ContactResult collisionresult = new ContactResult();
386 329
387 collisionresult.ConsumerID = p1.LocalID; 330 collisionresult.ConsumerID = p1.LocalID;
388 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); 331 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
389 collisionresult.Depth = contacts[i].depth; 332 collisionresult.Depth = contacts[i].depth;
@@ -438,4 +381,4 @@ namespace OpenSim.Region.PhysicsModule.ODE
438 public float length; 381 public float length;
439 public RayCallback callbackMethod; 382 public RayCallback callbackMethod;
440 } 383 }
441} \ No newline at end of file 384}
diff --git a/OpenSim/Region/PhysicsModules/Ode/OdePhysicsJoint.cs b/OpenSim/Region/PhysicsModules/Ode/OdePhysicsJoint.cs
index 2eb7ba6..e2578be 100644
--- a/OpenSim/Region/PhysicsModules/Ode/OdePhysicsJoint.cs
+++ b/OpenSim/Region/PhysicsModules/Ode/OdePhysicsJoint.cs
@@ -27,10 +27,8 @@
27 27
28using System; 28using System;
29using OpenMetaverse; 29using OpenMetaverse;
30using Ode.NET;
31using OpenSim.Framework; 30using OpenSim.Framework;
32using OpenSim.Region.PhysicsModules.SharedBase; 31using OpenSim.Region.PhysicsModules.SharedBase;
33using OpenSim.Region.PhysicsModule.ODE;
34 32
35namespace OpenSim.Region.PhysicsModule.ODE 33namespace OpenSim.Region.PhysicsModule.ODE
36{ 34{
diff --git a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs
index 8cc7f28..d15568e 100644
--- a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs
+++ b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs
@@ -31,31 +31,24 @@
31// or application thread stack may just blowup 31// or application thread stack may just blowup
32// see RayCast(ODERayCastRequest req) 32// see RayCast(ODERayCastRequest req)
33 33
34//#define USE_DRAWSTUFF
35//#define SPAM
36
37using System; 34using System;
38using System.Collections.Generic; 35using System.Collections.Generic;
39using System.Diagnostics; 36using System.Diagnostics;
40using System.IO; 37using System.IO;
41using System.Linq; 38using System.Linq;
42using System.Reflection; 39using System.Reflection;
40using System.Runtime.ExceptionServices;
43using System.Runtime.InteropServices; 41using System.Runtime.InteropServices;
44using System.Threading; 42using System.Threading;
45using log4net; 43using log4net;
46using Nini.Config; 44using Nini.Config;
47using Mono.Addins; 45using Mono.Addins;
48using Ode.NET;
49using OpenMetaverse; 46using OpenMetaverse;
50#if USE_DRAWSTUFF
51using Drawstuff.NET;
52#endif
53using OpenSim.Framework; 47using OpenSim.Framework;
54using OpenSim.Region.PhysicsModules.SharedBase; 48using OpenSim.Region.PhysicsModules.SharedBase;
55using OpenSim.Region.Framework.Scenes; 49using OpenSim.Region.Framework.Scenes;
56using OpenSim.Region.Framework.Interfaces; 50using OpenSim.Region.Framework.Interfaces;
57 51
58
59namespace OpenSim.Region.PhysicsModule.ODE 52namespace OpenSim.Region.PhysicsModule.ODE
60{ 53{
61 public enum StatusIndicators : int 54 public enum StatusIndicators : int
@@ -65,16 +58,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
65 End = 2 58 End = 2
66 } 59 }
67 60
68// public struct sCollisionData
69// {
70// public uint ColliderLocalId;
71// public uint CollidedWithLocalId;
72// public int NumberOfCollisions;
73// public int CollisionType;
74// public int StatusIndicator;
75// public int lastframe;
76// }
77
78 [Flags] 61 [Flags]
79 public enum CollisionCategories : int 62 public enum CollisionCategories : int
80 { 63 {
@@ -111,11 +94,9 @@ namespace OpenSim.Region.PhysicsModule.ODE
111 Rubber = 6 94 Rubber = 6
112 } 95 }
113 96
114 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ODEPhysicsScene")] 97 public class OdeScene : PhysicsScene
115 public class OdeScene : PhysicsScene, INonSharedRegionModule
116 { 98 {
117 private readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString()); 99 private readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString());
118 private bool m_Enabled = false;
119 100
120 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); 101 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
121 102
@@ -144,6 +125,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
144 /// .../opensim/bin/libode-x86_64.so(_Z12dCollideCCTLP6dxGeomS0_iP12dContactGeomi+0x92) [0x7f03b44bcf82] 125 /// .../opensim/bin/libode-x86_64.so(_Z12dCollideCCTLP6dxGeomS0_iP12dContactGeomi+0x92) [0x7f03b44bcf82]
145 /// </remarks> 126 /// </remarks>
146 internal static Object UniversalColliderSyncObject = new Object(); 127 internal static Object UniversalColliderSyncObject = new Object();
128 internal static Object SimulationLock = new Object();
147 129
148 /// <summary> 130 /// <summary>
149 /// Is stats collecting enabled for this ODE scene? 131 /// Is stats collecting enabled for this ODE scene?
@@ -276,8 +258,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
276 258
277 private Random fluidRandomizer = new Random(Environment.TickCount); 259 private Random fluidRandomizer = new Random(Environment.TickCount);
278 260
279 public bool m_suportCombine = true;
280
281 private uint m_regionWidth = Constants.RegionSize; 261 private uint m_regionWidth = Constants.RegionSize;
282 private uint m_regionHeight = Constants.RegionSize; 262 private uint m_regionHeight = Constants.RegionSize;
283 263
@@ -293,11 +273,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
293 273
294 private float contactsurfacelayer = 0.001f; 274 private float contactsurfacelayer = 0.001f;
295 275
296 private int worldHashspaceLow = -4; 276 private int HashspaceLow = -5;
297 private int worldHashspaceHigh = 128; 277 private int HashspaceHigh = 12;
298
299 private int smallHashspaceLow = -4;
300 private int smallHashspaceHigh = 66;
301 278
302 private float waterlevel = 0f; 279 private float waterlevel = 0f;
303 private int framecount = 0; 280 private int framecount = 0;
@@ -335,7 +312,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
335 public bool IsAvCapsuleTilted { get; private set; } 312 public bool IsAvCapsuleTilted { get; private set; }
336 313
337 private float avDensity = 80f; 314 private float avDensity = 80f;
338// private float avHeightFudgeFactor = 0.52f;
339 private float avMovementDivisorWalk = 1.3f; 315 private float avMovementDivisorWalk = 1.3f;
340 private float avMovementDivisorRun = 0.8f; 316 private float avMovementDivisorRun = 0.8f;
341 private float minimumGroundFlightOffset = 3f; 317 private float minimumGroundFlightOffset = 3f;
@@ -356,13 +332,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
356 public float bodyPIDD = 35f; 332 public float bodyPIDD = 35f;
357 public float bodyPIDG = 25; 333 public float bodyPIDG = 25;
358 334
359 public int geomCrossingFailuresBeforeOutofbounds = 5;
360
361 public float bodyMotorJointMaxforceTensor = 2;
362
363 public int bodyFramesAutoDisable = 20; 335 public int bodyFramesAutoDisable = 20;
364 336
365 private float[] _watermap;
366 private bool m_filterCollisions = true; 337 private bool m_filterCollisions = true;
367 338
368 private d.NearCallback nearCallback; 339 private d.NearCallback nearCallback;
@@ -473,31 +444,21 @@ namespace OpenSim.Region.PhysicsModule.ODE
473 private d.Contact WaterContact; 444 private d.Contact WaterContact;
474 private d.Contact[,] m_materialContacts; 445 private d.Contact[,] m_materialContacts;
475 446
476//Ckrinke: Comment out until used. We declare it, initialize it, but do not use it
477//Ckrinke private int m_randomizeWater = 200;
478 private int m_physicsiterations = 10; 447 private int m_physicsiterations = 10;
479 private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag 448 private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag
480 private readonly PhysicsActor PANull = new NullPhysicsActor(); 449 private readonly PhysicsActor PANull = new NullPhysicsActor();
481// private float step_time = 0.0f; 450 private float step_time = 0.0f;
482//Ckrinke: Comment out until used. We declare it, initialize it, but do not use it
483//Ckrinke private int ms = 0;
484 public IntPtr world; 451 public IntPtr world;
485 //private bool returncollisions = false;
486 // private uint obj1LocalID = 0;
487 private uint obj2LocalID = 0; 452 private uint obj2LocalID = 0;
488 //private int ctype = 0;
489 private OdeCharacter cc1; 453 private OdeCharacter cc1;
490 private OdePrim cp1; 454 private OdePrim cp1;
491 private OdeCharacter cc2; 455 private OdeCharacter cc2;
492 private OdePrim cp2; 456 private OdePrim cp2;
493 private int p1ExpectedPoints = 0; 457 private int p1ExpectedPoints = 0;
494 private int p2ExpectedPoints = 0; 458 private int p2ExpectedPoints = 0;
495 //private int cStartStop = 0;
496 //private string cDictKey = "";
497 459
498 public IntPtr space; 460 public IntPtr space;
499 461
500 //private IntPtr tmpSpace;
501 // split static geometry collision handling into spaces of 30 meters 462 // split static geometry collision handling into spaces of 30 meters
502 public IntPtr[,] staticPrimspace; 463 public IntPtr[,] staticPrimspace;
503 464
@@ -535,88 +496,37 @@ namespace OpenSim.Region.PhysicsModule.ODE
535 496
536 private ODERayCastRequestManager m_rayCastManager; 497 private ODERayCastRequestManager m_rayCastManager;
537 498
499 public Scene m_frameWorkScene = null;
538 500
539 #region INonSharedRegionModule 501 public OdeScene(Scene pscene, IConfigSource psourceconfig, string pname, string pversion)
540 public string Name
541 {
542 get { return "OpenDynamicsEngine"; }
543 }
544
545 public Type ReplaceableInterface
546 {
547 get { return null; }
548 }
549
550 public void Initialise(IConfigSource source)
551 {
552 // TODO: Move this out of Startup
553 IConfig config = source.Configs["Startup"];
554 if (config != null)
555 {
556 string physics = config.GetString("physics", string.Empty);
557 if (physics == Name)
558 {
559 m_Enabled = true;
560 m_config = source;
561
562 // We do this so that OpenSimulator on Windows loads the correct native ODE library depending on whether
563 // it's running as a 32-bit process or a 64-bit one. By invoking LoadLibary here, later DLLImports
564 // will find it already loaded later on.
565 //
566 // This isn't necessary for other platforms (e.g. Mac OSX and Linux) since the DLL used can be
567 // controlled in Ode.NET.dll.config
568 if (Util.IsWindows())
569 Util.LoadArchSpecificWindowsDll("ode.dll");
570
571 // Initializing ODE only when a scene is created allows alternative ODE plugins to co-habit (according to
572 // http://opensimulator.org/mantis/view.php?id=2750).
573 d.InitODE();
574
575 }
576 }
577
578 }
579
580 public void Close()
581 {
582 }
583
584 public void AddRegion(Scene scene)
585 { 502 {
586 if (!m_Enabled) 503 m_config = psourceconfig;
587 return; 504 m_frameWorkScene = pscene;
588 505
589 EngineType = Name; 506 EngineType = pname;
590 PhysicsSceneName = EngineType + "/" + scene.RegionInfo.RegionName; 507 PhysicsSceneName = EngineType + "/" + pscene.RegionInfo.RegionName;
508 EngineName = pname + " " + pversion;
591 509
592 scene.RegisterModuleInterface<PhysicsScene>(this); 510 pscene.RegisterModuleInterface<PhysicsScene>(this);
593 Vector3 extent = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, scene.RegionInfo.RegionSizeZ); 511 Vector3 extent = new Vector3(pscene.RegionInfo.RegionSizeX, pscene.RegionInfo.RegionSizeY, pscene.RegionInfo.RegionSizeZ);
594 Initialise(extent); 512 Initialise(extent);
595 InitialiseFromConfig(m_config); 513 InitialiseFromConfig(m_config);
596 514
597 // This may not be that good since terrain may not be avaiable at this point 515 // This may not be that good since terrain may not be avaiable at this point
598 base.Initialise(scene.PhysicsRequestAsset, 516 base.Initialise(pscene.PhysicsRequestAsset,
599 (scene.Heightmap != null ? scene.Heightmap.GetFloatsSerialised() : new float[(int)(extent.X * extent.Y)]), 517 (pscene.Heightmap != null ? pscene.Heightmap.GetFloatsSerialised() : new float[(int)(extent.X * extent.Y)]),
600 (float)scene.RegionInfo.RegionSettings.WaterHeight); 518 (float)pscene.RegionInfo.RegionSettings.WaterHeight);
601 519
602 } 520 }
603 521
604 public void RemoveRegion(Scene scene) 522 public void RegionLoaded()
605 { 523 {
606 if (!m_Enabled) 524 mesher = m_frameWorkScene.RequestModuleInterface<IMesher>();
607 return;
608 }
609
610 public void RegionLoaded(Scene scene)
611 {
612 if (!m_Enabled)
613 return;
614
615 mesher = scene.RequestModuleInterface<IMesher>();
616 if (mesher == null) 525 if (mesher == null)
617 m_log.WarnFormat("[ODE SCENE]: No mesher in {0}. Things will not work well.", PhysicsSceneName); 526 m_log.WarnFormat("[ODE SCENE]: No mesher in {0}. Things will not work well.", PhysicsSceneName);
527
528 m_frameWorkScene.PhysicsEnabled = true;
618 } 529 }
619 #endregion
620 530
621 /// <summary> 531 /// <summary>
622 /// Initiailizes the scene 532 /// Initiailizes the scene
@@ -625,16 +535,12 @@ namespace OpenSim.Region.PhysicsModule.ODE
625 /// </summary> 535 /// </summary>
626 private void Initialise(Vector3 regionExtent) 536 private void Initialise(Vector3 regionExtent)
627 { 537 {
628 WorldExtents.X = regionExtent.X; 538 WorldExtents.X = regionExtent.X;
629 m_regionWidth = (uint)regionExtent.X; 539 m_regionWidth = (uint)regionExtent.X;
630 WorldExtents.Y = regionExtent.Y; 540 WorldExtents.Y = regionExtent.Y;
631 m_regionHeight = (uint)regionExtent.Y; 541 m_regionHeight = (uint)regionExtent.Y;
632 542
633 m_suportCombine = false;
634
635 nearCallback = near; 543 nearCallback = near;
636 triCallback = TriCallback;
637 triArrayCallback = TriArrayCallback;
638 m_rayCastManager = new ODERayCastRequestManager(this); 544 m_rayCastManager = new ODERayCastRequestManager(this);
639 545
640 // Create the world and the first space 546 // Create the world and the first space
@@ -644,33 +550,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
644 contactgroup = d.JointGroupCreate(0); 550 contactgroup = d.JointGroupCreate(0);
645 551
646 d.WorldSetAutoDisableFlag(world, false); 552 d.WorldSetAutoDisableFlag(world, false);
647
648 #if USE_DRAWSTUFF
649 Thread viewthread = new Thread(new ParameterizedThreadStart(startvisualization));
650 viewthread.Start();
651 #endif
652
653 // _watermap = new float[258 * 258];
654
655 // Zero out the prim spaces array (we split our space into smaller spaces so
656 // we can hit test less.
657 } 553 }
658 554
659#if USE_DRAWSTUFF
660 public void startvisualization(object o)
661 {
662 ds.Functions fn;
663 fn.version = ds.VERSION;
664 fn.start = new ds.CallbackFunction(start);
665 fn.step = new ds.CallbackFunction(step);
666 fn.command = new ds.CallbackFunction(command);
667 fn.stop = null;
668 fn.path_to_textures = "./textures";
669 string[] args = new string[0];
670 ds.SimulationLoop(args.Length, args, 352, 288, ref fn);
671 }
672#endif
673
674 // Initialize from configs 555 // Initialize from configs
675 private void InitialiseFromConfig(IConfigSource config) 556 private void InitialiseFromConfig(IConfigSource config)
676 { 557 {
@@ -679,18 +560,9 @@ namespace OpenSim.Region.PhysicsModule.ODE
679 m_config = config; 560 m_config = config;
680 // Defaults 561 // Defaults
681 562
682 if (Environment.OSVersion.Platform == PlatformID.Unix) 563 avPIDD = 2200.0f;
683 { 564 avPIDP = 900.0f;
684 avPIDD = 3200.0f; 565 avStandupTensor = 550000f;
685 avPIDP = 1400.0f;
686 avStandupTensor = 2000000f;
687 }
688 else
689 {
690 avPIDD = 2200.0f;
691 avPIDP = 900.0f;
692 avStandupTensor = 550000f;
693 }
694 566
695 int contactsPerCollision = 80; 567 int contactsPerCollision = 80;
696 568
@@ -714,12 +586,10 @@ namespace OpenSim.Region.PhysicsModule.ODE
714 avatarTerminalVelocity, AvatarTerminalVelocity); 586 avatarTerminalVelocity, AvatarTerminalVelocity);
715 } 587 }
716 588
717 worldHashspaceLow = physicsconfig.GetInt("world_hashspace_size_low", -4); 589 HashspaceLow = physicsconfig.GetInt("world_hashspace_level_low", -5);
718 worldHashspaceHigh = physicsconfig.GetInt("world_hashspace_size_high", 128); 590 HashspaceHigh = physicsconfig.GetInt("world_hashspace_level_high", 12);
719 591
720 metersInSpace = physicsconfig.GetFloat("meters_in_small_space", 29.9f); 592 metersInSpace = physicsconfig.GetFloat("meters_in_small_space", 29.9f);
721 smallHashspaceLow = physicsconfig.GetInt("small_hashspace_size_low", -4);
722 smallHashspaceHigh = physicsconfig.GetInt("small_hashspace_size_high", 66);
723 593
724 contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", 0.001f); 594 contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", 0.001f);
725 595
@@ -738,7 +608,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
738 mAvatarObjectContactBounce = physicsconfig.GetFloat("m_avatarobjectcontact_bounce", 0.1f); 608 mAvatarObjectContactBounce = physicsconfig.GetFloat("m_avatarobjectcontact_bounce", 0.1f);
739 609
740 ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); 610 ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE);
741 m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", 10); 611 m_physicsiterations = physicsconfig.GetInt("world_solver_iterations", 10);
742 612
743 avDensity = physicsconfig.GetFloat("av_density", 80f); 613 avDensity = physicsconfig.GetFloat("av_density", 80f);
744// avHeightFudgeFactor = physicsconfig.GetFloat("av_height_fudge_factor", 0.52f); 614// avHeightFudgeFactor = physicsconfig.GetFloat("av_height_fudge_factor", 0.52f);
@@ -754,7 +624,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
754 624
755 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 5); 625 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 5);
756 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); 626 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15);
757 geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
758 627
759 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", 10.000006836f); 628 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", 10.000006836f);
760 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20); 629 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20);
@@ -767,29 +636,16 @@ namespace OpenSim.Region.PhysicsModule.ODE
767 meshSculptLOD = physicsconfig.GetFloat("mesh_lod", 32f); 636 meshSculptLOD = physicsconfig.GetFloat("mesh_lod", 32f);
768 MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", 16f); 637 MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", 16f);
769 m_filterCollisions = physicsconfig.GetBoolean("filter_collisions", false); 638 m_filterCollisions = physicsconfig.GetBoolean("filter_collisions", false);
770
771
772 639
773 if (Environment.OSVersion.Platform == PlatformID.Unix) 640 avPIDD = physicsconfig.GetFloat("av_pid_derivative", 2200.0f);
774 { 641 avPIDP = physicsconfig.GetFloat("av_pid_proportional", 900.0f);
775 avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", 2200.0f); 642 avStandupTensor = physicsconfig.GetFloat("av_capsule_standup_tensor", 550000f);
776 avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", 900.0f);
777 avStandupTensor = physicsconfig.GetFloat("av_capsule_standup_tensor_linux", 550000f);
778 bodyMotorJointMaxforceTensor = physicsconfig.GetFloat("body_motor_joint_maxforce_tensor_linux", 5f);
779 }
780 else
781 {
782 avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", 2200.0f);
783 avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", 900.0f);
784 avStandupTensor = physicsconfig.GetFloat("av_capsule_standup_tensor_win", 550000f);
785 bodyMotorJointMaxforceTensor = physicsconfig.GetFloat("body_motor_joint_maxforce_tensor_win", 5f);
786 }
787 643
788 physics_logging = physicsconfig.GetBoolean("physics_logging", false); 644 physics_logging = physicsconfig.GetBoolean("physics_logging", false);
789 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); 645 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
790 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); 646 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
791 647
792 m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false); 648// m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false);
793 minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); 649 minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f);
794 maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f); 650 maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f);
795 } 651 }
@@ -812,17 +668,15 @@ namespace OpenSim.Region.PhysicsModule.ODE
812 if (spaceGridMaxY > 24) 668 if (spaceGridMaxY > 24)
813 { 669 {
814 spaceGridMaxY = 24; 670 spaceGridMaxY = 24;
815 spacesPerMeterY = spaceGridMaxY / WorldExtents.Y ; 671 spacesPerMeterY = spaceGridMaxY / WorldExtents.Y;
816 } 672 }
817 673
818 staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY]; 674 staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY];
819 675
820 // make this index limits 676 // make this index limits
821 spaceGridMaxX--; 677 spaceGridMaxX--;
822 spaceGridMaxY--; 678 spaceGridMaxY--;
823 679
824
825
826 // Centeral contact friction and bounce 680 // Centeral contact friction and bounce
827 // ckrinke 11/10/08 Enabling soft_erp but not soft_cfm until I figure out why 681 // ckrinke 11/10/08 Enabling soft_erp but not soft_cfm until I figure out why
828 // an avatar falls through in Z but not in X or Y when walking on a prim. 682 // an avatar falls through in Z but not in X or Y when walking on a prim.
@@ -984,7 +838,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
984 m_materialContacts[(int)Material.Rubber, 1].surface.soft_cfm = 0.010f; 838 m_materialContacts[(int)Material.Rubber, 1].surface.soft_cfm = 0.010f;
985 m_materialContacts[(int)Material.Rubber, 1].surface.soft_erp = 0.010f; 839 m_materialContacts[(int)Material.Rubber, 1].surface.soft_erp = 0.010f;
986 840
987 d.HashSpaceSetLevels(space, worldHashspaceLow, worldHashspaceHigh); 841 d.HashSpaceSetLevels(space, HashspaceLow, HashspaceHigh);
988 842
989 // Set the gravity,, don't disable things automatically (we set it explicitly on some things) 843 // Set the gravity,, don't disable things automatically (we set it explicitly on some things)
990 844
@@ -997,9 +851,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
997 d.WorldSetLinearDampingThreshold(world, 256f); 851 d.WorldSetLinearDampingThreshold(world, 256f);
998 d.WorldSetMaxAngularSpeed(world, 256f); 852 d.WorldSetMaxAngularSpeed(world, 256f);
999 853
1000 // Set how many steps we go without running collision testing
1001 // This is in addition to the step size.
1002 // Essentially Steps * m_physicsiterations
1003 d.WorldSetQuickStepNumIterations(world, m_physicsiterations); 854 d.WorldSetQuickStepNumIterations(world, m_physicsiterations);
1004 //d.WorldSetContactMaxCorrectingVel(world, 1000.0f); 855 //d.WorldSetContactMaxCorrectingVel(world, 1000.0f);
1005 856
@@ -1014,22 +865,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
1014 _worldInitialized = true; 865 _worldInitialized = true;
1015 } 866 }
1016 867
1017// internal void waitForSpaceUnlock(IntPtr space)
1018// {
1019// //if (space != IntPtr.Zero)
1020// //while (d.SpaceLockQuery(space)) { } // Wait and do nothing
1021// }
1022
1023// /// <summary>
1024// /// Debug space message for printing the space that a prim/avatar is in.
1025// /// </summary>
1026// /// <param name="pos"></param>
1027// /// <returns>Returns which split up space the given position is in.</returns>
1028// public string whichspaceamIin(Vector3 pos)
1029// {
1030// return calculateSpaceForGeom(pos).ToString();
1031// }
1032
1033 #region Collision Detection 868 #region Collision Detection
1034 869
1035 /// <summary> 870 /// <summary>
@@ -1042,7 +877,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1042 /// <param name='contactsArray'></param> 877 /// <param name='contactsArray'></param>
1043 /// <param name='contactGeomSize'></param> 878 /// <param name='contactGeomSize'></param>
1044 private int CollideGeoms( 879 private int CollideGeoms(
1045 IntPtr geom1, IntPtr geom2, int maxContacts, Ode.NET.d.ContactGeom[] contactsArray, int contactGeomSize) 880 IntPtr geom1, IntPtr geom2, int maxContacts, d.ContactGeom[] contactsArray, int contactGeomSize)
1046 { 881 {
1047 int count; 882 int count;
1048 883
@@ -1113,7 +948,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1113 { 948 {
1114 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) 949 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
1115 return; 950 return;
1116 951
1117 // Separating static prim geometry spaces. 952 // Separating static prim geometry spaces.
1118 // We'll be calling near recursivly if one 953 // We'll be calling near recursivly if one
1119 // of them is a space to find all of the 954 // of them is a space to find all of the
@@ -1155,12 +990,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
1155 name2 = "null"; 990 name2 = "null";
1156 } 991 }
1157 992
1158 //if (id == d.GeomClassId.TriMeshClass)
1159 //{
1160 // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2);
1161 //m_log.Debug("near: A collision was detected between {1} and {2}", 0, name1, name2);
1162 //}
1163
1164 // Figure out how many contact points we have 993 // Figure out how many contact points we have
1165 int count = 0; 994 int count = 0;
1166 995
@@ -1175,7 +1004,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1175 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 1004 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
1176 return; 1005 return;
1177 1006
1178 count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); 1007 count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.unmanagedSizeOf);
1179 1008
1180 // All code after this is only relevant if we have any collisions 1009 // All code after this is only relevant if we have any collisions
1181 if (count <= 0) 1010 if (count <= 0)
@@ -1198,10 +1027,10 @@ namespace OpenSim.Region.PhysicsModule.ODE
1198 1027
1199 PhysicsActor p1; 1028 PhysicsActor p1;
1200 PhysicsActor p2; 1029 PhysicsActor p2;
1201 1030
1202 p1ExpectedPoints = 0; 1031 p1ExpectedPoints = 0;
1203 p2ExpectedPoints = 0; 1032 p2ExpectedPoints = 0;
1204 1033
1205 if (!actor_name_map.TryGetValue(g1, out p1)) 1034 if (!actor_name_map.TryGetValue(g1, out p1))
1206 { 1035 {
1207 p1 = PANull; 1036 p1 = PANull;
@@ -1238,7 +1067,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1238 IntPtr joint; 1067 IntPtr joint;
1239 // If we're colliding with terrain, use 'TerrainContact' instead of contact. 1068 // If we're colliding with terrain, use 'TerrainContact' instead of contact.
1240 // allows us to have different settings 1069 // allows us to have different settings
1241 1070
1242 // We only need to test p2 for 'jump crouch purposes' 1071 // We only need to test p2 for 'jump crouch purposes'
1243 if (p2 is OdeCharacter && p1.PhysicsActorType == (int)ActorTypes.Prim) 1072 if (p2 is OdeCharacter && p1.PhysicsActorType == (int)ActorTypes.Prim)
1244 { 1073 {
@@ -1252,7 +1081,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1252 { 1081 {
1253 p2.IsColliding = true; 1082 p2.IsColliding = true;
1254 } 1083 }
1255 1084
1256 //if ((framecount % m_returncollisions) == 0) 1085 //if ((framecount % m_returncollisions) == 0)
1257 1086
1258 switch (p1.PhysicsActorType) 1087 switch (p1.PhysicsActorType)
@@ -1279,110 +1108,9 @@ namespace OpenSim.Region.PhysicsModule.ODE
1279 // we don't want prim or avatar to explode 1108 // we don't want prim or avatar to explode
1280 1109
1281 #region InterPenetration Handling - Unintended physics explosions 1110 #region InterPenetration Handling - Unintended physics explosions
1282# region disabled code1
1283 1111
1284 if (curContact.depth >= 0.08f) 1112 if (curContact.depth >= 0.08f)
1285 { 1113 {
1286 //This is disabled at the moment only because it needs more tweaking
1287 //It will eventually be uncommented
1288 /*
1289 if (contact.depth >= 1.00f)
1290 {
1291 //m_log.Debug("[PHYSICS]: " + contact.depth.ToString());
1292 }
1293
1294 //If you interpenetrate a prim with an agent
1295 if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
1296 p1.PhysicsActorType == (int) ActorTypes.Prim) ||
1297 (p1.PhysicsActorType == (int) ActorTypes.Agent &&
1298 p2.PhysicsActorType == (int) ActorTypes.Prim))
1299 {
1300
1301 //contact.depth = contact.depth * 4.15f;
1302 /*
1303 if (p2.PhysicsActorType == (int) ActorTypes.Agent)
1304 {
1305 p2.CollidingObj = true;
1306 contact.depth = 0.003f;
1307 p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f);
1308 OdeCharacter character = (OdeCharacter) p2;
1309 character.SetPidStatus(true);
1310 contact.pos = new d.Vector3(contact.pos.X + (p1.Size.X / 2), contact.pos.Y + (p1.Size.Y / 2), contact.pos.Z + (p1.Size.Z / 2));
1311
1312 }
1313 else
1314 {
1315
1316 //contact.depth = 0.0000000f;
1317 }
1318 if (p1.PhysicsActorType == (int) ActorTypes.Agent)
1319 {
1320
1321 p1.CollidingObj = true;
1322 contact.depth = 0.003f;
1323 p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f);
1324 contact.pos = new d.Vector3(contact.pos.X + (p2.Size.X / 2), contact.pos.Y + (p2.Size.Y / 2), contact.pos.Z + (p2.Size.Z / 2));
1325 OdeCharacter character = (OdeCharacter)p1;
1326 character.SetPidStatus(true);
1327 }
1328 else
1329 {
1330
1331 //contact.depth = 0.0000000f;
1332 }
1333
1334
1335
1336 }
1337*/
1338 // If you interpenetrate a prim with another prim
1339 /*
1340 if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim)
1341 {
1342 #region disabledcode2
1343 //OdePrim op1 = (OdePrim)p1;
1344 //OdePrim op2 = (OdePrim)p2;
1345 //op1.m_collisionscore++;
1346 //op2.m_collisionscore++;
1347
1348 //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000)
1349 //{
1350 //op1.m_taintdisable = true;
1351 //AddPhysicsActorTaint(p1);
1352 //op2.m_taintdisable = true;
1353 //AddPhysicsActorTaint(p2);
1354 //}
1355
1356 //if (contact.depth >= 0.25f)
1357 //{
1358 // Don't collide, one or both prim will expld.
1359
1360 //op1.m_interpenetrationcount++;
1361 //op2.m_interpenetrationcount++;
1362 //interpenetrations_before_disable = 200;
1363 //if (op1.m_interpenetrationcount >= interpenetrations_before_disable)
1364 //{
1365 //op1.m_taintdisable = true;
1366 //AddPhysicsActorTaint(p1);
1367 //}
1368 //if (op2.m_interpenetrationcount >= interpenetrations_before_disable)
1369 //{
1370 // op2.m_taintdisable = true;
1371 //AddPhysicsActorTaint(p2);
1372 //}
1373
1374 //contact.depth = contact.depth / 8f;
1375 //contact.normal = new d.Vector3(0, 0, 1);
1376 //}
1377 //if (op1.m_disabled || op2.m_disabled)
1378 //{
1379 //Manually disabled objects stay disabled
1380 //contact.depth = 0f;
1381 //}
1382 #endregion
1383 }
1384 */
1385#endregion
1386 if (curContact.depth >= 1.00f) 1114 if (curContact.depth >= 1.00f)
1387 { 1115 {
1388 //m_log.Info("[P]: " + contact.depth.ToString()); 1116 //m_log.Info("[P]: " + contact.depth.ToString());
@@ -1432,7 +1160,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1432 1160
1433 // Logic for collision handling 1161 // Logic for collision handling
1434 // Note, that if *all* contacts are skipped (VolumeDetect) 1162 // Note, that if *all* contacts are skipped (VolumeDetect)
1435 // The prim still detects (and forwards) collision events but 1163 // The prim still detects (and forwards) collision events but
1436 // appears to be phantom for the world 1164 // appears to be phantom for the world
1437 Boolean skipThisContact = false; 1165 Boolean skipThisContact = false;
1438 1166
@@ -1507,10 +1235,10 @@ namespace OpenSim.Region.PhysicsModule.ODE
1507 material = ((OdePrim) p2).m_material; 1235 material = ((OdePrim) p2).m_material;
1508 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; 1236 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
1509 } 1237 }
1510 1238
1511 // Unnessesary because p1 is defined above 1239 // Unnessesary because p1 is defined above
1512 //if (p1 is OdePrim) 1240 //if (p1 is OdePrim)
1513 // { 1241 // {
1514 // p1ExpectedPoints = ((OdePrim)p1).ExpectedCollisionContacts; 1242 // p1ExpectedPoints = ((OdePrim)p1).ExpectedCollisionContacts;
1515 // } 1243 // }
1516 //m_log.DebugFormat("Material: {0}", material); 1244 //m_log.DebugFormat("Material: {0}", material);
@@ -1622,7 +1350,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1622 material = ((OdePrim)p2).m_material; 1350 material = ((OdePrim)p2).m_material;
1623 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; 1351 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
1624 } 1352 }
1625 1353
1626 //m_log.DebugFormat("Material: {0}", material); 1354 //m_log.DebugFormat("Material: {0}", material);
1627 m_materialContacts[material, 0].geom = curContact; 1355 m_materialContacts[material, 0].geom = curContact;
1628 1356
@@ -1642,7 +1370,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1642 } 1370 }
1643 1371
1644 collision_accounting_events(p1, p2, maxDepthContact); 1372 collision_accounting_events(p1, p2, maxDepthContact);
1645 1373
1646 if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle)) 1374 if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle))
1647 { 1375 {
1648 // If there are more then 3 contact points, it's likely 1376 // If there are more then 3 contact points, it's likely
@@ -1678,31 +1406,13 @@ namespace OpenSim.Region.PhysicsModule.ODE
1678 { 1406 {
1679 if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f) 1407 if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f)
1680 { 1408 {
1681 //contactGeom.depth *= .00005f; 1409 result = true;
1682 //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); 1410 break;
1683 // m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z));
1684 result = true;
1685 break;
1686 } 1411 }
1687// else
1688// {
1689// //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth));
1690// }
1691 } 1412 }
1692// else 1413 }
1693// {
1694// //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z));
1695// //int i = 0;
1696// }
1697 }
1698 else if (at == ActorTypes.Prim) 1414 else if (at == ActorTypes.Prim)
1699 { 1415 {
1700 //d.AABB aabb1 = new d.AABB();
1701 //d.AABB aabb2 = new d.AABB();
1702
1703 //d.GeomGetAABB(contactGeom.g2, out aabb2);
1704 //d.GeomGetAABB(contactGeom.g1, out aabb1);
1705 //aabb1.
1706 if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f))) 1416 if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)))
1707 { 1417 {
1708 if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z) 1418 if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z)
@@ -1729,9 +1439,28 @@ namespace OpenSim.Region.PhysicsModule.ODE
1729 obj2LocalID = 0; 1439 obj2LocalID = 0;
1730 //ctype = 0; 1440 //ctype = 0;
1731 //cStartStop = 0; 1441 //cStartStop = 0;
1732 if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) 1442// if (!p2.SubscribedEvents() && !p1.SubscribedEvents())
1443// return;
1444 bool p1events = p1.SubscribedEvents();
1445 bool p2events = p2.SubscribedEvents();
1446
1447 if (p1.IsVolumeDtc)
1448 p2events = false;
1449 if (p2.IsVolumeDtc)
1450 p1events = false;
1451
1452 if (!p2events && !p1events)
1733 return; 1453 return;
1734 1454
1455 Vector3 vel = Vector3.Zero;
1456 if (p2 != null && p2.IsPhysical)
1457 vel = p2.Velocity;
1458
1459 if (p1 != null && p1.IsPhysical)
1460 vel -= p1.Velocity;
1461
1462 contact.RelativeSpeed = Vector3.Dot(vel, contact.SurfaceNormal);
1463
1735 switch ((ActorTypes)p2.PhysicsActorType) 1464 switch ((ActorTypes)p2.PhysicsActorType)
1736 { 1465 {
1737 case ActorTypes.Agent: 1466 case ActorTypes.Agent:
@@ -1744,14 +1473,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
1744 cc1 = (OdeCharacter)p1; 1473 cc1 = (OdeCharacter)p1;
1745 obj2LocalID = cc1.LocalID; 1474 obj2LocalID = cc1.LocalID;
1746 cc1.AddCollisionEvent(cc2.LocalID, contact); 1475 cc1.AddCollisionEvent(cc2.LocalID, contact);
1747 //ctype = (int)CollisionCategories.Character;
1748
1749 //if (cc1.CollidingObj)
1750 //cStartStop = (int)StatusIndicators.Generic;
1751 //else
1752 //cStartStop = (int)StatusIndicators.Start;
1753
1754 //returncollisions = true;
1755 break; 1476 break;
1756 1477
1757 case ActorTypes.Prim: 1478 case ActorTypes.Prim:
@@ -1761,21 +1482,11 @@ namespace OpenSim.Region.PhysicsModule.ODE
1761 obj2LocalID = cp1.LocalID; 1482 obj2LocalID = cp1.LocalID;
1762 cp1.AddCollisionEvent(cc2.LocalID, contact); 1483 cp1.AddCollisionEvent(cc2.LocalID, contact);
1763 } 1484 }
1764 //ctype = (int)CollisionCategories.Geom;
1765
1766 //if (cp1.CollidingObj)
1767 //cStartStop = (int)StatusIndicators.Generic;
1768 //else
1769 //cStartStop = (int)StatusIndicators.Start;
1770
1771 //returncollisions = true;
1772 break; 1485 break;
1773 1486
1774 case ActorTypes.Ground: 1487 case ActorTypes.Ground:
1775 case ActorTypes.Unknown: 1488 case ActorTypes.Unknown:
1776 obj2LocalID = 0; 1489 obj2LocalID = 0;
1777 //ctype = (int)CollisionCategories.Land;
1778 //returncollisions = true;
1779 break; 1490 break;
1780 } 1491 }
1781 1492
@@ -1797,13 +1508,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
1797 cc1 = (OdeCharacter) p1; 1508 cc1 = (OdeCharacter) p1;
1798 obj2LocalID = cc1.LocalID; 1509 obj2LocalID = cc1.LocalID;
1799 cc1.AddCollisionEvent(cp2.LocalID, contact); 1510 cc1.AddCollisionEvent(cp2.LocalID, contact);
1800 //ctype = (int)CollisionCategories.Character;
1801
1802 //if (cc1.CollidingObj)
1803 //cStartStop = (int)StatusIndicators.Generic;
1804 //else
1805 //cStartStop = (int)StatusIndicators.Start;
1806 //returncollisions = true;
1807 } 1511 }
1808 break; 1512 break;
1809 case ActorTypes.Prim: 1513 case ActorTypes.Prim:
@@ -1813,23 +1517,12 @@ namespace OpenSim.Region.PhysicsModule.ODE
1813 cp1 = (OdePrim) p1; 1517 cp1 = (OdePrim) p1;
1814 obj2LocalID = cp1.LocalID; 1518 obj2LocalID = cp1.LocalID;
1815 cp1.AddCollisionEvent(cp2.LocalID, contact); 1519 cp1.AddCollisionEvent(cp2.LocalID, contact);
1816 //ctype = (int)CollisionCategories.Geom;
1817
1818 //if (cp1.CollidingObj)
1819 //cStartStop = (int)StatusIndicators.Generic;
1820 //else
1821 //cStartStop = (int)StatusIndicators.Start;
1822
1823 //returncollisions = true;
1824 } 1520 }
1825 break; 1521 break;
1826 1522
1827 case ActorTypes.Ground: 1523 case ActorTypes.Ground:
1828 case ActorTypes.Unknown: 1524 case ActorTypes.Unknown:
1829 obj2LocalID = 0; 1525 obj2LocalID = 0;
1830 //ctype = (int)CollisionCategories.Land;
1831
1832 //returncollisions = true;
1833 break; 1526 break;
1834 } 1527 }
1835 1528
@@ -1837,80 +1530,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1837 } 1530 }
1838 break; 1531 break;
1839 } 1532 }
1840 //if (returncollisions)
1841 //{
1842
1843 //lock (m_storedCollisions)
1844 //{
1845 //cDictKey = obj1LocalID.ToString() + obj2LocalID.ToString() + cStartStop.ToString() + ctype.ToString();
1846 //if (m_storedCollisions.ContainsKey(cDictKey))
1847 //{
1848 //sCollisionData objd = m_storedCollisions[cDictKey];
1849 //objd.NumberOfCollisions += 1;
1850 //objd.lastframe = framecount;
1851 //m_storedCollisions[cDictKey] = objd;
1852 //}
1853 //else
1854 //{
1855 //sCollisionData objd = new sCollisionData();
1856 //objd.ColliderLocalId = obj1LocalID;
1857 //objd.CollidedWithLocalId = obj2LocalID;
1858 //objd.CollisionType = ctype;
1859 //objd.NumberOfCollisions = 1;
1860 //objd.lastframe = framecount;
1861 //objd.StatusIndicator = cStartStop;
1862 //m_storedCollisions.Add(cDictKey, objd);
1863 //}
1864 //}
1865 // }
1866 }
1867
1868 private int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount)
1869 {
1870 /* String name1 = null;
1871 String name2 = null;
1872
1873 if (!geom_name_map.TryGetValue(trimesh, out name1))
1874 {
1875 name1 = "null";
1876 }
1877 if (!geom_name_map.TryGetValue(refObject, out name2))
1878 {
1879 name2 = "null";
1880 }
1881
1882 m_log.InfoFormat("TriArrayCallback: A collision was detected between {1} and {2}", 0, name1, name2);
1883 */
1884 return 1;
1885 }
1886
1887 private int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex)
1888 {
1889// String name1 = null;
1890// String name2 = null;
1891//
1892// if (!geom_name_map.TryGetValue(trimesh, out name1))
1893// {
1894// name1 = "null";
1895// }
1896//
1897// if (!geom_name_map.TryGetValue(refObject, out name2))
1898// {
1899// name2 = "null";
1900// }
1901
1902 // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex);
1903
1904 d.Vector3 v0 = new d.Vector3();
1905 d.Vector3 v1 = new d.Vector3();
1906 d.Vector3 v2 = new d.Vector3();
1907
1908 d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2);
1909 // m_log.DebugFormat("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z);
1910
1911 return 1;
1912 } 1533 }
1913
1914 /// <summary> 1534 /// <summary>
1915 /// This is our collision testing routine in ODE 1535 /// This is our collision testing routine in ODE
1916 /// </summary> 1536 /// </summary>
@@ -1924,11 +1544,11 @@ namespace OpenSim.Region.PhysicsModule.ODE
1924 // since we don't know if we're colliding yet 1544 // since we don't know if we're colliding yet
1925 if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) 1545 if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
1926 continue; 1546 continue;
1927 1547
1928 chr.IsColliding = false; 1548 chr.IsColliding = false;
1929 chr.CollidingGround = false; 1549 chr.CollidingGround = false;
1930 chr.CollidingObj = false; 1550 chr.CollidingObj = false;
1931 1551
1932 // Test the avatar's geometry for collision with the space 1552 // Test the avatar's geometry for collision with the space
1933 // This will return near and the space that they are the closest to 1553 // This will return near and the space that they are the closest to
1934 // And we'll run this again against the avatar and the space segment 1554 // And we'll run this again against the avatar and the space segment
@@ -1942,7 +1562,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
1942 { 1562 {
1943 m_log.ErrorFormat("[ODE SCENE]: Unable to space collide {0}", PhysicsSceneName); 1563 m_log.ErrorFormat("[ODE SCENE]: Unable to space collide {0}", PhysicsSceneName);
1944 } 1564 }
1945 1565
1946 //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y); 1566 //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y);
1947 //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10) 1567 //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10)
1948 //{ 1568 //{
@@ -2003,15 +1623,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
2003 1623
2004 #endregion 1624 #endregion
2005 1625
2006 public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
2007 {
2008 if (!m_suportCombine)
2009 return;
2010 m_worldOffset = offset;
2011 WorldExtents = new Vector2(extents.X, extents.Y);
2012 m_parentScene = pScene;
2013 }
2014
2015 // Recovered for use by fly height. Kitto Flora 1626 // Recovered for use by fly height. Kitto Flora
2016 internal float GetTerrainHeightAtXY(float x, float y) 1627 internal float GetTerrainHeightAtXY(float x, float y)
2017 { 1628 {
@@ -2019,12 +1630,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
2019 int offsetX = 0; 1630 int offsetX = 0;
2020 int offsetY = 0; 1631 int offsetY = 0;
2021 1632
2022 if (m_suportCombine)
2023 {
2024 offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
2025 offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
2026 }
2027
2028 if(RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom)) 1633 if(RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom))
2029 { 1634 {
2030 if (heightFieldGeom != IntPtr.Zero) 1635 if (heightFieldGeom != IntPtr.Zero)
@@ -2042,14 +1647,15 @@ namespace OpenSim.Region.PhysicsModule.ODE
2042 x = x - offsetX + 1f; 1647 x = x - offsetX + 1f;
2043 y = y - offsetY + 1f; 1648 y = y - offsetY + 1f;
2044 1649
2045 index = (int)((int)x * ((int)m_regionHeight +3) + (int)y); 1650 // map is rotated
1651 index = (int)x * ((int)m_regionHeight + 3) + (int)y;
2046 1652
2047 if (index < TerrainHeightFieldHeights[heightFieldGeom].Length) 1653 if (index < TerrainHeightFieldHeights[heightFieldGeom].Length)
2048 { 1654 {
2049 //m_log.DebugFormat("x{0} y{1} = {2}", x, y, (float)TerrainHeightFieldHeights[heightFieldGeom][index]); 1655 //m_log.DebugFormat("x{0} y{1} = {2}", x, y, (float)TerrainHeightFieldHeights[heightFieldGeom][index]);
2050 return (float)TerrainHeightFieldHeights[heightFieldGeom][index]; 1656 return (float)TerrainHeightFieldHeights[heightFieldGeom][index];
2051 } 1657 }
2052 1658
2053 else 1659 else
2054 return 0f; 1660 return 0f;
2055 } 1661 }
@@ -2069,7 +1675,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
2069 { 1675 {
2070 return 0f; 1676 return 0f;
2071 } 1677 }
2072 } 1678 }
2073// End recovered. Kitto Flora 1679// End recovered. Kitto Flora
2074 1680
2075 /// <summary> 1681 /// <summary>
@@ -2079,7 +1685,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
2079 internal void AddCollisionEventReporting(PhysicsActor obj) 1685 internal void AddCollisionEventReporting(PhysicsActor obj)
2080 { 1686 {
2081// m_log.DebugFormat("[PHYSICS]: Adding {0} {1} to collision event reporting", obj.SOPName, obj.LocalID); 1687// m_log.DebugFormat("[PHYSICS]: Adding {0} {1} to collision event reporting", obj.SOPName, obj.LocalID);
2082 1688
2083 lock (m_collisionEventActorsChanges) 1689 lock (m_collisionEventActorsChanges)
2084 m_collisionEventActorsChanges[obj.LocalID] = obj; 1690 m_collisionEventActorsChanges[obj.LocalID] = obj;
2085 } 1691 }
@@ -2099,7 +1705,9 @@ namespace OpenSim.Region.PhysicsModule.ODE
2099 #region Add/Remove Entities 1705 #region Add/Remove Entities
2100 1706
2101 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) 1707 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
2102 { 1708 {
1709 d.AllocateODEDataForThread(0);
1710
2103 OdeCharacter newAv 1711 OdeCharacter newAv
2104 = new OdeCharacter( 1712 = new OdeCharacter(
2105 avName, this, position, velocity, size, avPIDD, avPIDP, 1713 avName, this, position, velocity, size, avPIDD, avPIDP,
@@ -2119,7 +1727,12 @@ namespace OpenSim.Region.PhysicsModule.ODE
2119// "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2}", 1727// "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2}",
2120// actor.Name, actor.LocalID, Name); 1728// actor.Name, actor.LocalID, Name);
2121 1729
2122 ((OdeCharacter) actor).Destroy(); 1730 lock (OdeLock)
1731 {
1732 d.AllocateODEDataForThread(0);
1733
1734 ((OdeCharacter) actor).Destroy();
1735 }
2123 } 1736 }
2124 1737
2125 internal void AddCharacter(OdeCharacter chr) 1738 internal void AddCharacter(OdeCharacter chr)
@@ -2169,9 +1782,11 @@ namespace OpenSim.Region.PhysicsModule.ODE
2169 Vector3 siz = size; 1782 Vector3 siz = size;
2170 Quaternion rot = rotation; 1783 Quaternion rot = rotation;
2171 1784
1785
2172 OdePrim newPrim; 1786 OdePrim newPrim;
2173 lock (OdeLock) 1787 lock (OdeLock)
2174 { 1788 {
1789 d.AllocateODEDataForThread(0);
2175 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical); 1790 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical);
2176 1791
2177 lock (_prims) 1792 lock (_prims)
@@ -2456,7 +2071,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
2456 2071
2457 lock (externalJointRequestsLock) 2072 lock (externalJointRequestsLock)
2458 { 2073 {
2459 if (!requestedJointsToBeCreated.Contains(joint)) // forbid same creation request from entering twice 2074 if (!requestedJointsToBeCreated.Contains(joint)) // forbid same creation request from entering twice
2460 { 2075 {
2461 requestedJointsToBeCreated.Add(joint); 2076 requestedJointsToBeCreated.Add(joint);
2462 } 2077 }
@@ -2620,59 +2235,13 @@ namespace OpenSim.Region.PhysicsModule.ODE
2620 2235
2621 2236
2622 } 2237 }
2623 // we don't want to remove the main space
2624
2625 // If the geometry is in the targetspace, remove it from the target space
2626 //m_log.Warn(prim.m_targetSpace);
2627
2628 //if (prim.m_targetSpace != IntPtr.Zero)
2629 //{
2630 //if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom))
2631 //{
2632
2633 //if (d.GeomIsSpace(prim.m_targetSpace))
2634 //{
2635 //waitForSpaceUnlock(prim.m_targetSpace);
2636 //d.SpaceRemove(prim.m_targetSpace, prim.prim_geom);
2637 prim.m_targetSpace = IntPtr.Zero; 2238 prim.m_targetSpace = IntPtr.Zero;
2638 //}
2639 //else
2640 //{
2641 // m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
2642 //((OdePrim)prim).m_targetSpace.ToString());
2643 //}
2644
2645 //}
2646 //}
2647 //m_log.Warn(prim.prim_geom);
2648
2649 if (!prim.RemoveGeom()) 2239 if (!prim.RemoveGeom())
2650 m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene"); 2240 m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene");
2651 2241
2652 lock (_prims) 2242 lock (_prims)
2653 _prims.Remove(prim); 2243 _prims.Remove(prim);
2654 2244
2655 //If there are no more geometries in the sub-space, we don't need it in the main space anymore
2656 //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0)
2657 //{
2658 //if (prim.m_targetSpace != null)
2659 //{
2660 //if (d.GeomIsSpace(prim.m_targetSpace))
2661 //{
2662 //waitForSpaceUnlock(prim.m_targetSpace);
2663 //d.SpaceRemove(space, prim.m_targetSpace);
2664 // free up memory used by the space.
2665 //d.SpaceDestroy(prim.m_targetSpace);
2666 //int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position);
2667 //resetSpaceArrayItemToZero(xyspace[0], xyspace[1]);
2668 //}
2669 //else
2670 //{
2671 //m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
2672 //((OdePrim) prim).m_targetSpace.ToString());
2673 //}
2674 //}
2675 //}
2676 2245
2677 if (SupportsNINJAJoints) 2246 if (SupportsNINJAJoints)
2678 RemoveAllJointsConnectedToActorThreadLocked(prim); 2247 RemoveAllJointsConnectedToActorThreadLocked(prim);
@@ -2768,12 +2337,9 @@ namespace OpenSim.Region.PhysicsModule.ODE
2768 { 2337 {
2769 if (d.GeomIsSpace(currentspace)) 2338 if (d.GeomIsSpace(currentspace))
2770 { 2339 {
2771// waitForSpaceUnlock(currentspace);
2772// waitForSpaceUnlock(space);
2773 d.SpaceRemove(space, currentspace); 2340 d.SpaceRemove(space, currentspace);
2774 // free up memory used by the space. 2341 // free up memory used by the space.
2775 2342
2776 //d.SpaceDestroy(currentspace);
2777 resetSpaceArrayItemToZero(currentspace); 2343 resetSpaceArrayItemToZero(currentspace);
2778 } 2344 }
2779 else 2345 else
@@ -2831,7 +2397,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
2831 if (newspace == IntPtr.Zero) 2397 if (newspace == IntPtr.Zero)
2832 { 2398 {
2833 newspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]); 2399 newspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
2834 d.HashSpaceSetLevels(newspace, smallHashspaceLow, smallHashspaceHigh); 2400 d.HashSpaceSetLevels(newspace, HashspaceLow, HashspaceHigh);
2835 } 2401 }
2836 2402
2837 return newspace; 2403 return newspace;
@@ -2851,7 +2417,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
2851// waitForSpaceUnlock(space); 2417// waitForSpaceUnlock(space);
2852 d.SpaceSetSublevel(space, 1); 2418 d.SpaceSetSublevel(space, 1);
2853 d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]); 2419 d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]);
2854 2420
2855 return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]; 2421 return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY];
2856 } 2422 }
2857 2423
@@ -2948,7 +2514,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
2948 iPropertiesNotSupportedDefault++; 2514 iPropertiesNotSupportedDefault++;
2949 2515
2950 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) 2516 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
2951 iPropertiesNotSupportedDefault++; 2517 iPropertiesNotSupportedDefault++;
2952 2518
2953 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0) 2519 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
2954 iPropertiesNotSupportedDefault++; 2520 iPropertiesNotSupportedDefault++;
@@ -3021,7 +2587,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
3021#if SPAM 2587#if SPAM
3022 m_log.Debug("Mesh"); 2588 m_log.Debug("Mesh");
3023#endif 2589#endif
3024 return true; 2590 return true;
3025 } 2591 }
3026 2592
3027 /// <summary> 2593 /// <summary>
@@ -3052,6 +2618,49 @@ namespace OpenSim.Region.PhysicsModule.ODE
3052 } 2618 }
3053 } 2619 }
3054 2620
2621 // does all pending changes generated during region load process
2622 public override void ProcessPreSimulation()
2623 {
2624 lock (OdeLock)
2625 {
2626 if (world == IntPtr.Zero)
2627 {
2628 _taintedPrims.Clear();;
2629 return;
2630 }
2631
2632 int donechanges = 0;
2633 if (_taintedPrims.Count > 0)
2634 {
2635
2636 m_log.InfoFormat("[Ode] start processing pending actor operations");
2637 int tstart = Util.EnvironmentTickCount();
2638
2639 d.AllocateODEDataForThread(0);
2640
2641 lock (_taintedPrims)
2642 {
2643 foreach (OdePrim prim in _taintedPrims)
2644 {
2645 if (prim.m_taintremove)
2646 RemovePrimThreadLocked(prim);
2647 else
2648 prim.ProcessTaints();
2649
2650 prim.m_collisionscore = 0;
2651 donechanges++;
2652 }
2653 _taintedPrims.Clear();
2654 }
2655
2656 int time = Util.EnvironmentTickCountSubtract(tstart);
2657 m_log.InfoFormat("[Ode] finished {0} operations in {1}ms", donechanges, time);
2658 }
2659 m_log.InfoFormat("[Ode] {0} prim actors loaded",_prims.Count);
2660 }
2661 }
2662
2663
3055 /// <summary> 2664 /// <summary>
3056 /// This is our main simulate loop 2665 /// This is our main simulate loop
3057 /// </summary> 2666 /// </summary>
@@ -3065,7 +2674,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
3065 /// <returns>The number of frames simulated over that period.</returns> 2674 /// <returns>The number of frames simulated over that period.</returns>
3066 public override float Simulate(float timeStep) 2675 public override float Simulate(float timeStep)
3067 { 2676 {
3068 if (!_worldInitialized) return 11f; 2677 if (!_worldInitialized)
2678 return 1.0f;
3069 2679
3070 int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0; 2680 int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0;
3071 int tempTick = 0, tempTick2 = 0; 2681 int tempTick = 0, tempTick2 = 0;
@@ -3077,26 +2687,12 @@ namespace OpenSim.Region.PhysicsModule.ODE
3077 2687
3078 float fps = 0; 2688 float fps = 0;
3079 2689
3080 float timeLeft = timeStep; 2690 step_time += timeStep;
3081 2691
3082 //m_log.Info(timeStep.ToString()); 2692 float HalfOdeStep = ODE_STEPSIZE * 0.5f;
3083// step_time += timeSte 2693 if (step_time < HalfOdeStep)
3084// 2694 return 0;
3085// // If We're loaded down by something else, 2695
3086// // or debugging with the Visual Studio project on pause
3087// // skip a few frames to catch up gracefully.
3088// // without shooting the physicsactors all over the place
3089//
3090// if (step_time >= m_SkipFramesAtms)
3091// {
3092// // Instead of trying to catch up, it'll do 5 physics frames only
3093// step_time = ODE_STEPSIZE;
3094// m_physicsiterations = 5;
3095// }
3096// else
3097// {
3098// m_physicsiterations = 10;
3099// }
3100 2696
3101 // We change _collisionEventPrimChanges to avoid locking _collisionEventPrim itself and causing potential 2697 // We change _collisionEventPrimChanges to avoid locking _collisionEventPrim itself and causing potential
3102 // deadlock if the collision event tries to lock something else later on which is already locked by a 2698 // deadlock if the collision event tries to lock something else later on which is already locked by a
@@ -3120,29 +2716,12 @@ namespace OpenSim.Region.PhysicsModule.ODE
3120 CreateRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks 2716 CreateRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks
3121 } 2717 }
3122 2718
2719
3123 lock (OdeLock) 2720 lock (OdeLock)
3124 { 2721 {
3125 // Process 10 frames if the sim is running normal.. 2722 d.AllocateODEDataForThread(~0U);
3126 // process 5 frames if the sim is running slow
3127 //try
3128 //{
3129 //d.WorldSetQuickStepNumIterations(world, m_physicsiterations);
3130 //}
3131 //catch (StackOverflowException)
3132 //{
3133 // m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim.");
3134 // ode.drelease(world);
3135 //base.TriggerPhysicsBasedRestart();
3136 //}
3137 2723
3138 // Figure out the Frames Per Second we're going at. 2724 while (step_time > HalfOdeStep)
3139 //(step_time == 0.004f, there's 250 of those per second. Times the step time/step size
3140
3141 fps = (timeStep / ODE_STEPSIZE) * 1000;
3142 // HACK: Using a time dilation of 1.0 to debug rubberbanding issues
3143 //m_timeDilation = Math.Min((step_time / ODE_STEPSIZE) / (0.09375f / ODE_STEPSIZE), 1.0f);
3144
3145 while (timeLeft > 0.0f)
3146 { 2725 {
3147 try 2726 try
3148 { 2727 {
@@ -3241,10 +2820,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
3241 tempTick = tempTick2; 2820 tempTick = tempTick2;
3242 } 2821 }
3243 2822
3244 //if ((framecount % m_randomizeWater) == 0)
3245 // randomizeWater(waterlevel);
3246
3247 //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests();
3248 m_rayCastManager.ProcessQueuedRequests(); 2823 m_rayCastManager.ProcessQueuedRequests();
3249 2824
3250 if (CollectStats) 2825 if (CollectStats)
@@ -3265,7 +2840,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
3265 2840
3266 foreach (PhysicsActor obj in m_collisionEventActors.Values) 2841 foreach (PhysicsActor obj in m_collisionEventActors.Values)
3267 { 2842 {
3268// m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID); 2843 // m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID);
3269 2844
3270 switch ((ActorTypes)obj.PhysicsActorType) 2845 switch ((ActorTypes)obj.PhysicsActorType)
3271 { 2846 {
@@ -3295,7 +2870,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
3295 tempTick = tempTick2; 2870 tempTick = tempTick2;
3296 } 2871 }
3297 2872
3298 d.WorldQuickStep(world, ODE_STEPSIZE); 2873 lock(SimulationLock)
2874 d.WorldQuickStep(world, ODE_STEPSIZE);
3299 2875
3300 if (CollectStats) 2876 if (CollectStats)
3301 m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); 2877 m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick);
@@ -3307,7 +2883,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
3307 m_log.ErrorFormat("[ODE SCENE]: {0}, {1}, {2}", e.Message, e.TargetSite, e); 2883 m_log.ErrorFormat("[ODE SCENE]: {0}, {1}, {2}", e.Message, e.TargetSite, e);
3308 } 2884 }
3309 2885
3310 timeLeft -= ODE_STEPSIZE; 2886 step_time -= ODE_STEPSIZE;
2887 fps += ODE_STEPSIZE;
3311 } 2888 }
3312 2889
3313 if (CollectStats) 2890 if (CollectStats)
@@ -3403,6 +2980,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
3403 m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick); 2980 m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick);
3404 } 2981 }
3405 2982
2983 fps *= 1.0f/timeStep;
3406 return fps; 2984 return fps;
3407 } 2985 }
3408 2986
@@ -3531,7 +3109,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
3531 // as the axis for the hinge. 3109 // as the axis for the hinge.
3532 3110
3533 // Therefore, we must get the joint's coordinate frame based on the 3111 // Therefore, we must get the joint's coordinate frame based on the
3534 // joint.Rotation field, which originates from the orientation of the 3112 // joint.Rotation field, which originates from the orientation of the
3535 // joint's proxy object in the scene. 3113 // joint's proxy object in the scene.
3536 3114
3537 // The joint's coordinate frame is defined as the transformation matrix 3115 // The joint's coordinate frame is defined as the transformation matrix
@@ -3659,7 +3237,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
3659 int startTime = Util.EnvironmentTickCount(); 3237 int startTime = Util.EnvironmentTickCount();
3660 m_log.DebugFormat("[ODE SCENE]: Setting terrain for {0} with offset {1}", PhysicsSceneName, pOffset); 3238 m_log.DebugFormat("[ODE SCENE]: Setting terrain for {0} with offset {1}", PhysicsSceneName, pOffset);
3661 3239
3662 3240
3663 float[] _heightmap; 3241 float[] _heightmap;
3664 3242
3665 // ok im lasy this are just a aliases 3243 // ok im lasy this are just a aliases
@@ -3675,7 +3253,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
3675 3253
3676 _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples]; 3254 _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
3677 3255
3678
3679 const float scale = 1.0f; 3256 const float scale = 1.0f;
3680 const float offset = 0.0f; 3257 const float offset = 0.0f;
3681 const float thickness = 10f; 3258 const float thickness = 10f;
@@ -3722,6 +3299,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
3722 3299
3723 lock (OdeLock) 3300 lock (OdeLock)
3724 { 3301 {
3302 d.AllocateODEDataForThread(~0U);
3303
3725 IntPtr GroundGeom = IntPtr.Zero; 3304 IntPtr GroundGeom = IntPtr.Zero;
3726 if (RegionTerrain.TryGetValue(pOffset, out GroundGeom)) 3305 if (RegionTerrain.TryGetValue(pOffset, out GroundGeom))
3727 { 3306 {
@@ -3740,7 +3319,8 @@ namespace OpenSim.Region.PhysicsModule.ODE
3740 IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); 3319 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
3741 d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, 3320 d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0,
3742 heightmapWidth, heightmapHeight, 3321 heightmapWidth, heightmapHeight,
3743 (int)heightmapWidthSamples, (int)heightmapHeightSamples, 3322 (int)heightmapWidthSamples,
3323 (int)heightmapHeightSamples,
3744 scale, offset, thickness, wrap); 3324 scale, offset, thickness, wrap);
3745 3325
3746 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); 3326 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
@@ -3765,7 +3345,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
3765 3345
3766 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); 3346 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
3767 d.GeomSetRotation(GroundGeom, ref R); 3347 d.GeomSetRotation(GroundGeom, ref R);
3768 d.GeomSetPosition(GroundGeom, pOffset.X + regionsizeX * 0.5f, pOffset.Y + regionsizeY * 0.5f, 0f); 3348 d.GeomSetPosition(GroundGeom, pOffset.X + regionsizeX * 0.5f, pOffset.Y + regionsizeY * 0.5f, 0.0f);
3769 IntPtr testGround = IntPtr.Zero; 3349 IntPtr testGround = IntPtr.Zero;
3770 if (RegionTerrain.TryGetValue(pOffset, out testGround)) 3350 if (RegionTerrain.TryGetValue(pOffset, out testGround))
3771 { 3351 {
@@ -3788,82 +3368,30 @@ namespace OpenSim.Region.PhysicsModule.ODE
3788 return waterlevel; 3368 return waterlevel;
3789 } 3369 }
3790 3370
3791 public override bool SupportsCombining()
3792 {
3793 return m_suportCombine;
3794 }
3795
3796 public override void SetWaterLevel(float baseheight) 3371 public override void SetWaterLevel(float baseheight)
3797 { 3372 {
3798 waterlevel = baseheight; 3373 waterlevel = baseheight;
3799// randomizeWater(waterlevel);
3800 } 3374 }
3801 3375
3802/* 3376 [HandleProcessCorruptedStateExceptions]
3803 private void randomizeWater(float baseheight) 3377 public override void Dispose()
3804 { 3378 {
3805 uint heightmapWidth = m_regionWidth + 2; 3379 lock(SimulationLock)
3806 uint heightmapHeight = m_regionHeight + 2; 3380 lock(OdeLock)
3807 uint heightmapWidthSamples = m_regionWidth + 2;
3808 uint heightmapHeightSamples = m_regionHeight + 2;
3809 float scale = 1.0f;
3810 float offset = 0.0f;
3811 float thickness = 2.9f;
3812 int wrap = 0;
3813
3814 for (int i = 0; i < (258 * 258); i++)
3815 {
3816 _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f);
3817 // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f));
3818 }
3819
3820 lock (OdeLock)
3821 { 3381 {
3822 if (WaterGeom != IntPtr.Zero) 3382 if(world == IntPtr.Zero)
3823 { 3383 return;
3824 d.SpaceRemove(space, WaterGeom);
3825 }
3826 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
3827 d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight,
3828 (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale,
3829 offset, thickness, wrap);
3830 d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight);
3831 WaterGeom = d.CreateHeightfield(space, HeightmapData, 1);
3832 if (WaterGeom != IntPtr.Zero)
3833 {
3834 d.GeomSetCategoryBits(WaterGeom, (int)(CollisionCategories.Water));
3835 d.GeomSetCollideBits(WaterGeom, (int)(CollisionCategories.Space));
3836 }
3837
3838 geom_name_map[WaterGeom] = "Water";
3839
3840 d.Matrix3 R = new d.Matrix3();
3841
3842 Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f);
3843 Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f);
3844 //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1));
3845 3384
3846 q1 = q1 * q2; 3385 _worldInitialized = false;
3847 //q1 = q1 * q3;
3848 Vector3 v3;
3849 float angle;
3850 q1.GetAxisAngle(out v3, out angle);
3851 3386
3852 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); 3387 d.AllocateODEDataForThread(~0U);
3853 d.GeomSetRotation(WaterGeom, ref R);
3854 d.GeomSetPosition(WaterGeom, 128, 128, 0);
3855 }
3856 }
3857*/
3858 public override void Dispose()
3859 {
3860 _worldInitialized = false;
3861 3388
3862 m_rayCastManager.Dispose(); 3389 if (m_rayCastManager != null)
3863 m_rayCastManager = null; 3390 {
3391 m_rayCastManager.Dispose();
3392 m_rayCastManager = null;
3393 }
3864 3394
3865 lock (OdeLock)
3866 {
3867 lock (_prims) 3395 lock (_prims)
3868 { 3396 {
3869 foreach (OdePrim prm in _prims) 3397 foreach (OdePrim prm in _prims)
@@ -3876,10 +3404,33 @@ namespace OpenSim.Region.PhysicsModule.ODE
3876 //{ 3404 //{
3877 //RemoveAvatar(act); 3405 //RemoveAvatar(act);
3878 //} 3406 //}
3879 d.WorldDestroy(world); 3407 IntPtr GroundGeom = IntPtr.Zero;
3880 //d.CloseODE(); 3408 if (RegionTerrain.TryGetValue(m_worldOffset, out GroundGeom))
3409 {
3410 RegionTerrain.Remove(m_worldOffset);
3411 if (GroundGeom != IntPtr.Zero)
3412 {
3413 if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
3414 TerrainHeightFieldHeights.Remove(GroundGeom);
3415 d.GeomDestroy(GroundGeom);
3416 }
3417 }
3418
3419 try
3420 {
3421 d.WorldDestroy(world);
3422 world = IntPtr.Zero;
3423 }
3424 catch (AccessViolationException e)
3425 {
3426 m_log.ErrorFormat("[ODE SCENE]: exception {0}", e.Message);
3427 }
3881 } 3428 }
3429 }
3882 3430
3431 private int compareByCollisionsDesc(OdePrim A, OdePrim B)
3432 {
3433 return -A.CollisionScore.CompareTo(B.CollisionScore);
3883 } 3434 }
3884 3435
3885 public override Dictionary<uint, float> GetTopColliders() 3436 public override Dictionary<uint, float> GetTopColliders()
@@ -3889,7 +3440,7 @@ namespace OpenSim.Region.PhysicsModule.ODE
3889 lock (_prims) 3440 lock (_prims)
3890 { 3441 {
3891 List<OdePrim> orderedPrims = new List<OdePrim>(_prims); 3442 List<OdePrim> orderedPrims = new List<OdePrim>(_prims);
3892 orderedPrims.OrderByDescending(p => p.CollisionScore); 3443 orderedPrims.Sort(compareByCollisionsDesc);
3893 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore); 3444 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
3894 3445
3895 foreach (OdePrim p in _prims) 3446 foreach (OdePrim p in _prims)
@@ -3940,133 +3491,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
3940 return new List<ContactResult>(ourResults); 3491 return new List<ContactResult>(ourResults);
3941 } 3492 }
3942 3493
3943#if USE_DRAWSTUFF
3944 // Keyboard callback
3945 public void command(int cmd)
3946 {
3947 IntPtr geom;
3948 d.Mass mass;
3949 d.Vector3 sides = new d.Vector3(d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f);
3950
3951
3952
3953 Char ch = Char.ToLower((Char)cmd);
3954 switch ((Char)ch)
3955 {
3956 case 'w':
3957 try
3958 {
3959 Vector3 rotate = (new Vector3(1, 0, 0) * Quaternion.CreateFromEulers(hpr.Z * Utils.DEG_TO_RAD, hpr.Y * Utils.DEG_TO_RAD, hpr.X * Utils.DEG_TO_RAD));
3960
3961 xyz.X += rotate.X; xyz.Y += rotate.Y; xyz.Z += rotate.Z;
3962 ds.SetViewpoint(ref xyz, ref hpr);
3963 }
3964 catch (ArgumentException)
3965 { hpr.X = 0; }
3966 break;
3967
3968 case 'a':
3969 hpr.X++;
3970 ds.SetViewpoint(ref xyz, ref hpr);
3971 break;
3972
3973 case 's':
3974 try
3975 {
3976 Vector3 rotate2 = (new Vector3(-1, 0, 0) * Quaternion.CreateFromEulers(hpr.Z * Utils.DEG_TO_RAD, hpr.Y * Utils.DEG_TO_RAD, hpr.X * Utils.DEG_TO_RAD));
3977
3978 xyz.X += rotate2.X; xyz.Y += rotate2.Y; xyz.Z += rotate2.Z;
3979 ds.SetViewpoint(ref xyz, ref hpr);
3980 }
3981 catch (ArgumentException)
3982 { hpr.X = 0; }
3983 break;
3984 case 'd':
3985 hpr.X--;
3986 ds.SetViewpoint(ref xyz, ref hpr);
3987 break;
3988 case 'r':
3989 xyz.Z++;
3990 ds.SetViewpoint(ref xyz, ref hpr);
3991 break;
3992 case 'f':
3993 xyz.Z--;
3994 ds.SetViewpoint(ref xyz, ref hpr);
3995 break;
3996 case 'e':
3997 xyz.Y++;
3998 ds.SetViewpoint(ref xyz, ref hpr);
3999 break;
4000 case 'q':
4001 xyz.Y--;
4002 ds.SetViewpoint(ref xyz, ref hpr);
4003 break;
4004 }
4005 }
4006
4007 public void step(int pause)
4008 {
4009
4010 ds.SetColor(1.0f, 1.0f, 0.0f);
4011 ds.SetTexture(ds.Texture.Wood);
4012 lock (_prims)
4013 {
4014 foreach (OdePrim prm in _prims)
4015 {
4016 //IntPtr body = d.GeomGetBody(prm.prim_geom);
4017 if (prm.prim_geom != IntPtr.Zero)
4018 {
4019 d.Vector3 pos;
4020 d.GeomCopyPosition(prm.prim_geom, out pos);
4021 //d.BodyCopyPosition(body, out pos);
4022
4023 d.Matrix3 R;
4024 d.GeomCopyRotation(prm.prim_geom, out R);
4025 //d.BodyCopyRotation(body, out R);
4026
4027
4028 d.Vector3 sides = new d.Vector3();
4029 sides.X = prm.Size.X;
4030 sides.Y = prm.Size.Y;
4031 sides.Z = prm.Size.Z;
4032
4033 ds.DrawBox(ref pos, ref R, ref sides);
4034 }
4035 }
4036 }
4037 ds.SetColor(1.0f, 0.0f, 0.0f);
4038
4039 foreach (OdeCharacter chr in _characters)
4040 {
4041 if (chr.Shell != IntPtr.Zero)
4042 {
4043 IntPtr body = d.GeomGetBody(chr.Shell);
4044
4045 d.Vector3 pos;
4046 d.GeomCopyPosition(chr.Shell, out pos);
4047 //d.BodyCopyPosition(body, out pos);
4048
4049 d.Matrix3 R;
4050 d.GeomCopyRotation(chr.Shell, out R);
4051 //d.BodyCopyRotation(body, out R);
4052
4053 ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f);
4054 d.Vector3 sides = new d.Vector3();
4055 sides.X = 0.5f;
4056 sides.Y = 0.5f;
4057 sides.Z = 0.5f;
4058
4059 ds.DrawBox(ref pos, ref R, ref sides);
4060 }
4061 }
4062 }
4063
4064 public void start(int unused)
4065 {
4066 ds.SetViewpoint(ref xyz, ref hpr);
4067 }
4068#endif
4069
4070 public override Dictionary<string, float> GetStats() 3494 public override Dictionary<string, float> GetStats()
4071 { 3495 {
4072 if (!CollectStats) 3496 if (!CollectStats)
diff --git a/OpenSim/Region/PhysicsModules/Ode/Tests/ODETestClass.cs b/OpenSim/Region/PhysicsModules/Ode/Tests/ODETestClass.cs
index 6dc22bd..2c134e7 100644
--- a/OpenSim/Region/PhysicsModules/Ode/Tests/ODETestClass.cs
+++ b/OpenSim/Region/PhysicsModules/Ode/Tests/ODETestClass.cs
@@ -47,6 +47,8 @@ namespace OpenSim.Region.PhysicsModule.ODE.Tests
47 47
48 //private OpenSim.Region.PhysicsModule.ODE.OdePlugin cbt; 48 //private OpenSim.Region.PhysicsModule.ODE.OdePlugin cbt;
49 private PhysicsScene pScene; 49 private PhysicsScene pScene;
50 private OpenSim.Region.PhysicsModule.ODE.OdeModule odemodule;
51
50 52
51 [SetUp] 53 [SetUp]
52 public void Initialize() 54 public void Initialize()
@@ -65,19 +67,18 @@ namespace OpenSim.Region.PhysicsModule.ODE.Tests
65 info.RegionSizeX = info.RegionSizeY = info.RegionSizeZ = Constants.RegionSize; 67 info.RegionSizeX = info.RegionSizeY = info.RegionSizeZ = Constants.RegionSize;
66 OpenSim.Region.Framework.Scenes.Scene scene = new OpenSim.Region.Framework.Scenes.Scene(info); 68 OpenSim.Region.Framework.Scenes.Scene scene = new OpenSim.Region.Framework.Scenes.Scene(info);
67 69
68 //IMesher mesher = new OpenSim.Region.PhysicsModules.Meshing.Meshmerizer(); 70 //IMesher mesher = new OpenSim.Region.PhysicsModule.Meshing.Meshmerizer();
69 //INonSharedRegionModule mod = mesher as INonSharedRegionModule; 71 //INonSharedRegionModule mod = mesher as INonSharedRegionModule;
70 //mod.Initialise(openSimINI); 72 //mod.Initialise(openSimINI);
71 //mod.AddRegion(scene); 73 //mod.AddRegion(scene);
72 //mod.RegionLoaded(scene); 74 //mod.RegionLoaded(scene);
73 75
74 pScene = new OdeScene(); 76 // pScene = new OdeScene();
75 Console.WriteLine("HERE " + (pScene == null ? "Null" : "Not null")); 77 odemodule = new OpenSim.Region.PhysicsModule.ODE.OdeModule();
76 INonSharedRegionModule mod = (pScene as INonSharedRegionModule); 78 Console.WriteLine("HERE " + (odemodule == null ? "Null" : "Not null"));
77 Console.WriteLine("HERE " + (mod == null ? "Null" : "Not null")); 79 odemodule.Initialise(openSimINI);
78 mod.Initialise(openSimINI); 80 odemodule.AddRegion(scene);
79 mod.AddRegion(scene); 81 odemodule.RegionLoaded(scene);
80 mod.RegionLoaded(scene);
81 82
82 // Loading ODEPlugin 83 // Loading ODEPlugin
83 //cbt = new OdePlugin(); 84 //cbt = new OdePlugin();
@@ -90,6 +91,7 @@ namespace OpenSim.Region.PhysicsModule.ODE.Tests
90 { 91 {
91 _heightmap[i] = 21f; 92 _heightmap[i] = 21f;
92 } 93 }
94 pScene = scene.PhysicsScene;
93 pScene.SetTerrain(_heightmap); 95 pScene.SetTerrain(_heightmap);
94 } 96 }
95 97
diff --git a/OpenSim/Region/PhysicsModules/Ode/drawstuff.cs b/OpenSim/Region/PhysicsModules/Ode/drawstuff.cs
deleted file mode 100644
index 87ca446..0000000
--- a/OpenSim/Region/PhysicsModules/Ode/drawstuff.cs
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * Copyright ODE
3 * Ode.NET - .NET bindings for ODE
4 * Jason Perkins (starkos@industriousone.com)
5 * Licensed under the New BSD
6 * Part of the OpenDynamicsEngine
7Open Dynamics Engine
8Copyright (c) 2001-2007, Russell L. Smith.
9All rights reserved.
10
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions
13are met:
14
15Redistributions of source code must retain the above copyright notice,
16this list of conditions and the following disclaimer.
17
18Redistributions in binary form must reproduce the above copyright notice,
19this list of conditions and the following disclaimer in the documentation
20and/or other materials provided with the distribution.
21
22Neither the names of ODE's copyright owner nor the names of its
23contributors may be used to endorse or promote products derived from
24this software without specific prior written permission.
25
26THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
32TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 *
39 */
40
41using System;
42using System.Runtime.InteropServices;
43using Ode.NET;
44
45namespace Drawstuff.NET
46{
47#if dDOUBLE
48 using dReal = System.Double;
49#else
50 using dReal = System.Single;
51#endif
52
53 public static class ds
54 {
55 public const int VERSION = 2;
56
57 public enum Texture
58 {
59 None,
60 Wood
61 }
62
63 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
64 public delegate void CallbackFunction(int arg);
65
66 [StructLayout(LayoutKind.Sequential)]
67 public struct Functions
68 {
69 public int version;
70 public CallbackFunction start;
71 public CallbackFunction step;
72 public CallbackFunction command;
73 public CallbackFunction stop;
74 public string path_to_textures;
75 }
76
77 [DllImport("drawstuff", EntryPoint = "dsDrawBox")]
78 public static extern void DrawBox(ref d.Vector3 pos, ref d.Matrix3 R, ref d.Vector3 sides);
79
80 [DllImport("drawstuff", EntryPoint = "dsDrawCapsule")]
81 public static extern void DrawCapsule(ref d.Vector3 pos, ref d.Matrix3 R, dReal length, dReal radius);
82
83 [DllImport("drawstuff", EntryPoint = "dsDrawConvex")]
84 public static extern void DrawConvex(ref d.Vector3 pos, ref d.Matrix3 R, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
85
86 [DllImport("drawstuff", EntryPoint = "dsSetColor")]
87 public static extern void SetColor(float red, float green, float blue);
88
89 [DllImport("drawstuff", EntryPoint = "dsSetTexture")]
90 public static extern void SetTexture(Texture texture);
91
92 [DllImport("drawstuff", EntryPoint = "dsSetViewpoint")]
93 public static extern void SetViewpoint(ref d.Vector3 xyz, ref d.Vector3 hpr);
94
95 [DllImport("drawstuff", EntryPoint = "dsSimulationLoop")]
96 public static extern void SimulationLoop(int argc, string[] argv, int window_width, int window_height, ref Functions fn);
97 }
98}
diff --git a/OpenSim/Region/PhysicsModules/POS/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/POS/AssemblyInfo.cs
index e3a3e35..23fe9ae 100644
--- a/OpenSim/Region/PhysicsModules/POS/AssemblyInfo.cs
+++ b/OpenSim/Region/PhysicsModules/POS/AssemblyInfo.cs
@@ -56,7 +56,7 @@ using Mono.Addins;
56// You can specify all values by your own or you can build default build and revision 56// You can specify all values by your own or you can build default build and revision
57// numbers with the '*' character (the default): 57// numbers with the '*' character (the default):
58 58
59[assembly : AssemblyVersion("0.8.2.*")] 59[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
60 60
61[assembly: Addin("OpenSim.Region.PhysicsModule.POS", OpenSim.VersionInfo.VersionNumber)] 61[assembly: Addin("OpenSim.Region.PhysicsModule.POS", OpenSim.VersionInfo.VersionNumber)]
62[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] 62[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
diff --git a/OpenSim/Region/PhysicsModules/POS/POSCharacter.cs b/OpenSim/Region/PhysicsModules/POS/POSCharacter.cs
index 32469d9..341530e 100644
--- a/OpenSim/Region/PhysicsModules/POS/POSCharacter.cs
+++ b/OpenSim/Region/PhysicsModules/POS/POSCharacter.cs
@@ -248,7 +248,7 @@ namespace OpenSim.Region.PhysicsModule.POS
248 { 248 {
249 } 249 }
250 250
251 public override void LockAngularMotion(Vector3 axis) 251 public override void LockAngularMotion(byte axislocks)
252 { 252 {
253 } 253 }
254 254
@@ -273,10 +273,10 @@ namespace OpenSim.Region.PhysicsModule.POS
273 set { return; } 273 set { return; }
274 } 274 }
275 275
276 public override bool PIDActive 276 public override bool PIDActive
277 { 277 {
278 get { return false; } 278 get { return false; }
279 set { return; } 279 set { return; }
280 } 280 }
281 281
282 public override float PIDTau 282 public override float PIDTau
@@ -291,6 +291,7 @@ namespace OpenSim.Region.PhysicsModule.POS
291 291
292 public override bool PIDHoverActive 292 public override bool PIDHoverActive
293 { 293 {
294 get { return false; }
294 set { return; } 295 set { return; }
295 } 296 }
296 297
@@ -303,7 +304,7 @@ namespace OpenSim.Region.PhysicsModule.POS
303 { 304 {
304 set { return; } 305 set { return; }
305 } 306 }
306 307
307 public override Quaternion APIDTarget 308 public override Quaternion APIDTarget
308 { 309 {
309 set { return; } 310 set { return; }
diff --git a/OpenSim/Region/PhysicsModules/POS/POSPrim.cs b/OpenSim/Region/PhysicsModules/POS/POSPrim.cs
index 8aae716..180885d 100644
--- a/OpenSim/Region/PhysicsModules/POS/POSPrim.cs
+++ b/OpenSim/Region/PhysicsModules/POS/POSPrim.cs
@@ -250,7 +250,7 @@ namespace OpenSim.Region.PhysicsModule.POS
250 { 250 {
251 } 251 }
252 252
253 public override void LockAngularMotion(Vector3 axis) 253 public override void LockAngularMotion(byte axislocks)
254 { 254 {
255 } 255 }
256 256
@@ -286,6 +286,7 @@ namespace OpenSim.Region.PhysicsModule.POS
286 286
287 public override bool PIDHoverActive 287 public override bool PIDHoverActive
288 { 288 {
289 get { return false; }
289 set { return; } 290 set { return; }
290 } 291 }
291 292
@@ -298,7 +299,7 @@ namespace OpenSim.Region.PhysicsModule.POS
298 { 299 {
299 set { return; } 300 set { return; }
300 } 301 }
301 302
302 public override Quaternion APIDTarget 303 public override Quaternion APIDTarget
303 { 304 {
304 set { return; } 305 set { return; }
diff --git a/OpenSim/Region/PhysicsModules/POS/POSScene.cs b/OpenSim/Region/PhysicsModules/POS/POSScene.cs
index 6375f18..e62d876 100644
--- a/OpenSim/Region/PhysicsModules/POS/POSScene.cs
+++ b/OpenSim/Region/PhysicsModules/POS/POSScene.cs
@@ -54,6 +54,11 @@ namespace OpenSim.Region.PhysicsModule.POS
54 get { return "POS"; } 54 get { return "POS"; }
55 } 55 }
56 56
57 public string Version
58 {
59 get { return "1.0"; }
60 }
61
57 public Type ReplaceableInterface 62 public Type ReplaceableInterface
58 { 63 {
59 get { return null; } 64 get { return null; }
@@ -83,6 +88,7 @@ namespace OpenSim.Region.PhysicsModule.POS
83 88
84 EngineType = Name; 89 EngineType = Name;
85 PhysicsSceneName = EngineType + "/" + scene.RegionInfo.RegionName; 90 PhysicsSceneName = EngineType + "/" + scene.RegionInfo.RegionName;
91 EngineName = Name + " " + Version;
86 92
87 scene.RegisterModuleInterface<PhysicsScene>(this); 93 scene.RegisterModuleInterface<PhysicsScene>(this);
88 base.Initialise(scene.PhysicsRequestAsset, 94 base.Initialise(scene.PhysicsRequestAsset,
@@ -288,7 +294,7 @@ namespace OpenSim.Region.PhysicsModule.POS
288 character._velocity.Z = (character.Position.Z - oldposZ)/timeStep; 294 character._velocity.Z = (character.Position.Z - oldposZ)/timeStep;
289 } 295 }
290 } 296 }
291 return fps; 297 return 1.0f;
292 } 298 }
293 299
294 public override void GetResults() 300 public override void GetResults()
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/SharedBase/AssemblyInfo.cs
index 33f60e4..9027e2e 100644
--- a/OpenSim/Region/PhysicsModules/SharedBase/AssemblyInfo.cs
+++ b/OpenSim/Region/PhysicsModules/SharedBase/AssemblyInfo.cs
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
55// You can specify all values by your own or you can build default build and revision 55// You can specify all values by your own or you can build default build and revision
56// numbers with the '*' character (the default): 56// numbers with the '*' character (the default):
57 57
58[assembly : AssemblyVersion("0.8.2.*")] 58[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/IMesher.cs b/OpenSim/Region/PhysicsModules/SharedBase/IMesher.cs
index 5c75307..1a8409e 100644
--- a/OpenSim/Region/PhysicsModules/SharedBase/IMesher.cs
+++ b/OpenSim/Region/PhysicsModules/SharedBase/IMesher.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Runtime.InteropServices;
30using OpenSim.Framework; 31using OpenSim.Framework;
31using OpenMetaverse; 32using OpenMetaverse;
32 33
@@ -36,13 +37,18 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
36 { 37 {
37 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod); 38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod);
38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); 39 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical);
39 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache); 40 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde);
41 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde);
42 IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex);
43 void ReleaseMesh(IMesh mesh);
44 void ExpireReleaseMeshs();
45 void ExpireFileCache();
40 } 46 }
41 47
42 // Values for level of detail to be passed to the mesher. 48 // Values for level of detail to be passed to the mesher.
43 // Values origionally chosen for the LOD of sculpties (the sqrt(width*heigth) of sculpt texture) 49 // Values origionally chosen for the LOD of sculpties (the sqrt(width*heigth) of sculpt texture)
44 // Lower level of detail reduces the number of vertices used to represent the meshed shape. 50 // Lower level of detail reduces the number of vertices used to represent the meshed shape.
45 public enum LevelOfDetail 51 public enum LevelOfDetail
46 { 52 {
47 High = 32, 53 High = 32,
48 Medium = 16, 54 Medium = 16,
@@ -54,6 +60,25 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
54 { 60 {
55 } 61 }
56 62
63 [Serializable()]
64 [StructLayout(LayoutKind.Explicit)]
65 public struct AMeshKey
66 {
67 [FieldOffset(0)]
68 public UUID uuid;
69 [FieldOffset(0)]
70 public ulong hashA;
71 [FieldOffset(8)]
72 public ulong hashB;
73 [FieldOffset(16)]
74 public ulong hashC;
75
76 public override string ToString()
77 {
78 return uuid.ToString() + "-" + hashC.ToString("x") ;
79 }
80 }
81
57 public interface IMesh 82 public interface IMesh
58 { 83 {
59 List<Vector3> getVertexList(); 84 List<Vector3> getVertexList();
@@ -67,5 +92,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
67 void releasePinned(); 92 void releasePinned();
68 void Append(IMesh newMesh); 93 void Append(IMesh newMesh);
69 void TransformLinear(float[,] matrix, float[] offset); 94 void TransformLinear(float[,] matrix, float[] offset);
95 Vector3 GetCentroid();
96 Vector3 GetOBB();
70 } 97 }
71} 98}
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/IPhysicsParameters.cs b/OpenSim/Region/PhysicsModules/SharedBase/IPhysicsParameters.cs
index fb0c9e2..fb0c9e2 100644..100755
--- a/OpenSim/Region/PhysicsModules/SharedBase/IPhysicsParameters.cs
+++ b/OpenSim/Region/PhysicsModules/SharedBase/IPhysicsParameters.cs
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/NullPhysicsScene.cs b/OpenSim/Region/PhysicsModules/SharedBase/NullPhysicsScene.cs
index 432708c..8079e79 100644
--- a/OpenSim/Region/PhysicsModules/SharedBase/NullPhysicsScene.cs
+++ b/OpenSim/Region/PhysicsModules/SharedBase/NullPhysicsScene.cs
@@ -37,7 +37,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
37 class NullPhysicsScene : PhysicsScene 37 class NullPhysicsScene : PhysicsScene
38 { 38 {
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40 40
41 private static int m_workIndicator; 41 private static int m_workIndicator;
42 42
43 public override PhysicsActor AddAvatar( 43 public override PhysicsActor AddAvatar(
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs
index c04ff58..2fa98b5 100644
--- a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs
+++ b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs
@@ -43,7 +43,8 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
43 Unknown = 0, 43 Unknown = 0,
44 Agent = 1, 44 Agent = 1,
45 Prim = 2, 45 Prim = 2,
46 Ground = 3 46 Ground = 3,
47 Water = 4
47 } 48 }
48 49
49 public enum PIDHoverType 50 public enum PIDHoverType
@@ -54,20 +55,54 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
54 Absolute 55 Absolute
55 } 56 }
56 57
58 public struct CameraData
59 {
60 public Quaternion CameraRotation;
61 public Vector3 CameraAtAxis;
62 public bool MouseLook;
63 public bool Valid;
64 }
65
57 public struct ContactPoint 66 public struct ContactPoint
58 { 67 {
59 public Vector3 Position; 68 public Vector3 Position;
60 public Vector3 SurfaceNormal; 69 public Vector3 SurfaceNormal;
61 public float PenetrationDepth; 70 public float PenetrationDepth;
71 public float RelativeSpeed;
72 public bool CharacterFeet;
62 73
63 public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth) 74 public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
64 { 75 {
65 Position = position; 76 Position = position;
66 SurfaceNormal = surfaceNormal; 77 SurfaceNormal = surfaceNormal;
67 PenetrationDepth = penetrationDepth; 78 PenetrationDepth = penetrationDepth;
79 RelativeSpeed = 0f; // for now let this one be set explicity
80 CharacterFeet = true; // keep other plugins work as before
81 }
82
83 public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth, bool feet)
84 {
85 Position = position;
86 SurfaceNormal = surfaceNormal;
87 PenetrationDepth = penetrationDepth;
88 RelativeSpeed = 0f; // for now let this one be set explicity
89 CharacterFeet = feet; // keep other plugins work as before
68 } 90 }
69 } 91 }
70 92
93 public struct ContactData
94 {
95 public float mu;
96 public float bounce;
97 public bool softcolide;
98
99 public ContactData(float _mu, float _bounce, bool _softcolide)
100 {
101 mu = _mu;
102 bounce = _bounce;
103 softcolide = _softcolide;
104 }
105 }
71 /// <summary> 106 /// <summary>
72 /// Used to pass collision information to OnCollisionUpdate listeners. 107 /// Used to pass collision information to OnCollisionUpdate listeners.
73 /// </summary> 108 /// </summary>
@@ -100,8 +135,19 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
100 } 135 }
101 else 136 else
102 { 137 {
138 float lastVel = m_objCollisionList[localID].RelativeSpeed;
103 if (m_objCollisionList[localID].PenetrationDepth < contact.PenetrationDepth) 139 if (m_objCollisionList[localID].PenetrationDepth < contact.PenetrationDepth)
140 {
141 if(Math.Abs(lastVel) > Math.Abs(contact.RelativeSpeed))
142 contact.RelativeSpeed = lastVel;
104 m_objCollisionList[localID] = contact; 143 m_objCollisionList[localID] = contact;
144 }
145 else if(Math.Abs(lastVel) < Math.Abs(contact.RelativeSpeed))
146 {
147 ContactPoint tmp = m_objCollisionList[localID];
148 tmp.RelativeSpeed = contact.RelativeSpeed;
149 m_objCollisionList[localID] = tmp;
150 }
105 } 151 }
106 } 152 }
107 153
@@ -121,13 +167,15 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
121 public delegate void RequestTerseUpdate(); 167 public delegate void RequestTerseUpdate();
122 public delegate void CollisionUpdate(EventArgs e); 168 public delegate void CollisionUpdate(EventArgs e);
123 public delegate void OutOfBounds(Vector3 pos); 169 public delegate void OutOfBounds(Vector3 pos);
170 public delegate CameraData GetCameraData();
124 171
125// disable warning: public events 172 // disable warning: public events
126#pragma warning disable 67 173#pragma warning disable 67
127 public event PositionUpdate OnPositionUpdate; 174 public event PositionUpdate OnPositionUpdate;
128 public event VelocityUpdate OnVelocityUpdate; 175 public event VelocityUpdate OnVelocityUpdate;
129 public event OrientationUpdate OnOrientationUpdate; 176 public event OrientationUpdate OnOrientationUpdate;
130 public event RequestTerseUpdate OnRequestTerseUpdate; 177 public event RequestTerseUpdate OnRequestTerseUpdate;
178 public event GetCameraData OnPhysicsRequestingCameraData;
131 179
132 /// <summary> 180 /// <summary>
133 /// Subscribers to this event must synchronously handle the dictionary of collisions received, since the event 181 /// Subscribers to this event must synchronously handle the dictionary of collisions received, since the event
@@ -138,15 +186,47 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
138 public event OutOfBounds OnOutOfBounds; 186 public event OutOfBounds OnOutOfBounds;
139#pragma warning restore 67 187#pragma warning restore 67
140 188
189 public CameraData TryGetCameraData()
190 {
191 GetCameraData handler = OnPhysicsRequestingCameraData;
192 if (handler != null)
193 {
194 return handler();
195 }
196
197 return new CameraData { Valid = false };
198 }
199
141 public static PhysicsActor Null 200 public static PhysicsActor Null
142 { 201 {
143 get { return new NullPhysicsActor(); } 202 get { return new NullPhysicsActor(); }
144 } 203 }
145 204
205 public virtual bool Building { get; set; }
206
207 public virtual void getContactData(ref ContactData cdata)
208 {
209 cdata.mu = 0;
210 cdata.bounce = 0;
211 }
212
146 public abstract bool Stopped { get; } 213 public abstract bool Stopped { get; }
147 214
148 public abstract Vector3 Size { get; set; } 215 public abstract Vector3 Size { get; set; }
149 216
217 public virtual void setAvatarSize(Vector3 size, float feetOffset)
218 {
219 Size = size;
220 }
221
222 public virtual bool Phantom { get; set; }
223
224 public virtual bool IsVolumeDtc
225 {
226 get { return false; }
227 set { return; }
228 }
229
150 public virtual byte PhysicsShapeType { get; set; } 230 public virtual byte PhysicsShapeType { get; set; }
151 231
152 public abstract PrimitiveBaseShape Shape { set; } 232 public abstract PrimitiveBaseShape Shape { set; }
@@ -169,20 +249,21 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
169 /// XXX: Bizarrely, this cannot be "Terrain" or "Water" right now unless it really is simulating terrain or 249 /// XXX: Bizarrely, this cannot be "Terrain" or "Water" right now unless it really is simulating terrain or
170 /// water. This is not a problem due to the formatting of names given by prims and avatars. 250 /// water. This is not a problem due to the formatting of names given by prims and avatars.
171 /// </remarks> 251 /// </remarks>
172 public string Name { get; protected set; } 252 public string Name { get; set; }
173 253
174 /// <summary> 254 /// <summary>
175 /// This is being used by ODE joint code. 255 /// This is being used by ODE joint code.
176 /// </summary> 256 /// </summary>
177 public string SOPName; 257 public string SOPName;
178 258
259 public virtual void CrossingStart() { }
179 public abstract void CrossingFailure(); 260 public abstract void CrossingFailure();
180 261
181 public abstract void link(PhysicsActor obj); 262 public abstract void link(PhysicsActor obj);
182 263
183 public abstract void delink(); 264 public abstract void delink();
184 265
185 public abstract void LockAngularMotion(Vector3 axis); 266 public abstract void LockAngularMotion(byte axislocks);
186 267
187 public virtual void RequestPhysicsterseUpdate() 268 public virtual void RequestPhysicsterseUpdate()
188 { 269 {
@@ -245,6 +326,56 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
245 public abstract void VehicleRotationParam(int param, Quaternion rotation); 326 public abstract void VehicleRotationParam(int param, Quaternion rotation);
246 public abstract void VehicleFlags(int param, bool remove); 327 public abstract void VehicleFlags(int param, bool remove);
247 328
329 // This is an overridable version of SetVehicle() that works for all physics engines.
330 // This is VERY inefficient. It behoves any physics engine to override this and
331 // implement a more efficient setting of all the vehicle parameters.
332 public virtual void SetVehicle(object pvdata)
333 {
334 VehicleData vdata = (VehicleData)pvdata;
335 // vehicleActor.ProcessSetVehicle((VehicleData)vdata);
336
337 this.VehicleType = (int)vdata.m_type;
338 this.VehicleFlags(-1, false); // clears all flags
339 this.VehicleFlags((int)vdata.m_flags, false);
340
341 // Linear properties
342 this.VehicleVectorParam((int)Vehicle.LINEAR_MOTOR_DIRECTION, vdata.m_linearMotorDirection);
343 this.VehicleVectorParam((int)Vehicle.LINEAR_FRICTION_TIMESCALE, vdata.m_linearFrictionTimescale);
344 this.VehicleFloatParam((int)Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE, vdata.m_linearMotorDecayTimescale);
345 this.VehicleFloatParam((int)Vehicle.LINEAR_MOTOR_TIMESCALE, vdata.m_linearMotorTimescale);
346 this.VehicleVectorParam((int)Vehicle.LINEAR_MOTOR_OFFSET, vdata.m_linearMotorOffset);
347
348 //Angular properties
349 this.VehicleVectorParam((int)Vehicle.ANGULAR_MOTOR_DIRECTION, vdata.m_angularMotorDirection);
350 this.VehicleFloatParam((int)Vehicle.ANGULAR_MOTOR_TIMESCALE, vdata.m_angularMotorTimescale);
351 this.VehicleFloatParam((int)Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE, vdata.m_angularMotorDecayTimescale);
352 this.VehicleVectorParam((int)Vehicle.ANGULAR_FRICTION_TIMESCALE, vdata.m_angularFrictionTimescale);
353
354 //Deflection properties
355 this.VehicleFloatParam((int)Vehicle.ANGULAR_DEFLECTION_EFFICIENCY, vdata.m_angularDeflectionEfficiency);
356 this.VehicleFloatParam((int)Vehicle.ANGULAR_DEFLECTION_TIMESCALE, vdata.m_angularDeflectionTimescale);
357 this.VehicleFloatParam((int)Vehicle.LINEAR_DEFLECTION_EFFICIENCY, vdata.m_linearDeflectionEfficiency);
358 this.VehicleFloatParam((int)Vehicle.LINEAR_DEFLECTION_TIMESCALE, vdata.m_linearDeflectionTimescale);
359
360 //Banking properties
361 this.VehicleFloatParam((int)Vehicle.BANKING_EFFICIENCY, vdata.m_bankingEfficiency);
362 this.VehicleFloatParam((int)Vehicle.BANKING_MIX, vdata.m_bankingMix);
363 this.VehicleFloatParam((int)Vehicle.BANKING_TIMESCALE, vdata.m_bankingTimescale);
364
365 //Hover and Buoyancy properties
366 this.VehicleFloatParam((int)Vehicle.HOVER_HEIGHT, vdata.m_VhoverHeight);
367 this.VehicleFloatParam((int)Vehicle.HOVER_EFFICIENCY, vdata.m_VhoverEfficiency);
368 this.VehicleFloatParam((int)Vehicle.HOVER_TIMESCALE, vdata.m_VhoverTimescale);
369 this.VehicleFloatParam((int)Vehicle.BUOYANCY, vdata.m_VehicleBuoyancy);
370
371 //Attractor properties
372 this.VehicleFloatParam((int)Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, vdata.m_verticalAttractionEfficiency);
373 this.VehicleFloatParam((int)Vehicle.VERTICAL_ATTRACTION_TIMESCALE, vdata.m_verticalAttractionTimescale);
374
375 this.VehicleRotationParam((int)Vehicle.REFERENCE_FRAME, vdata.m_referenceFrame);
376 }
377
378
248 /// <summary> 379 /// <summary>
249 /// Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more 380 /// Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
250 /// </summary> 381 /// </summary>
@@ -253,6 +384,22 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
253 public abstract Vector3 GeometricCenter { get; } 384 public abstract Vector3 GeometricCenter { get; }
254 public abstract Vector3 CenterOfMass { get; } 385 public abstract Vector3 CenterOfMass { get; }
255 386
387 public virtual float PhysicsCost
388 {
389 get
390 {
391 return 0.1f;
392 }
393 }
394
395 public virtual float StreamCost
396 {
397 get
398 {
399 return 1.0f;
400 }
401 }
402
256 /// <summary> 403 /// <summary>
257 /// The desired velocity of this actor. 404 /// The desired velocity of this actor.
258 /// </summary> 405 /// </summary>
@@ -271,6 +418,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
271 } 418 }
272 419
273 public abstract Vector3 Velocity { get; set; } 420 public abstract Vector3 Velocity { get; set; }
421 public virtual Vector3 rootVelocity { get { return Vector3.Zero; } }
274 422
275 public abstract Vector3 Torque { get; set; } 423 public abstract Vector3 Torque { get; set; }
276 public abstract float CollisionScore { get; set;} 424 public abstract float CollisionScore { get; set;}
@@ -296,7 +444,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
296 444
297 // Used for llSetHoverHeight and maybe vehicle height 445 // Used for llSetHoverHeight and maybe vehicle height
298 // Hover Height will override MoveTo target's Z 446 // Hover Height will override MoveTo target's Z
299 public abstract bool PIDHoverActive { set;} 447 public abstract bool PIDHoverActive {get; set;}
300 public abstract float PIDHoverHeight { set;} 448 public abstract float PIDHoverHeight { set;}
301 public abstract PIDHoverType PIDHoverType { set;} 449 public abstract PIDHoverType PIDHoverType { set;}
302 public abstract float PIDHoverTau { set;} 450 public abstract float PIDHoverTau { set;}
@@ -306,7 +454,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
306 public abstract bool APIDActive { set;} 454 public abstract bool APIDActive { set;}
307 public abstract float APIDStrength { set;} 455 public abstract float APIDStrength { set;}
308 public abstract float APIDDamping { set;} 456 public abstract float APIDDamping { set;}
309 457
310 public abstract void AddForce(Vector3 force, bool pushforce); 458 public abstract void AddForce(Vector3 force, bool pushforce);
311 public abstract void AddAngularForce(Vector3 force, bool pushforce); 459 public abstract void AddAngularForce(Vector3 force, bool pushforce);
312 public abstract void SetMomentum(Vector3 momentum); 460 public abstract void SetMomentum(Vector3 momentum);
@@ -314,6 +462,29 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
314 public abstract void UnSubscribeEvents(); 462 public abstract void UnSubscribeEvents();
315 public abstract bool SubscribedEvents(); 463 public abstract bool SubscribedEvents();
316 464
465 public virtual void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { }
466 public virtual void AddVDTCCollisionEvent(uint CollidedWith, ContactPoint contact) { }
467
468 public virtual PhysicsInertiaData GetInertiaData()
469 {
470 PhysicsInertiaData data = new PhysicsInertiaData();
471 data.TotalMass = this.Mass;
472 data.CenterOfMass = CenterOfMass - Position;
473 data.Inertia = Vector3.Zero;
474 data.InertiaRotation = Vector4.Zero;
475 return data;
476 }
477
478 public virtual void SetInertiaData(PhysicsInertiaData inertia)
479 {
480 }
481
482 public virtual float SimulationSuspended { get; set; }
483
484 // Warning in a parent part it returns itself, not null
485 public virtual PhysicsActor ParentActor { get { return this; } }
486
487
317 // Extendable interface for new, physics engine specific operations 488 // Extendable interface for new, physics engine specific operations
318 public virtual object Extension(string pFunct, params object[] pParams) 489 public virtual object Extension(string pFunct, params object[] pParams)
319 { 490 {
@@ -324,9 +495,11 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
324 495
325 public class NullPhysicsActor : PhysicsActor 496 public class NullPhysicsActor : PhysicsActor
326 { 497 {
498 private ActorTypes m_actorType = ActorTypes.Unknown;
499
327 public override bool Stopped 500 public override bool Stopped
328 { 501 {
329 get{ return false; } 502 get{ return true; }
330 } 503 }
331 504
332 public override Vector3 Position 505 public override Vector3 Position
@@ -343,6 +516,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
343 516
344 public override uint LocalID 517 public override uint LocalID
345 { 518 {
519 get { return 0; }
346 set { return; } 520 set { return; }
347 } 521 }
348 522
@@ -402,50 +576,17 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
402 set { return; } 576 set { return; }
403 } 577 }
404 578
405 public override void VehicleFloatParam(int param, float value) 579 public override void VehicleFloatParam(int param, float value) {}
406 { 580 public override void VehicleVectorParam(int param, Vector3 value) { }
581 public override void VehicleRotationParam(int param, Quaternion rotation) { }
582 public override void VehicleFlags(int param, bool remove) { }
583 public override void SetVolumeDetect(int param) {}
584 public override void SetMaterial(int material) {}
585 public override Vector3 CenterOfMass { get { return Vector3.Zero; }}
407 586
408 } 587 public override Vector3 GeometricCenter { get { return Vector3.Zero; }}
409
410 public override void VehicleVectorParam(int param, Vector3 value)
411 {
412 588
413 } 589 public override PrimitiveBaseShape Shape { set { return; }}
414
415 public override void VehicleRotationParam(int param, Quaternion rotation)
416 {
417
418 }
419
420 public override void VehicleFlags(int param, bool remove)
421 {
422
423 }
424
425 public override void SetVolumeDetect(int param)
426 {
427
428 }
429
430 public override void SetMaterial(int material)
431 {
432
433 }
434
435 public override Vector3 CenterOfMass
436 {
437 get { return Vector3.Zero; }
438 }
439
440 public override Vector3 GeometricCenter
441 {
442 get { return Vector3.Zero; }
443 }
444
445 public override PrimitiveBaseShape Shape
446 {
447 set { return; }
448 }
449 590
450 public override Vector3 Velocity 591 public override Vector3 Velocity
451 { 592 {
@@ -465,9 +606,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
465 set { } 606 set { }
466 } 607 }
467 608
468 public override void CrossingFailure() 609 public override void CrossingFailure() {}
469 {
470 }
471 610
472 public override Quaternion Orientation 611 public override Quaternion Orientation
473 { 612 {
@@ -507,8 +646,20 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
507 646
508 public override int PhysicsActorType 647 public override int PhysicsActorType
509 { 648 {
510 get { return (int) ActorTypes.Unknown; } 649 get { return (int)m_actorType; }
511 set { return; } 650 set {
651 ActorTypes type = (ActorTypes)value;
652 switch (type)
653 {
654 case ActorTypes.Ground:
655 case ActorTypes.Water:
656 m_actorType = type;
657 break;
658 default:
659 m_actorType = ActorTypes.Unknown;
660 break;
661 }
662 }
512 } 663 }
513 664
514 public override bool Kinematic 665 public override bool Kinematic
@@ -517,26 +668,11 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
517 set { return; } 668 set { return; }
518 } 669 }
519 670
520 public override void link(PhysicsActor obj) 671 public override void link(PhysicsActor obj) { }
521 { 672 public override void delink() { }
522 } 673 public override void LockAngularMotion(byte axislocks) { }
523 674 public override void AddForce(Vector3 force, bool pushforce) { }
524 public override void delink() 675 public override void AddAngularForce(Vector3 force, bool pushforce) { }
525 {
526 }
527
528 public override void LockAngularMotion(Vector3 axis)
529 {
530 }
531
532 public override void AddForce(Vector3 force, bool pushforce)
533 {
534 }
535
536 public override void AddAngularForce(Vector3 force, bool pushforce)
537 {
538
539 }
540 676
541 public override Vector3 RotationalVelocity 677 public override Vector3 RotationalVelocity
542 { 678 {
@@ -546,39 +682,28 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
546 682
547 public override Vector3 PIDTarget { set { return; } } 683 public override Vector3 PIDTarget { set { return; } }
548 684
549 public override bool PIDActive 685 public override bool PIDActive
550 { 686 {
551 get { return false; } 687 get { return false; }
552 set { return; } 688 set { return; }
553 } 689 }
554 690
555 public override float PIDTau { set { return; } } 691 public override float PIDTau { set { return; } }
556 692
557 public override float PIDHoverHeight { set { return; } } 693 public override float PIDHoverHeight { set { return; } }
558 public override bool PIDHoverActive { set { return; } } 694 public override bool PIDHoverActive {get {return false;} set { return; } }
559 public override PIDHoverType PIDHoverType { set { return; } } 695 public override PIDHoverType PIDHoverType { set { return; } }
560 public override float PIDHoverTau { set { return; } } 696 public override float PIDHoverTau { set { return; } }
561 697
562 public override Quaternion APIDTarget { set { return; } } 698 public override Quaternion APIDTarget { set { return; } }
563 public override bool APIDActive { set { return; } } 699 public override bool APIDActive { set { return; } }
564 public override float APIDStrength { set { return; } } 700 public override float APIDStrength { set { return; } }
565 public override float APIDDamping { set { return; } } 701 public override float APIDDamping { set { return; } }
566
567 public override void SetMomentum(Vector3 momentum)
568 {
569 }
570
571 public override void SubscribeEvents(int ms)
572 {
573 702
574 } 703 public override void SetMomentum(Vector3 momentum) { }
575 public override void UnSubscribeEvents()
576 {
577 704
578 } 705 public override void SubscribeEvents(int ms) { }
579 public override bool SubscribedEvents() 706 public override void UnSubscribeEvents() { }
580 { 707 public override bool SubscribedEvents() { return false; }
581 return false;
582 }
583 } 708 }
584} 709}
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs
index 32691fc..e8d6334 100644
--- a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs
+++ b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs
@@ -41,6 +41,10 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
41 41
42 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); 42 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal);
43 public delegate void RayCallback(List<ContactResult> list); 43 public delegate void RayCallback(List<ContactResult> list);
44 public delegate void ProbeBoxCallback(List<ContactResult> list);
45 public delegate void ProbeSphereCallback(List<ContactResult> list);
46 public delegate void ProbePlaneCallback(List<ContactResult> list);
47 public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation);
44 48
45 public delegate void JointMoved(PhysicsJoint joint); 49 public delegate void JointMoved(PhysicsJoint joint);
46 public delegate void JointDeactivated(PhysicsJoint joint); 50 public delegate void JointDeactivated(PhysicsJoint joint);
@@ -89,6 +93,8 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
89 public Vector3 Normal; 93 public Vector3 Normal;
90 } 94 }
91 95
96
97
92 public abstract class PhysicsScene 98 public abstract class PhysicsScene
93 { 99 {
94// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 100// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -106,6 +112,8 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
106 /// </summary> 112 /// </summary>
107 public string EngineType { get; protected set; } 113 public string EngineType { get; protected set; }
108 114
115 public string EngineName { get; protected set; }
116
109 // The only thing that should register for this event is the SceneGraph 117 // The only thing that should register for this event is the SceneGraph
110 // Anything else could cause problems. 118 // Anything else could cause problems.
111 public event physicsCrash OnPhysicsCrash; 119 public event physicsCrash OnPhysicsCrash;
@@ -143,6 +151,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
143 /// <param name="size"></param> 151 /// <param name="size"></param>
144 /// <param name="isFlying"></param> 152 /// <param name="isFlying"></param>
145 /// <returns></returns> 153 /// <returns></returns>
154
146 public abstract PhysicsActor AddAvatar( 155 public abstract PhysicsActor AddAvatar(
147 string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying); 156 string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying);
148 157
@@ -161,12 +170,26 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
161 { 170 {
162 PhysicsActor ret = AddAvatar(avName, position, velocity, size, isFlying); 171 PhysicsActor ret = AddAvatar(avName, position, velocity, size, isFlying);
163 172
164 if (ret != null) 173 if (ret != null)
165 ret.LocalID = localID; 174 ret.LocalID = localID;
166 175
167 return ret; 176 return ret;
168 } 177 }
169 178
179 public virtual PhysicsActor AddAvatar(
180 uint localID, string avName, Vector3 position, Vector3 size, bool isFlying)
181 {
182 PhysicsActor ret = AddAvatar(localID, avName, position, Vector3.Zero, size, isFlying);
183 return ret;
184 }
185
186 public virtual PhysicsActor AddAvatar(
187 uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying)
188 {
189 PhysicsActor ret = AddAvatar(localID, avName, position, Vector3.Zero, size, isFlying);
190 return ret;
191 }
192
170 /// <summary> 193 /// <summary>
171 /// Remove an avatar. 194 /// Remove an avatar.
172 /// </summary> 195 /// </summary>
@@ -182,6 +205,19 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
182 public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 205 public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
183 Vector3 size, Quaternion rotation, bool isPhysical, uint localid); 206 Vector3 size, Quaternion rotation, bool isPhysical, uint localid);
184 207
208 public virtual PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
209 uint localid, byte[] sdata)
210 {
211 return null;
212 }
213
214 public virtual PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
215 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid)
216 {
217 return AddPrimShape(primName, pbs, position, size, rotation, isPhysical, localid);
218 }
219
220
185 public virtual PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 221 public virtual PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
186 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapetype, uint localid) 222 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapetype, uint localid)
187 { 223 {
@@ -255,6 +291,9 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
255 291
256 public abstract void AddPhysicsActorTaint(PhysicsActor prim); 292 public abstract void AddPhysicsActorTaint(PhysicsActor prim);
257 293
294
295 public virtual void ProcessPreSimulation() { }
296
258 /// <summary> 297 /// <summary>
259 /// Perform a simulation of the current physics scene over the given timestep. 298 /// Perform a simulation of the current physics scene over the given timestep.
260 /// </summary> 299 /// </summary>
@@ -293,28 +332,19 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
293 return false; 332 return false;
294 } 333 }
295 334
296 public virtual bool SupportsCombining()
297 {
298 return false;
299 }
300
301 public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) {}
302
303 public virtual void UnCombine(PhysicsScene pScene) {}
304
305 /// <summary> 335 /// <summary>
306 /// Queue a raycast against the physics scene. 336 /// Queue a raycast against the physics scene.
307 /// The provided callback method will be called when the raycast is complete 337 /// The provided callback method will be called when the raycast is complete
308 /// 338 ///
309 /// Many physics engines don't support collision testing at the same time as 339 /// Many physics engines don't support collision testing at the same time as
310 /// manipulating the physics scene, so we queue the request up and callback 340 /// manipulating the physics scene, so we queue the request up and callback
311 /// a custom method when the raycast is complete. 341 /// a custom method when the raycast is complete.
312 /// This allows physics engines that give an immediate result to callback immediately 342 /// This allows physics engines that give an immediate result to callback immediately
313 /// and ones that don't, to callback when it gets a result back. 343 /// and ones that don't, to callback when it gets a result back.
314 /// 344 ///
315 /// ODE for example will not allow you to change the scene while collision testing or 345 /// ODE for example will not allow you to change the scene while collision testing or
316 /// it asserts, 'opteration not valid for locked space'. This includes adding a ray to the scene. 346 /// it asserts, 'opteration not valid for locked space'. This includes adding a ray to the scene.
317 /// 347 ///
318 /// This is named RayCastWorld to not conflict with modrex's Raycast method. 348 /// This is named RayCastWorld to not conflict with modrex's Raycast method.
319 /// </summary> 349 /// </summary>
320 /// <param name="position">Origin of the ray</param> 350 /// <param name="position">Origin of the ray</param>
@@ -348,6 +378,31 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
348 return false; 378 return false;
349 } 379 }
350 380
381 public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags)
382 {
383 return new List<ContactResult>();
384 }
385
386 public virtual List<ContactResult> BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags)
387 {
388 return new List<ContactResult>();
389 }
390
391 public virtual List<ContactResult> SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags)
392 {
393 return new List<ContactResult>();
394 }
395
396 public virtual List<ContactResult> PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags)
397 {
398 return new List<ContactResult>();
399 }
400
401 public virtual int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
402 {
403 return 0;
404 }
405
351 // Extendable interface for new, physics engine specific operations 406 // Extendable interface for new, physics engine specific operations
352 public virtual object Extension(string pFunct, params object[] pParams) 407 public virtual object Extension(string pFunct, params object[] pParams)
353 { 408 {
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsVector.cs b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsVector.cs
index 76a82fa..5aae42f 100644
--- a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsVector.cs
+++ b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsVector.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
49 public Vector3(Vector3 pv) : this(pv.X, pv.Y, pv.Z) 49 public Vector3(Vector3 pv) : this(pv.X, pv.Y, pv.Z)
50 { 50 {
51 } 51 }
52 52
53 public void setValues(float x, float y, float z) 53 public void setValues(float x, float y, float z)
54 { 54 {
55 X = x; 55 X = x;
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/VehicleConstants.cs b/OpenSim/Region/PhysicsModules/SharedBase/VehicleConstants.cs
index 63a8cb8..0b4c8c6 100644
--- a/OpenSim/Region/PhysicsModules/SharedBase/VehicleConstants.cs
+++ b/OpenSim/Region/PhysicsModules/SharedBase/VehicleConstants.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using OpenMetaverse;
29 30
30namespace OpenSim.Region.PhysicsModules.SharedBase 31namespace OpenSim.Region.PhysicsModules.SharedBase
31{ 32{
@@ -37,7 +38,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
37 TYPE_NONE = 0, 38 TYPE_NONE = 0,
38 39
39 /// <summary> 40 /// <summary>
40 /// No Angular motor, High Left right friction, No Hover, Linear Deflection 1, no angular deflection 41 /// No Angular motor, High Left right friction, No Hover, Linear Deflection 1, no angular deflection
41 /// no vertical attractor, No banking, Identity rotation frame 42 /// no vertical attractor, No banking, Identity rotation frame
42 /// </summary> 43 /// </summary>
43 TYPE_SLED = 1, 44 TYPE_SLED = 1,
@@ -117,5 +118,47 @@ namespace OpenSim.Region.PhysicsModules.SharedBase
117 NO_DEFLECTION = 16392, 118 NO_DEFLECTION = 16392,
118 LOCK_ROTATION = 32784 119 LOCK_ROTATION = 32784
119 } 120 }
120 121
122 public struct VehicleData
123 {
124 public Vehicle m_type;
125 public VehicleFlag m_flags;
126
127 // Linear properties
128 public Vector3 m_linearMotorDirection;
129 public Vector3 m_linearFrictionTimescale;
130 public float m_linearMotorDecayTimescale;
131 public float m_linearMotorTimescale;
132 public Vector3 m_linearMotorOffset;
133
134 //Angular properties
135 public Vector3 m_angularMotorDirection;
136 public float m_angularMotorTimescale;
137 public float m_angularMotorDecayTimescale;
138 public Vector3 m_angularFrictionTimescale;
139
140 //Deflection properties
141 public float m_angularDeflectionEfficiency;
142 public float m_angularDeflectionTimescale;
143 public float m_linearDeflectionEfficiency;
144 public float m_linearDeflectionTimescale;
145
146 //Banking properties
147 public float m_bankingEfficiency;
148 public float m_bankingMix;
149 public float m_bankingTimescale;
150
151 //Hover and Buoyancy properties
152 public float m_VhoverHeight;
153 public float m_VhoverEfficiency;
154 public float m_VhoverTimescale;
155 public float m_VehicleBuoyancy;
156
157 //Attractor properties
158 public float m_verticalAttractionEfficiency;
159 public float m_verticalAttractionTimescale;
160
161 // Axis
162 public Quaternion m_referenceFrame;
163 }
121} 164}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs
new file mode 100644
index 0000000..35adf11
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs
@@ -0,0 +1,2024 @@
1/*
2 * based on:
3 * Ode.NET - .NET bindings for ODE
4 * Jason Perkins (starkos@industriousone.com)
5 * Licensed under the New BSD
6 * Part of the OpenDynamicsEngine
7Open Dynamics Engine
8Copyright (c) 2001-2007, Russell L. Smith.
9All rights reserved.
10
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions
13are met:
14
15Redistributions of source code must retain the above copyright notice,
16this list of conditions and the following disclaimer.
17
18Redistributions in binary form must reproduce the above copyright notice,
19this list of conditions and the following disclaimer in the documentation
20and/or other materials provided with the distribution.
21
22Neither the names of ODE's copyright owner nor the names of its
23contributors may be used to endorse or promote products derived from
24this software without specific prior written permission.
25
26THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
32TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 * changes by opensim team;
39 * changes by Aurora team http://www.aurora-sim.org/
40 * changes by Ubit Umarov
41 */
42
43using System;
44using System.Runtime.InteropServices;
45using System.Security;
46using OMV = OpenMetaverse;
47namespace OdeAPI
48{
49//#if dDOUBLE
50// don't see much use in double precision with time steps of 20ms and 10 iterations used on opensim
51// at least we save same memory and memory access time, FPU performance on intel usually is similar
52// using dReal = System.Double;
53//#else
54 using dReal = System.Single;
55//#endif
56
57 public static class d
58 {
59 public static dReal Infinity = dReal.MaxValue;
60 public static int NTotalBodies = 0;
61 public static int NTotalGeoms = 0;
62
63 public const uint CONTACTS_UNIMPORTANT = 0x80000000;
64
65 #region Flags and Enumerations
66
67 [Flags]
68 public enum AllocateODEDataFlags : uint
69 {
70 BasicData = 0,
71 CollisionData = 0x00000001,
72 All = ~0u
73 }
74
75 [Flags]
76 public enum IniteODEFlags : uint
77 {
78 dInitFlagManualThreadCleanup = 0x00000001
79 }
80
81 [Flags]
82 public enum ContactFlags : int
83 {
84 Mu2 = 0x001,
85 FDir1 = 0x002,
86 Bounce = 0x004,
87 SoftERP = 0x008,
88 SoftCFM = 0x010,
89 Motion1 = 0x020,
90 Motion2 = 0x040,
91 MotionN = 0x080,
92 Slip1 = 0x100,
93 Slip2 = 0x200,
94 Approx0 = 0x0000,
95 Approx1_1 = 0x1000,
96 Approx1_2 = 0x2000,
97 Approx1 = 0x3000
98 }
99
100 public enum GeomClassID : int
101 {
102 SphereClass,
103 BoxClass,
104 CapsuleClass,
105 CylinderClass,
106 PlaneClass,
107 RayClass,
108 ConvexClass,
109 GeomTransformClass,
110 TriMeshClass,
111 HeightfieldClass,
112 FirstSpaceClass,
113 SimpleSpaceClass = FirstSpaceClass,
114 HashSpaceClass,
115 QuadTreeSpaceClass,
116 LastSpaceClass = QuadTreeSpaceClass,
117 ubtTerrainClass,
118 FirstUserClass,
119 LastUserClass = FirstUserClass + MaxUserClasses - 1,
120 NumClasses,
121 MaxUserClasses = 5
122 }
123
124 public enum JointType : int
125 {
126 None,
127 Ball,
128 Hinge,
129 Slider,
130 Contact,
131 Universal,
132 Hinge2,
133 Fixed,
134 Null,
135 AMotor,
136 LMotor,
137 Plane2D
138 }
139
140 public enum JointParam : int
141 {
142 LoStop,
143 HiStop,
144 Vel,
145 FMax,
146 FudgeFactor,
147 Bounce,
148 CFM,
149 StopERP,
150 StopCFM,
151 SuspensionERP,
152 SuspensionCFM,
153 LoStop2 = 256,
154 HiStop2,
155 Vel2,
156 FMax2,
157 FudgeFactor2,
158 Bounce2,
159 CFM2,
160 StopERP2,
161 StopCFM2,
162 SuspensionERP2,
163 SuspensionCFM2,
164 LoStop3 = 512,
165 HiStop3,
166 Vel3,
167 FMax3,
168 FudgeFactor3,
169 Bounce3,
170 CFM3,
171 StopERP3,
172 StopCFM3,
173 SuspensionERP3,
174 SuspensionCFM3
175 }
176
177 public enum dSweepAndPruneAxis : int
178 {
179 XYZ = ((0)|(1<<2)|(2<<4)),
180 XZY = ((0)|(2<<2)|(1<<4)),
181 YXZ = ((1)|(0<<2)|(2<<4)),
182 YZX = ((1)|(2<<2)|(0<<4)),
183 ZXY = ((2)|(0<<2)|(1<<4)),
184 ZYX = ((2)|(1<<2)|(0<<4))
185 }
186
187 #endregion
188
189 #region Callbacks
190
191 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
192 public delegate int AABBTestFn(IntPtr o1, IntPtr o2, ref AABB aabb);
193
194 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
195 public delegate int ColliderFn(IntPtr o1, IntPtr o2, int flags, out ContactGeom contact, int skip);
196
197 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
198 public delegate void GetAABBFn(IntPtr geom, out AABB aabb);
199
200 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
201 public delegate ColliderFn GetColliderFnFn(int num);
202
203 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
204 public delegate void GeomDtorFn(IntPtr o);
205
206 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
207 public delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z);
208
209 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
210 public delegate dReal OSTerrainGetHeight(IntPtr p_user_data, int x, int z);
211
212 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
213 public delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2);
214
215 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
216 public delegate int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex);
217
218 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
219 public delegate int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount);
220
221 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
222 public delegate int TriRayCallback(IntPtr trimesh, IntPtr ray, int triangleIndex, dReal u, dReal v);
223
224 #endregion
225
226 #region Structs
227
228 [StructLayout(LayoutKind.Sequential)]
229 public struct AABB
230 {
231 public dReal MinX, MaxX;
232 public dReal MinY, MaxY;
233 public dReal MinZ, MaxZ;
234 }
235
236
237 [StructLayout(LayoutKind.Sequential)]
238 public struct Contact
239 {
240 public SurfaceParameters surface;
241 public ContactGeom geom;
242 public Vector3 fdir1;
243 public static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(Contact));
244 }
245
246
247 [StructLayout(LayoutKind.Sequential)]
248 public struct ContactGeom
249 {
250
251 public Vector3 pos;
252 public Vector3 normal;
253 public dReal depth;
254 public IntPtr g1;
255 public IntPtr g2;
256 public int side1;
257 public int side2;
258 public static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(ContactGeom));
259 }
260
261 [StructLayout(LayoutKind.Sequential)]
262 public struct GeomClass
263 {
264 public int bytes;
265 public GetColliderFnFn collider;
266 public GetAABBFn aabb;
267 public AABBTestFn aabb_test;
268 public GeomDtorFn dtor;
269 }
270
271
272 [StructLayout(LayoutKind.Sequential)]
273 public struct JointFeedback
274 {
275 public Vector3 f1;
276 public Vector3 t1;
277 public Vector3 f2;
278 public Vector3 t2;
279 }
280
281
282 [StructLayout(LayoutKind.Sequential)]
283 public struct Mass
284 {
285 public dReal mass;
286 public Vector4 c;
287 public Matrix3 I;
288 }
289
290
291 [StructLayout(LayoutKind.Sequential)]
292 public struct Matrix3
293 {
294 public Matrix3(dReal m00, dReal m10, dReal m20, dReal m01, dReal m11, dReal m21, dReal m02, dReal m12, dReal m22)
295 {
296 M00 = m00; M10 = m10; M20 = m20; _m30 = 0.0f;
297 M01 = m01; M11 = m11; M21 = m21; _m31 = 0.0f;
298 M02 = m02; M12 = m12; M22 = m22; _m32 = 0.0f;
299 }
300 public dReal M00, M10, M20;
301 private dReal _m30;
302 public dReal M01, M11, M21;
303 private dReal _m31;
304 public dReal M02, M12, M22;
305 private dReal _m32;
306 }
307
308 [StructLayout(LayoutKind.Sequential)]
309 public struct Matrix4
310 {
311 public Matrix4(dReal m00, dReal m10, dReal m20, dReal m30,
312 dReal m01, dReal m11, dReal m21, dReal m31,
313 dReal m02, dReal m12, dReal m22, dReal m32,
314 dReal m03, dReal m13, dReal m23, dReal m33)
315 {
316 M00 = m00; M10 = m10; M20 = m20; M30 = m30;
317 M01 = m01; M11 = m11; M21 = m21; M31 = m31;
318 M02 = m02; M12 = m12; M22 = m22; M32 = m32;
319 M03 = m03; M13 = m13; M23 = m23; M33 = m33;
320 }
321 public dReal M00, M10, M20, M30;
322 public dReal M01, M11, M21, M31;
323 public dReal M02, M12, M22, M32;
324 public dReal M03, M13, M23, M33;
325 }
326
327 [StructLayout(LayoutKind.Sequential)]
328 public struct Quaternion
329 {
330 public dReal W, X, Y, Z;
331 }
332
333
334 [StructLayout(LayoutKind.Sequential)]
335 public struct SurfaceParameters
336 {
337 public ContactFlags mode;
338 public dReal mu;
339 public dReal mu2;
340 public dReal bounce;
341 public dReal bounce_vel;
342 public dReal soft_erp;
343 public dReal soft_cfm;
344 public dReal motion1;
345 public dReal motion2;
346 public dReal motionN;
347 public dReal slip1;
348 public dReal slip2;
349 }
350
351
352 [StructLayout(LayoutKind.Sequential)]
353 public struct Vector3
354 {
355 public Vector3(dReal x, dReal y, dReal z)
356 {
357 X = x; Y = y; Z = z; _w = 0.0f;
358 }
359 public dReal X, Y, Z;
360 private dReal _w;
361 }
362
363
364 [StructLayout(LayoutKind.Sequential)]
365 public struct Vector4
366 {
367 public Vector4(dReal x, dReal y, dReal z, dReal w)
368 {
369 X = x; Y = y; Z = z; W = w;
370 }
371 public dReal X, Y, Z, W;
372 }
373
374 #endregion
375
376 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAllocateODEDataForThread"), SuppressUnmanagedCodeSecurity]
377 public static extern int AllocateODEDataForThread(uint ODEInitFlags);
378
379 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAreConnected"), SuppressUnmanagedCodeSecurity]
380 public static extern bool AreConnected(IntPtr b1, IntPtr b2);
381
382 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAreConnectedExcluding"), SuppressUnmanagedCodeSecurity]
383 public static extern bool AreConnectedExcluding(IntPtr b1, IntPtr b2, JointType joint_type);
384
385 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForce"), SuppressUnmanagedCodeSecurity]
386 public static extern void BodyAddForce(IntPtr body, dReal fx, dReal fy, dReal fz);
387
388 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForceAtPos"), SuppressUnmanagedCodeSecurity]
389 public static extern void BodyAddForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
390
391 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForceAtRelPos"), SuppressUnmanagedCodeSecurity]
392 public static extern void BodyAddForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
393
394 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForce"), SuppressUnmanagedCodeSecurity]
395 public static extern void BodyAddRelForce(IntPtr body, dReal fx, dReal fy, dReal fz);
396
397 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForceAtPos"), SuppressUnmanagedCodeSecurity]
398 public static extern void BodyAddRelForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
399
400 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForceAtRelPos"), SuppressUnmanagedCodeSecurity]
401 public static extern void BodyAddRelForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
402
403 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelTorque"), SuppressUnmanagedCodeSecurity]
404 public static extern void BodyAddRelTorque(IntPtr body, dReal fx, dReal fy, dReal fz);
405
406 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddTorque"), SuppressUnmanagedCodeSecurity]
407 public static extern void BodyAddTorque(IntPtr body, dReal fx, dReal fy, dReal fz);
408
409 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity]
410 public static extern void BodyCopyPosition(IntPtr body, out Vector3 pos);
411
412 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity]
413 public static extern void BodyCopyPosition(IntPtr body, out dReal X);
414
415 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity]
416 public static extern void BodyCopyQuaternion(IntPtr body, out Quaternion quat);
417
418 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity]
419 public static extern void BodyCopyQuaternion(IntPtr body, out dReal X);
420
421 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity]
422 public static extern void BodyCopyRotation(IntPtr body, out Matrix3 R);
423
424 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity]
425 public static extern void BodyCopyRotation(IntPtr body, out dReal M00);
426
427 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCreate"), SuppressUnmanagedCodeSecurity]
428 public static extern IntPtr BodyiCreate(IntPtr world);
429 public static IntPtr BodyCreate(IntPtr world)
430 {
431 NTotalBodies++;
432 return BodyiCreate(world);
433 }
434
435 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyDestroy"), SuppressUnmanagedCodeSecurity]
436 public static extern void BodyiDestroy(IntPtr body);
437 public static void BodyDestroy(IntPtr body)
438 {
439 NTotalBodies--;
440 BodyiDestroy(body);
441 }
442
443 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyDisable"), SuppressUnmanagedCodeSecurity]
444 public static extern void BodyDisable(IntPtr body);
445
446 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyEnable"), SuppressUnmanagedCodeSecurity]
447 public static extern void BodyEnable(IntPtr body);
448
449 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity]
450 public static extern dReal BodyGetAutoDisableAngularThreshold(IntPtr body);
451
452 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity]
453 public static extern bool BodyGetAutoDisableFlag(IntPtr body);
454
455 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableDefaults"), SuppressUnmanagedCodeSecurity]
456 public static extern void BodyGetAutoDisableDefaults(IntPtr body);
457
458 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity]
459 public static extern dReal BodyGetAutoDisableLinearThreshold(IntPtr body);
460
461 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity]
462 public static extern int BodyGetAutoDisableSteps(IntPtr body);
463
464 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableTime"), SuppressUnmanagedCodeSecurity]
465 public static extern dReal BodyGetAutoDisableTime(IntPtr body);
466
467 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularVel"), SuppressUnmanagedCodeSecurity]
468 public extern unsafe static Vector3* BodyGetAngularVelUnsafe(IntPtr body);
469 public static Vector3 BodyGetAngularVel(IntPtr body)
470 {
471 unsafe { return *(BodyGetAngularVelUnsafe(body)); }
472 }
473
474 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetData"), SuppressUnmanagedCodeSecurity]
475 public static extern IntPtr BodyGetData(IntPtr body);
476
477 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFiniteRotationMode"), SuppressUnmanagedCodeSecurity]
478 public static extern int BodyGetFiniteRotationMode(IntPtr body);
479
480 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFiniteRotationAxis"), SuppressUnmanagedCodeSecurity]
481 public static extern void BodyGetFiniteRotationAxis(IntPtr body, out Vector3 result);
482
483 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetForce"), SuppressUnmanagedCodeSecurity]
484 public extern unsafe static Vector3* BodyGetForceUnsafe(IntPtr body);
485 public static Vector3 BodyGetForce(IntPtr body)
486 {
487 unsafe { return *(BodyGetForceUnsafe(body)); }
488 }
489
490 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetGravityMode"), SuppressUnmanagedCodeSecurity]
491 public static extern bool BodyGetGravityMode(IntPtr body);
492
493 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetGyroscopicMode"), SuppressUnmanagedCodeSecurity]
494 public static extern int BodyGetGyroscopicMode(IntPtr body);
495
496 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetJoint"), SuppressUnmanagedCodeSecurity]
497 public static extern IntPtr BodyGetJoint(IntPtr body, int index);
498
499 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearVel"), SuppressUnmanagedCodeSecurity]
500 public extern unsafe static Vector3* BodyGetLinearVelUnsafe(IntPtr body);
501 public static Vector3 BodyGetLinearVel(IntPtr body)
502 {
503 unsafe { return *(BodyGetLinearVelUnsafe(body)); }
504 }
505
506 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetMass"), SuppressUnmanagedCodeSecurity]
507 public static extern void BodyGetMass(IntPtr body, out Mass mass);
508
509 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetNumJoints"), SuppressUnmanagedCodeSecurity]
510 public static extern int BodyGetNumJoints(IntPtr body);
511
512 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPointVel"), SuppressUnmanagedCodeSecurity]
513 public static extern void BodyGetPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
514
515 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPosition"), SuppressUnmanagedCodeSecurity]
516 public extern unsafe static Vector3* BodyGetPositionUnsafe(IntPtr body);
517 public static Vector3 BodyGetPosition(IntPtr body)
518 {
519 unsafe { return *(BodyGetPositionUnsafe(body)); }
520 }
521
522 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPosRelPoint"), SuppressUnmanagedCodeSecurity]
523 public static extern void BodyGetPosRelPoint(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
524
525 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetQuaternion"), SuppressUnmanagedCodeSecurity]
526 public extern unsafe static Quaternion* BodyGetQuaternionUnsafe(IntPtr body);
527 public static Quaternion BodyGetQuaternion(IntPtr body)
528 {
529 unsafe { return *(BodyGetQuaternionUnsafe(body)); }
530 }
531
532 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRelPointPos"), SuppressUnmanagedCodeSecurity]
533 public static extern void BodyGetRelPointPos(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
534
535 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRelPointVel"), SuppressUnmanagedCodeSecurity]
536 public static extern void BodyGetRelPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
537
538 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRotation"), SuppressUnmanagedCodeSecurity]
539 public extern unsafe static Matrix3* BodyGetRotationUnsafe(IntPtr body);
540 public static Matrix3 BodyGetRotation(IntPtr body)
541 {
542 unsafe { return *(BodyGetRotationUnsafe(body)); }
543 }
544
545 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetTorque"), SuppressUnmanagedCodeSecurity]
546 public extern unsafe static Vector3* BodyGetTorqueUnsafe(IntPtr body);
547 public static Vector3 BodyGetTorque(IntPtr body)
548 {
549 unsafe { return *(BodyGetTorqueUnsafe(body)); }
550 }
551
552 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetWorld"), SuppressUnmanagedCodeSecurity]
553 public static extern IntPtr BodyGetWorld(IntPtr body);
554
555 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFirstGeom"), SuppressUnmanagedCodeSecurity]
556 public static extern IntPtr BodyGetFirstGeom(IntPtr body);
557
558 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetNextGeom"), SuppressUnmanagedCodeSecurity]
559 public static extern IntPtr dBodyGetNextGeom(IntPtr Geom);
560
561
562 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyIsEnabled"), SuppressUnmanagedCodeSecurity]
563 public static extern bool BodyIsEnabled(IntPtr body);
564
565 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularVel"), SuppressUnmanagedCodeSecurity]
566 public static extern void BodySetAngularVel(IntPtr body, dReal x, dReal y, dReal z);
567
568 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity]
569 public static extern void BodySetAutoDisableAngularThreshold(IntPtr body, dReal angular_threshold);
570
571 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableDefaults"), SuppressUnmanagedCodeSecurity]
572 public static extern void BodySetAutoDisableDefaults(IntPtr body);
573
574 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableFlag"), SuppressUnmanagedCodeSecurity]
575 public static extern void BodySetAutoDisableFlag(IntPtr body, bool do_auto_disable);
576
577 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity]
578 public static extern void BodySetAutoDisableLinearThreshold(IntPtr body, dReal linear_threshold);
579
580 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableSteps"), SuppressUnmanagedCodeSecurity]
581 public static extern void BodySetAutoDisableSteps(IntPtr body, int steps);
582
583 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableTime"), SuppressUnmanagedCodeSecurity]
584 public static extern void BodySetAutoDisableTime(IntPtr body, dReal time);
585
586 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetData"), SuppressUnmanagedCodeSecurity]
587 public static extern void BodySetData(IntPtr body, IntPtr data);
588
589 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetFiniteRotationMode"), SuppressUnmanagedCodeSecurity]
590 public static extern void BodySetFiniteRotationMode(IntPtr body, int mode);
591
592 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetFiniteRotationAxis"), SuppressUnmanagedCodeSecurity]
593 public static extern void BodySetFiniteRotationAxis(IntPtr body, dReal x, dReal y, dReal z);
594
595 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearDamping"), SuppressUnmanagedCodeSecurity]
596 public static extern void BodySetLinearDamping(IntPtr body, dReal scale);
597
598 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDamping"), SuppressUnmanagedCodeSecurity]
599 public static extern void BodySetAngularDamping(IntPtr body, dReal scale);
600
601 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearDamping"), SuppressUnmanagedCodeSecurity]
602 public static extern dReal BodyGetLinearDamping(IntPtr body);
603
604 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularDamping"), SuppressUnmanagedCodeSecurity]
605 public static extern dReal BodyGetAngularDamping(IntPtr body);
606
607 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDamping"), SuppressUnmanagedCodeSecurity]
608 public static extern void BodySetDamping(IntPtr body, dReal linear_scale, dReal angular_scale);
609
610 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity]
611 public static extern void BodySetAngularDampingThreshold(IntPtr body, dReal threshold);
612
613 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity]
614 public static extern void BodySetLinearDampingThreshold(IntPtr body, dReal threshold);
615
616 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity]
617 public static extern dReal BodyGetLinearDampingThreshold(IntPtr body);
618
619 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity]
620 public static extern dReal BodyGetAngularDampingThreshold(IntPtr body);
621
622 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetForce"), SuppressUnmanagedCodeSecurity]
623 public static extern void BodySetForce(IntPtr body, dReal x, dReal y, dReal z);
624
625 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetGravityMode"), SuppressUnmanagedCodeSecurity]
626 public static extern void BodySetGravityMode(IntPtr body, bool mode);
627
628 /// <summary>
629 /// Sets the Gyroscopic term status on the body specified.
630 /// </summary>
631 /// <param name="body">Pointer to body</param>
632 /// <param name="enabled">NonZero enabled, Zero disabled</param>
633 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetGyroscopicMode"), SuppressUnmanagedCodeSecurity]
634 public static extern void dBodySetGyroscopicMode(IntPtr body, int enabled);
635
636 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearVel"), SuppressUnmanagedCodeSecurity]
637 public static extern void BodySetLinearVel(IntPtr body, dReal x, dReal y, dReal z);
638
639 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetMass"), SuppressUnmanagedCodeSecurity]
640 public static extern void BodySetMass(IntPtr body, ref Mass mass);
641
642 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetPosition"), SuppressUnmanagedCodeSecurity]
643 public static extern void BodySetPosition(IntPtr body, dReal x, dReal y, dReal z);
644
645 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity]
646 public static extern void BodySetQuaternion(IntPtr body, ref Quaternion q);
647
648 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity]
649 public static extern void BodySetQuaternion(IntPtr body, ref dReal w);
650
651 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity]
652 public static extern void BodySetRotation(IntPtr body, ref Matrix3 R);
653
654 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity]
655 public static extern void BodySetRotation(IntPtr body, ref dReal M00);
656
657 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetTorque"), SuppressUnmanagedCodeSecurity]
658 public static extern void BodySetTorque(IntPtr body, dReal x, dReal y, dReal z);
659
660 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyVectorFromWorld"), SuppressUnmanagedCodeSecurity]
661 public static extern void BodyVectorFromWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
662
663 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyVectorToWorld"), SuppressUnmanagedCodeSecurity]
664 public static extern void BodyVectorToWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result);
665
666 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBoxBox"), SuppressUnmanagedCodeSecurity]
667 public static extern void BoxBox(ref Vector3 p1, ref Matrix3 R1,
668 ref Vector3 side1, ref Vector3 p2,
669 ref Matrix3 R2, ref Vector3 side2,
670 ref Vector3 normal, out dReal depth, out int return_code,
671 int maxc, out ContactGeom contact, int skip);
672
673 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBoxTouchesBox"), SuppressUnmanagedCodeSecurity]
674 public static extern void BoxTouchesBox(ref Vector3 _p1, ref Matrix3 R1,
675 ref Vector3 side1, ref Vector3 _p2,
676 ref Matrix3 R2, ref Vector3 side2);
677
678 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCleanupODEAllDataForThread"), SuppressUnmanagedCodeSecurity]
679 public static extern void CleanupODEAllDataForThread();
680
681 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dClosestLineSegmentPoints"), SuppressUnmanagedCodeSecurity]
682 public static extern void ClosestLineSegmentPoints(ref Vector3 a1, ref Vector3 a2,
683 ref Vector3 b1, ref Vector3 b2,
684 ref Vector3 cp1, ref Vector3 cp2);
685
686 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCloseODE"), SuppressUnmanagedCodeSecurity]
687 public static extern void CloseODE();
688
689 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCollide"), SuppressUnmanagedCodeSecurity]
690 public static extern int Collide(IntPtr o1, IntPtr o2, int flags, [In, Out] ContactGeom[] contact, int skip);
691 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCollide"), SuppressUnmanagedCodeSecurity]
692 public static extern int CollidePtr(IntPtr o1, IntPtr o2, int flags, IntPtr contactgeomarray, int skip);
693
694 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dConnectingJoint"), SuppressUnmanagedCodeSecurity]
695 public static extern IntPtr ConnectingJoint(IntPtr j1, IntPtr j2);
696
697 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateBox"), SuppressUnmanagedCodeSecurity]
698 public static extern IntPtr CreateiBox(IntPtr space, dReal lx, dReal ly, dReal lz);
699 public static IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz)
700 {
701 NTotalGeoms++;
702 return CreateiBox(space, lx, ly, lz);
703 }
704
705 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCapsule"), SuppressUnmanagedCodeSecurity]
706 public static extern IntPtr CreateiCapsule(IntPtr space, dReal radius, dReal length);
707 public static IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length)
708 {
709 NTotalGeoms++;
710 return CreateiCapsule(space, radius, length);
711 }
712
713 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateConvex"), SuppressUnmanagedCodeSecurity]
714 public static extern IntPtr CreateiConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
715 public static IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons)
716 {
717 NTotalGeoms++;
718 return CreateiConvex(space, planes, planeCount, points, pointCount, polygons);
719 }
720
721 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCylinder"), SuppressUnmanagedCodeSecurity]
722 public static extern IntPtr CreateiCylinder(IntPtr space, dReal radius, dReal length);
723 public static IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length)
724 {
725 NTotalGeoms++;
726 return CreateiCylinder(space, radius, length);
727 }
728
729 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateHeightfield"), SuppressUnmanagedCodeSecurity]
730 public static extern IntPtr CreateiHeightfield(IntPtr space, IntPtr data, int bPlaceable);
731 public static IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable)
732 {
733 NTotalGeoms++;
734 return CreateiHeightfield(space, data, bPlaceable);
735 }
736
737 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateOSTerrain"), SuppressUnmanagedCodeSecurity]
738 public static extern IntPtr CreateiOSTerrain(IntPtr space, IntPtr data, int bPlaceable);
739 public static IntPtr CreateOSTerrain(IntPtr space, IntPtr data, int bPlaceable)
740 {
741 NTotalGeoms++;
742 return CreateiOSTerrain(space, data, bPlaceable);
743 }
744
745
746
747
748
749 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity]
750 public static extern IntPtr CreateiGeom(int classnum);
751 public static IntPtr CreateGeom(int classnum)
752 {
753 NTotalGeoms++;
754 return CreateiGeom(classnum);
755 }
756
757 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomClass"), SuppressUnmanagedCodeSecurity]
758 public static extern int CreateGeomClass(ref GeomClass classptr);
759
760 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomTransform"), SuppressUnmanagedCodeSecurity]
761 public static extern IntPtr CreateGeomTransform(IntPtr space);
762
763 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreatePlane"), SuppressUnmanagedCodeSecurity]
764 public static extern IntPtr CreateiPlane(IntPtr space, dReal a, dReal b, dReal c, dReal d);
765 public static IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d)
766 {
767 NTotalGeoms++;
768 return CreateiPlane(space, a, b, c, d);
769 }
770
771 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateRay"), SuppressUnmanagedCodeSecurity]
772 public static extern IntPtr CreateiRay(IntPtr space, dReal length);
773 public static IntPtr CreateRay(IntPtr space, dReal length)
774 {
775 NTotalGeoms++;
776 return CreateiRay(space, length);
777 }
778
779 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateSphere"), SuppressUnmanagedCodeSecurity]
780 public static extern IntPtr CreateiSphere(IntPtr space, dReal radius);
781 public static IntPtr CreateSphere(IntPtr space, dReal radius)
782 {
783 NTotalGeoms++;
784 return CreateiSphere(space, radius);
785 }
786
787 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateTriMesh"), SuppressUnmanagedCodeSecurity]
788 public static extern IntPtr CreateiTriMesh(IntPtr space, IntPtr data,
789 TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback);
790 public static IntPtr CreateTriMesh(IntPtr space, IntPtr data,
791 TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback)
792 {
793 NTotalGeoms++;
794 return CreateiTriMesh(space, data, callback, arrayCallback, rayCallback);
795 }
796 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity]
797 public static extern dReal Dot(ref dReal X0, ref dReal X1, int n);
798
799 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity]
800 public static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q);
801
802 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dFactorCholesky"), SuppressUnmanagedCodeSecurity]
803 public static extern int FactorCholesky(ref dReal A00, int n);
804
805 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dFactorLDLT"), SuppressUnmanagedCodeSecurity]
806 public static extern void FactorLDLT(ref dReal A, out dReal d, int n, int nskip);
807
808 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity]
809 public static extern void GeomBoxGetLengths(IntPtr geom, out Vector3 len);
810
811 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity]
812 public static extern void GeomBoxGetLengths(IntPtr geom, out dReal x);
813
814 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxPointDepth"), SuppressUnmanagedCodeSecurity]
815 public static extern dReal GeomBoxPointDepth(IntPtr geom, dReal x, dReal y, dReal z);
816
817 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxSetLengths"), SuppressUnmanagedCodeSecurity]
818 public static extern void GeomBoxSetLengths(IntPtr geom, dReal x, dReal y, dReal z);
819
820 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsuleGetParams"), SuppressUnmanagedCodeSecurity]
821 public static extern void GeomCapsuleGetParams(IntPtr geom, out dReal radius, out dReal length);
822
823 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsulePointDepth"), SuppressUnmanagedCodeSecurity]
824 public static extern dReal GeomCapsulePointDepth(IntPtr geom, dReal x, dReal y, dReal z);
825
826 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsuleSetParams"), SuppressUnmanagedCodeSecurity]
827 public static extern void GeomCapsuleSetParams(IntPtr geom, dReal radius, dReal length);
828
829 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomClearOffset"), SuppressUnmanagedCodeSecurity]
830 public static extern void GeomClearOffset(IntPtr geom);
831
832 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity]
833 public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref Vector3 pos);
834
835 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity]
836 public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref dReal X);
837
838 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity]
839 public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref Quaternion Q);
840
841 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity]
842 public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref dReal X);
843
844 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity]
845 public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref Matrix3 R);
846
847 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity]
848 public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref dReal M00);
849
850 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity]
851 public static extern void GeomCopyPosition(IntPtr geom, out Vector3 pos);
852
853 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity]
854 public static extern void GeomCopyPosition(IntPtr geom, out dReal X);
855
856 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity]
857 public static extern void GeomCopyRotation(IntPtr geom, out Matrix3 R);
858
859 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity]
860 public static extern void GeomCopyRotation(IntPtr geom, out dReal M00);
861
862 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCylinderGetParams"), SuppressUnmanagedCodeSecurity]
863 public static extern void GeomCylinderGetParams(IntPtr geom, out dReal radius, out dReal length);
864
865 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCylinderSetParams"), SuppressUnmanagedCodeSecurity]
866 public static extern void GeomCylinderSetParams(IntPtr geom, dReal radius, dReal length);
867
868 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDestroy"), SuppressUnmanagedCodeSecurity]
869 public static extern void GeomiDestroy(IntPtr geom);
870 public static void GeomDestroy(IntPtr geom)
871 {
872 NTotalGeoms--;
873 GeomiDestroy(geom);
874 }
875
876
877 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDisable"), SuppressUnmanagedCodeSecurity]
878 public static extern void GeomDisable(IntPtr geom);
879
880 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomEnable"), SuppressUnmanagedCodeSecurity]
881 public static extern void GeomEnable(IntPtr geom);
882
883 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity]
884 public static extern void GeomGetAABB(IntPtr geom, out AABB aabb);
885
886 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity]
887 public static extern void GeomGetAABB(IntPtr geom, out dReal minX);
888
889 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetBody"), SuppressUnmanagedCodeSecurity]
890 public static extern IntPtr GeomGetBody(IntPtr geom);
891
892 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity]
893 public static extern uint GeomGetCategoryBits(IntPtr geom);
894
895 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity]
896 public static extern IntPtr GeomGetClassData(IntPtr geom);
897
898 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity]
899 public static extern uint GeomGetCollideBits(IntPtr geom);
900
901 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity]
902 public static extern GeomClassID GeomGetClass(IntPtr geom);
903
904 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetData"), SuppressUnmanagedCodeSecurity]
905 public static extern IntPtr GeomGetData(IntPtr geom);
906
907 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetPosition"), SuppressUnmanagedCodeSecurity]
908 public extern unsafe static Vector3* GeomGetOffsetPositionUnsafe(IntPtr geom);
909 public static Vector3 GeomGetOffsetPosition(IntPtr geom)
910 {
911 unsafe { return *(GeomGetOffsetPositionUnsafe(geom)); }
912 }
913
914 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetRotation"), SuppressUnmanagedCodeSecurity]
915 public extern unsafe static Matrix3* GeomGetOffsetRotationUnsafe(IntPtr geom);
916 public static Matrix3 GeomGetOffsetRotation(IntPtr geom)
917 {
918 unsafe { return *(GeomGetOffsetRotationUnsafe(geom)); }
919 }
920
921 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetPosition"), SuppressUnmanagedCodeSecurity]
922 public extern unsafe static Vector3* GeomGetPositionUnsafe(IntPtr geom);
923 public static Vector3 GeomGetPosition(IntPtr geom)
924 {
925 unsafe { return *(GeomGetPositionUnsafe(geom)); }
926 }
927 public static OMV.Vector3 GeomGetPositionOMV(IntPtr geom)
928 {
929 Vector3 vtmp = GeomGetPosition(geom);
930 return new OMV.Vector3(vtmp.X, vtmp.Y, vtmp.Z);
931 }
932
933 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
934 public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q);
935 public static OMV.Quaternion GeomGetQuaternionOMV(IntPtr geom)
936 {
937 Quaternion qtmp;
938 GeomCopyQuaternion(geom, out qtmp);
939 return new OMV.Quaternion(qtmp.X, qtmp.Y, qtmp.Z, qtmp.W);
940 }
941
942 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
943 public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X);
944
945 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetRotation"), SuppressUnmanagedCodeSecurity]
946 public extern unsafe static Matrix3* GeomGetRotationUnsafe(IntPtr geom);
947 public static Matrix3 GeomGetRotation(IntPtr geom)
948 {
949 unsafe { return *(GeomGetRotationUnsafe(geom)); }
950 }
951
952 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetSpace"), SuppressUnmanagedCodeSecurity]
953 public static extern IntPtr GeomGetSpace(IntPtr geom);
954
955 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity]
956 public static extern void GeomHeightfieldDataBuildByte(IntPtr d, byte[] pHeightData, int bCopyHeightData,
957 dReal width, dReal depth, int widthSamples, int depthSamples,
958 dReal scale, dReal offset, dReal thickness, int bWrap);
959
960 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity]
961 public static extern void GeomHeightfieldDataBuildByte(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
962 dReal width, dReal depth, int widthSamples, int depthSamples,
963 dReal scale, dReal offset, dReal thickness, int bWrap);
964
965 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildCallback"), SuppressUnmanagedCodeSecurity]
966 public static extern void GeomHeightfieldDataBuildCallback(IntPtr d, IntPtr pUserData, HeightfieldGetHeight pCallback,
967 dReal width, dReal depth, int widthSamples, int depthSamples,
968 dReal scale, dReal offset, dReal thickness, int bWrap);
969
970 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity]
971 public static extern void GeomHeightfieldDataBuildShort(IntPtr d, ushort[] pHeightData, int bCopyHeightData,
972 dReal width, dReal depth, int widthSamples, int depthSamples,
973 dReal scale, dReal offset, dReal thickness, int bWrap);
974
975 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity]
976 public static extern void GeomHeightfieldDataBuildShort(IntPtr d, short[] pHeightData, int bCopyHeightData,
977 dReal width, dReal depth, int widthSamples, int depthSamples,
978 dReal scale, dReal offset, dReal thickness, int bWrap);
979
980 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity]
981 public static extern void GeomHeightfieldDataBuildShort(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
982 dReal width, dReal depth, int widthSamples, int depthSamples,
983 dReal scale, dReal offset, dReal thickness, int bWrap);
984
985 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity]
986 public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, float[] pHeightData, int bCopyHeightData,
987 dReal width, dReal depth, int widthSamples, int depthSamples,
988 dReal scale, dReal offset, dReal thickness, int bWrap);
989
990 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity]
991 public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
992 dReal width, dReal depth, int widthSamples, int depthSamples,
993 dReal scale, dReal offset, dReal thickness, int bWrap);
994
995
996
997 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity]
998 public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData,
999 dReal width, dReal depth, int widthSamples, int depthSamples,
1000 dReal scale, dReal offset, dReal thickness, int bWrap);
1001
1002 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity]
1003 public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
1004 dReal width, dReal depth, int widthSamples, int depthSamples,
1005 dReal scale, dReal offset, dReal thickness, int bWrap);
1006
1007 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataCreate"), SuppressUnmanagedCodeSecurity]
1008 public static extern IntPtr GeomHeightfieldDataCreate();
1009
1010 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataDestroy"), SuppressUnmanagedCodeSecurity]
1011 public static extern void GeomHeightfieldDataDestroy(IntPtr d);
1012
1013 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataSetBounds"), SuppressUnmanagedCodeSecurity]
1014 public static extern void GeomHeightfieldDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight);
1015
1016 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldGetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1017 public static extern IntPtr GeomHeightfieldGetHeightfieldData(IntPtr g);
1018
1019 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldSetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1020 public static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d);
1021
1022
1023 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataBuild"), SuppressUnmanagedCodeSecurity]
1024 public static extern void GeomOSTerrainDataBuild(IntPtr d, float[] pHeightData, int bCopyHeightData,
1025 dReal sampleSize, int widthSamples, int depthSamples,
1026 dReal offset, dReal thickness, int bWrap);
1027
1028 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataBuild"), SuppressUnmanagedCodeSecurity]
1029 public static extern void GeomOSTerrainDataBuild(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
1030 dReal sampleSize, int widthSamples, int depthSamples,
1031 dReal thickness, int bWrap);
1032
1033 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataCreate"), SuppressUnmanagedCodeSecurity]
1034 public static extern IntPtr GeomOSTerrainDataCreate();
1035
1036 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataDestroy"), SuppressUnmanagedCodeSecurity]
1037 public static extern void GeomOSTerrainDataDestroy(IntPtr d);
1038
1039 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataSetBounds"), SuppressUnmanagedCodeSecurity]
1040 public static extern void GeomOSTerrainDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight);
1041
1042 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainGetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1043 public static extern IntPtr GeomOSTerrainGetHeightfieldData(IntPtr g);
1044
1045 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainSetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1046 public static extern void GeomOSTerrainSetHeightfieldData(IntPtr g, IntPtr d);
1047
1048
1049 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsEnabled"), SuppressUnmanagedCodeSecurity]
1050 public static extern bool GeomIsEnabled(IntPtr geom);
1051
1052 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsOffset"), SuppressUnmanagedCodeSecurity]
1053 public static extern bool GeomIsOffset(IntPtr geom);
1054
1055 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsSpace"), SuppressUnmanagedCodeSecurity]
1056 public static extern bool GeomIsSpace(IntPtr geom);
1057
1058 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity]
1059 public static extern void GeomPlaneGetParams(IntPtr geom, ref Vector4 result);
1060
1061 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity]
1062 public static extern void GeomPlaneGetParams(IntPtr geom, ref dReal A);
1063
1064 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlanePointDepth"), SuppressUnmanagedCodeSecurity]
1065 public static extern dReal GeomPlanePointDepth(IntPtr geom, dReal x, dReal y, dReal z);
1066
1067 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneSetParams"), SuppressUnmanagedCodeSecurity]
1068 public static extern void GeomPlaneSetParams(IntPtr plane, dReal a, dReal b, dReal c, dReal d);
1069
1070 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity]
1071 public static extern void GeomRayGet(IntPtr ray, ref Vector3 start, ref Vector3 dir);
1072
1073 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity]
1074 public static extern void GeomRayGet(IntPtr ray, ref dReal startX, ref dReal dirX);
1075
1076 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetClosestHit"), SuppressUnmanagedCodeSecurity]
1077 public static extern int GeomRayGetClosestHit(IntPtr ray);
1078
1079 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetLength"), SuppressUnmanagedCodeSecurity]
1080 public static extern dReal GeomRayGetLength(IntPtr ray);
1081
1082 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetParams"), SuppressUnmanagedCodeSecurity]
1083 public static extern dReal GeomRayGetParams(IntPtr g, out int firstContact, out int backfaceCull);
1084
1085 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySet"), SuppressUnmanagedCodeSecurity]
1086 public static extern void GeomRaySet(IntPtr ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz);
1087
1088 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetClosestHit"), SuppressUnmanagedCodeSecurity]
1089 public static extern void GeomRaySetClosestHit(IntPtr ray, int closestHit);
1090
1091 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetLength"), SuppressUnmanagedCodeSecurity]
1092 public static extern void GeomRaySetLength(IntPtr ray, dReal length);
1093
1094 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetParams"), SuppressUnmanagedCodeSecurity]
1095 public static extern void GeomRaySetParams(IntPtr ray, int firstContact, int backfaceCull);
1096
1097 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetBody"), SuppressUnmanagedCodeSecurity]
1098 public static extern void GeomSetBody(IntPtr geom, IntPtr body);
1099
1100 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity]
1101 public static extern void GeomSetCategoryBits(IntPtr geom, uint bits);
1102
1103 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity]
1104 public static extern void GeomSetCollideBits(IntPtr geom, uint bits);
1105
1106 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity]
1107 public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
1108
1109 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetData"), SuppressUnmanagedCodeSecurity]
1110 public static extern void GeomSetData(IntPtr geom, IntPtr data);
1111
1112 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetPosition"), SuppressUnmanagedCodeSecurity]
1113 public static extern void GeomSetOffsetPosition(IntPtr geom, dReal x, dReal y, dReal z);
1114
1115 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity]
1116 public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref Quaternion Q);
1117
1118 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity]
1119 public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref dReal X);
1120
1121 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity]
1122 public static extern void GeomSetOffsetRotation(IntPtr geom, ref Matrix3 R);
1123
1124 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity]
1125 public static extern void GeomSetOffsetRotation(IntPtr geom, ref dReal M00);
1126
1127 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldPosition"), SuppressUnmanagedCodeSecurity]
1128 public static extern void GeomSetOffsetWorldPosition(IntPtr geom, dReal x, dReal y, dReal z);
1129
1130 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity]
1131 public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref Quaternion Q);
1132
1133 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity]
1134 public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref dReal X);
1135
1136 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity]
1137 public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref Matrix3 R);
1138
1139 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity]
1140 public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref dReal M00);
1141
1142 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetPosition"), SuppressUnmanagedCodeSecurity]
1143 public static extern void GeomSetPosition(IntPtr geom, dReal x, dReal y, dReal z);
1144
1145 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity]
1146 public static extern void GeomSetQuaternion(IntPtr geom, ref Quaternion quat);
1147
1148 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity]
1149 public static extern void GeomSetQuaternion(IntPtr geom, ref dReal w);
1150
1151 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity]
1152 public static extern void GeomSetRotation(IntPtr geom, ref Matrix3 R);
1153
1154 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity]
1155 public static extern void GeomSetRotation(IntPtr geom, ref dReal M00);
1156
1157 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSphereGetRadius"), SuppressUnmanagedCodeSecurity]
1158 public static extern dReal GeomSphereGetRadius(IntPtr geom);
1159
1160 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSpherePointDepth"), SuppressUnmanagedCodeSecurity]
1161 public static extern dReal GeomSpherePointDepth(IntPtr geom, dReal x, dReal y, dReal z);
1162
1163 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSphereSetRadius"), SuppressUnmanagedCodeSecurity]
1164 public static extern void GeomSphereSetRadius(IntPtr geom, dReal radius);
1165
1166 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetCleanup"), SuppressUnmanagedCodeSecurity]
1167 public static extern int GeomTransformGetCleanup(IntPtr geom);
1168
1169 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetGeom"), SuppressUnmanagedCodeSecurity]
1170 public static extern IntPtr GeomTransformGetGeom(IntPtr geom);
1171
1172 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetInfo"), SuppressUnmanagedCodeSecurity]
1173 public static extern int GeomTransformGetInfo(IntPtr geom);
1174
1175 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetCleanup"), SuppressUnmanagedCodeSecurity]
1176 public static extern void GeomTransformSetCleanup(IntPtr geom, int mode);
1177
1178 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetGeom"), SuppressUnmanagedCodeSecurity]
1179 public static extern void GeomTransformSetGeom(IntPtr geom, IntPtr obj);
1180
1181 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetInfo"), SuppressUnmanagedCodeSecurity]
1182 public static extern void GeomTransformSetInfo(IntPtr geom, int info);
1183
1184 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity]
1185 public static extern void GeomTriMeshDataBuildDouble(IntPtr d,
1186 double[] vertices, int vertexStride, int vertexCount,
1187 int[] indices, int indexCount, int triStride);
1188
1189 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity]
1190 public static extern void GeomTriMeshDataBuildDouble(IntPtr d,
1191 IntPtr vertices, int vertexStride, int vertexCount,
1192 IntPtr indices, int indexCount, int triStride);
1193
1194 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity]
1195 public static extern void GeomTriMeshDataBuildDouble1(IntPtr d,
1196 double[] vertices, int vertexStride, int vertexCount,
1197 int[] indices, int indexCount, int triStride,
1198 double[] normals);
1199
1200 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity]
1201 public static extern void GeomTriMeshDataBuildDouble(IntPtr d,
1202 IntPtr vertices, int vertexStride, int vertexCount,
1203 IntPtr indices, int indexCount, int triStride,
1204 IntPtr normals);
1205
1206 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity]
1207 public static extern void GeomTriMeshDataBuildSingle(IntPtr d,
1208 dReal[] vertices, int vertexStride, int vertexCount,
1209 int[] indices, int indexCount, int triStride);
1210
1211 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity]
1212 public static extern void GeomTriMeshDataBuildSingle(IntPtr d,
1213 IntPtr vertices, int vertexStride, int vertexCount,
1214 IntPtr indices, int indexCount, int triStride);
1215
1216 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity]
1217 public static extern void GeomTriMeshDataBuildSingle1(IntPtr d,
1218 dReal[] vertices, int vertexStride, int vertexCount,
1219 int[] indices, int indexCount, int triStride,
1220 dReal[] normals);
1221
1222 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity]
1223 public static extern void GeomTriMeshDataBuildSingle1(IntPtr d,
1224 IntPtr vertices, int vertexStride, int vertexCount,
1225 IntPtr indices, int indexCount, int triStride,
1226 IntPtr normals);
1227
1228 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity]
1229 public static extern void GeomTriMeshDataBuildSimple(IntPtr d,
1230 float[] vertices, int vertexStride, int vertexCount,
1231 int[] indices, int indexCount, int triStride);
1232
1233 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity]
1234 public static extern void GeomTriMeshDataBuildSimple(IntPtr d,
1235 IntPtr vertices, int vertexStride, int vertexCount,
1236 IntPtr indices, int indexCount, int triStride);
1237
1238 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity]
1239 public static extern void GeomTriMeshDataBuildSimple1(IntPtr d,
1240 float[] vertices, int vertexStride, int vertexCount,
1241 int[] indices, int indexCount, int triStride,
1242 float[] normals);
1243
1244 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity]
1245 public static extern void GeomTriMeshDataBuildSimple1(IntPtr d,
1246 IntPtr vertices, int vertexStride, int vertexCount,
1247 IntPtr indices, int indexCount, int triStride,
1248 IntPtr normals);
1249
1250 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshClearTCCache"), SuppressUnmanagedCodeSecurity]
1251 public static extern void GeomTriMeshClearTCCache(IntPtr g);
1252
1253 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataCreate"), SuppressUnmanagedCodeSecurity]
1254 public static extern IntPtr GeomTriMeshDataCreate();
1255
1256 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataDestroy"), SuppressUnmanagedCodeSecurity]
1257 public static extern void GeomTriMeshDataDestroy(IntPtr d);
1258
1259 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataGet"), SuppressUnmanagedCodeSecurity]
1260 public static extern IntPtr GeomTriMeshDataGet(IntPtr d, int data_id);
1261
1262 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataPreprocess"), SuppressUnmanagedCodeSecurity]
1263 public static extern void GeomTriMeshDataPreprocess(IntPtr d);
1264
1265 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataSet"), SuppressUnmanagedCodeSecurity]
1266 public static extern void GeomTriMeshDataSet(IntPtr d, int data_id, IntPtr in_data);
1267
1268 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataUpdate"), SuppressUnmanagedCodeSecurity]
1269 public static extern void GeomTriMeshDataUpdate(IntPtr d);
1270
1271 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshEnableTC"), SuppressUnmanagedCodeSecurity]
1272 public static extern void GeomTriMeshEnableTC(IntPtr g, int geomClass, bool enable);
1273
1274 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetArrayCallback"), SuppressUnmanagedCodeSecurity]
1275 public static extern TriArrayCallback GeomTriMeshGetArrayCallback(IntPtr g);
1276
1277 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetCallback"), SuppressUnmanagedCodeSecurity]
1278 public static extern TriCallback GeomTriMeshGetCallback(IntPtr g);
1279
1280 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetData"), SuppressUnmanagedCodeSecurity]
1281 public static extern IntPtr GeomTriMeshGetData(IntPtr g);
1282
1283 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetLastTransform"), SuppressUnmanagedCodeSecurity]
1284 public extern unsafe static Matrix4* GeomTriMeshGetLastTransformUnsafe(IntPtr geom);
1285 public static Matrix4 GeomTriMeshGetLastTransform(IntPtr geom)
1286 {
1287 unsafe { return *(GeomTriMeshGetLastTransformUnsafe(geom)); }
1288 }
1289
1290 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetPoint"), SuppressUnmanagedCodeSecurity]
1291 public extern static void GeomTriMeshGetPoint(IntPtr g, int index, dReal u, dReal v, ref Vector3 outVec);
1292
1293 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetRayCallback"), SuppressUnmanagedCodeSecurity]
1294 public static extern TriRayCallback GeomTriMeshGetRayCallback(IntPtr g);
1295
1296 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriangle"), SuppressUnmanagedCodeSecurity]
1297 public extern static void GeomTriMeshGetTriangle(IntPtr g, int index, ref Vector3 v0, ref Vector3 v1, ref Vector3 v2);
1298
1299 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriangleCount"), SuppressUnmanagedCodeSecurity]
1300 public extern static int GeomTriMeshGetTriangleCount(IntPtr g);
1301
1302 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriMeshDataID"), SuppressUnmanagedCodeSecurity]
1303 public static extern IntPtr GeomTriMeshGetTriMeshDataID(IntPtr g);
1304
1305 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshIsTCEnabled"), SuppressUnmanagedCodeSecurity]
1306 public static extern bool GeomTriMeshIsTCEnabled(IntPtr g, int geomClass);
1307
1308 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetArrayCallback"), SuppressUnmanagedCodeSecurity]
1309 public static extern void GeomTriMeshSetArrayCallback(IntPtr g, TriArrayCallback arrayCallback);
1310
1311 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetCallback"), SuppressUnmanagedCodeSecurity]
1312 public static extern void GeomTriMeshSetCallback(IntPtr g, TriCallback callback);
1313
1314 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetData"), SuppressUnmanagedCodeSecurity]
1315 public static extern void GeomTriMeshSetData(IntPtr g, IntPtr data);
1316
1317 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity]
1318 public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref Matrix4 last_trans);
1319
1320 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity]
1321 public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref dReal M00);
1322
1323 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetRayCallback"), SuppressUnmanagedCodeSecurity]
1324 public static extern void GeomTriMeshSetRayCallback(IntPtr g, TriRayCallback callback);
1325
1326 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGetConfiguration"), SuppressUnmanagedCodeSecurity]
1327 public static extern IntPtr iGetConfiguration();
1328
1329 public static string GetConfiguration()
1330 {
1331 IntPtr ptr = iGetConfiguration();
1332 string s = Marshal.PtrToStringAnsi(ptr);
1333 return s;
1334 }
1335
1336 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceCreate"), SuppressUnmanagedCodeSecurity]
1337 public static extern IntPtr HashSpaceCreate(IntPtr space);
1338
1339 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceGetLevels"), SuppressUnmanagedCodeSecurity]
1340 public static extern void HashSpaceGetLevels(IntPtr space, out int minlevel, out int maxlevel);
1341
1342 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceSetLevels"), SuppressUnmanagedCodeSecurity]
1343 public static extern void HashSpaceSetLevels(IntPtr space, int minlevel, int maxlevel);
1344
1345 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInfiniteAABB"), SuppressUnmanagedCodeSecurity]
1346 public static extern void InfiniteAABB(IntPtr geom, out AABB aabb);
1347
1348 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInitODE"), SuppressUnmanagedCodeSecurity]
1349 public static extern void InitODE();
1350
1351 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInitODE2"), SuppressUnmanagedCodeSecurity]
1352 public static extern int InitODE2(uint ODEInitFlags);
1353
1354 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dIsPositiveDefinite"), SuppressUnmanagedCodeSecurity]
1355 public static extern int IsPositiveDefinite(ref dReal A, int n);
1356
1357 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInvertPDMatrix"), SuppressUnmanagedCodeSecurity]
1358 public static extern int InvertPDMatrix(ref dReal A, out dReal Ainv, int n);
1359
1360 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddAMotorTorques"), SuppressUnmanagedCodeSecurity]
1361 public static extern void JointAddAMotorTorques(IntPtr joint, dReal torque1, dReal torque2, dReal torque3);
1362
1363 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddHingeTorque"), SuppressUnmanagedCodeSecurity]
1364 public static extern void JointAddHingeTorque(IntPtr joint, dReal torque);
1365
1366 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddHinge2Torque"), SuppressUnmanagedCodeSecurity]
1367 public static extern void JointAddHinge2Torques(IntPtr joint, dReal torque1, dReal torque2);
1368
1369 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddPRTorque"), SuppressUnmanagedCodeSecurity]
1370 public static extern void JointAddPRTorque(IntPtr joint, dReal torque);
1371
1372 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddUniversalTorque"), SuppressUnmanagedCodeSecurity]
1373 public static extern void JointAddUniversalTorques(IntPtr joint, dReal torque1, dReal torque2);
1374
1375 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddSliderForce"), SuppressUnmanagedCodeSecurity]
1376 public static extern void JointAddSliderForce(IntPtr joint, dReal force);
1377
1378 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAttach"), SuppressUnmanagedCodeSecurity]
1379 public static extern void JointAttach(IntPtr joint, IntPtr body1, IntPtr body2);
1380
1381 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateAMotor"), SuppressUnmanagedCodeSecurity]
1382 public static extern IntPtr JointCreateAMotor(IntPtr world, IntPtr group);
1383
1384 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateBall"), SuppressUnmanagedCodeSecurity]
1385 public static extern IntPtr JointCreateBall(IntPtr world, IntPtr group);
1386
1387 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateContact"), SuppressUnmanagedCodeSecurity]
1388 public static extern IntPtr JointCreateContact(IntPtr world, IntPtr group, ref Contact contact);
1389 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateContact"), SuppressUnmanagedCodeSecurity]
1390 public static extern IntPtr JointCreateContactPtr(IntPtr world, IntPtr group, IntPtr contact);
1391
1392 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateFixed"), SuppressUnmanagedCodeSecurity]
1393 public static extern IntPtr JointCreateFixed(IntPtr world, IntPtr group);
1394
1395 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateHinge"), SuppressUnmanagedCodeSecurity]
1396 public static extern IntPtr JointCreateHinge(IntPtr world, IntPtr group);
1397
1398 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateHinge2"), SuppressUnmanagedCodeSecurity]
1399 public static extern IntPtr JointCreateHinge2(IntPtr world, IntPtr group);
1400
1401 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateLMotor"), SuppressUnmanagedCodeSecurity]
1402 public static extern IntPtr JointCreateLMotor(IntPtr world, IntPtr group);
1403
1404 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateNull"), SuppressUnmanagedCodeSecurity]
1405 public static extern IntPtr JointCreateNull(IntPtr world, IntPtr group);
1406
1407 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreatePR"), SuppressUnmanagedCodeSecurity]
1408 public static extern IntPtr JointCreatePR(IntPtr world, IntPtr group);
1409
1410 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreatePlane2D"), SuppressUnmanagedCodeSecurity]
1411 public static extern IntPtr JointCreatePlane2D(IntPtr world, IntPtr group);
1412
1413 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateSlider"), SuppressUnmanagedCodeSecurity]
1414 public static extern IntPtr JointCreateSlider(IntPtr world, IntPtr group);
1415
1416 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateUniversal"), SuppressUnmanagedCodeSecurity]
1417 public static extern IntPtr JointCreateUniversal(IntPtr world, IntPtr group);
1418
1419 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointDestroy"), SuppressUnmanagedCodeSecurity]
1420 public static extern void JointDestroy(IntPtr j);
1421
1422 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAngle"), SuppressUnmanagedCodeSecurity]
1423 public static extern dReal JointGetAMotorAngle(IntPtr j, int anum);
1424
1425 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAngleRate"), SuppressUnmanagedCodeSecurity]
1426 public static extern dReal JointGetAMotorAngleRate(IntPtr j, int anum);
1427
1428 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAxis"), SuppressUnmanagedCodeSecurity]
1429 public static extern void JointGetAMotorAxis(IntPtr j, int anum, out Vector3 result);
1430
1431 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAxisRel"), SuppressUnmanagedCodeSecurity]
1432 public static extern int JointGetAMotorAxisRel(IntPtr j, int anum);
1433
1434 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorMode"), SuppressUnmanagedCodeSecurity]
1435 public static extern int JointGetAMotorMode(IntPtr j);
1436
1437 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorNumAxes"), SuppressUnmanagedCodeSecurity]
1438 public static extern int JointGetAMotorNumAxes(IntPtr j);
1439
1440 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorParam"), SuppressUnmanagedCodeSecurity]
1441 public static extern dReal JointGetAMotorParam(IntPtr j, int parameter);
1442
1443 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBallAnchor"), SuppressUnmanagedCodeSecurity]
1444 public static extern void JointGetBallAnchor(IntPtr j, out Vector3 result);
1445
1446 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBallAnchor2"), SuppressUnmanagedCodeSecurity]
1447 public static extern void JointGetBallAnchor2(IntPtr j, out Vector3 result);
1448
1449 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBody"), SuppressUnmanagedCodeSecurity]
1450 public static extern IntPtr JointGetBody(IntPtr j);
1451
1452 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetData"), SuppressUnmanagedCodeSecurity]
1453 public static extern IntPtr JointGetData(IntPtr j);
1454
1455 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetFeedback"), SuppressUnmanagedCodeSecurity]
1456 public extern unsafe static JointFeedback* JointGetFeedbackUnsafe(IntPtr j);
1457 public static JointFeedback JointGetFeedback(IntPtr j)
1458 {
1459 unsafe { return *(JointGetFeedbackUnsafe(j)); }
1460 }
1461
1462 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAnchor"), SuppressUnmanagedCodeSecurity]
1463 public static extern void JointGetHingeAnchor(IntPtr j, out Vector3 result);
1464
1465 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAngle"), SuppressUnmanagedCodeSecurity]
1466 public static extern dReal JointGetHingeAngle(IntPtr j);
1467
1468 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAngleRate"), SuppressUnmanagedCodeSecurity]
1469 public static extern dReal JointGetHingeAngleRate(IntPtr j);
1470
1471 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAxis"), SuppressUnmanagedCodeSecurity]
1472 public static extern void JointGetHingeAxis(IntPtr j, out Vector3 result);
1473
1474 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeParam"), SuppressUnmanagedCodeSecurity]
1475 public static extern dReal JointGetHingeParam(IntPtr j, int parameter);
1476
1477 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle1"), SuppressUnmanagedCodeSecurity]
1478 public static extern dReal JointGetHinge2Angle1(IntPtr j);
1479
1480 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle1Rate"), SuppressUnmanagedCodeSecurity]
1481 public static extern dReal JointGetHinge2Angle1Rate(IntPtr j);
1482
1483 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle2Rate"), SuppressUnmanagedCodeSecurity]
1484 public static extern dReal JointGetHinge2Angle2Rate(IntPtr j);
1485
1486 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAnchor2"), SuppressUnmanagedCodeSecurity]
1487 public static extern void JointGetHingeAnchor2(IntPtr j, out Vector3 result);
1488
1489 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Anchor"), SuppressUnmanagedCodeSecurity]
1490 public static extern void JointGetHinge2Anchor(IntPtr j, out Vector3 result);
1491
1492 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Anchor2"), SuppressUnmanagedCodeSecurity]
1493 public static extern void JointGetHinge2Anchor2(IntPtr j, out Vector3 result);
1494
1495 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Axis1"), SuppressUnmanagedCodeSecurity]
1496 public static extern void JointGetHinge2Axis1(IntPtr j, out Vector3 result);
1497
1498 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Axis2"), SuppressUnmanagedCodeSecurity]
1499 public static extern void JointGetHinge2Axis2(IntPtr j, out Vector3 result);
1500
1501 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Param"), SuppressUnmanagedCodeSecurity]
1502 public static extern dReal JointGetHinge2Param(IntPtr j, int parameter);
1503
1504 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorAxis"), SuppressUnmanagedCodeSecurity]
1505 public static extern void JointGetLMotorAxis(IntPtr j, int anum, out Vector3 result);
1506
1507 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorNumAxes"), SuppressUnmanagedCodeSecurity]
1508 public static extern int JointGetLMotorNumAxes(IntPtr j);
1509
1510 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorParam"), SuppressUnmanagedCodeSecurity]
1511 public static extern dReal JointGetLMotorParam(IntPtr j, int parameter);
1512
1513 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAnchor"), SuppressUnmanagedCodeSecurity]
1514 public static extern void JointGetPRAnchor(IntPtr j, out Vector3 result);
1515
1516 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAxis1"), SuppressUnmanagedCodeSecurity]
1517 public static extern void JointGetPRAxis1(IntPtr j, out Vector3 result);
1518
1519 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAxis2"), SuppressUnmanagedCodeSecurity]
1520 public static extern void JointGetPRAxis2(IntPtr j, out Vector3 result);
1521
1522 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRParam"), SuppressUnmanagedCodeSecurity]
1523 public static extern dReal JointGetPRParam(IntPtr j, int parameter);
1524
1525 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRPosition"), SuppressUnmanagedCodeSecurity]
1526 public static extern dReal JointGetPRPosition(IntPtr j);
1527
1528 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRPositionRate"), SuppressUnmanagedCodeSecurity]
1529 public static extern dReal JointGetPRPositionRate(IntPtr j);
1530
1531 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderAxis"), SuppressUnmanagedCodeSecurity]
1532 public static extern void JointGetSliderAxis(IntPtr j, out Vector3 result);
1533
1534 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderParam"), SuppressUnmanagedCodeSecurity]
1535 public static extern dReal JointGetSliderParam(IntPtr j, int parameter);
1536
1537 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderPosition"), SuppressUnmanagedCodeSecurity]
1538 public static extern dReal JointGetSliderPosition(IntPtr j);
1539
1540 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderPositionRate"), SuppressUnmanagedCodeSecurity]
1541 public static extern dReal JointGetSliderPositionRate(IntPtr j);
1542
1543 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetType"), SuppressUnmanagedCodeSecurity]
1544 public static extern JointType JointGetType(IntPtr j);
1545
1546 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAnchor"), SuppressUnmanagedCodeSecurity]
1547 public static extern void JointGetUniversalAnchor(IntPtr j, out Vector3 result);
1548
1549 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAnchor2"), SuppressUnmanagedCodeSecurity]
1550 public static extern void JointGetUniversalAnchor2(IntPtr j, out Vector3 result);
1551
1552 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle1"), SuppressUnmanagedCodeSecurity]
1553 public static extern dReal JointGetUniversalAngle1(IntPtr j);
1554
1555 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle1Rate"), SuppressUnmanagedCodeSecurity]
1556 public static extern dReal JointGetUniversalAngle1Rate(IntPtr j);
1557
1558 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle2"), SuppressUnmanagedCodeSecurity]
1559 public static extern dReal JointGetUniversalAngle2(IntPtr j);
1560
1561 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle2Rate"), SuppressUnmanagedCodeSecurity]
1562 public static extern dReal JointGetUniversalAngle2Rate(IntPtr j);
1563
1564 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngles"), SuppressUnmanagedCodeSecurity]
1565 public static extern void JointGetUniversalAngles(IntPtr j, out dReal angle1, out dReal angle2);
1566
1567 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAxis1"), SuppressUnmanagedCodeSecurity]
1568 public static extern void JointGetUniversalAxis1(IntPtr j, out Vector3 result);
1569
1570 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAxis2"), SuppressUnmanagedCodeSecurity]
1571 public static extern void JointGetUniversalAxis2(IntPtr j, out Vector3 result);
1572
1573 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalParam"), SuppressUnmanagedCodeSecurity]
1574 public static extern dReal JointGetUniversalParam(IntPtr j, int parameter);
1575
1576 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupCreate"), SuppressUnmanagedCodeSecurity]
1577 public static extern IntPtr JointGroupCreate(int max_size);
1578
1579 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupDestroy"), SuppressUnmanagedCodeSecurity]
1580 public static extern void JointGroupDestroy(IntPtr group);
1581
1582 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupEmpty"), SuppressUnmanagedCodeSecurity]
1583 public static extern void JointGroupEmpty(IntPtr group);
1584
1585 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorAngle"), SuppressUnmanagedCodeSecurity]
1586 public static extern void JointSetAMotorAngle(IntPtr j, int anum, dReal angle);
1587
1588 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorAxis"), SuppressUnmanagedCodeSecurity]
1589 public static extern void JointSetAMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z);
1590
1591 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorMode"), SuppressUnmanagedCodeSecurity]
1592 public static extern void JointSetAMotorMode(IntPtr j, int mode);
1593
1594 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorNumAxes"), SuppressUnmanagedCodeSecurity]
1595 public static extern void JointSetAMotorNumAxes(IntPtr group, int num);
1596
1597 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorParam"), SuppressUnmanagedCodeSecurity]
1598 public static extern void JointSetAMotorParam(IntPtr group, int parameter, dReal value);
1599
1600 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetBallAnchor"), SuppressUnmanagedCodeSecurity]
1601 public static extern void JointSetBallAnchor(IntPtr j, dReal x, dReal y, dReal z);
1602
1603 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetBallAnchor2"), SuppressUnmanagedCodeSecurity]
1604 public static extern void JointSetBallAnchor2(IntPtr j, dReal x, dReal y, dReal z);
1605
1606 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetData"), SuppressUnmanagedCodeSecurity]
1607 public static extern void JointSetData(IntPtr j, IntPtr data);
1608
1609 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetFeedback"), SuppressUnmanagedCodeSecurity]
1610 public static extern void JointSetFeedback(IntPtr j, out JointFeedback feedback);
1611
1612 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetFixed"), SuppressUnmanagedCodeSecurity]
1613 public static extern void JointSetFixed(IntPtr j);
1614
1615 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAnchor"), SuppressUnmanagedCodeSecurity]
1616 public static extern void JointSetHingeAnchor(IntPtr j, dReal x, dReal y, dReal z);
1617
1618 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAnchorDelta"), SuppressUnmanagedCodeSecurity]
1619 public static extern void JointSetHingeAnchorDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
1620
1621 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAxis"), SuppressUnmanagedCodeSecurity]
1622 public static extern void JointSetHingeAxis(IntPtr j, dReal x, dReal y, dReal z);
1623
1624 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeParam"), SuppressUnmanagedCodeSecurity]
1625 public static extern void JointSetHingeParam(IntPtr j, int parameter, dReal value);
1626
1627 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Anchor"), SuppressUnmanagedCodeSecurity]
1628 public static extern void JointSetHinge2Anchor(IntPtr j, dReal x, dReal y, dReal z);
1629
1630 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Axis1"), SuppressUnmanagedCodeSecurity]
1631 public static extern void JointSetHinge2Axis1(IntPtr j, dReal x, dReal y, dReal z);
1632
1633 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Axis2"), SuppressUnmanagedCodeSecurity]
1634 public static extern void JointSetHinge2Axis2(IntPtr j, dReal x, dReal y, dReal z);
1635
1636 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Param"), SuppressUnmanagedCodeSecurity]
1637 public static extern void JointSetHinge2Param(IntPtr j, int parameter, dReal value);
1638
1639 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorAxis"), SuppressUnmanagedCodeSecurity]
1640 public static extern void JointSetLMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z);
1641
1642 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorNumAxes"), SuppressUnmanagedCodeSecurity]
1643 public static extern void JointSetLMotorNumAxes(IntPtr j, int num);
1644
1645 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorParam"), SuppressUnmanagedCodeSecurity]
1646 public static extern void JointSetLMotorParam(IntPtr j, int parameter, dReal value);
1647
1648 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DAngleParam"), SuppressUnmanagedCodeSecurity]
1649 public static extern void JointSetPlane2DAngleParam(IntPtr j, int parameter, dReal value);
1650
1651 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DXParam"), SuppressUnmanagedCodeSecurity]
1652 public static extern void JointSetPlane2DXParam(IntPtr j, int parameter, dReal value);
1653
1654 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DYParam"), SuppressUnmanagedCodeSecurity]
1655 public static extern void JointSetPlane2DYParam(IntPtr j, int parameter, dReal value);
1656
1657 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAnchor"), SuppressUnmanagedCodeSecurity]
1658 public static extern void JointSetPRAnchor(IntPtr j, dReal x, dReal y, dReal z);
1659
1660 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAxis1"), SuppressUnmanagedCodeSecurity]
1661 public static extern void JointSetPRAxis1(IntPtr j, dReal x, dReal y, dReal z);
1662
1663 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAxis2"), SuppressUnmanagedCodeSecurity]
1664 public static extern void JointSetPRAxis2(IntPtr j, dReal x, dReal y, dReal z);
1665
1666 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRParam"), SuppressUnmanagedCodeSecurity]
1667 public static extern void JointSetPRParam(IntPtr j, int parameter, dReal value);
1668
1669 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderAxis"), SuppressUnmanagedCodeSecurity]
1670 public static extern void JointSetSliderAxis(IntPtr j, dReal x, dReal y, dReal z);
1671
1672 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderAxisDelta"), SuppressUnmanagedCodeSecurity]
1673 public static extern void JointSetSliderAxisDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
1674
1675 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderParam"), SuppressUnmanagedCodeSecurity]
1676 public static extern void JointSetSliderParam(IntPtr j, int parameter, dReal value);
1677
1678 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAnchor"), SuppressUnmanagedCodeSecurity]
1679 public static extern void JointSetUniversalAnchor(IntPtr j, dReal x, dReal y, dReal z);
1680
1681 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAxis1"), SuppressUnmanagedCodeSecurity]
1682 public static extern void JointSetUniversalAxis1(IntPtr j, dReal x, dReal y, dReal z);
1683
1684 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAxis2"), SuppressUnmanagedCodeSecurity]
1685 public static extern void JointSetUniversalAxis2(IntPtr j, dReal x, dReal y, dReal z);
1686
1687 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalParam"), SuppressUnmanagedCodeSecurity]
1688 public static extern void JointSetUniversalParam(IntPtr j, int parameter, dReal value);
1689
1690 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dLDLTAddTL"), SuppressUnmanagedCodeSecurity]
1691 public static extern void LDLTAddTL(ref dReal L, ref dReal d, ref dReal a, int n, int nskip);
1692
1693 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassAdd"), SuppressUnmanagedCodeSecurity]
1694 public static extern void MassAdd(ref Mass a, ref Mass b);
1695
1696 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassAdjust"), SuppressUnmanagedCodeSecurity]
1697 public static extern void MassAdjust(ref Mass m, dReal newmass);
1698
1699 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassCheck"), SuppressUnmanagedCodeSecurity]
1700 public static extern bool MassCheck(ref Mass m);
1701
1702 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity]
1703 public static extern void MassRotate(ref Mass mass, ref Matrix3 R);
1704
1705 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity]
1706 public static extern void MassRotate(ref Mass mass, ref dReal M00);
1707
1708 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetBox"), SuppressUnmanagedCodeSecurity]
1709 public static extern void MassSetBox(out Mass mass, dReal density, dReal lx, dReal ly, dReal lz);
1710
1711 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetBoxTotal"), SuppressUnmanagedCodeSecurity]
1712 public static extern void MassSetBoxTotal(out Mass mass, dReal total_mass, dReal lx, dReal ly, dReal lz);
1713
1714 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCapsule"), SuppressUnmanagedCodeSecurity]
1715 public static extern void MassSetCapsule(out Mass mass, dReal density, int direction, dReal radius, dReal length);
1716
1717 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCapsuleTotal"), SuppressUnmanagedCodeSecurity]
1718 public static extern void MassSetCapsuleTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length);
1719
1720 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCylinder"), SuppressUnmanagedCodeSecurity]
1721 public static extern void MassSetCylinder(out Mass mass, dReal density, int direction, dReal radius, dReal length);
1722
1723 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCylinderTotal"), SuppressUnmanagedCodeSecurity]
1724 public static extern void MassSetCylinderTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length);
1725
1726 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetParameters"), SuppressUnmanagedCodeSecurity]
1727 public static extern void MassSetParameters(out Mass mass, dReal themass,
1728 dReal cgx, dReal cgy, dReal cgz,
1729 dReal i11, dReal i22, dReal i33,
1730 dReal i12, dReal i13, dReal i23);
1731
1732 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetSphere"), SuppressUnmanagedCodeSecurity]
1733 public static extern void MassSetSphere(out Mass mass, dReal density, dReal radius);
1734
1735 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetSphereTotal"), SuppressUnmanagedCodeSecurity]
1736 public static extern void dMassSetSphereTotal(out Mass mass, dReal total_mass, dReal radius);
1737
1738 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetTrimesh"), SuppressUnmanagedCodeSecurity]
1739 public static extern void MassSetTrimesh(out Mass mass, dReal density, IntPtr g);
1740
1741 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetZero"), SuppressUnmanagedCodeSecurity]
1742 public static extern void MassSetZero(out Mass mass);
1743
1744 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassTranslate"), SuppressUnmanagedCodeSecurity]
1745 public static extern void MassTranslate(ref Mass mass, dReal x, dReal y, dReal z);
1746
1747 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply0"), SuppressUnmanagedCodeSecurity]
1748 public static extern void Multiply0(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r);
1749
1750 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply0"), SuppressUnmanagedCodeSecurity]
1751 private static extern void MultiplyiM3V3(out Vector3 vout, ref Matrix3 matrix, ref Vector3 vect,int p, int q, int r);
1752 public static void MultiplyM3V3(out Vector3 outvector, ref Matrix3 matrix, ref Vector3 invector)
1753 {
1754 MultiplyiM3V3(out outvector, ref matrix, ref invector, 3, 3, 1);
1755 }
1756
1757 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply1"), SuppressUnmanagedCodeSecurity]
1758 public static extern void Multiply1(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r);
1759
1760 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply2"), SuppressUnmanagedCodeSecurity]
1761 public static extern void Multiply2(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r);
1762
1763 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQFromAxisAndAngle"), SuppressUnmanagedCodeSecurity]
1764 public static extern void QFromAxisAndAngle(out Quaternion q, dReal ax, dReal ay, dReal az, dReal angle);
1765
1766 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQfromR"), SuppressUnmanagedCodeSecurity]
1767 public static extern void QfromR(out Quaternion q, ref Matrix3 R);
1768
1769 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply0"), SuppressUnmanagedCodeSecurity]
1770 public static extern void QMultiply0(out Quaternion qa, ref Quaternion qb, ref Quaternion qc);
1771
1772 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply1"), SuppressUnmanagedCodeSecurity]
1773 public static extern void QMultiply1(out Quaternion qa, ref Quaternion qb, ref Quaternion qc);
1774
1775 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply2"), SuppressUnmanagedCodeSecurity]
1776 public static extern void QMultiply2(out Quaternion qa, ref Quaternion qb, ref Quaternion qc);
1777
1778 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply3"), SuppressUnmanagedCodeSecurity]
1779 public static extern void QMultiply3(out Quaternion qa, ref Quaternion qb, ref Quaternion qc);
1780
1781 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQSetIdentity"), SuppressUnmanagedCodeSecurity]
1782 public static extern void QSetIdentity(out Quaternion q);
1783
1784 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity]
1785 public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref Vector3 center, ref Vector3 extents, int depth);
1786
1787 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity]
1788 public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref dReal centerX, ref dReal extentsX, int depth);
1789
1790 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRandReal"), SuppressUnmanagedCodeSecurity]
1791 public static extern dReal RandReal();
1792
1793 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFrom2Axes"), SuppressUnmanagedCodeSecurity]
1794 public static extern void RFrom2Axes(out Matrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz);
1795
1796 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromAxisAndAngle"), SuppressUnmanagedCodeSecurity]
1797 public static extern void RFromAxisAndAngle(out Matrix3 R, dReal x, dReal y, dReal z, dReal angle);
1798
1799 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromEulerAngles"), SuppressUnmanagedCodeSecurity]
1800 public static extern void RFromEulerAngles(out Matrix3 R, dReal phi, dReal theta, dReal psi);
1801
1802 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRfromQ"), SuppressUnmanagedCodeSecurity]
1803 public static extern void RfromQ(out Matrix3 R, ref Quaternion q);
1804
1805 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromZAxis"), SuppressUnmanagedCodeSecurity]
1806 public static extern void RFromZAxis(out Matrix3 R, dReal ax, dReal ay, dReal az);
1807
1808 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRSetIdentity"), SuppressUnmanagedCodeSecurity]
1809 public static extern void RSetIdentity(out Matrix3 R);
1810
1811 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSetValue"), SuppressUnmanagedCodeSecurity]
1812 public static extern void SetValue(out dReal a, int n);
1813
1814 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSetZero"), SuppressUnmanagedCodeSecurity]
1815 public static extern void SetZero(out dReal a, int n);
1816
1817 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSimpleSpaceCreate"), SuppressUnmanagedCodeSecurity]
1818 public static extern IntPtr SimpleSpaceCreate(IntPtr space);
1819
1820 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveCholesky"), SuppressUnmanagedCodeSecurity]
1821 public static extern void SolveCholesky(ref dReal L, out dReal b, int n);
1822
1823 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveL1"), SuppressUnmanagedCodeSecurity]
1824 public static extern void SolveL1(ref dReal L, out dReal b, int n, int nskip);
1825
1826 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveL1T"), SuppressUnmanagedCodeSecurity]
1827 public static extern void SolveL1T(ref dReal L, out dReal b, int n, int nskip);
1828
1829 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveLDLT"), SuppressUnmanagedCodeSecurity]
1830 public static extern void SolveLDLT(ref dReal L, ref dReal d, out dReal b, int n, int nskip);
1831
1832 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceAdd"), SuppressUnmanagedCodeSecurity]
1833 public static extern void SpaceAdd(IntPtr space, IntPtr geom);
1834
1835 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceLockQuery"), SuppressUnmanagedCodeSecurity]
1836 public static extern bool SpaceLockQuery(IntPtr space);
1837
1838 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceClean"), SuppressUnmanagedCodeSecurity]
1839 public static extern void SpaceClean(IntPtr space);
1840
1841 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceCollide"), SuppressUnmanagedCodeSecurity]
1842 public static extern void SpaceCollide(IntPtr space, IntPtr data, NearCallback callback);
1843
1844 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceCollide2"), SuppressUnmanagedCodeSecurity]
1845 public static extern void SpaceCollide2(IntPtr space1, IntPtr space2, IntPtr data, NearCallback callback);
1846
1847 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceDestroy"), SuppressUnmanagedCodeSecurity]
1848 public static extern void SpaceDestroy(IntPtr space);
1849
1850 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetCleanup"), SuppressUnmanagedCodeSecurity]
1851 public static extern bool SpaceGetCleanup(IntPtr space);
1852
1853 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetNumGeoms"), SuppressUnmanagedCodeSecurity]
1854 public static extern int SpaceGetNumGeoms(IntPtr space);
1855
1856 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetGeom"), SuppressUnmanagedCodeSecurity]
1857 public static extern IntPtr SpaceGetGeom(IntPtr space, int i);
1858
1859 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetSublevel"), SuppressUnmanagedCodeSecurity]
1860 public static extern int SpaceGetSublevel(IntPtr space);
1861
1862 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceQuery"), SuppressUnmanagedCodeSecurity]
1863 public static extern bool SpaceQuery(IntPtr space, IntPtr geom);
1864
1865 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceRemove"), SuppressUnmanagedCodeSecurity]
1866 public static extern void SpaceRemove(IntPtr space, IntPtr geom);
1867
1868 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetCleanup"), SuppressUnmanagedCodeSecurity]
1869 public static extern void SpaceSetCleanup(IntPtr space, bool mode);
1870
1871 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity]
1872 public static extern void SpaceSetSublevel(IntPtr space, int sublevel);
1873
1874 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSweepAndPruneSpaceCreate"), SuppressUnmanagedCodeSecurity]
1875 public static extern IntPtr SweepAndPruneSpaceCreate(IntPtr space, int AxisOrder);
1876
1877 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dVectorScale"), SuppressUnmanagedCodeSecurity]
1878 public static extern void VectorScale(out dReal a, ref dReal d, int n);
1879
1880 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldCreate"), SuppressUnmanagedCodeSecurity]
1881 public static extern IntPtr WorldCreate();
1882
1883 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldDestroy"), SuppressUnmanagedCodeSecurity]
1884 public static extern void WorldDestroy(IntPtr world);
1885
1886 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableAverageSamplesCount"), SuppressUnmanagedCodeSecurity]
1887 public static extern int WorldGetAutoDisableAverageSamplesCount(IntPtr world);
1888
1889 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity]
1890 public static extern dReal WorldGetAutoDisableAngularThreshold(IntPtr world);
1891
1892 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity]
1893 public static extern bool WorldGetAutoDisableFlag(IntPtr world);
1894
1895 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity]
1896 public static extern dReal WorldGetAutoDisableLinearThreshold(IntPtr world);
1897
1898 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity]
1899 public static extern int WorldGetAutoDisableSteps(IntPtr world);
1900
1901 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableTime"), SuppressUnmanagedCodeSecurity]
1902 public static extern dReal WorldGetAutoDisableTime(IntPtr world);
1903
1904 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity]
1905 public static extern int WorldGetAutoEnableDepthSF1(IntPtr world);
1906
1907 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetCFM"), SuppressUnmanagedCodeSecurity]
1908 public static extern dReal WorldGetCFM(IntPtr world);
1909
1910 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetERP"), SuppressUnmanagedCodeSecurity]
1911 public static extern dReal WorldGetERP(IntPtr world);
1912
1913 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity]
1914 public static extern void WorldGetGravity(IntPtr world, out Vector3 gravity);
1915
1916 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity]
1917 public static extern void WorldGetGravity(IntPtr world, out dReal X);
1918
1919 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity]
1920 public static extern dReal WorldGetContactMaxCorrectingVel(IntPtr world);
1921
1922 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity]
1923 public static extern dReal WorldGetContactSurfaceLayer(IntPtr world);
1924
1925 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAngularDamping"), SuppressUnmanagedCodeSecurity]
1926 public static extern dReal WorldGetAngularDamping(IntPtr world);
1927
1928 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity]
1929 public static extern dReal WorldGetAngularDampingThreshold(IntPtr world);
1930
1931 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetLinearDamping"), SuppressUnmanagedCodeSecurity]
1932 public static extern dReal WorldGetLinearDamping(IntPtr world);
1933
1934 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity]
1935 public static extern dReal WorldGetLinearDampingThreshold(IntPtr world);
1936
1937 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity]
1938 public static extern int WorldGetQuickStepNumIterations(IntPtr world);
1939
1940 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetQuickStepW"), SuppressUnmanagedCodeSecurity]
1941 public static extern dReal WorldGetQuickStepW(IntPtr world);
1942
1943 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetMaxAngularSpeed"), SuppressUnmanagedCodeSecurity]
1944 public static extern dReal WorldGetMaxAngularSpeed(IntPtr world);
1945
1946 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity]
1947 public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out Vector3 force);
1948
1949 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity]
1950 public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out dReal forceX);
1951
1952 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldQuickStep"), SuppressUnmanagedCodeSecurity]
1953 public static extern void WorldQuickStep(IntPtr world, dReal stepsize);
1954
1955 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAngularDamping"), SuppressUnmanagedCodeSecurity]
1956 public static extern void WorldSetAngularDamping(IntPtr world, dReal scale);
1957
1958 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity]
1959 public static extern void WorldSetAngularDampingThreshold(IntPtr world, dReal threshold);
1960
1961 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity]
1962 public static extern void WorldSetAutoDisableAngularThreshold(IntPtr world, dReal angular_threshold);
1963
1964 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableAverageSamplesCount"), SuppressUnmanagedCodeSecurity]
1965 public static extern void WorldSetAutoDisableAverageSamplesCount(IntPtr world, int average_samples_count);
1966
1967 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableFlag"), SuppressUnmanagedCodeSecurity]
1968 public static extern void WorldSetAutoDisableFlag(IntPtr world, bool do_auto_disable);
1969
1970 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity]
1971 public static extern void WorldSetAutoDisableLinearThreshold(IntPtr world, dReal linear_threshold);
1972
1973 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableSteps"), SuppressUnmanagedCodeSecurity]
1974 public static extern void WorldSetAutoDisableSteps(IntPtr world, int steps);
1975
1976 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableTime"), SuppressUnmanagedCodeSecurity]
1977 public static extern void WorldSetAutoDisableTime(IntPtr world, dReal time);
1978
1979 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity]
1980 public static extern void WorldSetAutoEnableDepthSF1(IntPtr world, int autoEnableDepth);
1981
1982 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetCFM"), SuppressUnmanagedCodeSecurity]
1983 public static extern void WorldSetCFM(IntPtr world, dReal cfm);
1984
1985 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity]
1986 public static extern void WorldSetContactMaxCorrectingVel(IntPtr world, dReal vel);
1987
1988 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity]
1989 public static extern void WorldSetContactSurfaceLayer(IntPtr world, dReal depth);
1990
1991 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetDamping"), SuppressUnmanagedCodeSecurity]
1992 public static extern void WorldSetDamping(IntPtr world, dReal linear_scale, dReal angular_scale);
1993
1994 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetERP"), SuppressUnmanagedCodeSecurity]
1995 public static extern void WorldSetERP(IntPtr world, dReal erp);
1996
1997 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetGravity"), SuppressUnmanagedCodeSecurity]
1998 public static extern void WorldSetGravity(IntPtr world, dReal x, dReal y, dReal z);
1999
2000 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetLinearDamping"), SuppressUnmanagedCodeSecurity]
2001 public static extern void WorldSetLinearDamping(IntPtr world, dReal scale);
2002
2003 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity]
2004 public static extern void WorldSetLinearDampingThreshold(IntPtr world, dReal threshold);
2005
2006 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity]
2007 public static extern void WorldSetQuickStepNumIterations(IntPtr world, int num);
2008
2009 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetQuickStepW"), SuppressUnmanagedCodeSecurity]
2010 public static extern void WorldSetQuickStepW(IntPtr world, dReal over_relaxation);
2011
2012 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetMaxAngularSpeed"), SuppressUnmanagedCodeSecurity]
2013 public static extern void WorldSetMaxAngularSpeed(IntPtr world, dReal max_speed);
2014
2015 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldStep"), SuppressUnmanagedCodeSecurity]
2016 public static extern void WorldStep(IntPtr world, dReal stepsize);
2017
2018 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldStepFast1"), SuppressUnmanagedCodeSecurity]
2019 public static extern void WorldStepFast1(IntPtr world, dReal stepsize, int maxiterations);
2020
2021 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldExportDIF"), SuppressUnmanagedCodeSecurity]
2022 public static extern void WorldExportDIF(IntPtr world, string filename, bool append, string prefix);
2023 }
2024}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs
new file mode 100644
index 0000000..0e46471
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs
@@ -0,0 +1,2036 @@
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
28
29// Revision by Ubit 2011/12
30
31using System;
32using System.Collections.Generic;
33using System.Reflection;
34using OpenMetaverse;
35using OdeAPI;
36using OpenSim.Framework;
37using OpenSim.Region.PhysicsModules.SharedBase;
38using log4net;
39
40namespace OpenSim.Region.PhysicsModule.ubOde
41{
42 /// <summary>
43 /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves.
44 /// </summary>
45
46 public enum dParam : int
47 {
48 LowStop = 0,
49 HiStop = 1,
50 Vel = 2,
51 FMax = 3,
52 FudgeFactor = 4,
53 Bounce = 5,
54 CFM = 6,
55 StopERP = 7,
56 StopCFM = 8,
57 LoStop2 = 256,
58 HiStop2 = 257,
59 Vel2 = 258,
60 FMax2 = 259,
61 StopERP2 = 7 + 256,
62 StopCFM2 = 8 + 256,
63 LoStop3 = 512,
64 HiStop3 = 513,
65 Vel3 = 514,
66 FMax3 = 515,
67 StopERP3 = 7 + 512,
68 StopCFM3 = 8 + 512
69 }
70
71 public class OdeCharacter : PhysicsActor
72 {
73 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
74
75 private Vector3 _position;
76 private Vector3 _zeroPosition;
77 private Vector3 _velocity;
78 private Vector3 _target_velocity;
79 private Vector3 _acceleration;
80 private Vector3 m_rotationalVelocity;
81 private Vector3 m_size;
82 private Vector3 m_collideNormal;
83 private Vector3 m_lastFallVel;
84 private Quaternion m_orientation;
85 private Quaternion m_orientation2D;
86 private float m_mass = 80f;
87 public float m_density = 60f;
88 private bool m_pidControllerActive = true;
89
90 const float basePID_D = 0.55f; // scaled for unit mass unit time (2200 /(50*80))
91 const float basePID_P = 0.225f; // scaled for unit mass unit time (900 /(50*80))
92 public float PID_D;
93 public float PID_P;
94
95 private float timeStep;
96 private float invtimeStep;
97
98 private float m_feetOffset = 0;
99 private float feetOff = 0;
100 private float boneOff = 0;
101 private float AvaAvaSizeXsq = 0.3f;
102 private float AvaAvaSizeYsq = 0.2f;
103
104 public float walkDivisor = 1.3f;
105 public float runDivisor = 0.8f;
106 private bool m_flying = false;
107 private bool m_iscolliding = false;
108 private bool m_iscollidingGround = false;
109 private bool m_iscollidingObj = false;
110 private bool m_alwaysRun = false;
111
112 private bool _zeroFlag = false;
113 private bool m_haveLastFallVel = false;
114
115 private uint m_localID = 0;
116 public bool m_returnCollisions = false;
117 // taints and their non-tainted counterparts
118 public bool m_isPhysical = false; // the current physical status
119 public float MinimumGroundFlightOffset = 3f;
120
121 private float m_buoyancy = 0f;
122
123 private bool m_freemove = false;
124
125// private string m_name = String.Empty;
126 // other filter control
127 int m_colliderfilter = 0;
128 int m_colliderGroundfilter = 0;
129 int m_colliderObjectfilter = 0;
130
131 // Default we're a Character
132 private CollisionCategories m_collisionCategories = (CollisionCategories.Character);
133
134 // Default, Collide with Other Geometries, spaces, bodies and characters.
135 private CollisionCategories m_collisionFlags = (CollisionCategories.Character
136 | CollisionCategories.Geom
137 | CollisionCategories.VolumeDtc
138 );
139 // we do land collisions not ode | CollisionCategories.Land);
140 public IntPtr Body = IntPtr.Zero;
141 private ODEScene m_parent_scene;
142 private IntPtr capsule = IntPtr.Zero;
143 public IntPtr collider = IntPtr.Zero;
144
145 public IntPtr Amotor = IntPtr.Zero;
146
147 public d.Mass ShellMass;
148
149 public int m_eventsubscription = 0;
150 private int m_cureventsubscription = 0;
151 private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate();
152 private bool SentEmptyCollisionsEvent;
153
154 // unique UUID of this character object
155 public UUID m_uuid;
156 public bool bad = false;
157
158 float mu;
159
160 // HoverHeight control
161 private float m_PIDHoverHeight;
162 private float m_PIDHoverTau;
163 private bool m_useHoverPID;
164 private PIDHoverType m_PIDHoverType;
165 private float m_targetHoverHeight;
166
167
168 public OdeCharacter(uint localID, String avName, ODEScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor)
169 {
170 m_uuid = UUID.Random();
171 m_localID = localID;
172 m_parent_scene = parent_scene;
173
174 timeStep = parent_scene.ODE_STEPSIZE;
175 invtimeStep = 1 / timeStep;
176
177 if (pos.IsFinite())
178 {
179 if (pos.Z > 99999f)
180 {
181 pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
182 }
183 if (pos.Z < -100f) // shouldn't this be 0 ?
184 {
185 pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
186 }
187 _position = pos;
188 }
189 else
190 {
191 _position = new Vector3(((float)m_parent_scene.WorldExtents.X * 0.5f), ((float)m_parent_scene.WorldExtents.Y * 0.5f), parent_scene.GetTerrainHeightAtXY(128f, 128f) + 10f);
192 m_log.Warn("[PHYSICS]: Got NaN Position on Character Create");
193 }
194
195 m_size.X = pSize.X;
196 m_size.Y = pSize.Y;
197 m_size.Z = pSize.Z;
198
199 if(m_size.X <0.01f)
200 m_size.X = 0.01f;
201 if(m_size.Y <0.01f)
202 m_size.Y = 0.01f;
203 if(m_size.Z <0.01f)
204 m_size.Z = 0.01f;
205
206 m_feetOffset = pfeetOffset;
207 m_orientation = Quaternion.Identity;
208 m_orientation2D = Quaternion.Identity;
209 m_density = density;
210
211 // force lower density for testing
212 m_density = 3.0f;
213
214 mu = m_parent_scene.AvatarFriction;
215
216 walkDivisor = walk_divisor;
217 runDivisor = rundivisor;
218
219 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default
220
221 PID_D = basePID_D * m_mass * invtimeStep;
222 PID_P = basePID_P * m_mass * invtimeStep;
223
224 m_isPhysical = false; // current status: no ODE information exists
225
226 Name = avName;
227
228 AddChange(changes.Add, null);
229 }
230
231 public override int PhysicsActorType
232 {
233 get { return (int)ActorTypes.Agent; }
234 set { return; }
235 }
236
237 public override void getContactData(ref ContactData cdata)
238 {
239 cdata.mu = mu;
240 cdata.bounce = 0;
241 cdata.softcolide = false;
242 }
243
244 public override bool Building { get; set; }
245
246 /// <summary>
247 /// If this is set, the avatar will move faster
248 /// </summary>
249 public override bool SetAlwaysRun
250 {
251 get { return m_alwaysRun; }
252 set { m_alwaysRun = value; }
253 }
254
255 public override uint LocalID
256 {
257 get { return m_localID; }
258 set { m_localID = value; }
259 }
260
261 public override PhysicsActor ParentActor
262 {
263 get { return (PhysicsActor)this; }
264 }
265
266 public override bool Grabbed
267 {
268 set { return; }
269 }
270
271 public override bool Selected
272 {
273 set { return; }
274 }
275
276 public override float Buoyancy
277 {
278 get { return m_buoyancy; }
279 set { m_buoyancy = value; }
280 }
281
282 public override bool FloatOnWater
283 {
284 set { return; }
285 }
286
287 public override bool IsPhysical
288 {
289 get { return m_isPhysical; }
290 set { return; }
291 }
292
293 public override bool ThrottleUpdates
294 {
295 get { return false; }
296 set { return; }
297 }
298
299 public override bool Flying
300 {
301 get { return m_flying; }
302 set
303 {
304 m_flying = value;
305// m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying);
306 }
307 }
308
309 /// <summary>
310 /// Returns if the avatar is colliding in general.
311 /// This includes the ground and objects and avatar.
312 /// </summary>
313 public override bool IsColliding
314 {
315 get { return (m_iscolliding || m_iscollidingGround); }
316 set
317 {
318 if (value)
319 {
320 m_colliderfilter += 3;
321 if (m_colliderfilter > 3)
322 m_colliderfilter = 3;
323 }
324 else
325 {
326 m_colliderfilter--;
327 if (m_colliderfilter < 0)
328 m_colliderfilter = 0;
329 }
330
331 if (m_colliderfilter == 0)
332 m_iscolliding = false;
333 else
334 {
335 m_pidControllerActive = true;
336 m_iscolliding = true;
337 m_freemove = false;
338 }
339 }
340 }
341
342 /// <summary>
343 /// Returns if an avatar is colliding with the ground
344 /// </summary>
345 public override bool CollidingGround
346 {
347 get { return m_iscollidingGround; }
348 set
349 {
350/* we now control this
351 if (value)
352 {
353 m_colliderGroundfilter += 2;
354 if (m_colliderGroundfilter > 2)
355 m_colliderGroundfilter = 2;
356 }
357 else
358 {
359 m_colliderGroundfilter--;
360 if (m_colliderGroundfilter < 0)
361 m_colliderGroundfilter = 0;
362 }
363
364 if (m_colliderGroundfilter == 0)
365 m_iscollidingGround = false;
366 else
367 m_iscollidingGround = true;
368 */
369 }
370
371 }
372
373 /// <summary>
374 /// Returns if the avatar is colliding with an object
375 /// </summary>
376 public override bool CollidingObj
377 {
378 get { return m_iscollidingObj; }
379 set
380 {
381 // Ubit filter this also
382 if (value)
383 {
384 m_colliderObjectfilter += 2;
385 if (m_colliderObjectfilter > 2)
386 m_colliderObjectfilter = 2;
387 }
388 else
389 {
390 m_colliderObjectfilter--;
391 if (m_colliderObjectfilter < 0)
392 m_colliderObjectfilter = 0;
393 }
394
395 if (m_colliderObjectfilter == 0)
396 m_iscollidingObj = false;
397 else
398 m_iscollidingObj = true;
399
400// m_iscollidingObj = value;
401
402 if (m_iscollidingObj)
403 m_pidControllerActive = false;
404 else
405 m_pidControllerActive = true;
406 }
407 }
408
409 /// <summary>
410 /// turn the PID controller on or off.
411 /// The PID Controller will turn on all by itself in many situations
412 /// </summary>
413 /// <param name="status"></param>
414 public void SetPidStatus(bool status)
415 {
416 m_pidControllerActive = status;
417 }
418
419 public override bool Stopped
420 {
421 get { return _zeroFlag; }
422 }
423
424 /// <summary>
425 /// This 'puts' an avatar somewhere in the physics space.
426 /// Not really a good choice unless you 'know' it's a good
427 /// spot otherwise you're likely to orbit the avatar.
428 /// </summary>
429 public override Vector3 Position
430 {
431 get { return _position; }
432 set
433 {
434 if (value.IsFinite())
435 {
436 if (value.Z > 9999999f)
437 {
438 value.Z = m_parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
439 }
440 if (value.Z < -100f)
441 {
442 value.Z = m_parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
443 }
444 AddChange(changes.Position, value);
445 }
446 else
447 {
448 m_log.Warn("[PHYSICS]: Got a NaN Position from Scene on a Character");
449 }
450 }
451 }
452
453 public override Vector3 RotationalVelocity
454 {
455 get { return m_rotationalVelocity; }
456 set { m_rotationalVelocity = value; }
457 }
458
459 /// <summary>
460 /// This property sets the height of the avatar only. We use the height to make sure the avatar stands up straight
461 /// and use it to offset landings properly
462 /// </summary>
463 public override Vector3 Size
464 {
465 get
466 {
467 return m_size;
468 }
469 set
470 {
471 if (value.IsFinite())
472 {
473 if(value.X <0.01f)
474 value.X = 0.01f;
475 if(value.Y <0.01f)
476 value.Y = 0.01f;
477 if(value.Z <0.01f)
478 value.Z = 0.01f;
479
480 AddChange(changes.Size, value);
481 }
482 else
483 {
484 m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character");
485 }
486 }
487 }
488
489 public override void setAvatarSize(Vector3 size, float feetOffset)
490 {
491 if (size.IsFinite())
492 {
493 if (size.X < 0.01f)
494 size.X = 0.01f;
495 if (size.Y < 0.01f)
496 size.Y = 0.01f;
497 if (size.Z < 0.01f)
498 size.Z = 0.01f;
499
500 strAvatarSize st = new strAvatarSize();
501 st.size = size;
502 st.offset = feetOffset;
503 AddChange(changes.AvatarSize, st);
504 }
505 else
506 {
507 m_log.Warn("[PHYSICS]: Got a NaN AvatarSize from Scene on a Character");
508 }
509
510 }
511 /// <summary>
512 /// This creates the Avatar's physical Surrogate at the position supplied
513 /// </summary>
514 /// <param name="npositionX"></param>
515 /// <param name="npositionY"></param>
516 /// <param name="npositionZ"></param>
517
518 //
519 /// <summary>
520 /// Uses the capped cyllinder volume formula to calculate the avatar's mass.
521 /// This may be used in calculations in the scene/scenepresence
522 /// </summary>
523 public override float Mass
524 {
525 get
526 {
527 return m_mass;
528 }
529 }
530 public override void link(PhysicsActor obj)
531 {
532
533 }
534
535 public override void delink()
536 {
537
538 }
539
540 public override void LockAngularMotion(byte axislocks)
541 {
542
543 }
544
545
546 public override Vector3 Force
547 {
548 get { return _target_velocity; }
549 set { return; }
550 }
551
552 public override int VehicleType
553 {
554 get { return 0; }
555 set { return; }
556 }
557
558 public override void VehicleFloatParam(int param, float value)
559 {
560
561 }
562
563 public override void VehicleVectorParam(int param, Vector3 value)
564 {
565
566 }
567
568 public override void VehicleRotationParam(int param, Quaternion rotation)
569 {
570
571 }
572
573 public override void VehicleFlags(int param, bool remove)
574 {
575
576 }
577
578 public override void SetVolumeDetect(int param)
579 {
580
581 }
582
583 public override Vector3 CenterOfMass
584 {
585 get
586 {
587 Vector3 pos = _position;
588 return pos;
589 }
590 }
591
592 public override Vector3 GeometricCenter
593 {
594 get
595 {
596 Vector3 pos = _position;
597 return pos;
598 }
599 }
600
601 public override PrimitiveBaseShape Shape
602 {
603 set { return; }
604 }
605
606 public override Vector3 rootVelocity
607 {
608 get
609 {
610 return _velocity;
611 }
612 }
613
614 public override Vector3 Velocity
615 {
616 get
617 {
618 return _velocity;
619 }
620 set
621 {
622 if (value.IsFinite())
623 {
624 AddChange(changes.Velocity, value);
625 }
626 else
627 {
628 m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character");
629 }
630 }
631 }
632
633 public override Vector3 TargetVelocity
634 {
635 get
636 {
637 return m_targetVelocity;
638 }
639 set
640 {
641 if (value.IsFinite())
642 {
643 AddChange(changes.TargetVelocity, value);
644 }
645 else
646 {
647 m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character");
648 }
649 }
650 }
651
652 public override Vector3 Torque
653 {
654 get { return Vector3.Zero; }
655 set { return; }
656 }
657
658 public override float CollisionScore
659 {
660 get { return 0f; }
661 set { }
662 }
663
664 public override bool Kinematic
665 {
666 get { return false; }
667 set { }
668 }
669
670 public override Quaternion Orientation
671 {
672 get { return m_orientation; }
673 set
674 {
675// fakeori = value;
676// givefakeori++;
677 value.Normalize();
678 AddChange(changes.Orientation, value);
679 }
680 }
681
682 public override Vector3 Acceleration
683 {
684 get { return _acceleration; }
685 set { }
686 }
687
688 public void SetAcceleration(Vector3 accel)
689 {
690 m_pidControllerActive = true;
691 _acceleration = accel;
692 }
693
694 /// <summary>
695 /// Adds the force supplied to the Target Velocity
696 /// The PID controller takes this target velocity and tries to make it a reality
697 /// </summary>
698 /// <param name="force"></param>
699 public override void AddForce(Vector3 force, bool pushforce)
700 {
701 if (force.IsFinite())
702 {
703 if (pushforce)
704 {
705 AddChange(changes.Force, force * m_density / (m_parent_scene.ODE_STEPSIZE * 28f));
706 }
707 else
708 {
709 AddChange(changes.TargetVelocity, force);
710 }
711 }
712 else
713 {
714 m_log.Warn("[PHYSICS]: Got a NaN force applied to a Character");
715 }
716 //m_lastUpdateSent = false;
717 }
718
719 public override void AddAngularForce(Vector3 force, bool pushforce)
720 {
721
722 }
723
724 public override void SetMomentum(Vector3 momentum)
725 {
726 if (momentum.IsFinite())
727 AddChange(changes.Momentum, momentum);
728 }
729
730
731 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
732 {
733 // sizes one day should came from visual parameters
734 float sx = m_size.X;
735 float sy = m_size.Y;
736 float sz = m_size.Z;
737
738 float bot = -sz * 0.5f + m_feetOffset;
739 boneOff = bot + 0.3f;
740
741 float feetsz = sz * 0.45f;
742 if (feetsz > 0.6f)
743 feetsz = 0.6f;
744
745 feetOff = bot + feetsz;
746
747 AvaAvaSizeXsq = 0.4f * sx;
748 AvaAvaSizeXsq *= AvaAvaSizeXsq;
749 AvaAvaSizeYsq = 0.5f * sy;
750 AvaAvaSizeYsq *= AvaAvaSizeYsq;
751
752 m_parent_scene.waitForSpaceUnlock(m_parent_scene.CharsSpace);
753
754 collider = d.HashSpaceCreate(m_parent_scene.CharsSpace);
755 d.HashSpaceSetLevels(collider, -4, 3);
756 d.SpaceSetSublevel(collider, 3);
757 d.SpaceSetCleanup(collider, false);
758 d.GeomSetCategoryBits(collider, (uint)m_collisionCategories);
759 d.GeomSetCollideBits(collider, (uint)m_collisionFlags);
760
761 float r = m_size.X;
762 if (m_size.Y > r)
763 r = m_size.Y;
764 float l = m_size.Z - r;
765 r *= 0.5f;
766
767 capsule = d.CreateCapsule(collider, r, l);
768
769 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass
770
771 d.MassSetBoxTotal(out ShellMass, m_mass, m_size.X, m_size.Y, m_size.Z);
772
773 PID_D = basePID_D * m_mass / m_parent_scene.ODE_STEPSIZE;
774 PID_P = basePID_P * m_mass / m_parent_scene.ODE_STEPSIZE;
775
776 Body = d.BodyCreate(m_parent_scene.world);
777
778 _zeroFlag = false;
779 m_pidControllerActive = true;
780 m_freemove = false;
781
782 _velocity = Vector3.Zero;
783
784 d.BodySetAutoDisableFlag(Body, false);
785 d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
786
787 _position.X = npositionX;
788 _position.Y = npositionY;
789 _position.Z = npositionZ;
790
791 d.BodySetMass(Body, ref ShellMass);
792 d.GeomSetBody(capsule, Body);
793
794 // The purpose of the AMotor here is to keep the avatar's physical
795 // surrogate from rotating while moving
796 Amotor = d.JointCreateAMotor(m_parent_scene.world, IntPtr.Zero);
797 d.JointAttach(Amotor, Body, IntPtr.Zero);
798
799 d.JointSetAMotorMode(Amotor, 0);
800 d.JointSetAMotorNumAxes(Amotor, 3);
801 d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
802 d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
803 d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
804
805 d.JointSetAMotorAngle(Amotor, 0, 0);
806 d.JointSetAMotorAngle(Amotor, 1, 0);
807 d.JointSetAMotorAngle(Amotor, 2, 0);
808
809 d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD
810 d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f);
811 d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f);
812 d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
813 d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
814 d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
815
816 // These lowstops and high stops are effectively (no wiggle room)
817 d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f);
818 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f);
819 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f);
820 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f);
821 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f);
822 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f);
823
824 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
825 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0);
826 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0);
827
828 d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e8f);
829 d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e8f);
830 d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e8f);
831 }
832
833 /// <summary>
834 /// Destroys the avatar body and geom
835
836 private void AvatarGeomAndBodyDestroy()
837 {
838 // Kill the Amotor
839 if (Amotor != IntPtr.Zero)
840 {
841 d.JointDestroy(Amotor);
842 Amotor = IntPtr.Zero;
843 }
844
845 if (Body != IntPtr.Zero)
846 {
847 //kill the body
848 d.BodyDestroy(Body);
849 Body = IntPtr.Zero;
850 }
851
852 //kill the Geoms
853 if (capsule != IntPtr.Zero)
854 {
855 m_parent_scene.actor_name_map.Remove(capsule);
856 m_parent_scene.waitForSpaceUnlock(collider);
857 d.GeomDestroy(capsule);
858 capsule = IntPtr.Zero;
859 }
860
861 if (collider != IntPtr.Zero)
862 {
863 d.SpaceDestroy(collider);
864 collider = IntPtr.Zero;
865 }
866
867 }
868
869 //in place 2D rotation around Z assuming rot is normalised and is a rotation around Z
870 public void RotateXYonZ(ref float x, ref float y, ref Quaternion rot)
871 {
872 float sin = 2.0f * rot.Z * rot.W;
873 float cos = rot.W * rot.W - rot.Z * rot.Z;
874 float tx = x;
875
876 x = tx * cos - y * sin;
877 y = tx * sin + y * cos;
878 }
879 public void RotateXYonZ(ref float x, ref float y, ref float sin, ref float cos)
880 {
881 float tx = x;
882 x = tx * cos - y * sin;
883 y = tx * sin + y * cos;
884 }
885 public void invRotateXYonZ(ref float x, ref float y, ref float sin, ref float cos)
886 {
887 float tx = x;
888 x = tx * cos + y * sin;
889 y = -tx * sin + y * cos;
890 }
891
892 public void invRotateXYonZ(ref float x, ref float y, ref Quaternion rot)
893 {
894 float sin = - 2.0f * rot.Z * rot.W;
895 float cos = rot.W * rot.W - rot.Z * rot.Z;
896 float tx = x;
897
898 x = tx * cos - y * sin;
899 y = tx * sin + y * cos;
900 }
901
902 public bool Collide(IntPtr me, IntPtr other, bool reverse, ref d.ContactGeom contact,
903 ref d.ContactGeom altContact , ref bool useAltcontact, ref bool feetcollision)
904 {
905 feetcollision = false;
906 useAltcontact = false;
907
908 if (me == capsule)
909 {
910 Vector3 offset;
911
912 float h = contact.pos.Z - _position.Z;
913 offset.Z = h - feetOff;
914
915 offset.X = contact.pos.X - _position.X;
916 offset.Y = contact.pos.Y - _position.Y;
917
918 d.GeomClassID gtype = d.GeomGetClass(other);
919 if (gtype == d.GeomClassID.CapsuleClass)
920 {
921 Vector3 roff = offset * Quaternion.Inverse(m_orientation2D);
922 float r = roff.X *roff.X / AvaAvaSizeXsq;
923 r += (roff.Y * roff.Y) / AvaAvaSizeYsq;
924 if (r > 1.0f)
925 return false;
926
927 float dp = 1.0f -(float)Math.Sqrt((double)r);
928 if (dp > 0.05f)
929 dp = 0.05f;
930
931 contact.depth = dp;
932
933 if (offset.Z < 0)
934 {
935 feetcollision = true;
936 if (h < boneOff)
937 {
938 m_collideNormal.X = contact.normal.X;
939 m_collideNormal.Y = contact.normal.Y;
940 m_collideNormal.Z = contact.normal.Z;
941 IsColliding = true;
942 }
943 }
944 return true;
945 }
946
947 if (gtype == d.GeomClassID.SphereClass && d.GeomGetBody(other) != IntPtr.Zero)
948 {
949 if(d.GeomSphereGetRadius(other) < 0.5)
950 return true;
951 }
952
953 if (offset.Z > 0 || contact.normal.Z > 0.35f)
954 {
955 if (offset.Z <= 0)
956 {
957 feetcollision = true;
958 if (h < boneOff)
959 {
960 m_collideNormal.X = contact.normal.X;
961 m_collideNormal.Y = contact.normal.Y;
962 m_collideNormal.Z = contact.normal.Z;
963 IsColliding = true;
964 }
965 }
966 return true;
967 }
968
969 if(m_flying)
970 return true;
971
972 feetcollision = true;
973 if (h < boneOff)
974 {
975 m_collideNormal.X = contact.normal.X;
976 m_collideNormal.Y = contact.normal.Y;
977 m_collideNormal.Z = contact.normal.Z;
978 IsColliding = true;
979 }
980
981 altContact = contact;
982 useAltcontact = true;
983
984 offset.Z -= 0.2f;
985
986 offset.Normalize();
987
988 float tdp = contact.depth;
989 float t = offset.X;
990 t = Math.Abs(t);
991 if(t > 1e-6)
992 {
993 tdp /= t;
994 tdp *= contact.normal.X;
995 }
996 else
997 tdp *= 10;
998
999 if (tdp > 0.25f)
1000 tdp = 0.25f;
1001
1002 altContact.depth = tdp;
1003
1004 if (reverse)
1005 {
1006 altContact.normal.X = offset.X;
1007 altContact.normal.Y = offset.Y;
1008 altContact.normal.Z = offset.Z;
1009 }
1010 else
1011 {
1012 altContact.normal.X = -offset.X;
1013 altContact.normal.Y = -offset.Y;
1014 altContact.normal.Z = -offset.Z;
1015 }
1016 return true;
1017 }
1018 return false;
1019 }
1020
1021 /// <summary>
1022 /// Called from Simulate
1023 /// This is the avatar's movement control + PID Controller
1024 /// </summary>
1025 /// <param name="timeStep"></param>
1026 public void Move(List<OdeCharacter> defects)
1027 {
1028 if (Body == IntPtr.Zero)
1029 return;
1030
1031 d.Vector3 dtmp = d.BodyGetPosition(Body);
1032 Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
1033
1034 // the Amotor still lets avatar rotation to drift during colisions
1035 // so force it back to identity
1036
1037 d.Quaternion qtmp;
1038 qtmp.W = m_orientation2D.W;
1039 qtmp.X = m_orientation2D.X;
1040 qtmp.Y = m_orientation2D.Y;
1041 qtmp.Z = m_orientation2D.Z;
1042 d.BodySetQuaternion(Body, ref qtmp);
1043
1044 if (m_pidControllerActive == false)
1045 {
1046 _zeroPosition = localpos;
1047 }
1048
1049 if (!localpos.IsFinite())
1050 {
1051 m_log.Warn("[PHYSICS]: Avatar Position is non-finite!");
1052 defects.Add(this);
1053 // _parent_scene.RemoveCharacter(this);
1054
1055 // destroy avatar capsule and related ODE data
1056 AvatarGeomAndBodyDestroy();
1057 return;
1058 }
1059
1060 // check outbounds forcing to be in world
1061 bool fixbody = false;
1062 if (localpos.X < 0.0f)
1063 {
1064 fixbody = true;
1065 localpos.X = 0.1f;
1066 }
1067 else if (localpos.X > m_parent_scene.WorldExtents.X - 0.1f)
1068 {
1069 fixbody = true;
1070 localpos.X = m_parent_scene.WorldExtents.X - 0.1f;
1071 }
1072 if (localpos.Y < 0.0f)
1073 {
1074 fixbody = true;
1075 localpos.Y = 0.1f;
1076 }
1077 else if (localpos.Y > m_parent_scene.WorldExtents.Y - 0.1)
1078 {
1079 fixbody = true;
1080 localpos.Y = m_parent_scene.WorldExtents.Y - 0.1f;
1081 }
1082 if (fixbody)
1083 {
1084 m_freemove = false;
1085 d.BodySetPosition(Body, localpos.X, localpos.Y, localpos.Z);
1086 }
1087
1088 float breakfactor;
1089
1090 Vector3 vec = Vector3.Zero;
1091 dtmp = d.BodyGetLinearVel(Body);
1092 Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
1093 float velLengthSquared = vel.LengthSquared();
1094
1095 Vector3 ctz = _target_velocity;
1096
1097 float movementdivisor = 1f;
1098 //Ubit change divisions into multiplications below
1099 if (!m_alwaysRun)
1100 movementdivisor = 1 / walkDivisor;
1101 else
1102 movementdivisor = 1 / runDivisor;
1103
1104 ctz.X *= movementdivisor;
1105 ctz.Y *= movementdivisor;
1106
1107 //******************************************
1108 // colide with land
1109
1110 d.AABB aabb;
1111// d.GeomGetAABB(feetbox, out aabb);
1112 d.GeomGetAABB(capsule, out aabb);
1113 float chrminZ = aabb.MinZ; // move up a bit
1114 Vector3 posch = localpos;
1115
1116 float ftmp;
1117
1118 if (m_flying)
1119 {
1120 ftmp = timeStep;
1121 posch.X += vel.X * ftmp;
1122 posch.Y += vel.Y * ftmp;
1123 }
1124
1125 float terrainheight = m_parent_scene.GetTerrainHeightAtXY(posch.X, posch.Y);
1126 if (chrminZ < terrainheight)
1127 {
1128 if (ctz.Z < 0)
1129 ctz.Z = 0;
1130
1131 if(!m_haveLastFallVel)
1132 {
1133 m_lastFallVel = vel;
1134 m_haveLastFallVel = true;
1135 }
1136
1137 Vector3 n = m_parent_scene.GetTerrainNormalAtXY(posch.X, posch.Y);
1138 float depth = terrainheight - chrminZ;
1139
1140 vec.Z = depth * PID_P * 50;
1141
1142 if (!m_flying)
1143 {
1144 vec.Z += -vel.Z * PID_D;
1145 if(n.Z < 0.4f)
1146 {
1147 vec.X = depth * PID_P * 50 - vel.X * PID_D;
1148 vec.X *= n.X;
1149 vec.Y = depth * PID_P * 50 - vel.Y * PID_D;
1150 vec.Y *= n.Y;
1151 vec.Z *= n.Z;
1152 if(n.Z < 0.1f)
1153 {
1154 // cancel the slope pose
1155 n.X = 0f;
1156 n.Y = 0f;
1157 n.Z = 1.0f;
1158 }
1159 }
1160 }
1161
1162 if (depth < 0.2f)
1163 {
1164 m_colliderGroundfilter++;
1165 if (m_colliderGroundfilter > 2)
1166 {
1167 m_iscolliding = true;
1168 m_colliderfilter = 2;
1169
1170 if (m_colliderGroundfilter > 10)
1171 {
1172 m_colliderGroundfilter = 10;
1173 m_freemove = false;
1174 }
1175
1176 m_collideNormal.X = n.X;
1177 m_collideNormal.Y = n.Y;
1178 m_collideNormal.Z = n.Z;
1179
1180 m_iscollidingGround = true;
1181
1182 ContactPoint contact = new ContactPoint();
1183 contact.PenetrationDepth = depth;
1184 contact.Position.X = localpos.X;
1185 contact.Position.Y = localpos.Y;
1186 contact.Position.Z = terrainheight;
1187 contact.SurfaceNormal.X = -n.X;
1188 contact.SurfaceNormal.Y = -n.Y;
1189 contact.SurfaceNormal.Z = -n.Z;
1190 contact.RelativeSpeed = Vector3.Dot(m_lastFallVel, n);
1191 contact.CharacterFeet = true;
1192 AddCollisionEvent(0, contact);
1193 m_lastFallVel = vel;
1194
1195// vec.Z *= 0.5f;
1196 }
1197 }
1198
1199 else
1200 {
1201 m_colliderGroundfilter -= 5;
1202 if (m_colliderGroundfilter <= 0)
1203 {
1204 m_colliderGroundfilter = 0;
1205 m_iscollidingGround = false;
1206 }
1207 }
1208 }
1209 else
1210 {
1211 m_haveLastFallVel = false;
1212 m_colliderGroundfilter -= 5;
1213 if (m_colliderGroundfilter <= 0)
1214 {
1215 m_colliderGroundfilter = 0;
1216 m_iscollidingGround = false;
1217 }
1218 }
1219
1220 bool hoverPIDActive = false;
1221
1222 if (m_useHoverPID && m_PIDHoverTau != 0 && m_PIDHoverHeight != 0)
1223 {
1224 hoverPIDActive = true;
1225
1226 switch (m_PIDHoverType)
1227 {
1228 case PIDHoverType.Ground:
1229 m_targetHoverHeight = terrainheight + m_PIDHoverHeight;
1230 break;
1231
1232 case PIDHoverType.GroundAndWater:
1233 float waterHeight = m_parent_scene.GetWaterLevel();
1234 if (terrainheight > waterHeight)
1235 m_targetHoverHeight = terrainheight + m_PIDHoverHeight;
1236 else
1237 m_targetHoverHeight = waterHeight + m_PIDHoverHeight;
1238 break;
1239 } // end switch (m_PIDHoverType)
1240
1241 // don't go underground
1242 if (m_targetHoverHeight > terrainheight + 0.5f * (aabb.MaxZ - aabb.MinZ))
1243 {
1244 float fz = (m_targetHoverHeight - localpos.Z);
1245
1246 // if error is zero, use position control; otherwise, velocity control
1247 if (Math.Abs(fz) < 0.01f)
1248 {
1249 ctz.Z = 0;
1250 }
1251 else
1252 {
1253 _zeroFlag = false;
1254 fz /= m_PIDHoverTau;
1255
1256 float tmp = Math.Abs(fz);
1257 if (tmp > 50)
1258 fz = 50 * Math.Sign(fz);
1259 else if (tmp < 0.1)
1260 fz = 0.1f * Math.Sign(fz);
1261
1262 ctz.Z = fz;
1263 }
1264 }
1265 }
1266
1267 //******************************************
1268 if (!m_iscolliding)
1269 m_collideNormal.Z = 0;
1270
1271 bool tviszero = (ctz.X == 0.0f && ctz.Y == 0.0f && ctz.Z == 0.0f);
1272
1273 if (!tviszero)
1274 {
1275 m_freemove = false;
1276
1277 // movement relative to surface if moving on it
1278 // dont disturbe vertical movement, ie jumps
1279 if (m_iscolliding && !m_flying && ctz.Z == 0 && m_collideNormal.Z > 0.2f && m_collideNormal.Z < 0.94f)
1280 {
1281 float p = ctz.X * m_collideNormal.X + ctz.Y * m_collideNormal.Y;
1282 ctz.X *= (float)Math.Sqrt(1 - m_collideNormal.X * m_collideNormal.X);
1283 ctz.Y *= (float)Math.Sqrt(1 - m_collideNormal.Y * m_collideNormal.Y);
1284 ctz.Z -= p;
1285 if (ctz.Z < 0)
1286 ctz.Z *= 2;
1287
1288 }
1289
1290 }
1291
1292 if (!m_freemove)
1293 {
1294
1295 // if velocity is zero, use position control; otherwise, velocity control
1296 if (tviszero && m_iscolliding && !m_flying)
1297 {
1298 // keep track of where we stopped. No more slippin' & slidin'
1299 if (!_zeroFlag)
1300 {
1301 _zeroFlag = true;
1302 _zeroPosition = localpos;
1303 }
1304 if (m_pidControllerActive)
1305 {
1306 // We only want to deactivate the PID Controller if we think we want to have our surrogate
1307 // react to the physics scene by moving it's position.
1308 // Avatar to Avatar collisions
1309 // Prim to avatar collisions
1310
1311 vec.X = -vel.X * PID_D * 2f + (_zeroPosition.X - localpos.X) * (PID_P * 5);
1312 vec.Y = -vel.Y * PID_D * 2f + (_zeroPosition.Y - localpos.Y) * (PID_P * 5);
1313 if(vel.Z > 0)
1314 vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P;
1315 else
1316 vec.Z += (-vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P) * 0.2f;
1317/*
1318 if (flying)
1319 {
1320 vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P;
1321 }
1322*/
1323 }
1324 //PidStatus = true;
1325 }
1326 else
1327 {
1328 m_pidControllerActive = true;
1329 _zeroFlag = false;
1330
1331 if (m_iscolliding)
1332 {
1333 if (!m_flying)
1334 {
1335 // we are on a surface
1336 if (ctz.Z > 0f)
1337 {
1338 // moving up or JUMPING
1339 vec.Z += (ctz.Z - vel.Z) * PID_D * 2f;
1340 vec.X += (ctz.X - vel.X) * (PID_D);
1341 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1342 }
1343 else
1344 {
1345 // we are moving down on a surface
1346 if (ctz.Z == 0)
1347 {
1348 if (vel.Z > 0)
1349 vec.Z -= vel.Z * PID_D * 2f;
1350 vec.X += (ctz.X - vel.X) * (PID_D);
1351 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1352 }
1353 // intencionally going down
1354 else
1355 {
1356 if (ctz.Z < vel.Z)
1357 vec.Z += (ctz.Z - vel.Z) * PID_D;
1358 else
1359 {
1360 }
1361
1362 if (Math.Abs(ctz.X) > Math.Abs(vel.X))
1363 vec.X += (ctz.X - vel.X) * (PID_D);
1364 if (Math.Abs(ctz.Y) > Math.Abs(vel.Y))
1365 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1366 }
1367 }
1368
1369 // We're standing on something
1370 }
1371 else
1372 {
1373 // We're flying and colliding with something
1374 vec.X += (ctz.X - vel.X) * (PID_D * 0.0625f);
1375 vec.Y += (ctz.Y - vel.Y) * (PID_D * 0.0625f);
1376 vec.Z += (ctz.Z - vel.Z) * (PID_D * 0.0625f);
1377 }
1378 }
1379 else // ie not colliding
1380 {
1381 if (m_flying || hoverPIDActive) //(!m_iscolliding && flying)
1382 {
1383 // we're in mid air suspended
1384 vec.X += (ctz.X - vel.X) * (PID_D);
1385 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1386 vec.Z += (ctz.Z - vel.Z) * (PID_D);
1387 }
1388
1389 else
1390 {
1391 // we're not colliding and we're not flying so that means we're falling!
1392 // m_iscolliding includes collisions with the ground.
1393
1394 // d.Vector3 pos = d.BodyGetPosition(Body);
1395 vec.X += (ctz.X - vel.X) * PID_D * 0.833f;
1396 vec.Y += (ctz.Y - vel.Y) * PID_D * 0.833f;
1397 // hack for breaking on fall
1398 if (ctz.Z == -9999f)
1399 vec.Z += -vel.Z * PID_D - m_parent_scene.gravityz * m_mass;
1400 }
1401 }
1402 }
1403
1404 if (velLengthSquared > 2500.0f) // 50m/s apply breaks
1405 {
1406 breakfactor = 0.16f * m_mass;
1407 vec.X -= breakfactor * vel.X;
1408 vec.Y -= breakfactor * vel.Y;
1409 vec.Z -= breakfactor * vel.Z;
1410 }
1411 }
1412 else
1413 {
1414 breakfactor = m_mass;
1415 vec.X -= breakfactor * vel.X;
1416 vec.Y -= breakfactor * vel.Y;
1417 if (m_flying)
1418 vec.Z -= 0.5f * breakfactor * vel.Z;
1419 else
1420 vec.Z -= .16f* m_mass * vel.Z;
1421 }
1422
1423 if (m_flying || hoverPIDActive)
1424 {
1425 vec.Z -= m_parent_scene.gravityz * m_mass;
1426
1427 if(!hoverPIDActive)
1428 {
1429 //Added for auto fly height. Kitto Flora
1430 float target_altitude = terrainheight + MinimumGroundFlightOffset;
1431
1432 if (localpos.Z < target_altitude)
1433 {
1434 vec.Z += (target_altitude - localpos.Z) * PID_P * 5.0f;
1435 }
1436 // end add Kitto Flora
1437 }
1438 }
1439
1440 if (vec.IsFinite())
1441 {
1442 if (vec.X != 0 || vec.Y !=0 || vec.Z !=0)
1443 d.BodyAddForce(Body, vec.X, vec.Y, vec.Z);
1444 }
1445 else
1446 {
1447 m_log.Warn("[PHYSICS]: Got a NaN force vector in Move()");
1448 m_log.Warn("[PHYSICS]: Avatar Position is non-finite!");
1449 defects.Add(this);
1450 // _parent_scene.RemoveCharacter(this);
1451 // destroy avatar capsule and related ODE data
1452 AvatarGeomAndBodyDestroy();
1453 return;
1454 }
1455
1456 // update our local ideia of position velocity and aceleration
1457 // _position = localpos;
1458 _position = localpos;
1459
1460 if (_zeroFlag)
1461 {
1462 _velocity = Vector3.Zero;
1463 _acceleration = Vector3.Zero;
1464 m_rotationalVelocity = Vector3.Zero;
1465 }
1466 else
1467 {
1468 Vector3 a =_velocity; // previus velocity
1469 SetSmooth(ref _velocity, ref vel, 2);
1470 a = (_velocity - a) * invtimeStep;
1471 SetSmooth(ref _acceleration, ref a, 2);
1472
1473 dtmp = d.BodyGetAngularVel(Body);
1474 m_rotationalVelocity.X = 0f;
1475 m_rotationalVelocity.Y = 0f;
1476 m_rotationalVelocity.Z = dtmp.Z;
1477 Math.Round(m_rotationalVelocity.Z,3);
1478 }
1479 }
1480
1481 public void round(ref Vector3 v, int digits)
1482 {
1483 v.X = (float)Math.Round(v.X, digits);
1484 v.Y = (float)Math.Round(v.Y, digits);
1485 v.Z = (float)Math.Round(v.Z, digits);
1486 }
1487
1488 public void SetSmooth(ref Vector3 dst, ref Vector3 value)
1489 {
1490 dst.X = 0.1f * dst.X + 0.9f * value.X;
1491 dst.Y = 0.1f * dst.Y + 0.9f * value.Y;
1492 dst.Z = 0.1f * dst.Z + 0.9f * value.Z;
1493 }
1494
1495 public void SetSmooth(ref Vector3 dst, ref Vector3 value, int rounddigits)
1496 {
1497 dst.X = 0.4f * dst.X + 0.6f * value.X;
1498 dst.X = (float)Math.Round(dst.X, rounddigits);
1499
1500 dst.Y = 0.4f * dst.Y + 0.6f * value.Y;
1501 dst.Y = (float)Math.Round(dst.Y, rounddigits);
1502
1503 dst.Z = 0.4f * dst.Z + 0.6f * value.Z;
1504 dst.Z = (float)Math.Round(dst.Z, rounddigits);
1505 }
1506
1507
1508 /// <summary>
1509 /// Updates the reported position and velocity.
1510 /// Used to copy variables from unmanaged space at heartbeat rate and also trigger scene updates acording
1511 /// also outbounds checking
1512 /// copy and outbounds now done in move(..) at ode rate
1513 ///
1514 /// </summary>
1515 public void UpdatePositionAndVelocity()
1516 {
1517 return;
1518
1519// if (Body == IntPtr.Zero)
1520// return;
1521
1522 }
1523
1524 /// <summary>
1525 /// Cleanup the things we use in the scene.
1526 /// </summary>
1527 public void Destroy()
1528 {
1529 AddChange(changes.Remove, null);
1530 }
1531
1532 public override void CrossingFailure()
1533 {
1534 }
1535
1536 public override Vector3 PIDTarget { set { return; } }
1537 public override bool PIDActive {get {return m_pidControllerActive;} set { return; } }
1538 public override float PIDTau { set { return; } }
1539
1540 public override float PIDHoverHeight
1541 {
1542 set
1543 {
1544 AddChange(changes.PIDHoverHeight,value);
1545 }
1546 }
1547 public override bool PIDHoverActive
1548 {
1549 get
1550 {
1551 return m_useHoverPID;
1552 }
1553 set
1554 {
1555 AddChange(changes.PIDHoverActive, value);
1556 }
1557 }
1558
1559 public override PIDHoverType PIDHoverType
1560 {
1561 set
1562 {
1563 AddChange(changes.PIDHoverType,value);
1564 }
1565 }
1566
1567 public override float PIDHoverTau
1568 {
1569 set
1570 {
1571 float tmp =0;
1572 if (value > 0)
1573 {
1574 float mint = (0.05f > timeStep ? 0.05f : timeStep);
1575 if (value < mint)
1576 tmp = mint;
1577 else
1578 tmp = value;
1579 }
1580 AddChange(changes.PIDHoverTau, tmp);
1581 }
1582 }
1583
1584 public override Quaternion APIDTarget { set { return; } }
1585
1586 public override bool APIDActive { set { return; } }
1587
1588 public override float APIDStrength { set { return; } }
1589
1590 public override float APIDDamping { set { return; } }
1591
1592 public override void SubscribeEvents(int ms)
1593 {
1594 m_eventsubscription = ms;
1595 m_cureventsubscription = 0;
1596 CollisionEventsThisFrame.Clear();
1597 SentEmptyCollisionsEvent = false;
1598 }
1599
1600 public override void UnSubscribeEvents()
1601 {
1602 m_eventsubscription = 0;
1603 m_parent_scene.RemoveCollisionEventReporting(this);
1604 lock(CollisionEventsThisFrame)
1605 CollisionEventsThisFrame.Clear();
1606 }
1607
1608 public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
1609 {
1610 lock(CollisionEventsThisFrame)
1611 CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
1612 m_parent_scene.AddCollisionEventReporting(this);
1613 }
1614
1615 public void SendCollisions(int timestep)
1616 {
1617 if (m_cureventsubscription < 50000)
1618 m_cureventsubscription += timestep;
1619
1620 if (m_cureventsubscription < m_eventsubscription)
1621 return;
1622
1623 lock(CollisionEventsThisFrame)
1624 {
1625 int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count;
1626
1627 if (!SentEmptyCollisionsEvent || ncolisions > 0)
1628 {
1629 base.SendCollisionUpdate(CollisionEventsThisFrame);
1630 m_cureventsubscription = 0;
1631
1632 if (ncolisions == 0)
1633 {
1634 SentEmptyCollisionsEvent = true;
1635 // _parent_scene.RemoveCollisionEventReporting(this);
1636 }
1637 else
1638 {
1639 SentEmptyCollisionsEvent = false;
1640 CollisionEventsThisFrame.Clear();
1641 }
1642 }
1643 }
1644 }
1645
1646 public override bool SubscribedEvents()
1647 {
1648 if (m_eventsubscription > 0)
1649 return true;
1650 return false;
1651 }
1652
1653 private void changePhysicsStatus(bool NewStatus)
1654 {
1655 if (NewStatus != m_isPhysical)
1656 {
1657 if (NewStatus)
1658 {
1659 AvatarGeomAndBodyDestroy();
1660
1661 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z);
1662
1663 m_parent_scene.actor_name_map[collider] = (PhysicsActor)this;
1664 m_parent_scene.actor_name_map[capsule] = (PhysicsActor)this;
1665 m_parent_scene.AddCharacter(this);
1666 }
1667 else
1668 {
1669 m_parent_scene.RemoveCollisionEventReporting(this);
1670 m_parent_scene.RemoveCharacter(this);
1671 // destroy avatar capsule and related ODE data
1672 AvatarGeomAndBodyDestroy();
1673 }
1674 m_freemove = false;
1675 m_isPhysical = NewStatus;
1676 }
1677 }
1678
1679 private void changeAdd()
1680 {
1681 changePhysicsStatus(true);
1682 }
1683
1684 private void changeRemove()
1685 {
1686 changePhysicsStatus(false);
1687 }
1688
1689 private void changeShape(PrimitiveBaseShape arg)
1690 {
1691 }
1692
1693 private void changeAvatarSize(strAvatarSize st)
1694 {
1695 m_feetOffset = st.offset;
1696 changeSize(st.size);
1697 }
1698
1699 private void changeSize(Vector3 pSize)
1700 {
1701 if (pSize.IsFinite())
1702 {
1703 // for now only look to Z changes since viewers also don't change X and Y
1704 if (pSize.Z != m_size.Z)
1705 {
1706 AvatarGeomAndBodyDestroy();
1707
1708 float oldsz = m_size.Z;
1709 m_size = pSize;
1710
1711 AvatarGeomAndBodyCreation(_position.X, _position.Y,
1712 _position.Z + (m_size.Z - oldsz) * 0.5f);
1713
1714// Velocity = Vector3.Zero;
1715 m_targetVelocity = Vector3.Zero;
1716
1717 m_parent_scene.actor_name_map[collider] = (PhysicsActor)this;
1718 m_parent_scene.actor_name_map[capsule] = (PhysicsActor)this;
1719 }
1720 m_freemove = false;
1721 m_pidControllerActive = true;
1722 }
1723 else
1724 {
1725 m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character");
1726 }
1727 }
1728
1729 private void changePosition( Vector3 newPos)
1730 {
1731 if (Body != IntPtr.Zero)
1732 d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z);
1733 _position = newPos;
1734 m_freemove = false;
1735 m_pidControllerActive = true;
1736 }
1737
1738 private void changeOrientation(Quaternion newOri)
1739 {
1740 if (m_orientation != newOri)
1741 {
1742 m_orientation = newOri; // keep a copy for core use
1743 // but only use rotations around Z
1744
1745 m_orientation2D.W = newOri.W;
1746 m_orientation2D.Z = newOri.Z;
1747
1748 float t = m_orientation2D.W * m_orientation2D.W + m_orientation2D.Z * m_orientation2D.Z;
1749 if (t > 0)
1750 {
1751 t = 1.0f / (float)Math.Sqrt(t);
1752 m_orientation2D.W *= t;
1753 m_orientation2D.Z *= t;
1754 }
1755 else
1756 {
1757 m_orientation2D.W = 1.0f;
1758 m_orientation2D.Z = 0f;
1759 }
1760 m_orientation2D.Y = 0f;
1761 m_orientation2D.X = 0f;
1762
1763 d.Quaternion myrot = new d.Quaternion();
1764 myrot.X = m_orientation2D.X;
1765 myrot.Y = m_orientation2D.Y;
1766 myrot.Z = m_orientation2D.Z;
1767 myrot.W = m_orientation2D.W;
1768 d.BodySetQuaternion(Body, ref myrot);
1769 }
1770 }
1771
1772 private void changeVelocity(Vector3 newVel)
1773 {
1774 _velocity = newVel;
1775 setFreeMove();
1776
1777 if (Body != IntPtr.Zero)
1778 d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z);
1779 }
1780
1781 private void changeTargetVelocity(Vector3 newVel)
1782 {
1783 m_pidControllerActive = true;
1784 m_freemove = false;
1785 _target_velocity = newVel;
1786 }
1787
1788 private void changeSetTorque(Vector3 newTorque)
1789 {
1790 }
1791
1792 private void changeAddForce(Vector3 newForce)
1793 {
1794 }
1795
1796 private void changeAddAngularForce(Vector3 arg)
1797 {
1798 }
1799
1800 private void changeAngularLock(byte arg)
1801 {
1802 }
1803
1804 private void changeFloatOnWater(bool arg)
1805 {
1806 }
1807
1808 private void changeVolumedetetion(bool arg)
1809 {
1810 }
1811
1812 private void changeSelectedStatus(bool arg)
1813 {
1814 }
1815
1816 private void changeDisable(bool arg)
1817 {
1818 }
1819
1820 private void changeBuilding(bool arg)
1821 {
1822 }
1823
1824 private void setFreeMove()
1825 {
1826 m_pidControllerActive = true;
1827 _zeroFlag = false;
1828 _target_velocity = Vector3.Zero;
1829 m_freemove = true;
1830 m_colliderfilter = -1;
1831 m_colliderObjectfilter = -1;
1832 m_colliderGroundfilter = -1;
1833
1834 m_iscolliding = false;
1835 m_iscollidingGround = false;
1836 m_iscollidingObj = false;
1837
1838 CollisionEventsThisFrame.Clear();
1839 }
1840
1841 private void changeForce(Vector3 newForce)
1842 {
1843 setFreeMove();
1844
1845 if (Body != IntPtr.Zero)
1846 {
1847 if (newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0)
1848 d.BodyAddForce(Body, newForce.X, newForce.Y, newForce.Z);
1849 }
1850 }
1851
1852 // for now momentum is actually velocity
1853 private void changeMomentum(Vector3 newmomentum)
1854 {
1855 _velocity = newmomentum;
1856 setFreeMove();
1857
1858 if (Body != IntPtr.Zero)
1859 d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z);
1860 }
1861
1862 private void changePIDHoverHeight(float val)
1863 {
1864 m_PIDHoverHeight = val;
1865 if (val == 0)
1866 m_useHoverPID = false;
1867 }
1868
1869 private void changePIDHoverType(PIDHoverType type)
1870 {
1871 m_PIDHoverType = type;
1872 }
1873
1874 private void changePIDHoverTau(float tau)
1875 {
1876 m_PIDHoverTau = tau;
1877 }
1878
1879 private void changePIDHoverActive(bool active)
1880 {
1881 m_useHoverPID = active;
1882 }
1883
1884 private void donullchange()
1885 {
1886 }
1887
1888 public bool DoAChange(changes what, object arg)
1889 {
1890 if (collider == IntPtr.Zero && what != changes.Add && what != changes.Remove)
1891 {
1892 return false;
1893 }
1894
1895 // nasty switch
1896 switch (what)
1897 {
1898 case changes.Add:
1899 changeAdd();
1900 break;
1901 case changes.Remove:
1902 changeRemove();
1903 break;
1904
1905 case changes.Position:
1906 changePosition((Vector3)arg);
1907 break;
1908
1909 case changes.Orientation:
1910 changeOrientation((Quaternion)arg);
1911 break;
1912
1913 case changes.PosOffset:
1914 donullchange();
1915 break;
1916
1917 case changes.OriOffset:
1918 donullchange();
1919 break;
1920
1921 case changes.Velocity:
1922 changeVelocity((Vector3)arg);
1923 break;
1924
1925 case changes.TargetVelocity:
1926 changeTargetVelocity((Vector3)arg);
1927 break;
1928
1929 // case changes.Acceleration:
1930 // changeacceleration((Vector3)arg);
1931 // break;
1932 // case changes.AngVelocity:
1933 // changeangvelocity((Vector3)arg);
1934 // break;
1935
1936 case changes.Force:
1937 changeForce((Vector3)arg);
1938 break;
1939
1940 case changes.Torque:
1941 changeSetTorque((Vector3)arg);
1942 break;
1943
1944 case changes.AddForce:
1945 changeAddForce((Vector3)arg);
1946 break;
1947
1948 case changes.AddAngForce:
1949 changeAddAngularForce((Vector3)arg);
1950 break;
1951
1952 case changes.AngLock:
1953 changeAngularLock((byte)arg);
1954 break;
1955
1956 case changes.Size:
1957 changeSize((Vector3)arg);
1958 break;
1959
1960 case changes.AvatarSize:
1961 changeAvatarSize((strAvatarSize)arg);
1962 break;
1963
1964 case changes.Momentum:
1965 changeMomentum((Vector3)arg);
1966 break;
1967
1968 case changes.PIDHoverHeight:
1969 changePIDHoverHeight((float)arg);
1970 break;
1971
1972 case changes.PIDHoverType:
1973 changePIDHoverType((PIDHoverType)arg);
1974 break;
1975
1976 case changes.PIDHoverTau:
1977 changePIDHoverTau((float)arg);
1978 break;
1979
1980 case changes.PIDHoverActive:
1981 changePIDHoverActive((bool)arg);
1982 break;
1983
1984/* not in use for now
1985 case changes.Shape:
1986 changeShape((PrimitiveBaseShape)arg);
1987 break;
1988
1989 case changes.CollidesWater:
1990 changeFloatOnWater((bool)arg);
1991 break;
1992
1993 case changes.VolumeDtc:
1994 changeVolumedetetion((bool)arg);
1995 break;
1996
1997 case changes.Physical:
1998 changePhysicsStatus((bool)arg);
1999 break;
2000
2001 case changes.Selected:
2002 changeSelectedStatus((bool)arg);
2003 break;
2004
2005 case changes.disabled:
2006 changeDisable((bool)arg);
2007 break;
2008
2009 case changes.building:
2010 changeBuilding((bool)arg);
2011 break;
2012*/
2013 case changes.Null:
2014 donullchange();
2015 break;
2016
2017 default:
2018 donullchange();
2019 break;
2020 }
2021 return false;
2022 }
2023
2024 public void AddChange(changes what, object arg)
2025 {
2026 m_parent_scene.AddChange((PhysicsActor)this, what, arg);
2027 }
2028
2029 private struct strAvatarSize
2030 {
2031 public Vector3 size;
2032 public float offset;
2033 }
2034
2035 }
2036}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs
new file mode 100644
index 0000000..ce10065
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs
@@ -0,0 +1,1205 @@
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
28/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
29 * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
30 * ODEPrim.cs contains methods dealing with Prim editing, Prim
31 * characteristics and Kinetic motion.
32 * ODEDynamics.cs contains methods dealing with Prim Physical motion
33 * (dynamics) and the associated settings. Old Linear and angular
34 * motors for dynamic motion have been replace with MoveLinear()
35 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic
36 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
37 * switch between 'VEHICLE' parameter use and general dynamics
38 * settings use.
39 */
40
41// Extensive change Ubit 2012
42
43using System;
44using System.Collections.Generic;
45using System.Reflection;
46using System.Runtime.InteropServices;
47using log4net;
48using OpenMetaverse;
49using OdeAPI;
50using OpenSim.Framework;
51using OpenSim.Region.PhysicsModules.SharedBase;
52
53namespace OpenSim.Region.PhysicsModule.ubOde
54{
55 public class ODEDynamics
56 {
57 public Vehicle Type
58 {
59 get { return m_type; }
60 }
61
62 private OdePrim rootPrim;
63 private ODEScene _pParentScene;
64
65 // Vehicle properties
66 // WARNING this are working copies for internel use
67 // their values may not be the corresponding parameter
68
69 private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
70 private Quaternion m_RollreferenceFrame = Quaternion.Identity; // what hell is this ?
71
72 private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
73
74 private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
75 // HOVER_TERRAIN_ONLY
76 // HOVER_GLOBAL_HEIGHT
77 // NO_DEFLECTION_UP
78 // HOVER_WATER_ONLY
79 // HOVER_UP_ONLY
80 // LIMIT_MOTOR_UP
81 // LIMIT_ROLL_ONLY
82 private Vector3 m_BlockingEndPoint = Vector3.Zero; // not sl
83
84 // Linear properties
85 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
86 private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
87 private float m_linearMotorDecayTimescale = 120;
88 private float m_linearMotorTimescale = 1000;
89 private Vector3 m_linearMotorOffset = Vector3.Zero;
90
91 //Angular properties
92 private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
93 private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate
94 private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate
95 private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate
96
97 //Deflection properties
98 private float m_angularDeflectionEfficiency = 0;
99 private float m_angularDeflectionTimescale = 1000;
100 private float m_linearDeflectionEfficiency = 0;
101 private float m_linearDeflectionTimescale = 1000;
102
103 //Banking properties
104 private float m_bankingEfficiency = 0;
105 private float m_bankingMix = 0;
106 private float m_bankingTimescale = 1000;
107
108 //Hover and Buoyancy properties
109 private float m_VhoverHeight = 0f;
110 private float m_VhoverEfficiency = 0f;
111 private float m_VhoverTimescale = 1000f;
112 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
113 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
114 // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
115 // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
116
117 //Attractor properties
118 private float m_verticalAttractionEfficiency = 1.0f; // damped
119 private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor.
120
121
122 // auxiliar
123 private float m_lmEfect = 0f; // current linear motor eficiency
124 private float m_lmDecay = 0f; // current linear decay
125
126 private float m_amEfect = 0; // current angular motor eficiency
127 private float m_amDecay = 0f; // current linear decay
128
129 private float m_ffactor = 1.0f;
130
131 private float m_timestep = 0.02f;
132 private float m_invtimestep = 50;
133
134
135 float m_ampwr;
136 float m_amdampX;
137 float m_amdampY;
138 float m_amdampZ;
139
140 float m_gravmod;
141
142 public float FrictionFactor
143 {
144 get
145 {
146 return m_ffactor;
147 }
148 }
149
150 public float GravMod
151 {
152 set
153 {
154 m_gravmod = value;
155 }
156 }
157
158
159 public ODEDynamics(OdePrim rootp)
160 {
161 rootPrim = rootp;
162 _pParentScene = rootPrim._parent_scene;
163 m_timestep = _pParentScene.ODE_STEPSIZE;
164 m_invtimestep = 1.0f / m_timestep;
165 m_gravmod = rootPrim.GravModifier;
166 }
167
168 public void DoSetVehicle(VehicleData vd)
169 {
170 m_type = vd.m_type;
171 m_flags = vd.m_flags;
172
173
174 // Linear properties
175 m_linearMotorDirection = vd.m_linearMotorDirection;
176
177 m_linearFrictionTimescale = vd.m_linearFrictionTimescale;
178 if (m_linearFrictionTimescale.X < m_timestep) m_linearFrictionTimescale.X = m_timestep;
179 if (m_linearFrictionTimescale.Y < m_timestep) m_linearFrictionTimescale.Y = m_timestep;
180 if (m_linearFrictionTimescale.Z < m_timestep) m_linearFrictionTimescale.Z = m_timestep;
181
182 m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale;
183 if (m_linearMotorDecayTimescale < m_timestep) m_linearMotorDecayTimescale = m_timestep;
184 m_linearMotorDecayTimescale += 0.2f;
185 m_linearMotorDecayTimescale *= m_invtimestep;
186
187 m_linearMotorTimescale = vd.m_linearMotorTimescale;
188 if (m_linearMotorTimescale < m_timestep) m_linearMotorTimescale = m_timestep;
189
190 m_linearMotorOffset = vd.m_linearMotorOffset;
191
192 //Angular properties
193 m_angularMotorDirection = vd.m_angularMotorDirection;
194 m_angularMotorTimescale = vd.m_angularMotorTimescale;
195 if (m_angularMotorTimescale < m_timestep) m_angularMotorTimescale = m_timestep;
196
197 m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale;
198 if (m_angularMotorDecayTimescale < m_timestep) m_angularMotorDecayTimescale = m_timestep;
199 m_angularMotorDecayTimescale *= m_invtimestep;
200
201 m_angularFrictionTimescale = vd.m_angularFrictionTimescale;
202 if (m_angularFrictionTimescale.X < m_timestep) m_angularFrictionTimescale.X = m_timestep;
203 if (m_angularFrictionTimescale.Y < m_timestep) m_angularFrictionTimescale.Y = m_timestep;
204 if (m_angularFrictionTimescale.Z < m_timestep) m_angularFrictionTimescale.Z = m_timestep;
205
206 //Deflection properties
207 m_angularDeflectionEfficiency = vd.m_angularDeflectionEfficiency;
208 m_angularDeflectionTimescale = vd.m_angularDeflectionTimescale;
209 if (m_angularDeflectionTimescale < m_timestep) m_angularDeflectionTimescale = m_timestep;
210
211 m_linearDeflectionEfficiency = vd.m_linearDeflectionEfficiency;
212 m_linearDeflectionTimescale = vd.m_linearDeflectionTimescale;
213 if (m_linearDeflectionTimescale < m_timestep) m_linearDeflectionTimescale = m_timestep;
214
215 //Banking properties
216 m_bankingEfficiency = vd.m_bankingEfficiency;
217 m_bankingMix = vd.m_bankingMix;
218 m_bankingTimescale = vd.m_bankingTimescale;
219 if (m_bankingTimescale < m_timestep) m_bankingTimescale = m_timestep;
220
221 //Hover and Buoyancy properties
222 m_VhoverHeight = vd.m_VhoverHeight;
223 m_VhoverEfficiency = vd.m_VhoverEfficiency;
224 m_VhoverTimescale = vd.m_VhoverTimescale;
225 if (m_VhoverTimescale < m_timestep) m_VhoverTimescale = m_timestep;
226
227 m_VehicleBuoyancy = vd.m_VehicleBuoyancy;
228
229 //Attractor properties
230 m_verticalAttractionEfficiency = vd.m_verticalAttractionEfficiency;
231 m_verticalAttractionTimescale = vd.m_verticalAttractionTimescale;
232 if (m_verticalAttractionTimescale < m_timestep) m_verticalAttractionTimescale = m_timestep;
233
234 // Axis
235 m_referenceFrame = vd.m_referenceFrame;
236
237 m_lmEfect = 0;
238 m_lmDecay = (1.0f - 1.0f / m_linearMotorDecayTimescale);
239 m_amEfect = 0;
240 m_ffactor = 1.0f;
241 }
242
243 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
244 {
245 float len;
246 if(float.IsNaN(pValue) || float.IsInfinity(pValue))
247 return;
248
249 switch (pParam)
250 {
251 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
252 if (pValue < 0f) pValue = 0f;
253 if (pValue > 1f) pValue = 1f;
254 m_angularDeflectionEfficiency = pValue;
255 break;
256 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
257 if (pValue < m_timestep) pValue = m_timestep;
258 m_angularDeflectionTimescale = pValue;
259 break;
260 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
261 if (pValue < m_timestep) pValue = m_timestep;
262 else if (pValue > 120) pValue = 120;
263 m_angularMotorDecayTimescale = pValue * m_invtimestep;
264 m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale;
265 break;
266 case Vehicle.ANGULAR_MOTOR_TIMESCALE:
267 if (pValue < m_timestep) pValue = m_timestep;
268 m_angularMotorTimescale = pValue;
269 break;
270 case Vehicle.BANKING_EFFICIENCY:
271 if (pValue < -1f) pValue = -1f;
272 if (pValue > 1f) pValue = 1f;
273 m_bankingEfficiency = pValue;
274 break;
275 case Vehicle.BANKING_MIX:
276 if (pValue < 0f) pValue = 0f;
277 if (pValue > 1f) pValue = 1f;
278 m_bankingMix = pValue;
279 break;
280 case Vehicle.BANKING_TIMESCALE:
281 if (pValue < m_timestep) pValue = m_timestep;
282 m_bankingTimescale = pValue;
283 break;
284 case Vehicle.BUOYANCY:
285 if (pValue < -1f) pValue = -1f;
286 if (pValue > 1f) pValue = 1f;
287 m_VehicleBuoyancy = pValue;
288 break;
289 case Vehicle.HOVER_EFFICIENCY:
290 if (pValue < 0f) pValue = 0f;
291 if (pValue > 1f) pValue = 1f;
292 m_VhoverEfficiency = pValue;
293 break;
294 case Vehicle.HOVER_HEIGHT:
295 m_VhoverHeight = pValue;
296 break;
297 case Vehicle.HOVER_TIMESCALE:
298 if (pValue < m_timestep) pValue = m_timestep;
299 m_VhoverTimescale = pValue;
300 break;
301 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
302 if (pValue < 0f) pValue = 0f;
303 if (pValue > 1f) pValue = 1f;
304 m_linearDeflectionEfficiency = pValue;
305 break;
306 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
307 if (pValue < m_timestep) pValue = m_timestep;
308 m_linearDeflectionTimescale = pValue;
309 break;
310 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
311 if (pValue < m_timestep) pValue = m_timestep;
312 else if (pValue > 120) pValue = 120;
313 m_linearMotorDecayTimescale = (0.2f +pValue) * m_invtimestep;
314 m_lmDecay = (1.0f - 1.0f / m_linearMotorDecayTimescale);
315 break;
316 case Vehicle.LINEAR_MOTOR_TIMESCALE:
317 if (pValue < m_timestep) pValue = m_timestep;
318 m_linearMotorTimescale = pValue;
319 break;
320 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
321 if (pValue < 0f) pValue = 0f;
322 if (pValue > 1f) pValue = 1f;
323 m_verticalAttractionEfficiency = pValue;
324 break;
325 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
326 if (pValue < m_timestep) pValue = m_timestep;
327 m_verticalAttractionTimescale = pValue;
328 break;
329
330 // These are vector properties but the engine lets you use a single float value to
331 // set all of the components to the same value
332 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
333 if (pValue < m_timestep) pValue = m_timestep;
334 m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
335 break;
336 case Vehicle.ANGULAR_MOTOR_DIRECTION:
337 m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
338 len = m_angularMotorDirection.Length();
339 if (len > 12.566f)
340 m_angularMotorDirection *= (12.566f / len);
341
342 m_amEfect = 1.0f ; // turn it on
343 m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale;
344
345 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
346 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
347 d.BodyEnable(rootPrim.Body);
348
349 break;
350 case Vehicle.LINEAR_FRICTION_TIMESCALE:
351 if (pValue < m_timestep) pValue = m_timestep;
352 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
353 break;
354 case Vehicle.LINEAR_MOTOR_DIRECTION:
355 m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
356 len = m_linearMotorDirection.Length();
357 if (len > 100.0f)
358 m_linearMotorDirection *= (100.0f / len);
359
360 m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale;
361 m_lmEfect = 1.0f; // turn it on
362
363 m_ffactor = 0.0f;
364 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
365 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
366 d.BodyEnable(rootPrim.Body);
367 break;
368 case Vehicle.LINEAR_MOTOR_OFFSET:
369 m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
370 len = m_linearMotorOffset.Length();
371 if (len > 100.0f)
372 m_linearMotorOffset *= (100.0f / len);
373 break;
374 }
375 }//end ProcessFloatVehicleParam
376
377 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
378 {
379 float len;
380 if(!pValue.IsFinite())
381 return;
382
383 switch (pParam)
384 {
385 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
386 if (pValue.X < m_timestep) pValue.X = m_timestep;
387 if (pValue.Y < m_timestep) pValue.Y = m_timestep;
388 if (pValue.Z < m_timestep) pValue.Z = m_timestep;
389
390 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
391 break;
392 case Vehicle.ANGULAR_MOTOR_DIRECTION:
393 m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
394 // Limit requested angular speed to 2 rps= 4 pi rads/sec
395 len = m_angularMotorDirection.Length();
396 if (len > 12.566f)
397 m_angularMotorDirection *= (12.566f / len);
398
399 m_amEfect = 1.0f; // turn it on
400 m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale;
401
402 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
403 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
404 d.BodyEnable(rootPrim.Body);
405 break;
406 case Vehicle.LINEAR_FRICTION_TIMESCALE:
407 if (pValue.X < m_timestep) pValue.X = m_timestep;
408 if (pValue.Y < m_timestep) pValue.Y = m_timestep;
409 if (pValue.Z < m_timestep) pValue.Z = m_timestep;
410 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
411 break;
412 case Vehicle.LINEAR_MOTOR_DIRECTION:
413 m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
414 len = m_linearMotorDirection.Length();
415 if (len > 100.0f)
416 m_linearMotorDirection *= (100.0f / len);
417
418 m_lmEfect = 1.0f; // turn it on
419 m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale;
420
421 m_ffactor = 0.0f;
422 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
423 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
424 d.BodyEnable(rootPrim.Body);
425 break;
426 case Vehicle.LINEAR_MOTOR_OFFSET:
427 m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
428 len = m_linearMotorOffset.Length();
429 if (len > 100.0f)
430 m_linearMotorOffset *= (100.0f / len);
431 break;
432 case Vehicle.BLOCK_EXIT:
433 m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z);
434 break;
435 }
436 }//end ProcessVectorVehicleParam
437
438 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
439 {
440 switch (pParam)
441 {
442 case Vehicle.REFERENCE_FRAME:
443 // m_referenceFrame = Quaternion.Inverse(pValue);
444 m_referenceFrame = pValue;
445 break;
446 case Vehicle.ROLL_FRAME:
447 m_RollreferenceFrame = pValue;
448 break;
449 }
450 }//end ProcessRotationVehicleParam
451
452 internal void ProcessVehicleFlags(int pParam, bool remove)
453 {
454 if (remove)
455 {
456 m_flags &= ~((VehicleFlag)pParam);
457 }
458 else
459 {
460 m_flags |= (VehicleFlag)pParam;
461 }
462 }//end ProcessVehicleFlags
463
464 internal void ProcessTypeChange(Vehicle pType)
465 {
466 m_lmEfect = 0;
467
468 m_amEfect = 0;
469 m_ffactor = 1f;
470
471 m_linearMotorDirection = Vector3.Zero;
472 m_angularMotorDirection = Vector3.Zero;
473
474 m_BlockingEndPoint = Vector3.Zero;
475 m_RollreferenceFrame = Quaternion.Identity;
476 m_linearMotorOffset = Vector3.Zero;
477
478 m_referenceFrame = Quaternion.Identity;
479
480 // Set Defaults For Type
481 m_type = pType;
482 switch (pType)
483 {
484 case Vehicle.TYPE_NONE:
485 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
486 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
487 m_linearMotorTimescale = 1000;
488 m_linearMotorDecayTimescale = 120 * m_invtimestep;
489 m_angularMotorTimescale = 1000;
490 m_angularMotorDecayTimescale = 1000 * m_invtimestep;
491 m_VhoverHeight = 0;
492 m_VhoverEfficiency = 1;
493 m_VhoverTimescale = 1000;
494 m_VehicleBuoyancy = 0;
495 m_linearDeflectionEfficiency = 0;
496 m_linearDeflectionTimescale = 1000;
497 m_angularDeflectionEfficiency = 0;
498 m_angularDeflectionTimescale = 1000;
499 m_bankingEfficiency = 0;
500 m_bankingMix = 1;
501 m_bankingTimescale = 1000;
502 m_verticalAttractionEfficiency = 0;
503 m_verticalAttractionTimescale = 1000;
504
505 m_flags = (VehicleFlag)0;
506 break;
507
508 case Vehicle.TYPE_SLED:
509 m_linearFrictionTimescale = new Vector3(30, 1, 1000);
510 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
511 m_linearMotorTimescale = 1000;
512 m_linearMotorDecayTimescale = 120 * m_invtimestep;
513 m_angularMotorTimescale = 1000;
514 m_angularMotorDecayTimescale = 120 * m_invtimestep;
515 m_VhoverHeight = 0;
516 m_VhoverEfficiency = 1;
517 m_VhoverTimescale = 10;
518 m_VehicleBuoyancy = 0;
519 m_linearDeflectionEfficiency = 1;
520 m_linearDeflectionTimescale = 1;
521 m_angularDeflectionEfficiency = 0;
522 m_angularDeflectionTimescale = 10;
523 m_verticalAttractionEfficiency = 1;
524 m_verticalAttractionTimescale = 1000;
525 m_bankingEfficiency = 0;
526 m_bankingMix = 1;
527 m_bankingTimescale = 10;
528 m_flags &=
529 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
530 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
531 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
532 VehicleFlag.LIMIT_ROLL_ONLY |
533 VehicleFlag.LIMIT_MOTOR_UP);
534 break;
535
536 case Vehicle.TYPE_CAR:
537 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
538 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
539 m_linearMotorTimescale = 1;
540 m_linearMotorDecayTimescale = 60 * m_invtimestep;
541 m_angularMotorTimescale = 1;
542 m_angularMotorDecayTimescale = 0.8f * m_invtimestep;
543 m_VhoverHeight = 0;
544 m_VhoverEfficiency = 0;
545 m_VhoverTimescale = 1000;
546 m_VehicleBuoyancy = 0;
547 m_linearDeflectionEfficiency = 1;
548 m_linearDeflectionTimescale = 2;
549 m_angularDeflectionEfficiency = 0;
550 m_angularDeflectionTimescale = 10;
551 m_verticalAttractionEfficiency = 1f;
552 m_verticalAttractionTimescale = 10f;
553 m_bankingEfficiency = -0.2f;
554 m_bankingMix = 1;
555 m_bankingTimescale = 1;
556 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
557 VehicleFlag.HOVER_TERRAIN_ONLY |
558 VehicleFlag.HOVER_GLOBAL_HEIGHT);
559 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
560 VehicleFlag.LIMIT_ROLL_ONLY |
561 VehicleFlag.LIMIT_MOTOR_UP |
562 VehicleFlag.HOVER_UP_ONLY);
563 break;
564 case Vehicle.TYPE_BOAT:
565 m_linearFrictionTimescale = new Vector3(10, 3, 2);
566 m_angularFrictionTimescale = new Vector3(10, 10, 10);
567 m_linearMotorTimescale = 5;
568 m_linearMotorDecayTimescale = 60 * m_invtimestep;
569 m_angularMotorTimescale = 4;
570 m_angularMotorDecayTimescale = 4 * m_invtimestep;
571 m_VhoverHeight = 0;
572 m_VhoverEfficiency = 0.5f;
573 m_VhoverTimescale = 2;
574 m_VehicleBuoyancy = 1;
575 m_linearDeflectionEfficiency = 0.5f;
576 m_linearDeflectionTimescale = 3;
577 m_angularDeflectionEfficiency = 0.5f;
578 m_angularDeflectionTimescale = 5;
579 m_verticalAttractionEfficiency = 0.5f;
580 m_verticalAttractionTimescale = 5f;
581 m_bankingEfficiency = -0.3f;
582 m_bankingMix = 0.8f;
583 m_bankingTimescale = 1;
584 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
585 VehicleFlag.HOVER_GLOBAL_HEIGHT |
586 VehicleFlag.HOVER_UP_ONLY); // |
587// VehicleFlag.LIMIT_ROLL_ONLY);
588 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
589 VehicleFlag.LIMIT_MOTOR_UP |
590 VehicleFlag.HOVER_UP_ONLY | // new sl
591 VehicleFlag.HOVER_WATER_ONLY);
592 break;
593
594 case Vehicle.TYPE_AIRPLANE:
595 m_linearFrictionTimescale = new Vector3(200, 10, 5);
596 m_angularFrictionTimescale = new Vector3(20, 20, 20);
597 m_linearMotorTimescale = 2;
598 m_linearMotorDecayTimescale = 60 * m_invtimestep;
599 m_angularMotorTimescale = 4;
600 m_angularMotorDecayTimescale = 8 * m_invtimestep;
601 m_VhoverHeight = 0;
602 m_VhoverEfficiency = 0.5f;
603 m_VhoverTimescale = 1000;
604 m_VehicleBuoyancy = 0;
605 m_linearDeflectionEfficiency = 0.5f;
606 m_linearDeflectionTimescale = 0.5f;
607 m_angularDeflectionEfficiency = 1;
608 m_angularDeflectionTimescale = 2;
609 m_verticalAttractionEfficiency = 0.9f;
610 m_verticalAttractionTimescale = 2f;
611 m_bankingEfficiency = 1;
612 m_bankingMix = 0.7f;
613 m_bankingTimescale = 2;
614 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
615 VehicleFlag.HOVER_TERRAIN_ONLY |
616 VehicleFlag.HOVER_GLOBAL_HEIGHT |
617 VehicleFlag.HOVER_UP_ONLY |
618 VehicleFlag.NO_DEFLECTION_UP |
619 VehicleFlag.LIMIT_MOTOR_UP);
620 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
621 break;
622
623 case Vehicle.TYPE_BALLOON:
624 m_linearFrictionTimescale = new Vector3(5, 5, 5);
625 m_angularFrictionTimescale = new Vector3(10, 10, 10);
626 m_linearMotorTimescale = 5;
627 m_linearMotorDecayTimescale = 60 * m_invtimestep;
628 m_angularMotorTimescale = 6;
629 m_angularMotorDecayTimescale = 10 * m_invtimestep;
630 m_VhoverHeight = 5;
631 m_VhoverEfficiency = 0.8f;
632 m_VhoverTimescale = 10;
633 m_VehicleBuoyancy = 1;
634 m_linearDeflectionEfficiency = 0;
635 m_linearDeflectionTimescale = 5 * m_invtimestep;
636 m_angularDeflectionEfficiency = 0;
637 m_angularDeflectionTimescale = 5;
638 m_verticalAttractionEfficiency = 1f;
639 m_verticalAttractionTimescale = 1000f;
640 m_bankingEfficiency = 0;
641 m_bankingMix = 0.7f;
642 m_bankingTimescale = 5;
643 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
644 VehicleFlag.HOVER_TERRAIN_ONLY |
645 VehicleFlag.HOVER_UP_ONLY |
646 VehicleFlag.NO_DEFLECTION_UP |
647 VehicleFlag.LIMIT_MOTOR_UP | //);
648 VehicleFlag.LIMIT_ROLL_ONLY | // new sl
649 VehicleFlag.HOVER_GLOBAL_HEIGHT); // new sl
650
651// m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
652// VehicleFlag.HOVER_GLOBAL_HEIGHT);
653 break;
654
655 }
656 // disable mouse steering
657 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER |
658 VehicleFlag.MOUSELOOK_BANK |
659 VehicleFlag.CAMERA_DECOUPLED);
660
661 m_lmDecay = (1.0f - 1.0f / m_linearMotorDecayTimescale);
662 m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale;
663
664 }//end SetDefaultsForType
665
666 internal void Stop()
667 {
668 m_lmEfect = 0;
669 m_lmDecay = 0f;
670 m_amEfect = 0;
671 m_amDecay = 0;
672 m_ffactor = 1f;
673 }
674
675 public static Vector3 Xrot(Quaternion rot)
676 {
677 Vector3 vec;
678 rot.Normalize(); // just in case
679 vec.X = 2 * (rot.X * rot.X + rot.W * rot.W) - 1;
680 vec.Y = 2 * (rot.X * rot.Y + rot.Z * rot.W);
681 vec.Z = 2 * (rot.X * rot.Z - rot.Y * rot.W);
682 return vec;
683 }
684
685 public static Vector3 Zrot(Quaternion rot)
686 {
687 Vector3 vec;
688 rot.Normalize(); // just in case
689 vec.X = 2 * (rot.X * rot.Z + rot.Y * rot.W);
690 vec.Y = 2 * (rot.Y * rot.Z - rot.X * rot.W);
691 vec.Z = 2 * (rot.Z * rot.Z + rot.W * rot.W) - 1;
692
693 return vec;
694 }
695
696 private const float pi = (float)Math.PI;
697 private const float halfpi = 0.5f * (float)Math.PI;
698 private const float twopi = 2.0f * pi;
699
700 public static Vector3 ubRot2Euler(Quaternion rot)
701 {
702 // returns roll in X
703 // pitch in Y
704 // yaw in Z
705 Vector3 vec;
706
707 // assuming rot is normalised
708 // rot.Normalize();
709
710 float zX = rot.X * rot.Z + rot.Y * rot.W;
711
712 if (zX < -0.49999f)
713 {
714 vec.X = 0;
715 vec.Y = -halfpi;
716 vec.Z = (float)(-2d * Math.Atan(rot.X / rot.W));
717 }
718 else if (zX > 0.49999f)
719 {
720 vec.X = 0;
721 vec.Y = halfpi;
722 vec.Z = (float)(2d * Math.Atan(rot.X / rot.W));
723 }
724 else
725 {
726 vec.Y = (float)Math.Asin(2 * zX);
727
728 float sqw = rot.W * rot.W;
729
730 float minuszY = rot.X * rot.W - rot.Y * rot.Z;
731 float zZ = rot.Z * rot.Z + sqw - 0.5f;
732
733 vec.X = (float)Math.Atan2(minuszY, zZ);
734
735 float yX = rot.Z * rot.W - rot.X * rot.Y; //( have negative ?)
736 float yY = rot.X * rot.X + sqw - 0.5f;
737 vec.Z = (float)Math.Atan2(yX, yY);
738 }
739 return vec;
740 }
741
742 public static void GetRollPitch(Quaternion rot, out float roll, out float pitch)
743 {
744 // assuming rot is normalised
745 // rot.Normalize();
746
747 float zX = rot.X * rot.Z + rot.Y * rot.W;
748
749 if (zX < -0.49999f)
750 {
751 roll = 0;
752 pitch = -halfpi;
753 }
754 else if (zX > 0.49999f)
755 {
756 roll = 0;
757 pitch = halfpi;
758 }
759 else
760 {
761 pitch = (float)Math.Asin(2 * zX);
762
763 float minuszY = rot.X * rot.W - rot.Y * rot.Z;
764 float zZ = rot.Z * rot.Z + rot.W * rot.W - 0.5f;
765
766 roll = (float)Math.Atan2(minuszY, zZ);
767 }
768 return ;
769 }
770
771 internal void Step()
772 {
773 IntPtr Body = rootPrim.Body;
774
775 d.Mass dmass;
776 d.BodyGetMass(Body, out dmass);
777
778 d.Quaternion rot = d.BodyGetQuaternion(Body);
779 Quaternion objrotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
780 Quaternion rotq = objrotq; // rotq = rotation of object
781 rotq *= m_referenceFrame; // rotq is now rotation in vehicle reference frame
782 Quaternion irotq = Quaternion.Inverse(rotq);
783
784 d.Vector3 dvtmp;
785 Vector3 tmpV;
786 Vector3 curVel; // velocity in world
787 Vector3 curAngVel; // angular velocity in world
788 Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame
789 Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in vehicle frame
790 d.Vector3 dtorque = new d.Vector3();
791
792 dvtmp = d.BodyGetLinearVel(Body);
793 curVel.X = dvtmp.X;
794 curVel.Y = dvtmp.Y;
795 curVel.Z = dvtmp.Z;
796 Vector3 curLocalVel = curVel * irotq; // current velocity in local
797
798 dvtmp = d.BodyGetAngularVel(Body);
799 curAngVel.X = dvtmp.X;
800 curAngVel.Y = dvtmp.Y;
801 curAngVel.Z = dvtmp.Z;
802 Vector3 curLocalAngVel = curAngVel * irotq; // current angular velocity in local
803
804 float ldampZ = 0;
805
806 bool mousemode = false;
807 bool mousemodebank = false;
808
809 float bankingEfficiency;
810 float verticalAttractionTimescale = m_verticalAttractionTimescale;
811
812 if((m_flags & (VehicleFlag.MOUSELOOK_STEER | VehicleFlag.MOUSELOOK_BANK)) != 0 )
813 {
814 mousemode = true;
815 mousemodebank = (m_flags & VehicleFlag.MOUSELOOK_BANK) != 0;
816 if(mousemodebank)
817 {
818 bankingEfficiency = m_bankingEfficiency;
819 if(verticalAttractionTimescale < 149.9)
820 verticalAttractionTimescale *= 2.0f; // reduce current instability
821 }
822 else
823 bankingEfficiency = 0;
824 }
825 else
826 bankingEfficiency = m_bankingEfficiency;
827
828 // linear motor
829 if (m_lmEfect > 0.01 && m_linearMotorTimescale < 1000)
830 {
831 tmpV = m_linearMotorDirection - curLocalVel; // velocity error
832 tmpV *= m_lmEfect / m_linearMotorTimescale; // error to correct in this timestep
833 tmpV *= rotq; // to world
834
835 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
836 tmpV.Z = 0;
837
838 if (m_linearMotorOffset.X != 0 || m_linearMotorOffset.Y != 0 || m_linearMotorOffset.Z != 0)
839 {
840 // have offset, do it now
841 tmpV *= dmass.mass;
842 d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z);
843 }
844 else
845 {
846 force.X += tmpV.X;
847 force.Y += tmpV.Y;
848 force.Z += tmpV.Z;
849 }
850
851 m_lmEfect *= m_lmDecay;
852// m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared();
853 m_ffactor = 0.0f;
854 }
855 else
856 {
857 m_lmEfect = 0;
858 m_ffactor = 1f;
859 }
860
861 // hover
862 if (m_VhoverTimescale < 300 && rootPrim.prim_geom != IntPtr.Zero)
863 {
864 // d.Vector3 pos = d.BodyGetPosition(Body);
865 d.Vector3 pos = d.GeomGetPosition(rootPrim.prim_geom);
866 pos.Z -= 0.21f; // minor offset that seems to be always there in sl
867
868 float t = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
869 float perr;
870
871 // default to global but don't go underground
872 perr = m_VhoverHeight - pos.Z;
873
874 if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == 0)
875 {
876 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
877 {
878 perr += _pParentScene.GetWaterLevel();
879 }
880 else if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
881 {
882 perr += t;
883 }
884 else
885 {
886 float w = _pParentScene.GetWaterLevel();
887 if (t > w)
888 perr += t;
889 else
890 perr += w;
891 }
892 }
893 else if (t > m_VhoverHeight)
894 perr = t - pos.Z; ;
895
896 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > -0.1)
897 {
898 ldampZ = m_VhoverEfficiency * m_invtimestep;
899
900 perr *= (1.0f + ldampZ) / m_VhoverTimescale;
901
902 // force.Z += perr - curVel.Z * tmp;
903 force.Z += perr;
904 ldampZ *= -curVel.Z;
905
906 force.Z += _pParentScene.gravityz * m_gravmod * (1f - m_VehicleBuoyancy);
907 }
908 else // no buoyancy
909 force.Z += _pParentScene.gravityz;
910 }
911 else
912 {
913 // default gravity and Buoyancy
914 force.Z += _pParentScene.gravityz * m_gravmod * (1f - m_VehicleBuoyancy);
915 }
916
917 // linear deflection
918 if (m_linearDeflectionEfficiency > 0)
919 {
920 float len = curVel.Length();
921 if (len > 0.01) // if moving
922 {
923 Vector3 atAxis;
924 atAxis = Xrot(rotq); // where are we pointing to
925 atAxis *= len; // make it same size as world velocity vector
926
927 tmpV = -atAxis; // oposite direction
928 atAxis -= curVel; // error to one direction
929 len = atAxis.LengthSquared();
930
931 tmpV -= curVel; // error to oposite
932 float lens = tmpV.LengthSquared();
933
934 if (len > 0.01 || lens > 0.01) // do nothing if close enougth
935 {
936 if (len < lens)
937 tmpV = atAxis;
938
939 tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep
940 force.X += tmpV.X;
941 force.Y += tmpV.Y;
942 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) == 0)
943 force.Z += tmpV.Z;
944 }
945 }
946 }
947
948 // linear friction/damping
949 if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0)
950 {
951 tmpV.X = -curLocalVel.X / m_linearFrictionTimescale.X;
952 tmpV.Y = -curLocalVel.Y / m_linearFrictionTimescale.Y;
953 tmpV.Z = -curLocalVel.Z / m_linearFrictionTimescale.Z;
954 tmpV *= rotq; // to world
955
956 if(ldampZ != 0 && Math.Abs(ldampZ) > Math.Abs(tmpV.Z))
957 tmpV.Z = ldampZ;
958 force.X += tmpV.X;
959 force.Y += tmpV.Y;
960 force.Z += tmpV.Z;
961 }
962
963 // vertical atractor
964 if (verticalAttractionTimescale < 300)
965 {
966 float roll;
967 float pitch;
968
969 float ftmp = m_invtimestep / verticalAttractionTimescale / verticalAttractionTimescale;
970
971 float ftmp2;
972 ftmp2 = 0.5f * m_verticalAttractionEfficiency * m_invtimestep;
973 m_amdampX = ftmp2;
974
975 m_ampwr = 1.0f - 0.8f * m_verticalAttractionEfficiency;
976
977 GetRollPitch(irotq, out roll, out pitch);
978
979 if (roll > halfpi)
980 roll = pi - roll;
981 else if (roll < -halfpi)
982 roll = -pi - roll;
983
984 float effroll = pitch / halfpi;
985 effroll *= effroll;
986 effroll = 1 - effroll;
987 effroll *= roll;
988
989 torque.X += effroll * ftmp;
990
991 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)
992 {
993 float effpitch = roll / halfpi;
994 effpitch *= effpitch;
995 effpitch = 1 - effpitch;
996 effpitch *= pitch;
997
998 torque.Y += effpitch * ftmp;
999 }
1000
1001 if (bankingEfficiency != 0 && Math.Abs(effroll) > 0.01)
1002 {
1003
1004 float broll = effroll;
1005 /*
1006 if (broll > halfpi)
1007 broll = pi - broll;
1008 else if (broll < -halfpi)
1009 broll = -pi - broll;
1010 */
1011 broll *= m_bankingEfficiency;
1012 if (m_bankingMix != 0)
1013 {
1014 float vfact = Math.Abs(curLocalVel.X) / 10.0f;
1015 if (vfact > 1.0f) vfact = 1.0f;
1016
1017 if (curLocalVel.X >= 0)
1018 broll *= (1 + (vfact - 1) * m_bankingMix);
1019 else
1020 broll *= -(1 + (vfact - 1) * m_bankingMix);
1021 }
1022 // make z rot be in world Z not local as seems to be in sl
1023
1024 broll = broll / m_bankingTimescale;
1025
1026
1027 tmpV = Zrot(irotq);
1028 tmpV *= broll;
1029
1030 torque.X += tmpV.X;
1031 torque.Y += tmpV.Y;
1032 torque.Z += tmpV.Z;
1033
1034 m_amdampZ = Math.Abs(m_bankingEfficiency) / m_bankingTimescale;
1035 m_amdampY = m_amdampZ;
1036
1037 }
1038 else
1039 {
1040 m_amdampZ = 1 / m_angularFrictionTimescale.Z;
1041 m_amdampY = m_amdampX;
1042 }
1043 }
1044 else
1045 {
1046 m_ampwr = 1.0f;
1047 m_amdampX = 1 / m_angularFrictionTimescale.X;
1048 m_amdampY = 1 / m_angularFrictionTimescale.Y;
1049 m_amdampZ = 1 / m_angularFrictionTimescale.Z;
1050 }
1051
1052 if(mousemode)
1053 {
1054 CameraData cam = rootPrim.TryGetCameraData();
1055 if(cam.Valid && cam.MouseLook)
1056 {
1057 Vector3 dirv = cam.CameraAtAxis * irotq;
1058
1059 float invamts = 1.0f/m_angularMotorTimescale;
1060 float tmp;
1061
1062 // get out of x == 0 plane
1063 if(Math.Abs(dirv.X) < 0.001f)
1064 dirv.X = 0.001f;
1065
1066 if (Math.Abs(dirv.Z) > 0.01)
1067 {
1068 tmp = -(float)Math.Atan2(dirv.Z, dirv.X) * m_angularMotorDirection.Y;
1069 if(tmp < -4f)
1070 tmp = -4f;
1071 else if(tmp > 4f)
1072 tmp = 4f;
1073 torque.Y += (tmp - curLocalAngVel.Y) * invamts;
1074 torque.Y -= curLocalAngVel.Y * m_amdampY;
1075 }
1076 else
1077 torque.Y -= curLocalAngVel.Y * m_invtimestep;
1078
1079 if (Math.Abs(dirv.Y) > 0.01)
1080 {
1081 if(mousemodebank)
1082 {
1083 tmp = -(float)Math.Atan2(dirv.Y, dirv.X) * m_angularMotorDirection.X;
1084 if(tmp < -4f)
1085 tmp = -4f;
1086 else if(tmp > 4f)
1087 tmp = 4f;
1088 torque.X += (tmp - curLocalAngVel.X) * invamts;
1089 }
1090 else
1091 {
1092 tmp = (float)Math.Atan2(dirv.Y, dirv.X) * m_angularMotorDirection.Z;
1093 tmp *= invamts;
1094 if(tmp < -4f)
1095 tmp = -4f;
1096 else if(tmp > 4f)
1097 tmp = 4f;
1098 torque.Z += (tmp - curLocalAngVel.Z) * invamts;
1099 }
1100 torque.X -= curLocalAngVel.X * m_amdampX;
1101 torque.Z -= curLocalAngVel.Z * m_amdampZ;
1102 }
1103 else
1104 {
1105 if(mousemodebank)
1106 torque.X -= curLocalAngVel.X * m_invtimestep;
1107 else
1108 torque.Z -= curLocalAngVel.Z * m_invtimestep;
1109 }
1110 }
1111 else
1112 {
1113 if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0)
1114 {
1115 torque.X -= curLocalAngVel.X * 10f;
1116 torque.Y -= curLocalAngVel.Y * 10f;
1117 torque.Z -= curLocalAngVel.Z * 10f;
1118 }
1119 }
1120 }
1121 else
1122 {
1123 // angular motor
1124 if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000)
1125 {
1126 tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error
1127 tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep
1128 torque.X += tmpV.X * m_ampwr;
1129 torque.Y += tmpV.Y * m_ampwr;
1130 torque.Z += tmpV.Z;
1131
1132 m_amEfect *= m_amDecay;
1133 }
1134 else
1135 m_amEfect = 0;
1136
1137 // angular deflection
1138 if (m_angularDeflectionEfficiency > 0)
1139 {
1140 Vector3 dirv;
1141
1142 if (curLocalVel.X > 0.01f)
1143 dirv = curLocalVel;
1144 else if (curLocalVel.X < -0.01f)
1145 // use oposite
1146 dirv = -curLocalVel;
1147 else
1148 {
1149 // make it fall into small positive x case
1150 dirv.X = 0.01f;
1151 dirv.Y = curLocalVel.Y;
1152 dirv.Z = curLocalVel.Z;
1153 }
1154
1155 float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale;
1156
1157 if (Math.Abs(dirv.Z) > 0.01)
1158 {
1159 torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp;
1160 }
1161
1162 if (Math.Abs(dirv.Y) > 0.01)
1163 {
1164 torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp;
1165 }
1166 }
1167
1168 if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0)
1169 {
1170 torque.X -= curLocalAngVel.X * m_amdampX;
1171 torque.Y -= curLocalAngVel.Y * m_amdampY;
1172 torque.Z -= curLocalAngVel.Z * m_amdampZ;
1173 }
1174 }
1175
1176 force *= dmass.mass;
1177
1178 force += rootPrim.m_force;
1179 force += rootPrim.m_forceacc;
1180 rootPrim.m_forceacc = Vector3.Zero;
1181
1182 if (force.X != 0 || force.Y != 0 || force.Z != 0)
1183 {
1184 d.BodyAddForce(Body, force.X, force.Y, force.Z);
1185 }
1186
1187 if (torque.X != 0 || torque.Y != 0 || torque.Z != 0)
1188 {
1189 torque *= m_referenceFrame; // to object frame
1190 dtorque.X = torque.X ;
1191 dtorque.Y = torque.Y;
1192 dtorque.Z = torque.Z;
1193
1194 d.MultiplyM3V3(out dvtmp, ref dmass.I, ref dtorque);
1195 d.BodyAddRelTorque(Body, dvtmp.X, dvtmp.Y, dvtmp.Z); // add torque in object frame
1196 }
1197
1198 torque = rootPrim.m_torque;
1199 torque += rootPrim.m_angularForceacc;
1200 rootPrim.m_angularForceacc = Vector3.Zero;
1201 if (torque.X != 0 || torque.Y != 0 || torque.Z != 0)
1202 d.BodyAddTorque(Body,torque.X, torque.Y, torque.Z);
1203 }
1204 }
1205}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs
new file mode 100644
index 0000000..5465035
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs
@@ -0,0 +1,946 @@
1/*
2 * AJLDuarte 2012
3 */
4
5using System;
6using System.Threading;
7using System.Collections.Generic;
8using System.IO;
9using System.Reflection;
10using System.Runtime.InteropServices;
11using System.Text;
12using OpenSim.Framework;
13using OpenSim.Region.PhysicsModules.SharedBase;
14using OdeAPI;
15using log4net;
16using Nini.Config;
17using OpenMetaverse;
18
19namespace OpenSim.Region.PhysicsModule.ubOde
20{
21 public enum MeshState : byte
22 {
23 noNeed = 0,
24
25 loadingAsset = 1,
26
27 AssetOK = 0x0f, // 00001111
28
29 NeedMask = 0x30, // 00110000
30 needMesh = 0x10, // 00010000
31 needAsset = 0x20, // 00100000
32
33 FailMask = 0xC0, // 11000000
34 AssetFailed = 0x40, // 01000000
35 MeshFailed = 0x80, // 10000000
36
37 MeshNoColide = FailMask | needAsset
38 }
39
40 public enum meshWorkerCmnds : byte
41 {
42 nop = 0,
43 addnew,
44 changefull,
45 changesize,
46 changeshapetype,
47 getmesh,
48 }
49
50 public class ODEPhysRepData
51 {
52 public PhysicsActor actor;
53 public PrimitiveBaseShape pbs;
54 public IMesh mesh;
55
56 public Vector3 size;
57 public Vector3 OBB;
58 public Vector3 OBBOffset;
59
60 public float volume;
61
62 public byte shapetype;
63 public bool hasOBB;
64 public bool hasMeshVolume;
65 public bool isTooSmall;
66 public MeshState meshState;
67 public UUID? assetID;
68 public meshWorkerCmnds comand;
69 }
70
71 public class ODEMeshWorker
72 {
73 private ILog m_log;
74 private ODEScene m_scene;
75 private IMesher m_mesher;
76
77 public bool meshSculptedPrim = true;
78 public float meshSculptLOD = 32;
79 public float MeshSculptphysicalLOD = 32;
80 public float MinSizeToMeshmerize = 0.1f;
81
82 private OpenSim.Framework.BlockingQueue<ODEPhysRepData> workQueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>();
83 private bool m_running;
84
85 private Thread m_thread;
86
87 public ODEMeshWorker(ODEScene pScene, ILog pLog, IMesher pMesher, IConfig pConfig)
88 {
89 m_scene = pScene;
90 m_log = pLog;
91 m_mesher = pMesher;
92
93 if (pConfig != null)
94 {
95 meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
96 meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
97 MinSizeToMeshmerize = pConfig.GetFloat("mesh_min_size", MinSizeToMeshmerize);
98 MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
99 }
100 m_running = true;
101 m_thread = new Thread(DoWork);
102 m_thread.Name = "OdeMeshWorker";
103 m_thread.Start();
104 }
105
106 private void DoWork()
107 {
108 m_mesher.ExpireFileCache();
109
110 while(m_running)
111 {
112 ODEPhysRepData nextRep = workQueue.Dequeue();
113 if(!m_running)
114 return;
115 if (nextRep == null)
116 continue;
117 if (m_scene.haveActor(nextRep.actor))
118 {
119 switch (nextRep.comand)
120 {
121 case meshWorkerCmnds.changefull:
122 case meshWorkerCmnds.changeshapetype:
123 case meshWorkerCmnds.changesize:
124 GetMesh(nextRep);
125 if (CreateActorPhysRep(nextRep) && m_scene.haveActor(nextRep.actor))
126 m_scene.AddChange(nextRep.actor, changes.PhysRepData, nextRep);
127 break;
128 case meshWorkerCmnds.getmesh:
129 DoRepDataGetMesh(nextRep);
130 break;
131 }
132 }
133 }
134 }
135
136 public void Stop()
137 {
138 try
139 {
140 m_thread.Abort();
141 workQueue.Clear();
142 }
143 catch
144 {
145 }
146 }
147
148 public void ChangeActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
149 Vector3 size, byte shapetype)
150 {
151 ODEPhysRepData repData = new ODEPhysRepData();
152 repData.actor = actor;
153 repData.pbs = pbs;
154 repData.size = size;
155 repData.shapetype = shapetype;
156
157 CheckMesh(repData);
158 CalcVolumeData(repData);
159 m_scene.AddChange(actor, changes.PhysRepData, repData);
160 return;
161 }
162
163 public ODEPhysRepData NewActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
164 Vector3 size, byte shapetype)
165 {
166 ODEPhysRepData repData = new ODEPhysRepData();
167 repData.actor = actor;
168 repData.pbs = pbs;
169 repData.size = size;
170 repData.shapetype = shapetype;
171
172 CheckMesh(repData);
173 CalcVolumeData(repData);
174 m_scene.AddChange(actor, changes.AddPhysRep, repData);
175 return repData;
176 }
177
178 public void RequestMesh(ODEPhysRepData repData)
179 {
180 repData.mesh = null;
181
182 if (repData.meshState == MeshState.needAsset)
183 {
184 PrimitiveBaseShape pbs = repData.pbs;
185
186 // check if we got outdated
187
188 if (!pbs.SculptEntry || pbs.SculptTexture == UUID.Zero)
189 {
190 repData.meshState = MeshState.noNeed;
191 return;
192 }
193
194 repData.assetID = pbs.SculptTexture;
195 repData.meshState = MeshState.loadingAsset;
196
197 repData.comand = meshWorkerCmnds.getmesh;
198 workQueue.Enqueue(repData);
199 }
200 }
201
202 // creates and prepares a mesh to use and calls parameters estimation
203 public bool CreateActorPhysRep(ODEPhysRepData repData)
204 {
205 IMesh mesh = repData.mesh;
206
207 if (mesh != null)
208 {
209 IntPtr vertices, indices;
210 int vertexCount, indexCount;
211 int vertexStride, triStride;
212
213 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
214 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
215
216 if (vertexCount == 0 || indexCount == 0)
217 {
218 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}",
219 repData.actor.Name, repData.pbs.SculptTexture.ToString());
220 repData.meshState = MeshState.MeshFailed;
221 repData.hasOBB = false;
222 repData.mesh = null;
223 m_scene.mesher.ReleaseMesh(mesh);
224 }
225 else
226 {
227 repData.OBBOffset = mesh.GetCentroid();
228 repData.OBB = mesh.GetOBB();
229 repData.hasOBB = true;
230 mesh.releaseSourceMeshData();
231 }
232 }
233 CalcVolumeData(repData);
234 return true;
235 }
236
237 public void AssetLoaded(ODEPhysRepData repData)
238 {
239 if (m_scene.haveActor(repData.actor))
240 {
241 if (needsMeshing(repData)) // no need for pbs now?
242 {
243 repData.comand = meshWorkerCmnds.changefull;
244 workQueue.Enqueue(repData);
245 }
246 }
247 else
248 repData.pbs.SculptData = Utils.EmptyBytes;
249 }
250
251 public void DoRepDataGetMesh(ODEPhysRepData repData)
252 {
253 if (!repData.pbs.SculptEntry)
254 return;
255
256 if (repData.meshState != MeshState.loadingAsset)
257 return;
258
259 if (repData.assetID == null || repData.assetID == UUID.Zero)
260 return;
261
262 if (repData.assetID != repData.pbs.SculptTexture)
263 return;
264
265 // check if it is in cache
266 GetMesh(repData);
267 if (repData.meshState != MeshState.needAsset)
268 {
269 CreateActorPhysRep(repData);
270 m_scene.AddChange(repData.actor, changes.PhysRepData, repData);
271 return;
272 }
273
274 RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod;
275 if (assetProvider == null)
276 return;
277 ODEAssetRequest asr = new ODEAssetRequest(this, assetProvider, repData, m_log);
278 }
279
280
281 /// <summary>
282 /// Routine to figure out if we need to mesh this prim with our mesher
283 /// </summary>
284 /// <param name="pbs"></param>
285 /// <returns></returns>
286 public bool needsMeshing(ODEPhysRepData repData)
287 {
288 PrimitiveBaseShape pbs = repData.pbs;
289 // check sculpts or meshs
290
291 Vector3 scale = pbs.Scale;
292 if(scale.X <= MinSizeToMeshmerize &&
293 scale.Y <= MinSizeToMeshmerize &&
294 scale.Z <= MinSizeToMeshmerize)
295 {
296 repData.isTooSmall = true;
297 return false;
298 }
299
300 if (pbs.SculptEntry)
301 {
302 if (meshSculptedPrim)
303 return true;
304
305 if (pbs.SculptType == (byte)SculptType.Mesh) // always do meshs
306 return true;
307
308 return false;
309 }
310
311 // convex shapes have no holes
312 ushort profilehollow = pbs.ProfileHollow;
313 if(repData.shapetype == 2)
314 profilehollow = 0;
315
316 // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim
317
318 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
319 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
320 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
321 {
322
323 if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
324 && profilehollow == 0
325 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
326 && pbs.PathBegin == 0 && pbs.PathEnd == 0
327 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
328 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
329 && pbs.PathShearX == 0 && pbs.PathShearY == 0)
330 {
331 return false;
332 }
333 }
334
335 // following code doesn't give meshs to boxes and spheres ever
336 // and it's odd.. so for now just return true if asked to force meshs
337 // hopefully mesher will fail if doesn't suport so things still get basic boxes
338
339 int iPropertiesNotSupportedDefault = 0;
340
341 if (profilehollow != 0)
342 iPropertiesNotSupportedDefault++;
343
344 if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
345 iPropertiesNotSupportedDefault++;
346
347 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
348 iPropertiesNotSupportedDefault++;
349
350 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
351 iPropertiesNotSupportedDefault++;
352
353 if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
354 iPropertiesNotSupportedDefault++;
355
356 if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
357 iPropertiesNotSupportedDefault++;
358
359 if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
360 iPropertiesNotSupportedDefault++;
361
362 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
363 iPropertiesNotSupportedDefault++;
364
365 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
366 iPropertiesNotSupportedDefault++;
367
368 // test for torus
369 if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
370 {
371 if (pbs.PathCurve == (byte)Extrusion.Curve1)
372 {
373 iPropertiesNotSupportedDefault++;
374 }
375 }
376 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
377 {
378 if (pbs.PathCurve == (byte)Extrusion.Straight)
379 {
380 iPropertiesNotSupportedDefault++;
381 }
382
383 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
384 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
385 {
386 iPropertiesNotSupportedDefault++;
387 }
388 }
389 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
390 {
391 if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
392 {
393 iPropertiesNotSupportedDefault++;
394 }
395 }
396 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
397 {
398 if (pbs.PathCurve == (byte)Extrusion.Straight)
399 {
400 iPropertiesNotSupportedDefault++;
401 }
402 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
403 {
404 iPropertiesNotSupportedDefault++;
405 }
406 }
407
408 if (iPropertiesNotSupportedDefault == 0)
409 {
410 return false;
411 }
412 return true;
413 }
414
415 // see if we need a mesh and if so if we have a cached one
416 // called with a new repData
417 public void CheckMesh(ODEPhysRepData repData)
418 {
419 PhysicsActor actor = repData.actor;
420 PrimitiveBaseShape pbs = repData.pbs;
421
422 if (!needsMeshing(repData))
423 {
424 repData.meshState = MeshState.noNeed;
425 repData.hasOBB = false;
426 return;
427 }
428
429 IMesh mesh = null;
430
431 Vector3 size = repData.size;
432
433 int clod = (int)LevelOfDetail.High;
434 byte shapetype = repData.shapetype;
435 bool convex = shapetype == 2;
436
437 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
438
439 if (mesh == null)
440 {
441 if (pbs.SculptEntry)
442 {
443 if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero)
444 {
445 repData.assetID = pbs.SculptTexture;
446 repData.meshState = MeshState.needAsset;
447 }
448 else
449 repData.meshState = MeshState.MeshFailed;
450
451 return;
452 }
453 else
454 {
455 repData.meshState = MeshState.needMesh;
456 mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true);
457 if (mesh == null)
458 {
459 repData.meshState = MeshState.MeshFailed;
460 return;
461 }
462 }
463 }
464
465 repData.meshState = MeshState.AssetOK;
466 repData.mesh = mesh;
467 repData.OBB = mesh.GetOBB();
468 repData.OBBOffset = mesh.GetCentroid();
469 repData.hasOBB = true;
470
471 if (pbs.SculptEntry)
472 {
473 repData.assetID = pbs.SculptTexture;
474 }
475
476 pbs.SculptData = Utils.EmptyBytes;
477 return ;
478 }
479
480 public void GetMesh(ODEPhysRepData repData)
481 {
482 PhysicsActor actor = repData.actor;
483
484 PrimitiveBaseShape pbs = repData.pbs;
485
486 repData.mesh = null;
487 repData.hasOBB = false;
488
489 if (!needsMeshing(repData))
490 {
491 repData.meshState = MeshState.noNeed;
492 return;
493 }
494
495 if (repData.meshState == MeshState.MeshFailed)
496 return;
497
498 if (pbs.SculptEntry)
499 {
500 if (repData.meshState == MeshState.AssetFailed)
501 {
502 if (pbs.SculptTexture == repData.assetID)
503 return;
504 }
505 }
506
507 repData.meshState = MeshState.noNeed;
508
509 IMesh mesh = null;
510 Vector3 size = repData.size;
511 byte shapetype = repData.shapetype;
512
513 bool convex;
514 int clod = (int)LevelOfDetail.High;
515 if (shapetype == 0)
516 convex = false;
517 else
518 {
519 convex = true;
520 if (pbs.SculptType != (byte)SculptType.Mesh)
521 clod = (int)LevelOfDetail.Low;
522 }
523
524 mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true);
525
526 if (mesh == null)
527 {
528 if (pbs.SculptEntry)
529 {
530 if (pbs.SculptTexture == UUID.Zero)
531 return;
532
533 repData.assetID = pbs.SculptTexture;
534
535 if (pbs.SculptData == null || pbs.SculptData.Length == 0)
536 {
537 repData.meshState = MeshState.needAsset;
538 return;
539 }
540 }
541 }
542
543 repData.mesh = mesh;
544 repData.pbs.SculptData = Utils.EmptyBytes;
545
546 if (mesh == null)
547 {
548 if (pbs.SculptEntry)
549 repData.meshState = MeshState.AssetFailed;
550 else
551 repData.meshState = MeshState.MeshFailed;
552
553 return;
554 }
555
556 repData.meshState = MeshState.AssetOK;
557
558 return;
559 }
560
561 private void CalculateBasicPrimVolume(ODEPhysRepData repData)
562 {
563 Vector3 _size = repData.size;
564
565 float volume = _size.X * _size.Y * _size.Z; // default
566 if(repData.isTooSmall)
567 {
568 repData.volume = volume;
569 return;
570 }
571
572 PrimitiveBaseShape _pbs = repData.pbs;
573 float tmp;
574
575 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
576 float hollowVolume = hollowAmount * hollowAmount;
577
578 switch (_pbs.ProfileShape)
579 {
580 case ProfileShape.Square:
581 // default box
582
583 if (_pbs.PathCurve == (byte)Extrusion.Straight)
584 {
585 if (hollowAmount > 0.0)
586 {
587 switch (_pbs.HollowShape)
588 {
589 case HollowShape.Square:
590 case HollowShape.Same:
591 break;
592
593 case HollowShape.Circle:
594
595 hollowVolume *= 0.78539816339f;
596 break;
597
598 case HollowShape.Triangle:
599
600 hollowVolume *= (0.5f * .5f);
601 break;
602
603 default:
604 hollowVolume = 0;
605 break;
606 }
607 volume *= (1.0f - hollowVolume);
608 }
609 }
610
611 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
612 {
613 //a tube
614
615 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
616 tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY);
617 volume -= volume * tmp * tmp;
618
619 if (hollowAmount > 0.0)
620 {
621 hollowVolume *= hollowAmount;
622
623 switch (_pbs.HollowShape)
624 {
625 case HollowShape.Square:
626 case HollowShape.Same:
627 break;
628
629 case HollowShape.Circle:
630 hollowVolume *= 0.78539816339f;
631 break;
632
633 case HollowShape.Triangle:
634 hollowVolume *= 0.5f * 0.5f;
635 break;
636 default:
637 hollowVolume = 0;
638 break;
639 }
640 volume *= (1.0f - hollowVolume);
641 }
642 }
643
644 break;
645
646 case ProfileShape.Circle:
647
648 if (_pbs.PathCurve == (byte)Extrusion.Straight)
649 {
650 volume *= 0.78539816339f; // elipse base
651
652 if (hollowAmount > 0.0)
653 {
654 switch (_pbs.HollowShape)
655 {
656 case HollowShape.Same:
657 case HollowShape.Circle:
658 break;
659
660 case HollowShape.Square:
661 hollowVolume *= 0.5f * 2.5984480504799f;
662 break;
663
664 case HollowShape.Triangle:
665 hollowVolume *= .5f * 1.27323954473516f;
666 break;
667
668 default:
669 hollowVolume = 0;
670 break;
671 }
672 volume *= (1.0f - hollowVolume);
673 }
674 }
675
676 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
677 {
678 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
679 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
680 volume *= (1.0f - tmp * tmp);
681
682 if (hollowAmount > 0.0)
683 {
684
685 // calculate the hollow volume by it's shape compared to the prim shape
686 hollowVolume *= hollowAmount;
687
688 switch (_pbs.HollowShape)
689 {
690 case HollowShape.Same:
691 case HollowShape.Circle:
692 break;
693
694 case HollowShape.Square:
695 hollowVolume *= 0.5f * 2.5984480504799f;
696 break;
697
698 case HollowShape.Triangle:
699 hollowVolume *= .5f * 1.27323954473516f;
700 break;
701
702 default:
703 hollowVolume = 0;
704 break;
705 }
706 volume *= (1.0f - hollowVolume);
707 }
708 }
709 break;
710
711 case ProfileShape.HalfCircle:
712 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
713 {
714 volume *= 0.5236f;
715
716 if (hollowAmount > 0.0)
717 {
718 hollowVolume *= hollowAmount;
719
720 switch (_pbs.HollowShape)
721 {
722 case HollowShape.Circle:
723 case HollowShape.Triangle: // diference in sl is minor and odd
724 case HollowShape.Same:
725 break;
726
727 case HollowShape.Square:
728 hollowVolume *= 0.909f;
729 break;
730
731 // case HollowShape.Triangle:
732 // hollowVolume *= .827f;
733 // break;
734 default:
735 hollowVolume = 0;
736 break;
737 }
738 volume *= (1.0f - hollowVolume);
739 }
740
741 }
742 break;
743
744 case ProfileShape.EquilateralTriangle:
745
746 if (_pbs.PathCurve == (byte)Extrusion.Straight)
747 {
748 volume *= 0.32475953f;
749
750 if (hollowAmount > 0.0)
751 {
752
753 // calculate the hollow volume by it's shape compared to the prim shape
754 switch (_pbs.HollowShape)
755 {
756 case HollowShape.Same:
757 case HollowShape.Triangle:
758 hollowVolume *= .25f;
759 break;
760
761 case HollowShape.Square:
762 hollowVolume *= 0.499849f * 3.07920140172638f;
763 break;
764
765 case HollowShape.Circle:
766 // Hollow shape is a perfect cyllinder in respect to the cube's scale
767 // Cyllinder hollow volume calculation
768
769 hollowVolume *= 0.1963495f * 3.07920140172638f;
770 break;
771
772 default:
773 hollowVolume = 0;
774 break;
775 }
776 volume *= (1.0f - hollowVolume);
777 }
778 }
779 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
780 {
781 volume *= 0.32475953f;
782 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
783 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
784 volume *= (1.0f - tmp * tmp);
785
786 if (hollowAmount > 0.0)
787 {
788
789 hollowVolume *= hollowAmount;
790
791 switch (_pbs.HollowShape)
792 {
793 case HollowShape.Same:
794 case HollowShape.Triangle:
795 hollowVolume *= .25f;
796 break;
797
798 case HollowShape.Square:
799 hollowVolume *= 0.499849f * 3.07920140172638f;
800 break;
801
802 case HollowShape.Circle:
803
804 hollowVolume *= 0.1963495f * 3.07920140172638f;
805 break;
806
807 default:
808 hollowVolume = 0;
809 break;
810 }
811 volume *= (1.0f - hollowVolume);
812 }
813 }
814 break;
815
816 default:
817 break;
818 }
819
820 float taperX1;
821 float taperY1;
822 float taperX;
823 float taperY;
824 float pathBegin;
825 float pathEnd;
826 float profileBegin;
827 float profileEnd;
828
829 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
830 {
831 taperX1 = _pbs.PathScaleX * 0.01f;
832 if (taperX1 > 1.0f)
833 taperX1 = 2.0f - taperX1;
834 taperX = 1.0f - taperX1;
835
836 taperY1 = _pbs.PathScaleY * 0.01f;
837 if (taperY1 > 1.0f)
838 taperY1 = 2.0f - taperY1;
839 taperY = 1.0f - taperY1;
840 }
841 else
842 {
843 taperX = _pbs.PathTaperX * 0.01f;
844 if (taperX < 0.0f)
845 taperX = -taperX;
846 taperX1 = 1.0f - taperX;
847
848 taperY = _pbs.PathTaperY * 0.01f;
849 if (taperY < 0.0f)
850 taperY = -taperY;
851 taperY1 = 1.0f - taperY;
852 }
853
854 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
855
856 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
857 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
858 volume *= (pathEnd - pathBegin);
859
860 // this is crude aproximation
861 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
862 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
863 volume *= (profileEnd - profileBegin);
864
865 repData.volume = volume;
866 }
867
868 private void CalcVolumeData(ODEPhysRepData repData)
869 {
870 if (repData.hasOBB)
871 {
872 Vector3 OBB = repData.OBB;
873 }
874 else
875 {
876 Vector3 OBB = repData.size;
877 OBB.X *= 0.5f;
878 OBB.Y *= 0.5f;
879 OBB.Z *= 0.5f;
880
881 repData.OBB = OBB;
882 repData.OBBOffset = Vector3.Zero;
883 }
884
885 CalculateBasicPrimVolume(repData);
886 }
887 }
888
889 public class ODEAssetRequest
890 {
891 ODEMeshWorker m_worker;
892 private ILog m_log;
893 ODEPhysRepData repData;
894
895 public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider,
896 ODEPhysRepData pRepData, ILog plog)
897 {
898 m_worker = pWorker;
899 m_log = plog;
900 repData = pRepData;
901
902 repData.meshState = MeshState.AssetFailed;
903 if (provider == null)
904 return;
905
906 if (repData.assetID == null)
907 return;
908
909 UUID assetID = (UUID) repData.assetID;
910 if (assetID == UUID.Zero)
911 return;
912
913 repData.meshState = MeshState.loadingAsset;
914 provider(assetID, ODEassetReceived);
915 }
916
917 void ODEassetReceived(AssetBase asset)
918 {
919 repData.meshState = MeshState.AssetFailed;
920 if (asset != null)
921 {
922 if (asset.Data != null && asset.Data.Length > 0)
923 {
924 repData.meshState = MeshState.noNeed;
925
926 if (!repData.pbs.SculptEntry)
927 return;
928 if (repData.pbs.SculptTexture != repData.assetID)
929 return;
930
931// repData.pbs.SculptData = new byte[asset.Data.Length];
932// asset.Data.CopyTo(repData.pbs.SculptData,0);
933 repData.pbs.SculptData = asset.Data;
934 repData.meshState = MeshState.AssetOK;
935 m_worker.AssetLoaded(repData);
936 }
937 else
938 m_log.WarnFormat("[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.",
939 repData.actor.Name, asset.ID.ToString());
940 }
941 else
942 m_log.WarnFormat("[PHYSICS]: asset provider returned null asset for mesh of prim {0}.",
943 repData.actor.Name);
944 }
945 }
946}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs
new file mode 100644
index 0000000..4cb1736
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs
@@ -0,0 +1,112 @@
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4using log4net;
5using Nini.Config;
6using Mono.Addins;
7using OdeAPI;
8using OpenSim.Framework;
9using OpenSim.Region.Framework.Scenes;
10using OpenSim.Region.Framework.Interfaces;
11
12namespace OpenSim.Region.PhysicsModule.ubOde
13{
14 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ubODEPhysicsScene")]
15 class ubOdeModule : INonSharedRegionModule
16 {
17 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
18
19 private static Dictionary<Scene, ODEScene> m_scenes = new Dictionary<Scene, ODEScene>();
20 private bool m_Enabled = false;
21 private IConfigSource m_config;
22 private bool OSOdeLib;
23
24
25 #region INonSharedRegionModule
26
27 public string Name
28 {
29 get { return "ubODE"; }
30 }
31
32 public string Version
33 {
34 get { return "1.0"; }
35 }
36
37 public Type ReplaceableInterface
38 {
39 get { return null; }
40 }
41
42 public void Initialise(IConfigSource source)
43 {
44 IConfig config = source.Configs["Startup"];
45 if (config != null)
46 {
47 string physics = config.GetString("physics", string.Empty);
48 if (physics == Name)
49 {
50 m_config = source;
51 m_Enabled = true;
52
53 if (Util.IsWindows())
54 Util.LoadArchSpecificWindowsDll("ode.dll");
55
56 d.InitODE();
57
58 string ode_config = d.GetConfiguration();
59 if (ode_config != null && ode_config != "")
60 {
61 m_log.InfoFormat("[ubODE] ode library configuration: {0}", ode_config);
62
63 if (ode_config.Contains("ODE_OPENSIM"))
64 {
65 OSOdeLib = true;
66 }
67 }
68 }
69 }
70 }
71
72 public void Close()
73 {
74 }
75
76 public void AddRegion(Scene scene)
77 {
78 if (!m_Enabled)
79 return;
80
81 if(m_scenes.ContainsKey(scene)) // ???
82 return;
83 ODEScene newodescene = new ODEScene(scene, m_config, Name, Version, OSOdeLib);
84 m_scenes[scene] = newodescene;
85 }
86
87 public void RemoveRegion(Scene scene)
88 {
89 if (!m_Enabled)
90 return;
91
92 // a odescene.dispose is called later directly by scene.cs
93 // since it is seen as a module interface
94
95 if(m_scenes.ContainsKey(scene))
96 m_scenes.Remove(scene);
97 }
98
99 public void RegionLoaded(Scene scene)
100 {
101 if (!m_Enabled)
102 return;
103
104 if(m_scenes.ContainsKey(scene))
105 {
106 m_scenes[scene].RegionLoaded();
107 }
108
109 }
110 #endregion
111 }
112}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs
new file mode 100644
index 0000000..aa208e2
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs
@@ -0,0 +1,4256 @@
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
28/*
29 * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
30 * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
31 * ODEPrim.cs contains methods dealing with Prim editing, Prim
32 * characteristics and Kinetic motion.
33 * ODEDynamics.cs contains methods dealing with Prim Physical motion
34 * (dynamics) and the associated settings. Old Linear and angular
35 * motors for dynamic motion have been replace with MoveLinear()
36 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic
37 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
38 * switch between 'VEHICLE' parameter use and general dynamics
39 * settings use.
40 */
41
42//#define SPAM
43
44using System;
45using System.Collections.Generic;
46using System.Reflection;
47using System.Runtime.InteropServices;
48using System.Threading;
49using log4net;
50using OpenMetaverse;
51using OdeAPI;
52using OpenSim.Framework;
53using OpenSim.Region.PhysicsModules.SharedBase;
54
55namespace OpenSim.Region.PhysicsModule.ubOde
56{
57 public class OdePrim : PhysicsActor
58 {
59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
60
61 private bool m_isphysical;
62 private bool m_fakeisphysical;
63 private bool m_isphantom;
64 private bool m_fakeisphantom;
65 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
66 private bool m_fakeisVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
67
68 internal bool m_building;
69 protected bool m_forcePosOrRotation;
70 private bool m_iscolliding;
71
72 internal bool m_isSelected;
73 private bool m_delaySelect;
74 private bool m_lastdoneSelected;
75 internal bool m_outbounds;
76
77 private byte m_angularlocks = 0;
78
79 private Quaternion m_lastorientation;
80 private Quaternion _orientation;
81
82 private Vector3 _position;
83 private Vector3 _velocity;
84 private Vector3 m_lastVelocity;
85 private Vector3 m_lastposition;
86 private Vector3 m_rotationalVelocity;
87 private Vector3 _size;
88 private Vector3 m_acceleration;
89 private IntPtr Amotor;
90
91 internal Vector3 m_force;
92 internal Vector3 m_forceacc;
93 internal Vector3 m_torque;
94 internal Vector3 m_angularForceacc;
95
96 private float m_invTimeStep;
97 private float m_timeStep;
98
99 private Vector3 m_PIDTarget;
100 private float m_PIDTau;
101 private bool m_usePID;
102
103 private float m_PIDHoverHeight;
104 private float m_PIDHoverTau;
105 private bool m_useHoverPID;
106 private PIDHoverType m_PIDHoverType;
107 private float m_targetHoverHeight;
108 private float m_groundHeight;
109 private float m_waterHeight;
110 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
111
112 private int m_body_autodisable_frames;
113 public int m_bodydisablecontrol = 0;
114 private float m_gravmod = 1.0f;
115
116 // Default we're a Geometry
117 private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
118 // Default colide nonphysical don't try to colide with anything
119 private const CollisionCategories m_default_collisionFlagsNotPhysical = 0;
120
121 private const CollisionCategories m_default_collisionFlagsPhysical = (CollisionCategories.Geom |
122 CollisionCategories.Character |
123 CollisionCategories.Land |
124 CollisionCategories.VolumeDtc);
125
126// private bool m_collidesLand = true;
127 private bool m_collidesWater;
128// public bool m_returnCollisions;
129
130 private bool m_NoColide; // for now only for internal use for bad meshs
131
132
133 // Default, Collide with Other Geometries, spaces and Bodies
134 private CollisionCategories m_collisionFlags = m_default_collisionFlagsNotPhysical;
135
136 public bool m_disabled;
137
138 private uint m_localID;
139
140 private IMesh m_mesh;
141 private object m_meshlock = new object();
142 private PrimitiveBaseShape _pbs;
143
144 private UUID? m_assetID;
145 private MeshState m_meshState;
146
147 public ODEScene _parent_scene;
148
149 /// <summary>
150 /// The physics space which contains prim geometry
151 /// </summary>
152 public IntPtr m_targetSpace;
153
154 public IntPtr prim_geom;
155 public IntPtr _triMeshData;
156
157 private PhysicsActor _parent;
158
159 private List<OdePrim> childrenPrim = new List<OdePrim>();
160
161 public float m_collisionscore;
162 private int m_colliderfilter = 0;
163
164 public IntPtr collide_geom; // for objects: geom if single prim space it linkset
165
166 private float m_density;
167 private byte m_shapetype;
168 private byte m_fakeShapetype;
169 public bool _zeroFlag;
170 private bool m_lastUpdateSent;
171
172 public IntPtr Body;
173
174 private Vector3 _target_velocity;
175
176 public Vector3 m_OBBOffset;
177 public Vector3 m_OBB;
178 public float primOOBradiusSQ;
179
180 private bool m_hasOBB = true;
181
182 private float m_physCost;
183 private float m_streamCost;
184
185 public d.Mass primdMass; // prim inertia information on it's own referencial
186 private PhysicsInertiaData m_InertiaOverride;
187 float primMass; // prim own mass
188 float primVolume; // prim own volume;
189 float m_mass; // object mass acording to case
190
191 public int givefakepos;
192 private Vector3 fakepos;
193 public int givefakeori;
194 private Quaternion fakeori;
195 private PhysicsInertiaData m_fakeInertiaOverride;
196
197 private int m_eventsubscription;
198 private int m_cureventsubscription;
199 private CollisionEventUpdate CollisionEventsThisFrame = null;
200 private CollisionEventUpdate CollisionVDTCEventsThisFrame = null;
201 private bool SentEmptyCollisionsEvent;
202
203 public volatile bool childPrim;
204
205 public ODEDynamics m_vehicle;
206
207 internal int m_material = (int)Material.Wood;
208 private float mu;
209 private float bounce;
210
211 /// <summary>
212 /// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
213 /// </summary>
214 public override bool IsPhysical // this is not reliable for internal use
215 {
216 get { return m_fakeisphysical; }
217 set
218 {
219 m_fakeisphysical = value; // we show imediatly to outside that we changed physical
220 // and also to stop imediatly some updates
221 // but real change will only happen in taintprocessing
222
223 if (!value) // Zero the remembered last velocity
224 m_lastVelocity = Vector3.Zero;
225 AddChange(changes.Physical, value);
226 }
227 }
228
229 public override bool IsVolumeDtc
230 {
231 get { return m_fakeisVolumeDetect; }
232 set
233 {
234 m_fakeisVolumeDetect = value;
235 AddChange(changes.VolumeDtc, value);
236 }
237 }
238
239 public override bool Phantom // this is not reliable for internal use
240 {
241 get { return m_fakeisphantom; }
242 set
243 {
244 m_fakeisphantom = value;
245 AddChange(changes.Phantom, value);
246 }
247 }
248
249 public override bool Building // this is not reliable for internal use
250 {
251 get { return m_building; }
252 set
253 {
254// if (value)
255// m_building = true;
256 AddChange(changes.building, value);
257 }
258 }
259
260 public override void getContactData(ref ContactData cdata)
261 {
262 cdata.mu = mu;
263 cdata.bounce = bounce;
264
265 // cdata.softcolide = m_softcolide;
266 cdata.softcolide = false;
267
268 if (m_isphysical)
269 {
270 ODEDynamics veh;
271 if (_parent != null)
272 veh = ((OdePrim)_parent).m_vehicle;
273 else
274 veh = m_vehicle;
275
276 if (veh != null && veh.Type != Vehicle.TYPE_NONE)
277 cdata.mu *= veh.FrictionFactor;
278// cdata.mu *= 0;
279 }
280 }
281
282 public override float PhysicsCost
283 {
284 get
285 {
286 return m_physCost;
287 }
288 }
289
290 public override float StreamCost
291 {
292 get
293 {
294 return m_streamCost;
295 }
296 }
297
298 public override int PhysicsActorType
299 {
300 get { return (int)ActorTypes.Prim; }
301 set { return; }
302 }
303
304 public override bool SetAlwaysRun
305 {
306 get { return false; }
307 set { return; }
308 }
309
310 public override uint LocalID
311 {
312 get { return m_localID; }
313 set
314 {
315 uint oldid = m_localID;
316 m_localID = value;
317 _parent_scene.changePrimID(this, oldid);
318 }
319 }
320
321 public override PhysicsActor ParentActor
322 {
323 get
324 {
325 if (childPrim)
326 return _parent;
327 else
328 return (PhysicsActor)this;
329 }
330 }
331
332 public override bool Grabbed
333 {
334 set { return; }
335 }
336
337 public override bool Selected
338 {
339 set
340 {
341 if (value)
342 m_isSelected = value; // if true set imediatly to stop moves etc
343 AddChange(changes.Selected, value);
344 }
345 }
346
347 public override bool Flying
348 {
349 // no flying prims for you
350 get { return false; }
351 set { }
352 }
353
354 public override bool IsColliding
355 {
356 get { return m_iscolliding; }
357 set
358 {
359 if (value)
360 {
361 m_colliderfilter += 2;
362 if (m_colliderfilter > 2)
363 m_colliderfilter = 2;
364 }
365 else
366 {
367 m_colliderfilter--;
368 if (m_colliderfilter < 0)
369 m_colliderfilter = 0;
370 }
371
372 if (m_colliderfilter == 0)
373 m_iscolliding = false;
374 else
375 m_iscolliding = true;
376 }
377 }
378
379 public override bool CollidingGround
380 {
381 get { return false; }
382 set { return; }
383 }
384
385 public override bool CollidingObj
386 {
387 get { return false; }
388 set { return; }
389 }
390
391
392 public override bool ThrottleUpdates {get;set;}
393
394 public override bool Stopped
395 {
396 get { return _zeroFlag; }
397 }
398
399 public override Vector3 Position
400 {
401 get
402 {
403 if (givefakepos > 0)
404 return fakepos;
405 else
406 return _position;
407 }
408
409 set
410 {
411 fakepos = value;
412 givefakepos++;
413 AddChange(changes.Position, value);
414 }
415 }
416
417 public override Vector3 Size
418 {
419 get { return _size; }
420 set
421 {
422 if (value.IsFinite())
423 {
424 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, value, m_fakeShapetype);
425 }
426 else
427 {
428 m_log.WarnFormat("[PHYSICS]: Got NaN Size on object {0}", Name);
429 }
430 }
431 }
432
433 public override float Mass
434 {
435 get { return primMass; }
436 }
437
438 public override Vector3 Force
439 {
440 get { return m_force; }
441 set
442 {
443 if (value.IsFinite())
444 {
445 AddChange(changes.Force, value);
446 }
447 else
448 {
449 m_log.WarnFormat("[PHYSICS]: NaN in Force Applied to an Object {0}", Name);
450 }
451 }
452 }
453
454 public override void SetVolumeDetect(int param)
455 {
456 m_fakeisVolumeDetect = (param != 0);
457 AddChange(changes.VolumeDtc, m_fakeisVolumeDetect);
458 }
459
460 public override Vector3 GeometricCenter
461 {
462 // this is not real geometric center but a average of positions relative to root prim acording to
463 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
464 // ignoring tortured prims details since sl also seems to ignore
465 // so no real use in doing it on physics
466 get
467 {
468 return Vector3.Zero;
469 }
470 }
471
472 public override PhysicsInertiaData GetInertiaData()
473 {
474 PhysicsInertiaData inertia;
475 if(childPrim)
476 {
477 if(_parent != null)
478 return _parent.GetInertiaData();
479 else
480 {
481 inertia = new PhysicsInertiaData();
482 inertia.TotalMass = -1;
483 return inertia;
484 }
485 }
486
487 inertia = new PhysicsInertiaData();
488
489 // double buffering
490 if(m_fakeInertiaOverride != null)
491 {
492 d.Mass objdmass = new d.Mass();
493 objdmass.I.M00 = m_fakeInertiaOverride.Inertia.X;
494 objdmass.I.M11 = m_fakeInertiaOverride.Inertia.Y;
495 objdmass.I.M22 = m_fakeInertiaOverride.Inertia.Z;
496
497 objdmass.mass = m_fakeInertiaOverride.TotalMass;
498
499 if(Math.Abs(m_fakeInertiaOverride.InertiaRotation.W) < 0.999)
500 {
501 d.Matrix3 inertiarotmat = new d.Matrix3();
502 d.Quaternion inertiarot = new d.Quaternion();
503
504 inertiarot.X = m_fakeInertiaOverride.InertiaRotation.X;
505 inertiarot.Y = m_fakeInertiaOverride.InertiaRotation.Y;
506 inertiarot.Z = m_fakeInertiaOverride.InertiaRotation.Z;
507 inertiarot.W = m_fakeInertiaOverride.InertiaRotation.W;
508 d.RfromQ(out inertiarotmat, ref inertiarot);
509 d.MassRotate(ref objdmass, ref inertiarotmat);
510 }
511
512 inertia.TotalMass = m_fakeInertiaOverride.TotalMass;
513 inertia.CenterOfMass = m_fakeInertiaOverride.CenterOfMass;
514 inertia.Inertia.X = objdmass.I.M00;
515 inertia.Inertia.Y = objdmass.I.M11;
516 inertia.Inertia.Z = objdmass.I.M22;
517 inertia.InertiaRotation.X = objdmass.I.M01;
518 inertia.InertiaRotation.Y = objdmass.I.M02;
519 inertia.InertiaRotation.Z = objdmass.I.M12;
520 return inertia;
521 }
522
523 inertia.TotalMass = m_mass;
524
525 if(Body == IntPtr.Zero || prim_geom == IntPtr.Zero)
526 {
527 inertia.CenterOfMass = Vector3.Zero;
528 inertia.Inertia = Vector3.Zero;
529 inertia.InertiaRotation = Vector4.Zero;
530 return inertia;
531 }
532
533 d.Vector3 dtmp;
534 d.Mass m = new d.Mass();
535 lock(_parent_scene.OdeLock)
536 {
537 d.AllocateODEDataForThread(0);
538 dtmp = d.GeomGetOffsetPosition(prim_geom);
539 d.BodyGetMass(Body, out m);
540 }
541
542 Vector3 cm = new Vector3(-dtmp.X, -dtmp.Y, -dtmp.Z);
543 inertia.CenterOfMass = cm;
544 inertia.Inertia = new Vector3(m.I.M00, m.I.M11, m.I.M22);
545 inertia.InertiaRotation = new Vector4(m.I.M01, m.I.M02 , m.I.M12, 0);
546
547 return inertia;
548 }
549
550 public override void SetInertiaData(PhysicsInertiaData inertia)
551 {
552 if(childPrim)
553 {
554 if(_parent != null)
555 _parent.SetInertiaData(inertia);
556 return;
557 }
558
559 if(inertia.TotalMass > 0)
560 m_fakeInertiaOverride = new PhysicsInertiaData(inertia);
561 else
562 m_fakeInertiaOverride = null;
563
564 if (inertia.TotalMass > _parent_scene.maximumMassObject)
565 inertia.TotalMass = _parent_scene.maximumMassObject;
566 AddChange(changes.SetInertia,(object)m_fakeInertiaOverride);
567 }
568
569 public override Vector3 CenterOfMass
570 {
571 get
572 {
573 lock (_parent_scene.OdeLock)
574 {
575 d.AllocateODEDataForThread(0);
576
577 d.Vector3 dtmp;
578 if (!childPrim && Body != IntPtr.Zero)
579 {
580 dtmp = d.BodyGetPosition(Body);
581 return new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
582 }
583 else if (prim_geom != IntPtr.Zero)
584 {
585 d.Quaternion dq;
586 d.GeomCopyQuaternion(prim_geom, out dq);
587 Quaternion q;
588 q.X = dq.X;
589 q.Y = dq.Y;
590 q.Z = dq.Z;
591 q.W = dq.W;
592
593 Vector3 Ptot = m_OBBOffset * q;
594 dtmp = d.GeomGetPosition(prim_geom);
595 Ptot.X += dtmp.X;
596 Ptot.Y += dtmp.Y;
597 Ptot.Z += dtmp.Z;
598
599 // if(childPrim) we only know about physical linksets
600 return Ptot;
601/*
602 float tmass = _mass;
603 Ptot *= tmass;
604
605 float m;
606
607 foreach (OdePrim prm in childrenPrim)
608 {
609 m = prm._mass;
610 Ptot += prm.CenterOfMass * m;
611 tmass += m;
612 }
613
614 if (tmass == 0)
615 tmass = 0;
616 else
617 tmass = 1.0f / tmass;
618
619 Ptot *= tmass;
620 return Ptot;
621*/
622 }
623 else
624 return _position;
625 }
626 }
627 }
628
629 public override PrimitiveBaseShape Shape
630 {
631 set
632 {
633// AddChange(changes.Shape, value);
634 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, value, _size, m_fakeShapetype);
635 }
636 }
637
638 public override byte PhysicsShapeType
639 {
640 get
641 {
642 return m_fakeShapetype;
643 }
644 set
645 {
646 m_fakeShapetype = value;
647 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, _size, value);
648 }
649 }
650
651 public override Vector3 rootVelocity
652 {
653 get
654 {
655 if(_parent != null)
656 return ((OdePrim)_parent).Velocity;
657 return Velocity;
658 }
659 }
660
661 public override Vector3 Velocity
662 {
663 get
664 {
665 if (_zeroFlag)
666 return Vector3.Zero;
667 return _velocity;
668 }
669 set
670 {
671 if (value.IsFinite())
672 {
673 if(m_outbounds)
674 _velocity = value;
675 else
676 AddChange(changes.Velocity, value);
677 }
678 else
679 {
680 m_log.WarnFormat("[PHYSICS]: Got NaN Velocity in Object {0}", Name);
681 }
682 }
683 }
684
685 public override Vector3 Torque
686 {
687 get
688 {
689 if (!IsPhysical || Body == IntPtr.Zero)
690 return Vector3.Zero;
691
692 return m_torque;
693 }
694
695 set
696 {
697 if (value.IsFinite())
698 {
699 AddChange(changes.Torque, value);
700 }
701 else
702 {
703 m_log.WarnFormat("[PHYSICS]: Got NaN Torque in Object {0}", Name);
704 }
705 }
706 }
707
708 public override float CollisionScore
709 {
710 get { return m_collisionscore; }
711 set { m_collisionscore = value; }
712 }
713
714 public override bool Kinematic
715 {
716 get { return false; }
717 set { }
718 }
719
720 public override Quaternion Orientation
721 {
722 get
723 {
724 if (givefakeori > 0)
725 return fakeori;
726 else
727
728 return _orientation;
729 }
730 set
731 {
732 if (QuaternionIsFinite(value))
733 {
734 fakeori = value;
735 givefakeori++;
736
737 value.Normalize();
738
739 AddChange(changes.Orientation, value);
740 }
741 else
742 m_log.WarnFormat("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object {0}", Name);
743
744 }
745 }
746
747 public override Vector3 Acceleration
748 {
749 get { return m_acceleration; }
750 set
751 {
752 if(m_outbounds)
753 m_acceleration = value;
754 }
755 }
756
757 public override Vector3 RotationalVelocity
758 {
759 get
760 {
761 Vector3 pv = Vector3.Zero;
762 if (_zeroFlag)
763 return pv;
764
765 if (m_rotationalVelocity.ApproxEquals(pv, 0.0001f))
766 return pv;
767
768 return m_rotationalVelocity;
769 }
770 set
771 {
772 if (value.IsFinite())
773 {
774 if(m_outbounds)
775 m_rotationalVelocity = value;
776 else
777 AddChange(changes.AngVelocity, value);
778 }
779 else
780 {
781 m_log.WarnFormat("[PHYSICS]: Got NaN RotationalVelocity in Object {0}", Name);
782 }
783 }
784 }
785
786 public override float Buoyancy
787 {
788 get { return m_buoyancy; }
789 set
790 {
791 AddChange(changes.Buoyancy,value);
792 }
793 }
794
795 public override bool FloatOnWater
796 {
797 set
798 {
799 AddChange(changes.CollidesWater, value);
800 }
801 }
802
803 public override Vector3 PIDTarget
804 {
805 set
806 {
807 if (value.IsFinite())
808 {
809 AddChange(changes.PIDTarget,value);
810 }
811 else
812 m_log.WarnFormat("[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name);
813 }
814 }
815
816 public override bool PIDActive
817 {
818 get
819 {
820 return m_usePID;
821 }
822 set
823 {
824 AddChange(changes.PIDActive,value);
825 }
826 }
827
828 public override float PIDTau
829 {
830 set
831 {
832 float tmp = 0;
833 if (value > 0)
834 {
835 float mint = (0.05f > m_timeStep ? 0.05f : m_timeStep);
836 if (value < mint)
837 tmp = mint;
838 else
839 tmp = value;
840 }
841 AddChange(changes.PIDTau,tmp);
842 }
843 }
844
845 public override float PIDHoverHeight
846 {
847 set
848 {
849 AddChange(changes.PIDHoverHeight,value);
850 }
851 }
852 public override bool PIDHoverActive
853 {
854 get
855 {
856 return m_useHoverPID;
857 }
858 set
859 {
860 AddChange(changes.PIDHoverActive, value);
861 }
862 }
863
864 public override PIDHoverType PIDHoverType
865 {
866 set
867 {
868 AddChange(changes.PIDHoverType,value);
869 }
870 }
871
872 public override float PIDHoverTau
873 {
874 set
875 {
876 float tmp =0;
877 if (value > 0)
878 {
879 float mint = (0.05f > m_timeStep ? 0.05f : m_timeStep);
880 if (value < mint)
881 tmp = mint;
882 else
883 tmp = value;
884 }
885 AddChange(changes.PIDHoverTau, tmp);
886 }
887 }
888
889 public override Quaternion APIDTarget { set { return; } }
890
891 public override bool APIDActive { set { return; } }
892
893 public override float APIDStrength { set { return; } }
894
895 public override float APIDDamping { set { return; } }
896
897 public override int VehicleType
898 {
899 // we may need to put a fake on this
900 get
901 {
902 if (m_vehicle == null)
903 return (int)Vehicle.TYPE_NONE;
904 else
905 return (int)m_vehicle.Type;
906 }
907 set
908 {
909 AddChange(changes.VehicleType, value);
910 }
911 }
912
913 public override void VehicleFloatParam(int param, float value)
914 {
915 strVehicleFloatParam fp = new strVehicleFloatParam();
916 fp.param = param;
917 fp.value = value;
918 AddChange(changes.VehicleFloatParam, fp);
919 }
920
921 public override void VehicleVectorParam(int param, Vector3 value)
922 {
923 strVehicleVectorParam fp = new strVehicleVectorParam();
924 fp.param = param;
925 fp.value = value;
926 AddChange(changes.VehicleVectorParam, fp);
927 }
928
929 public override void VehicleRotationParam(int param, Quaternion value)
930 {
931 strVehicleQuatParam fp = new strVehicleQuatParam();
932 fp.param = param;
933 fp.value = value;
934 AddChange(changes.VehicleRotationParam, fp);
935 }
936
937 public override void VehicleFlags(int param, bool value)
938 {
939 strVehicleBoolParam bp = new strVehicleBoolParam();
940 bp.param = param;
941 bp.value = value;
942 AddChange(changes.VehicleFlags, bp);
943 }
944
945 public override void SetVehicle(object vdata)
946 {
947 AddChange(changes.SetVehicle, vdata);
948 }
949 public void SetAcceleration(Vector3 accel)
950 {
951 m_acceleration = accel;
952 }
953
954 public override void AddForce(Vector3 force, bool pushforce)
955 {
956 if (force.IsFinite())
957 {
958 if(pushforce)
959 AddChange(changes.AddForce, force);
960 else // a impulse
961 AddChange(changes.AddForce, force * m_invTimeStep);
962 }
963 else
964 {
965 m_log.WarnFormat("[PHYSICS]: Got Invalid linear force vector from Scene in Object {0}", Name);
966 }
967 //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString());
968 }
969
970 public override void AddAngularForce(Vector3 force, bool pushforce)
971 {
972 if (force.IsFinite())
973 {
974// if(pushforce) for now applyrotationimpulse seems more happy applied as a force
975 AddChange(changes.AddAngForce, force);
976// else // a impulse
977// AddChange(changes.AddAngForce, force * m_invTimeStep);
978 }
979 else
980 {
981 m_log.WarnFormat("[PHYSICS]: Got Invalid Angular force vector from Scene in Object {0}", Name);
982 }
983 }
984
985 public override void CrossingFailure()
986 {
987 lock(_parent_scene.OdeLock)
988 {
989 if (m_outbounds)
990 {
991 _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f);
992 _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f);
993 _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f);
994
995 m_lastposition = _position;
996 _velocity.X = 0;
997 _velocity.Y = 0;
998 _velocity.Z = 0;
999
1000 d.AllocateODEDataForThread(0);
1001
1002 m_lastVelocity = _velocity;
1003 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
1004 m_vehicle.Stop();
1005
1006 if(Body != IntPtr.Zero)
1007 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
1008 if (prim_geom != IntPtr.Zero)
1009 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1010
1011 m_outbounds = false;
1012 changeDisable(false);
1013 base.RequestPhysicsterseUpdate();
1014 }
1015 }
1016 }
1017
1018 public override void CrossingStart()
1019 {
1020 lock(_parent_scene.OdeLock)
1021 {
1022 if (m_outbounds || childPrim)
1023 return;
1024
1025 m_outbounds = true;
1026
1027 m_lastposition = _position;
1028 m_lastorientation = _orientation;
1029
1030 d.AllocateODEDataForThread(0);
1031 if(Body != IntPtr.Zero)
1032 {
1033 d.Vector3 dtmp = d.BodyGetAngularVel(Body);
1034 m_rotationalVelocity.X = dtmp.X;
1035 m_rotationalVelocity.Y = dtmp.Y;
1036 m_rotationalVelocity.Z = dtmp.Z;
1037
1038 dtmp = d.BodyGetLinearVel(Body);
1039 _velocity.X = dtmp.X;
1040 _velocity.Y = dtmp.Y;
1041 _velocity.Z = dtmp.Z;
1042
1043 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
1044 d.BodySetAngularVel(Body, 0, 0, 0);
1045 }
1046 if(prim_geom != IntPtr.Zero)
1047 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1048 disableBodySoft(); // stop collisions
1049 UnSubscribeEvents();
1050 }
1051 }
1052
1053 public override void SetMomentum(Vector3 momentum)
1054 {
1055 }
1056
1057 public override void SetMaterial(int pMaterial)
1058 {
1059 m_material = pMaterial;
1060 mu = _parent_scene.m_materialContactsData[pMaterial].mu;
1061 bounce = _parent_scene.m_materialContactsData[pMaterial].bounce;
1062 }
1063
1064 public override float Density
1065 {
1066 get
1067 {
1068 return m_density * 100f;
1069 }
1070 set
1071 {
1072 float old = m_density;
1073 m_density = value / 100f;
1074 // if(m_density != old)
1075 // UpdatePrimBodyData();
1076 }
1077 }
1078 public override float GravModifier
1079 {
1080 get
1081 {
1082 return m_gravmod;
1083 }
1084 set
1085 {
1086 m_gravmod = value;
1087 if (m_vehicle != null)
1088 m_vehicle.GravMod = m_gravmod;
1089 }
1090 }
1091 public override float Friction
1092 {
1093 get
1094 {
1095 return mu;
1096 }
1097 set
1098 {
1099 mu = value;
1100 }
1101 }
1102
1103 public override float Restitution
1104 {
1105 get
1106 {
1107 return bounce;
1108 }
1109 set
1110 {
1111 bounce = value;
1112 }
1113 }
1114
1115 public void setPrimForRemoval()
1116 {
1117 AddChange(changes.Remove, null);
1118 }
1119
1120 public override void link(PhysicsActor obj)
1121 {
1122 AddChange(changes.Link, obj);
1123 }
1124
1125 public override void delink()
1126 {
1127 AddChange(changes.DeLink, null);
1128 }
1129
1130 public override void LockAngularMotion(byte axislock)
1131 {
1132// m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z);
1133 AddChange(changes.AngLock, axislock);
1134
1135 }
1136
1137 public override void SubscribeEvents(int ms)
1138 {
1139 m_eventsubscription = ms;
1140 m_cureventsubscription = 0;
1141 if (CollisionEventsThisFrame == null)
1142 CollisionEventsThisFrame = new CollisionEventUpdate();
1143 if (CollisionVDTCEventsThisFrame == null)
1144 CollisionVDTCEventsThisFrame = new CollisionEventUpdate();
1145 SentEmptyCollisionsEvent = false;
1146 }
1147
1148 public override void UnSubscribeEvents()
1149 {
1150 if (CollisionVDTCEventsThisFrame != null)
1151 {
1152 CollisionVDTCEventsThisFrame.Clear();
1153 CollisionVDTCEventsThisFrame = null;
1154 }
1155 if (CollisionEventsThisFrame != null)
1156 {
1157 CollisionEventsThisFrame.Clear();
1158 CollisionEventsThisFrame = null;
1159 }
1160 m_eventsubscription = 0;
1161 _parent_scene.RemoveCollisionEventReporting(this);
1162 }
1163
1164 public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
1165 {
1166 if (CollisionEventsThisFrame == null)
1167 CollisionEventsThisFrame = new CollisionEventUpdate();
1168
1169 CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
1170 _parent_scene.AddCollisionEventReporting(this);
1171 }
1172
1173 public override void AddVDTCCollisionEvent(uint CollidedWith, ContactPoint contact)
1174 {
1175 if (CollisionVDTCEventsThisFrame == null)
1176 CollisionVDTCEventsThisFrame = new CollisionEventUpdate();
1177
1178 CollisionVDTCEventsThisFrame.AddCollider(CollidedWith, contact);
1179 _parent_scene.AddCollisionEventReporting(this);
1180 }
1181
1182 internal void SleeperAddCollisionEvents()
1183 {
1184 if(CollisionEventsThisFrame != null && CollisionEventsThisFrame.m_objCollisionList.Count != 0)
1185 {
1186 foreach(KeyValuePair<uint,ContactPoint> kvp in CollisionEventsThisFrame.m_objCollisionList)
1187 {
1188 if(kvp.Key == 0)
1189 continue;
1190 OdePrim other = _parent_scene.getPrim(kvp.Key);
1191 if(other == null)
1192 continue;
1193 ContactPoint cp = kvp.Value;
1194 cp.SurfaceNormal = - cp.SurfaceNormal;
1195 cp.RelativeSpeed = -cp.RelativeSpeed;
1196 other.AddCollisionEvent(ParentActor.LocalID,cp);
1197 }
1198 }
1199 if(CollisionVDTCEventsThisFrame != null && CollisionVDTCEventsThisFrame.m_objCollisionList.Count != 0)
1200 {
1201 foreach(KeyValuePair<uint,ContactPoint> kvp in CollisionVDTCEventsThisFrame.m_objCollisionList)
1202 {
1203 OdePrim other = _parent_scene.getPrim(kvp.Key);
1204 if(other == null)
1205 continue;
1206 ContactPoint cp = kvp.Value;
1207 cp.SurfaceNormal = - cp.SurfaceNormal;
1208 cp.RelativeSpeed = -cp.RelativeSpeed;
1209 other.AddCollisionEvent(ParentActor.LocalID,cp);
1210 }
1211 }
1212 }
1213
1214 internal void clearSleeperCollisions()
1215 {
1216 if(CollisionVDTCEventsThisFrame != null && CollisionVDTCEventsThisFrame.Count >0 )
1217 CollisionVDTCEventsThisFrame.Clear();
1218 }
1219
1220 public void SendCollisions(int timestep)
1221 {
1222 if (m_cureventsubscription < 50000)
1223 m_cureventsubscription += timestep;
1224
1225
1226 if (m_cureventsubscription < m_eventsubscription)
1227 return;
1228
1229 if (CollisionEventsThisFrame == null)
1230 return;
1231
1232 int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count;
1233
1234 if (!SentEmptyCollisionsEvent || ncolisions > 0)
1235 {
1236 base.SendCollisionUpdate(CollisionEventsThisFrame);
1237 m_cureventsubscription = 0;
1238
1239 if (ncolisions == 0)
1240 {
1241 SentEmptyCollisionsEvent = true;
1242// _parent_scene.RemoveCollisionEventReporting(this);
1243 }
1244 else if(Body == IntPtr.Zero || (d.BodyIsEnabled(Body) && m_bodydisablecontrol >= 0 ))
1245 {
1246 SentEmptyCollisionsEvent = false;
1247 CollisionEventsThisFrame.Clear();
1248 }
1249 }
1250 }
1251
1252 public override bool SubscribedEvents()
1253 {
1254 if (m_eventsubscription > 0)
1255 return true;
1256 return false;
1257 }
1258
1259 public OdePrim(String primName, ODEScene parent_scene, Vector3 pos, Vector3 size,
1260 Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical,bool pisPhantom,byte _shapeType,uint plocalID)
1261 {
1262 _parent_scene = parent_scene;
1263
1264 Name = primName;
1265 m_localID = plocalID;
1266
1267 m_vehicle = null;
1268
1269 if (!pos.IsFinite())
1270 {
1271 pos = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f),
1272 parent_scene.GetTerrainHeightAtXY(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f)) + 0.5f);
1273 m_log.WarnFormat("[PHYSICS]: Got nonFinite Object create Position for {0}", Name);
1274 }
1275 _position = pos;
1276 givefakepos = 0;
1277
1278 m_timeStep = parent_scene.ODE_STEPSIZE;
1279 m_invTimeStep = 1f / m_timeStep;
1280
1281 m_density = parent_scene.geomDefaultDensity;
1282 m_body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
1283
1284 prim_geom = IntPtr.Zero;
1285 collide_geom = IntPtr.Zero;
1286 Body = IntPtr.Zero;
1287
1288 if (!size.IsFinite())
1289 {
1290 size = new Vector3(0.5f, 0.5f, 0.5f);
1291 m_log.WarnFormat("[PHYSICS]: Got nonFinite Object create Size for {0}", Name);
1292 }
1293
1294 if (size.X <= 0) size.X = 0.01f;
1295 if (size.Y <= 0) size.Y = 0.01f;
1296 if (size.Z <= 0) size.Z = 0.01f;
1297
1298 _size = size;
1299
1300 if (!QuaternionIsFinite(rotation))
1301 {
1302 rotation = Quaternion.Identity;
1303 m_log.WarnFormat("[PHYSICS]: Got nonFinite Object create Rotation for {0}", Name);
1304 }
1305
1306 _orientation = rotation;
1307 givefakeori = 0;
1308
1309 _pbs = pbs;
1310
1311 m_targetSpace = IntPtr.Zero;
1312
1313 if (pos.Z < 0)
1314 {
1315 m_isphysical = false;
1316 }
1317 else
1318 {
1319 m_isphysical = pisPhysical;
1320 }
1321 m_fakeisphysical = m_isphysical;
1322
1323 m_isVolumeDetect = false;
1324 m_fakeisVolumeDetect = false;
1325
1326 m_force = Vector3.Zero;
1327
1328 m_iscolliding = false;
1329 m_colliderfilter = 0;
1330 m_NoColide = false;
1331
1332 _triMeshData = IntPtr.Zero;
1333
1334 m_fakeShapetype = _shapeType;
1335
1336 m_lastdoneSelected = false;
1337 m_isSelected = false;
1338 m_delaySelect = false;
1339
1340 m_isphantom = pisPhantom;
1341 m_fakeisphantom = pisPhantom;
1342
1343 mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
1344 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
1345
1346 m_building = true; // control must set this to false when done
1347
1348 AddChange(changes.Add, null);
1349
1350 // get basic mass parameters
1351 ODEPhysRepData repData = _parent_scene.m_meshWorker.NewActorPhysRep(this, _pbs, _size, _shapeType);
1352
1353 primVolume = repData.volume;
1354 m_OBB = repData.OBB;
1355 m_OBBOffset = repData.OBBOffset;
1356
1357 UpdatePrimBodyData();
1358 }
1359
1360 private void resetCollisionAccounting()
1361 {
1362 m_collisionscore = 0;
1363 }
1364
1365 private void UpdateCollisionCatFlags()
1366 {
1367 if(m_isphysical && m_disabled)
1368 {
1369 m_collisionCategories = 0;
1370 m_collisionFlags = 0;
1371 }
1372
1373 else if (m_isSelected)
1374 {
1375 m_collisionCategories = CollisionCategories.Selected;
1376 m_collisionFlags = 0;
1377 }
1378
1379 else if (m_isVolumeDetect)
1380 {
1381 m_collisionCategories = CollisionCategories.VolumeDtc;
1382 if (m_isphysical)
1383 m_collisionFlags = CollisionCategories.Geom | CollisionCategories.Character;
1384 else
1385 m_collisionFlags = 0;
1386 }
1387 else if (m_isphantom)
1388 {
1389 m_collisionCategories = CollisionCategories.Phantom;
1390 if (m_isphysical)
1391 m_collisionFlags = CollisionCategories.Land;
1392 else
1393 m_collisionFlags = 0;
1394 }
1395 else
1396 {
1397 m_collisionCategories = CollisionCategories.Geom;
1398 if (m_isphysical)
1399 m_collisionFlags = m_default_collisionFlagsPhysical;
1400 else
1401 m_collisionFlags = m_default_collisionFlagsNotPhysical;
1402 }
1403 }
1404
1405 private void ApplyCollisionCatFlags()
1406 {
1407 if (prim_geom != IntPtr.Zero)
1408 {
1409 if (!childPrim && childrenPrim.Count > 0)
1410 {
1411 foreach (OdePrim prm in childrenPrim)
1412 {
1413 if (m_isphysical && m_disabled)
1414 {
1415 prm.m_collisionCategories = 0;
1416 prm.m_collisionFlags = 0;
1417 }
1418 else
1419 {
1420 // preserve some
1421 if (prm.m_isSelected)
1422 {
1423 prm.m_collisionCategories = CollisionCategories.Selected;
1424 prm.m_collisionFlags = 0;
1425 }
1426 else if (prm.m_isVolumeDetect)
1427 {
1428 prm.m_collisionCategories = CollisionCategories.VolumeDtc;
1429 if (m_isphysical)
1430 prm.m_collisionFlags = CollisionCategories.Geom | CollisionCategories.Character;
1431 else
1432 prm.m_collisionFlags = 0;
1433 }
1434 else if (prm.m_isphantom)
1435 {
1436 prm.m_collisionCategories = CollisionCategories.Phantom;
1437 if (m_isphysical)
1438 prm.m_collisionFlags = CollisionCategories.Land;
1439 else
1440 prm.m_collisionFlags = 0;
1441 }
1442 else
1443 {
1444 prm.m_collisionCategories = m_collisionCategories;
1445 prm.m_collisionFlags = m_collisionFlags;
1446 }
1447 }
1448
1449 if (prm.prim_geom != IntPtr.Zero)
1450 {
1451 if (prm.m_NoColide)
1452 {
1453 d.GeomSetCategoryBits(prm.prim_geom, 0);
1454 if (m_isphysical)
1455 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1456 else
1457 d.GeomSetCollideBits(prm.prim_geom, 0);
1458 }
1459 else
1460 {
1461 d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
1462 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
1463 }
1464 }
1465 }
1466 }
1467
1468 if (m_NoColide)
1469 {
1470 d.GeomSetCategoryBits(prim_geom, 0);
1471 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
1472 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
1473 {
1474 d.GeomSetCategoryBits(collide_geom, 0);
1475 d.GeomSetCollideBits(collide_geom, (uint)CollisionCategories.Land);
1476 }
1477 }
1478 else
1479 {
1480 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1481 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1482 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
1483 {
1484 d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories);
1485 d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags);
1486 }
1487 }
1488 }
1489 }
1490
1491 private void createAMotor(byte axislock)
1492 {
1493 if (Body == IntPtr.Zero)
1494 return;
1495
1496 if (Amotor != IntPtr.Zero)
1497 {
1498 d.JointDestroy(Amotor);
1499 Amotor = IntPtr.Zero;
1500 }
1501
1502 int axisnum = 0;
1503 bool axisX = false;
1504 bool axisY = false;
1505 bool axisZ = false;
1506 if((axislock & 0x02) != 0)
1507 {
1508 axisnum++;
1509 axisX = true;
1510 }
1511 if((axislock & 0x04) != 0)
1512 {
1513 axisnum++;
1514 axisY = true;
1515 }
1516 if((axislock & 0x08) != 0)
1517 {
1518 axisnum++;
1519 axisZ = true;
1520 }
1521
1522 if(axisnum == 0)
1523 return;
1524 // stop it
1525 d.BodySetTorque(Body, 0, 0, 0);
1526 d.BodySetAngularVel(Body, 0, 0, 0);
1527
1528 Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
1529 d.JointAttach(Amotor, Body, IntPtr.Zero);
1530
1531 d.JointSetAMotorMode(Amotor, 0);
1532
1533 d.JointSetAMotorNumAxes(Amotor, axisnum);
1534
1535 // get current orientation to lock
1536
1537 d.Quaternion dcur = d.BodyGetQuaternion(Body);
1538 Quaternion curr; // crap convertion between identical things
1539 curr.X = dcur.X;
1540 curr.Y = dcur.Y;
1541 curr.Z = dcur.Z;
1542 curr.W = dcur.W;
1543 Vector3 ax;
1544
1545 int i = 0;
1546 int j = 0;
1547 if (axisX)
1548 {
1549 ax = (new Vector3(1, 0, 0)) * curr; // rotate world X to current local X
1550 d.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z);
1551 d.JointSetAMotorAngle(Amotor, 0, 0);
1552 d.JointSetAMotorParam(Amotor, (int)d.JointParam.LoStop, 0f);
1553 d.JointSetAMotorParam(Amotor, (int)d.JointParam.HiStop, 0f);
1554 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
1555 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f);
1556 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f);
1557 d.JointSetAMotorParam(Amotor, (int)d.JointParam.CFM, 0f);
1558 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f);
1559 d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f);
1560 d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f);
1561 i++;
1562 j = 256; // move to next axis set
1563 }
1564
1565 if (axisY)
1566 {
1567 ax = (new Vector3(0, 1, 0)) * curr;
1568 d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z);
1569 d.JointSetAMotorAngle(Amotor, i, 0);
1570 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f);
1571 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f);
1572 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0);
1573 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
1574 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
1575 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f);
1576 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
1577 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
1578 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
1579 i++;
1580 j += 256;
1581 }
1582
1583 if (axisZ)
1584 {
1585 ax = (new Vector3(0, 0, 1)) * curr;
1586 d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z);
1587 d.JointSetAMotorAngle(Amotor, i, 0);
1588 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f);
1589 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f);
1590 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0);
1591 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
1592 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
1593 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f);
1594 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
1595 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
1596 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
1597 }
1598 }
1599
1600
1601 private void SetGeom(IntPtr geom)
1602 {
1603 prim_geom = geom;
1604 //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
1605 if (prim_geom != IntPtr.Zero)
1606 {
1607
1608 if (m_NoColide)
1609 {
1610 d.GeomSetCategoryBits(prim_geom, 0);
1611 if (m_isphysical)
1612 {
1613 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
1614 }
1615 else
1616 {
1617 d.GeomSetCollideBits(prim_geom, 0);
1618 d.GeomDisable(prim_geom);
1619 }
1620 }
1621 else
1622 {
1623 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1624 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1625 }
1626
1627 UpdatePrimBodyData();
1628 _parent_scene.actor_name_map[prim_geom] = this;
1629
1630/*
1631// debug
1632 d.AABB aabb;
1633 d.GeomGetAABB(prim_geom, out aabb);
1634 float x = aabb.MaxX - aabb.MinX;
1635 float y = aabb.MaxY - aabb.MinY;
1636 float z = aabb.MaxZ - aabb.MinZ;
1637 if( x > 60.0f || y > 60.0f || z > 60.0f)
1638 m_log.WarnFormat("[PHYSICS]: large prim geo {0},size {1}, AABBsize <{2},{3},{4}, mesh {5} at {6}",
1639 Name, _size.ToString(), x, y, z, _pbs.SculptEntry ? _pbs.SculptTexture.ToString() : "primMesh", _position.ToString());
1640 else if (x < 0.001f || y < 0.001f || z < 0.001f)
1641 m_log.WarnFormat("[PHYSICS]: small prim geo {0},size {1}, AABBsize <{2},{3},{4}, mesh {5} at {6}",
1642 Name, _size.ToString(), x, y, z, _pbs.SculptEntry ? _pbs.SculptTexture.ToString() : "primMesh", _position.ToString());
1643*/
1644
1645 }
1646 else
1647 m_log.Warn("Setting bad Geom");
1648 }
1649
1650 private bool GetMeshGeom()
1651 {
1652 IntPtr vertices, indices;
1653 int vertexCount, indexCount;
1654 int vertexStride, triStride;
1655
1656 IMesh mesh = m_mesh;
1657
1658 if (mesh == null)
1659 return false;
1660
1661 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
1662 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
1663
1664 if (vertexCount == 0 || indexCount == 0)
1665 {
1666 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on OdePrim {0}, mesh {1} at {2}",
1667 Name, _pbs.SculptEntry ? _pbs.SculptTexture.ToString() : "primMesh",_position.ToString());
1668
1669 m_hasOBB = false;
1670 m_OBBOffset = Vector3.Zero;
1671 m_OBB = _size * 0.5f;
1672
1673 m_physCost = 0.1f;
1674 m_streamCost = 1.0f;
1675
1676 _parent_scene.mesher.ReleaseMesh(mesh);
1677 m_meshState = MeshState.MeshFailed;
1678 m_mesh = null;
1679 return false;
1680 }
1681
1682 if (vertexCount > 64000 || indexCount > 64000)
1683 {
1684 m_log.WarnFormat("[PHYSICS]: large mesh data on OdePrim {0}, mesh {1} at {2}, {3} vertices, {4} indexes",
1685 Name, _pbs.SculptEntry ? _pbs.SculptTexture.ToString() : "primMesh",
1686 _position.ToString() ,vertexCount , indexCount );
1687 }
1688 IntPtr geo = IntPtr.Zero;
1689
1690 try
1691 {
1692 _triMeshData = d.GeomTriMeshDataCreate();
1693
1694 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1695 d.GeomTriMeshDataPreprocess(_triMeshData);
1696
1697 geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
1698 }
1699
1700 catch (Exception e)
1701 {
1702 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e);
1703 if (_triMeshData != IntPtr.Zero)
1704 {
1705 try
1706 {
1707 d.GeomTriMeshDataDestroy(_triMeshData);
1708 }
1709 catch
1710 {
1711 }
1712 }
1713 _triMeshData = IntPtr.Zero;
1714
1715 m_hasOBB = false;
1716 m_OBBOffset = Vector3.Zero;
1717 m_OBB = _size * 0.5f;
1718 m_physCost = 0.1f;
1719 m_streamCost = 1.0f;
1720
1721 _parent_scene.mesher.ReleaseMesh(mesh);
1722 m_meshState = MeshState.MeshFailed;
1723 m_mesh = null;
1724 return false;
1725 }
1726
1727 m_physCost = 0.0013f * (float)indexCount;
1728 // todo
1729 m_streamCost = 1.0f;
1730
1731 SetGeom(geo);
1732
1733 return true;
1734 }
1735
1736 private void CreateGeom(bool OverrideToBox)
1737 {
1738 bool hasMesh = false;
1739
1740 m_NoColide = false;
1741
1742 if ((m_meshState & MeshState.MeshNoColide) != 0)
1743 m_NoColide = true;
1744
1745 else if(!OverrideToBox && m_mesh != null)
1746 {
1747 if (GetMeshGeom())
1748 hasMesh = true;
1749 else
1750 m_NoColide = true;
1751 }
1752
1753
1754 if (!hasMesh)
1755 {
1756 IntPtr geo = IntPtr.Zero;
1757
1758 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
1759 && _size.X == _size.Y && _size.Y == _size.Z)
1760 { // it's a sphere
1761 try
1762 {
1763 geo = d.CreateSphere(m_targetSpace, _size.X * 0.5f);
1764 }
1765 catch (Exception e)
1766 {
1767 m_log.WarnFormat("[PHYSICS]: Create sphere failed: {0}", e);
1768 return;
1769 }
1770 }
1771 else
1772 {// do it as a box
1773 try
1774 {
1775 geo = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1776 }
1777 catch (Exception e)
1778 {
1779 m_log.Warn("[PHYSICS]: Create box failed: {0}", e);
1780 return;
1781 }
1782 }
1783 m_physCost = 0.1f;
1784 m_streamCost = 1.0f;
1785 SetGeom(geo);
1786 }
1787 }
1788
1789 private void RemoveGeom()
1790 {
1791 if (prim_geom != IntPtr.Zero)
1792 {
1793 _parent_scene.actor_name_map.Remove(prim_geom);
1794
1795 try
1796 {
1797 d.GeomDestroy(prim_geom);
1798 if (_triMeshData != IntPtr.Zero)
1799 {
1800 d.GeomTriMeshDataDestroy(_triMeshData);
1801 _triMeshData = IntPtr.Zero;
1802 }
1803 }
1804 catch (Exception e)
1805 {
1806 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e);
1807 }
1808
1809 prim_geom = IntPtr.Zero;
1810 collide_geom = IntPtr.Zero;
1811 m_targetSpace = IntPtr.Zero;
1812 }
1813 else
1814 {
1815 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name);
1816 }
1817
1818 lock (m_meshlock)
1819 {
1820 if (m_mesh != null)
1821 {
1822 _parent_scene.mesher.ReleaseMesh(m_mesh);
1823 m_mesh = null;
1824 }
1825 }
1826
1827 Body = IntPtr.Zero;
1828 m_hasOBB = false;
1829 }
1830
1831 //sets non physical prim m_targetSpace to right space in spaces grid for static prims
1832 // should only be called for non physical prims unless they are becoming non physical
1833 private void SetInStaticSpace(OdePrim prim)
1834 {
1835 IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace);
1836 prim.m_targetSpace = targetSpace;
1837 collide_geom = IntPtr.Zero;
1838 }
1839
1840 public void enableBodySoft()
1841 {
1842 m_disabled = false;
1843 if (!childPrim && !m_isSelected)
1844 {
1845 if (m_isphysical && Body != IntPtr.Zero)
1846 {
1847 UpdateCollisionCatFlags();
1848 ApplyCollisionCatFlags();
1849
1850 _zeroFlag = true;
1851 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
1852 d.BodyEnable(Body);
1853 }
1854 }
1855 resetCollisionAccounting();
1856 }
1857
1858 private void disableBodySoft()
1859 {
1860 m_disabled = true;
1861 if (!childPrim)
1862 {
1863 if (m_isphysical && Body != IntPtr.Zero)
1864 {
1865 if (m_isSelected)
1866 m_collisionFlags = CollisionCategories.Selected;
1867 else
1868 m_collisionCategories = 0;
1869 m_collisionFlags = 0;
1870 ApplyCollisionCatFlags();
1871 d.BodyDisable(Body);
1872 }
1873 }
1874 }
1875
1876 private void MakeBody()
1877 {
1878 if (!m_isphysical) // only physical get bodies
1879 return;
1880
1881 if (childPrim) // child prims don't get bodies;
1882 return;
1883
1884 if (m_building)
1885 return;
1886
1887 if (prim_geom == IntPtr.Zero)
1888 {
1889 m_log.Warn("[PHYSICS]: Unable to link the linkset. Root has no geom yet");
1890 return;
1891 }
1892
1893 if (Body != IntPtr.Zero)
1894 {
1895 DestroyBody();
1896 m_log.Warn("[PHYSICS]: MakeBody called having a body");
1897 }
1898
1899 if (d.GeomGetBody(prim_geom) != IntPtr.Zero)
1900 {
1901 d.GeomSetBody(prim_geom, IntPtr.Zero);
1902 m_log.Warn("[PHYSICS]: MakeBody root geom already had a body");
1903 }
1904
1905 bool noInertiaOverride = (m_InertiaOverride == null);
1906
1907 Body = d.BodyCreate(_parent_scene.world);
1908
1909 d.Matrix3 mymat = new d.Matrix3();
1910 d.Quaternion myrot = new d.Quaternion();
1911 d.Mass objdmass = new d.Mass { };
1912
1913 myrot.X = _orientation.X;
1914 myrot.Y = _orientation.Y;
1915 myrot.Z = _orientation.Z;
1916 myrot.W = _orientation.W;
1917 d.RfromQ(out mymat, ref myrot);
1918
1919 // set the body rotation
1920 d.BodySetRotation(Body, ref mymat);
1921
1922 if(noInertiaOverride)
1923 {
1924 objdmass = primdMass;
1925 d.MassRotate(ref objdmass, ref mymat);
1926 }
1927
1928 // recompute full object inertia if needed
1929 if (childrenPrim.Count > 0)
1930 {
1931 d.Matrix3 mat = new d.Matrix3();
1932 d.Quaternion quat = new d.Quaternion();
1933 d.Mass tmpdmass = new d.Mass { };
1934 Vector3 rcm;
1935
1936 rcm.X = _position.X;
1937 rcm.Y = _position.Y;
1938 rcm.Z = _position.Z;
1939
1940 lock (childrenPrim)
1941 {
1942 foreach (OdePrim prm in childrenPrim)
1943 {
1944 if (prm.prim_geom == IntPtr.Zero)
1945 {
1946 m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements, skipping it. No geom yet");
1947 continue;
1948 }
1949
1950 quat.X = prm._orientation.X;
1951 quat.Y = prm._orientation.Y;
1952 quat.Z = prm._orientation.Z;
1953 quat.W = prm._orientation.W;
1954 d.RfromQ(out mat, ref quat);
1955
1956 // fix prim colision cats
1957
1958 if (d.GeomGetBody(prm.prim_geom) != IntPtr.Zero)
1959 {
1960 d.GeomSetBody(prm.prim_geom, IntPtr.Zero);
1961 m_log.Warn("[PHYSICS]: MakeBody child geom already had a body");
1962 }
1963
1964 d.GeomClearOffset(prm.prim_geom);
1965 d.GeomSetBody(prm.prim_geom, Body);
1966 prm.Body = Body;
1967 d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation
1968
1969 if(noInertiaOverride)
1970 {
1971 tmpdmass = prm.primdMass;
1972
1973 d.MassRotate(ref tmpdmass, ref mat);
1974 Vector3 ppos = prm._position;
1975 ppos.X -= rcm.X;
1976 ppos.Y -= rcm.Y;
1977 ppos.Z -= rcm.Z;
1978 // refer inertia to root prim center of mass position
1979 d.MassTranslate(ref tmpdmass,
1980 ppos.X,
1981 ppos.Y,
1982 ppos.Z);
1983
1984 d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia
1985 }
1986 }
1987 }
1988 }
1989
1990 d.GeomClearOffset(prim_geom); // make sure we don't have a hidden offset
1991 // associate root geom with body
1992 d.GeomSetBody(prim_geom, Body);
1993
1994 if(noInertiaOverride)
1995 d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z);
1996 else
1997 {
1998 Vector3 ncm = m_InertiaOverride.CenterOfMass * _orientation;
1999 d.BodySetPosition(Body,
2000 _position.X + ncm.X,
2001 _position.Y + ncm.Y,
2002 _position.Z + ncm.Z);
2003 }
2004
2005 d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z);
2006
2007 if(noInertiaOverride)
2008 {
2009 d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body
2010 myrot.X = -myrot.X;
2011 myrot.Y = -myrot.Y;
2012 myrot.Z = -myrot.Z;
2013
2014 d.RfromQ(out mymat, ref myrot);
2015 d.MassRotate(ref objdmass, ref mymat);
2016
2017 d.BodySetMass(Body, ref objdmass);
2018 m_mass = objdmass.mass;
2019 }
2020 else
2021 {
2022 objdmass.c.X = 0;
2023 objdmass.c.Y = 0;
2024 objdmass.c.Z = 0;
2025
2026 objdmass.I.M00 = m_InertiaOverride.Inertia.X;
2027 objdmass.I.M11 = m_InertiaOverride.Inertia.Y;
2028 objdmass.I.M22 = m_InertiaOverride.Inertia.Z;
2029
2030 objdmass.mass = m_InertiaOverride.TotalMass;
2031
2032 if(Math.Abs(m_InertiaOverride.InertiaRotation.W) < 0.999)
2033 {
2034 d.Matrix3 inertiarotmat = new d.Matrix3();
2035 d.Quaternion inertiarot = new d.Quaternion();
2036
2037 inertiarot.X = m_InertiaOverride.InertiaRotation.X;
2038 inertiarot.Y = m_InertiaOverride.InertiaRotation.Y;
2039 inertiarot.Z = m_InertiaOverride.InertiaRotation.Z;
2040 inertiarot.W = m_InertiaOverride.InertiaRotation.W;
2041 d.RfromQ(out inertiarotmat, ref inertiarot);
2042 d.MassRotate(ref objdmass, ref inertiarotmat);
2043 }
2044 d.BodySetMass(Body, ref objdmass);
2045
2046 m_mass = objdmass.mass;
2047 }
2048
2049 // disconnect from world gravity so we can apply buoyancy
2050 d.BodySetGravityMode(Body, false);
2051
2052 d.BodySetAutoDisableFlag(Body, true);
2053 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
2054 d.BodySetAutoDisableAngularThreshold(Body, 0.05f);
2055 d.BodySetAutoDisableLinearThreshold(Body, 0.05f);
2056 d.BodySetDamping(Body, .004f, .001f);
2057
2058 if (m_targetSpace != IntPtr.Zero)
2059 {
2060 _parent_scene.waitForSpaceUnlock(m_targetSpace);
2061 if (d.SpaceQuery(m_targetSpace, prim_geom))
2062 d.SpaceRemove(m_targetSpace, prim_geom);
2063 }
2064
2065 if (childrenPrim.Count == 0)
2066 {
2067 collide_geom = prim_geom;
2068 m_targetSpace = _parent_scene.ActiveSpace;
2069 }
2070 else
2071 {
2072 m_targetSpace = d.HashSpaceCreate(_parent_scene.ActiveSpace);
2073 d.HashSpaceSetLevels(m_targetSpace, -2, 8);
2074 d.SpaceSetSublevel(m_targetSpace, 3);
2075 d.SpaceSetCleanup(m_targetSpace, false);
2076
2077 d.GeomSetCategoryBits(m_targetSpace, (uint)(CollisionCategories.Space |
2078 CollisionCategories.Geom |
2079 CollisionCategories.Phantom |
2080 CollisionCategories.VolumeDtc
2081 ));
2082 d.GeomSetCollideBits(m_targetSpace, 0);
2083 collide_geom = m_targetSpace;
2084 }
2085
2086 d.SpaceAdd(m_targetSpace, prim_geom);
2087
2088 if (m_delaySelect)
2089 {
2090 m_isSelected = true;
2091 m_delaySelect = false;
2092 }
2093
2094 m_collisionscore = 0;
2095
2096 UpdateCollisionCatFlags();
2097 ApplyCollisionCatFlags();
2098
2099 _parent_scene.addActivePrim(this);
2100
2101 lock (childrenPrim)
2102 {
2103 foreach (OdePrim prm in childrenPrim)
2104 {
2105 if (prm.prim_geom == IntPtr.Zero)
2106 continue;
2107
2108 Vector3 ppos = prm._position;
2109 d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position
2110
2111 if (prm.m_targetSpace != m_targetSpace)
2112 {
2113 if (prm.m_targetSpace != IntPtr.Zero)
2114 {
2115 _parent_scene.waitForSpaceUnlock(prm.m_targetSpace);
2116 if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom))
2117 d.SpaceRemove(prm.m_targetSpace, prm.prim_geom);
2118 }
2119 prm.m_targetSpace = m_targetSpace;
2120 d.SpaceAdd(m_targetSpace, prm.prim_geom);
2121 }
2122
2123 prm.m_collisionscore = 0;
2124
2125 if(!m_disabled)
2126 prm.m_disabled = false;
2127
2128 _parent_scene.addActivePrim(prm);
2129 }
2130 }
2131
2132 // The body doesn't already have a finite rotation mode set here
2133 if (m_angularlocks != 0 && _parent == null)
2134 {
2135 createAMotor(m_angularlocks);
2136 }
2137
2138 if (m_isSelected || m_disabled)
2139 {
2140 d.BodyDisable(Body);
2141 _zeroFlag = true;
2142 }
2143 else
2144 {
2145 d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z);
2146 d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
2147
2148 _zeroFlag = false;
2149 m_bodydisablecontrol = 0;
2150 }
2151 _parent_scene.addActiveGroups(this);
2152 }
2153
2154 private void DestroyBody()
2155 {
2156 if (Body != IntPtr.Zero)
2157 {
2158 _parent_scene.remActivePrim(this);
2159
2160 collide_geom = IntPtr.Zero;
2161
2162 if (m_disabled)
2163 m_collisionCategories = 0;
2164 else if (m_isSelected)
2165 m_collisionCategories = CollisionCategories.Selected;
2166 else if (m_isVolumeDetect)
2167 m_collisionCategories = CollisionCategories.VolumeDtc;
2168 else if (m_isphantom)
2169 m_collisionCategories = CollisionCategories.Phantom;
2170 else
2171 m_collisionCategories = CollisionCategories.Geom;
2172
2173 m_collisionFlags = 0;
2174
2175 if (prim_geom != IntPtr.Zero)
2176 {
2177 if (m_NoColide)
2178 {
2179 d.GeomSetCategoryBits(prim_geom, 0);
2180 d.GeomSetCollideBits(prim_geom, 0);
2181 }
2182 else
2183 {
2184 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
2185 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
2186 }
2187 UpdateDataFromGeom();
2188 d.GeomSetBody(prim_geom, IntPtr.Zero);
2189 SetInStaticSpace(this);
2190 }
2191
2192 if (!childPrim)
2193 {
2194 lock (childrenPrim)
2195 {
2196 foreach (OdePrim prm in childrenPrim)
2197 {
2198 _parent_scene.remActivePrim(prm);
2199
2200 if (prm.m_isSelected)
2201 prm.m_collisionCategories = CollisionCategories.Selected;
2202 else if (prm.m_isVolumeDetect)
2203 prm.m_collisionCategories = CollisionCategories.VolumeDtc;
2204 else if (prm.m_isphantom)
2205 prm.m_collisionCategories = CollisionCategories.Phantom;
2206 else
2207 prm.m_collisionCategories = CollisionCategories.Geom;
2208
2209 prm.m_collisionFlags = 0;
2210
2211 if (prm.prim_geom != IntPtr.Zero)
2212 {
2213 if (prm.m_NoColide)
2214 {
2215 d.GeomSetCategoryBits(prm.prim_geom, 0);
2216 d.GeomSetCollideBits(prm.prim_geom, 0);
2217 }
2218 else
2219 {
2220 d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
2221 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
2222 }
2223 prm.UpdateDataFromGeom();
2224 SetInStaticSpace(prm);
2225 }
2226 prm.Body = IntPtr.Zero;
2227 prm.m_mass = prm.primMass;
2228 prm.m_collisionscore = 0;
2229 }
2230 }
2231 if (Amotor != IntPtr.Zero)
2232 {
2233 d.JointDestroy(Amotor);
2234 Amotor = IntPtr.Zero;
2235 }
2236 _parent_scene.remActiveGroup(this);
2237 d.BodyDestroy(Body);
2238 }
2239 Body = IntPtr.Zero;
2240 }
2241 m_mass = primMass;
2242 m_collisionscore = 0;
2243 }
2244
2245 private void FixInertia(Vector3 NewPos,Quaternion newrot)
2246 {
2247 d.Matrix3 mat = new d.Matrix3();
2248 d.Quaternion quat = new d.Quaternion();
2249
2250 d.Mass tmpdmass = new d.Mass { };
2251 d.Mass objdmass = new d.Mass { };
2252
2253 d.BodyGetMass(Body, out tmpdmass);
2254 objdmass = tmpdmass;
2255
2256 d.Vector3 dobjpos;
2257 d.Vector3 thispos;
2258
2259 // get current object position and rotation
2260 dobjpos = d.BodyGetPosition(Body);
2261
2262 // get prim own inertia in its local frame
2263 tmpdmass = primdMass;
2264
2265 // transform to object frame
2266 mat = d.GeomGetOffsetRotation(prim_geom);
2267 d.MassRotate(ref tmpdmass, ref mat);
2268
2269 thispos = d.GeomGetOffsetPosition(prim_geom);
2270 d.MassTranslate(ref tmpdmass,
2271 thispos.X,
2272 thispos.Y,
2273 thispos.Z);
2274
2275 // subtract current prim inertia from object
2276 DMassSubPartFromObj(ref tmpdmass, ref objdmass);
2277
2278 // back prim own inertia
2279 tmpdmass = primdMass;
2280
2281 // update to new position and orientation
2282 _position = NewPos;
2283 d.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z);
2284 _orientation = newrot;
2285 quat.X = newrot.X;
2286 quat.Y = newrot.Y;
2287 quat.Z = newrot.Z;
2288 quat.W = newrot.W;
2289 d.GeomSetOffsetWorldQuaternion(prim_geom, ref quat);
2290
2291 mat = d.GeomGetOffsetRotation(prim_geom);
2292 d.MassRotate(ref tmpdmass, ref mat);
2293
2294 thispos = d.GeomGetOffsetPosition(prim_geom);
2295 d.MassTranslate(ref tmpdmass,
2296 thispos.X,
2297 thispos.Y,
2298 thispos.Z);
2299
2300 d.MassAdd(ref objdmass, ref tmpdmass);
2301
2302 // fix all positions
2303 IntPtr g = d.BodyGetFirstGeom(Body);
2304 while (g != IntPtr.Zero)
2305 {
2306 thispos = d.GeomGetOffsetPosition(g);
2307 thispos.X -= objdmass.c.X;
2308 thispos.Y -= objdmass.c.Y;
2309 thispos.Z -= objdmass.c.Z;
2310 d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z);
2311 g = d.dBodyGetNextGeom(g);
2312 }
2313 d.BodyVectorToWorld(Body,objdmass.c.X, objdmass.c.Y, objdmass.c.Z,out thispos);
2314
2315 d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z);
2316 d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body
2317 d.BodySetMass(Body, ref objdmass);
2318 m_mass = objdmass.mass;
2319 }
2320
2321 private void FixInertia(Vector3 NewPos)
2322 {
2323 d.Matrix3 primmat = new d.Matrix3();
2324 d.Mass tmpdmass = new d.Mass { };
2325 d.Mass objdmass = new d.Mass { };
2326 d.Mass primmass = new d.Mass { };
2327
2328 d.Vector3 dobjpos;
2329 d.Vector3 thispos;
2330
2331 d.BodyGetMass(Body, out objdmass);
2332
2333 // get prim own inertia in its local frame
2334 primmass = primdMass;
2335 // transform to object frame
2336 primmat = d.GeomGetOffsetRotation(prim_geom);
2337 d.MassRotate(ref primmass, ref primmat);
2338
2339 tmpdmass = primmass;
2340
2341 thispos = d.GeomGetOffsetPosition(prim_geom);
2342 d.MassTranslate(ref tmpdmass,
2343 thispos.X,
2344 thispos.Y,
2345 thispos.Z);
2346
2347 // subtract current prim inertia from object
2348 DMassSubPartFromObj(ref tmpdmass, ref objdmass);
2349
2350 // update to new position
2351 _position = NewPos;
2352 d.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z);
2353
2354 thispos = d.GeomGetOffsetPosition(prim_geom);
2355 d.MassTranslate(ref primmass,
2356 thispos.X,
2357 thispos.Y,
2358 thispos.Z);
2359
2360 d.MassAdd(ref objdmass, ref primmass);
2361
2362 // fix all positions
2363 IntPtr g = d.BodyGetFirstGeom(Body);
2364 while (g != IntPtr.Zero)
2365 {
2366 thispos = d.GeomGetOffsetPosition(g);
2367 thispos.X -= objdmass.c.X;
2368 thispos.Y -= objdmass.c.Y;
2369 thispos.Z -= objdmass.c.Z;
2370 d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z);
2371 g = d.dBodyGetNextGeom(g);
2372 }
2373
2374 d.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos);
2375
2376 // get current object position and rotation
2377 dobjpos = d.BodyGetPosition(Body);
2378
2379 d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z);
2380 d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body
2381 d.BodySetMass(Body, ref objdmass);
2382 m_mass = objdmass.mass;
2383 }
2384
2385 private void FixInertia(Quaternion newrot)
2386 {
2387 d.Matrix3 mat = new d.Matrix3();
2388 d.Quaternion quat = new d.Quaternion();
2389
2390 d.Mass tmpdmass = new d.Mass { };
2391 d.Mass objdmass = new d.Mass { };
2392 d.Vector3 dobjpos;
2393 d.Vector3 thispos;
2394
2395 d.BodyGetMass(Body, out objdmass);
2396
2397 // get prim own inertia in its local frame
2398 tmpdmass = primdMass;
2399 mat = d.GeomGetOffsetRotation(prim_geom);
2400 d.MassRotate(ref tmpdmass, ref mat);
2401 // transform to object frame
2402 thispos = d.GeomGetOffsetPosition(prim_geom);
2403 d.MassTranslate(ref tmpdmass,
2404 thispos.X,
2405 thispos.Y,
2406 thispos.Z);
2407
2408 // subtract current prim inertia from object
2409 DMassSubPartFromObj(ref tmpdmass, ref objdmass);
2410
2411 // update to new orientation
2412 _orientation = newrot;
2413 quat.X = newrot.X;
2414 quat.Y = newrot.Y;
2415 quat.Z = newrot.Z;
2416 quat.W = newrot.W;
2417 d.GeomSetOffsetWorldQuaternion(prim_geom, ref quat);
2418
2419 tmpdmass = primdMass;
2420 mat = d.GeomGetOffsetRotation(prim_geom);
2421 d.MassRotate(ref tmpdmass, ref mat);
2422 d.MassTranslate(ref tmpdmass,
2423 thispos.X,
2424 thispos.Y,
2425 thispos.Z);
2426
2427 d.MassAdd(ref objdmass, ref tmpdmass);
2428
2429 // fix all positions
2430 IntPtr g = d.BodyGetFirstGeom(Body);
2431 while (g != IntPtr.Zero)
2432 {
2433 thispos = d.GeomGetOffsetPosition(g);
2434 thispos.X -= objdmass.c.X;
2435 thispos.Y -= objdmass.c.Y;
2436 thispos.Z -= objdmass.c.Z;
2437 d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z);
2438 g = d.dBodyGetNextGeom(g);
2439 }
2440
2441 d.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos);
2442 // get current object position and rotation
2443 dobjpos = d.BodyGetPosition(Body);
2444
2445 d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z);
2446 d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body
2447 d.BodySetMass(Body, ref objdmass);
2448 m_mass = objdmass.mass;
2449 }
2450
2451
2452 #region Mass Calculation
2453
2454 private void UpdatePrimBodyData()
2455 {
2456 primMass = m_density * primVolume;
2457
2458 if (primMass <= 0)
2459 primMass = 0.0001f;//ckrinke: Mass must be greater then zero.
2460 if (primMass > _parent_scene.maximumMassObject)
2461 primMass = _parent_scene.maximumMassObject;
2462
2463 m_mass = primMass; // just in case
2464
2465 d.MassSetBoxTotal(out primdMass, primMass, 2.0f * m_OBB.X, 2.0f * m_OBB.Y, 2.0f * m_OBB.Z);
2466
2467 d.MassTranslate(ref primdMass,
2468 m_OBBOffset.X,
2469 m_OBBOffset.Y,
2470 m_OBBOffset.Z);
2471
2472 primOOBradiusSQ = m_OBB.LengthSquared();
2473
2474 if (_triMeshData != IntPtr.Zero)
2475 {
2476 float pc = m_physCost;
2477 float psf = primOOBradiusSQ;
2478 psf *= 1.33f * .2f;
2479 pc *= psf;
2480 if (pc < 0.1f)
2481 pc = 0.1f;
2482
2483 m_physCost = pc;
2484 }
2485 else
2486 m_physCost = 0.1f;
2487
2488 m_streamCost = 1.0f;
2489 }
2490
2491 #endregion
2492
2493
2494 /// <summary>
2495 /// Add a child prim to this parent prim.
2496 /// </summary>
2497 /// <param name="prim">Child prim</param>
2498 // I'm the parent
2499 // prim is the child
2500 public void ParentPrim(OdePrim prim)
2501 {
2502 //Console.WriteLine("ParentPrim " + m_primName);
2503 if (this.m_localID != prim.m_localID)
2504 {
2505 DestroyBody(); // for now we need to rebuil entire object on link change
2506
2507 lock (childrenPrim)
2508 {
2509 // adopt the prim
2510 if (!childrenPrim.Contains(prim))
2511 childrenPrim.Add(prim);
2512
2513 // see if this prim has kids and adopt them also
2514 // should not happen for now
2515 foreach (OdePrim prm in prim.childrenPrim)
2516 {
2517 if (!childrenPrim.Contains(prm))
2518 {
2519 if (prm.Body != IntPtr.Zero)
2520 {
2521 if (prm.prim_geom != IntPtr.Zero)
2522 d.GeomSetBody(prm.prim_geom, IntPtr.Zero);
2523 if (prm.Body != prim.Body)
2524 prm.DestroyBody(); // don't loose bodies around
2525 prm.Body = IntPtr.Zero;
2526 }
2527
2528 childrenPrim.Add(prm);
2529 prm._parent = this;
2530 }
2531 }
2532 }
2533 //Remove old children from the prim
2534 prim.childrenPrim.Clear();
2535
2536 if (prim.Body != IntPtr.Zero)
2537 {
2538 if (prim.prim_geom != IntPtr.Zero)
2539 d.GeomSetBody(prim.prim_geom, IntPtr.Zero);
2540 prim.DestroyBody(); // don't loose bodies around
2541 prim.Body = IntPtr.Zero;
2542 }
2543
2544 prim.childPrim = true;
2545 prim._parent = this;
2546
2547 MakeBody(); // full nasty reconstruction
2548 }
2549 }
2550
2551 private void UpdateChildsfromgeom()
2552 {
2553 if (childrenPrim.Count > 0)
2554 {
2555 foreach (OdePrim prm in childrenPrim)
2556 prm.UpdateDataFromGeom();
2557 }
2558 }
2559
2560 private void UpdateDataFromGeom()
2561 {
2562 if (prim_geom != IntPtr.Zero)
2563 {
2564 d.Quaternion qtmp;
2565 d.GeomCopyQuaternion(prim_geom, out qtmp);
2566 _orientation.X = qtmp.X;
2567 _orientation.Y = qtmp.Y;
2568 _orientation.Z = qtmp.Z;
2569 _orientation.W = qtmp.W;
2570/*
2571// Debug
2572 float qlen = _orientation.Length();
2573 if (qlen > 1.01f || qlen < 0.99)
2574 m_log.WarnFormat("[PHYSICS]: Got nonnorm quaternion from geom in Object {0} norm {1}", Name, qlen);
2575//
2576*/
2577 _orientation.Normalize();
2578
2579 d.Vector3 lpos = d.GeomGetPosition(prim_geom);
2580 _position.X = lpos.X;
2581 _position.Y = lpos.Y;
2582 _position.Z = lpos.Z;
2583 }
2584 }
2585
2586 private void ChildDelink(OdePrim odePrim, bool remakebodies)
2587 {
2588 // Okay, we have a delinked child.. destroy all body and remake
2589 if (odePrim != this && !childrenPrim.Contains(odePrim))
2590 return;
2591
2592 DestroyBody();
2593
2594 if (odePrim == this) // delinking the root prim
2595 {
2596 OdePrim newroot = null;
2597 lock (childrenPrim)
2598 {
2599 if (childrenPrim.Count > 0)
2600 {
2601 newroot = childrenPrim[0];
2602 childrenPrim.RemoveAt(0);
2603 foreach (OdePrim prm in childrenPrim)
2604 {
2605 newroot.childrenPrim.Add(prm);
2606 }
2607 childrenPrim.Clear();
2608 }
2609 if (newroot != null)
2610 {
2611 newroot.childPrim = false;
2612 newroot._parent = null;
2613 if (remakebodies)
2614 newroot.MakeBody();
2615 }
2616 }
2617 }
2618
2619 else
2620 {
2621 lock (childrenPrim)
2622 {
2623 childrenPrim.Remove(odePrim);
2624 odePrim.childPrim = false;
2625 odePrim._parent = null;
2626 // odePrim.UpdateDataFromGeom();
2627 if (remakebodies)
2628 odePrim.MakeBody();
2629 }
2630 }
2631 if (remakebodies)
2632 MakeBody();
2633 }
2634
2635 protected void ChildRemove(OdePrim odePrim, bool reMakeBody)
2636 {
2637 // Okay, we have a delinked child.. destroy all body and remake
2638 if (odePrim != this && !childrenPrim.Contains(odePrim))
2639 return;
2640
2641 DestroyBody();
2642
2643 if (odePrim == this)
2644 {
2645 OdePrim newroot = null;
2646 lock (childrenPrim)
2647 {
2648 if (childrenPrim.Count > 0)
2649 {
2650 newroot = childrenPrim[0];
2651 childrenPrim.RemoveAt(0);
2652 foreach (OdePrim prm in childrenPrim)
2653 {
2654 newroot.childrenPrim.Add(prm);
2655 }
2656 childrenPrim.Clear();
2657 }
2658 if (newroot != null)
2659 {
2660 newroot.childPrim = false;
2661 newroot._parent = null;
2662 newroot.MakeBody();
2663 }
2664 }
2665 if (reMakeBody)
2666 MakeBody();
2667 return;
2668 }
2669 else
2670 {
2671 lock (childrenPrim)
2672 {
2673 childrenPrim.Remove(odePrim);
2674 odePrim.childPrim = false;
2675 odePrim._parent = null;
2676 if (reMakeBody)
2677 odePrim.MakeBody();
2678 }
2679 }
2680 MakeBody();
2681 }
2682
2683
2684 #region changes
2685
2686 private void changeadd()
2687 {
2688 _parent_scene.addToPrims(this);
2689 }
2690
2691 private void changeAngularLock(byte newLocks)
2692 {
2693 // do we have a Physical object?
2694 if (Body != IntPtr.Zero)
2695 {
2696 //Check that we have a Parent
2697 //If we have a parent then we're not authorative here
2698 if (_parent == null)
2699 {
2700 if (newLocks != 0)
2701 {
2702 createAMotor(newLocks);
2703 }
2704 else
2705 {
2706 if (Amotor != IntPtr.Zero)
2707 {
2708 d.JointDestroy(Amotor);
2709 Amotor = IntPtr.Zero;
2710 }
2711 }
2712 }
2713 }
2714 // Store this for later in case we get turned into a separate body
2715 m_angularlocks = newLocks;
2716 }
2717
2718 private void changeLink(OdePrim NewParent)
2719 {
2720 if (_parent == null && NewParent != null)
2721 {
2722 NewParent.ParentPrim(this);
2723 }
2724 else if (_parent != null)
2725 {
2726 if (_parent is OdePrim)
2727 {
2728 if (NewParent != _parent)
2729 {
2730 (_parent as OdePrim).ChildDelink(this, false); // for now...
2731 childPrim = false;
2732
2733 if (NewParent != null)
2734 {
2735 NewParent.ParentPrim(this);
2736 }
2737 }
2738 }
2739 }
2740 _parent = NewParent;
2741 }
2742
2743
2744 private void Stop()
2745 {
2746 if (!childPrim)
2747 {
2748// m_force = Vector3.Zero;
2749 m_forceacc = Vector3.Zero;
2750 m_angularForceacc = Vector3.Zero;
2751// m_torque = Vector3.Zero;
2752 _velocity = Vector3.Zero;
2753 m_acceleration = Vector3.Zero;
2754 m_rotationalVelocity = Vector3.Zero;
2755 _target_velocity = Vector3.Zero;
2756 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
2757 m_vehicle.Stop();
2758
2759 _zeroFlag = false;
2760 base.RequestPhysicsterseUpdate();
2761 }
2762
2763 if (Body != IntPtr.Zero)
2764 {
2765 d.BodySetForce(Body, 0f, 0f, 0f);
2766 d.BodySetTorque(Body, 0f, 0f, 0f);
2767 d.BodySetLinearVel(Body, 0f, 0f, 0f);
2768 d.BodySetAngularVel(Body, 0f, 0f, 0f);
2769 }
2770 }
2771
2772 private void changePhantomStatus(bool newval)
2773 {
2774 m_isphantom = newval;
2775
2776 UpdateCollisionCatFlags();
2777 ApplyCollisionCatFlags();
2778 }
2779
2780/* not in use
2781 internal void ChildSelectedChange(bool childSelect)
2782 {
2783 if(childPrim)
2784 return;
2785
2786 if (childSelect == m_isSelected)
2787 return;
2788
2789 if (childSelect)
2790 {
2791 DoSelectedStatus(true);
2792 }
2793
2794 else
2795 {
2796 foreach (OdePrim prm in childrenPrim)
2797 {
2798 if (prm.m_isSelected)
2799 return;
2800 }
2801 DoSelectedStatus(false);
2802 }
2803 }
2804*/
2805 private void changeSelectedStatus(bool newval)
2806 {
2807 if (m_lastdoneSelected == newval)
2808 return;
2809
2810 m_lastdoneSelected = newval;
2811 DoSelectedStatus(newval);
2812 }
2813
2814 private void CheckDelaySelect()
2815 {
2816 if (m_delaySelect)
2817 {
2818 DoSelectedStatus(m_isSelected);
2819 }
2820 }
2821
2822 private void DoSelectedStatus(bool newval)
2823 {
2824 m_isSelected = newval;
2825 Stop();
2826
2827 if (newval)
2828 {
2829 if (!childPrim && Body != IntPtr.Zero)
2830 d.BodyDisable(Body);
2831
2832 if (m_delaySelect || m_isphysical)
2833 {
2834 m_collisionCategories = CollisionCategories.Selected;
2835 m_collisionFlags = 0;
2836
2837 if (!childPrim)
2838 {
2839 foreach (OdePrim prm in childrenPrim)
2840 {
2841 prm.m_collisionCategories = m_collisionCategories;
2842 prm.m_collisionFlags = m_collisionFlags;
2843
2844 if (prm.prim_geom != IntPtr.Zero)
2845 {
2846
2847 if (prm.m_NoColide)
2848 {
2849 d.GeomSetCategoryBits(prm.prim_geom, 0);
2850 d.GeomSetCollideBits(prm.prim_geom, 0);
2851 }
2852 else
2853 {
2854 d.GeomSetCategoryBits(prm.prim_geom, (uint)m_collisionCategories);
2855 d.GeomSetCollideBits(prm.prim_geom, (uint)m_collisionFlags);
2856 }
2857 }
2858 prm.m_delaySelect = false;
2859 }
2860 }
2861// else if (_parent != null)
2862// ((OdePrim)_parent).ChildSelectedChange(true);
2863
2864
2865 if (prim_geom != IntPtr.Zero)
2866 {
2867 if (m_NoColide)
2868 {
2869 d.GeomSetCategoryBits(prim_geom, 0);
2870 d.GeomSetCollideBits(prim_geom, 0);
2871 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
2872 {
2873 d.GeomSetCategoryBits(collide_geom, 0);
2874 d.GeomSetCollideBits(collide_geom, 0);
2875 }
2876
2877 }
2878 else
2879 {
2880 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
2881 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
2882 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
2883 {
2884 d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories);
2885 d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags);
2886 }
2887 }
2888 }
2889
2890 m_delaySelect = false;
2891 }
2892 else if(!m_isphysical)
2893 {
2894 m_delaySelect = true;
2895 }
2896 }
2897 else
2898 {
2899 if (!childPrim)
2900 {
2901 if (Body != IntPtr.Zero && !m_disabled)
2902 {
2903 _zeroFlag = true;
2904 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
2905 d.BodyEnable(Body);
2906 }
2907 }
2908// else if (_parent != null)
2909// ((OdePrim)_parent).ChildSelectedChange(false);
2910
2911 UpdateCollisionCatFlags();
2912 ApplyCollisionCatFlags();
2913
2914 m_delaySelect = false;
2915 }
2916
2917 resetCollisionAccounting();
2918 }
2919
2920 private void changePosition(Vector3 newPos)
2921 {
2922 CheckDelaySelect();
2923 if (m_isphysical)
2924 {
2925 if (childPrim) // inertia is messed, must rebuild
2926 {
2927 if (m_building)
2928 {
2929 _position = newPos;
2930 }
2931
2932 else if (m_forcePosOrRotation && _position != newPos && Body != IntPtr.Zero)
2933 {
2934 FixInertia(newPos);
2935 if (!d.BodyIsEnabled(Body))
2936 {
2937 _zeroFlag = true;
2938 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
2939 d.BodyEnable(Body);
2940 }
2941 }
2942 }
2943 else
2944 {
2945 if (_position != newPos)
2946 {
2947 d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z);
2948 _position = newPos;
2949 }
2950 if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
2951 {
2952 _zeroFlag = true;
2953 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
2954 d.BodyEnable(Body);
2955 }
2956 }
2957 }
2958 else
2959 {
2960 if (prim_geom != IntPtr.Zero)
2961 {
2962 if (newPos != _position)
2963 {
2964 d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z);
2965 _position = newPos;
2966
2967 m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, _position, m_targetSpace);
2968 }
2969 }
2970 }
2971 givefakepos--;
2972 if (givefakepos < 0)
2973 givefakepos = 0;
2974// changeSelectedStatus();
2975 resetCollisionAccounting();
2976 }
2977
2978 private void changeOrientation(Quaternion newOri)
2979 {
2980 CheckDelaySelect();
2981 if (m_isphysical)
2982 {
2983 if (childPrim) // inertia is messed, must rebuild
2984 {
2985 if (m_building)
2986 {
2987 _orientation = newOri;
2988 }
2989/*
2990 else if (m_forcePosOrRotation && _orientation != newOri && Body != IntPtr.Zero)
2991 {
2992 FixInertia(_position, newOri);
2993 if (!d.BodyIsEnabled(Body))
2994 d.BodyEnable(Body);
2995 }
2996*/
2997 }
2998 else
2999 {
3000 if (newOri != _orientation)
3001 {
3002 d.Quaternion myrot = new d.Quaternion();
3003 myrot.X = newOri.X;
3004 myrot.Y = newOri.Y;
3005 myrot.Z = newOri.Z;
3006 myrot.W = newOri.W;
3007 d.GeomSetQuaternion(prim_geom, ref myrot);
3008 _orientation = newOri;
3009
3010 if (Body != IntPtr.Zero)
3011 {
3012 if(m_angularlocks != 0)
3013 createAMotor(m_angularlocks);
3014 }
3015 }
3016 if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
3017 {
3018 _zeroFlag = true;
3019 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
3020 d.BodyEnable(Body);
3021 }
3022 }
3023 }
3024 else
3025 {
3026 if (prim_geom != IntPtr.Zero)
3027 {
3028 if (newOri != _orientation)
3029 {
3030 d.Quaternion myrot = new d.Quaternion();
3031 myrot.X = newOri.X;
3032 myrot.Y = newOri.Y;
3033 myrot.Z = newOri.Z;
3034 myrot.W = newOri.W;
3035 d.GeomSetQuaternion(prim_geom, ref myrot);
3036 _orientation = newOri;
3037 }
3038 }
3039 }
3040 givefakeori--;
3041 if (givefakeori < 0)
3042 givefakeori = 0;
3043 resetCollisionAccounting();
3044 }
3045
3046 private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri)
3047 {
3048 CheckDelaySelect();
3049 if (m_isphysical)
3050 {
3051 if (childPrim && m_building) // inertia is messed, must rebuild
3052 {
3053 _position = newPos;
3054 _orientation = newOri;
3055 }
3056 else
3057 {
3058 if (newOri != _orientation)
3059 {
3060 d.Quaternion myrot = new d.Quaternion();
3061 myrot.X = newOri.X;
3062 myrot.Y = newOri.Y;
3063 myrot.Z = newOri.Z;
3064 myrot.W = newOri.W;
3065 d.GeomSetQuaternion(prim_geom, ref myrot);
3066 _orientation = newOri;
3067 if (Body != IntPtr.Zero && m_angularlocks != 0)
3068 createAMotor(m_angularlocks);
3069 }
3070 if (_position != newPos)
3071 {
3072 d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z);
3073 _position = newPos;
3074 }
3075 if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
3076 {
3077 _zeroFlag = true;
3078 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
3079 d.BodyEnable(Body);
3080 }
3081 }
3082 }
3083 else
3084 {
3085 // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
3086 // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
3087
3088 if (prim_geom != IntPtr.Zero)
3089 {
3090 if (newOri != _orientation)
3091 {
3092 d.Quaternion myrot = new d.Quaternion();
3093 myrot.X = newOri.X;
3094 myrot.Y = newOri.Y;
3095 myrot.Z = newOri.Z;
3096 myrot.W = newOri.W;
3097 d.GeomSetQuaternion(prim_geom, ref myrot);
3098 _orientation = newOri;
3099 }
3100
3101 if (newPos != _position)
3102 {
3103 d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z);
3104 _position = newPos;
3105
3106 m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, _position, m_targetSpace);
3107 }
3108 }
3109 }
3110 givefakepos--;
3111 if (givefakepos < 0)
3112 givefakepos = 0;
3113 givefakeori--;
3114 if (givefakeori < 0)
3115 givefakeori = 0;
3116 resetCollisionAccounting();
3117 }
3118
3119 private void changeDisable(bool disable)
3120 {
3121 if (disable)
3122 {
3123 if (!m_disabled)
3124 disableBodySoft();
3125 }
3126 else
3127 {
3128 if (m_disabled)
3129 enableBodySoft();
3130 }
3131 }
3132
3133 private void changePhysicsStatus(bool NewStatus)
3134 {
3135 CheckDelaySelect();
3136
3137 m_isphysical = NewStatus;
3138
3139 if (!childPrim)
3140 {
3141 if (NewStatus)
3142 {
3143 if (Body == IntPtr.Zero)
3144 MakeBody();
3145 }
3146 else
3147 {
3148 if (Body != IntPtr.Zero)
3149 {
3150 DestroyBody();
3151 }
3152 Stop();
3153 }
3154 }
3155
3156 resetCollisionAccounting();
3157 }
3158
3159 private void changeSize(Vector3 newSize)
3160 {
3161 }
3162
3163 private void changeShape(PrimitiveBaseShape newShape)
3164 {
3165 }
3166
3167 private void changeAddPhysRep(ODEPhysRepData repData)
3168 {
3169 _size = repData.size; //??
3170 _pbs = repData.pbs;
3171
3172 m_mesh = repData.mesh;
3173
3174 m_assetID = repData.assetID;
3175 m_meshState = repData.meshState;
3176
3177 m_hasOBB = repData.hasOBB;
3178 m_OBBOffset = repData.OBBOffset;
3179 m_OBB = repData.OBB;
3180
3181 primVolume = repData.volume;
3182
3183 CreateGeom(repData.isTooSmall);
3184
3185 if (prim_geom != IntPtr.Zero)
3186 {
3187 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3188 d.Quaternion myrot = new d.Quaternion();
3189 myrot.X = _orientation.X;
3190 myrot.Y = _orientation.Y;
3191 myrot.Z = _orientation.Z;
3192 myrot.W = _orientation.W;
3193 d.GeomSetQuaternion(prim_geom, ref myrot);
3194 }
3195
3196 if (!m_isphysical)
3197 {
3198 SetInStaticSpace(this);
3199 UpdateCollisionCatFlags();
3200 ApplyCollisionCatFlags();
3201 }
3202 else
3203 MakeBody();
3204
3205 if ((m_meshState & MeshState.NeedMask) != 0)
3206 {
3207 repData.size = _size;
3208 repData.pbs = _pbs;
3209 repData.shapetype = m_fakeShapetype;
3210 _parent_scene.m_meshWorker.RequestMesh(repData);
3211 }
3212 else
3213 m_shapetype = repData.shapetype;
3214 }
3215
3216 private void changePhysRepData(ODEPhysRepData repData)
3217 {
3218 if(_size == repData.size &&
3219 _pbs == repData.pbs &&
3220 m_shapetype == repData.shapetype &&
3221 m_mesh == repData.mesh &&
3222 primVolume == repData.volume)
3223 return;
3224
3225 CheckDelaySelect();
3226
3227 OdePrim parent = (OdePrim)_parent;
3228
3229 bool chp = childPrim;
3230
3231 if (chp)
3232 {
3233 if (parent != null)
3234 {
3235 parent.DestroyBody();
3236 }
3237 }
3238 else
3239 {
3240 DestroyBody();
3241 }
3242
3243 RemoveGeom();
3244
3245 _size = repData.size;
3246 _pbs = repData.pbs;
3247
3248 m_mesh = repData.mesh;
3249
3250 m_assetID = repData.assetID;
3251 m_meshState = repData.meshState;
3252
3253 m_hasOBB = repData.hasOBB;
3254 m_OBBOffset = repData.OBBOffset;
3255 m_OBB = repData.OBB;
3256
3257 primVolume = repData.volume;
3258
3259 CreateGeom(repData.isTooSmall);
3260
3261 if (prim_geom != IntPtr.Zero)
3262 {
3263 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3264 d.Quaternion myrot = new d.Quaternion();
3265 myrot.X = _orientation.X;
3266 myrot.Y = _orientation.Y;
3267 myrot.Z = _orientation.Z;
3268 myrot.W = _orientation.W;
3269 d.GeomSetQuaternion(prim_geom, ref myrot);
3270 }
3271
3272 if (m_isphysical)
3273 {
3274 if (chp)
3275 {
3276 if (parent != null)
3277 {
3278 parent.MakeBody();
3279 }
3280 }
3281 else
3282 MakeBody();
3283 }
3284 else
3285 {
3286 SetInStaticSpace(this);
3287 UpdateCollisionCatFlags();
3288 ApplyCollisionCatFlags();
3289 }
3290
3291 resetCollisionAccounting();
3292
3293 if ((m_meshState & MeshState.NeedMask) != 0)
3294 {
3295 repData.size = _size;
3296 repData.pbs = _pbs;
3297 repData.shapetype = m_fakeShapetype;
3298 _parent_scene.m_meshWorker.RequestMesh(repData);
3299 }
3300 else
3301 m_shapetype = repData.shapetype;
3302 }
3303
3304 private void changeFloatOnWater(bool newval)
3305 {
3306 m_collidesWater = newval;
3307
3308 UpdateCollisionCatFlags();
3309 ApplyCollisionCatFlags();
3310 }
3311
3312 private void changeSetTorque(Vector3 newtorque)
3313 {
3314 if (!m_isSelected && !m_outbounds)
3315 {
3316 if (m_isphysical && Body != IntPtr.Zero)
3317 {
3318 if (m_disabled)
3319 enableBodySoft();
3320 else if (!d.BodyIsEnabled(Body))
3321 {
3322 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
3323 d.BodyEnable(Body);
3324 }
3325 }
3326 m_torque = newtorque;
3327 }
3328 }
3329
3330 private void changeForce(Vector3 force)
3331 {
3332 m_force = force;
3333 if (!m_isSelected && !m_outbounds && Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
3334 {
3335 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
3336 d.BodyEnable(Body);
3337 }
3338 }
3339
3340 private void changeAddForce(Vector3 theforce)
3341 {
3342 m_forceacc += theforce;
3343 if (!m_isSelected && !m_outbounds)
3344 {
3345 lock (this)
3346 {
3347 //m_log.Info("[PHYSICS]: dequeing forcelist");
3348 if (m_isphysical && Body != IntPtr.Zero)
3349 {
3350 if (m_disabled)
3351 enableBodySoft();
3352 else if (!d.BodyIsEnabled(Body))
3353 {
3354 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
3355 d.BodyEnable(Body);
3356 }
3357 }
3358 }
3359 m_collisionscore = 0;
3360 }
3361 }
3362
3363 // actually angular impulse
3364 private void changeAddAngularImpulse(Vector3 aimpulse)
3365 {
3366 m_angularForceacc += aimpulse * m_invTimeStep;
3367 if (!m_isSelected && !m_outbounds)
3368 {
3369 lock (this)
3370 {
3371 if (m_isphysical && Body != IntPtr.Zero)
3372 {
3373 if (m_disabled)
3374 enableBodySoft();
3375 else if (!d.BodyIsEnabled(Body))
3376 {
3377 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
3378 d.BodyEnable(Body);
3379 }
3380 }
3381 }
3382 m_collisionscore = 0;
3383 }
3384 }
3385
3386 private void changevelocity(Vector3 newVel)
3387 {
3388 float len = newVel.LengthSquared();
3389 if (len > 100000.0f) // limit to 100m/s
3390 {
3391 len = 100.0f / (float)Math.Sqrt(len);
3392 newVel *= len;
3393 }
3394
3395 if (!m_isSelected && !m_outbounds)
3396 {
3397 if (Body != IntPtr.Zero)
3398 {
3399 if (m_disabled)
3400 enableBodySoft();
3401 else if (!d.BodyIsEnabled(Body))
3402 {
3403 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
3404 d.BodyEnable(Body);
3405 }
3406 d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z);
3407 }
3408 //resetCollisionAccounting();
3409 }
3410 _velocity = newVel;
3411 }
3412
3413 private void changeangvelocity(Vector3 newAngVel)
3414 {
3415 float len = newAngVel.LengthSquared();
3416 if (len > _parent_scene.maxAngVelocitySQ)
3417 {
3418 len = _parent_scene.maximumAngularVelocity / (float)Math.Sqrt(len);
3419 newAngVel *= len;
3420 }
3421
3422 if (!m_isSelected && !m_outbounds)
3423 {
3424 if (Body != IntPtr.Zero)
3425 {
3426 if (m_disabled)
3427 enableBodySoft();
3428 else if (!d.BodyIsEnabled(Body))
3429 {
3430 d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
3431 d.BodyEnable(Body);
3432 }
3433 d.BodySetAngularVel(Body, newAngVel.X, newAngVel.Y, newAngVel.Z);
3434 }
3435 //resetCollisionAccounting();
3436 }
3437 m_rotationalVelocity = newAngVel;
3438 }
3439
3440 private void changeVolumedetetion(bool newVolDtc)
3441 {
3442 m_isVolumeDetect = newVolDtc;
3443 m_fakeisVolumeDetect = newVolDtc;
3444 UpdateCollisionCatFlags();
3445 ApplyCollisionCatFlags();
3446 }
3447
3448 protected void changeBuilding(bool newbuilding)
3449 {
3450 // Check if we need to do anything
3451 if (newbuilding == m_building)
3452 return;
3453
3454 if ((bool)newbuilding)
3455 {
3456 m_building = true;
3457 if (!childPrim)
3458 DestroyBody();
3459 }
3460 else
3461 {
3462 m_building = false;
3463 CheckDelaySelect();
3464 if (!childPrim)
3465 MakeBody();
3466 }
3467 if (!childPrim && childrenPrim.Count > 0)
3468 {
3469 foreach (OdePrim prm in childrenPrim)
3470 prm.changeBuilding(m_building); // call directly
3471 }
3472 }
3473
3474 public void changeSetVehicle(VehicleData vdata)
3475 {
3476 if (m_vehicle == null)
3477 m_vehicle = new ODEDynamics(this);
3478 m_vehicle.DoSetVehicle(vdata);
3479 }
3480
3481 private void changeVehicleType(int value)
3482 {
3483 if (value == (int)Vehicle.TYPE_NONE)
3484 {
3485 if (m_vehicle != null)
3486 m_vehicle = null;
3487 }
3488 else
3489 {
3490 if (m_vehicle == null)
3491 m_vehicle = new ODEDynamics(this);
3492
3493 m_vehicle.ProcessTypeChange((Vehicle)value);
3494 }
3495 }
3496
3497 private void changeVehicleFloatParam(strVehicleFloatParam fp)
3498 {
3499 if (m_vehicle == null)
3500 return;
3501
3502 m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value);
3503 }
3504
3505 private void changeVehicleVectorParam(strVehicleVectorParam vp)
3506 {
3507 if (m_vehicle == null)
3508 return;
3509 m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value);
3510 }
3511
3512 private void changeVehicleRotationParam(strVehicleQuatParam qp)
3513 {
3514 if (m_vehicle == null)
3515 return;
3516 m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value);
3517 }
3518
3519 private void changeVehicleFlags(strVehicleBoolParam bp)
3520 {
3521 if (m_vehicle == null)
3522 return;
3523 m_vehicle.ProcessVehicleFlags(bp.param, bp.value);
3524 }
3525
3526 private void changeBuoyancy(float b)
3527 {
3528 m_buoyancy = b;
3529 }
3530
3531 private void changePIDTarget(Vector3 trg)
3532 {
3533 m_PIDTarget = trg;
3534 }
3535
3536 private void changePIDTau(float tau)
3537 {
3538 m_PIDTau = tau;
3539 }
3540
3541 private void changePIDActive(bool val)
3542 {
3543 m_usePID = val;
3544 }
3545
3546 private void changePIDHoverHeight(float val)
3547 {
3548 m_PIDHoverHeight = val;
3549 if (val == 0)
3550 m_useHoverPID = false;
3551 }
3552
3553 private void changePIDHoverType(PIDHoverType type)
3554 {
3555 m_PIDHoverType = type;
3556 }
3557
3558 private void changePIDHoverTau(float tau)
3559 {
3560 m_PIDHoverTau = tau;
3561 }
3562
3563 private void changePIDHoverActive(bool active)
3564 {
3565 m_useHoverPID = active;
3566 }
3567
3568 private void changeInertia(PhysicsInertiaData inertia)
3569 {
3570 m_InertiaOverride = inertia;
3571
3572 if (Body != IntPtr.Zero)
3573 DestroyBody();
3574 MakeBody();
3575 }
3576
3577 #endregion
3578
3579 public void Move()
3580 {
3581 if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
3582 !m_disabled && !m_isSelected && !m_building && !m_outbounds)
3583 {
3584 if (!d.BodyIsEnabled(Body))
3585 {
3586 // let vehicles sleep
3587 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
3588 return;
3589
3590 if (++m_bodydisablecontrol < 50)
3591 return;
3592
3593 // clear residuals
3594 d.BodySetAngularVel(Body,0f,0f,0f);
3595 d.BodySetLinearVel(Body,0f,0f,0f);
3596 _zeroFlag = true;
3597 d.BodySetAutoDisableSteps(Body, 1);
3598 d.BodyEnable(Body);
3599 m_bodydisablecontrol = -3;
3600 }
3601
3602 if(m_bodydisablecontrol < 0)
3603 m_bodydisablecontrol++;
3604
3605 d.Vector3 lpos = d.GeomGetPosition(prim_geom); // root position that is seem by rest of simulator
3606
3607 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
3608 {
3609 // 'VEHICLES' are dealt with in ODEDynamics.cs
3610 m_vehicle.Step();
3611 return;
3612 }
3613
3614 float fx = 0;
3615 float fy = 0;
3616 float fz = 0;
3617
3618 float mass = m_mass;
3619
3620 if (m_usePID && m_PIDTau > 0)
3621 {
3622 // for now position error
3623 _target_velocity =
3624 new Vector3(
3625 (m_PIDTarget.X - lpos.X),
3626 (m_PIDTarget.Y - lpos.Y),
3627 (m_PIDTarget.Z - lpos.Z)
3628 );
3629
3630 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.02f))
3631 {
3632 d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
3633 d.BodySetLinearVel(Body, 0, 0, 0);
3634 return;
3635 }
3636 else
3637 {
3638 _zeroFlag = false;
3639
3640 float tmp = 1 / m_PIDTau;
3641 _target_velocity *= tmp;
3642
3643 // apply limits
3644 tmp = _target_velocity.Length();
3645 if (tmp > 50.0f)
3646 {
3647 tmp = 50 / tmp;
3648 _target_velocity *= tmp;
3649 }
3650 else if (tmp < 0.05f)
3651 {
3652 tmp = 0.05f / tmp;
3653 _target_velocity *= tmp;
3654 }
3655
3656 d.Vector3 vel = d.BodyGetLinearVel(Body);
3657 fx = (_target_velocity.X - vel.X) * m_invTimeStep;
3658 fy = (_target_velocity.Y - vel.Y) * m_invTimeStep;
3659 fz = (_target_velocity.Z - vel.Z) * m_invTimeStep;
3660// d.BodySetLinearVel(Body, _target_velocity.X, _target_velocity.Y, _target_velocity.Z);
3661 }
3662 } // end if (m_usePID)
3663
3664 // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller
3665 else if (m_useHoverPID && m_PIDHoverTau != 0 && m_PIDHoverHeight != 0)
3666 {
3667
3668 // Non-Vehicles have a limited set of Hover options.
3669 // determine what our target height really is based on HoverType
3670
3671 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(lpos.X, lpos.Y);
3672
3673 switch (m_PIDHoverType)
3674 {
3675 case PIDHoverType.Ground:
3676 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
3677 break;
3678
3679 case PIDHoverType.GroundAndWater:
3680 m_waterHeight = _parent_scene.GetWaterLevel();
3681 if (m_groundHeight > m_waterHeight)
3682 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
3683 else
3684 m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
3685 break;
3686 } // end switch (m_PIDHoverType)
3687
3688 // don't go underground unless volumedetector
3689
3690 if (m_targetHoverHeight > m_groundHeight || m_isVolumeDetect)
3691 {
3692 d.Vector3 vel = d.BodyGetLinearVel(Body);
3693
3694 fz = (m_targetHoverHeight - lpos.Z);
3695
3696 // if error is zero, use position control; otherwise, velocity control
3697 if (Math.Abs(fz) < 0.01f)
3698 {
3699 d.BodySetPosition(Body, lpos.X, lpos.Y, m_targetHoverHeight);
3700 d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
3701 }
3702 else
3703 {
3704 _zeroFlag = false;
3705 fz /= m_PIDHoverTau;
3706
3707 float tmp = Math.Abs(fz);
3708 if (tmp > 50)
3709 fz = 50 * Math.Sign(fz);
3710 else if (tmp < 0.1)
3711 fz = 0.1f * Math.Sign(fz);
3712
3713 fz = ((fz - vel.Z) * m_invTimeStep);
3714 }
3715 }
3716 }
3717 else
3718 {
3719 float b = (1.0f - m_buoyancy) * m_gravmod;
3720 fx = _parent_scene.gravityx * b;
3721 fy = _parent_scene.gravityy * b;
3722 fz = _parent_scene.gravityz * b;
3723 }
3724
3725 fx *= mass;
3726 fy *= mass;
3727 fz *= mass;
3728
3729 // constant force
3730 fx += m_force.X;
3731 fy += m_force.Y;
3732 fz += m_force.Z;
3733
3734 fx += m_forceacc.X;
3735 fy += m_forceacc.Y;
3736 fz += m_forceacc.Z;
3737
3738 m_forceacc = Vector3.Zero;
3739
3740 //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
3741 if (fx != 0 || fy != 0 || fz != 0)
3742 {
3743 d.BodyAddForce(Body, fx, fy, fz);
3744 //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz);
3745 }
3746
3747 Vector3 trq;
3748
3749 trq = m_torque;
3750 trq += m_angularForceacc;
3751 m_angularForceacc = Vector3.Zero;
3752 if (trq.X != 0 || trq.Y != 0 || trq.Z != 0)
3753 {
3754 d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z);
3755 }
3756 }
3757 else
3758 { // is not physical, or is not a body or is selected
3759 // _zeroPosition = d.BodyGetPosition(Body);
3760 return;
3761 //Console.WriteLine("Nothing " + Name);
3762
3763 }
3764 }
3765
3766 public void UpdatePositionAndVelocity(int frame)
3767 {
3768 if (_parent == null && !m_isSelected && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero)
3769 {
3770 if(m_bodydisablecontrol < 0)
3771 return;
3772
3773 bool bodyenabled = d.BodyIsEnabled(Body);
3774 if (bodyenabled || !_zeroFlag)
3775 {
3776 bool lastZeroFlag = _zeroFlag;
3777
3778 d.Vector3 lpos = d.GeomGetPosition(prim_geom);
3779
3780 // check outside region
3781 if (lpos.Z < -100 || lpos.Z > 100000f)
3782 {
3783 m_outbounds = true;
3784
3785 lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
3786 m_acceleration.X = 0;
3787 m_acceleration.Y = 0;
3788 m_acceleration.Z = 0;
3789
3790 _velocity.X = 0;
3791 _velocity.Y = 0;
3792 _velocity.Z = 0;
3793 m_rotationalVelocity.X = 0;
3794 m_rotationalVelocity.Y = 0;
3795 m_rotationalVelocity.Z = 0;
3796
3797 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
3798 d.BodySetAngularVel(Body, 0, 0, 0); // stop it
3799 d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere
3800 m_lastposition = _position;
3801 m_lastorientation = _orientation;
3802
3803 base.RequestPhysicsterseUpdate();
3804
3805// throttleCounter = 0;
3806 _zeroFlag = true;
3807
3808 disableBodySoft(); // disable it and colisions
3809 base.RaiseOutOfBounds(_position);
3810 return;
3811 }
3812
3813 if (lpos.X < 0f)
3814 {
3815 _position.X = Util.Clip(lpos.X, -2f, -0.1f);
3816 m_outbounds = true;
3817 }
3818 else if (lpos.X > _parent_scene.WorldExtents.X)
3819 {
3820 _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
3821 m_outbounds = true;
3822 }
3823 if (lpos.Y < 0f)
3824 {
3825 _position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
3826 m_outbounds = true;
3827 }
3828 else if (lpos.Y > _parent_scene.WorldExtents.Y)
3829 {
3830 _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
3831 m_outbounds = true;
3832 }
3833
3834 if (m_outbounds)
3835 {
3836 m_lastposition = _position;
3837 m_lastorientation = _orientation;
3838
3839 d.Vector3 dtmp = d.BodyGetAngularVel(Body);
3840 m_rotationalVelocity.X = dtmp.X;
3841 m_rotationalVelocity.Y = dtmp.Y;
3842 m_rotationalVelocity.Z = dtmp.Z;
3843
3844 dtmp = d.BodyGetLinearVel(Body);
3845 _velocity.X = dtmp.X;
3846 _velocity.Y = dtmp.Y;
3847 _velocity.Z = dtmp.Z;
3848
3849 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
3850 d.BodySetAngularVel(Body, 0, 0, 0);
3851 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3852 disableBodySoft(); // stop collisions
3853 UnSubscribeEvents();
3854
3855 base.RequestPhysicsterseUpdate();
3856 return;
3857 }
3858
3859 d.Quaternion ori;
3860 d.GeomCopyQuaternion(prim_geom, out ori);
3861
3862 // decide if moving
3863 // use positions since this are integrated quantities
3864 // tolerance values depende a lot on simulation noise...
3865 // use simple math.abs since we dont need to be exact
3866 if(!bodyenabled)
3867 {
3868 _zeroFlag = true;
3869 }
3870 else
3871 {
3872 float poserror;
3873 float angerror;
3874 if(_zeroFlag)
3875 {
3876 poserror = 0.01f;
3877 angerror = 0.001f;
3878 }
3879 else
3880 {
3881 poserror = 0.005f;
3882 angerror = 0.0005f;
3883 }
3884
3885 if (
3886 (Math.Abs(_position.X - lpos.X) < poserror)
3887 && (Math.Abs(_position.Y - lpos.Y) < poserror)
3888 && (Math.Abs(_position.Z - lpos.Z) < poserror)
3889 && (Math.Abs(_orientation.X - ori.X) < angerror)
3890 && (Math.Abs(_orientation.Y - ori.Y) < angerror)
3891 && (Math.Abs(_orientation.Z - ori.Z) < angerror) // ignore W
3892 )
3893 _zeroFlag = true;
3894 else
3895 _zeroFlag = false;
3896 }
3897
3898 // update position
3899 if (!(_zeroFlag && lastZeroFlag))
3900 {
3901 _position.X = lpos.X;
3902 _position.Y = lpos.Y;
3903 _position.Z = lpos.Z;
3904
3905 _orientation.X = ori.X;
3906 _orientation.Y = ori.Y;
3907 _orientation.Z = ori.Z;
3908 _orientation.W = ori.W;
3909 }
3910
3911 // update velocities and acceleration
3912 if (_zeroFlag || lastZeroFlag)
3913 {
3914 // disable interpolators
3915 _velocity = Vector3.Zero;
3916 m_acceleration = Vector3.Zero;
3917 m_rotationalVelocity = Vector3.Zero;
3918 }
3919 else
3920 {
3921 d.Vector3 vel = d.BodyGetLinearVel(Body);
3922
3923 m_acceleration = _velocity;
3924
3925 if ((Math.Abs(vel.X) < 0.005f) &&
3926 (Math.Abs(vel.Y) < 0.005f) &&
3927 (Math.Abs(vel.Z) < 0.005f))
3928 {
3929 _velocity = Vector3.Zero;
3930 float t = -m_invTimeStep;
3931 m_acceleration = m_acceleration * t;
3932 }
3933 else
3934 {
3935 _velocity.X = vel.X;
3936 _velocity.Y = vel.Y;
3937 _velocity.Z = vel.Z;
3938 m_acceleration = (_velocity - m_acceleration) * m_invTimeStep;
3939 }
3940
3941 if ((Math.Abs(m_acceleration.X) < 0.01f) &&
3942 (Math.Abs(m_acceleration.Y) < 0.01f) &&
3943 (Math.Abs(m_acceleration.Z) < 0.01f))
3944 {
3945 m_acceleration = Vector3.Zero;
3946 }
3947
3948 vel = d.BodyGetAngularVel(Body);
3949 if ((Math.Abs(vel.X) < 0.0001) &&
3950 (Math.Abs(vel.Y) < 0.0001) &&
3951 (Math.Abs(vel.Z) < 0.0001)
3952 )
3953 {
3954 m_rotationalVelocity = Vector3.Zero;
3955 }
3956 else
3957 {
3958 m_rotationalVelocity.X = vel.X;
3959 m_rotationalVelocity.Y = vel.Y;
3960 m_rotationalVelocity.Z = vel.Z;
3961 }
3962 }
3963
3964 if (_zeroFlag)
3965 {
3966 if (!m_lastUpdateSent)
3967 {
3968 base.RequestPhysicsterseUpdate();
3969 if (lastZeroFlag)
3970 m_lastUpdateSent = true;
3971 }
3972 return;
3973 }
3974
3975 base.RequestPhysicsterseUpdate();
3976 m_lastUpdateSent = false;
3977 }
3978 }
3979 }
3980
3981 internal static bool QuaternionIsFinite(Quaternion q)
3982 {
3983 if (Single.IsNaN(q.X) || Single.IsInfinity(q.X))
3984 return false;
3985 if (Single.IsNaN(q.Y) || Single.IsInfinity(q.Y))
3986 return false;
3987 if (Single.IsNaN(q.Z) || Single.IsInfinity(q.Z))
3988 return false;
3989 if (Single.IsNaN(q.W) || Single.IsInfinity(q.W))
3990 return false;
3991 return true;
3992 }
3993
3994 internal static void DMassSubPartFromObj(ref d.Mass part, ref d.Mass theobj)
3995 {
3996 // assumes object center of mass is zero
3997 float smass = part.mass;
3998 theobj.mass -= smass;
3999
4000 smass *= 1.0f / (theobj.mass); ;
4001
4002 theobj.c.X -= part.c.X * smass;
4003 theobj.c.Y -= part.c.Y * smass;
4004 theobj.c.Z -= part.c.Z * smass;
4005
4006 theobj.I.M00 -= part.I.M00;
4007 theobj.I.M01 -= part.I.M01;
4008 theobj.I.M02 -= part.I.M02;
4009 theobj.I.M10 -= part.I.M10;
4010 theobj.I.M11 -= part.I.M11;
4011 theobj.I.M12 -= part.I.M12;
4012 theobj.I.M20 -= part.I.M20;
4013 theobj.I.M21 -= part.I.M21;
4014 theobj.I.M22 -= part.I.M22;
4015 }
4016
4017 private void donullchange()
4018 {
4019 }
4020
4021 public bool DoAChange(changes what, object arg)
4022 {
4023 if (prim_geom == IntPtr.Zero && what != changes.Add && what != changes.AddPhysRep && what != changes.Remove)
4024 {
4025 return false;
4026 }
4027
4028 // nasty switch
4029 switch (what)
4030 {
4031 case changes.Add:
4032 changeadd();
4033 break;
4034
4035 case changes.AddPhysRep:
4036 changeAddPhysRep((ODEPhysRepData)arg);
4037 break;
4038
4039 case changes.Remove:
4040 //If its being removed, we don't want to rebuild the physical rep at all, so ignore this stuff...
4041 //When we return true, it destroys all of the prims in the linkset anyway
4042 if (_parent != null)
4043 {
4044 OdePrim parent = (OdePrim)_parent;
4045 parent.ChildRemove(this, false);
4046 }
4047 else
4048 ChildRemove(this, false);
4049
4050 m_vehicle = null;
4051 RemoveGeom();
4052 m_targetSpace = IntPtr.Zero;
4053 UnSubscribeEvents();
4054 return true;
4055
4056 case changes.Link:
4057 OdePrim tmp = (OdePrim)arg;
4058 changeLink(tmp);
4059 break;
4060
4061 case changes.DeLink:
4062 changeLink(null);
4063 break;
4064
4065 case changes.Position:
4066 changePosition((Vector3)arg);
4067 break;
4068
4069 case changes.Orientation:
4070 changeOrientation((Quaternion)arg);
4071 break;
4072
4073 case changes.PosOffset:
4074 donullchange();
4075 break;
4076
4077 case changes.OriOffset:
4078 donullchange();
4079 break;
4080
4081 case changes.Velocity:
4082 changevelocity((Vector3)arg);
4083 break;
4084
4085 case changes.TargetVelocity:
4086 break;
4087
4088// case changes.Acceleration:
4089// changeacceleration((Vector3)arg);
4090// break;
4091
4092 case changes.AngVelocity:
4093 changeangvelocity((Vector3)arg);
4094 break;
4095
4096 case changes.Force:
4097 changeForce((Vector3)arg);
4098 break;
4099
4100 case changes.Torque:
4101 changeSetTorque((Vector3)arg);
4102 break;
4103
4104 case changes.AddForce:
4105 changeAddForce((Vector3)arg);
4106 break;
4107
4108 case changes.AddAngForce:
4109 changeAddAngularImpulse((Vector3)arg);
4110 break;
4111
4112 case changes.AngLock:
4113 changeAngularLock((byte)arg);
4114 break;
4115
4116 case changes.Size:
4117 changeSize((Vector3)arg);
4118 break;
4119
4120 case changes.Shape:
4121 changeShape((PrimitiveBaseShape)arg);
4122 break;
4123
4124 case changes.PhysRepData:
4125 changePhysRepData((ODEPhysRepData) arg);
4126 break;
4127
4128 case changes.CollidesWater:
4129 changeFloatOnWater((bool)arg);
4130 break;
4131
4132 case changes.VolumeDtc:
4133 changeVolumedetetion((bool)arg);
4134 break;
4135
4136 case changes.Phantom:
4137 changePhantomStatus((bool)arg);
4138 break;
4139
4140 case changes.Physical:
4141 changePhysicsStatus((bool)arg);
4142 break;
4143
4144 case changes.Selected:
4145 changeSelectedStatus((bool)arg);
4146 break;
4147
4148 case changes.disabled:
4149 changeDisable((bool)arg);
4150 break;
4151
4152 case changes.building:
4153 changeBuilding((bool)arg);
4154 break;
4155
4156 case changes.VehicleType:
4157 changeVehicleType((int)arg);
4158 break;
4159
4160 case changes.VehicleFlags:
4161 changeVehicleFlags((strVehicleBoolParam) arg);
4162 break;
4163
4164 case changes.VehicleFloatParam:
4165 changeVehicleFloatParam((strVehicleFloatParam) arg);
4166 break;
4167
4168 case changes.VehicleVectorParam:
4169 changeVehicleVectorParam((strVehicleVectorParam) arg);
4170 break;
4171
4172 case changes.VehicleRotationParam:
4173 changeVehicleRotationParam((strVehicleQuatParam) arg);
4174 break;
4175
4176 case changes.SetVehicle:
4177 changeSetVehicle((VehicleData) arg);
4178 break;
4179
4180 case changes.Buoyancy:
4181 changeBuoyancy((float)arg);
4182 break;
4183
4184 case changes.PIDTarget:
4185 changePIDTarget((Vector3)arg);
4186 break;
4187
4188 case changes.PIDTau:
4189 changePIDTau((float)arg);
4190 break;
4191
4192 case changes.PIDActive:
4193 changePIDActive((bool)arg);
4194 break;
4195
4196 case changes.PIDHoverHeight:
4197 changePIDHoverHeight((float)arg);
4198 break;
4199
4200 case changes.PIDHoverType:
4201 changePIDHoverType((PIDHoverType)arg);
4202 break;
4203
4204 case changes.PIDHoverTau:
4205 changePIDHoverTau((float)arg);
4206 break;
4207
4208 case changes.PIDHoverActive:
4209 changePIDHoverActive((bool)arg);
4210 break;
4211
4212 case changes.SetInertia:
4213 changeInertia((PhysicsInertiaData) arg);
4214 break;
4215
4216 case changes.Null:
4217 donullchange();
4218 break;
4219
4220 default:
4221 donullchange();
4222 break;
4223 }
4224 return false;
4225 }
4226
4227 public void AddChange(changes what, object arg)
4228 {
4229 _parent_scene.AddChange((PhysicsActor) this, what, arg);
4230 }
4231
4232 private struct strVehicleBoolParam
4233 {
4234 public int param;
4235 public bool value;
4236 }
4237
4238 private struct strVehicleFloatParam
4239 {
4240 public int param;
4241 public float value;
4242 }
4243
4244 private struct strVehicleQuatParam
4245 {
4246 public int param;
4247 public Quaternion value;
4248 }
4249
4250 private struct strVehicleVectorParam
4251 {
4252 public int param;
4253 public Vector3 value;
4254 }
4255 }
4256}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs b/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs
new file mode 100644
index 0000000..f671722
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs
@@ -0,0 +1,689 @@
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.Reflection;
31using System.Runtime.InteropServices;
32using System.Text;
33using OpenSim.Framework;
34using OpenSim.Region.PhysicsModules.SharedBase;
35using OdeAPI;
36using log4net;
37using OpenMetaverse;
38
39namespace OpenSim.Region.PhysicsModule.ubOde
40{
41 /// <summary>
42 /// Processes raycast requests as ODE is in a state to be able to do them.
43 /// This ensures that it's thread safe and there will be no conflicts.
44 /// Requests get returned by a different thread then they were requested by.
45 /// </summary>
46 public class ODERayCastRequestManager
47 {
48 /// <summary>
49 /// Pending ray requests
50 /// </summary>
51 protected OpenSim.Framework.LocklessQueue<ODERayRequest> m_PendingRequests = new OpenSim.Framework.LocklessQueue<ODERayRequest>();
52
53 /// <summary>
54 /// Scene that created this object.
55 /// </summary>
56 private ODEScene m_scene;
57
58 IntPtr ray; // the ray. we only need one for our lifetime
59 IntPtr Sphere;
60 IntPtr Box;
61 IntPtr Plane;
62
63 private int CollisionContactGeomsPerTest = 25;
64 private const int DefaultMaxCount = 25;
65 private const int MaxTimePerCallMS = 30;
66
67 /// <summary>
68 /// ODE near callback delegate
69 /// </summary>
70 private d.NearCallback nearCallback;
71 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
72 private List<ContactResult> m_contactResults = new List<ContactResult>();
73 private RayFilterFlags CurrentRayFilter;
74 private int CurrentMaxCount;
75
76 public ODERayCastRequestManager(ODEScene pScene)
77 {
78 m_scene = pScene;
79 nearCallback = near;
80 ray = d.CreateRay(IntPtr.Zero, 1.0f);
81 d.GeomSetCategoryBits(ray, 0);
82 Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f);
83 d.GeomSetCategoryBits(Box, 0);
84 Sphere = d.CreateSphere(IntPtr.Zero,1.0f);
85 d.GeomSetCategoryBits(Sphere, 0);
86 Plane = d.CreatePlane(IntPtr.Zero, 0f,0f,1f,1f);
87 d.GeomSetCategoryBits(Sphere, 0);
88 }
89
90 public void QueueRequest(ODERayRequest req)
91 {
92 if (req.Count == 0)
93 req.Count = DefaultMaxCount;
94
95 m_PendingRequests.Enqueue(req);
96 }
97
98 /// <summary>
99 /// Process all queued raycast requests
100 /// </summary>
101 /// <returns>Time in MS the raycasts took to process.</returns>
102 public int ProcessQueuedRequests()
103 {
104
105 if (m_PendingRequests.Count <= 0)
106 return 0;
107
108 if (m_scene.ContactgeomsArray == IntPtr.Zero || ray == IntPtr.Zero)
109 // oops something got wrong or scene isn't ready still
110 {
111 m_PendingRequests.Clear();
112 return 0;
113 }
114
115 int time = Util.EnvironmentTickCount();
116
117 ODERayRequest req;
118 int closestHit;
119 int backfacecull;
120 CollisionCategories catflags;
121
122 while (m_PendingRequests.Dequeue(out req))
123 {
124 if (req.callbackMethod != null)
125 {
126 IntPtr geom = IntPtr.Zero;
127 if (req.actor != null)
128 {
129 if (m_scene.haveActor(req.actor))
130 {
131 if (req.actor is OdePrim)
132 geom = ((OdePrim)req.actor).prim_geom;
133 else if (req.actor is OdeCharacter)
134 geom = ((OdePrim)req.actor).prim_geom;
135 }
136 if (geom == IntPtr.Zero)
137 {
138 NoContacts(req);
139 continue;
140 }
141 }
142
143 CurrentRayFilter = req.filter;
144 CurrentMaxCount = req.Count;
145
146 CollisionContactGeomsPerTest = req.Count & 0xffff;
147
148 closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1);
149 backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1);
150
151 if (req.callbackMethod is ProbeBoxCallback)
152 {
153 if (CollisionContactGeomsPerTest > 80)
154 CollisionContactGeomsPerTest = 80;
155 d.GeomBoxSetLengths(Box, req.Normal.X, req.Normal.Y, req.Normal.Z);
156 d.GeomSetPosition(Box, req.Origin.X, req.Origin.Y, req.Origin.Z);
157 d.Quaternion qtmp;
158 qtmp.X = req.orientation.X;
159 qtmp.Y = req.orientation.Y;
160 qtmp.Z = req.orientation.Z;
161 qtmp.W = req.orientation.W;
162 d.GeomSetQuaternion(Box, ref qtmp);
163 }
164 else if (req.callbackMethod is ProbeSphereCallback)
165 {
166 if (CollisionContactGeomsPerTest > 80)
167 CollisionContactGeomsPerTest = 80;
168
169 d.GeomSphereSetRadius(Sphere, req.length);
170 d.GeomSetPosition(Sphere, req.Origin.X, req.Origin.Y, req.Origin.Z);
171 }
172 else if (req.callbackMethod is ProbePlaneCallback)
173 {
174 if (CollisionContactGeomsPerTest > 80)
175 CollisionContactGeomsPerTest = 80;
176
177 d.GeomPlaneSetParams(Plane, req.Normal.X, req.Normal.Y, req.Normal.Z, req.length);
178 }
179
180 else
181 {
182 if (CollisionContactGeomsPerTest > 25)
183 CollisionContactGeomsPerTest = 25;
184
185 d.GeomRaySetLength(ray, req.length);
186 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
187 d.GeomRaySetParams(ray, 0, backfacecull);
188
189 if (req.callbackMethod is RaycastCallback)
190 {
191 // if we only want one get only one per Collision pair saving memory
192 CurrentRayFilter |= RayFilterFlags.ClosestHit;
193 d.GeomRaySetClosestHit(ray, 1);
194 }
195 else
196 d.GeomRaySetClosestHit(ray, closestHit);
197 }
198
199 if ((CurrentRayFilter & RayFilterFlags.ContactsUnImportant) != 0)
200 unchecked
201 {
202 CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT;
203 }
204
205 if (geom == IntPtr.Zero)
206 {
207 // translate ray filter to Collision flags
208 catflags = 0;
209 if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0)
210 catflags |= CollisionCategories.VolumeDtc;
211 if ((CurrentRayFilter & RayFilterFlags.phantom) != 0)
212 catflags |= CollisionCategories.Phantom;
213 if ((CurrentRayFilter & RayFilterFlags.agent) != 0)
214 catflags |= CollisionCategories.Character;
215 if ((CurrentRayFilter & RayFilterFlags.PrimsNonPhantom) != 0)
216 catflags |= CollisionCategories.Geom;
217 if ((CurrentRayFilter & RayFilterFlags.land) != 0)
218 catflags |= CollisionCategories.Land;
219 if ((CurrentRayFilter & RayFilterFlags.water) != 0)
220 catflags |= CollisionCategories.Water;
221
222 if (catflags != 0)
223 {
224 if (req.callbackMethod is ProbeBoxCallback)
225 {
226 catflags |= CollisionCategories.Space;
227 d.GeomSetCollideBits(Box, (uint)catflags);
228 d.GeomSetCategoryBits(Box, (uint)catflags);
229 doProbe(req, Box);
230 }
231 else if (req.callbackMethod is ProbeSphereCallback)
232 {
233 catflags |= CollisionCategories.Space;
234 d.GeomSetCollideBits(Sphere, (uint)catflags);
235 d.GeomSetCategoryBits(Sphere, (uint)catflags);
236 doProbe(req, Sphere);
237 }
238 else if (req.callbackMethod is ProbePlaneCallback)
239 {
240 catflags |= CollisionCategories.Space;
241 d.GeomSetCollideBits(Plane, (uint)catflags);
242 d.GeomSetCategoryBits(Plane, (uint)catflags);
243 doPlane(req,IntPtr.Zero);
244 }
245 else
246 {
247 d.GeomSetCollideBits(ray, (uint)catflags);
248 doSpaceRay(req);
249 }
250 }
251 }
252 else
253 {
254 // if we select a geom don't use filters
255
256 if (req.callbackMethod is ProbePlaneCallback)
257 {
258 d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All);
259 doPlane(req,geom);
260 }
261 else
262 {
263 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
264 doGeomRay(req,geom);
265 }
266 }
267 }
268
269 if (Util.EnvironmentTickCountSubtract(time) > MaxTimePerCallMS)
270 break;
271 }
272
273 lock (m_contactResults)
274 m_contactResults.Clear();
275
276 return Util.EnvironmentTickCountSubtract(time);
277 }
278 /// <summary>
279 /// Method that actually initiates the raycast with spaces
280 /// </summary>
281 /// <param name="req"></param>
282 ///
283
284 private void NoContacts(ODERayRequest req)
285 {
286 if (req.callbackMethod is RaycastCallback)
287 {
288 ((RaycastCallback)req.callbackMethod)(false, Vector3.Zero, 0, 0, Vector3.Zero);
289 return;
290 }
291 List<ContactResult> cresult = new List<ContactResult>();
292
293 if (req.callbackMethod is RayCallback)
294 ((RayCallback)req.callbackMethod)(cresult);
295 else if (req.callbackMethod is ProbeBoxCallback)
296 ((ProbeBoxCallback)req.callbackMethod)(cresult);
297 else if (req.callbackMethod is ProbeSphereCallback)
298 ((ProbeSphereCallback)req.callbackMethod)(cresult);
299 }
300
301 private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhantom;
302// private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
303 private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhantom;
304
305 private void doSpaceRay(ODERayRequest req)
306 {
307 // Collide tests
308 if ((CurrentRayFilter & FilterActiveSpace) != 0)
309 {
310 d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
311 d.SpaceCollide2(ray, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
312 }
313 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
314 d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
315 if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
316 {
317 // current ode land to ray collisions is very bad
318 // so for now limit its range badly
319 if (req.length > 60.0f)
320 {
321 Vector3 t = req.Normal * req.length;
322 float tmp = t.X * t.X + t.Y * t.Y;
323 if(tmp > 2500)
324 {
325 float tmp2 = req.length * req.length - tmp + 2500;
326 tmp2 = (float)Math.Sqrt(tmp2);
327 d.GeomRaySetLength(ray, tmp2);
328 }
329
330 }
331 d.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
332 }
333
334 if (req.callbackMethod is RaycastCallback)
335 {
336 // Define default results
337 bool hitYN = false;
338 uint hitConsumerID = 0;
339 float distance = float.MaxValue;
340 Vector3 closestcontact = Vector3.Zero;
341 Vector3 snormal = Vector3.Zero;
342
343 // Find closest contact and object.
344 lock (m_contactResults)
345 {
346 foreach (ContactResult cResult in m_contactResults)
347 {
348 if(cResult.Depth < distance)
349 {
350 closestcontact = cResult.Pos;
351 hitConsumerID = cResult.ConsumerID;
352 distance = cResult.Depth;
353 snormal = cResult.Normal;
354 }
355 }
356 m_contactResults.Clear();
357 }
358
359 if (distance > 0 && distance < float.MaxValue)
360 hitYN = true;
361 ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
362 }
363 else
364 {
365 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
366 lock (m_PendingRequests)
367 {
368 cresult.AddRange(m_contactResults);
369 m_contactResults.Clear();
370 }
371 ((RayCallback)req.callbackMethod)(cresult);
372 }
373 }
374
375 private void doProbe(ODERayRequest req, IntPtr probe)
376 {
377 // Collide tests
378 if ((CurrentRayFilter & FilterActiveSpace) != 0)
379 {
380 d.SpaceCollide2(probe, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
381 d.SpaceCollide2(probe, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
382 }
383 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
384 d.SpaceCollide2(probe, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
385 if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
386 d.SpaceCollide2(probe, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
387
388 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
389 lock (m_PendingRequests)
390 {
391 cresult.AddRange(m_contactResults);
392 m_contactResults.Clear();
393 }
394 if (req.callbackMethod is ProbeBoxCallback)
395 ((ProbeBoxCallback)req.callbackMethod)(cresult);
396 else if (req.callbackMethod is ProbeSphereCallback)
397 ((ProbeSphereCallback)req.callbackMethod)(cresult);
398 }
399
400 private void doPlane(ODERayRequest req,IntPtr geom)
401 {
402 // Collide tests
403 if (geom == IntPtr.Zero)
404 {
405 if ((CurrentRayFilter & FilterActiveSpace) != 0)
406 {
407 d.SpaceCollide2(Plane, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
408 d.SpaceCollide2(Plane, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
409 }
410 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
411 d.SpaceCollide2(Plane, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
412 if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
413 d.SpaceCollide2(Plane, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
414 }
415 else
416 {
417 d.SpaceCollide2(Plane, geom, IntPtr.Zero, nearCallback);
418 }
419
420 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
421 lock (m_PendingRequests)
422 {
423 cresult.AddRange(m_contactResults);
424 m_contactResults.Clear();
425 }
426
427 ((ProbePlaneCallback)req.callbackMethod)(cresult);
428 }
429
430 /// <summary>
431 /// Method that actually initiates the raycast with a geom
432 /// </summary>
433 /// <param name="req"></param>
434 private void doGeomRay(ODERayRequest req, IntPtr geom)
435 {
436 // Collide test
437 d.SpaceCollide2(ray, geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
438
439 if (req.callbackMethod is RaycastCallback)
440 {
441 // Define default results
442 bool hitYN = false;
443 uint hitConsumerID = 0;
444 float distance = float.MaxValue;
445 Vector3 closestcontact = Vector3.Zero;
446 Vector3 snormal = Vector3.Zero;
447
448 // Find closest contact and object.
449 lock (m_contactResults)
450 {
451 foreach (ContactResult cResult in m_contactResults)
452 {
453 if(cResult.Depth < distance )
454 {
455 closestcontact = cResult.Pos;
456 hitConsumerID = cResult.ConsumerID;
457 distance = cResult.Depth;
458 snormal = cResult.Normal;
459 }
460 }
461 m_contactResults.Clear();
462 }
463
464 if (distance > 0 && distance < float.MaxValue)
465 hitYN = true;
466
467 ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
468 }
469 else
470 {
471 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
472 lock (m_PendingRequests)
473 {
474 cresult.AddRange(m_contactResults);
475 m_contactResults.Clear();
476 }
477 ((RayCallback)req.callbackMethod)(cresult);
478 }
479 }
480
481 private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
482 {
483 IntPtr ContactgeomsArray = m_scene.ContactgeomsArray;
484 if (ContactgeomsArray == IntPtr.Zero || index >= CollisionContactGeomsPerTest)
485 return false;
486
487 IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf));
488 newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom));
489 return true;
490 }
491
492 // This is the standard Near. g1 is the ray
493 private void near(IntPtr space, IntPtr g1, IntPtr g2)
494 {
495 if (g2 == IntPtr.Zero || g1 == g2)
496 return;
497
498 if (m_contactResults.Count >= CurrentMaxCount)
499 return;
500
501 if (d.GeomIsSpace(g2))
502 {
503 try
504 {
505 d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
506 }
507 catch (Exception e)
508 {
509 m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
510 }
511 return;
512 }
513
514 int count = 0;
515 try
516 {
517 count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
518 }
519 catch (Exception e)
520 {
521 m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
522 return;
523 }
524
525 if (count == 0)
526 return;
527/*
528 uint cat1 = d.GeomGetCategoryBits(g1);
529 uint cat2 = d.GeomGetCategoryBits(g2);
530 uint col1 = d.GeomGetCollideBits(g1);
531 uint col2 = d.GeomGetCollideBits(g2);
532*/
533
534 uint ID = 0;
535 PhysicsActor p2 = null;
536
537 m_scene.actor_name_map.TryGetValue(g2, out p2);
538
539 if (p2 == null)
540 return;
541
542 switch (p2.PhysicsActorType)
543 {
544 case (int)ActorTypes.Prim:
545
546 RayFilterFlags thisFlags;
547
548 if (p2.IsPhysical)
549 thisFlags = RayFilterFlags.physical;
550 else
551 thisFlags = RayFilterFlags.nonphysical;
552
553 if (p2.Phantom)
554 thisFlags |= RayFilterFlags.phantom;
555
556 if (p2.IsVolumeDtc)
557 thisFlags |= RayFilterFlags.volumedtc;
558
559 if ((thisFlags & CurrentRayFilter) == 0)
560 return;
561
562 ID = ((OdePrim)p2).LocalID;
563 break;
564
565 case (int)ActorTypes.Agent:
566
567 if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
568 return;
569 else
570 ID = ((OdeCharacter)p2).LocalID;
571 break;
572
573 case (int)ActorTypes.Ground:
574
575 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
576 return;
577 break;
578
579 case (int)ActorTypes.Water:
580
581 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
582 return;
583 break;
584
585 default:
586 break;
587 }
588
589 d.ContactGeom curcontact = new d.ContactGeom();
590
591 // closestHit for now only works for meshs, so must do it for others
592 if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
593 {
594 // Loop all contacts, build results.
595 for (int i = 0; i < count; i++)
596 {
597 if (!GetCurContactGeom(i, ref curcontact))
598 break;
599
600 ContactResult collisionresult = new ContactResult();
601 collisionresult.ConsumerID = ID;
602 collisionresult.Pos.X = curcontact.pos.X;
603 collisionresult.Pos.Y = curcontact.pos.Y;
604 collisionresult.Pos.Z = curcontact.pos.Z;
605 collisionresult.Depth = curcontact.depth;
606 collisionresult.Normal.X = curcontact.normal.X;
607 collisionresult.Normal.Y = curcontact.normal.Y;
608 collisionresult.Normal.Z = curcontact.normal.Z;
609 lock (m_contactResults)
610 {
611 m_contactResults.Add(collisionresult);
612 if (m_contactResults.Count >= CurrentMaxCount)
613 return;
614 }
615 }
616 }
617 else
618 {
619 // keep only closest contact
620 ContactResult collisionresult = new ContactResult();
621 collisionresult.ConsumerID = ID;
622 collisionresult.Depth = float.MaxValue;
623
624 for (int i = 0; i < count; i++)
625 {
626 if (!GetCurContactGeom(i, ref curcontact))
627 break;
628
629 if (curcontact.depth < collisionresult.Depth)
630 {
631 collisionresult.Pos.X = curcontact.pos.X;
632 collisionresult.Pos.Y = curcontact.pos.Y;
633 collisionresult.Pos.Z = curcontact.pos.Z;
634 collisionresult.Depth = curcontact.depth;
635 collisionresult.Normal.X = curcontact.normal.X;
636 collisionresult.Normal.Y = curcontact.normal.Y;
637 collisionresult.Normal.Z = curcontact.normal.Z;
638 }
639 }
640
641 if (collisionresult.Depth != float.MaxValue)
642 {
643 lock (m_contactResults)
644 m_contactResults.Add(collisionresult);
645 }
646 }
647 }
648
649 /// <summary>
650 /// Dereference the creator scene so that it can be garbage collected if needed.
651 /// </summary>
652 internal void Dispose()
653 {
654 m_scene = null;
655 if (ray != IntPtr.Zero)
656 {
657 d.GeomDestroy(ray);
658 ray = IntPtr.Zero;
659 }
660 if (Box != IntPtr.Zero)
661 {
662 d.GeomDestroy(Box);
663 Box = IntPtr.Zero;
664 }
665 if (Sphere != IntPtr.Zero)
666 {
667 d.GeomDestroy(Sphere);
668 Sphere = IntPtr.Zero;
669 }
670 if (Plane != IntPtr.Zero)
671 {
672 d.GeomDestroy(Plane);
673 Plane = IntPtr.Zero;
674 }
675 }
676 }
677
678 public struct ODERayRequest
679 {
680 public PhysicsActor actor;
681 public Vector3 Origin;
682 public Vector3 Normal;
683 public int Count;
684 public float length;
685 public object callbackMethod;
686 public RayFilterFlags filter;
687 public Quaternion orientation;
688 }
689}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs
new file mode 100644
index 0000000..0b51820
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs
@@ -0,0 +1,2824 @@
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
28// Revision 2011/12/13 by Ubit Umarov
29//#define SPAM
30
31using System;
32using System.Collections.Generic;
33using System.Linq;
34using System.Reflection;
35using System.Runtime.InteropServices;
36using System.Threading;
37using System.IO;
38using System.Diagnostics;
39using log4net;
40using Nini.Config;
41using Mono.Addins;
42using OdeAPI;
43using OpenSim.Framework;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.PhysicsModules.SharedBase;
47using OpenMetaverse;
48
49namespace OpenSim.Region.PhysicsModule.ubOde
50{
51 // colision flags of things others can colide with
52 // rays, sensors, probes removed since can't be colided with
53 // The top space where things are placed provided further selection
54 // ie physical are in active space nonphysical in static
55 // this should be exclusive as possible
56
57 [Flags]
58 public enum CollisionCategories : uint
59 {
60 Disabled = 0,
61 //by 'things' types
62 Space = 0x01,
63 Geom = 0x02, // aka prim/part
64 Character = 0x04,
65 Land = 0x08,
66 Water = 0x010,
67
68 // by state
69 Phantom = 0x01000,
70 VolumeDtc = 0x02000,
71 Selected = 0x04000,
72 NoShape = 0x08000,
73
74
75 All = 0xffffffff
76 }
77
78 /// <summary>
79 /// Material type for a primitive
80 /// </summary>
81 public enum Material : int
82 {
83 /// <summary></summary>
84 Stone = 0,
85 /// <summary></summary>
86 Metal = 1,
87 /// <summary></summary>
88 Glass = 2,
89 /// <summary></summary>
90 Wood = 3,
91 /// <summary></summary>
92 Flesh = 4,
93 /// <summary></summary>
94 Plastic = 5,
95 /// <summary></summary>
96 Rubber = 6,
97
98 light = 7 // compatibility with old viewers
99 }
100
101 public enum changes : int
102 {
103 Add = 0, // arg null. finishs the prim creation. should be used internally only ( to remove later ?)
104 Remove,
105 Link, // arg AuroraODEPrim new parent prim or null to delink. Makes the prim part of a object with prim parent as root
106 // or removes from a object if arg is null
107 DeLink,
108 Position, // arg Vector3 new position in world coords. Changes prim position. Prim must know if it is root or child
109 Orientation, // arg Quaternion new orientation in world coords. Changes prim position. Prim must know it it is root or child
110 PosOffset, // not in use
111 // arg Vector3 new position in local coords. Changes prim position in object
112 OriOffset, // not in use
113 // arg Vector3 new position in local coords. Changes prim position in object
114 Velocity,
115 TargetVelocity,
116 AngVelocity,
117 Acceleration,
118 Force,
119 Torque,
120 Momentum,
121
122 AddForce,
123 AddAngForce,
124 AngLock,
125
126 Buoyancy,
127
128 PIDTarget,
129 PIDTau,
130 PIDActive,
131
132 PIDHoverHeight,
133 PIDHoverType,
134 PIDHoverTau,
135 PIDHoverActive,
136
137 Size,
138 AvatarSize,
139 Shape,
140 PhysRepData,
141 AddPhysRep,
142
143 CollidesWater,
144 VolumeDtc,
145
146 Physical,
147 Phantom,
148 Selected,
149 disabled,
150 building,
151
152 VehicleType,
153 VehicleFloatParam,
154 VehicleVectorParam,
155 VehicleRotationParam,
156 VehicleFlags,
157 SetVehicle,
158 SetInertia,
159
160 Null //keep this last used do dim the methods array. does nothing but pulsing the prim
161 }
162
163 public struct ODEchangeitem
164 {
165 public PhysicsActor actor;
166 public OdeCharacter character;
167 public changes what;
168 public Object arg;
169 }
170
171 public class ODEScene : PhysicsScene
172 {
173 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
174
175 public bool m_OSOdeLib = false;
176 public Scene m_frameWorkScene = null;
177
178// private int threadid = 0;
179
180// const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce;
181
182 const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2;
183 const float comumContactERP = 0.75f;
184 const float comumContactCFM = 0.0001f;
185 const float comumContactSLIP = 0f;
186
187 float frictionMovementMult = 0.8f;
188
189 float TerrainBounce = 0.001f;
190 float TerrainFriction = 0.3f;
191
192 public float AvatarFriction = 0;// 0.9f * 0.5f;
193
194 // this netx dimensions are only relevant for terrain partition (mega regions)
195 // WorldExtents below has the simulation dimensions
196 // they should be identical except on mega regions
197 private uint m_regionWidth = Constants.RegionSize;
198 private uint m_regionHeight = Constants.RegionSize;
199
200 public float ODE_STEPSIZE = 0.020f;
201 public float HalfOdeStep = 0.01f;
202 public int odetimestepMS = 20; // rounded
203 private float metersInSpace = 25.6f;
204 private float m_timeDilation = 1.0f;
205
206 private double m_lastframe;
207 private double m_lastMeshExpire;
208
209 public float gravityx = 0f;
210 public float gravityy = 0f;
211 public float gravityz = -9.8f;
212
213 private float waterlevel = 0f;
214 private int framecount = 0;
215
216 private float avDensity = 80f;
217 private float avMovementDivisorWalk = 1.3f;
218 private float avMovementDivisorRun = 0.8f;
219 private float minimumGroundFlightOffset = 3f;
220 public float maximumMassObject = 10000.01f;
221 public float geomDefaultDensity = 10.0f;
222
223 public float maximumAngularVelocity = 12.0f; // default 12rad/s
224 public float maxAngVelocitySQ = 144f; // squared value
225
226 public float bodyPIDD = 35f;
227 public float bodyPIDG = 25;
228
229 public int bodyFramesAutoDisable = 5;
230
231 private d.NearCallback nearCallback;
232
233 private Dictionary<uint,OdePrim> _prims = new Dictionary<uint,OdePrim>();
234 private HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>();
235 private HashSet<OdePrim> _activeprims = new HashSet<OdePrim>();
236 private HashSet<OdePrim> _activegroups = new HashSet<OdePrim>();
237
238 public OpenSim.Framework.LocklessQueue<ODEchangeitem> ChangesQueue = new OpenSim.Framework.LocklessQueue<ODEchangeitem>();
239
240 /// <summary>
241 /// A list of actors that should receive collision events.
242 /// </summary>
243 private List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>();
244 private List<PhysicsActor> _collisionEventPrimRemove = new List<PhysicsActor>();
245
246 private HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>();
247 public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>();
248
249 private float contactsurfacelayer = 0.002f;
250
251 private int contactsPerCollision = 80;
252 internal IntPtr ContactgeomsArray = IntPtr.Zero;
253 private IntPtr GlobalContactsArray = IntPtr.Zero;
254 private d.Contact SharedTmpcontact = new d.Contact();
255
256 const int maxContactsbeforedeath = 6000;
257 private volatile int m_global_contactcount = 0;
258
259 private IntPtr contactgroup;
260
261 public ContactData[] m_materialContactsData = new ContactData[8];
262
263 private IntPtr TerrainGeom;
264 private float[] TerrainHeightFieldHeight;
265 private GCHandle TerrainHeightFieldHeightsHandler = new GCHandle();
266
267 private int m_physicsiterations = 15;
268 private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag
269// private PhysicsActor PANull = new NullPhysicsActor();
270 private float step_time = 0.0f;
271
272 public IntPtr world;
273
274 // split the spaces acording to contents type
275 // ActiveSpace contains characters and active prims
276 // StaticSpace contains land and other that is mostly static in enviroment
277 // this can contain subspaces, like the grid in staticspace
278 // as now space only contains this 2 top spaces
279
280 public IntPtr TopSpace; // the global space
281 public IntPtr ActiveSpace; // space for active prims
282 public IntPtr CharsSpace; // space for active prims
283 public IntPtr StaticSpace; // space for the static things around
284 public IntPtr GroundSpace; // space for ground
285
286 // some speedup variables
287 private int spaceGridMaxX;
288 private int spaceGridMaxY;
289 private float spacesPerMeterX;
290 private float spacesPerMeterY;
291
292 // split static geometry collision into a grid as before
293 private IntPtr[,] staticPrimspace;
294 private IntPtr[] staticPrimspaceOffRegion;
295
296 public Object OdeLock;
297 public static Object SimulationLock;
298
299 public IMesher mesher;
300
301 public IConfigSource m_config;
302
303 public bool physics_logging = false;
304 public int physics_logging_interval = 0;
305 public bool physics_logging_append_existing_logfile = false;
306
307 public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize);
308
309 private ODERayCastRequestManager m_rayCastManager;
310 public ODEMeshWorker m_meshWorker;
311
312 /* maybe needed if ode uses tls
313 private void checkThread()
314 {
315
316 int th = Thread.CurrentThread.ManagedThreadId;
317 if(th != threadid)
318 {
319 threadid = th;
320 d.AllocateODEDataForThread(~0U);
321 }
322 }
323 */
324
325 IConfig physicsconfig = null;
326
327 public ODEScene(Scene pscene, IConfigSource psourceconfig, string pname, string pversion, bool pOSOdeLib)
328 {
329 OdeLock = new Object();
330
331 EngineType = pname;
332 PhysicsSceneName = EngineType + "/" + pscene.RegionInfo.RegionName;
333 EngineName = pname + " " + pversion;
334 m_config = psourceconfig;
335 m_OSOdeLib = pOSOdeLib;
336
337// m_OSOdeLib = false; //debug
338
339 m_frameWorkScene = pscene;
340
341 m_frameWorkScene.RegisterModuleInterface<PhysicsScene>(this);
342
343 Initialization();
344
345 base.Initialise(m_frameWorkScene.PhysicsRequestAsset,
346 (m_frameWorkScene.Heightmap != null ? m_frameWorkScene.Heightmap.GetFloatsSerialised() : new float[m_frameWorkScene.RegionInfo.RegionSizeX * m_frameWorkScene.RegionInfo.RegionSizeY]),
347 (float)m_frameWorkScene.RegionInfo.RegionSettings.WaterHeight);
348 }
349
350 public void RegionLoaded()
351 {
352 mesher = m_frameWorkScene.RequestModuleInterface<IMesher>();
353 if (mesher == null)
354 {
355 m_log.ErrorFormat("[ubOde] No mesher. module disabled");
356 return;
357 }
358
359 m_meshWorker = new ODEMeshWorker(this, m_log, mesher, physicsconfig);
360 m_frameWorkScene.PhysicsEnabled = true;
361 }
362 /// <summary>
363 /// Initiailizes the scene
364 /// Sets many properties that ODE requires to be stable
365 /// These settings need to be tweaked 'exactly' right or weird stuff happens.
366 /// </summary>
367 private void Initialization()
368 {
369 d.AllocateODEDataForThread(~0U);
370
371 SimulationLock = new Object();
372
373 nearCallback = near;
374
375 m_rayCastManager = new ODERayCastRequestManager(this);
376
377 WorldExtents.X = m_frameWorkScene.RegionInfo.RegionSizeX;
378 m_regionWidth = (uint)WorldExtents.X;
379 WorldExtents.Y = m_frameWorkScene.RegionInfo.RegionSizeY;
380 m_regionHeight = (uint)WorldExtents.Y;
381
382 lock (OdeLock)
383 {
384 // Create the world and the first space
385 try
386 {
387 world = d.WorldCreate();
388 TopSpace = d.HashSpaceCreate(IntPtr.Zero);
389
390 // now the major subspaces
391 ActiveSpace = d.HashSpaceCreate(TopSpace);
392 CharsSpace = d.HashSpaceCreate(TopSpace);
393 StaticSpace = d.HashSpaceCreate(TopSpace);
394 GroundSpace = d.HashSpaceCreate(TopSpace);
395 }
396 catch
397 {
398 // i must RtC#FM
399 // i did!
400 }
401
402 d.HashSpaceSetLevels(TopSpace, -5, 12);
403 d.HashSpaceSetLevels(ActiveSpace, -5, 10);
404 d.HashSpaceSetLevels(CharsSpace, -4, 3);
405 d.HashSpaceSetLevels(StaticSpace, -5, 12);
406 d.HashSpaceSetLevels(GroundSpace, 0, 8);
407
408 // demote to second level
409 d.SpaceSetSublevel(ActiveSpace, 1);
410 d.SpaceSetSublevel(CharsSpace, 1);
411 d.SpaceSetSublevel(StaticSpace, 1);
412 d.SpaceSetSublevel(GroundSpace, 1);
413
414 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
415 CollisionCategories.Geom |
416 CollisionCategories.Character |
417 CollisionCategories.Phantom |
418 CollisionCategories.VolumeDtc
419 ));
420 d.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space |
421 CollisionCategories.Geom |
422 CollisionCategories.Character |
423 CollisionCategories.Phantom |
424 CollisionCategories.VolumeDtc
425 ));
426 d.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space |
427 CollisionCategories.Geom |
428 CollisionCategories.Character |
429 CollisionCategories.Phantom |
430 CollisionCategories.VolumeDtc
431 ));
432 d.GeomSetCollideBits(CharsSpace, 0);
433
434 d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space |
435 CollisionCategories.Geom |
436 // CollisionCategories.Land |
437 // CollisionCategories.Water |
438 CollisionCategories.Phantom |
439 CollisionCategories.VolumeDtc
440 ));
441 d.GeomSetCollideBits(StaticSpace, 0);
442
443 d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land));
444 d.GeomSetCollideBits(GroundSpace, 0);
445
446 contactgroup = d.JointGroupCreate(maxContactsbeforedeath + 1);
447 //contactgroup
448
449 d.WorldSetAutoDisableFlag(world, false);
450 }
451
452
453 // checkThread();
454
455
456 // Defaults
457
458 int contactsPerCollision = 80;
459
460 physicsconfig = null;
461
462 if (m_config != null)
463 {
464 physicsconfig = m_config.Configs["ODEPhysicsSettings"];
465 if (physicsconfig != null)
466 {
467 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
468 gravityy = physicsconfig.GetFloat("world_gravityy", gravityy);
469 gravityz = physicsconfig.GetFloat("world_gravityz", gravityz);
470
471 metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace);
472
473 // contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer);
474
475 ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE);
476
477 avDensity = physicsconfig.GetFloat("av_density", avDensity);
478 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
479 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);
480
481 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);
482
483 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
484// bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
485
486 physics_logging = physicsconfig.GetBoolean("physics_logging", false);
487 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
488 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
489
490 minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", minimumGroundFlightOffset);
491 maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", maximumMassObject);
492
493 avDensity *= 3f / 80f; // scale other engines density option to this
494 }
495 }
496
497 float heartbeat = 1/m_frameWorkScene.FrameTime;
498 maximumAngularVelocity = 0.49f * heartbeat *(float)Math.PI;
499 maxAngVelocitySQ = maximumAngularVelocity * maximumAngularVelocity;
500
501 d.WorldSetCFM(world, comumContactCFM);
502 d.WorldSetERP(world, comumContactERP);
503
504 d.WorldSetGravity(world, gravityx, gravityy, gravityz);
505
506 d.WorldSetLinearDamping(world, 0.001f);
507 d.WorldSetAngularDamping(world, 0.002f);
508 d.WorldSetAngularDampingThreshold(world, 0f);
509 d.WorldSetLinearDampingThreshold(world, 0f);
510 d.WorldSetMaxAngularSpeed(world, maximumAngularVelocity);
511
512 d.WorldSetQuickStepNumIterations(world, m_physicsiterations);
513
514 d.WorldSetContactSurfaceLayer(world, contactsurfacelayer);
515 d.WorldSetContactMaxCorrectingVel(world, 60.0f);
516
517 HalfOdeStep = ODE_STEPSIZE * 0.5f;
518 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f);
519
520 ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf);
521 GlobalContactsArray = Marshal.AllocHGlobal((maxContactsbeforedeath + 100) * d.Contact.unmanagedSizeOf);
522
523 SharedTmpcontact.geom.g1 = IntPtr.Zero;
524 SharedTmpcontact.geom.g2 = IntPtr.Zero;
525
526 SharedTmpcontact.geom.side1 = -1;
527 SharedTmpcontact.geom.side2 = -1;
528
529 SharedTmpcontact.surface.mode = comumContactFlags;
530 SharedTmpcontact.surface.mu = 0;
531 SharedTmpcontact.surface.bounce = 0;
532 SharedTmpcontact.surface.bounce_vel = 1.5f;
533 SharedTmpcontact.surface.soft_cfm = comumContactCFM;
534 SharedTmpcontact.surface.soft_erp = comumContactERP;
535 SharedTmpcontact.surface.slip1 = comumContactSLIP;
536 SharedTmpcontact.surface.slip2 = comumContactSLIP;
537
538 m_materialContactsData[(int)Material.Stone].mu = 0.8f;
539 m_materialContactsData[(int)Material.Stone].bounce = 0.4f;
540
541 m_materialContactsData[(int)Material.Metal].mu = 0.3f;
542 m_materialContactsData[(int)Material.Metal].bounce = 0.4f;
543
544 m_materialContactsData[(int)Material.Glass].mu = 0.2f;
545 m_materialContactsData[(int)Material.Glass].bounce = 0.7f;
546
547 m_materialContactsData[(int)Material.Wood].mu = 0.6f;
548 m_materialContactsData[(int)Material.Wood].bounce = 0.5f;
549
550 m_materialContactsData[(int)Material.Flesh].mu = 0.9f;
551 m_materialContactsData[(int)Material.Flesh].bounce = 0.3f;
552
553 m_materialContactsData[(int)Material.Plastic].mu = 0.4f;
554 m_materialContactsData[(int)Material.Plastic].bounce = 0.7f;
555
556 m_materialContactsData[(int)Material.Rubber].mu = 0.9f;
557 m_materialContactsData[(int)Material.Rubber].bounce = 0.95f;
558
559 m_materialContactsData[(int)Material.light].mu = 0.0f;
560 m_materialContactsData[(int)Material.light].bounce = 0.0f;
561
562
563 spacesPerMeterX = 1.0f / metersInSpace;
564 spacesPerMeterY = spacesPerMeterX;
565 spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeterX);
566 spaceGridMaxY = (int)(WorldExtents.Y * spacesPerMeterY);
567
568 if (spaceGridMaxX > 24)
569 {
570 spaceGridMaxX = 24;
571 spacesPerMeterX = spaceGridMaxX / WorldExtents.X;
572 }
573
574 if (spaceGridMaxY > 24)
575 {
576 spaceGridMaxY = 24;
577 spacesPerMeterY = spaceGridMaxY / WorldExtents.Y;
578 }
579
580 staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY];
581
582 // create all spaces now
583 int i, j;
584 IntPtr newspace;
585
586 for (i = 0; i < spaceGridMaxX; i++)
587 for (j = 0; j < spaceGridMaxY; j++)
588 {
589 newspace = d.HashSpaceCreate(StaticSpace);
590 d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space);
591 waitForSpaceUnlock(newspace);
592 d.SpaceSetSublevel(newspace, 2);
593 d.HashSpaceSetLevels(newspace, -2, 8);
594 d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space |
595 CollisionCategories.Geom |
596 CollisionCategories.Land |
597 CollisionCategories.Water |
598 CollisionCategories.Phantom |
599 CollisionCategories.VolumeDtc
600 ));
601 d.GeomSetCollideBits(newspace, 0);
602
603 staticPrimspace[i, j] = newspace;
604 }
605
606 // let this now be index limit
607 spaceGridMaxX--;
608 spaceGridMaxY--;
609
610 // create 4 off world spaces (x<0,x>max,y<0,y>max)
611 staticPrimspaceOffRegion = new IntPtr[4];
612
613 for (i = 0; i < 4; i++)
614 {
615 newspace = d.HashSpaceCreate(StaticSpace);
616 d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space);
617 waitForSpaceUnlock(newspace);
618 d.SpaceSetSublevel(newspace, 2);
619 d.HashSpaceSetLevels(newspace, -2, 8);
620 d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space |
621 CollisionCategories.Geom |
622 CollisionCategories.Land |
623 CollisionCategories.Water |
624 CollisionCategories.Phantom |
625 CollisionCategories.VolumeDtc
626 ));
627 d.GeomSetCollideBits(newspace, 0);
628
629 staticPrimspaceOffRegion[i] = newspace;
630 }
631
632 m_lastframe = Util.GetTimeStamp();
633 m_lastMeshExpire = m_lastframe;
634 step_time = -1;
635 }
636
637 internal void waitForSpaceUnlock(IntPtr space)
638 {
639 //if (space != IntPtr.Zero)
640 //while (d.SpaceLockQuery(space)) { } // Wait and do nothing
641 }
642
643 #region Collision Detection
644
645 // sets a global contact for a joint for contactgeom , and base contact description)
646 private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom,bool smooth)
647 {
648 if (m_global_contactcount >= maxContactsbeforedeath)
649 return IntPtr.Zero;
650
651 m_global_contactcount++;
652 if(smooth)
653 SharedTmpcontact.geom.depth = contactGeom.depth * 0.05f;
654 else
655 SharedTmpcontact.geom.depth = contactGeom.depth;
656 SharedTmpcontact.geom.pos = contactGeom.pos;
657 SharedTmpcontact.geom.normal = contactGeom.normal;
658
659 IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf));
660 Marshal.StructureToPtr(SharedTmpcontact, contact, true);
661 return d.JointCreateContactPtr(world, contactgroup, contact);
662 }
663
664 private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
665 {
666 if (ContactgeomsArray == IntPtr.Zero || index >= contactsPerCollision)
667 return false;
668
669 IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf));
670 newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom));
671 return true;
672 }
673
674 /// <summary>
675 /// This is our near callback. A geometry is near a body
676 /// </summary>
677 /// <param name="space">The space that contains the geoms. Remember, spaces are also geoms</param>
678 /// <param name="g1">a geometry or space</param>
679 /// <param name="g2">another geometry or space</param>
680 ///
681
682 private void near(IntPtr space, IntPtr g1, IntPtr g2)
683 {
684 // no lock here! It's invoked from within Simulate(), which is thread-locked
685
686 if (m_global_contactcount >= maxContactsbeforedeath)
687 return;
688
689 // Test if we're colliding a geom with a space.
690 // If so we have to drill down into the space recursively
691
692 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
693 return;
694
695 if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
696 {
697 // We'll be calling near recursivly if one
698 // of them is a space to find all of the
699 // contact points in the space
700 try
701 {
702 d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
703 }
704 catch (AccessViolationException)
705 {
706 m_log.Warn("[PHYSICS]: Unable to collide test a space");
707 return;
708 }
709 //here one should check collisions of geoms inside a space
710 // but on each space we only should have geoms that not colide amoung each other
711 // so we don't dig inside spaces
712 return;
713 }
714
715 // get geom bodies to check if we already a joint contact
716 // guess this shouldn't happen now
717 IntPtr b1 = d.GeomGetBody(g1);
718 IntPtr b2 = d.GeomGetBody(g2);
719
720 // d.GeomClassID id = d.GeomGetClass(g1);
721
722 // Figure out how many contact points we have
723 int count = 0;
724 try
725 {
726 // Colliding Geom To Geom
727 // This portion of the function 'was' blatantly ripped off from BoxStack.cs
728
729 if (g1 == g2)
730 return; // Can't collide with yourself
731
732// if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
733// return;
734 /*
735 // debug
736 PhysicsActor dp2;
737 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
738 {
739 d.AABB aabb;
740 d.GeomGetAABB(g2, out aabb);
741 float x = aabb.MaxX - aabb.MinX;
742 float y = aabb.MaxY - aabb.MinY;
743 float z = aabb.MaxZ - aabb.MinZ;
744 if (x > 60.0f || y > 60.0f || z > 60.0f)
745 {
746 if (!actor_name_map.TryGetValue(g2, out dp2))
747 m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2");
748 else
749 m_log.WarnFormat("[PHYSICS]: land versus large prim geo {0},size {1}, AABBsize <{2},{3},{4}>, at {5} ori {6},({7})",
750 dp2.Name, dp2.Size, x, y, z,
751 dp2.Position.ToString(),
752 dp2.Orientation.ToString(),
753 dp2.Orientation.Length());
754 return;
755 }
756 }
757 //
758 */
759
760
761 if (d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc ||
762 d.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc)
763 {
764 int cflags;
765 unchecked
766 {
767 cflags = (int)(1 | d.CONTACTS_UNIMPORTANT);
768 }
769 count = d.CollidePtr(g1, g2, cflags, ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
770 }
771 else
772 count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
773 }
774 catch (SEHException)
775 {
776 m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
777 // ode.drelease(world);
778 base.TriggerPhysicsBasedRestart();
779 }
780 catch (Exception e)
781 {
782 m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message);
783 return;
784 }
785
786 // contacts done
787 if (count == 0)
788 return;
789
790 // try get physical actors
791 PhysicsActor p1;
792 PhysicsActor p2;
793
794 if (!actor_name_map.TryGetValue(g1, out p1))
795 {
796 m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 1");
797 return;
798 }
799
800 if (!actor_name_map.TryGetValue(g2, out p2))
801 {
802 m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2");
803 return;
804 }
805
806
807 // get first contact
808 d.ContactGeom curContact = new d.ContactGeom();
809
810 if (!GetCurContactGeom(0, ref curContact))
811 return;
812
813 ContactPoint maxDepthContact = new ContactPoint();
814
815 // do volume detection case
816 if ((p1.IsVolumeDtc || p2.IsVolumeDtc))
817 {
818 maxDepthContact = new ContactPoint(
819 new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z),
820 new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z),
821 curContact.depth, false
822 );
823
824 collision_accounting_events(p1, p2, maxDepthContact);
825 return;
826 }
827
828 // big messy collision analises
829
830 float mu = 0;
831 float bounce = 0;
832// bool IgnoreNegSides = false;
833
834 ContactData contactdata1 = new ContactData(0, 0, false);
835 ContactData contactdata2 = new ContactData(0, 0, false);
836
837 bool dop1ava = false;
838 bool dop2ava = false;
839 bool ignore = false;
840 bool smoothMesh = false;
841
842 switch (p1.PhysicsActorType)
843 {
844 case (int)ActorTypes.Agent:
845 {
846 dop1ava = true;
847 switch (p2.PhysicsActorType)
848 {
849 case (int)ActorTypes.Agent:
850 case (int)ActorTypes.Prim:
851 break;
852
853 default:
854 ignore = true; // avatar to terrain and water ignored
855 break;
856 }
857 break;
858 }
859
860 case (int)ActorTypes.Prim:
861 {
862 switch (p2.PhysicsActorType)
863 {
864 case (int)ActorTypes.Agent:
865 dop2ava = true;
866 break;
867
868 case (int)ActorTypes.Prim:
869 Vector3 relV = p1.rootVelocity - p2.rootVelocity;
870 float relVlenSQ = relV.LengthSquared();
871 if (relVlenSQ > 0.0001f)
872 {
873 p1.CollidingObj = true;
874 p2.CollidingObj = true;
875 }
876 p1.getContactData(ref contactdata1);
877 p2.getContactData(ref contactdata2);
878 bounce = contactdata1.bounce * contactdata2.bounce;
879 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
880
881 if (relVlenSQ > 0.01f)
882 mu *= frictionMovementMult;
883
884 if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass &&
885 d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass)
886 smoothMesh = true;
887 break;
888
889 case (int)ActorTypes.Ground:
890 p1.getContactData(ref contactdata1);
891 bounce = contactdata1.bounce * TerrainBounce;
892 mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction);
893
894 Vector3 v1 = p1.rootVelocity;
895 if (Math.Abs(v1.X) > 0.1f || Math.Abs(v1.Y) > 0.1f)
896 mu *= frictionMovementMult;
897 p1.CollidingGround = true;
898
899 if(d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass)
900 smoothMesh = true;
901 break;
902
903 case (int)ActorTypes.Water:
904 default:
905 ignore = true;
906 break;
907 }
908 }
909 break;
910
911 case (int)ActorTypes.Ground:
912 if (p2.PhysicsActorType == (int)ActorTypes.Prim)
913 {
914 p2.CollidingGround = true;
915 p2.getContactData(ref contactdata2);
916 bounce = contactdata2.bounce * TerrainBounce;
917 mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction);
918
919// if (curContact.side1 > 0) // should be 2 ?
920// IgnoreNegSides = true;
921 Vector3 v2 = p2.rootVelocity;
922 if (Math.Abs(v2.X) > 0.1f || Math.Abs(v2.Y) > 0.1f)
923 mu *= frictionMovementMult;
924
925 if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass)
926 smoothMesh = true;
927 }
928 else
929 ignore = true;
930 break;
931
932 case (int)ActorTypes.Water:
933 default:
934 break;
935 }
936
937 if (ignore)
938 return;
939
940 IntPtr Joint;
941 bool FeetCollision = false;
942 int ncontacts = 0;
943
944 int i = 0;
945
946 maxDepthContact = new ContactPoint();
947 maxDepthContact.PenetrationDepth = float.MinValue;
948 ContactPoint minDepthContact = new ContactPoint();
949 minDepthContact.PenetrationDepth = float.MaxValue;
950
951 SharedTmpcontact.geom.depth = 0;
952 SharedTmpcontact.surface.mu = mu;
953 SharedTmpcontact.surface.bounce = bounce;
954
955 d.ContactGeom altContact = new d.ContactGeom();
956 bool useAltcontact;
957 bool noskip;
958
959 if(dop1ava || dop2ava)
960 smoothMesh = false;
961
962 while (true)
963 {
964 noskip = true;
965 useAltcontact = false;
966
967 if (dop1ava)
968 {
969 if ((((OdeCharacter)p1).Collide(g1, g2, false, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision)))
970 {
971 if (p2.PhysicsActorType == (int)ActorTypes.Agent)
972 {
973 p1.CollidingObj = true;
974 p2.CollidingObj = true;
975 }
976 else if (p2.rootVelocity.LengthSquared() > 0.0f)
977 p2.CollidingObj = true;
978 }
979 else
980 noskip = false;
981 }
982 else if (dop2ava)
983 {
984 if ((((OdeCharacter)p2).Collide(g2, g1, true, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision)))
985 {
986 if (p1.PhysicsActorType == (int)ActorTypes.Agent)
987 {
988 p1.CollidingObj = true;
989 p2.CollidingObj = true;
990 }
991 else if (p1.rootVelocity.LengthSquared() > 0.0f)
992 p1.CollidingObj = true;
993 }
994 else
995 noskip = false;
996 }
997
998 if (noskip)
999 {
1000 if(useAltcontact)
1001 Joint = CreateContacJoint(ref altContact,smoothMesh);
1002 else
1003 Joint = CreateContacJoint(ref curContact,smoothMesh);
1004 if (Joint == IntPtr.Zero)
1005 break;
1006
1007 d.JointAttach(Joint, b1, b2);
1008
1009 ncontacts++;
1010
1011 if (curContact.depth > maxDepthContact.PenetrationDepth)
1012 {
1013 maxDepthContact.Position.X = curContact.pos.X;
1014 maxDepthContact.Position.Y = curContact.pos.Y;
1015 maxDepthContact.Position.Z = curContact.pos.Z;
1016 maxDepthContact.PenetrationDepth = curContact.depth;
1017 maxDepthContact.CharacterFeet = FeetCollision;
1018 }
1019
1020 if (curContact.depth < minDepthContact.PenetrationDepth)
1021 {
1022 minDepthContact.PenetrationDepth = curContact.depth;
1023 minDepthContact.SurfaceNormal.X = curContact.normal.X;
1024 minDepthContact.SurfaceNormal.Y = curContact.normal.Y;
1025 minDepthContact.SurfaceNormal.Z = curContact.normal.Z;
1026 }
1027 }
1028
1029 if (++i >= count)
1030 break;
1031
1032 if (!GetCurContactGeom(i, ref curContact))
1033 break;
1034 }
1035
1036 if (ncontacts > 0)
1037 {
1038 maxDepthContact.SurfaceNormal.X = minDepthContact.SurfaceNormal.X;
1039 maxDepthContact.SurfaceNormal.Y = minDepthContact.SurfaceNormal.Y;
1040 maxDepthContact.SurfaceNormal.Z = minDepthContact.SurfaceNormal.Z;
1041
1042 collision_accounting_events(p1, p2, maxDepthContact);
1043 }
1044 }
1045
1046 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact)
1047 {
1048 uint obj2LocalID = 0;
1049
1050 // update actors collision score
1051 if (p1.CollisionScore < float.MaxValue)
1052 p1.CollisionScore += 1.0f;
1053 if (p2.CollisionScore < float.MaxValue)
1054 p2.CollisionScore += 1.0f;
1055
1056 bool p1events = p1.SubscribedEvents();
1057 bool p2events = p2.SubscribedEvents();
1058
1059 if (p1.IsVolumeDtc)
1060 p2events = false;
1061 if (p2.IsVolumeDtc)
1062 p1events = false;
1063
1064 if (!p2events && !p1events)
1065 return;
1066
1067 Vector3 vel = Vector3.Zero;
1068 if (p2 != null && p2.IsPhysical)
1069 vel = p2.rootVelocity;
1070
1071 if (p1 != null && p1.IsPhysical)
1072 vel -= p1.rootVelocity;
1073
1074 contact.RelativeSpeed = Vector3.Dot(vel, contact.SurfaceNormal);
1075
1076 switch ((ActorTypes)p1.PhysicsActorType)
1077 {
1078 case ActorTypes.Agent:
1079 case ActorTypes.Prim:
1080 {
1081 switch ((ActorTypes)p2.PhysicsActorType)
1082 {
1083 case ActorTypes.Agent:
1084 case ActorTypes.Prim:
1085 if (p2events)
1086 {
1087 //AddCollisionEventReporting(p2);
1088 p2.AddCollisionEvent(p1.ParentActor.LocalID, contact);
1089 }
1090 else if(p1.IsVolumeDtc)
1091 p2.AddVDTCCollisionEvent(p1.ParentActor.LocalID, contact);
1092
1093 obj2LocalID = p2.ParentActor.LocalID;
1094 break;
1095
1096 case ActorTypes.Ground:
1097 case ActorTypes.Unknown:
1098 default:
1099 obj2LocalID = 0;
1100 break;
1101 }
1102 if (p1events)
1103 {
1104 contact.SurfaceNormal = -contact.SurfaceNormal;
1105 contact.RelativeSpeed = -contact.RelativeSpeed;
1106 //AddCollisionEventReporting(p1);
1107 p1.AddCollisionEvent(obj2LocalID, contact);
1108 }
1109 else if(p2.IsVolumeDtc)
1110 {
1111 contact.SurfaceNormal = -contact.SurfaceNormal;
1112 contact.RelativeSpeed = -contact.RelativeSpeed;
1113 //AddCollisionEventReporting(p1);
1114 p1.AddVDTCCollisionEvent(obj2LocalID, contact);
1115 }
1116 break;
1117 }
1118 case ActorTypes.Ground:
1119 case ActorTypes.Unknown:
1120 default:
1121 {
1122 if (p2events && !p2.IsVolumeDtc)
1123 {
1124 //AddCollisionEventReporting(p2);
1125 p2.AddCollisionEvent(0, contact);
1126 }
1127 break;
1128 }
1129 }
1130 }
1131
1132 /// <summary>
1133 /// This is our collision testing routine in ODE
1134 /// </summary>
1135 /// <param name="timeStep"></param>
1136 private void collision_optimized()
1137 {
1138 lock (_characters)
1139 {
1140 try
1141 {
1142 foreach (OdeCharacter chr in _characters)
1143 {
1144 if (chr == null)
1145 continue;
1146
1147 chr.IsColliding = false;
1148 // chr.CollidingGround = false; not done here
1149 chr.CollidingObj = false;
1150
1151 if(chr.Body == IntPtr.Zero || chr.collider == IntPtr.Zero )
1152 continue;
1153
1154 // do colisions with static space
1155 d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback);
1156
1157 // no coll with gnd
1158 }
1159 // chars with chars
1160 d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback);
1161
1162 }
1163 catch (AccessViolationException)
1164 {
1165 m_log.Warn("[PHYSICS]: Unable to collide Character to static space");
1166 }
1167
1168 }
1169
1170 lock (_activeprims)
1171 {
1172 foreach (OdePrim aprim in _activeprims)
1173 {
1174 aprim.CollisionScore = 0;
1175 aprim.IsColliding = false;
1176 if(!aprim.m_outbounds && d.BodyIsEnabled(aprim.Body))
1177 aprim.clearSleeperCollisions();
1178 }
1179 }
1180
1181 lock (_activegroups)
1182 {
1183 try
1184 {
1185 foreach (OdePrim aprim in _activegroups)
1186 {
1187 if(!aprim.m_outbounds && d.BodyIsEnabled(aprim.Body) &&
1188 aprim.collide_geom != IntPtr.Zero)
1189 {
1190 d.SpaceCollide2(StaticSpace, aprim.collide_geom, IntPtr.Zero, nearCallback);
1191 d.SpaceCollide2(GroundSpace, aprim.collide_geom, IntPtr.Zero, nearCallback);
1192 }
1193 }
1194 }
1195 catch (Exception e)
1196 {
1197 m_log.Warn("[PHYSICS]: Unable to collide Active to Static: " + e.Message);
1198 }
1199 }
1200
1201 // colide active amoung them
1202 try
1203 {
1204 d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback);
1205 }
1206 catch (Exception e)
1207 {
1208 m_log.Warn("[PHYSICS]: Unable to collide in Active: " + e.Message);
1209 }
1210
1211 // and with chars
1212 try
1213 {
1214 d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback);
1215 }
1216 catch (Exception e)
1217 {
1218 m_log.Warn("[PHYSICS]: Unable to collide Active to Character: " + e.Message);
1219 }
1220 }
1221
1222 #endregion
1223 /// <summary>
1224 /// Add actor to the list that should receive collision events in the simulate loop.
1225 /// </summary>
1226 /// <param name="obj"></param>
1227 public void AddCollisionEventReporting(PhysicsActor obj)
1228 {
1229 if (!_collisionEventPrim.Contains(obj))
1230 _collisionEventPrim.Add(obj);
1231 }
1232
1233 /// <summary>
1234 /// Remove actor from the list that should receive collision events in the simulate loop.
1235 /// </summary>
1236 /// <param name="obj"></param>
1237 public void RemoveCollisionEventReporting(PhysicsActor obj)
1238 {
1239 lock(_collisionEventPrimRemove)
1240 {
1241 if (_collisionEventPrim.Contains(obj) && !_collisionEventPrimRemove.Contains(obj))
1242 _collisionEventPrimRemove.Add(obj);
1243 }
1244 }
1245
1246 public override float TimeDilation
1247 {
1248 get { return m_timeDilation; }
1249 }
1250
1251 public override bool SupportsNINJAJoints
1252 {
1253 get { return false; }
1254 }
1255
1256 #region Add/Remove Entities
1257
1258 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
1259 {
1260 return null;
1261 }
1262
1263 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying)
1264 {
1265 OdeCharacter newAv = new OdeCharacter(localID, avName, this, position,
1266 size, feetOffset, avDensity, avMovementDivisorWalk, avMovementDivisorRun);
1267 newAv.Flying = isFlying;
1268 newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset;
1269
1270 return newAv;
1271 }
1272
1273 public void AddCharacter(OdeCharacter chr)
1274 {
1275 lock (_characters)
1276 {
1277 if (!_characters.Contains(chr))
1278 {
1279 _characters.Add(chr);
1280 if (chr.bad)
1281 m_log.DebugFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid);
1282 }
1283 }
1284 }
1285
1286 public void RemoveCharacter(OdeCharacter chr)
1287 {
1288 lock (_characters)
1289 {
1290 if (_characters.Contains(chr))
1291 {
1292 _characters.Remove(chr);
1293 }
1294 }
1295 }
1296
1297 public void BadCharacter(OdeCharacter chr)
1298 {
1299 lock (_badCharacter)
1300 {
1301 if (!_badCharacter.Contains(chr))
1302 _badCharacter.Add(chr);
1303 }
1304 }
1305
1306 public override void RemoveAvatar(PhysicsActor actor)
1307 {
1308 //m_log.Debug("[PHYSICS]:ODELOCK");
1309 lock (OdeLock)
1310 {
1311 d.AllocateODEDataForThread(0);
1312 ((OdeCharacter) actor).Destroy();
1313 }
1314 }
1315
1316
1317 public void addActivePrim(OdePrim activatePrim)
1318 {
1319 // adds active prim..
1320 lock (_activeprims)
1321 {
1322 if (!_activeprims.Contains(activatePrim))
1323 _activeprims.Add(activatePrim);
1324 }
1325 }
1326
1327 public void addActiveGroups(OdePrim activatePrim)
1328 {
1329 lock (_activegroups)
1330 {
1331 if (!_activegroups.Contains(activatePrim))
1332 _activegroups.Add(activatePrim);
1333 }
1334 }
1335
1336 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
1337 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID)
1338 {
1339 OdePrim newPrim;
1340 lock (OdeLock)
1341 {
1342
1343 newPrim = new OdePrim(name, this, position, size, rotation, pbs, isphysical, isPhantom, shapeType, localID);
1344 }
1345 return newPrim;
1346 }
1347
1348 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1349 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid)
1350 {
1351 return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, 0 , localid);
1352 }
1353
1354
1355 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1356 Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
1357 {
1358 return AddPrim(primName, position, size, rotation, pbs, isPhysical,false, 0, localid);
1359 }
1360
1361 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1362 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid)
1363 {
1364 return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid);
1365 }
1366
1367 public void remActivePrim(OdePrim deactivatePrim)
1368 {
1369 lock (_activeprims)
1370 {
1371 _activeprims.Remove(deactivatePrim);
1372 }
1373 }
1374 public void remActiveGroup(OdePrim deactivatePrim)
1375 {
1376 lock (_activegroups)
1377 {
1378 _activegroups.Remove(deactivatePrim);
1379 }
1380 }
1381
1382 public override void RemovePrim(PhysicsActor prim)
1383 {
1384 // As with all ODE physics operations, we don't remove the prim immediately but signal that it should be
1385 // removed in the next physics simulate pass.
1386 if (prim is OdePrim)
1387 {
1388// lock (OdeLock)
1389 {
1390
1391 OdePrim p = (OdePrim)prim;
1392 p.setPrimForRemoval();
1393 }
1394 }
1395 }
1396
1397 public void RemovePrimThreadLocked(OdePrim prim)
1398 {
1399 //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName);
1400 lock (prim)
1401 {
1402// RemoveCollisionEventReporting(prim);
1403 lock (_prims)
1404 _prims.Remove(prim.LocalID);
1405 }
1406
1407 }
1408
1409 public void addToPrims(OdePrim prim)
1410 {
1411 lock (_prims)
1412 _prims[prim.LocalID] = prim;
1413 }
1414
1415 public OdePrim getPrim(uint id)
1416 {
1417 lock (_prims)
1418 {
1419 if(_prims.ContainsKey(id))
1420 return _prims[id];
1421 else
1422 return null;
1423 }
1424 }
1425
1426 public bool havePrim(OdePrim prm)
1427 {
1428 lock (_prims)
1429 return _prims.ContainsKey(prm.LocalID);
1430 }
1431
1432 public void changePrimID(OdePrim prim,uint oldID)
1433 {
1434 lock (_prims)
1435 {
1436 if(_prims.ContainsKey(oldID))
1437 _prims.Remove(oldID);
1438 _prims[prim.LocalID] = prim;
1439 }
1440 }
1441
1442 public bool haveActor(PhysicsActor actor)
1443 {
1444 if (actor is OdePrim)
1445 {
1446 lock (_prims)
1447 return _prims.ContainsKey(((OdePrim)actor).LocalID);
1448 }
1449 else if (actor is OdeCharacter)
1450 {
1451 lock (_characters)
1452 return _characters.Contains((OdeCharacter)actor);
1453 }
1454 return false;
1455 }
1456
1457 #endregion
1458
1459 #region Space Separation Calculation
1460
1461 /// <summary>
1462 /// Called when a static prim moves or becomes static
1463 /// Places the prim in a space one the static sub-spaces grid
1464 /// </summary>
1465 /// <param name="geom">the pointer to the geom that moved</param>
1466 /// <param name="pos">the position that the geom moved to</param>
1467 /// <param name="currentspace">a pointer to the space it was in before it was moved.</param>
1468 /// <returns>a pointer to the new space it's in</returns>
1469 public IntPtr MoveGeomToStaticSpace(IntPtr geom, Vector3 pos, IntPtr currentspace)
1470 {
1471 // moves a prim into another static sub-space or from another space into a static sub-space
1472
1473 // Called ODEPrim so
1474 // it's already in locked space.
1475
1476 if (geom == IntPtr.Zero) // shouldn't happen
1477 return IntPtr.Zero;
1478
1479 // get the static sub-space for current position
1480 IntPtr newspace = calculateSpaceForGeom(pos);
1481
1482 if (newspace == currentspace) // if we are there all done
1483 return newspace;
1484
1485 // else remove it from its current space
1486 if (currentspace != IntPtr.Zero && d.SpaceQuery(currentspace, geom))
1487 {
1488 if (d.GeomIsSpace(currentspace))
1489 {
1490 waitForSpaceUnlock(currentspace);
1491 d.SpaceRemove(currentspace, geom);
1492
1493 if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0)
1494 {
1495 d.SpaceDestroy(currentspace);
1496 }
1497 }
1498 else
1499 {
1500 m_log.Info("[Physics]: Invalid or empty Space passed to 'MoveGeomToStaticSpace':" + currentspace +
1501 " Geom:" + geom);
1502 }
1503 }
1504 else // odd currentspace is null or doesn't contain the geom? lets try the geom ideia of current space
1505 {
1506 currentspace = d.GeomGetSpace(geom);
1507 if (currentspace != IntPtr.Zero)
1508 {
1509 if (d.GeomIsSpace(currentspace))
1510 {
1511 waitForSpaceUnlock(currentspace);
1512 d.SpaceRemove(currentspace, geom);
1513
1514 if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0)
1515 {
1516 d.SpaceDestroy(currentspace);
1517 }
1518
1519 }
1520 }
1521 }
1522
1523 // put the geom in the newspace
1524 waitForSpaceUnlock(newspace);
1525 d.SpaceAdd(newspace, geom);
1526
1527 // let caller know this newspace
1528 return newspace;
1529 }
1530
1531 /// <summary>
1532 /// Calculates the space the prim should be in by its position
1533 /// </summary>
1534 /// <param name="pos"></param>
1535 /// <returns>a pointer to the space. This could be a new space or reused space.</returns>
1536 public IntPtr calculateSpaceForGeom(Vector3 pos)
1537 {
1538 int x, y;
1539
1540 if (pos.X < 0)
1541 return staticPrimspaceOffRegion[0];
1542
1543 if (pos.Y < 0)
1544 return staticPrimspaceOffRegion[2];
1545
1546 x = (int)(pos.X * spacesPerMeterX);
1547 if (x > spaceGridMaxX)
1548 return staticPrimspaceOffRegion[1];
1549
1550 y = (int)(pos.Y * spacesPerMeterY);
1551 if (y > spaceGridMaxY)
1552 return staticPrimspaceOffRegion[3];
1553
1554 return staticPrimspace[x, y];
1555 }
1556
1557 #endregion
1558
1559
1560 /// <summary>
1561 /// Called to queue a change to a actor
1562 /// to use in place of old taint mechanism so changes do have a time sequence
1563 /// </summary>
1564
1565 public void AddChange(PhysicsActor actor, changes what, Object arg)
1566 {
1567 ODEchangeitem item = new ODEchangeitem();
1568 item.actor = actor;
1569 item.what = what;
1570 item.arg = arg;
1571 ChangesQueue.Enqueue(item);
1572 }
1573
1574 /// <summary>
1575 /// Called after our prim properties are set Scale, position etc.
1576 /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex
1577 /// This assures us that we have no race conditions
1578 /// </summary>
1579 /// <param name="prim"></param>
1580 public override void AddPhysicsActorTaint(PhysicsActor prim)
1581 {
1582 }
1583
1584 // does all pending changes generated during region load process
1585 public override void ProcessPreSimulation()
1586 {
1587 lock (OdeLock)
1588 {
1589 if (world == IntPtr.Zero)
1590 {
1591 ChangesQueue.Clear();
1592 return;
1593 }
1594
1595 d.AllocateODEDataForThread(~0U);
1596
1597 ODEchangeitem item;
1598
1599 int donechanges = 0;
1600 if (ChangesQueue.Count > 0)
1601 {
1602 m_log.InfoFormat("[ubOde] start processing pending actor operations");
1603 int tstart = Util.EnvironmentTickCount();
1604
1605 while (ChangesQueue.Dequeue(out item))
1606 {
1607 if (item.actor != null)
1608 {
1609 try
1610 {
1611 if (item.actor is OdeCharacter)
1612 ((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
1613 else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
1614 RemovePrimThreadLocked((OdePrim)item.actor);
1615 }
1616 catch
1617 {
1618 m_log.WarnFormat("[PHYSICS]: Operation failed for a actor {0} {1}",
1619 item.actor.Name, item.what.ToString());
1620 }
1621 }
1622 donechanges++;
1623 }
1624 int time = Util.EnvironmentTickCountSubtract(tstart);
1625 m_log.InfoFormat("[ubOde] finished {0} operations in {1}ms", donechanges, time);
1626 }
1627 m_log.InfoFormat("[ubOde] {0} prim actors loaded",_prims.Count);
1628 }
1629 m_lastframe = Util.GetTimeStamp() + 0.5;
1630 step_time = -0.5f;
1631 }
1632
1633 /// <summary>
1634 /// This is our main simulate loop
1635 /// It's thread locked by a Mutex in the scene.
1636 /// It holds Collisions, it instructs ODE to step through the physical reactions
1637 /// It moves the objects around in memory
1638 /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup)
1639 /// </summary>
1640 /// <param name="timeStep"></param>
1641 /// <returns></returns>
1642 public override float Simulate(float reqTimeStep)
1643 {
1644 double now = Util.GetTimeStamp();
1645 double timeStep = now - m_lastframe;
1646 m_lastframe = now;
1647
1648 // acumulate time so we can reduce error
1649 step_time += (float)timeStep;
1650
1651 if (step_time < HalfOdeStep)
1652 return 0;
1653
1654 if (framecount < 0)
1655 framecount = 0;
1656
1657 framecount++;
1658
1659// checkThread();
1660 int nodeframes = 0;
1661 float fps = 0;
1662
1663 lock (SimulationLock)
1664 lock(OdeLock)
1665 {
1666 if (world == IntPtr.Zero)
1667 {
1668 ChangesQueue.Clear();
1669 return 0;
1670 }
1671
1672 ODEchangeitem item;
1673
1674// d.WorldSetQuickStepNumIterations(world, curphysiteractions);
1675
1676 double loopstartMS = Util.GetTimeStampMS();
1677 double looptimeMS = 0;
1678 double changestimeMS = 0;
1679 double maxChangestime = (int)(reqTimeStep * 500f); // half the time
1680 double maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time
1681
1682// double collisionTime = 0;
1683// double qstepTIme = 0;
1684// double tmpTime = 0;
1685
1686 d.AllocateODEDataForThread(~0U);
1687
1688 if (ChangesQueue.Count > 0)
1689 {
1690 while (ChangesQueue.Dequeue(out item))
1691 {
1692 if (item.actor != null)
1693 {
1694 try
1695 {
1696 if (item.actor is OdeCharacter)
1697 ((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
1698 else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
1699 RemovePrimThreadLocked((OdePrim)item.actor);
1700 }
1701 catch
1702 {
1703 m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}",
1704 item.actor.Name, item.what.ToString());
1705 }
1706 }
1707 changestimeMS = Util.GetTimeStampMS() - loopstartMS;
1708 if (changestimeMS > maxChangestime)
1709 break;
1710 }
1711 }
1712
1713 // do simulation taking at most 150ms total time including changes
1714 while (step_time > HalfOdeStep)
1715 {
1716 try
1717 {
1718 // clear pointer/counter to contacts to pass into joints
1719 m_global_contactcount = 0;
1720
1721
1722 // Move characters
1723 lock (_characters)
1724 {
1725 List<OdeCharacter> defects = new List<OdeCharacter>();
1726 foreach (OdeCharacter actor in _characters)
1727 {
1728 if (actor != null)
1729 actor.Move(defects);
1730 }
1731 if (defects.Count != 0)
1732 {
1733 foreach (OdeCharacter defect in defects)
1734 {
1735 RemoveCharacter(defect);
1736 }
1737 defects.Clear();
1738 }
1739 }
1740
1741 // Move other active objects
1742 lock (_activegroups)
1743 {
1744 foreach (OdePrim aprim in _activegroups)
1745 {
1746 aprim.Move();
1747 }
1748 }
1749
1750 m_rayCastManager.ProcessQueuedRequests();
1751
1752// tmpTime = Util.GetTimeStampMS();
1753 collision_optimized();
1754// collisionTime += Util.GetTimeStampMS() - tmpTime;
1755
1756 lock(_collisionEventPrimRemove)
1757 {
1758 foreach (PhysicsActor obj in _collisionEventPrimRemove)
1759 _collisionEventPrim.Remove(obj);
1760
1761 _collisionEventPrimRemove.Clear();
1762 }
1763
1764 List<OdePrim> sleepers = new List<OdePrim>();
1765 foreach (PhysicsActor obj in _collisionEventPrim)
1766 {
1767 if (obj == null)
1768 continue;
1769
1770 switch ((ActorTypes)obj.PhysicsActorType)
1771 {
1772 case ActorTypes.Agent:
1773 OdeCharacter cobj = (OdeCharacter)obj;
1774 cobj.SendCollisions((int)(odetimestepMS));
1775 break;
1776
1777 case ActorTypes.Prim:
1778 OdePrim pobj = (OdePrim)obj;
1779 if (!pobj.m_outbounds)
1780 {
1781 pobj.SendCollisions((int)(odetimestepMS));
1782 if(pobj.Body != IntPtr.Zero && !pobj.m_isSelected &&
1783 !pobj.m_disabled && !pobj.m_building &&
1784 !d.BodyIsEnabled(pobj.Body))
1785 sleepers.Add(pobj);
1786 }
1787 break;
1788 }
1789 }
1790
1791 foreach(OdePrim prm in sleepers)
1792 prm.SleeperAddCollisionEvents();
1793 sleepers.Clear();
1794
1795 // do a ode simulation step
1796// tmpTime = Util.GetTimeStampMS();
1797 d.WorldQuickStep(world, ODE_STEPSIZE);
1798 d.JointGroupEmpty(contactgroup);
1799// qstepTIme += Util.GetTimeStampMS() - tmpTime;
1800
1801 // update managed ideia of physical data and do updates to core
1802 /*
1803 lock (_characters)
1804 {
1805 foreach (OdeCharacter actor in _characters)
1806 {
1807 if (actor != null)
1808 {
1809 if (actor.bad)
1810 m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
1811
1812 actor.UpdatePositionAndVelocity();
1813 }
1814 }
1815 }
1816 */
1817
1818 lock (_activegroups)
1819 {
1820 {
1821 foreach (OdePrim actor in _activegroups)
1822 {
1823 if (actor.IsPhysical)
1824 {
1825 actor.UpdatePositionAndVelocity(framecount);
1826 }
1827 }
1828 }
1829 }
1830 }
1831 catch (Exception e)
1832 {
1833 m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e);
1834// ode.dunlock(world);
1835 }
1836
1837 step_time -= ODE_STEPSIZE;
1838 nodeframes++;
1839
1840 looptimeMS = Util.GetTimeStampMS() - loopstartMS;
1841 if (looptimeMS > maxLoopTime)
1842 break;
1843 }
1844
1845 lock (_badCharacter)
1846 {
1847 if (_badCharacter.Count > 0)
1848 {
1849 foreach (OdeCharacter chr in _badCharacter)
1850 {
1851 RemoveCharacter(chr);
1852 }
1853
1854 _badCharacter.Clear();
1855 }
1856 }
1857
1858// information block for in debug breakpoint only
1859/*
1860 int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace);
1861 int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);
1862 int ngroundgeoms = d.SpaceGetNumGeoms(GroundSpace);
1863
1864 int nactivegeoms = 0;
1865 int nactivespaces = 0;
1866
1867 int nstaticgeoms = 0;
1868 int nstaticspaces = 0;
1869 IntPtr sp;
1870
1871 for (int i = 0; i < ntopactivegeoms; i++)
1872 {
1873 sp = d.SpaceGetGeom(ActiveSpace, i);
1874 if (d.GeomIsSpace(sp))
1875 {
1876 nactivespaces++;
1877 nactivegeoms += d.SpaceGetNumGeoms(sp);
1878 }
1879 else
1880 nactivegeoms++;
1881 }
1882
1883 for (int i = 0; i < ntopstaticgeoms; i++)
1884 {
1885 sp = d.SpaceGetGeom(StaticSpace, i);
1886 if (d.GeomIsSpace(sp))
1887 {
1888 nstaticspaces++;
1889 nstaticgeoms += d.SpaceGetNumGeoms(sp);
1890 }
1891 else
1892 nstaticgeoms++;
1893 }
1894
1895 int ntopgeoms = d.SpaceGetNumGeoms(TopSpace);
1896
1897 int totgeoms = nstaticgeoms + nactivegeoms + ngroundgeoms + 1; // one ray
1898 int nbodies = d.NTotalBodies;
1899 int ngeoms = d.NTotalGeoms;
1900*/
1901/*
1902 looptimeMS /= nodeframes;
1903 if(looptimeMS > 0.080)
1904 {
1905 collisionTime /= nodeframes;
1906 qstepTIme /= nodeframes;
1907 }
1908*/
1909 // Finished with all sim stepping. If requested, dump world state to file for debugging.
1910 // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed?
1911 // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots?
1912 if (physics_logging && (physics_logging_interval > 0) && (framecount % physics_logging_interval == 0))
1913 {
1914 string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename
1915 string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file
1916
1917 if (physics_logging_append_existing_logfile)
1918 {
1919 string header = "-------------- START OF PHYSICS FRAME " + framecount.ToString() + " --------------";
1920 TextWriter fwriter = File.AppendText(fname);
1921 fwriter.WriteLine(header);
1922 fwriter.Close();
1923 }
1924
1925 d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix);
1926 }
1927
1928 fps = (float)nodeframes * ODE_STEPSIZE / reqTimeStep;
1929
1930 if(step_time < HalfOdeStep)
1931 m_timeDilation = 1.0f;
1932 else if (step_time > m_SkipFramesAtms)
1933 {
1934 // if we lag too much skip frames
1935 m_timeDilation = 0.0f;
1936 step_time = 0;
1937 m_lastframe = Util.GetTimeStamp(); // skip also the time lost
1938 }
1939 else
1940 {
1941 m_timeDilation = ODE_STEPSIZE / step_time;
1942 if (m_timeDilation > 1)
1943 m_timeDilation = 1;
1944 }
1945
1946 if (m_timeDilation == 1 && now - m_lastMeshExpire > 30)
1947 {
1948 mesher.ExpireReleaseMeshs();
1949 m_lastMeshExpire = now;
1950 }
1951
1952
1953 }
1954
1955 return fps;
1956 }
1957
1958 /// <summary>
1959 public override void GetResults()
1960 {
1961 }
1962
1963 public override bool IsThreaded
1964 {
1965 // for now we won't be multithreaded
1966 get { return (false); }
1967 }
1968
1969 public float GetTerrainHeightAtXY(float x, float y)
1970 {
1971 if (TerrainGeom == IntPtr.Zero)
1972 return 0f;
1973
1974 if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0)
1975 return 0f;
1976
1977 // TerrainHeightField for ODE as offset 1m
1978 x += 1f;
1979 y += 1f;
1980
1981 // make position fit into array
1982 if (x < 0)
1983 x = 0;
1984 if (y < 0)
1985 y = 0;
1986
1987 // integer indexs
1988 int ix;
1989 int iy;
1990 // interpolators offset
1991 float dx;
1992 float dy;
1993
1994 int regsizeX = (int)m_regionWidth + 3; // map size see setterrain number of samples
1995 int regsizeY = (int)m_regionHeight + 3; // map size see setterrain number of samples
1996 int regsize = regsizeX;
1997
1998 if (m_OSOdeLib)
1999 {
2000 if (x < regsizeX - 1)
2001 {
2002 ix = (int)x;
2003 dx = x - (float)ix;
2004 }
2005 else // out world use external height
2006 {
2007 ix = regsizeX - 2;
2008 dx = 0;
2009 }
2010 if (y < regsizeY - 1)
2011 {
2012 iy = (int)y;
2013 dy = y - (float)iy;
2014 }
2015 else
2016 {
2017 iy = regsizeY - 2;
2018 dy = 0;
2019 }
2020 }
2021 else
2022 {
2023 // we still have square fixed size regions
2024 // also flip x and y because of how map is done for ODE fliped axis
2025 // so ix,iy,dx and dy are inter exchanged
2026
2027 regsize = regsizeY;
2028
2029 if (x < regsizeX - 1)
2030 {
2031 iy = (int)x;
2032 dy = x - (float)iy;
2033 }
2034 else // out world use external height
2035 {
2036 iy = regsizeX - 2;
2037 dy = 0;
2038 }
2039 if (y < regsizeY - 1)
2040 {
2041 ix = (int)y;
2042 dx = y - (float)ix;
2043 }
2044 else
2045 {
2046 ix = regsizeY - 2;
2047 dx = 0;
2048 }
2049 }
2050
2051 float h0;
2052 float h1;
2053 float h2;
2054
2055 iy *= regsize;
2056 iy += ix; // all indexes have iy + ix
2057
2058 float[] heights = TerrainHeightFieldHeight;
2059 /*
2060 if ((dx + dy) <= 1.0f)
2061 {
2062 h0 = ((float)heights[iy]); // 0,0 vertice
2063 h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0
2064 h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0
2065 }
2066 else
2067 {
2068 h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice
2069 h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0
2070 h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1
2071 }
2072 */
2073 h0 = ((float)heights[iy]); // 0,0 vertice
2074
2075 if (dy>dx)
2076 {
2077 iy += regsize;
2078 h2 = (float)heights[iy]; // 0,1 vertice
2079 h1 = (h2 - h0) * dy; // 0,1 vertice minus 0,0
2080 h2 = ((float)heights[iy + 1] - h2) * dx; // 1,1 vertice minus 0,1
2081 }
2082 else
2083 {
2084 iy++;
2085 h2 = (float)heights[iy]; // vertice 1,0
2086 h1 = (h2 - h0) * dx; // 1,0 vertice minus 0,0
2087 h2 = (((float)heights[iy + regsize]) - h2) * dy; // 1,1 vertice minus 1,0
2088 }
2089
2090 return h0 + h1 + h2;
2091 }
2092
2093 public Vector3 GetTerrainNormalAtXY(float x, float y)
2094 {
2095 Vector3 norm = new Vector3(0, 0, 1);
2096
2097 if (TerrainGeom == IntPtr.Zero)
2098 return norm;
2099
2100 if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0)
2101 return norm;
2102
2103 // TerrainHeightField for ODE as offset 1m
2104 x += 1f;
2105 y += 1f;
2106
2107 // make position fit into array
2108 if (x < 0)
2109 x = 0;
2110 if (y < 0)
2111 y = 0;
2112
2113 // integer indexs
2114 int ix;
2115 int iy;
2116 // interpolators offset
2117 float dx;
2118 float dy;
2119
2120 int regsizeX = (int)m_regionWidth + 3; // map size see setterrain number of samples
2121 int regsizeY = (int)m_regionHeight + 3; // map size see setterrain number of samples
2122 int regsize = regsizeX;
2123
2124 int xstep = 1;
2125 int ystep = regsizeX;
2126 bool firstTri = false;
2127
2128 if (m_OSOdeLib)
2129 {
2130 if (x < regsizeX - 1)
2131 {
2132 ix = (int)x;
2133 dx = x - (float)ix;
2134 }
2135 else // out world use external height
2136 {
2137 ix = regsizeX - 2;
2138 dx = 0;
2139 }
2140 if (y < regsizeY - 1)
2141 {
2142 iy = (int)y;
2143 dy = y - (float)iy;
2144 }
2145 else
2146 {
2147 iy = regsizeY - 2;
2148 dy = 0;
2149 }
2150 firstTri = dy > dx;
2151 }
2152
2153 else
2154 {
2155 xstep = regsizeY;
2156 ystep = 1;
2157 regsize = regsizeY;
2158
2159 // we still have square fixed size regions
2160 // also flip x and y because of how map is done for ODE fliped axis
2161 // so ix,iy,dx and dy are inter exchanged
2162 if (x < regsizeX - 1)
2163 {
2164 iy = (int)x;
2165 dy = x - (float)iy;
2166 }
2167 else // out world use external height
2168 {
2169 iy = regsizeX - 2;
2170 dy = 0;
2171 }
2172 if (y < regsizeY - 1)
2173 {
2174 ix = (int)y;
2175 dx = y - (float)ix;
2176 }
2177 else
2178 {
2179 ix = regsizeY - 2;
2180 dx = 0;
2181 }
2182 firstTri = dx > dy;
2183 }
2184
2185 float h0;
2186 float h1;
2187 float h2;
2188
2189 iy *= regsize;
2190 iy += ix; // all indexes have iy + ix
2191
2192 float[] heights = TerrainHeightFieldHeight;
2193
2194 if (firstTri)
2195 {
2196 h1 = ((float)heights[iy]); // 0,0 vertice
2197 iy += ystep;
2198 h0 = (float)heights[iy]; // 0,1
2199 h2 = (float)heights[iy+xstep]; // 1,1 vertice
2200 norm.X = h0 - h2;
2201 norm.Y = h1 - h0;
2202 }
2203 else
2204 {
2205 h2 = ((float)heights[iy]); // 0,0 vertice
2206 iy += xstep;
2207 h0 = ((float)heights[iy]); // 1,0 vertice
2208 h1 = (float)heights[iy+ystep]; // vertice 1,1
2209 norm.X = h2 - h0;
2210 norm.Y = h0 - h1;
2211 }
2212 norm.Z = 1;
2213 norm.Normalize();
2214 return norm;
2215 }
2216
2217 public override void SetTerrain(float[] heightMap)
2218 {
2219 if (m_OSOdeLib)
2220 OSSetTerrain(heightMap);
2221 else
2222 OriSetTerrain(heightMap);
2223 }
2224
2225 public void OriSetTerrain(float[] heightMap)
2226 {
2227 // assumes 1m size grid and constante size square regions
2228 // needs to know about sims around in future
2229
2230 float[] _heightmap;
2231
2232 uint regionsizeX = m_regionWidth;
2233 uint regionsizeY = m_regionHeight;
2234
2235 // map is rotated
2236 uint heightmapWidth = regionsizeY + 2;
2237 uint heightmapHeight = regionsizeX + 2;
2238
2239 uint heightmapWidthSamples = heightmapWidth + 1;
2240 uint heightmapHeightSamples = heightmapHeight + 1;
2241
2242 _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
2243
2244 const float scale = 1.0f;
2245 const float offset = 0.0f;
2246 const float thickness = 10f;
2247 const int wrap = 0;
2248
2249
2250 float hfmin = float.MaxValue;
2251 float hfmax = float.MinValue;
2252 float val;
2253 uint xx;
2254 uint yy;
2255
2256 uint maxXX = regionsizeX - 1;
2257 uint maxYY = regionsizeY - 1;
2258 // flipping map adding one margin all around so things don't fall in edges
2259
2260 uint xt = 0;
2261 xx = 0;
2262
2263 for (uint x = 0; x < heightmapWidthSamples; x++)
2264 {
2265 if (x > 1 && xx < maxXX)
2266 xx++;
2267 yy = 0;
2268 for (uint y = 0; y < heightmapHeightSamples; y++)
2269 {
2270 if (y > 1 && y < maxYY)
2271 yy += regionsizeX;
2272
2273 val = heightMap[yy + xx];
2274 if (val < 0.0f)
2275 val = 0.0f; // no neg terrain as in chode
2276 _heightmap[xt + y] = val;
2277
2278 if (hfmin > val)
2279 hfmin = val;
2280 if (hfmax < val)
2281 hfmax = val;
2282 }
2283 xt += heightmapHeightSamples;
2284 }
2285
2286 lock (OdeLock)
2287 {
2288 d.AllocateODEDataForThread(~0U);
2289
2290 if (TerrainGeom != IntPtr.Zero)
2291 {
2292 actor_name_map.Remove(TerrainGeom);
2293 d.GeomDestroy(TerrainGeom);
2294
2295 }
2296
2297 if (TerrainHeightFieldHeightsHandler.IsAllocated)
2298 TerrainHeightFieldHeightsHandler.Free();
2299
2300 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
2301
2302 TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned);
2303
2304 d.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0,
2305 heightmapHeight, heightmapWidth ,
2306 (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale,
2307 offset, thickness, wrap);
2308
2309 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
2310
2311 TerrainGeom = d.CreateHeightfield(GroundSpace, HeightmapData, 1);
2312
2313 if (TerrainGeom != IntPtr.Zero)
2314 {
2315 d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land));
2316 d.GeomSetCollideBits(TerrainGeom, 0);
2317
2318 PhysicsActor pa = new NullPhysicsActor();
2319 pa.Name = "Terrain";
2320 pa.PhysicsActorType = (int)ActorTypes.Ground;
2321 actor_name_map[TerrainGeom] = pa;
2322
2323// geom_name_map[GroundGeom] = "Terrain";
2324
2325 d.Quaternion q = new d.Quaternion();
2326 q.X = 0.5f;
2327 q.Y = 0.5f;
2328 q.Z = 0.5f;
2329 q.W = 0.5f;
2330
2331 d.GeomSetQuaternion(TerrainGeom, ref q);
2332 d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f);
2333 TerrainHeightFieldHeight = _heightmap;
2334 }
2335 else
2336 TerrainHeightFieldHeightsHandler.Free();
2337 }
2338 }
2339
2340 public void OSSetTerrain(float[] heightMap)
2341 {
2342 // assumes 1m size grid and constante size square regions
2343 // needs to know about sims around in future
2344
2345 float[] _heightmap;
2346
2347 uint regionsizeX = m_regionWidth;
2348 uint regionsizeY = m_regionHeight;
2349
2350 uint heightmapWidth = regionsizeX + 2;
2351 uint heightmapHeight = regionsizeY + 2;
2352
2353 uint heightmapWidthSamples = heightmapWidth + 1;
2354 uint heightmapHeightSamples = heightmapHeight + 1;
2355
2356 _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
2357
2358
2359 float hfmin = float.MaxValue;
2360// float hfmax = float.MinValue;
2361 float val;
2362
2363
2364 uint maxXX = regionsizeX + 1;
2365 uint maxYY = regionsizeY + 1;
2366 // adding one margin all around so things don't fall in edges
2367
2368 uint xx;
2369 uint yy = 0;
2370 uint yt = 0;
2371
2372 for (uint y = 0; y < heightmapHeightSamples; y++)
2373 {
2374 if (y > 1 && y < maxYY)
2375 yy += regionsizeX;
2376 xx = 0;
2377 for (uint x = 0; x < heightmapWidthSamples; x++)
2378 {
2379 if (x > 1 && x < maxXX)
2380 xx++;
2381
2382 val = heightMap[yy + xx];
2383 if (val < 0.0f)
2384 val = 0.0f; // no neg terrain as in chode
2385 _heightmap[yt + x] = val;
2386
2387 if (hfmin > val)
2388 hfmin = val;
2389// if (hfmax < val)
2390// hfmax = val;
2391 }
2392 yt += heightmapWidthSamples;
2393 }
2394
2395 lock (OdeLock)
2396 {
2397 if (TerrainGeom != IntPtr.Zero)
2398 {
2399 actor_name_map.Remove(TerrainGeom);
2400 d.GeomDestroy(TerrainGeom);
2401 }
2402
2403 if (TerrainHeightFieldHeightsHandler.IsAllocated)
2404 TerrainHeightFieldHeightsHandler.Free();
2405
2406 TerrainHeightFieldHeight = null;
2407
2408 IntPtr HeightmapData = d.GeomOSTerrainDataCreate();
2409
2410 const int wrap = 0;
2411 float thickness = hfmin;
2412 if (thickness < 0)
2413 thickness = 1;
2414
2415 TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned);
2416
2417 d.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f,
2418 (int)heightmapWidthSamples, (int)heightmapHeightSamples,
2419 thickness, wrap);
2420
2421// d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
2422 TerrainGeom = d.CreateOSTerrain(GroundSpace, HeightmapData, 1);
2423 if (TerrainGeom != IntPtr.Zero)
2424 {
2425 d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land));
2426 d.GeomSetCollideBits(TerrainGeom, 0);
2427
2428 PhysicsActor pa = new NullPhysicsActor();
2429 pa.Name = "Terrain";
2430 pa.PhysicsActorType = (int)ActorTypes.Ground;
2431 actor_name_map[TerrainGeom] = pa;
2432
2433// geom_name_map[GroundGeom] = "Terrain";
2434
2435 d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f);
2436 TerrainHeightFieldHeight = _heightmap;
2437 }
2438 else
2439 TerrainHeightFieldHeightsHandler.Free();
2440 }
2441 }
2442
2443 public override void DeleteTerrain()
2444 {
2445 }
2446
2447 public float GetWaterLevel()
2448 {
2449 return waterlevel;
2450 }
2451
2452 public override void SetWaterLevel(float baseheight)
2453 {
2454 waterlevel = baseheight;
2455 }
2456
2457 public override void Dispose()
2458 {
2459 lock (OdeLock)
2460 {
2461
2462 if (world == IntPtr.Zero)
2463 return;
2464
2465 d.AllocateODEDataForThread(~0U);
2466
2467 if (m_meshWorker != null)
2468 m_meshWorker.Stop();
2469
2470 if (m_rayCastManager != null)
2471 {
2472 m_rayCastManager.Dispose();
2473 m_rayCastManager = null;
2474 }
2475
2476 lock (_prims)
2477 {
2478 ChangesQueue.Clear();
2479 foreach (OdePrim prm in _prims.Values)
2480 {
2481 prm.DoAChange(changes.Remove, null);
2482 _collisionEventPrim.Remove(prm);
2483 }
2484 _prims.Clear();
2485 }
2486
2487 OdeCharacter[] chtorem;
2488 lock (_characters)
2489 {
2490 chtorem = new OdeCharacter[_characters.Count];
2491 _characters.CopyTo(chtorem);
2492 }
2493
2494 ChangesQueue.Clear();
2495 foreach (OdeCharacter ch in chtorem)
2496 ch.DoAChange(changes.Remove, null);
2497
2498 if (TerrainGeom != IntPtr.Zero)
2499 d.GeomDestroy(TerrainGeom);
2500 TerrainGeom = IntPtr.Zero;
2501
2502 if (TerrainHeightFieldHeightsHandler.IsAllocated)
2503 TerrainHeightFieldHeightsHandler.Free();
2504
2505 TerrainHeightFieldHeight = null;
2506
2507 if (ContactgeomsArray != IntPtr.Zero)
2508 {
2509 Marshal.FreeHGlobal(ContactgeomsArray);
2510 ContactgeomsArray = IntPtr.Zero;
2511 }
2512 if (GlobalContactsArray != IntPtr.Zero)
2513 {
2514 Marshal.FreeHGlobal(GlobalContactsArray);
2515 GlobalContactsArray = IntPtr.Zero;
2516 }
2517
2518 d.WorldDestroy(world);
2519 world = IntPtr.Zero;
2520 //d.CloseODE();
2521 }
2522 }
2523
2524 private int compareByCollisionsDesc(OdePrim A, OdePrim B)
2525 {
2526 return -A.CollisionScore.CompareTo(B.CollisionScore);
2527 }
2528
2529 public override Dictionary<uint, float> GetTopColliders()
2530 {
2531 Dictionary<uint, float> topColliders;
2532 List<OdePrim> orderedPrims;
2533 lock (_activeprims)
2534 orderedPrims = new List<OdePrim>(_activeprims);
2535
2536 orderedPrims.Sort(compareByCollisionsDesc);
2537 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
2538
2539 return topColliders;
2540 }
2541
2542 public override bool SupportsRayCast()
2543 {
2544 return true;
2545 }
2546
2547 public override void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
2548 {
2549 if (retMethod != null)
2550 {
2551 ODERayRequest req = new ODERayRequest();
2552 req.actor = null;
2553 req.callbackMethod = retMethod;
2554 req.length = length;
2555 req.Normal = direction;
2556 req.Origin = position;
2557 req.Count = 0;
2558 req.filter = RayFilterFlags.AllPrims;
2559
2560 m_rayCastManager.QueueRequest(req);
2561 }
2562 }
2563
2564 public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod)
2565 {
2566 if (retMethod != null)
2567 {
2568 ODERayRequest req = new ODERayRequest();
2569 req.actor = null;
2570 req.callbackMethod = retMethod;
2571 req.length = length;
2572 req.Normal = direction;
2573 req.Origin = position;
2574 req.Count = Count;
2575 req.filter = RayFilterFlags.AllPrims;
2576
2577 m_rayCastManager.QueueRequest(req);
2578 }
2579 }
2580
2581
2582 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
2583 {
2584 List<ContactResult> ourresults = new List<ContactResult>();
2585 object SyncObject = new object();
2586
2587 RayCallback retMethod = delegate(List<ContactResult> results)
2588 {
2589 lock (SyncObject)
2590 {
2591 ourresults = results;
2592 Monitor.PulseAll(SyncObject);
2593 }
2594 };
2595
2596 ODERayRequest req = new ODERayRequest();
2597 req.actor = null;
2598 req.callbackMethod = retMethod;
2599 req.length = length;
2600 req.Normal = direction;
2601 req.Origin = position;
2602 req.Count = Count;
2603 req.filter = RayFilterFlags.AllPrims;
2604
2605 lock (SyncObject)
2606 {
2607 m_rayCastManager.QueueRequest(req);
2608 if (!Monitor.Wait(SyncObject, 500))
2609 return null;
2610 else
2611 return ourresults;
2612 }
2613 }
2614
2615 public override bool SupportsRaycastWorldFiltered()
2616 {
2617 return true;
2618 }
2619
2620 public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
2621 {
2622 object SyncObject = new object();
2623 List<ContactResult> ourresults = new List<ContactResult>();
2624
2625 RayCallback retMethod = delegate(List<ContactResult> results)
2626 {
2627 lock (SyncObject)
2628 {
2629 ourresults = results;
2630 Monitor.PulseAll(SyncObject);
2631 }
2632 };
2633
2634 ODERayRequest req = new ODERayRequest();
2635 req.actor = null;
2636 req.callbackMethod = retMethod;
2637 req.length = length;
2638 req.Normal = direction;
2639 req.Origin = position;
2640 req.Count = Count;
2641 req.filter = filter;
2642
2643 lock (SyncObject)
2644 {
2645 m_rayCastManager.QueueRequest(req);
2646 if (!Monitor.Wait(SyncObject, 500))
2647 return null;
2648 else
2649 return ourresults;
2650 }
2651 }
2652
2653 public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags)
2654 {
2655 if (actor == null)
2656 return new List<ContactResult>();
2657
2658 IntPtr geom;
2659 if (actor is OdePrim)
2660 geom = ((OdePrim)actor).prim_geom;
2661 else if (actor is OdeCharacter)
2662 geom = ((OdePrim)actor).prim_geom;
2663 else
2664 return new List<ContactResult>();
2665
2666 if (geom == IntPtr.Zero)
2667 return new List<ContactResult>();
2668
2669 List<ContactResult> ourResults = null;
2670 object SyncObject = new object();
2671
2672 RayCallback retMethod = delegate(List<ContactResult> results)
2673 {
2674 lock (SyncObject)
2675 {
2676 ourResults = results;
2677 Monitor.PulseAll(SyncObject);
2678 }
2679 };
2680
2681 ODERayRequest req = new ODERayRequest();
2682 req.actor = actor;
2683 req.callbackMethod = retMethod;
2684 req.length = length;
2685 req.Normal = direction;
2686 req.Origin = position;
2687 req.Count = Count;
2688 req.filter = flags;
2689
2690 lock (SyncObject)
2691 {
2692 m_rayCastManager.QueueRequest(req);
2693 if (!Monitor.Wait(SyncObject, 500))
2694 return new List<ContactResult>();
2695 }
2696
2697 if (ourResults == null)
2698 return new List<ContactResult>();
2699 return ourResults;
2700 }
2701
2702 public override List<ContactResult> BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags)
2703 {
2704 List<ContactResult> ourResults = null;
2705 object SyncObject = new object();
2706
2707 ProbeBoxCallback retMethod = delegate(List<ContactResult> results)
2708 {
2709 lock (SyncObject)
2710 {
2711 ourResults = results;
2712 Monitor.PulseAll(SyncObject);
2713 }
2714 };
2715
2716 ODERayRequest req = new ODERayRequest();
2717 req.actor = null;
2718 req.callbackMethod = retMethod;
2719 req.Normal = size;
2720 req.Origin = position;
2721 req.orientation = orientation;
2722 req.Count = Count;
2723 req.filter = flags;
2724
2725 lock (SyncObject)
2726 {
2727 m_rayCastManager.QueueRequest(req);
2728 if (!Monitor.Wait(SyncObject, 500))
2729 return new List<ContactResult>();
2730 }
2731
2732 if (ourResults == null)
2733 return new List<ContactResult>();
2734 return ourResults;
2735 }
2736
2737 public override List<ContactResult> SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags)
2738 {
2739 List<ContactResult> ourResults = null;
2740 object SyncObject = new object();
2741
2742 ProbeSphereCallback retMethod = delegate(List<ContactResult> results)
2743 {
2744 ourResults = results;
2745 Monitor.PulseAll(SyncObject);
2746 };
2747
2748 ODERayRequest req = new ODERayRequest();
2749 req.actor = null;
2750 req.callbackMethod = retMethod;
2751 req.length = radius;
2752 req.Origin = position;
2753 req.Count = Count;
2754 req.filter = flags;
2755
2756
2757 lock (SyncObject)
2758 {
2759 m_rayCastManager.QueueRequest(req);
2760 if (!Monitor.Wait(SyncObject, 500))
2761 return new List<ContactResult>();
2762 }
2763
2764 if (ourResults == null)
2765 return new List<ContactResult>();
2766 return ourResults;
2767 }
2768
2769 public override List<ContactResult> PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags)
2770 {
2771 IntPtr geom = IntPtr.Zero;;
2772
2773 if (actor != null)
2774 {
2775 if (actor is OdePrim)
2776 geom = ((OdePrim)actor).prim_geom;
2777 else if (actor is OdeCharacter)
2778 geom = ((OdePrim)actor).prim_geom;
2779 }
2780
2781 List<ContactResult> ourResults = null;
2782 object SyncObject = new object();
2783
2784 ProbePlaneCallback retMethod = delegate(List<ContactResult> results)
2785 {
2786 ourResults = results;
2787 Monitor.PulseAll(SyncObject);
2788 };
2789
2790 ODERayRequest req = new ODERayRequest();
2791 req.actor = null;
2792 req.callbackMethod = retMethod;
2793 req.length = plane.W;
2794 req.Normal.X = plane.X;
2795 req.Normal.Y = plane.Y;
2796 req.Normal.Z = plane.Z;
2797 req.Count = Count;
2798 req.filter = flags;
2799
2800 lock (SyncObject)
2801 {
2802 m_rayCastManager.QueueRequest(req);
2803 if (!Monitor.Wait(SyncObject, 500))
2804 return new List<ContactResult>();
2805 }
2806
2807 if (ourResults == null)
2808 return new List<ContactResult>();
2809 return ourResults;
2810 }
2811
2812 public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
2813 {
2814 Util.FireAndForget( delegate
2815 {
2816 ODESitAvatar sitAvatar = new ODESitAvatar(this, m_rayCastManager);
2817 if(sitAvatar != null)
2818 sitAvatar.Sit(actor, AbsolutePosition, CameraPosition, offset, AvatarSize, PhysicsSitResponse);
2819 });
2820 return 1;
2821 }
2822
2823 }
2824}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODESitAvatar.cs b/OpenSim/Region/PhysicsModules/ubOde/ODESitAvatar.cs
new file mode 100644
index 0000000..214205d
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODESitAvatar.cs
@@ -0,0 +1,356 @@
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// Ubit Umarov 2012
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Runtime.InteropServices;
32using System.Text;
33using OpenSim.Framework;
34using OpenSim.Region.PhysicsModules.SharedBase;
35using OdeAPI;
36using log4net;
37using OpenMetaverse;
38
39namespace OpenSim.Region.PhysicsModule.ubOde
40{
41 /// <summary>
42 /// </summary>
43 public class ODESitAvatar
44 {
45 private ODEScene m_scene;
46 private ODERayCastRequestManager m_raymanager;
47
48 public ODESitAvatar(ODEScene pScene, ODERayCastRequestManager raymanager)
49 {
50 m_scene = pScene;
51 m_raymanager = raymanager;
52 }
53
54 private static Vector3 SitAjust = new Vector3(0, 0, 0.4f);
55 private const RayFilterFlags RaySitFlags = RayFilterFlags.AllPrims | RayFilterFlags.ClosestHit;
56
57 private void RotAroundZ(float x, float y, ref Quaternion ori)
58 {
59 double ang = Math.Atan2(y, x);
60 ang *= 0.5d;
61 float s = (float)Math.Sin(ang);
62 float c = (float)Math.Cos(ang);
63
64 ori.X = 0;
65 ori.Y = 0;
66 ori.Z = s;
67 ori.W = c;
68 }
69
70
71 public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse)
72 {
73 if (!m_scene.haveActor(actor) || !(actor is OdePrim) || ((OdePrim)actor).prim_geom == IntPtr.Zero)
74 {
75 PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
76 return;
77 }
78
79 IntPtr geom = ((OdePrim)actor).prim_geom;
80
81 Vector3 geopos = d.GeomGetPositionOMV(geom);
82 Quaternion geomOri = d.GeomGetQuaternionOMV(geom);
83
84// Vector3 geopos = actor.Position;
85// Quaternion geomOri = actor.Orientation;
86
87 Quaternion geomInvOri = Quaternion.Conjugate(geomOri);
88
89 Quaternion ori = Quaternion.Identity;
90
91 Vector3 rayDir = geopos + offset - avCameraPosition;
92
93 float raylen = rayDir.Length();
94 if (raylen < 0.001f)
95 {
96 PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
97 return;
98 }
99 float t = 1 / raylen;
100 rayDir.X *= t;
101 rayDir.Y *= t;
102 rayDir.Z *= t;
103
104 raylen += 30f; // focal point may be far
105 List<ContactResult> rayResults;
106
107 rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags);
108 if (rayResults.Count == 0)
109 {
110/* if this fundamental ray failed, then just fail so user can try another spot and not be sitted far on a big prim
111 d.AABB aabb;
112 d.GeomGetAABB(geom, out aabb);
113 offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z);
114 ori = geomInvOri;
115 offset *= geomInvOri;
116 PhysicsSitResponse(1, actor.LocalID, offset, ori);
117*/
118 PhysicsSitResponse(0, actor.LocalID, offset, ori);
119 return;
120 }
121
122 int status = 1;
123
124 offset = rayResults[0].Pos - geopos;
125
126 d.GeomClassID geoclass = d.GeomGetClass(geom);
127
128 if (geoclass == d.GeomClassID.SphereClass)
129 {
130 float r = d.GeomSphereGetRadius(geom);
131
132 offset.Normalize();
133 offset *= r;
134
135 RotAroundZ(offset.X, offset.Y, ref ori);
136
137 if (r < 0.4f)
138 {
139 offset = new Vector3(0, 0, r);
140 }
141 else
142 {
143 if (offset.Z < 0.4f)
144 {
145 t = offset.Z;
146 float rsq = r * r;
147
148 t = 1.0f / (rsq - t * t);
149 offset.X *= t;
150 offset.Y *= t;
151 offset.Z = 0.4f;
152 t = rsq - 0.16f;
153 offset.X *= t;
154 offset.Y *= t;
155 }
156 else if (r > 0.8f && offset.Z > 0.8f * r)
157 {
158 status = 3;
159 avOffset.X = -avOffset.X;
160 avOffset.Z *= 1.6f;
161 }
162 }
163
164 offset += avOffset * ori;
165
166 ori = geomInvOri * ori;
167 offset *= geomInvOri;
168
169 PhysicsSitResponse(status, actor.LocalID, offset, ori);
170 return;
171 }
172
173 Vector3 norm = rayResults[0].Normal;
174
175 if (norm.Z < -0.4f)
176 {
177 PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity);
178 return;
179 }
180
181
182 float SitNormX = -rayDir.X;
183 float SitNormY = -rayDir.Y;
184
185 Vector3 pivot = geopos + offset;
186
187 float edgeNormalX = norm.X;
188 float edgeNormalY = norm.Y;
189 float edgeDirX = -rayDir.X;
190 float edgeDirY = -rayDir.Y;
191 Vector3 edgePos = rayResults[0].Pos;
192 float edgeDist = float.MaxValue;
193
194 bool foundEdge = false;
195
196 if (norm.Z < 0.5f)
197 {
198 float rayDist = 4.0f;
199
200 for (int i = 0; i < 6; i++)
201 {
202 pivot.X -= 0.01f * norm.X;
203 pivot.Y -= 0.01f * norm.Y;
204 pivot.Z -= 0.01f * norm.Z;
205
206 rayDir.X = -norm.X * norm.Z;
207 rayDir.Y = -norm.Y * norm.Z;
208 rayDir.Z = 1.0f - norm.Z * norm.Z;
209 rayDir.Normalize();
210
211 rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
212 if (rayResults.Count == 0)
213 break;
214
215 if (Math.Abs(rayResults[0].Normal.Z) < 0.7f)
216 {
217 rayDist -= rayResults[0].Depth;
218 if (rayDist < 0f)
219 break;
220
221 pivot = rayResults[0].Pos;
222 norm = rayResults[0].Normal;
223 edgeNormalX = norm.X;
224 edgeNormalY = norm.Y;
225 edgeDirX = -rayDir.X;
226 edgeDirY = -rayDir.Y;
227 }
228 else
229 {
230 foundEdge = true;
231 edgePos = rayResults[0].Pos;
232 break;
233 }
234 }
235
236 if (!foundEdge)
237 {
238 PhysicsSitResponse(0, actor.LocalID, offset, ori);
239 return;
240 }
241 avOffset.X *= 0.5f;
242 }
243
244 else if (norm.Z > 0.866f)
245 {
246 float toCamBaseX = avCameraPosition.X - pivot.X;
247 float toCamBaseY = avCameraPosition.Y - pivot.Y;
248 float toCamX = toCamBaseX;
249 float toCamY = toCamBaseY;
250
251 for (int j = 0; j < 4; j++)
252 {
253 float rayDist = 1.0f;
254 float curEdgeDist = 0.0f;
255
256 for (int i = 0; i < 3; i++)
257 {
258 pivot.Z -= 0.01f;
259 rayDir.X = toCamX;
260 rayDir.Y = toCamY;
261 rayDir.Z = (-toCamX * norm.X - toCamY * norm.Y) / norm.Z;
262 rayDir.Normalize();
263
264 rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
265 if (rayResults.Count == 0)
266 break;
267
268 curEdgeDist += rayResults[0].Depth;
269
270 if (rayResults[0].Normal.Z > 0.5f)
271 {
272 rayDist -= rayResults[0].Depth;
273 if (rayDist < 0f)
274 break;
275
276 pivot = rayResults[0].Pos;
277 norm = rayResults[0].Normal;
278 }
279 else
280 {
281 foundEdge = true;
282 if (curEdgeDist < edgeDist)
283 {
284 edgeDist = curEdgeDist;
285 edgeNormalX = rayResults[0].Normal.X;
286 edgeNormalY = rayResults[0].Normal.Y;
287 edgeDirX = rayDir.X;
288 edgeDirY = rayDir.Y;
289 edgePos = rayResults[0].Pos;
290 }
291 break;
292 }
293 }
294 if (foundEdge && edgeDist < 0.2f)
295 break;
296
297 pivot = geopos + offset;
298
299 switch (j)
300 {
301 case 0:
302 toCamX = -toCamBaseY;
303 toCamY = toCamBaseX;
304 break;
305 case 1:
306 toCamX = toCamBaseY;
307 toCamY = -toCamBaseX;
308 break;
309 case 2:
310 toCamX = -toCamBaseX;
311 toCamY = -toCamBaseY;
312 break;
313 default:
314 break;
315 }
316 }
317
318 if (!foundEdge)
319 {
320 avOffset.X = -avOffset.X;
321 avOffset.Z *= 1.6f;
322
323 RotAroundZ(SitNormX, SitNormY, ref ori);
324
325 offset += avOffset * ori;
326
327 ori = geomInvOri * ori;
328 offset *= geomInvOri;
329
330 PhysicsSitResponse(3, actor.LocalID, offset, ori);
331 return;
332 }
333 avOffset.X *= 0.5f;
334 }
335
336 SitNormX = edgeNormalX;
337 SitNormY = edgeNormalY;
338 if (edgeDirX * SitNormX + edgeDirY * SitNormY < 0)
339 {
340 SitNormX = -SitNormX;
341 SitNormY = -SitNormY;
342 }
343
344 RotAroundZ(SitNormX, SitNormY, ref ori);
345
346 offset = edgePos + avOffset * ori;
347 offset -= geopos;
348
349 ori = geomInvOri * ori;
350 offset *= geomInvOri;
351
352 PhysicsSitResponse(1, actor.LocalID, offset, ori);
353 return;
354 }
355 }
356}
diff --git a/OpenSim/Region/PhysicsModules/ubOde/Properties/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/ubOde/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5baab9f
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOde/Properties/AssemblyInfo.cs
@@ -0,0 +1,61 @@
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.Reflection;
29using System.Runtime.InteropServices;
30using Mono.Addins;
31
32// Information about this assembly is defined by the following
33// attributes.
34//
35// change them to the information which is associated with the assembly
36// you compile.
37
38[assembly : AssemblyTitle("OpenSim.Region.PhysicsModule.ubOde")]
39[assembly : AssemblyDescription("Ubit Variation of ODE")]
40[assembly : AssemblyConfiguration("")]
41[assembly : AssemblyCompany("http://opensimulator.org")]
42[assembly : AssemblyProduct("ubOde")]
43[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
44[assembly : AssemblyTrademark("")]
45[assembly : AssemblyCulture("")]
46
47// This sets the default COM visibility of types in the assembly to invisible.
48// If you need to expose a type to COM, use [ComVisible(true)] on that type.
49
50[assembly : ComVisible(false)]
51
52// The assembly version has following format :
53//
54// Major.Minor.Build.Revision
55//
56// You can specify all values by your own or you can build default build and revision
57// numbers with the '*' character (the default):
58
59[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
60[assembly: Addin("OpenSim.Region.PhysicsModule.ubOde", OpenSim.VersionInfo.VersionNumber)]
61[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] \ No newline at end of file
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/HelperTypes.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/HelperTypes.cs
new file mode 100644
index 0000000..ea37301
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/HelperTypes.cs
@@ -0,0 +1,340 @@
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.Diagnostics;
31using System.Globalization;
32using OpenMetaverse;
33using OpenSim.Region.PhysicsModules.SharedBase;
34using OpenSim.Region.PhysicsModule.ubODEMeshing;
35
36public class Vertex : IComparable<Vertex>
37{
38 Vector3 vector;
39
40 public float X
41 {
42 get { return vector.X; }
43 set { vector.X = value; }
44 }
45
46 public float Y
47 {
48 get { return vector.Y; }
49 set { vector.Y = value; }
50 }
51
52 public float Z
53 {
54 get { return vector.Z; }
55 set { vector.Z = value; }
56 }
57
58 public Vertex(float x, float y, float z)
59 {
60 vector.X = x;
61 vector.Y = y;
62 vector.Z = z;
63 }
64
65 public Vertex normalize()
66 {
67 float tlength = vector.Length();
68 if (tlength != 0f)
69 {
70 float mul = 1.0f / tlength;
71 return new Vertex(vector.X * mul, vector.Y * mul, vector.Z * mul);
72 }
73 else
74 {
75 return new Vertex(0f, 0f, 0f);
76 }
77 }
78
79 public Vertex cross(Vertex v)
80 {
81 return new Vertex(vector.Y * v.Z - vector.Z * v.Y, vector.Z * v.X - vector.X * v.Z, vector.X * v.Y - vector.Y * v.X);
82 }
83
84 // disable warning: mono compiler moans about overloading
85 // operators hiding base operator but should not according to C#
86 // language spec
87#pragma warning disable 0108
88 public static Vertex operator *(Vertex v, Quaternion q)
89 {
90 // From http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/
91
92 Vertex v2 = new Vertex(0f, 0f, 0f);
93
94 v2.X = q.W * q.W * v.X +
95 2f * q.Y * q.W * v.Z -
96 2f * q.Z * q.W * v.Y +
97 q.X * q.X * v.X +
98 2f * q.Y * q.X * v.Y +
99 2f * q.Z * q.X * v.Z -
100 q.Z * q.Z * v.X -
101 q.Y * q.Y * v.X;
102
103 v2.Y =
104 2f * q.X * q.Y * v.X +
105 q.Y * q.Y * v.Y +
106 2f * q.Z * q.Y * v.Z +
107 2f * q.W * q.Z * v.X -
108 q.Z * q.Z * v.Y +
109 q.W * q.W * v.Y -
110 2f * q.X * q.W * v.Z -
111 q.X * q.X * v.Y;
112
113 v2.Z =
114 2f * q.X * q.Z * v.X +
115 2f * q.Y * q.Z * v.Y +
116 q.Z * q.Z * v.Z -
117 2f * q.W * q.Y * v.X -
118 q.Y * q.Y * v.Z +
119 2f * q.W * q.X * v.Y -
120 q.X * q.X * v.Z +
121 q.W * q.W * v.Z;
122
123 return v2;
124 }
125
126 public static Vertex operator +(Vertex v1, Vertex v2)
127 {
128 return new Vertex(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
129 }
130
131 public static Vertex operator -(Vertex v1, Vertex v2)
132 {
133 return new Vertex(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
134 }
135
136 public static Vertex operator *(Vertex v1, Vertex v2)
137 {
138 return new Vertex(v1.X * v2.X, v1.Y * v2.Y, v1.Z * v2.Z);
139 }
140
141 public static Vertex operator +(Vertex v1, float am)
142 {
143 v1.X += am;
144 v1.Y += am;
145 v1.Z += am;
146 return v1;
147 }
148
149 public static Vertex operator -(Vertex v1, float am)
150 {
151 v1.X -= am;
152 v1.Y -= am;
153 v1.Z -= am;
154 return v1;
155 }
156
157 public static Vertex operator *(Vertex v1, float am)
158 {
159 v1.X *= am;
160 v1.Y *= am;
161 v1.Z *= am;
162 return v1;
163 }
164
165 public static Vertex operator /(Vertex v1, float am)
166 {
167 if (am == 0f)
168 {
169 return new Vertex(0f,0f,0f);
170 }
171 float mul = 1.0f / am;
172 v1.X *= mul;
173 v1.Y *= mul;
174 v1.Z *= mul;
175 return v1;
176 }
177#pragma warning restore 0108
178
179
180 public float dot(Vertex v)
181 {
182 return X * v.X + Y * v.Y + Z * v.Z;
183 }
184
185 public Vertex(Vector3 v)
186 {
187 vector = v;
188 }
189
190 public Vertex Clone()
191 {
192 return new Vertex(X, Y, Z);
193 }
194
195 public static Vertex FromAngle(double angle)
196 {
197 return new Vertex((float) Math.Cos(angle), (float) Math.Sin(angle), 0.0f);
198 }
199
200 public float Length()
201 {
202 return vector.Length();
203 }
204
205 public virtual bool Equals(Vertex v, float tolerance)
206 {
207 Vertex diff = this - v;
208 float d = diff.Length();
209 if (d < tolerance)
210 return true;
211
212 return false;
213 }
214
215
216 public int CompareTo(Vertex other)
217 {
218 if (X < other.X)
219 return -1;
220
221 if (X > other.X)
222 return 1;
223
224 if (Y < other.Y)
225 return -1;
226
227 if (Y > other.Y)
228 return 1;
229
230 if (Z < other.Z)
231 return -1;
232
233 if (Z > other.Z)
234 return 1;
235
236 return 0;
237 }
238
239 public static bool operator >(Vertex me, Vertex other)
240 {
241 return me.CompareTo(other) > 0;
242 }
243
244 public static bool operator <(Vertex me, Vertex other)
245 {
246 return me.CompareTo(other) < 0;
247 }
248
249 public String ToRaw()
250 {
251 // Why this stuff with the number formatter?
252 // Well, the raw format uses the english/US notation of numbers
253 // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
254 // The german notation uses these characters exactly vice versa!
255 // The Float.ToString() routine is a localized one, giving different results depending on the country
256 // settings your machine works with. Unusable for a machine readable file format :-(
257 NumberFormatInfo nfi = new NumberFormatInfo();
258 nfi.NumberDecimalSeparator = ".";
259 nfi.NumberDecimalDigits = 6;
260
261 String s1 = X.ToString(nfi) + " " + Y.ToString(nfi) + " " + Z.ToString(nfi);
262
263 return s1;
264 }
265}
266
267public class Triangle
268{
269 public Vertex v1;
270 public Vertex v2;
271 public Vertex v3;
272
273 public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
274 {
275 v1 = _v1;
276 v2 = _v2;
277 v3 = _v3;
278 }
279
280 public Triangle(float _v1x,float _v1y,float _v1z,
281 float _v2x,float _v2y,float _v2z,
282 float _v3x,float _v3y,float _v3z)
283 {
284 v1 = new Vertex(_v1x, _v1y, _v1z);
285 v2 = new Vertex(_v2x, _v2y, _v2z);
286 v3 = new Vertex(_v3x, _v3y, _v3z);
287 }
288
289 public override String ToString()
290 {
291 NumberFormatInfo nfi = new NumberFormatInfo();
292 nfi.CurrencyDecimalDigits = 2;
293 nfi.CurrencyDecimalSeparator = ".";
294
295 String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
296 String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
297 String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
298
299 return s1 + ";" + s2 + ";" + s3;
300 }
301
302 public Vector3 getNormal()
303 {
304 // Vertices
305
306 // Vectors for edges
307 Vector3 e1;
308 Vector3 e2;
309
310 e1 = new Vector3(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
311 e2 = new Vector3(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
312
313 // Cross product for normal
314 Vector3 n = Vector3.Cross(e1, e2);
315
316 // Length
317 float l = n.Length();
318
319 // Normalized "normal"
320 n = n/l;
321
322 return n;
323 }
324
325 public void invertNormal()
326 {
327 Vertex vt;
328 vt = v1;
329 v1 = v2;
330 v2 = vt;
331 }
332
333 // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
334 // debugging purposes
335 public String ToStringRaw()
336 {
337 String output = v1.ToRaw() + " " + v2.ToRaw() + " " + v3.ToRaw();
338 return output;
339 }
340}
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs
new file mode 100644
index 0000000..5d2b1f7
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs
@@ -0,0 +1,636 @@
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.IO;
31using System.Runtime.InteropServices;
32using OpenSim.Region.PhysicsModules.SharedBase;
33using PrimMesher;
34using OpenMetaverse;
35using System.Runtime.Serialization;
36using System.Runtime.Serialization.Formatters.Binary;
37
38namespace OpenSim.Region.PhysicsModule.ubODEMeshing
39{
40 public class MeshBuildingData
41 {
42 private class vertexcomp : IEqualityComparer<Vertex>
43 {
44 public bool Equals(Vertex v1, Vertex v2)
45 {
46 if (v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z)
47 return true;
48 else
49 return false;
50 }
51 public int GetHashCode(Vertex v)
52 {
53 int a = v.X.GetHashCode();
54 int b = v.Y.GetHashCode();
55 int c = v.Z.GetHashCode();
56 return (a << 16) ^ (b << 8) ^ c;
57 }
58 }
59
60 public Dictionary<Vertex, int> m_vertices;
61 public List<Triangle> m_triangles;
62 public float m_obbXmin;
63 public float m_obbXmax;
64 public float m_obbYmin;
65 public float m_obbYmax;
66 public float m_obbZmin;
67 public float m_obbZmax;
68 public Vector3 m_centroid;
69 public int m_centroidDiv;
70
71 public MeshBuildingData()
72 {
73 vertexcomp vcomp = new vertexcomp();
74 m_vertices = new Dictionary<Vertex, int>(vcomp);
75 m_triangles = new List<Triangle>();
76 m_centroid = Vector3.Zero;
77 m_centroidDiv = 0;
78 m_obbXmin = float.MaxValue;
79 m_obbXmax = float.MinValue;
80 m_obbYmin = float.MaxValue;
81 m_obbYmax = float.MinValue;
82 m_obbZmin = float.MaxValue;
83 m_obbZmax = float.MinValue;
84 }
85 }
86
87 [Serializable()]
88 public class Mesh : IMesh
89 {
90 float[] vertices;
91 int[] indexes;
92 Vector3 m_obb;
93 Vector3 m_obboffset;
94 [NonSerialized()]
95 MeshBuildingData m_bdata;
96 [NonSerialized()]
97 GCHandle vhandler;
98 [NonSerialized()]
99 GCHandle ihandler;
100 [NonSerialized()]
101 IntPtr m_verticesPtr = IntPtr.Zero;
102 [NonSerialized()]
103 IntPtr m_indicesPtr = IntPtr.Zero;
104 [NonSerialized()]
105 int m_vertexCount = 0;
106 [NonSerialized()]
107 int m_indexCount = 0;
108
109 public int RefCount { get; set; }
110 public AMeshKey Key { get; set; }
111
112 public Mesh(bool forbuild)
113 {
114 if(forbuild)
115 m_bdata = new MeshBuildingData();
116 m_obb = new Vector3(0.5f, 0.5f, 0.5f);
117 m_obboffset = Vector3.Zero;
118 }
119
120 public Mesh Scale(Vector3 scale)
121 {
122 if (m_verticesPtr == null || m_indicesPtr == null)
123 return null;
124
125 Mesh result = new Mesh(false);
126
127 float x = scale.X;
128 float y = scale.Y;
129 float z = scale.Z;
130
131 float tmp;
132 tmp = m_obb.X * x;
133 if(tmp < 0.0005f)
134 tmp = 0.0005f;
135 result.m_obb.X = tmp;
136
137 tmp = m_obb.Y * y;
138 if(tmp < 0.0005f)
139 tmp = 0.0005f;
140 result.m_obb.Y = tmp;
141
142 tmp = m_obb.Z * z;
143 if(tmp < 0.0005f)
144 tmp = 0.0005f;
145 result.m_obb.Z = tmp;
146
147 result.m_obboffset.X = m_obboffset.X * x;
148 result.m_obboffset.Y = m_obboffset.Y * y;
149 result.m_obboffset.Z = m_obboffset.Z * z;
150
151 result.vertices = new float[vertices.Length];
152 int j = 0;
153 for (int i = 0; i < m_vertexCount; i++)
154 {
155 result.vertices[j] = vertices[j] * x;
156 j++;
157 result.vertices[j] = vertices[j] * y;
158 j++;
159 result.vertices[j] = vertices[j] * z;
160 j++;
161 }
162
163 result.indexes = new int[indexes.Length];
164 indexes.CopyTo(result.indexes,0);
165
166 result.pinMemory();
167
168 return result;
169 }
170
171 public Mesh Clone()
172 {
173 Mesh result = new Mesh(false);
174
175 if (m_bdata != null)
176 {
177 result.m_bdata = new MeshBuildingData();
178 foreach (Triangle t in m_bdata.m_triangles)
179 {
180 result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
181 }
182 result.m_bdata.m_centroid = m_bdata.m_centroid;
183 result.m_bdata.m_centroidDiv = m_bdata.m_centroidDiv;
184 result.m_bdata.m_obbXmin = m_bdata.m_obbXmin;
185 result.m_bdata.m_obbXmax = m_bdata.m_obbXmax;
186 result.m_bdata.m_obbYmin = m_bdata.m_obbYmin;
187 result.m_bdata.m_obbYmax = m_bdata.m_obbYmax;
188 result.m_bdata.m_obbZmin = m_bdata.m_obbZmin;
189 result.m_bdata.m_obbZmax = m_bdata.m_obbZmax;
190 }
191 result.m_obb = m_obb;
192 result.m_obboffset = m_obboffset;
193 return result;
194 }
195
196 public void addVertexLStats(Vertex v)
197 {
198 float x = v.X;
199 float y = v.Y;
200 float z = v.Z;
201
202 m_bdata.m_centroid.X += x;
203 m_bdata.m_centroid.Y += y;
204 m_bdata.m_centroid.Z += z;
205 m_bdata.m_centroidDiv++;
206
207 if (x > m_bdata.m_obbXmax)
208 m_bdata.m_obbXmax = x;
209 if (x < m_bdata.m_obbXmin)
210 m_bdata.m_obbXmin = x;
211
212 if (y > m_bdata.m_obbYmax)
213 m_bdata.m_obbYmax = y;
214 if (y < m_bdata.m_obbYmin)
215 m_bdata.m_obbYmin = y;
216
217 if (z > m_bdata.m_obbZmax)
218 m_bdata.m_obbZmax = z;
219 if (z < m_bdata.m_obbZmin)
220 m_bdata.m_obbZmin = z;
221
222 }
223
224 public void Add(Triangle triangle)
225 {
226 if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
227 throw new NotSupportedException("Attempt to Add to a pinned Mesh");
228
229
230 triangle.v1.X = (float)Math.Round(triangle.v1.X, 6);
231 triangle.v1.Y = (float)Math.Round(triangle.v1.Y, 6);
232 triangle.v1.Z = (float)Math.Round(triangle.v1.Z, 6);
233 triangle.v2.X = (float)Math.Round(triangle.v2.X, 6);
234 triangle.v2.Y = (float)Math.Round(triangle.v2.Y, 6);
235 triangle.v2.Z = (float)Math.Round(triangle.v2.Z, 6);
236 triangle.v3.X = (float)Math.Round(triangle.v3.X, 6);
237 triangle.v3.Y = (float)Math.Round(triangle.v3.Y, 6);
238 triangle.v3.Z = (float)Math.Round(triangle.v3.Z, 6);
239
240 if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z ==
241 triangle.v2.Z)
242 || (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z ==
243 triangle.v3.Z)
244 || (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z ==
245 triangle.v3.Z)
246 )
247 {
248 return;
249 }
250
251 if (m_bdata.m_vertices.Count == 0)
252 {
253 m_bdata.m_centroidDiv = 0;
254 m_bdata.m_centroid = Vector3.Zero;
255 }
256
257 if (!m_bdata.m_vertices.ContainsKey(triangle.v1))
258 {
259 m_bdata.m_vertices[triangle.v1] = m_bdata.m_vertices.Count;
260 addVertexLStats(triangle.v1);
261 }
262 if (!m_bdata.m_vertices.ContainsKey(triangle.v2))
263 {
264 m_bdata.m_vertices[triangle.v2] = m_bdata.m_vertices.Count;
265 addVertexLStats(triangle.v2);
266 }
267 if (!m_bdata.m_vertices.ContainsKey(triangle.v3))
268 {
269 m_bdata.m_vertices[triangle.v3] = m_bdata.m_vertices.Count;
270 addVertexLStats(triangle.v3);
271 }
272 m_bdata.m_triangles.Add(triangle);
273 }
274
275 public Vector3 GetCentroid()
276 {
277 return m_obboffset;
278
279 }
280
281 public Vector3 GetOBB()
282 {
283 return m_obb;
284/*
285 float x, y, z;
286 if (m_bdata.m_centroidDiv > 0)
287 {
288 x = (m_bdata.m_obbXmax - m_bdata.m_obbXmin) * 0.5f;
289 y = (m_bdata.m_obbYmax - m_bdata.m_obbYmin) * 0.5f;
290 z = (m_bdata.m_obbZmax - m_bdata.m_obbZmin) * 0.5f;
291 }
292 else // ??
293 {
294 x = 0.5f;
295 y = 0.5f;
296 z = 0.5f;
297 }
298 return new Vector3(x, y, z);
299*/
300 }
301
302 public int numberVertices()
303 {
304 return m_bdata.m_vertices.Count;
305 }
306
307 public int numberTriangles()
308 {
309 return m_bdata.m_triangles.Count;
310 }
311
312 public List<Vector3> getVertexList()
313 {
314 List<Vector3> result = new List<Vector3>();
315 foreach (Vertex v in m_bdata.m_vertices.Keys)
316 {
317 result.Add(new Vector3(v.X, v.Y, v.Z));
318 }
319 return result;
320 }
321
322 public float[] getVertexListAsFloat()
323 {
324 if (m_bdata.m_vertices == null)
325 throw new NotSupportedException();
326 float[] result = new float[m_bdata.m_vertices.Count * 3];
327 foreach (KeyValuePair<Vertex, int> kvp in m_bdata.m_vertices)
328 {
329 Vertex v = kvp.Key;
330 int i = kvp.Value;
331 result[3 * i + 0] = v.X;
332 result[3 * i + 1] = v.Y;
333 result[3 * i + 2] = v.Z;
334 }
335 return result;
336 }
337
338 public float[] getVertexListAsFloatLocked()
339 {
340 return null;
341 }
342
343 public void getVertexListAsPtrToFloatArray(out IntPtr _vertices, out int vertexStride, out int vertexCount)
344 {
345 // A vertex is 3 floats
346 vertexStride = 3 * sizeof(float);
347
348 // If there isn't an unmanaged array allocated yet, do it now
349 if (m_verticesPtr == IntPtr.Zero && m_bdata != null)
350 {
351 vertices = getVertexListAsFloat();
352 // Each vertex is 3 elements (floats)
353 m_vertexCount = vertices.Length / 3;
354 vhandler = GCHandle.Alloc(vertices, GCHandleType.Pinned);
355 m_verticesPtr = vhandler.AddrOfPinnedObject();
356 GC.AddMemoryPressure(Buffer.ByteLength(vertices));
357 }
358 _vertices = m_verticesPtr;
359 vertexCount = m_vertexCount;
360 }
361
362 public int[] getIndexListAsInt()
363 {
364 if (m_bdata.m_triangles == null)
365 throw new NotSupportedException();
366 int[] result = new int[m_bdata.m_triangles.Count * 3];
367 for (int i = 0; i < m_bdata.m_triangles.Count; i++)
368 {
369 Triangle t = m_bdata.m_triangles[i];
370 result[3 * i + 0] = m_bdata.m_vertices[t.v1];
371 result[3 * i + 1] = m_bdata.m_vertices[t.v2];
372 result[3 * i + 2] = m_bdata.m_vertices[t.v3];
373 }
374 return result;
375 }
376
377 /// <summary>
378 /// creates a list of index values that defines triangle faces. THIS METHOD FREES ALL NON-PINNED MESH DATA
379 /// </summary>
380 /// <returns></returns>
381 public int[] getIndexListAsIntLocked()
382 {
383 return null;
384 }
385
386 public void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount)
387 {
388 // If there isn't an unmanaged array allocated yet, do it now
389 if (m_indicesPtr == IntPtr.Zero && m_bdata != null)
390 {
391 indexes = getIndexListAsInt();
392 m_indexCount = indexes.Length;
393 ihandler = GCHandle.Alloc(indexes, GCHandleType.Pinned);
394 m_indicesPtr = ihandler.AddrOfPinnedObject();
395 GC.AddMemoryPressure(Buffer.ByteLength(indexes));
396 }
397 // A triangle is 3 ints (indices)
398 triStride = 3 * sizeof(int);
399 indices = m_indicesPtr;
400 indexCount = m_indexCount;
401 }
402
403 public void releasePinned()
404 {
405 if (m_verticesPtr != IntPtr.Zero)
406 {
407 vhandler.Free();
408 GC.RemoveMemoryPressure(Buffer.ByteLength(vertices));
409 vertices = null;
410 m_verticesPtr = IntPtr.Zero;
411 }
412 if (m_indicesPtr != IntPtr.Zero)
413 {
414 ihandler.Free();
415 GC.RemoveMemoryPressure(Buffer.ByteLength(indexes));
416 indexes = null;
417 m_indicesPtr = IntPtr.Zero;
418 }
419 }
420
421 /// <summary>
422 /// frees up the source mesh data to minimize memory - call this method after calling get*Locked() functions
423 /// </summary>
424 public void releaseSourceMeshData()
425 {
426 if (m_bdata != null)
427 {
428 m_bdata.m_triangles = null;
429 m_bdata.m_vertices = null;
430 }
431 }
432
433 public void releaseBuildingMeshData()
434 {
435 if (m_bdata != null)
436 {
437 m_bdata.m_triangles = null;
438 m_bdata.m_vertices = null;
439 m_bdata = null;
440 }
441 }
442
443 public void Append(IMesh newMesh)
444 {
445 if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
446 throw new NotSupportedException("Attempt to Append to a pinned Mesh");
447
448 if (!(newMesh is Mesh))
449 return;
450
451 foreach (Triangle t in ((Mesh)newMesh).m_bdata.m_triangles)
452 Add(t);
453 }
454
455 // Do a linear transformation of mesh.
456 public void TransformLinear(float[,] matrix, float[] offset)
457 {
458 if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
459 throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh");
460
461 foreach (Vertex v in m_bdata.m_vertices.Keys)
462 {
463 if (v == null)
464 continue;
465 float x, y, z;
466 x = v.X*matrix[0, 0] + v.Y*matrix[1, 0] + v.Z*matrix[2, 0];
467 y = v.X*matrix[0, 1] + v.Y*matrix[1, 1] + v.Z*matrix[2, 1];
468 z = v.X*matrix[0, 2] + v.Y*matrix[1, 2] + v.Z*matrix[2, 2];
469 v.X = x + offset[0];
470 v.Y = y + offset[1];
471 v.Z = z + offset[2];
472 }
473 }
474
475 public void DumpRaw(String path, String name, String title)
476 {
477 if (path == null)
478 return;
479 if (m_bdata == null)
480 return;
481 String fileName = name + "_" + title + ".raw";
482 String completePath = System.IO.Path.Combine(path, fileName);
483 StreamWriter sw = new StreamWriter(completePath);
484 foreach (Triangle t in m_bdata.m_triangles)
485 {
486 String s = t.ToStringRaw();
487 sw.WriteLine(s);
488 }
489 sw.Close();
490 }
491
492 public void TrimExcess()
493 {
494 m_bdata.m_triangles.TrimExcess();
495 }
496
497 public void pinMemory()
498 {
499 m_vertexCount = vertices.Length / 3;
500 vhandler = GCHandle.Alloc(vertices, GCHandleType.Pinned);
501 m_verticesPtr = vhandler.AddrOfPinnedObject();
502 GC.AddMemoryPressure(Buffer.ByteLength(vertices));
503
504 m_indexCount = indexes.Length;
505 ihandler = GCHandle.Alloc(indexes, GCHandleType.Pinned);
506 m_indicesPtr = ihandler.AddrOfPinnedObject();
507 GC.AddMemoryPressure(Buffer.ByteLength(indexes));
508 }
509
510 public void PrepForOde()
511 {
512 // If there isn't an unmanaged array allocated yet, do it now
513 if (m_verticesPtr == IntPtr.Zero)
514 vertices = getVertexListAsFloat();
515
516 // If there isn't an unmanaged array allocated yet, do it now
517 if (m_indicesPtr == IntPtr.Zero)
518 indexes = getIndexListAsInt();
519
520 float x, y, z;
521
522 if (m_bdata.m_centroidDiv > 0)
523 {
524 m_obboffset = new Vector3(m_bdata.m_centroid.X / m_bdata.m_centroidDiv, m_bdata.m_centroid.Y / m_bdata.m_centroidDiv, m_bdata.m_centroid.Z / m_bdata.m_centroidDiv);
525 x = (m_bdata.m_obbXmax - m_bdata.m_obbXmin) * 0.5f;
526 if(x < 0.0005f)
527 x = 0.0005f;
528 y = (m_bdata.m_obbYmax - m_bdata.m_obbYmin) * 0.5f;
529 if(y < 0.0005f)
530 y = 0.0005f;
531 z = (m_bdata.m_obbZmax - m_bdata.m_obbZmin) * 0.5f;
532 if(z < 0.0005f)
533 z = 0.0005f;
534 }
535
536 else
537 {
538 m_obboffset = Vector3.Zero;
539 x = 0.5f;
540 y = 0.5f;
541 z = 0.5f;
542 }
543
544 m_obb = new Vector3(x, y, z);
545
546 releaseBuildingMeshData();
547 pinMemory();
548 }
549
550 public bool ToStream(Stream st)
551 {
552 if (m_indicesPtr == IntPtr.Zero || m_verticesPtr == IntPtr.Zero)
553 return false;
554
555 bool ok = true;
556
557 try
558 {
559 using(BinaryWriter bw = new BinaryWriter(st))
560 {
561 bw.Write(m_vertexCount);
562 bw.Write(m_indexCount);
563
564 for (int i = 0; i < 3 * m_vertexCount; i++)
565 bw.Write(vertices[i]);
566 for (int i = 0; i < m_indexCount; i++)
567 bw.Write(indexes[i]);
568 bw.Write(m_obb.X);
569 bw.Write(m_obb.Y);
570 bw.Write(m_obb.Z);
571 bw.Write(m_obboffset.X);
572 bw.Write(m_obboffset.Y);
573 bw.Write(m_obboffset.Z);
574 bw.Flush();
575 bw.Close();
576 }
577 }
578 catch
579 {
580 ok = false;
581 }
582
583 return ok;
584 }
585
586 public static Mesh FromStream(Stream st, AMeshKey key)
587 {
588 Mesh mesh = new Mesh(false);
589
590 bool ok = true;
591 try
592 {
593 using(BinaryReader br = new BinaryReader(st))
594 {
595 mesh.m_vertexCount = br.ReadInt32();
596 mesh.m_indexCount = br.ReadInt32();
597
598 int n = 3 * mesh.m_vertexCount;
599 mesh.vertices = new float[n];
600 for (int i = 0; i < n; i++)
601 mesh.vertices[i] = br.ReadSingle();
602
603 mesh.indexes = new int[mesh.m_indexCount];
604 for (int i = 0; i < mesh.m_indexCount; i++)
605 mesh.indexes[i] = br.ReadInt32();
606
607 mesh.m_obb.X = br.ReadSingle();
608 mesh.m_obb.Y = br.ReadSingle();
609 mesh.m_obb.Z = br.ReadSingle();
610
611 mesh.m_obboffset.X = br.ReadSingle();
612 mesh.m_obboffset.Y = br.ReadSingle();
613 mesh.m_obboffset.Z = br.ReadSingle();
614 }
615 }
616 catch
617 {
618 ok = false;
619 }
620
621 if (ok)
622 {
623 mesh.pinMemory();
624
625 mesh.Key = key;
626 mesh.RefCount = 1;
627
628 return mesh;
629 }
630
631 mesh.vertices = null;
632 mesh.indexes = null;
633 return null;
634 }
635 }
636}
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
new file mode 100644
index 0000000..032d4ed
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
@@ -0,0 +1,1602 @@
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//#define SPAM
28
29using System;
30using System.Collections.Generic;
31using OpenSim.Framework;
32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.PhysicsModules.SharedBase;
35using OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet;
36using OpenMetaverse;
37using OpenMetaverse.StructuredData;
38using System.Drawing;
39using System.Threading;
40using System.IO.Compression;
41using PrimMesher;
42using log4net;
43using Nini.Config;
44using System.Reflection;
45using System.IO;
46
47using Mono.Addins;
48
49namespace OpenSim.Region.PhysicsModule.ubODEMeshing
50{
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ubODEMeshmerizer")]
52 public class ubMeshmerizer : IMesher, INonSharedRegionModule
53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 // Setting baseDir to a path will enable the dumping of raw files
57 // raw files can be imported by blender so a visual inspection of the results can be done
58
59 private static string cacheControlFilename = "cntr";
60 private bool m_Enabled = false;
61
62 public static object diskLock = new object();
63
64 public bool doMeshFileCache = true;
65 public bool doCacheExpire = true;
66 public string cachePath = "MeshCache";
67 public TimeSpan CacheExpire;
68
69// const string baseDir = "rawFiles";
70 private const string baseDir = null; //"rawFiles";
71
72 private bool useMeshiesPhysicsMesh = true;
73 private bool doConvexPrims = true;
74 private bool doConvexSculpts = true;
75
76 private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>();
77 private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>();
78
79 #region INonSharedRegionModule
80 public string Name
81 {
82 get { return "ubODEMeshmerizer"; }
83 }
84
85 public Type ReplaceableInterface
86 {
87 get { return null; }
88 }
89
90 public void Initialise(IConfigSource config)
91 {
92 IConfig start_config = config.Configs["Startup"];
93
94 string mesher = start_config.GetString("meshing", string.Empty);
95 if (mesher == Name)
96 {
97 float fcache = 48.0f;
98 // float fcache = 0.02f;
99
100 IConfig mesh_config = config.Configs["Mesh"];
101 if (mesh_config != null)
102 {
103 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
104 doConvexPrims = mesh_config.GetBoolean("ConvexPrims",doConvexPrims);
105 doConvexSculpts = mesh_config.GetBoolean("ConvexSculpts",doConvexPrims);
106 doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache);
107 cachePath = mesh_config.GetString("MeshFileCachePath", cachePath);
108 fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache);
109 doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire);
110
111 m_Enabled = true;
112 }
113
114 CacheExpire = TimeSpan.FromHours(fcache);
115
116 if(String.IsNullOrEmpty(cachePath))
117 doMeshFileCache = false;
118
119 if(doMeshFileCache)
120 {
121 if(!checkCache())
122 {
123 doMeshFileCache = false;
124 doCacheExpire = false;
125 }
126 }
127 else
128 doCacheExpire = false;
129 }
130 }
131
132 public void Close()
133 {
134 }
135
136 public void AddRegion(Scene scene)
137 {
138 if (!m_Enabled)
139 return;
140
141 scene.RegisterModuleInterface<IMesher>(this);
142 }
143
144 public void RemoveRegion(Scene scene)
145 {
146 if (!m_Enabled)
147 return;
148
149 scene.UnregisterModuleInterface<IMesher>(this);
150 }
151
152 public void RegionLoaded(Scene scene)
153 {
154 if (!m_Enabled)
155 return;
156 }
157
158 #endregion
159
160 private void ReportPrimError(string message, string primName, PrimMesh primMesh)
161 {
162 m_log.Error(message);
163 m_log.Error("\nPrim Name: " + primName);
164 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString());
165 }
166
167 /// <summary>
168 /// Add a submesh to an existing list of coords and faces.
169 /// </summary>
170 /// <param name="subMeshData"></param>
171 /// <param name="size">Size of entire object</param>
172 /// <param name="coords"></param>
173 /// <param name="faces"></param>
174 private void AddSubMesh(OSDMap subMeshData, List<Coord> coords, List<Face> faces)
175 {
176 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap));
177
178 // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level
179 // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no
180 // geometry for this submesh.
181 if (subMeshData.ContainsKey("NoGeometry") && ((OSDBoolean)subMeshData["NoGeometry"]))
182 return;
183
184 OpenMetaverse.Vector3 posMax;
185 OpenMetaverse.Vector3 posMin;
186 if (subMeshData.ContainsKey("PositionDomain"))
187 {
188 posMax = ((OSDMap)subMeshData["PositionDomain"])["Max"].AsVector3();
189 posMin = ((OSDMap)subMeshData["PositionDomain"])["Min"].AsVector3();
190 }
191 else
192 {
193 posMax = new Vector3(0.5f, 0.5f, 0.5f);
194 posMin = new Vector3(-0.5f, -0.5f, -0.5f);
195 }
196
197 ushort faceIndexOffset = (ushort)coords.Count;
198
199 byte[] posBytes = subMeshData["Position"].AsBinary();
200 for (int i = 0; i < posBytes.Length; i += 6)
201 {
202 ushort uX = Utils.BytesToUInt16(posBytes, i);
203 ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
204 ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);
205
206 Coord c = new Coord(
207 Utils.UInt16ToFloat(uX, posMin.X, posMax.X),
208 Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y),
209 Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z));
210
211 coords.Add(c);
212 }
213
214 byte[] triangleBytes = subMeshData["TriangleList"].AsBinary();
215 for (int i = 0; i < triangleBytes.Length; i += 6)
216 {
217 ushort v1 = (ushort)(Utils.BytesToUInt16(triangleBytes, i) + faceIndexOffset);
218 ushort v2 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 2) + faceIndexOffset);
219 ushort v3 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 4) + faceIndexOffset);
220 Face f = new Face(v1, v2, v3);
221 faces.Add(f);
222 }
223 }
224
225 /// <summary>
226 /// Create a physics mesh from data that comes with the prim. The actual data used depends on the prim type.
227 /// </summary>
228 /// <param name="primName"></param>
229 /// <param name="primShape"></param>
230 /// <param name="size"></param>
231 /// <param name="lod"></param>
232 /// <returns></returns>
233 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, float lod, bool convex)
234 {
235// m_log.DebugFormat(
236// "[MESH]: Creating physics proxy for {0}, shape {1}",
237// primName, (OpenMetaverse.SculptType)primShape.SculptType);
238
239 List<Coord> coords;
240 List<Face> faces;
241 bool needsConvexProcessing = convex;
242
243 if (primShape.SculptEntry)
244 {
245 if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh)
246 {
247 if (!useMeshiesPhysicsMesh)
248 return null;
249
250 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex))
251 return null;
252 needsConvexProcessing = false;
253 }
254 else
255 {
256 if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces))
257 return null;
258 needsConvexProcessing &= doConvexSculpts;
259 }
260 }
261 else
262 {
263 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, convex, out coords, out faces))
264 return null;
265 needsConvexProcessing &= doConvexPrims;
266 }
267
268 int numCoords = coords.Count;
269 int numFaces = faces.Count;
270
271 if(numCoords < 3 || (!needsConvexProcessing && numFaces < 1))
272 {
273 m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName);
274 return null;
275 }
276
277 if(needsConvexProcessing)
278 {
279 List<Coord> convexcoords;
280 List<Face> convexfaces;
281 if(CreateBoundingHull(coords, out convexcoords, out convexfaces) && convexcoords != null && convexfaces != null)
282 {
283 coords.Clear();
284 coords = convexcoords;
285 numCoords = coords.Count;
286
287 faces.Clear();
288 faces = convexfaces;
289 numFaces = faces.Count;
290 }
291 else
292 m_log.ErrorFormat("[ubMESH]: failed to create convex for {0} using normal mesh", primName);
293 }
294
295 Mesh mesh = new Mesh(true);
296 // Add the corresponding triangles to the mesh
297 for (int i = 0; i < numFaces; i++)
298 {
299 Face f = faces[i];
300 mesh.Add(new Triangle(coords[f.v1].X, coords[f.v1].Y, coords[f.v1].Z,
301 coords[f.v2].X, coords[f.v2].Y, coords[f.v2].Z,
302 coords[f.v3].X, coords[f.v3].Y, coords[f.v3].Z));
303 }
304
305 coords.Clear();
306 faces.Clear();
307
308 if(mesh.numberVertices() < 3 || mesh.numberTriangles() < 1)
309 {
310 m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName);
311 return null;
312 }
313
314 primShape.SculptData = Utils.EmptyBytes;
315
316 return mesh;
317 }
318
319 /// <summary>
320 /// Generate the co-ords and faces necessary to construct a mesh from the mesh data the accompanies a prim.
321 /// </summary>
322 /// <param name="primName"></param>
323 /// <param name="primShape"></param>
324 /// <param name="size"></param>
325 /// <param name="coords">Coords are added to this list by the method.</param>
326 /// <param name="faces">Faces are added to this list by the method.</param>
327 /// <returns>true if coords and faces were successfully generated, false if not</returns>
328 private bool GenerateCoordsAndFacesFromPrimMeshData(
329 string primName, PrimitiveBaseShape primShape, out List<Coord> coords, out List<Face> faces, bool convex)
330 {
331// m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
332
333
334 // for ubOde we have a diferent mesh use priority
335 // priority is to use full mesh then decomposition
336 // SL does the oposite
337 bool usemesh = false;
338
339 coords = new List<Coord>();
340 faces = new List<Face>();
341 OSD meshOsd = null;
342
343 if (primShape.SculptData == null || primShape.SculptData.Length <= 0)
344 {
345// m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName);
346 return false;
347 }
348
349 long start = 0;
350 using (MemoryStream data = new MemoryStream(primShape.SculptData))
351 {
352 try
353 {
354 OSD osd = OSDParser.DeserializeLLSDBinary(data);
355 if (osd is OSDMap)
356 meshOsd = (OSDMap)osd;
357 else
358 {
359 m_log.WarnFormat("[Mesh}: unable to cast mesh asset to OSDMap prim: {0}",primName);
360 return false;
361 }
362 }
363 catch (Exception e)
364 {
365 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
366 return false;
367 }
368
369 start = data.Position;
370 }
371
372 if (meshOsd is OSDMap)
373 {
374 OSDMap physicsParms = null;
375 OSDMap map = (OSDMap)meshOsd;
376
377 if (!convex)
378 {
379 if (map.ContainsKey("physics_shape"))
380 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
381 else if (map.ContainsKey("physics_mesh"))
382 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
383
384 if (physicsParms != null)
385 usemesh = true;
386 }
387
388 if(!usemesh && (map.ContainsKey("physics_convex")))
389 physicsParms = (OSDMap)map["physics_convex"];
390
391 if (physicsParms == null)
392 {
393 //m_log.WarnFormat("[MESH]: unknown mesh type for prim {0}",primName);
394 return false;
395 }
396
397 int physOffset = physicsParms["offset"].AsInteger() + (int)start;
398 int physSize = physicsParms["size"].AsInteger();
399
400 if (physOffset < 0 || physSize == 0)
401 return false; // no mesh data in asset
402
403 OSD decodedMeshOsd = new OSD();
404 byte[] meshBytes = new byte[physSize];
405 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
406
407 try
408 {
409 using (MemoryStream inMs = new MemoryStream(meshBytes))
410 {
411 using (MemoryStream outMs = new MemoryStream())
412 {
413 using (DeflateStream decompressionStream = new DeflateStream(inMs, CompressionMode.Decompress))
414 {
415 byte[] readBuffer = new byte[2048];
416 inMs.Read(readBuffer, 0, 2); // skip first 2 bytes in header
417 int readLen = 0;
418
419 while ((readLen = decompressionStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
420 outMs.Write(readBuffer, 0, readLen);
421
422 outMs.Flush();
423 outMs.Seek(0, SeekOrigin.Begin);
424
425 byte[] decompressedBuf = outMs.GetBuffer();
426
427 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
428 }
429 }
430 }
431 }
432 catch (Exception e)
433 {
434 m_log.Error("[MESH]: exception decoding physical mesh prim " + primName +" : " + e.ToString());
435 return false;
436 }
437
438 if (usemesh)
439 {
440 OSDArray decodedMeshOsdArray = null;
441
442 // physics_shape is an array of OSDMaps, one for each submesh
443 if (decodedMeshOsd is OSDArray)
444 {
445// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
446
447 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
448 foreach (OSD subMeshOsd in decodedMeshOsdArray)
449 {
450 if (subMeshOsd is OSDMap)
451 AddSubMesh(subMeshOsd as OSDMap, coords, faces);
452 }
453 }
454 }
455 else
456 {
457 OSDMap cmap = (OSDMap)decodedMeshOsd;
458 if (cmap == null)
459 return false;
460
461 byte[] data;
462
463 List<float3> vs = new List<float3>();
464 PHullResult hullr = new PHullResult();
465 float3 f3;
466 Coord c;
467 Face f;
468 Vector3 range;
469 Vector3 min;
470
471 const float invMaxU16 = 1.0f / 65535f;
472 int t1;
473 int t2;
474 int t3;
475 int i;
476 int nverts;
477 int nindexs;
478
479 if (cmap.ContainsKey("Max"))
480 range = cmap["Max"].AsVector3();
481 else
482 range = new Vector3(0.5f, 0.5f, 0.5f);
483
484 if (cmap.ContainsKey("Min"))
485 min = cmap["Min"].AsVector3();
486 else
487 min = new Vector3(-0.5f, -0.5f, -0.5f);
488
489 range = range - min;
490 range *= invMaxU16;
491
492 if(!convex)
493 {
494 // if mesh data not present and not convex then we need convex decomposition data
495 if (cmap.ContainsKey("HullList") && cmap.ContainsKey("Positions"))
496 {
497 List<int> hsizes = new List<int>();
498 int totalpoints = 0;
499 data = cmap["HullList"].AsBinary();
500 for (i = 0; i < data.Length; i++)
501 {
502 t1 = data[i];
503 if (t1 == 0)
504 t1 = 256;
505 totalpoints += t1;
506 hsizes.Add(t1);
507 }
508
509 data = cmap["Positions"].AsBinary();
510 int ptr = 0;
511 int vertsoffset = 0;
512
513 if (totalpoints == data.Length / 6) // 2 bytes per coord, 3 coords per point
514 {
515 foreach (int hullsize in hsizes)
516 {
517 for (i = 0; i < hullsize; i++ )
518 {
519 t1 = data[ptr++];
520 t1 += data[ptr++] << 8;
521 t2 = data[ptr++];
522 t2 += data[ptr++] << 8;
523 t3 = data[ptr++];
524 t3 += data[ptr++] << 8;
525
526 f3 = new float3((t1 * range.X + min.X),
527 (t2 * range.Y + min.Y),
528 (t3 * range.Z + min.Z));
529 vs.Add(f3);
530 }
531
532 if(hullsize <3)
533 {
534 vs.Clear();
535 continue;
536 }
537
538 if (hullsize <5)
539 {
540 foreach (float3 point in vs)
541 {
542 c.X = point.x;
543 c.Y = point.y;
544 c.Z = point.z;
545 coords.Add(c);
546 }
547 f = new Face(vertsoffset, vertsoffset + 1, vertsoffset + 2);
548 faces.Add(f);
549
550 if (hullsize == 4)
551 {
552 // not sure about orientation..
553 f = new Face(vertsoffset, vertsoffset + 2, vertsoffset + 3);
554 faces.Add(f);
555 f = new Face(vertsoffset, vertsoffset + 3, vertsoffset + 1);
556 faces.Add(f);
557 f = new Face(vertsoffset + 3, vertsoffset + 2, vertsoffset + 1);
558 faces.Add(f);
559 }
560 vertsoffset += vs.Count;
561 vs.Clear();
562 continue;
563 }
564
565 List<int> indices;
566 if (!HullUtils.ComputeHull(vs, out indices))
567 {
568 vs.Clear();
569 continue;
570 }
571
572 nverts = vs.Count;
573 nindexs = indices.Count;
574
575 if (nindexs % 3 != 0)
576 {
577 vs.Clear();
578 continue;
579 }
580
581 for (i = 0; i < nverts; i++)
582 {
583 c.X = vs[i].x;
584 c.Y = vs[i].y;
585 c.Z = vs[i].z;
586 coords.Add(c);
587 }
588
589 for (i = 0; i < nindexs; i += 3)
590 {
591 t1 = indices[i];
592 if (t1 > nverts)
593 break;
594 t2 = indices[i + 1];
595 if (t2 > nverts)
596 break;
597 t3 = indices[i + 2];
598 if (t3 > nverts)
599 break;
600 f = new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3);
601 faces.Add(f);
602 }
603 vertsoffset += nverts;
604 vs.Clear();
605 }
606 }
607 if (coords.Count > 0 && faces.Count > 0)
608 return true;
609 }
610 else
611 {
612 // if neither mesh or decomposition present, warn and use convex
613 //m_log.WarnFormat("[MESH]: Data for PRIM shape type ( mesh or decomposition) not found for prim {0}",primName);
614 }
615 }
616 vs.Clear();
617
618 if (cmap.ContainsKey("BoundingVerts"))
619 {
620 data = cmap["BoundingVerts"].AsBinary();
621
622 for (i = 0; i < data.Length; )
623 {
624 t1 = data[i++];
625 t1 += data[i++] << 8;
626 t2 = data[i++];
627 t2 += data[i++] << 8;
628 t3 = data[i++];
629 t3 += data[i++] << 8;
630
631 f3 = new float3((t1 * range.X + min.X),
632 (t2 * range.Y + min.Y),
633 (t3 * range.Z + min.Z));
634 vs.Add(f3);
635 }
636
637 nverts = vs.Count;
638
639 if (nverts < 3)
640 {
641 vs.Clear();
642 return false;
643 }
644
645 if (nverts < 5)
646 {
647 foreach (float3 point in vs)
648 {
649 c.X = point.x;
650 c.Y = point.y;
651 c.Z = point.z;
652 coords.Add(c);
653 }
654
655 f = new Face(0, 1, 2);
656 faces.Add(f);
657
658 if (nverts == 4)
659 {
660 f = new Face(0, 2, 3);
661 faces.Add(f);
662 f = new Face(0, 3, 1);
663 faces.Add(f);
664 f = new Face( 3, 2, 1);
665 faces.Add(f);
666 }
667 vs.Clear();
668 return true;
669 }
670
671 List<int> indices;
672 if (!HullUtils.ComputeHull(vs, out indices))
673 return false;
674
675 nindexs = indices.Count;
676
677 if (nindexs % 3 != 0)
678 return false;
679
680 for (i = 0; i < nverts; i++)
681 {
682 c.X = vs[i].x;
683 c.Y = vs[i].y;
684 c.Z = vs[i].z;
685 coords.Add(c);
686 }
687 for (i = 0; i < nindexs; i += 3)
688 {
689 t1 = indices[i];
690 if (t1 > nverts)
691 break;
692 t2 = indices[i + 1];
693 if (t2 > nverts)
694 break;
695 t3 = indices[i + 2];
696 if (t3 > nverts)
697 break;
698 f = new Face(t1, t2, t3);
699 faces.Add(f);
700 }
701 vs.Clear();
702 if (coords.Count > 0 && faces.Count > 0)
703 return true;
704 }
705 else
706 return false;
707 }
708 }
709
710 return true;
711 }
712
713 /// <summary>
714 /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim.
715 /// </summary>
716 /// <param name="primName"></param>
717 /// <param name="primShape"></param>
718 /// <param name="size"></param>
719 /// <param name="lod"></param>
720 /// <param name="coords">Coords are added to this list by the method.</param>
721 /// <param name="faces">Faces are added to this list by the method.</param>
722 /// <returns>true if coords and faces were successfully generated, false if not</returns>
723 private bool GenerateCoordsAndFacesFromPrimSculptData(
724 string primName, PrimitiveBaseShape primShape, float lod, out List<Coord> coords, out List<Face> faces)
725 {
726 coords = new List<Coord>();
727 faces = new List<Face>();
728 PrimMesher.SculptMesh sculptMesh;
729 Image idata = null;
730
731 if (primShape.SculptData == null || primShape.SculptData.Length == 0)
732 return false;
733
734 try
735 {
736 OpenMetaverse.Imaging.ManagedImage unusedData;
737 OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
738
739 unusedData = null;
740
741 if (idata == null)
742 {
743 // In some cases it seems that the decode can return a null bitmap without throwing
744 // an exception
745 m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName);
746 return false;
747 }
748 }
749 catch (DllNotFoundException)
750 {
751 m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!");
752 return false;
753 }
754 catch (IndexOutOfRangeException)
755 {
756 m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
757 return false;
758 }
759 catch (Exception ex)
760 {
761 m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
762 return false;
763 }
764
765 PrimMesher.SculptMesh.SculptType sculptType;
766 // remove mirror and invert bits
767 OpenMetaverse.SculptType pbsSculptType = ((OpenMetaverse.SculptType)(primShape.SculptType & 0x3f));
768 switch (pbsSculptType)
769 {
770 case OpenMetaverse.SculptType.Cylinder:
771 sculptType = PrimMesher.SculptMesh.SculptType.cylinder;
772 break;
773 case OpenMetaverse.SculptType.Plane:
774 sculptType = PrimMesher.SculptMesh.SculptType.plane;
775 break;
776 case OpenMetaverse.SculptType.Torus:
777 sculptType = PrimMesher.SculptMesh.SculptType.torus;
778 break;
779 case OpenMetaverse.SculptType.Sphere:
780 sculptType = PrimMesher.SculptMesh.SculptType.sphere;
781 break;
782 default:
783 sculptType = PrimMesher.SculptMesh.SculptType.plane;
784 break;
785 }
786
787 bool mirror = ((primShape.SculptType & 128) != 0);
788 bool invert = ((primShape.SculptType & 64) != 0);
789
790 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, mirror, invert);
791
792 idata.Dispose();
793
794// sculptMesh.DumpRaw(baseDir, primName, "primMesh");
795
796 coords = sculptMesh.coords;
797 faces = sculptMesh.faces;
798
799 return true;
800 }
801
802 /// <summary>
803 /// Generate the co-ords and faces necessary to construct a mesh from the shape data the accompanies a prim.
804 /// </summary>
805 /// <param name="primName"></param>
806 /// <param name="primShape"></param>
807 /// <param name="size"></param>
808 /// <param name="coords">Coords are added to this list by the method.</param>
809 /// <param name="faces">Faces are added to this list by the method.</param>
810 /// <returns>true if coords and faces were successfully generated, false if not</returns>
811 private bool GenerateCoordsAndFacesFromPrimShapeData(
812 string primName, PrimitiveBaseShape primShape, float lod, bool convex,
813 out List<Coord> coords, out List<Face> faces)
814 {
815 PrimMesh primMesh;
816 coords = new List<Coord>();
817 faces = new List<Face>();
818
819 float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
820 float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
821 float pathBegin = (float)primShape.PathBegin * 2.0e-5f;
822 float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f;
823 float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f;
824 float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f;
825
826 float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f;
827 float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
828
829 if (profileBegin < 0.0f)
830 profileBegin = 0.0f;
831
832 if (profileEnd < 0.02f)
833 profileEnd = 0.02f;
834 else if (profileEnd > 1.0f)
835 profileEnd = 1.0f;
836
837 if (profileBegin >= profileEnd)
838 profileBegin = profileEnd - 0.02f;
839
840 float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
841 if(convex)
842 profileHollow = 0.0f;
843 else if (profileHollow > 0.95f)
844 profileHollow = 0.95f;
845
846 int sides = 4;
847 LevelOfDetail iLOD = (LevelOfDetail)lod;
848 byte profshape = (byte)(primShape.ProfileCurve & 0x07);
849
850 if (profshape == (byte)ProfileShape.EquilateralTriangle
851 || profshape == (byte)ProfileShape.IsometricTriangle
852 || profshape == (byte)ProfileShape.RightTriangle)
853 sides = 3;
854 else if (profshape == (byte)ProfileShape.Circle)
855 {
856 switch (iLOD)
857 {
858 case LevelOfDetail.High: sides = 24; break;
859 case LevelOfDetail.Medium: sides = 12; break;
860 case LevelOfDetail.Low: sides = 6; break;
861 case LevelOfDetail.VeryLow: sides = 3; break;
862 default: sides = 24; break;
863 }
864 }
865 else if (profshape == (byte)ProfileShape.HalfCircle)
866 { // half circle, prim is a sphere
867 switch (iLOD)
868 {
869 case LevelOfDetail.High: sides = 24; break;
870 case LevelOfDetail.Medium: sides = 12; break;
871 case LevelOfDetail.Low: sides = 6; break;
872 case LevelOfDetail.VeryLow: sides = 3; break;
873 default: sides = 24; break;
874 }
875
876 profileBegin = 0.5f * profileBegin + 0.5f;
877 profileEnd = 0.5f * profileEnd + 0.5f;
878 }
879
880 int hollowSides = sides;
881 if (primShape.HollowShape == HollowShape.Circle)
882 {
883 switch (iLOD)
884 {
885 case LevelOfDetail.High: hollowSides = 24; break;
886 case LevelOfDetail.Medium: hollowSides = 12; break;
887 case LevelOfDetail.Low: hollowSides = 6; break;
888 case LevelOfDetail.VeryLow: hollowSides = 3; break;
889 default: hollowSides = 24; break;
890 }
891 }
892 else if (primShape.HollowShape == HollowShape.Square)
893 hollowSides = 4;
894 else if (primShape.HollowShape == HollowShape.Triangle)
895 {
896 if (profshape == (byte)ProfileShape.HalfCircle)
897 hollowSides = 6;
898 else
899 hollowSides = 3;
900 }
901
902 primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);
903
904 if (primMesh.errorMessage != null)
905 if (primMesh.errorMessage.Length > 0)
906 m_log.Error("[ERROR] " + primMesh.errorMessage);
907
908 primMesh.topShearX = pathShearX;
909 primMesh.topShearY = pathShearY;
910 primMesh.pathCutBegin = pathBegin;
911 primMesh.pathCutEnd = pathEnd;
912
913 if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible)
914 {
915 primMesh.twistBegin = (primShape.PathTwistBegin * 18) / 10;
916 primMesh.twistEnd = (primShape.PathTwist * 18) / 10;
917 primMesh.taperX = pathScaleX;
918 primMesh.taperY = pathScaleY;
919
920#if SPAM
921 m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
922#endif
923 try
924 {
925 primMesh.ExtrudeLinear();
926 }
927 catch (Exception ex)
928 {
929 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
930 return false;
931 }
932 }
933 else
934 {
935 primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f;
936 primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f;
937 primMesh.radius = 0.01f * primShape.PathRadiusOffset;
938 primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
939 primMesh.skew = 0.01f * primShape.PathSkew;
940 primMesh.twistBegin = (primShape.PathTwistBegin * 36) / 10;
941 primMesh.twistEnd = (primShape.PathTwist * 36) / 10;
942 primMesh.taperX = primShape.PathTaperX * 0.01f;
943 primMesh.taperY = primShape.PathTaperY * 0.01f;
944
945 if(profshape == (byte)ProfileShape.HalfCircle)
946 {
947 if(primMesh.holeSizeY < 0.01f)
948 primMesh.holeSizeY = 0.01f;
949 else if(primMesh.holeSizeY > 1.0f)
950 primMesh.holeSizeY = 1.0f;
951 }
952
953#if SPAM
954 m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
955#endif
956 try
957 {
958 primMesh.ExtrudeCircular();
959 }
960 catch (Exception ex)
961 {
962 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
963 return false;
964 }
965 }
966
967// primMesh.DumpRaw(baseDir, primName, "primMesh");
968
969 coords = primMesh.coords;
970 faces = primMesh.faces;
971
972 return true;
973 }
974
975 public AMeshKey GetMeshUniqueKey(PrimitiveBaseShape primShape, Vector3 size, byte lod, bool convex)
976 {
977 AMeshKey key = new AMeshKey();
978 Byte[] someBytes;
979
980 key.hashB = 5181;
981 key.hashC = 5181;
982 ulong hash = 5381;
983
984 if (primShape.SculptEntry)
985 {
986 key.uuid = primShape.SculptTexture;
987 key.hashC = mdjb2(key.hashC, primShape.SculptType);
988 key.hashC = mdjb2(key.hashC, primShape.PCode);
989 }
990 else
991 {
992 hash = mdjb2(hash, primShape.PathCurve);
993 hash = mdjb2(hash, (byte)primShape.HollowShape);
994 hash = mdjb2(hash, (byte)primShape.ProfileShape);
995 hash = mdjb2(hash, primShape.PathBegin);
996 hash = mdjb2(hash, primShape.PathEnd);
997 hash = mdjb2(hash, primShape.PathScaleX);
998 hash = mdjb2(hash, primShape.PathScaleY);
999 hash = mdjb2(hash, primShape.PathShearX);
1000 key.hashA = hash;
1001 hash = key.hashB;
1002 hash = mdjb2(hash, primShape.PathShearY);
1003 hash = mdjb2(hash, (byte)primShape.PathTwist);
1004 hash = mdjb2(hash, (byte)primShape.PathTwistBegin);
1005 hash = mdjb2(hash, (byte)primShape.PathRadiusOffset);
1006 hash = mdjb2(hash, (byte)primShape.PathTaperX);
1007 hash = mdjb2(hash, (byte)primShape.PathTaperY);
1008 hash = mdjb2(hash, primShape.PathRevolutions);
1009 hash = mdjb2(hash, (byte)primShape.PathSkew);
1010 hash = mdjb2(hash, primShape.ProfileBegin);
1011 hash = mdjb2(hash, primShape.ProfileEnd);
1012 hash = mdjb2(hash, primShape.ProfileHollow);
1013 hash = mdjb2(hash, primShape.PCode);
1014 key.hashB = hash;
1015 }
1016
1017 hash = key.hashC;
1018
1019 hash = mdjb2(hash, lod);
1020
1021 if (size == m_MeshUnitSize)
1022 {
1023 hash = hash << 8;
1024 hash |= 8;
1025 }
1026 else
1027 {
1028 someBytes = size.GetBytes();
1029 for (int i = 0; i < someBytes.Length; i++)
1030 hash = mdjb2(hash, someBytes[i]);
1031 hash = hash << 8;
1032 }
1033
1034 if (convex)
1035 hash |= 4;
1036
1037 if (primShape.SculptEntry)
1038 {
1039 hash |= 1;
1040 if (primShape.SculptType == (byte)SculptType.Mesh)
1041 hash |= 2;
1042 }
1043
1044 key.hashC = hash;
1045
1046 return key;
1047 }
1048
1049 private ulong mdjb2(ulong hash, byte c)
1050 {
1051 return ((hash << 5) + hash) + (ulong)c;
1052 }
1053
1054 private ulong mdjb2(ulong hash, ushort c)
1055 {
1056 hash = ((hash << 5) + hash) + (ulong)((byte)c);
1057 return ((hash << 5) + hash) + (ulong)(c >> 8);
1058 }
1059
1060 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
1061 {
1062 return CreateMesh(primName, primShape, size, lod, false,false,false);
1063 }
1064
1065 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical)
1066 {
1067 return CreateMesh(primName, primShape, size, lod, false,false,false);
1068 }
1069
1070 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde)
1071 {
1072 return CreateMesh(primName, primShape, size, lod, false, false, false);
1073 }
1074
1075 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
1076 {
1077 Mesh mesh = null;
1078
1079 if (size.X < 0.01f) size.X = 0.01f;
1080 if (size.Y < 0.01f) size.Y = 0.01f;
1081 if (size.Z < 0.01f) size.Z = 0.01f;
1082
1083 AMeshKey key = GetMeshUniqueKey(primShape, size, (byte)lod, convex);
1084 lock (m_uniqueMeshes)
1085 {
1086 m_uniqueMeshes.TryGetValue(key, out mesh);
1087
1088 if (mesh != null)
1089 {
1090 mesh.RefCount++;
1091 return mesh;
1092 }
1093
1094 // try to find a identical mesh on meshs recently released
1095 lock (m_uniqueReleasedMeshes)
1096 {
1097 m_uniqueReleasedMeshes.TryGetValue(key, out mesh);
1098 if (mesh != null)
1099 {
1100 m_uniqueReleasedMeshes.Remove(key);
1101 try
1102 {
1103 m_uniqueMeshes.Add(key, mesh);
1104 }
1105 catch { }
1106 mesh.RefCount = 1;
1107 return mesh;
1108 }
1109 }
1110 }
1111 return null;
1112 }
1113
1114 private static Vector3 m_MeshUnitSize = new Vector3(1.0f, 1.0f, 1.0f);
1115
1116 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde)
1117 {
1118#if SPAM
1119 m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName);
1120#endif
1121
1122 Mesh mesh = null;
1123
1124 if (size.X < 0.01f) size.X = 0.01f;
1125 if (size.Y < 0.01f) size.Y = 0.01f;
1126 if (size.Z < 0.01f) size.Z = 0.01f;
1127
1128 // try to find a identical mesh on meshs in use
1129
1130 AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex);
1131
1132 lock (m_uniqueMeshes)
1133 {
1134 m_uniqueMeshes.TryGetValue(key, out mesh);
1135
1136 if (mesh != null)
1137 {
1138 mesh.RefCount++;
1139 return mesh;
1140 }
1141
1142 // try to find a identical mesh on meshs recently released
1143 lock (m_uniqueReleasedMeshes)
1144 {
1145 m_uniqueReleasedMeshes.TryGetValue(key, out mesh);
1146 if (mesh != null)
1147 {
1148 m_uniqueReleasedMeshes.Remove(key);
1149 try
1150 {
1151 m_uniqueMeshes.Add(key, mesh);
1152 }
1153 catch { }
1154 mesh.RefCount = 1;
1155 return mesh;
1156 }
1157 }
1158 }
1159
1160 Mesh UnitMesh = null;
1161 AMeshKey unitKey = GetMeshUniqueKey(primShape, m_MeshUnitSize, (byte)lod, convex);
1162
1163 lock (m_uniqueReleasedMeshes)
1164 {
1165 m_uniqueReleasedMeshes.TryGetValue(unitKey, out UnitMesh);
1166 if (UnitMesh != null)
1167 {
1168 UnitMesh.RefCount = 1;
1169 }
1170 }
1171
1172 if (UnitMesh == null && primShape.SculptEntry && doMeshFileCache)
1173 UnitMesh = GetFromFileCache(unitKey);
1174
1175 if (UnitMesh == null)
1176 {
1177 UnitMesh = CreateMeshFromPrimMesher(primName, primShape, lod, convex);
1178
1179 if (UnitMesh == null)
1180 return null;
1181
1182 UnitMesh.DumpRaw(baseDir, unitKey.ToString(), "Z");
1183
1184 if (forOde)
1185 {
1186 // force pinned mem allocation
1187 UnitMesh.PrepForOde();
1188 }
1189 else
1190 UnitMesh.TrimExcess();
1191
1192 UnitMesh.Key = unitKey;
1193 UnitMesh.RefCount = 1;
1194
1195 if (doMeshFileCache && primShape.SculptEntry)
1196 StoreToFileCache(unitKey, UnitMesh);
1197
1198 lock (m_uniqueReleasedMeshes)
1199 {
1200 try
1201 {
1202 m_uniqueReleasedMeshes.Add(unitKey, UnitMesh);
1203 }
1204 catch { }
1205 }
1206 }
1207
1208 mesh = UnitMesh.Scale(size);
1209 mesh.Key = key;
1210 mesh.RefCount = 1;
1211 lock (m_uniqueMeshes)
1212 {
1213 try
1214 {
1215 m_uniqueMeshes.Add(key, mesh);
1216 }
1217 catch { }
1218 }
1219
1220 return mesh;
1221 }
1222
1223 public void ReleaseMesh(IMesh imesh)
1224 {
1225 if (imesh == null)
1226 return;
1227
1228 Mesh mesh = (Mesh)imesh;
1229
1230 lock (m_uniqueMeshes)
1231 {
1232 int curRefCount = mesh.RefCount;
1233 curRefCount--;
1234
1235 if (curRefCount > 0)
1236 {
1237 mesh.RefCount = curRefCount;
1238 return;
1239 }
1240
1241 mesh.RefCount = 0;
1242 m_uniqueMeshes.Remove(mesh.Key);
1243 lock (m_uniqueReleasedMeshes)
1244 {
1245 try
1246 {
1247 m_uniqueReleasedMeshes.Add(mesh.Key, mesh);
1248 }
1249 catch { }
1250 }
1251 }
1252 }
1253
1254 public void ExpireReleaseMeshs()
1255 {
1256 if (m_uniqueReleasedMeshes.Count == 0)
1257 return;
1258
1259 List<Mesh> meshstodelete = new List<Mesh>();
1260 int refcntr;
1261
1262 lock (m_uniqueReleasedMeshes)
1263 {
1264 foreach (Mesh m in m_uniqueReleasedMeshes.Values)
1265 {
1266 refcntr = m.RefCount;
1267 refcntr--;
1268 if (refcntr > -6)
1269 m.RefCount = refcntr;
1270 else
1271 meshstodelete.Add(m);
1272 }
1273
1274 foreach (Mesh m in meshstodelete)
1275 {
1276 m_uniqueReleasedMeshes.Remove(m.Key);
1277 m.releaseBuildingMeshData();
1278 m.releasePinned();
1279 }
1280 }
1281 }
1282
1283 public void FileNames(AMeshKey key, out string dir, out string fullFileName)
1284 {
1285 string id = key.ToString();
1286 string init = id.Substring(0, 1);
1287 dir = System.IO.Path.Combine(cachePath, init);
1288 fullFileName = System.IO.Path.Combine(dir, id);
1289 }
1290
1291 public string FullFileName(AMeshKey key)
1292 {
1293 string id = key.ToString();
1294 string init = id.Substring(0,1);
1295 id = System.IO.Path.Combine(init, id);
1296 id = System.IO.Path.Combine(cachePath, id);
1297 return id;
1298 }
1299
1300 private Mesh GetFromFileCache(AMeshKey key)
1301 {
1302 Mesh mesh = null;
1303 string filename = FullFileName(key);
1304 bool ok = true;
1305
1306 lock (diskLock)
1307 {
1308 if (File.Exists(filename))
1309 {
1310 try
1311 {
1312 using(FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
1313 {
1314// BinaryFormatter bformatter = new BinaryFormatter();
1315 mesh = Mesh.FromStream(stream,key);
1316 }
1317
1318 }
1319 catch (Exception e)
1320 {
1321 ok = false;
1322 m_log.ErrorFormat(
1323 "[MESH CACHE]: Failed to get file {0}. Exception {1} {2}",
1324 filename, e.Message, e.StackTrace);
1325 }
1326
1327 try
1328 {
1329 if (mesh == null || !ok)
1330 File.Delete(filename);
1331 else
1332 File.SetLastAccessTimeUtc(filename, DateTime.UtcNow);
1333 }
1334 catch
1335 {
1336 }
1337
1338 }
1339 }
1340
1341 return mesh;
1342 }
1343
1344 private void StoreToFileCache(AMeshKey key, Mesh mesh)
1345 {
1346 bool ok = false;
1347
1348 // Make sure the target cache directory exists
1349 string dir = String.Empty;
1350 string filename = String.Empty;
1351
1352 FileNames(key, out dir, out filename);
1353
1354 lock (diskLock)
1355 {
1356 Stream stream = null;
1357 try
1358 {
1359 if (!Directory.Exists(dir))
1360 {
1361 Directory.CreateDirectory(dir);
1362 }
1363
1364 stream = File.Open(filename, FileMode.Create);
1365 ok = mesh.ToStream(stream);
1366 }
1367 catch (IOException e)
1368 {
1369 m_log.ErrorFormat(
1370 "[MESH CACHE]: Failed to write file {0}. Exception {1} {2}.",
1371 filename, e.Message, e.StackTrace);
1372 ok = false;
1373 }
1374 finally
1375 {
1376 if(stream != null)
1377 stream.Dispose();
1378 }
1379
1380 if (!ok && File.Exists(filename))
1381 {
1382 try
1383 {
1384 File.Delete(filename);
1385 }
1386 catch (IOException e)
1387 {
1388 m_log.ErrorFormat(
1389 "[MESH CACHE]: Failed to delete file {0}",filename);
1390 }
1391 }
1392 }
1393 }
1394
1395 public void ExpireFileCache()
1396 {
1397 if (!doCacheExpire)
1398 return;
1399
1400 string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename);
1401
1402 lock (diskLock)
1403 {
1404 try
1405 {
1406 if (File.Exists(controlfile))
1407 {
1408 int ndeleted = 0;
1409 int totalfiles = 0;
1410 int ndirs = 0;
1411 DateTime OlderTime = File.GetLastAccessTimeUtc(controlfile) - CacheExpire;
1412 File.SetLastAccessTimeUtc(controlfile, DateTime.UtcNow);
1413
1414 foreach (string dir in Directory.GetDirectories(cachePath))
1415 {
1416 try
1417 {
1418 foreach (string file in Directory.GetFiles(dir))
1419 {
1420 try
1421 {
1422 if (File.GetLastAccessTimeUtc(file) < OlderTime)
1423 {
1424 File.Delete(file);
1425 ndeleted++;
1426 }
1427 }
1428 catch { }
1429 totalfiles++;
1430 }
1431 }
1432 catch { }
1433 ndirs++;
1434 }
1435
1436 if (ndeleted == 0)
1437 m_log.InfoFormat("[MESH CACHE]: {0} Files in {1} cache folders, no expires",
1438 totalfiles,ndirs);
1439 else
1440 m_log.InfoFormat("[MESH CACHE]: {0} Files in {1} cache folders, expired {2} files accessed before {3}",
1441 totalfiles,ndirs, ndeleted, OlderTime.ToString());
1442 }
1443 else
1444 {
1445 m_log.Info("[MESH CACHE]: Expire delayed to next startup");
1446 FileStream fs = File.Create(controlfile,4096,FileOptions.WriteThrough);
1447 fs.Close();
1448 }
1449 }
1450 catch { }
1451 }
1452 }
1453
1454 public bool checkCache()
1455 {
1456 string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename);
1457 lock (diskLock)
1458 {
1459 try
1460 {
1461 if (!Directory.Exists(cachePath))
1462 {
1463 Directory.CreateDirectory(cachePath);
1464 Thread.Sleep(100);
1465 FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough);
1466 fs.Close();
1467 return true;
1468 }
1469 }
1470 catch
1471 {
1472 doMeshFileCache = false;
1473 doCacheExpire = false;
1474 return false;
1475 }
1476 finally {}
1477
1478 if (File.Exists(controlfile))
1479 return true;
1480
1481 try
1482 {
1483 Directory.Delete(cachePath, true);
1484 while(Directory.Exists(cachePath))
1485 Thread.Sleep(100);
1486 }
1487 catch(Exception e)
1488 {
1489 m_log.Error("[MESH CACHE]: failed to delete old version of the cache: " + e.Message);
1490 doMeshFileCache = false;
1491 doCacheExpire = false;
1492 return false;
1493 }
1494 finally {}
1495 try
1496 {
1497 Directory.CreateDirectory(cachePath);
1498 while(!Directory.Exists(cachePath))
1499 Thread.Sleep(100);
1500 }
1501 catch(Exception e)
1502 {
1503 m_log.Error("[MESH CACHE]: failed to create new cache folder: " + e.Message);
1504 doMeshFileCache = false;
1505 doCacheExpire = false;
1506 return false;
1507 }
1508 finally {}
1509
1510 try
1511 {
1512 FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough);
1513 fs.Close();
1514 }
1515 catch(Exception e)
1516 {
1517 m_log.Error("[MESH CACHE]: failed to create new control file: " + e.Message);
1518 doMeshFileCache = false;
1519 doCacheExpire = false;
1520 return false;
1521 }
1522 finally {}
1523
1524 return true;
1525 }
1526 }
1527
1528 public bool CreateBoundingHull(List<Coord> inputVertices, out List<Coord> convexcoords, out List<Face> newfaces)
1529 {
1530 convexcoords = null;
1531 newfaces = null;
1532 HullDesc desc = new HullDesc();
1533 HullResult result = new HullResult();
1534
1535 int nInputVerts = inputVertices.Count;
1536 int i;
1537
1538 List<float3> vs = new List<float3>(nInputVerts);
1539 float3 f3;
1540
1541 //useless copy
1542 for(i = 0 ; i < nInputVerts; i++)
1543 {
1544 f3 = new float3(inputVertices[i].X, inputVertices[i].Y, inputVertices[i].Z);
1545 vs.Add(f3);
1546 }
1547
1548 desc.Vertices = vs;
1549 desc.Flags = HullFlag.QF_TRIANGLES;
1550 desc.MaxVertices = 256;
1551
1552 try
1553 {
1554 HullError ret = HullUtils.CreateConvexHull(desc, ref result);
1555 if (ret != HullError.QE_OK)
1556 return false;
1557 int nverts = result.OutputVertices.Count;
1558 int nindx = result.Indices.Count;
1559 if(nverts < 3 || nindx< 3)
1560 return false;
1561 if(nindx % 3 != 0)
1562 return false;
1563
1564 convexcoords = new List<Coord>(nverts);
1565 Coord c;
1566 vs = result.OutputVertices;
1567
1568 for(i = 0 ; i < nverts; i++)
1569 {
1570 c = new Coord(vs[i].x, vs[i].y, vs[i].z);
1571 convexcoords.Add(c);
1572 }
1573
1574 newfaces = new List<Face>(nindx / 3);
1575 List<int> indxs = result.Indices;
1576 int k, l, m;
1577 Face f;
1578 for(i = 0 ; i < nindx;)
1579 {
1580 k = indxs[i++];
1581 l = indxs[i++];
1582 m = indxs[i++];
1583 if(k > nInputVerts)
1584 continue;
1585 if(l > nInputVerts)
1586 continue;
1587 if(m > nInputVerts)
1588 continue;
1589 f = new Face(k,l,m);
1590 newfaces.Add(f);
1591 }
1592 return true;
1593 }
1594 catch
1595 {
1596
1597 return false;
1598 }
1599 return false;
1600 }
1601 }
1602}
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs
new file mode 100644
index 0000000..e93175f
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs
@@ -0,0 +1,1707 @@
1/*
2 * Copyright (c) Contributors
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.Text;
31using System.IO;
32
33namespace PrimMesher
34{
35 public struct Quat
36 {
37 /// <summary>X value</summary>
38 public float X;
39 /// <summary>Y value</summary>
40 public float Y;
41 /// <summary>Z value</summary>
42 public float Z;
43 /// <summary>W value</summary>
44 public float W;
45
46 public Quat(float x, float y, float z, float w)
47 {
48 X = x;
49 Y = y;
50 Z = z;
51 W = w;
52 }
53
54 public Quat(Coord axis, float angle)
55 {
56 axis = axis.Normalize();
57
58 angle *= 0.5f;
59 float c = (float)Math.Cos(angle);
60 float s = (float)Math.Sin(angle);
61
62 X = axis.X * s;
63 Y = axis.Y * s;
64 Z = axis.Z * s;
65 W = c;
66
67 Normalize();
68 }
69
70 public float Length()
71 {
72 return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
73 }
74
75 public Quat Normalize()
76 {
77 const float MAG_THRESHOLD = 0.0000001f;
78 float mag = Length();
79
80 // Catch very small rounding errors when normalizing
81 if (mag > MAG_THRESHOLD)
82 {
83 float oomag = 1f / mag;
84 X *= oomag;
85 Y *= oomag;
86 Z *= oomag;
87 W *= oomag;
88 }
89 else
90 {
91 X = 0f;
92 Y = 0f;
93 Z = 0f;
94 W = 1f;
95 }
96
97 return this;
98 }
99
100 public static Quat operator *(Quat q1, Quat q2)
101 {
102 float x = q1.W * q2.X + q1.X * q2.W + q1.Y * q2.Z - q1.Z * q2.Y;
103 float y = q1.W * q2.Y - q1.X * q2.Z + q1.Y * q2.W + q1.Z * q2.X;
104 float z = q1.W * q2.Z + q1.X * q2.Y - q1.Y * q2.X + q1.Z * q2.W;
105 float w = q1.W * q2.W - q1.X * q2.X - q1.Y * q2.Y - q1.Z * q2.Z;
106 return new Quat(x, y, z, w);
107 }
108
109 public override string ToString()
110 {
111 return "< X: " + this.X.ToString() + ", Y: " + this.Y.ToString() + ", Z: " + this.Z.ToString() + ", W: " + this.W.ToString() + ">";
112 }
113 }
114
115 public struct Coord
116 {
117 public float X;
118 public float Y;
119 public float Z;
120
121 public Coord(float x, float y, float z)
122 {
123 this.X = x;
124 this.Y = y;
125 this.Z = z;
126 }
127
128 public float Length()
129 {
130 return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z);
131 }
132
133 public Coord Invert()
134 {
135 this.X = -this.X;
136 this.Y = -this.Y;
137 this.Z = -this.Z;
138
139 return this;
140 }
141
142 public Coord Normalize()
143 {
144 const float MAG_THRESHOLD = 0.0000001f;
145 float mag = Length();
146
147 // Catch very small rounding errors when normalizing
148 if (mag > MAG_THRESHOLD)
149 {
150 float oomag = 1.0f / mag;
151 this.X *= oomag;
152 this.Y *= oomag;
153 this.Z *= oomag;
154 }
155 else
156 {
157 this.X = 0.0f;
158 this.Y = 0.0f;
159 this.Z = 0.0f;
160 }
161
162 return this;
163 }
164
165 public override string ToString()
166 {
167 return this.X.ToString() + " " + this.Y.ToString() + " " + this.Z.ToString();
168 }
169
170 public static Coord Cross(Coord c1, Coord c2)
171 {
172 return new Coord(
173 c1.Y * c2.Z - c2.Y * c1.Z,
174 c1.Z * c2.X - c2.Z * c1.X,
175 c1.X * c2.Y - c2.X * c1.Y
176 );
177 }
178
179 public static Coord operator +(Coord v, Coord a)
180 {
181 return new Coord(v.X + a.X, v.Y + a.Y, v.Z + a.Z);
182 }
183
184 public static Coord operator *(Coord v, Coord m)
185 {
186 return new Coord(v.X * m.X, v.Y * m.Y, v.Z * m.Z);
187 }
188
189 public static Coord operator *(Coord v, Quat q)
190 {
191 // From http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/
192
193 Coord c2 = new Coord(0.0f, 0.0f, 0.0f);
194
195 c2.X = q.W * q.W * v.X +
196 2f * q.Y * q.W * v.Z -
197 2f * q.Z * q.W * v.Y +
198 q.X * q.X * v.X +
199 2f * q.Y * q.X * v.Y +
200 2f * q.Z * q.X * v.Z -
201 q.Z * q.Z * v.X -
202 q.Y * q.Y * v.X;
203
204 c2.Y =
205 2f * q.X * q.Y * v.X +
206 q.Y * q.Y * v.Y +
207 2f * q.Z * q.Y * v.Z +
208 2f * q.W * q.Z * v.X -
209 q.Z * q.Z * v.Y +
210 q.W * q.W * v.Y -
211 2f * q.X * q.W * v.Z -
212 q.X * q.X * v.Y;
213
214 c2.Z =
215 2f * q.X * q.Z * v.X +
216 2f * q.Y * q.Z * v.Y +
217 q.Z * q.Z * v.Z -
218 2f * q.W * q.Y * v.X -
219 q.Y * q.Y * v.Z +
220 2f * q.W * q.X * v.Y -
221 q.X * q.X * v.Z +
222 q.W * q.W * v.Z;
223
224 return c2;
225 }
226 }
227
228 public struct Face
229 {
230 public int primFace;
231
232 // vertices
233 public int v1;
234 public int v2;
235 public int v3;
236
237 public Face(int v1, int v2, int v3)
238 {
239 primFace = 0;
240
241 this.v1 = v1;
242 this.v2 = v2;
243 this.v3 = v3;
244 }
245
246 public Coord SurfaceNormal(List<Coord> coordList)
247 {
248 Coord c1 = coordList[this.v1];
249 Coord c2 = coordList[this.v2];
250 Coord c3 = coordList[this.v3];
251
252 Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z);
253 Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z);
254
255 return Coord.Cross(edge1, edge2).Normalize();
256 }
257 }
258
259 internal struct Angle
260 {
261 internal float angle;
262 internal float X;
263 internal float Y;
264
265 internal Angle(float angle, float x, float y)
266 {
267 this.angle = angle;
268 this.X = x;
269 this.Y = y;
270 }
271 }
272
273 internal class AngleList
274 {
275 private float iX, iY; // intersection point
276
277 private static Angle[] angles3 =
278 {
279 new Angle(0.0f, 1.0f, 0.0f),
280 new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f),
281 new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f),
282 new Angle(1.0f, 1.0f, 0.0f)
283 };
284
285 private static Angle[] angles4 =
286 {
287 new Angle(0.0f, 1.0f, 0.0f),
288 new Angle(0.25f, 0.0f, 1.0f),
289 new Angle(0.5f, -1.0f, 0.0f),
290 new Angle(0.75f, 0.0f, -1.0f),
291 new Angle(1.0f, 1.0f, 0.0f)
292 };
293
294 private static Angle[] angles6 =
295 {
296 new Angle(0.0f, 1.0f, 0.0f),
297 new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f),
298 new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f),
299 new Angle(0.5f, -1.0f, 0.0f),
300 new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f),
301 new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f),
302 new Angle(1.0f, 1.0f, 0.0f)
303 };
304
305 private static Angle[] angles12 =
306 {
307 new Angle(0.0f, 1.0f, 0.0f),
308 new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f),
309 new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f),
310 new Angle(0.25f, 0.0f, 1.0f),
311 new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f),
312 new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f),
313 new Angle(0.5f, -1.0f, 0.0f),
314 new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f),
315 new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f),
316 new Angle(0.75f, 0.0f, -1.0f),
317 new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f),
318 new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f),
319 new Angle(1.0f, 1.0f, 0.0f)
320 };
321
322 private static Angle[] angles24 =
323 {
324 new Angle(0.0f, 1.0f, 0.0f),
325 new Angle(0.041666666666666664f, 0.96592582628906831f, 0.25881904510252074f),
326 new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f),
327 new Angle(0.125f, 0.70710678118654757f, 0.70710678118654746f),
328 new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f),
329 new Angle(0.20833333333333331f, 0.25881904510252096f, 0.9659258262890682f),
330 new Angle(0.25f, 0.0f, 1.0f),
331 new Angle(0.29166666666666663f, -0.25881904510252063f, 0.96592582628906831f),
332 new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f),
333 new Angle(0.375f, -0.70710678118654746f, 0.70710678118654757f),
334 new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f),
335 new Angle(0.45833333333333331f, -0.9659258262890682f, 0.25881904510252102f),
336 new Angle(0.5f, -1.0f, 0.0f),
337 new Angle(0.54166666666666663f, -0.96592582628906842f, -0.25881904510252035f),
338 new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f),
339 new Angle(0.62499999999999989f, -0.70710678118654791f, -0.70710678118654713f),
340 new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f),
341 new Angle(0.70833333333333326f, -0.25881904510252152f, -0.96592582628906809f),
342 new Angle(0.75f, 0.0f, -1.0f),
343 new Angle(0.79166666666666663f, 0.2588190451025203f, -0.96592582628906842f),
344 new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f),
345 new Angle(0.875f, 0.70710678118654735f, -0.70710678118654768f),
346 new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f),
347 new Angle(0.95833333333333326f, 0.96592582628906809f, -0.25881904510252157f),
348 new Angle(1.0f, 1.0f, 0.0f)
349 };
350
351 private Angle interpolatePoints(float newPoint, Angle p1, Angle p2)
352 {
353 float m = (newPoint - p1.angle) / (p2.angle - p1.angle);
354 return new Angle(newPoint, p1.X + m * (p2.X - p1.X), p1.Y + m * (p2.Y - p1.Y));
355 }
356
357 private void intersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
358 { // ref: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/
359 double denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
360 double uaNumerator = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
361
362 if (denom != 0.0)
363 {
364 double ua = uaNumerator / denom;
365 iX = (float)(x1 + ua * (x2 - x1));
366 iY = (float)(y1 + ua * (y2 - y1));
367 }
368 }
369
370 internal List<Angle> angles;
371
372 internal void makeAngles(int sides, float startAngle, float stopAngle, bool hasCut)
373 {
374 angles = new List<Angle>();
375
376 const double twoPi = System.Math.PI * 2.0;
377 const float twoPiInv = (float)(1.0d / twoPi);
378
379 if (sides < 1)
380 throw new Exception("number of sides not greater than zero");
381 if (stopAngle <= startAngle)
382 throw new Exception("stopAngle not greater than startAngle");
383
384 if ((sides == 3 || sides == 4 || sides == 6 || sides == 12 || sides == 24))
385 {
386 startAngle *= twoPiInv;
387 stopAngle *= twoPiInv;
388
389 Angle[] sourceAngles;
390 switch (sides)
391 {
392 case 3:
393 sourceAngles = angles3;
394 break;
395 case 4:
396 sourceAngles = angles4;
397 break;
398 case 6:
399 sourceAngles = angles6;
400 break;
401 case 12:
402 sourceAngles = angles12;
403 break;
404 default:
405 sourceAngles = angles24;
406 break;
407 }
408
409 int startAngleIndex = (int)(startAngle * sides);
410 int endAngleIndex = sourceAngles.Length - 1;
411
412 if (hasCut)
413 {
414 if (stopAngle < 1.0f)
415 endAngleIndex = (int)(stopAngle * sides) + 1;
416 if (endAngleIndex == startAngleIndex)
417 endAngleIndex++;
418
419 for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++)
420 {
421 angles.Add(sourceAngles[angleIndex]);
422 }
423
424 if (startAngle > 0.0f)
425 angles[0] = interpolatePoints(startAngle, angles[0], angles[1]);
426
427 if (stopAngle < 1.0f)
428 {
429 int lastAngleIndex = angles.Count - 1;
430 angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]);
431 }
432 }
433 else
434 {
435 for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex; angleIndex++)
436 angles.Add(sourceAngles[angleIndex]);
437 }
438 }
439 else
440 {
441 double stepSize = twoPi / sides;
442
443 int startStep = (int)(startAngle / stepSize);
444 double angle = stepSize * startStep;
445 int step = startStep;
446 double stopAngleTest = stopAngle;
447 if (stopAngle < twoPi)
448 {
449 stopAngleTest = stepSize * ((int)(stopAngle / stepSize) + 1);
450 if (stopAngleTest < stopAngle)
451 stopAngleTest += stepSize;
452 if (stopAngleTest > twoPi)
453 stopAngleTest = twoPi;
454 }
455
456 while (angle <= stopAngleTest)
457 {
458 Angle newAngle;
459 newAngle.angle = (float)angle;
460 newAngle.X = (float)System.Math.Cos(angle);
461 newAngle.Y = (float)System.Math.Sin(angle);
462 angles.Add(newAngle);
463 step += 1;
464 angle = stepSize * step;
465 }
466
467 if (startAngle > angles[0].angle)
468 {
469 Angle newAngle;
470 intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, 0.0f, 0.0f, (float)Math.Cos(startAngle), (float)Math.Sin(startAngle));
471 newAngle.angle = startAngle;
472 newAngle.X = iX;
473 newAngle.Y = iY;
474 angles[0] = newAngle;
475 }
476
477 int index = angles.Count - 1;
478 if (stopAngle < angles[index].angle)
479 {
480 Angle newAngle;
481 intersection(angles[index - 1].X, angles[index - 1].Y, angles[index].X, angles[index].Y, 0.0f, 0.0f, (float)Math.Cos(stopAngle), (float)Math.Sin(stopAngle));
482 newAngle.angle = stopAngle;
483 newAngle.X = iX;
484 newAngle.Y = iY;
485 angles[index] = newAngle;
486 }
487 }
488 }
489 }
490
491 /// <summary>
492 /// generates a profile for extrusion
493 /// </summary>
494 public class Profile
495 {
496 private const float twoPi = 2.0f * (float)Math.PI;
497
498 public string errorMessage = null;
499
500 public List<Coord> coords;
501 public List<Face> faces;
502
503 // use these for making individual meshes for each prim face
504 public List<int> outerCoordIndices = null;
505 public List<int> hollowCoordIndices = null;
506
507 public int numOuterVerts = 0;
508 public int numHollowVerts = 0;
509
510 public int outerFaceNumber = -1;
511 public int hollowFaceNumber = -1;
512
513 public int bottomFaceNumber = 0;
514 public int numPrimFaces = 0;
515
516 public Profile()
517 {
518 coords = new List<Coord>();
519 faces = new List<Face>();
520 }
521
522 public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool hasProfileCut, bool createFaces)
523 {
524 const float halfSqr2 = 0.7071067811866f;
525
526 coords = new List<Coord>();
527 faces = new List<Face>();
528
529 List<Coord> hollowCoords = new List<Coord>();
530
531 bool hasHollow = (hollow > 0.0f);
532
533 AngleList angles = new AngleList();
534 AngleList hollowAngles = new AngleList();
535
536 float xScale = 0.5f;
537 float yScale = 0.5f;
538 if (sides == 4) // corners of a square are sqrt(2) from center
539 {
540 xScale = halfSqr2;
541 yScale = halfSqr2;
542 }
543
544 float startAngle = profileStart * twoPi;
545 float stopAngle = profileEnd * twoPi;
546
547 try { angles.makeAngles(sides, startAngle, stopAngle,hasProfileCut); }
548 catch (Exception ex)
549 {
550
551 errorMessage = "makeAngles failed: Exception: " + ex.ToString()
552 + "\nsides: " + sides.ToString() + " startAngle: " + startAngle.ToString() + " stopAngle: " + stopAngle.ToString();
553
554 return;
555 }
556
557 numOuterVerts = angles.angles.Count;
558
559 Angle angle;
560 Coord newVert = new Coord();
561
562 // flag to create as few triangles as possible for 3 or 4 side profile
563 bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut);
564
565 if (hasHollow)
566 {
567 if (sides == hollowSides)
568 hollowAngles = angles;
569 else
570 {
571 try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle, hasProfileCut); }
572 catch (Exception ex)
573 {
574 errorMessage = "makeAngles failed: Exception: " + ex.ToString()
575 + "\nsides: " + sides.ToString() + " startAngle: " + startAngle.ToString() + " stopAngle: " + stopAngle.ToString();
576
577 return;
578 }
579
580 int numHollowAngles = hollowAngles.angles.Count;
581 for (int i = 0; i < numHollowAngles; i++)
582 {
583 angle = hollowAngles.angles[i];
584 newVert.X = hollow * xScale * angle.X;
585 newVert.Y = hollow * yScale * angle.Y;
586 newVert.Z = 0.0f;
587
588 hollowCoords.Add(newVert);
589 }
590 }
591 numHollowVerts = hollowAngles.angles.Count;
592 }
593 else if (!simpleFace)
594 {
595 Coord center = new Coord(0.0f, 0.0f, 0.0f);
596 this.coords.Add(center);
597 }
598
599 int numAngles = angles.angles.Count;
600 bool hollowsame = (hasHollow && hollowSides == sides);
601
602 for (int i = 0; i < numAngles; i++)
603 {
604 angle = angles.angles[i];
605 newVert.X = angle.X * xScale;
606 newVert.Y = angle.Y * yScale;
607 newVert.Z = 0.0f;
608 coords.Add(newVert);
609 if (hollowsame)
610 {
611 newVert.X *= hollow;
612 newVert.Y *= hollow;
613 hollowCoords.Add(newVert);
614 }
615 }
616
617 if (hasHollow)
618 {
619 hollowCoords.Reverse();
620 coords.AddRange(hollowCoords);
621
622 if (createFaces)
623 {
624 int numTotalVerts = numOuterVerts + numHollowVerts;
625
626 if (numOuterVerts == numHollowVerts)
627 {
628 Face newFace = new Face();
629
630 for (int coordIndex = 0; coordIndex < numOuterVerts - 1; coordIndex++)
631 {
632 newFace.v1 = coordIndex;
633 newFace.v2 = coordIndex + 1;
634 newFace.v3 = numTotalVerts - coordIndex - 1;
635 faces.Add(newFace);
636
637 newFace.v1 = coordIndex + 1;
638 newFace.v2 = numTotalVerts - coordIndex - 2;
639 newFace.v3 = numTotalVerts - coordIndex - 1;
640 faces.Add(newFace);
641 }
642 if (!hasProfileCut)
643 {
644 newFace.v1 = numOuterVerts - 1;
645 newFace.v2 = 0;
646 newFace.v3 = numOuterVerts;
647 faces.Add(newFace);
648
649 newFace.v1 = 0;
650 newFace.v2 = numTotalVerts - 1;
651 newFace.v3 = numOuterVerts;
652 faces.Add(newFace);
653 }
654 }
655 else if (numOuterVerts < numHollowVerts)
656 {
657 Face newFace = new Face();
658 int j = 0; // j is the index for outer vertices
659 int i;
660 int maxJ = numOuterVerts - 1;
661 float curHollowAngle = 0;
662 for (i = 0; i < numHollowVerts; i++) // i is the index for inner vertices
663 {
664 curHollowAngle = hollowAngles.angles[i].angle;
665 if (j < maxJ)
666 {
667 if (angles.angles[j + 1].angle - curHollowAngle < curHollowAngle - angles.angles[j].angle + 0.000001f)
668 {
669 newFace.v1 = numTotalVerts - i - 1;
670 newFace.v2 = j;
671 newFace.v3 = j + 1;
672 faces.Add(newFace);
673 j++;
674 }
675 }
676 else
677 {
678 if (1.0f - curHollowAngle < curHollowAngle - angles.angles[j].angle + 0.000001f)
679 break;
680 }
681
682 newFace.v1 = j;
683 newFace.v2 = numTotalVerts - i - 2;
684 newFace.v3 = numTotalVerts - i - 1;
685
686 faces.Add(newFace);
687 }
688
689 if (!hasProfileCut)
690 {
691 if (i == numHollowVerts)
692 {
693 newFace.v1 = numTotalVerts - numHollowVerts;
694 newFace.v2 = maxJ;
695 newFace.v3 = 0;
696
697 faces.Add(newFace);
698 }
699 else
700 {
701 if (1.0f - curHollowAngle < curHollowAngle - angles.angles[maxJ].angle + 0.000001f)
702 {
703 newFace.v1 = numTotalVerts - i - 1;
704 newFace.v2 = maxJ;
705 newFace.v3 = 0;
706
707 faces.Add(newFace);
708 }
709
710 for (; i < numHollowVerts - 1; i++)
711 {
712 newFace.v1 = 0;
713 newFace.v2 = numTotalVerts - i - 2;
714 newFace.v3 = numTotalVerts - i - 1;
715
716 faces.Add(newFace);
717 }
718 }
719
720 newFace.v1 = 0;
721 newFace.v2 = numTotalVerts - 1;
722 newFace.v3 = numTotalVerts - numHollowVerts;
723 faces.Add(newFace);
724 }
725 }
726 else // numHollowVerts < numOuterVerts
727 {
728 Face newFace = new Face();
729 int j = 0; // j is the index for inner vertices
730 int maxJ = numHollowVerts - 1;
731 for (int i = 0; i < numOuterVerts; i++)
732 {
733 if (j < maxJ)
734 if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f)
735 {
736 newFace.v1 = i;
737 newFace.v2 = numTotalVerts - j - 2;
738 newFace.v3 = numTotalVerts - j - 1;
739
740 faces.Add(newFace);
741 j += 1;
742 }
743
744 newFace.v1 = numTotalVerts - j - 1;
745 newFace.v2 = i;
746 newFace.v3 = i + 1;
747
748 faces.Add(newFace);
749 }
750
751 if (!hasProfileCut)
752 {
753 int i = numOuterVerts - 1;
754
755 if (hollowAngles.angles[0].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[maxJ].angle + 0.000001f)
756 {
757 newFace.v1 = 0;
758 newFace.v2 = numTotalVerts - 1;
759 newFace.v3 = numTotalVerts - maxJ - 1;
760
761 faces.Add(newFace);
762 }
763
764 newFace.v1 = numTotalVerts - maxJ - 1;
765 newFace.v2 = i;
766 newFace.v3 = 0;
767
768 faces.Add(newFace);
769 }
770 }
771 }
772
773 }
774
775 else if (createFaces)
776 {
777 if (simpleFace)
778 {
779 if (sides == 3)
780 faces.Add(new Face(0, 1, 2));
781 else if (sides == 4)
782 {
783 faces.Add(new Face(0, 1, 2));
784 faces.Add(new Face(0, 2, 3));
785 }
786 }
787 else
788 {
789 for (int i = 1; i < numAngles ; i++)
790 {
791 Face newFace = new Face();
792 newFace.v1 = 0;
793 newFace.v2 = i;
794 newFace.v3 = i + 1;
795 faces.Add(newFace);
796 }
797 if (!hasProfileCut)
798 {
799 Face newFace = new Face();
800 newFace.v1 = 0;
801 newFace.v2 = numAngles;
802 newFace.v3 = 1;
803 faces.Add(newFace);
804 }
805 }
806 }
807
808
809 hollowCoords = null;
810 }
811
812
813 public Profile Copy()
814 {
815 return Copy(true);
816 }
817
818 public Profile Copy(bool needFaces)
819 {
820 Profile copy = new Profile();
821
822 copy.coords.AddRange(coords);
823
824 if (needFaces)
825 copy.faces.AddRange(faces);
826
827 copy.numOuterVerts = numOuterVerts;
828 copy.numHollowVerts = numHollowVerts;
829
830 return copy;
831 }
832
833 public void AddPos(Coord v)
834 {
835 this.AddPos(v.X, v.Y, v.Z);
836 }
837
838 public void AddPos(float x, float y, float z)
839 {
840 int i;
841 int numVerts = coords.Count;
842 Coord vert;
843
844 for (i = 0; i < numVerts; i++)
845 {
846 vert = coords[i];
847 vert.X += x;
848 vert.Y += y;
849 vert.Z += z;
850 this.coords[i] = vert;
851 }
852 }
853
854 public void AddRot(Quat q)
855 {
856 int i;
857 int numVerts = coords.Count;
858
859 for (i = 0; i < numVerts; i++)
860 coords[i] *= q;
861 }
862
863 public void Scale(float x, float y)
864 {
865 int i;
866 int numVerts = coords.Count;
867 Coord vert;
868
869 for (i = 0; i < numVerts; i++)
870 {
871 vert = coords[i];
872 vert.X *= x;
873 vert.X = (float)Math.Round(vert.X,5);
874 vert.Y *= y;
875 vert.Y = (float)Math.Round(vert.Y,5);
876 coords[i] = vert;
877 }
878
879 if(x == 0f || y == 0f)
880 faces = new List<Face>();
881 }
882
883 /// <summary>
884 /// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices
885 /// </summary>
886 public void FlipNormals()
887 {
888 int numFaces = faces.Count;
889 if(numFaces == 0)
890 return;
891
892 int i;
893 Face tmpFace;
894 int tmp;
895
896 for (i = 0; i < numFaces; i++)
897 {
898 tmpFace = faces[i];
899 tmp = tmpFace.v3;
900 tmpFace.v3 = tmpFace.v1;
901 tmpFace.v1 = tmp;
902 faces[i] = tmpFace;
903 }
904 }
905
906 public void AddValue2FaceVertexIndices(int num)
907 {
908 int numFaces = faces.Count;
909 if(numFaces == 0)
910 return;
911
912 Face tmpFace;
913
914 for (int i = 0; i < numFaces; i++)
915 {
916 tmpFace = faces[i];
917 tmpFace.v1 += num;
918 tmpFace.v2 += num;
919 tmpFace.v3 += num;
920
921 faces[i] = tmpFace;
922 }
923 }
924
925 public void DumpRaw(String path, String name, String title)
926 {
927 if (path == null)
928 return;
929 String fileName = name + "_" + title + ".raw";
930 String completePath = System.IO.Path.Combine(path, fileName);
931 StreamWriter sw = new StreamWriter(completePath);
932
933 for (int i = 0; i < faces.Count; i++)
934 {
935 string s = coords[faces[i].v1].ToString();
936 s += " " + coords[faces[i].v2].ToString();
937 s += " " + coords[faces[i].v3].ToString();
938
939 sw.WriteLine(s);
940 }
941
942 sw.Close();
943 }
944 }
945
946 public struct PathNode
947 {
948 public Coord position;
949 public Quat rotation;
950 public float xScale;
951 public float yScale;
952 public float percentOfPath;
953 }
954
955 public enum PathType { Linear = 0, Circular = 1, Flexible = 2 }
956
957 public class Path
958 {
959 public List<PathNode> pathNodes = new List<PathNode>();
960
961 public float twistBegin = 0.0f;
962 public float twistEnd = 0.0f;
963 public float topShearX = 0.0f;
964 public float topShearY = 0.0f;
965 public float pathCutBegin = 0.0f;
966 public float pathCutEnd = 1.0f;
967 public float dimpleBegin = 0.0f;
968 public float dimpleEnd = 1.0f;
969 public float skew = 0.0f;
970 public float holeSizeX = 1.0f; // called pathScaleX in pbs
971 public float holeSizeY = 0.25f;
972 public float taperX = 0.0f;
973 public float taperY = 0.0f;
974 public float radius = 0.0f;
975 public float revolutions = 1.0f;
976 public int stepsPerRevolution = 24;
977
978 private const float twoPi = 2.0f * (float)Math.PI;
979
980 public void Create(PathType pathType, int steps)
981 {
982 if (taperX > .9999f)
983 taperX = 1.0f;
984 else if (taperX < -.9999f)
985 taperX = -1.0f;
986 if (taperY > .9999f)
987 taperY = 1.0f;
988 else if (taperY < -.9999f)
989 taperY = -1.0f;
990
991 if (pathType == PathType.Linear || pathType == PathType.Flexible)
992 {
993 int step = 0;
994
995 float length = pathCutEnd - pathCutBegin;
996 float twistTotal = twistEnd - twistBegin;
997 float twistTotalAbs = Math.Abs(twistTotal);
998 if (twistTotalAbs > 0.01f)
999 steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
1000
1001 float start = -0.5f;
1002 float stepSize = length / (float)steps;
1003 float percentOfPathMultiplier = stepSize * 0.999999f;
1004 float xOffset = topShearX * pathCutBegin;
1005 float yOffset = topShearY * pathCutBegin;
1006 float zOffset = start;
1007 float xOffsetStepIncrement = topShearX * length / steps;
1008 float yOffsetStepIncrement = topShearY * length / steps;
1009
1010 float percentOfPath = pathCutBegin;
1011 zOffset += percentOfPath;
1012
1013 // sanity checks
1014
1015 bool done = false;
1016
1017 while (!done)
1018 {
1019 PathNode newNode = new PathNode();
1020
1021 newNode.xScale = 1.0f;
1022 if (taperX > 0.0f)
1023 newNode.xScale -= percentOfPath * taperX;
1024 else if(taperX < 0.0f)
1025 newNode.xScale += (1.0f - percentOfPath) * taperX;
1026
1027 newNode.yScale = 1.0f;
1028 if (taperY > 0.0f)
1029 newNode.yScale -= percentOfPath * taperY;
1030 else if(taperY < 0.0f)
1031 newNode.yScale += (1.0f - percentOfPath) * taperY;
1032
1033 float twist = twistBegin + twistTotal * percentOfPath;
1034
1035 newNode.rotation = new Quat(new Coord(0.0f, 0.0f, 1.0f), twist);
1036 newNode.position = new Coord(xOffset, yOffset, zOffset);
1037 newNode.percentOfPath = percentOfPath;
1038
1039 pathNodes.Add(newNode);
1040
1041 if (step < steps)
1042 {
1043 step += 1;
1044 percentOfPath += percentOfPathMultiplier;
1045 xOffset += xOffsetStepIncrement;
1046 yOffset += yOffsetStepIncrement;
1047 zOffset += stepSize;
1048 if (percentOfPath > pathCutEnd)
1049 done = true;
1050 }
1051 else done = true;
1052 }
1053 } // end of linear path code
1054
1055 else // pathType == Circular
1056 {
1057 float twistTotal = twistEnd - twistBegin;
1058
1059 // if the profile has a lot of twist, add more layers otherwise the layers may overlap
1060 // and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't
1061 // accurately match the viewer
1062 float twistTotalAbs = Math.Abs(twistTotal);
1063 if (twistTotalAbs > 0.01f)
1064 {
1065 if (twistTotalAbs > Math.PI * 1.5f)
1066 steps *= 2;
1067 if (twistTotalAbs > Math.PI * 3.0f)
1068 steps *= 2;
1069 }
1070
1071 float yPathScale = holeSizeY * 0.5f;
1072 float pathLength = pathCutEnd - pathCutBegin;
1073 float totalSkew = skew * 2.0f * pathLength;
1074 float skewStart = pathCutBegin * 2.0f * skew - skew;
1075 float xOffsetTopShearXFactor = topShearX * (0.25f + 0.5f * (0.5f - holeSizeY));
1076 float yShearCompensation = 1.0f + Math.Abs(topShearY) * 0.25f;
1077
1078 // It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end
1079 // angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used
1080 // to calculate the sine for generating the path radius appears to approximate it's effects there
1081 // too, but there are some subtle differences in the radius which are noticeable as the prim size
1082 // increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on
1083 // the meshes generated with this technique appear nearly identical in shape to the same prims when
1084 // displayed by the viewer.
1085
1086 float startAngle = (twoPi * pathCutBegin * revolutions) - topShearY * 0.9f;
1087 float endAngle = (twoPi * pathCutEnd * revolutions) - topShearY * 0.9f;
1088 float stepSize = twoPi / stepsPerRevolution;
1089
1090 int step = (int)(startAngle / stepSize);
1091 float angle = startAngle;
1092
1093 bool done = false;
1094 while (!done) // loop through the length of the path and add the layers
1095 {
1096 PathNode newNode = new PathNode();
1097
1098 float xProfileScale = (1.0f - Math.Abs(skew)) * holeSizeX;
1099 float yProfileScale = holeSizeY;
1100
1101 float percentOfPath = angle / (twoPi * revolutions);
1102 float percentOfAngles = (angle - startAngle) / (endAngle - startAngle);
1103
1104 if (taperX > 0.01f)
1105 xProfileScale *= 1.0f - percentOfPath * taperX;
1106 else if (taperX < -0.01f)
1107 xProfileScale *= 1.0f + (1.0f - percentOfPath) * taperX;
1108
1109 if (taperY > 0.01f)
1110 yProfileScale *= 1.0f - percentOfPath * taperY;
1111 else if (taperY < -0.01f)
1112 yProfileScale *= 1.0f + (1.0f - percentOfPath) * taperY;
1113
1114 newNode.xScale = xProfileScale;
1115 newNode.yScale = yProfileScale;
1116
1117 float radiusScale = 1.0f;
1118 if (radius > 0.001f)
1119 radiusScale = 1.0f - radius * percentOfPath;
1120 else if (radius < 0.001f)
1121 radiusScale = 1.0f + radius * (1.0f - percentOfPath);
1122
1123 float twist = twistBegin + twistTotal * percentOfPath;
1124
1125 float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles);
1126 xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor;
1127
1128 float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale;
1129
1130 float zOffset = (float)Math.Sin(angle + topShearY) * (0.5f - yPathScale) * radiusScale;
1131
1132 newNode.position = new Coord(xOffset, yOffset, zOffset);
1133
1134 // now orient the rotation of the profile layer relative to it's position on the path
1135 // adding taperY to the angle used to generate the quat appears to approximate the viewer
1136
1137 newNode.rotation = new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + topShearY);
1138
1139 // next apply twist rotation to the profile layer
1140 if (twistTotal != 0.0f || twistBegin != 0.0f)
1141 newNode.rotation *= new Quat(new Coord(0.0f, 0.0f, 1.0f), twist);
1142
1143 newNode.percentOfPath = percentOfPath;
1144
1145 pathNodes.Add(newNode);
1146
1147 // calculate terms for next iteration
1148 // calculate the angle for the next iteration of the loop
1149
1150 if (angle >= endAngle - 0.01)
1151 done = true;
1152 else
1153 {
1154 step += 1;
1155 angle = stepSize * step;
1156 if (angle > endAngle)
1157 angle = endAngle;
1158 }
1159 }
1160 }
1161 }
1162 }
1163
1164 public class PrimMesh
1165 {
1166 public string errorMessage = "";
1167 private const float twoPi = 2.0f * (float)Math.PI;
1168
1169 public List<Coord> coords;
1170// public List<Coord> normals;
1171 public List<Face> faces;
1172
1173 private int sides = 4;
1174 private int hollowSides = 4;
1175 private float profileStart = 0.0f;
1176 private float profileEnd = 1.0f;
1177 private float hollow = 0.0f;
1178 public int twistBegin = 0;
1179 public int twistEnd = 0;
1180 public float topShearX = 0.0f;
1181 public float topShearY = 0.0f;
1182 public float pathCutBegin = 0.0f;
1183 public float pathCutEnd = 1.0f;
1184 public float dimpleBegin = 0.0f;
1185 public float dimpleEnd = 1.0f;
1186 public float skew = 0.0f;
1187 public float holeSizeX = 1.0f; // called pathScaleX in pbs
1188 public float holeSizeY = 0.25f;
1189 public float taperX = 0.0f;
1190 public float taperY = 0.0f;
1191 public float radius = 0.0f;
1192 public float revolutions = 1.0f;
1193 public int stepsPerRevolution = 24;
1194
1195 private bool hasProfileCut = false;
1196 private bool hasHollow = false;
1197
1198 public int numPrimFaces = 0;
1199
1200 /// <summary>
1201 /// Human readable string representation of the parameters used to create a mesh.
1202 /// </summary>
1203 /// <returns></returns>
1204 public string ParamsToDisplayString()
1205 {
1206 string s = "";
1207 s += "sides..................: " + this.sides.ToString();
1208 s += "\nhollowSides..........: " + this.hollowSides.ToString();
1209 s += "\nprofileStart.........: " + this.profileStart.ToString();
1210 s += "\nprofileEnd...........: " + this.profileEnd.ToString();
1211 s += "\nhollow...............: " + this.hollow.ToString();
1212 s += "\ntwistBegin...........: " + this.twistBegin.ToString();
1213 s += "\ntwistEnd.............: " + this.twistEnd.ToString();
1214 s += "\ntopShearX............: " + this.topShearX.ToString();
1215 s += "\ntopShearY............: " + this.topShearY.ToString();
1216 s += "\npathCutBegin.........: " + this.pathCutBegin.ToString();
1217 s += "\npathCutEnd...........: " + this.pathCutEnd.ToString();
1218 s += "\ndimpleBegin..........: " + this.dimpleBegin.ToString();
1219 s += "\ndimpleEnd............: " + this.dimpleEnd.ToString();
1220 s += "\nskew.................: " + this.skew.ToString();
1221 s += "\nholeSizeX............: " + this.holeSizeX.ToString();
1222 s += "\nholeSizeY............: " + this.holeSizeY.ToString();
1223 s += "\ntaperX...............: " + this.taperX.ToString();
1224 s += "\ntaperY...............: " + this.taperY.ToString();
1225 s += "\nradius...............: " + this.radius.ToString();
1226 s += "\nrevolutions..........: " + this.revolutions.ToString();
1227 s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString();
1228 s += "\nhasProfileCut........: " + this.hasProfileCut.ToString();
1229 s += "\nhasHollow............: " + this.hasHollow.ToString();
1230
1231 return s;
1232 }
1233
1234 public bool HasProfileCut
1235 {
1236 get { return hasProfileCut; }
1237 set { hasProfileCut = value; }
1238 }
1239
1240 public bool HasHollow
1241 {
1242 get { return hasHollow; }
1243 }
1244
1245
1246 /// <summary>
1247 /// Constructs a PrimMesh object and creates the profile for extrusion.
1248 /// </summary>
1249 /// <param name="sides"></param>
1250 /// <param name="profileStart"></param>
1251 /// <param name="profileEnd"></param>
1252 /// <param name="hollow"></param>
1253 /// <param name="hollowSides"></param>
1254 /// <param name="sphereMode"></param>
1255 public PrimMesh(int _sides, float _profileStart, float _profileEnd, float _hollow, int _hollowSides)
1256 {
1257 coords = new List<Coord>();
1258 faces = new List<Face>();
1259
1260 sides = _sides;
1261 profileStart = _profileStart;
1262 profileEnd = _profileEnd;
1263 hollow = _hollow;
1264 hollowSides = _hollowSides;
1265
1266 if (sides < 3)
1267 sides = 3;
1268 if (hollowSides < 3)
1269 hollowSides = 3;
1270 if (profileStart < 0.0f)
1271 profileStart = 0.0f;
1272 if (profileEnd > 1.0f)
1273 profileEnd = 1.0f;
1274 if (profileEnd < 0.02f)
1275 profileEnd = 0.02f;
1276 if (profileStart >= profileEnd)
1277 profileStart = profileEnd - 0.02f;
1278 if (hollow > 0.99f)
1279 hollow = 0.99f;
1280 if (hollow < 0.0f)
1281 hollow = 0.0f;
1282 }
1283
1284 /// <summary>
1285 /// Extrudes a profile along a path.
1286 /// </summary>
1287 public void Extrude(PathType pathType)
1288 {
1289 bool needEndFaces = false;
1290
1291 coords = new List<Coord>();
1292 faces = new List<Face>();
1293
1294 int steps = 1;
1295
1296 float length = pathCutEnd - pathCutBegin;
1297
1298 hasProfileCut = this.profileEnd - this.profileStart < 0.9999f;
1299
1300 hasHollow = (this.hollow > 0.001f);
1301
1302 float twistBegin = this.twistBegin / 360.0f * twoPi;
1303 float twistEnd = this.twistEnd / 360.0f * twoPi;
1304 float twistTotal = twistEnd - twistBegin;
1305 float twistTotalAbs = Math.Abs(twistTotal);
1306 if (twistTotalAbs > 0.01f)
1307 steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
1308
1309 float hollow = this.hollow;
1310 float initialProfileRot = 0.0f;
1311
1312 if (pathType == PathType.Circular)
1313 {
1314 needEndFaces = false;
1315 if (pathCutBegin != 0.0f || pathCutEnd != 1.0f)
1316 needEndFaces = true;
1317 else if (taperX != 0.0f || taperY != 0.0f)
1318 needEndFaces = true;
1319 else if (skew != 0.0f)
1320 needEndFaces = true;
1321 else if (twistTotal != 0.0f)
1322 needEndFaces = true;
1323 else if (radius != 0.0f)
1324 needEndFaces = true;
1325 }
1326 else needEndFaces = true;
1327
1328 if (pathType == PathType.Circular)
1329 {
1330 if (sides == 3)
1331 {
1332 initialProfileRot = (float)Math.PI;
1333 if (hollowSides == 4)
1334 {
1335 if (hollow > 0.7f)
1336 hollow = 0.7f;
1337 hollow *= 0.707f;
1338 }
1339 else hollow *= 0.5f;
1340 }
1341 else if (sides == 4)
1342 {
1343 initialProfileRot = 0.25f * (float)Math.PI;
1344 if (hollowSides != 4)
1345 hollow *= 0.707f;
1346 }
1347 else if (sides > 4)
1348 {
1349 initialProfileRot = (float)Math.PI;
1350 if (hollowSides == 4)
1351 {
1352 if (hollow > 0.7f)
1353 hollow = 0.7f;
1354 hollow /= 0.7f;
1355 }
1356 }
1357 }
1358 else
1359 {
1360 if (sides == 3)
1361 {
1362 if (hollowSides == 4)
1363 {
1364 if (hollow > 0.7f)
1365 hollow = 0.7f;
1366 hollow *= 0.707f;
1367 }
1368 else hollow *= 0.5f;
1369 }
1370 else if (sides == 4)
1371 {
1372 initialProfileRot = 1.25f * (float)Math.PI;
1373 if (hollowSides != 4)
1374 hollow *= 0.707f;
1375 }
1376 else if (sides == 24 && hollowSides == 4)
1377 hollow *= 1.414f;
1378 }
1379
1380 Profile profile = new Profile(sides, profileStart, profileEnd, hollow, hollowSides,
1381 HasProfileCut,true);
1382 errorMessage = profile.errorMessage;
1383
1384 numPrimFaces = profile.numPrimFaces;
1385
1386 if (initialProfileRot != 0.0f)
1387 {
1388 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
1389 }
1390
1391 Path path = new Path();
1392 path.twistBegin = twistBegin;
1393 path.twistEnd = twistEnd;
1394 path.topShearX = topShearX;
1395 path.topShearY = topShearY;
1396 path.pathCutBegin = pathCutBegin;
1397 path.pathCutEnd = pathCutEnd;
1398 path.dimpleBegin = dimpleBegin;
1399 path.dimpleEnd = dimpleEnd;
1400 path.skew = skew;
1401 path.holeSizeX = holeSizeX;
1402 path.holeSizeY = holeSizeY;
1403 path.taperX = taperX;
1404 path.taperY = taperY;
1405 path.radius = radius;
1406 path.revolutions = revolutions;
1407 path.stepsPerRevolution = stepsPerRevolution;
1408
1409 path.Create(pathType, steps);
1410
1411 int lastNode = path.pathNodes.Count - 1;
1412
1413 for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++)
1414 {
1415 PathNode node = path.pathNodes[nodeIndex];
1416 Profile newLayer = profile.Copy();
1417
1418 newLayer.Scale(node.xScale, node.yScale);
1419 newLayer.AddRot(node.rotation);
1420 newLayer.AddPos(node.position);
1421
1422 // append this layer
1423 int coordsStart = coords.Count;
1424 coords.AddRange(newLayer.coords);
1425
1426 if (needEndFaces && nodeIndex == 0 && newLayer.faces.Count > 0)
1427 {
1428 newLayer.AddValue2FaceVertexIndices(coordsStart);
1429 newLayer.FlipNormals();
1430 faces.AddRange(newLayer.faces);
1431 }
1432
1433 // fill faces between layers
1434
1435 List<Face> linkfaces = new List<Face>();
1436 int numVerts = newLayer.coords.Count;
1437 Face newFace1 = new Face();
1438 Face newFace2 = new Face();
1439
1440 if (nodeIndex > 0)
1441 {
1442 int startVert = coordsStart;
1443 int endVert = coords.Count;
1444 if (!hasProfileCut)
1445 {
1446 if(numVerts > 5 && !hasHollow)
1447 startVert++;
1448 int i = startVert;
1449 for (int l = 0; l < profile.numOuterVerts - 1; l++)
1450 {
1451 newFace1.v1 = i;
1452 newFace1.v2 = i - numVerts;
1453 newFace1.v3 = i + 1;
1454 linkfaces.Add(newFace1);
1455
1456 newFace2.v1 = i + 1;
1457 newFace2.v2 = i - numVerts;
1458 newFace2.v3 = i + 1 - numVerts;
1459 linkfaces.Add(newFace2);
1460 i++;
1461 }
1462
1463 newFace1.v1 = i;
1464 newFace1.v2 = i - numVerts;
1465 newFace1.v3 = startVert;
1466 linkfaces.Add(newFace1);
1467
1468 newFace2.v1 = startVert;
1469 newFace2.v2 = i - numVerts;
1470 newFace2.v3 = startVert - numVerts;
1471 linkfaces.Add(newFace2);
1472
1473 if (hasHollow)
1474 {
1475 startVert = ++i;
1476 for (int l = 0; l < profile.numHollowVerts - 1; l++)
1477 {
1478 newFace1.v1 = i;
1479 newFace1.v2 = i - numVerts;
1480 newFace1.v3 = i + 1;
1481 linkfaces.Add(newFace1);
1482
1483 newFace2.v1 = i + 1;
1484 newFace2.v2 = i - numVerts;
1485 newFace2.v3 = i + 1 - numVerts;
1486 linkfaces.Add(newFace2);
1487 i++;
1488 }
1489
1490 newFace1.v1 = i;
1491 newFace1.v2 = i - numVerts;
1492 newFace1.v3 = startVert;
1493 linkfaces.Add(newFace1);
1494
1495 newFace2.v1 = startVert;
1496 newFace2.v2 = i - numVerts;
1497 newFace2.v3 = startVert - numVerts;
1498 linkfaces.Add(newFace2);
1499 }
1500 }
1501 else
1502 {
1503 for (int i = startVert; i < endVert; i++)
1504 {
1505 int iNext = i + 1;
1506 if (i == endVert - 1)
1507 iNext = startVert;
1508
1509 newFace1.v1 = i;
1510 newFace1.v2 = i - numVerts;
1511 newFace1.v3 = iNext;
1512 linkfaces.Add(newFace1);
1513
1514 newFace2.v1 = iNext;
1515 newFace2.v2 = i - numVerts;
1516 newFace2.v3 = iNext - numVerts;
1517 linkfaces.Add(newFace2);
1518 }
1519 }
1520 }
1521
1522 if(linkfaces.Count > 0)
1523 faces.AddRange(linkfaces);
1524
1525 if (needEndFaces && nodeIndex == lastNode && newLayer.faces.Count > 0)
1526 {
1527 newLayer.AddValue2FaceVertexIndices(coordsStart);
1528 faces.AddRange(newLayer.faces);
1529 }
1530
1531 } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++)
1532 // more cleanup will be done at Meshmerizer.cs
1533 }
1534
1535
1536 /// <summary>
1537 /// DEPRICATED - use Extrude(PathType.Linear) instead
1538 /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
1539 /// </summary>
1540 ///
1541 public void ExtrudeLinear()
1542 {
1543 Extrude(PathType.Linear);
1544 }
1545
1546
1547 /// <summary>
1548 /// DEPRICATED - use Extrude(PathType.Circular) instead
1549 /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring.
1550 /// </summary>
1551 ///
1552 public void ExtrudeCircular()
1553 {
1554 Extrude(PathType.Circular);
1555 }
1556
1557
1558 private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3)
1559 {
1560 Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z);
1561 Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z);
1562
1563 Coord normal = Coord.Cross(edge1, edge2);
1564
1565 normal.Normalize();
1566
1567 return normal;
1568 }
1569
1570 private Coord SurfaceNormal(Face face)
1571 {
1572 return SurfaceNormal(this.coords[face.v1], this.coords[face.v2], this.coords[face.v3]);
1573 }
1574
1575 /// <summary>
1576 /// Calculate the surface normal for a face in the list of faces
1577 /// </summary>
1578 /// <param name="faceIndex"></param>
1579 /// <returns></returns>
1580 public Coord SurfaceNormal(int faceIndex)
1581 {
1582 int numFaces = this.faces.Count;
1583 if (faceIndex < 0 || faceIndex >= numFaces)
1584 throw new Exception("faceIndex out of range");
1585
1586 return SurfaceNormal(this.faces[faceIndex]);
1587 }
1588
1589 /// <summary>
1590 /// Duplicates a PrimMesh object. All object properties are copied by value, including lists.
1591 /// </summary>
1592 /// <returns></returns>
1593 public PrimMesh Copy()
1594 {
1595 PrimMesh copy = new PrimMesh(this.sides, this.profileStart, this.profileEnd, this.hollow, this.hollowSides);
1596 copy.twistBegin = this.twistBegin;
1597 copy.twistEnd = this.twistEnd;
1598 copy.topShearX = this.topShearX;
1599 copy.topShearY = this.topShearY;
1600 copy.pathCutBegin = this.pathCutBegin;
1601 copy.pathCutEnd = this.pathCutEnd;
1602 copy.dimpleBegin = this.dimpleBegin;
1603 copy.dimpleEnd = this.dimpleEnd;
1604 copy.skew = this.skew;
1605 copy.holeSizeX = this.holeSizeX;
1606 copy.holeSizeY = this.holeSizeY;
1607 copy.taperX = this.taperX;
1608 copy.taperY = this.taperY;
1609 copy.radius = this.radius;
1610 copy.revolutions = this.revolutions;
1611 copy.stepsPerRevolution = this.stepsPerRevolution;
1612
1613 copy.numPrimFaces = this.numPrimFaces;
1614 copy.errorMessage = this.errorMessage;
1615
1616 copy.coords = new List<Coord>(this.coords);
1617 copy.faces = new List<Face>(this.faces);
1618
1619 return copy;
1620 }
1621
1622 /// <summary>
1623 /// Adds a value to each XYZ vertex coordinate in the mesh
1624 /// </summary>
1625 /// <param name="x"></param>
1626 /// <param name="y"></param>
1627 /// <param name="z"></param>
1628 public void AddPos(float x, float y, float z)
1629 {
1630 int i;
1631 int numVerts = this.coords.Count;
1632 Coord vert;
1633
1634 for (i = 0; i < numVerts; i++)
1635 {
1636 vert = this.coords[i];
1637 vert.X += x;
1638 vert.Y += y;
1639 vert.Z += z;
1640 this.coords[i] = vert;
1641 }
1642 }
1643
1644 /// <summary>
1645 /// Rotates the mesh
1646 /// </summary>
1647 /// <param name="q"></param>
1648 public void AddRot(Quat q)
1649 {
1650 int i;
1651 int numVerts = this.coords.Count;
1652
1653 for (i = 0; i < numVerts; i++)
1654 this.coords[i] *= q;
1655 }
1656
1657#if VERTEX_INDEXER
1658 public VertexIndexer GetVertexIndexer()
1659 {
1660 return null;
1661 }
1662#endif
1663
1664 /// <summary>
1665 /// Scales the mesh
1666 /// </summary>
1667 /// <param name="x"></param>
1668 /// <param name="y"></param>
1669 /// <param name="z"></param>
1670 public void Scale(float x, float y, float z)
1671 {
1672 int i;
1673 int numVerts = this.coords.Count;
1674 //Coord vert;
1675
1676 Coord m = new Coord(x, y, z);
1677 for (i = 0; i < numVerts; i++)
1678 this.coords[i] *= m;
1679 }
1680
1681 /// <summary>
1682 /// Dumps the mesh to a Blender compatible "Raw" format file
1683 /// </summary>
1684 /// <param name="path"></param>
1685 /// <param name="name"></param>
1686 /// <param name="title"></param>
1687 public void DumpRaw(String path, String name, String title)
1688 {
1689 if (path == null)
1690 return;
1691 String fileName = name + "_" + title + ".raw";
1692 String completePath = System.IO.Path.Combine(path, fileName);
1693 StreamWriter sw = new StreamWriter(completePath);
1694
1695 for (int i = 0; i < this.faces.Count; i++)
1696 {
1697 string s = this.coords[this.faces[i].v1].ToString();
1698 s += " " + this.coords[this.faces[i].v2].ToString();
1699 s += " " + this.coords[this.faces[i].v3].ToString();
1700
1701 sw.WriteLine(s);
1702 }
1703
1704 sw.Close();
1705 }
1706 }
1707}
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Properties/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6503e35
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4using Mono.Addins;
5
6// General Information about an assembly is controlled through the following
7// set of attributes. Change these attribute values to modify the information
8// associated with an assembly.
9[assembly: AssemblyTitle("OpenSim.Region.PhysicsModule.ubODEMeshing")]
10[assembly: AssemblyDescription("Mesher for ubODE")]
11[assembly: AssemblyConfiguration("")]
12[assembly: AssemblyCompany("http://opensimulator.org")]
13[assembly: AssemblyProduct("OpenSim")]
14[assembly: AssemblyCopyright("OpenSimulator developers")]
15[assembly: AssemblyTrademark("")]
16[assembly: AssemblyCulture("")]
17
18// Setting ComVisible to false makes the types in this assembly not visible
19// to COM components. If you need to access a type in this assembly from
20// COM, set the ComVisible attribute to true on that type.
21[assembly: ComVisible(false)]
22
23// The following GUID is for the ID of the typelib if this project is exposed to COM
24[assembly: Guid("4b7e35c2-a9dd-4b10-b778-eb417f4f6884")]
25
26// Version information for an assembly consists of the following four values:
27//
28// Major Version
29// Minor Version
30// Build Number
31// Revision
32//
33[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
34
35[assembly: Addin("OpenSim.Region.PhysicsModule.ubOdeMeshing", OpenSim.VersionInfo.VersionNumber)]
36[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMap.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMap.cs
new file mode 100644
index 0000000..ebe2523
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMap.cs
@@ -0,0 +1,238 @@
1/*
2 * Copyright (c) Contributors
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.Text;
31
32using System.Drawing;
33using System.Drawing.Imaging;
34
35namespace PrimMesher
36{
37 public class SculptMap
38 {
39 public int width;
40 public int height;
41 public byte[] redBytes;
42 public byte[] greenBytes;
43 public byte[] blueBytes;
44
45 public SculptMap()
46 {
47 }
48
49 public SculptMap(Bitmap bm, int lod)
50 {
51 int bmW = bm.Width;
52 int bmH = bm.Height;
53
54 if (bmW == 0 || bmH == 0)
55 throw new Exception("SculptMap: bitmap has no data");
56
57 int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
58
59 bool needsScaling = false;
60 bool smallMap = false;
61
62 width = bmW;
63 height = bmH;
64
65 while (width * height > numLodPixels * 4)
66 {
67 width >>= 1;
68 height >>= 1;
69 needsScaling = true;
70 }
71
72 if (needsScaling)
73 bm = ScaleImage(bm, width, height);
74
75 if (width * height > numLodPixels)
76 {
77 smallMap = false;
78 width >>= 1;
79 height >>= 1;
80 }
81 else
82 smallMap = true;
83
84 int numBytes = (width + 1) * (height + 1);
85 redBytes = new byte[numBytes];
86 greenBytes = new byte[numBytes];
87 blueBytes = new byte[numBytes];
88
89 int byteNdx = 0;
90 Color c;
91
92 try
93 {
94 for (int y = 0; y <= height; y++)
95 {
96 for (int x = 0; x < width; x++)
97 {
98 if (smallMap)
99 c = bm.GetPixel(x, y < height ? y : y - 1);
100 else
101 c = bm.GetPixel(x * 2, y < height ? y * 2 : y * 2 - 1);
102
103 redBytes[byteNdx] = c.R;
104 greenBytes[byteNdx] = c.G;
105 blueBytes[byteNdx] = c.B;
106
107 ++byteNdx;
108 }
109
110 if (smallMap)
111 c = bm.GetPixel(width - 1, y < height ? y : y - 1);
112 else
113 c = bm.GetPixel(width * 2 - 1, y < height ? y * 2 : y * 2 - 1);
114
115 redBytes[byteNdx] = c.R;
116 greenBytes[byteNdx] = c.G;
117 blueBytes[byteNdx] = c.B;
118
119 ++byteNdx;
120 }
121 }
122 catch (Exception e)
123 {
124 if (needsScaling)
125 bm.Dispose();
126 throw new Exception("Caught exception processing byte arrays in SculptMap(): e: " + e.ToString());
127 }
128
129 width++;
130 height++;
131 if(needsScaling)
132 bm.Dispose();
133 }
134
135 public List<List<Coord>> ToRows(bool mirror)
136 {
137 int numRows = height;
138 int numCols = width;
139
140 List<List<Coord>> rows = new List<List<Coord>>(numRows);
141
142 float pixScale = 1.0f / 255;
143
144 int rowNdx, colNdx;
145 int smNdx = 0;
146
147 for (rowNdx = 0; rowNdx < numRows; rowNdx++)
148 {
149 List<Coord> row = new List<Coord>(numCols);
150 for (colNdx = 0; colNdx < numCols; colNdx++)
151 {
152
153 if (mirror)
154 row.Add(new Coord(-((float)redBytes[smNdx] * pixScale - 0.5f), ((float)greenBytes[smNdx] * pixScale - 0.5f), (float)blueBytes[smNdx] * pixScale - 0.5f));
155 else
156 row.Add(new Coord((float)redBytes[smNdx] * pixScale - 0.5f, (float)greenBytes[smNdx] * pixScale - 0.5f, (float)blueBytes[smNdx] * pixScale - 0.5f));
157
158 ++smNdx;
159 }
160 rows.Add(row);
161 }
162 return rows;
163 }
164
165 private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight)
166 {
167 Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
168
169 Color c;
170
171 // will let last step to be eventually diferent, as seems to be in sl
172
173 float xscale = (float)srcImage.Width / (float)destWidth;
174 float yscale = (float)srcImage.Height / (float)destHeight;
175
176 int lastsx = srcImage.Width - 1;
177 int lastsy = srcImage.Height - 1;
178 int lastdx = destWidth - 1;
179 int lastdy = destHeight - 1;
180
181 float sy = 0.5f;
182 float sx;
183
184 for (int y = 0; y < lastdy; y++)
185 {
186 sx = 0.5f;
187 for (int x = 0; x < lastdx; x++)
188 {
189 try
190 {
191 c = srcImage.GetPixel((int)(sx), (int)(sy));
192 scaledImage.SetPixel(x, y, Color.FromArgb(c.R, c.G, c.B));
193 }
194 catch (IndexOutOfRangeException)
195 {
196 }
197 sx += xscale;
198 }
199 try
200 {
201 c = srcImage.GetPixel(lastsx, (int)(sy));
202 scaledImage.SetPixel(lastdx, y, Color.FromArgb(c.R, c.G, c.B));
203 }
204 catch (IndexOutOfRangeException)
205 {
206 }
207
208 sy += yscale;
209 }
210
211 sx = 0.5f;
212 for (int x = 0; x < lastdx; x++)
213 {
214 try
215 {
216 c = srcImage.GetPixel((int)(sx), lastsy);
217 scaledImage.SetPixel(x, lastdy, Color.FromArgb(c.R, c.G, c.B));
218 }
219 catch (IndexOutOfRangeException)
220 {
221 }
222
223 sx += xscale;
224 }
225 try
226 {
227 c = srcImage.GetPixel(lastsx, lastsy);
228 scaledImage.SetPixel(lastdx, lastdy, Color.FromArgb(c.R, c.G, c.B));
229 }
230 catch (IndexOutOfRangeException)
231 {
232 }
233
234 srcImage.Dispose();
235 return scaledImage;
236 }
237 }
238} \ No newline at end of file
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMesh.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMesh.cs
new file mode 100644
index 0000000..bc1375b
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMesh.cs
@@ -0,0 +1,220 @@
1/*
2 * Copyright (c) Contributors
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.Text;
31using System.IO;
32
33using System.Drawing;
34using System.Drawing.Imaging;
35
36namespace PrimMesher
37{
38
39 public class SculptMesh
40 {
41 public List<Coord> coords;
42 public List<Face> faces;
43
44 public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 };
45
46
47 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool mirror, bool invert)
48 {
49 if (mirror)
50 invert = !invert;
51
52 SculptMap smap = new SculptMap(sculptBitmap, lod);
53
54 List<List<Coord>> rows = smap.ToRows(mirror);
55
56 _SculptMesh(rows, sculptType, invert);
57 }
58
59 private void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool invert)
60 {
61 coords = new List<Coord>();
62 faces = new List<Face>();
63
64 sculptType = (SculptType)(((int)sculptType) & 0x07);
65
66 int width = rows[0].Count;
67
68 int p1, p2, p3, p4;
69
70 int imageX, imageY;
71
72 if (sculptType != SculptType.plane)
73 {
74 if (rows.Count % 2 == 0)
75 {
76 for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++)
77 rows[rowNdx].Add(rows[rowNdx][0]);
78 }
79 else
80 {
81 int lastIndex = rows[0].Count - 1;
82
83 for (int i = 0; i < rows.Count; i++)
84 rows[i][0] = rows[i][lastIndex];
85 }
86 }
87
88 Coord topPole = rows[0][width / 2];
89 Coord bottomPole = rows[rows.Count - 1][width / 2];
90
91 if (sculptType == SculptType.sphere)
92 {
93 if (rows.Count % 2 == 0)
94 {
95 int count = rows[0].Count;
96 List<Coord> topPoleRow = new List<Coord>(count);
97 List<Coord> bottomPoleRow = new List<Coord>(count);
98
99 for (int i = 0; i < count; i++)
100 {
101 topPoleRow.Add(topPole);
102 bottomPoleRow.Add(bottomPole);
103 }
104 rows.Insert(0, topPoleRow);
105 rows.Add(bottomPoleRow);
106 }
107 else
108 {
109 int count = rows[0].Count;
110
111 List<Coord> topPoleRow = rows[0];
112 List<Coord> bottomPoleRow = rows[rows.Count - 1];
113
114 for (int i = 0; i < count; i++)
115 {
116 topPoleRow[i] = topPole;
117 bottomPoleRow[i] = bottomPole;
118 }
119 }
120 }
121
122 if (sculptType == SculptType.torus)
123 rows.Add(rows[0]);
124
125 int coordsDown = rows.Count;
126 int coordsAcross = rows[0].Count;
127
128 float widthUnit = 1.0f / (coordsAcross - 1);
129 float heightUnit = 1.0f / (coordsDown - 1);
130
131 for (imageY = 0; imageY < coordsDown; imageY++)
132 {
133 int rowOffset = imageY * coordsAcross;
134
135 for (imageX = 0; imageX < coordsAcross; imageX++)
136 {
137 /*
138 * p1-----p2
139 * | \ f2 |
140 * | \ |
141 * | f1 \|
142 * p3-----p4
143 */
144
145 p4 = rowOffset + imageX;
146 p3 = p4 - 1;
147
148 p2 = p4 - coordsAcross;
149 p1 = p3 - coordsAcross;
150
151 this.coords.Add(rows[imageY][imageX]);
152
153 if (imageY > 0 && imageX > 0)
154 {
155 Face f1, f2;
156
157 if (invert)
158 {
159 f1 = new Face(p1, p4, p3);
160 f2 = new Face(p1, p2, p4);
161 }
162 else
163 {
164 f1 = new Face(p1, p3, p4);
165 f2 = new Face(p1, p4, p2);
166 }
167
168 this.faces.Add(f1);
169 this.faces.Add(f2);
170 }
171 }
172 }
173 }
174
175 /// <summary>
176 /// Duplicates a SculptMesh object. All object properties are copied by value, including lists.
177 /// </summary>
178 /// <returns></returns>
179 public SculptMesh Copy()
180 {
181 return new SculptMesh(this);
182 }
183
184 public SculptMesh(SculptMesh sm)
185 {
186 coords = new List<Coord>(sm.coords);
187 faces = new List<Face>(sm.faces);
188 }
189
190 public void Scale(float x, float y, float z)
191 {
192 int i;
193 int numVerts = this.coords.Count;
194
195 Coord m = new Coord(x, y, z);
196 for (i = 0; i < numVerts; i++)
197 this.coords[i] *= m;
198 }
199
200 public void DumpRaw(String path, String name, String title)
201 {
202 if (path == null)
203 return;
204 String fileName = name + "_" + title + ".raw";
205 String completePath = System.IO.Path.Combine(path, fileName);
206 StreamWriter sw = new StreamWriter(completePath);
207
208 for (int i = 0; i < this.faces.Count; i++)
209 {
210 string s = this.coords[this.faces[i].v1].ToString();
211 s += " " + this.coords[this.faces[i].v2].ToString();
212 s += " " + this.coords[this.faces[i].v3].ToString();
213
214 sw.WriteLine(s);
215 }
216
217 sw.Close();
218 }
219 }
220}