diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs | 467 |
1 files changed, 183 insertions, 284 deletions
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs index 004ee7f..0003085 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs | |||
@@ -34,15 +34,10 @@ using System.Linq; | |||
34 | using System.Reflection; | 34 | using System.Reflection; |
35 | using System.Runtime.InteropServices; | 35 | using System.Runtime.InteropServices; |
36 | using System.Threading; | 36 | using System.Threading; |
37 | using System.IO; | ||
38 | using System.Diagnostics; | ||
39 | using log4net; | 37 | using log4net; |
40 | using Nini.Config; | 38 | using Nini.Config; |
41 | using Mono.Addins; | ||
42 | using OdeAPI; | ||
43 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
44 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
45 | using OpenSim.Region.Framework.Interfaces; | ||
46 | using OpenSim.Region.PhysicsModules.SharedBase; | 41 | using OpenSim.Region.PhysicsModules.SharedBase; |
47 | using OpenMetaverse; | 42 | using OpenMetaverse; |
48 | 43 | ||
@@ -179,12 +174,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
179 | 174 | ||
180 | // const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; | 175 | // const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; |
181 | 176 | ||
182 | const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; | 177 | // const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; |
178 | const SafeNativeMethods.ContactFlags comumContactFlags = SafeNativeMethods.ContactFlags.Bounce | SafeNativeMethods.ContactFlags.Approx1; | ||
183 | const float comumContactERP = 0.75f; | 179 | const float comumContactERP = 0.75f; |
184 | const float comumContactCFM = 0.0001f; | 180 | const float comumContactCFM = 0.0001f; |
185 | const float comumContactSLIP = 0f; | 181 | const float comumContactSLIP = 0f; |
186 | 182 | ||
187 | float frictionMovementMult = 0.8f; | 183 | // float frictionMovementMult = 0.2f; |
188 | 184 | ||
189 | float TerrainBounce = 0.001f; | 185 | float TerrainBounce = 0.001f; |
190 | float TerrainFriction = 0.3f; | 186 | float TerrainFriction = 0.3f; |
@@ -200,7 +196,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
200 | public float ODE_STEPSIZE = 0.020f; | 196 | public float ODE_STEPSIZE = 0.020f; |
201 | public float HalfOdeStep = 0.01f; | 197 | public float HalfOdeStep = 0.01f; |
202 | public int odetimestepMS = 20; // rounded | 198 | public int odetimestepMS = 20; // rounded |
203 | private float metersInSpace = 25.6f; | ||
204 | private float m_timeDilation = 1.0f; | 199 | private float m_timeDilation = 1.0f; |
205 | 200 | ||
206 | private double m_lastframe; | 201 | private double m_lastframe; |
@@ -228,7 +223,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
228 | 223 | ||
229 | public int bodyFramesAutoDisable = 5; | 224 | public int bodyFramesAutoDisable = 5; |
230 | 225 | ||
231 | private d.NearCallback nearCallback; | 226 | private SafeNativeMethods.NearCallback nearCallback; |
232 | 227 | ||
233 | private Dictionary<uint,OdePrim> _prims = new Dictionary<uint,OdePrim>(); | 228 | private Dictionary<uint,OdePrim> _prims = new Dictionary<uint,OdePrim>(); |
234 | private HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); | 229 | private HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); |
@@ -251,7 +246,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
251 | private int contactsPerCollision = 80; | 246 | private int contactsPerCollision = 80; |
252 | internal IntPtr ContactgeomsArray = IntPtr.Zero; | 247 | internal IntPtr ContactgeomsArray = IntPtr.Zero; |
253 | private IntPtr GlobalContactsArray = IntPtr.Zero; | 248 | private IntPtr GlobalContactsArray = IntPtr.Zero; |
254 | private d.Contact SharedTmpcontact = new d.Contact(); | 249 | private SafeNativeMethods.Contact SharedTmpcontact = new SafeNativeMethods.Contact(); |
255 | 250 | ||
256 | const int maxContactsbeforedeath = 6000; | 251 | const int maxContactsbeforedeath = 6000; |
257 | private volatile int m_global_contactcount = 0; | 252 | private volatile int m_global_contactcount = 0; |
@@ -283,16 +278,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
283 | public IntPtr StaticSpace; // space for the static things around | 278 | public IntPtr StaticSpace; // space for the static things around |
284 | public IntPtr GroundSpace; // space for ground | 279 | public IntPtr GroundSpace; // space for ground |
285 | 280 | ||
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; | 281 | public Object OdeLock; |
297 | public static Object SimulationLock; | 282 | public static Object SimulationLock; |
298 | 283 | ||
@@ -366,7 +351,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
366 | /// </summary> | 351 | /// </summary> |
367 | private void Initialization() | 352 | private void Initialization() |
368 | { | 353 | { |
369 | d.AllocateODEDataForThread(~0U); | 354 | SafeNativeMethods.AllocateODEDataForThread(~0U); |
370 | 355 | ||
371 | SimulationLock = new Object(); | 356 | SimulationLock = new Object(); |
372 | 357 | ||
@@ -384,14 +369,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
384 | // Create the world and the first space | 369 | // Create the world and the first space |
385 | try | 370 | try |
386 | { | 371 | { |
387 | world = d.WorldCreate(); | 372 | world = SafeNativeMethods.WorldCreate(); |
388 | TopSpace = d.HashSpaceCreate(IntPtr.Zero); | 373 | TopSpace = SafeNativeMethods.SimpleSpaceCreate(IntPtr.Zero); |
389 | 374 | ActiveSpace = SafeNativeMethods.SimpleSpaceCreate(TopSpace); | |
390 | // now the major subspaces | 375 | CharsSpace = SafeNativeMethods.SimpleSpaceCreate(TopSpace); |
391 | ActiveSpace = d.HashSpaceCreate(TopSpace); | 376 | GroundSpace = SafeNativeMethods.SimpleSpaceCreate(TopSpace); |
392 | CharsSpace = d.HashSpaceCreate(TopSpace); | 377 | float sx = WorldExtents.X + 16; |
393 | StaticSpace = d.HashSpaceCreate(TopSpace); | 378 | float sy = WorldExtents.Y + 16; |
394 | GroundSpace = d.HashSpaceCreate(TopSpace); | 379 | SafeNativeMethods.Vector3 ex =new SafeNativeMethods.Vector3(sx, sy, 0); |
380 | SafeNativeMethods.Vector3 px =new SafeNativeMethods.Vector3(sx * 0.5f, sx * 0.5f, 0); | ||
381 | if(sx < sy) | ||
382 | sx = sy; | ||
383 | sx = (float)Math.Log(sx) * 1.442695f + 0.5f; | ||
384 | int dp = (int)sx - 2; | ||
385 | if(dp > 8) | ||
386 | dp = 8; | ||
387 | else if(dp < 4) | ||
388 | dp = 4; | ||
389 | StaticSpace = SafeNativeMethods.QuadTreeSpaceCreate(TopSpace, ref px, ref ex, dp); | ||
395 | } | 390 | } |
396 | catch | 391 | catch |
397 | { | 392 | { |
@@ -399,54 +394,48 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
399 | // i did! | 394 | // i did! |
400 | } | 395 | } |
401 | 396 | ||
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 | 397 | // demote to second level |
409 | d.SpaceSetSublevel(ActiveSpace, 1); | 398 | SafeNativeMethods.SpaceSetSublevel(ActiveSpace, 1); |
410 | d.SpaceSetSublevel(CharsSpace, 1); | 399 | SafeNativeMethods.SpaceSetSublevel(CharsSpace, 1); |
411 | d.SpaceSetSublevel(StaticSpace, 1); | 400 | SafeNativeMethods.SpaceSetSublevel(StaticSpace, 1); |
412 | d.SpaceSetSublevel(GroundSpace, 1); | 401 | SafeNativeMethods.SpaceSetSublevel(GroundSpace, 1); |
413 | 402 | ||
414 | d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | | 403 | SafeNativeMethods.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | |
415 | CollisionCategories.Geom | | 404 | CollisionCategories.Geom | |
416 | CollisionCategories.Character | | 405 | CollisionCategories.Character | |
417 | CollisionCategories.Phantom | | 406 | CollisionCategories.Phantom | |
418 | CollisionCategories.VolumeDtc | 407 | CollisionCategories.VolumeDtc |
419 | )); | 408 | )); |
420 | d.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space | | 409 | SafeNativeMethods.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space | |
421 | CollisionCategories.Geom | | 410 | CollisionCategories.Geom | |
422 | CollisionCategories.Character | | 411 | CollisionCategories.Character | |
423 | CollisionCategories.Phantom | | 412 | CollisionCategories.Phantom | |
424 | CollisionCategories.VolumeDtc | 413 | CollisionCategories.VolumeDtc |
425 | )); | 414 | )); |
426 | d.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space | | 415 | SafeNativeMethods.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space | |
427 | CollisionCategories.Geom | | 416 | CollisionCategories.Geom | |
428 | CollisionCategories.Character | | 417 | CollisionCategories.Character | |
429 | CollisionCategories.Phantom | | 418 | CollisionCategories.Phantom | |
430 | CollisionCategories.VolumeDtc | 419 | CollisionCategories.VolumeDtc |
431 | )); | 420 | )); |
432 | d.GeomSetCollideBits(CharsSpace, 0); | 421 | SafeNativeMethods.GeomSetCollideBits(CharsSpace, 0); |
433 | 422 | ||
434 | d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space | | 423 | SafeNativeMethods.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space | |
435 | CollisionCategories.Geom | | 424 | CollisionCategories.Geom | |
436 | // CollisionCategories.Land | | 425 | // CollisionCategories.Land | |
437 | // CollisionCategories.Water | | 426 | // CollisionCategories.Water | |
438 | CollisionCategories.Phantom | | 427 | CollisionCategories.Phantom | |
439 | CollisionCategories.VolumeDtc | 428 | CollisionCategories.VolumeDtc |
440 | )); | 429 | )); |
441 | d.GeomSetCollideBits(StaticSpace, 0); | 430 | SafeNativeMethods.GeomSetCollideBits(StaticSpace, 0); |
442 | 431 | ||
443 | d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land)); | 432 | SafeNativeMethods.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land)); |
444 | d.GeomSetCollideBits(GroundSpace, 0); | 433 | SafeNativeMethods.GeomSetCollideBits(GroundSpace, 0); |
445 | 434 | ||
446 | contactgroup = d.JointGroupCreate(maxContactsbeforedeath + 1); | 435 | contactgroup = SafeNativeMethods.JointGroupCreate(maxContactsbeforedeath + 1); |
447 | //contactgroup | 436 | //contactgroup |
448 | 437 | ||
449 | d.WorldSetAutoDisableFlag(world, false); | 438 | SafeNativeMethods.WorldSetAutoDisableFlag(world, false); |
450 | } | 439 | } |
451 | 440 | ||
452 | 441 | ||
@@ -468,8 +457,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
468 | gravityy = physicsconfig.GetFloat("world_gravityy", gravityy); | 457 | gravityy = physicsconfig.GetFloat("world_gravityy", gravityy); |
469 | gravityz = physicsconfig.GetFloat("world_gravityz", gravityz); | 458 | gravityz = physicsconfig.GetFloat("world_gravityz", gravityz); |
470 | 459 | ||
471 | metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace); | ||
472 | |||
473 | // contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); | 460 | // contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); |
474 | 461 | ||
475 | ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); | 462 | ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); |
@@ -498,27 +485,27 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
498 | maximumAngularVelocity = 0.49f * heartbeat *(float)Math.PI; | 485 | maximumAngularVelocity = 0.49f * heartbeat *(float)Math.PI; |
499 | maxAngVelocitySQ = maximumAngularVelocity * maximumAngularVelocity; | 486 | maxAngVelocitySQ = maximumAngularVelocity * maximumAngularVelocity; |
500 | 487 | ||
501 | d.WorldSetCFM(world, comumContactCFM); | 488 | SafeNativeMethods.WorldSetCFM(world, comumContactCFM); |
502 | d.WorldSetERP(world, comumContactERP); | 489 | SafeNativeMethods.WorldSetERP(world, comumContactERP); |
503 | 490 | ||
504 | d.WorldSetGravity(world, gravityx, gravityy, gravityz); | 491 | SafeNativeMethods.WorldSetGravity(world, gravityx, gravityy, gravityz); |
505 | 492 | ||
506 | d.WorldSetLinearDamping(world, 0.001f); | 493 | SafeNativeMethods.WorldSetLinearDamping(world, 0.001f); |
507 | d.WorldSetAngularDamping(world, 0.002f); | 494 | SafeNativeMethods.WorldSetAngularDamping(world, 0.002f); |
508 | d.WorldSetAngularDampingThreshold(world, 0f); | 495 | SafeNativeMethods.WorldSetAngularDampingThreshold(world, 0f); |
509 | d.WorldSetLinearDampingThreshold(world, 0f); | 496 | SafeNativeMethods.WorldSetLinearDampingThreshold(world, 0f); |
510 | d.WorldSetMaxAngularSpeed(world, maximumAngularVelocity); | 497 | SafeNativeMethods.WorldSetMaxAngularSpeed(world, maximumAngularVelocity); |
511 | 498 | ||
512 | d.WorldSetQuickStepNumIterations(world, m_physicsiterations); | 499 | SafeNativeMethods.WorldSetQuickStepNumIterations(world, m_physicsiterations); |
513 | 500 | ||
514 | d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); | 501 | SafeNativeMethods.WorldSetContactSurfaceLayer(world, contactsurfacelayer); |
515 | d.WorldSetContactMaxCorrectingVel(world, 60.0f); | 502 | SafeNativeMethods.WorldSetContactMaxCorrectingVel(world, 60.0f); |
516 | 503 | ||
517 | HalfOdeStep = ODE_STEPSIZE * 0.5f; | 504 | HalfOdeStep = ODE_STEPSIZE * 0.5f; |
518 | odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f); | 505 | odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f); |
519 | 506 | ||
520 | ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); | 507 | ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * SafeNativeMethods.ContactGeom.unmanagedSizeOf); |
521 | GlobalContactsArray = Marshal.AllocHGlobal((maxContactsbeforedeath + 100) * d.Contact.unmanagedSizeOf); | 508 | GlobalContactsArray = Marshal.AllocHGlobal((maxContactsbeforedeath + 100) * SafeNativeMethods.Contact.unmanagedSizeOf); |
522 | 509 | ||
523 | SharedTmpcontact.geom.g1 = IntPtr.Zero; | 510 | SharedTmpcontact.geom.g1 = IntPtr.Zero; |
524 | SharedTmpcontact.geom.g2 = IntPtr.Zero; | 511 | SharedTmpcontact.geom.g2 = IntPtr.Zero; |
@@ -559,76 +546,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
559 | m_materialContactsData[(int)Material.light].mu = 0.0f; | 546 | m_materialContactsData[(int)Material.light].mu = 0.0f; |
560 | m_materialContactsData[(int)Material.light].bounce = 0.0f; | 547 | m_materialContactsData[(int)Material.light].bounce = 0.0f; |
561 | 548 | ||
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(); | 549 | m_lastframe = Util.GetTimeStamp(); |
633 | m_lastMeshExpire = m_lastframe; | 550 | m_lastMeshExpire = m_lastframe; |
634 | step_time = -1; | 551 | step_time = -1; |
@@ -643,7 +560,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
643 | #region Collision Detection | 560 | #region Collision Detection |
644 | 561 | ||
645 | // sets a global contact for a joint for contactgeom , and base contact description) | 562 | // sets a global contact for a joint for contactgeom , and base contact description) |
646 | private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom,bool smooth) | 563 | private IntPtr CreateContacJoint(ref SafeNativeMethods.ContactGeom contactGeom,bool smooth) |
647 | { | 564 | { |
648 | if (m_global_contactcount >= maxContactsbeforedeath) | 565 | if (m_global_contactcount >= maxContactsbeforedeath) |
649 | return IntPtr.Zero; | 566 | return IntPtr.Zero; |
@@ -656,18 +573,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
656 | SharedTmpcontact.geom.pos = contactGeom.pos; | 573 | SharedTmpcontact.geom.pos = contactGeom.pos; |
657 | SharedTmpcontact.geom.normal = contactGeom.normal; | 574 | SharedTmpcontact.geom.normal = contactGeom.normal; |
658 | 575 | ||
659 | IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf)); | 576 | IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * SafeNativeMethods.Contact.unmanagedSizeOf)); |
660 | Marshal.StructureToPtr(SharedTmpcontact, contact, true); | 577 | Marshal.StructureToPtr(SharedTmpcontact, contact, true); |
661 | return d.JointCreateContactPtr(world, contactgroup, contact); | 578 | return SafeNativeMethods.JointCreateContactPtr(world, contactgroup, contact); |
662 | } | 579 | } |
663 | 580 | ||
664 | private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) | 581 | private bool GetCurContactGeom(int index, ref SafeNativeMethods.ContactGeom newcontactgeom) |
665 | { | 582 | { |
666 | if (ContactgeomsArray == IntPtr.Zero || index >= contactsPerCollision) | 583 | if (ContactgeomsArray == IntPtr.Zero || index >= contactsPerCollision) |
667 | return false; | 584 | return false; |
668 | 585 | ||
669 | IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); | 586 | IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * SafeNativeMethods.ContactGeom.unmanagedSizeOf)); |
670 | newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom)); | 587 | newcontactgeom = (SafeNativeMethods.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(SafeNativeMethods.ContactGeom)); |
671 | return true; | 588 | return true; |
672 | } | 589 | } |
673 | 590 | ||
@@ -692,14 +609,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
692 | if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) | 609 | if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) |
693 | return; | 610 | return; |
694 | 611 | ||
695 | if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) | 612 | if (SafeNativeMethods.GeomIsSpace(g1) || SafeNativeMethods.GeomIsSpace(g2)) |
696 | { | 613 | { |
697 | // We'll be calling near recursivly if one | 614 | // We'll be calling near recursivly if one |
698 | // of them is a space to find all of the | 615 | // of them is a space to find all of the |
699 | // contact points in the space | 616 | // contact points in the space |
700 | try | 617 | try |
701 | { | 618 | { |
702 | d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); | 619 | SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); |
703 | } | 620 | } |
704 | catch (AccessViolationException) | 621 | catch (AccessViolationException) |
705 | { | 622 | { |
@@ -714,8 +631,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
714 | 631 | ||
715 | // get geom bodies to check if we already a joint contact | 632 | // get geom bodies to check if we already a joint contact |
716 | // guess this shouldn't happen now | 633 | // guess this shouldn't happen now |
717 | IntPtr b1 = d.GeomGetBody(g1); | 634 | IntPtr b1 = SafeNativeMethods.GeomGetBody(g1); |
718 | IntPtr b2 = d.GeomGetBody(g2); | 635 | IntPtr b2 = SafeNativeMethods.GeomGetBody(g2); |
719 | 636 | ||
720 | // d.GeomClassID id = d.GeomGetClass(g1); | 637 | // d.GeomClassID id = d.GeomGetClass(g1); |
721 | 638 | ||
@@ -757,19 +674,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
757 | // | 674 | // |
758 | */ | 675 | */ |
759 | 676 | ||
760 | 677 | if (SafeNativeMethods.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || | |
761 | if (d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || | 678 | SafeNativeMethods.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc) |
762 | d.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc) | ||
763 | { | 679 | { |
764 | int cflags; | 680 | int cflags; |
765 | unchecked | 681 | unchecked |
766 | { | 682 | { |
767 | cflags = (int)(1 | d.CONTACTS_UNIMPORTANT); | 683 | cflags = (int)(1 | SafeNativeMethods.CONTACTS_UNIMPORTANT); |
768 | } | 684 | } |
769 | count = d.CollidePtr(g1, g2, cflags, ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); | 685 | count = SafeNativeMethods.CollidePtr(g1, g2, cflags, ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); |
770 | } | 686 | } |
771 | else | 687 | else |
772 | count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); | 688 | count = SafeNativeMethods.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); |
773 | } | 689 | } |
774 | catch (SEHException) | 690 | catch (SEHException) |
775 | { | 691 | { |
@@ -805,7 +721,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
805 | 721 | ||
806 | 722 | ||
807 | // get first contact | 723 | // get first contact |
808 | d.ContactGeom curContact = new d.ContactGeom(); | 724 | SafeNativeMethods.ContactGeom curContact = new SafeNativeMethods.ContactGeom(); |
809 | 725 | ||
810 | if (!GetCurContactGeom(0, ref curContact)) | 726 | if (!GetCurContactGeom(0, ref curContact)) |
811 | return; | 727 | return; |
@@ -866,9 +782,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
866 | break; | 782 | break; |
867 | 783 | ||
868 | case (int)ActorTypes.Prim: | 784 | case (int)ActorTypes.Prim: |
869 | Vector3 relV = p1.rootVelocity - p2.rootVelocity; | 785 | // Vector3 relV = p1.rootVelocity - p2.rootVelocity; |
870 | float relVlenSQ = relV.LengthSquared(); | 786 | // float relVlenSQ = relV.LengthSquared(); |
871 | if (relVlenSQ > 0.0001f) | 787 | // if (relVlenSQ > 0.0001f) |
872 | { | 788 | { |
873 | p1.CollidingObj = true; | 789 | p1.CollidingObj = true; |
874 | p2.CollidingObj = true; | 790 | p2.CollidingObj = true; |
@@ -878,11 +794,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
878 | bounce = contactdata1.bounce * contactdata2.bounce; | 794 | bounce = contactdata1.bounce * contactdata2.bounce; |
879 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); | 795 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); |
880 | 796 | ||
881 | if (relVlenSQ > 0.01f) | 797 | // if (relVlenSQ > 0.01f) |
882 | mu *= frictionMovementMult; | 798 | // mu *= frictionMovementMult; |
883 | 799 | ||
884 | if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass && | 800 | if(SafeNativeMethods.GeomGetClass(g2) == SafeNativeMethods.GeomClassID.TriMeshClass && |
885 | d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) | 801 | SafeNativeMethods.GeomGetClass(g1) == SafeNativeMethods.GeomClassID.TriMeshClass) |
886 | smoothMesh = true; | 802 | smoothMesh = true; |
887 | break; | 803 | break; |
888 | 804 | ||
@@ -891,12 +807,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
891 | bounce = contactdata1.bounce * TerrainBounce; | 807 | bounce = contactdata1.bounce * TerrainBounce; |
892 | mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); | 808 | mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); |
893 | 809 | ||
894 | Vector3 v1 = p1.rootVelocity; | 810 | // Vector3 v1 = p1.rootVelocity; |
895 | if (Math.Abs(v1.X) > 0.1f || Math.Abs(v1.Y) > 0.1f) | 811 | // if (Math.Abs(v1.X) > 0.1f || Math.Abs(v1.Y) > 0.1f) |
896 | mu *= frictionMovementMult; | 812 | // mu *= frictionMovementMult; |
897 | p1.CollidingGround = true; | 813 | p1.CollidingGround = true; |
898 | 814 | ||
899 | if(d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) | 815 | if(SafeNativeMethods.GeomGetClass(g1) == SafeNativeMethods.GeomClassID.TriMeshClass) |
900 | smoothMesh = true; | 816 | smoothMesh = true; |
901 | break; | 817 | break; |
902 | 818 | ||
@@ -918,11 +834,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
918 | 834 | ||
919 | // if (curContact.side1 > 0) // should be 2 ? | 835 | // if (curContact.side1 > 0) // should be 2 ? |
920 | // IgnoreNegSides = true; | 836 | // IgnoreNegSides = true; |
921 | Vector3 v2 = p2.rootVelocity; | 837 | // Vector3 v2 = p2.rootVelocity; |
922 | if (Math.Abs(v2.X) > 0.1f || Math.Abs(v2.Y) > 0.1f) | 838 | // if (Math.Abs(v2.X) > 0.1f || Math.Abs(v2.Y) > 0.1f) |
923 | mu *= frictionMovementMult; | 839 | // mu *= frictionMovementMult; |
924 | 840 | ||
925 | if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass) | 841 | if(SafeNativeMethods.GeomGetClass(g2) == SafeNativeMethods.GeomClassID.TriMeshClass) |
926 | smoothMesh = true; | 842 | smoothMesh = true; |
927 | } | 843 | } |
928 | else | 844 | else |
@@ -952,7 +868,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
952 | SharedTmpcontact.surface.mu = mu; | 868 | SharedTmpcontact.surface.mu = mu; |
953 | SharedTmpcontact.surface.bounce = bounce; | 869 | SharedTmpcontact.surface.bounce = bounce; |
954 | 870 | ||
955 | d.ContactGeom altContact = new d.ContactGeom(); | 871 | SafeNativeMethods.ContactGeom altContact = new SafeNativeMethods.ContactGeom(); |
956 | bool useAltcontact; | 872 | bool useAltcontact; |
957 | bool noskip; | 873 | bool noskip; |
958 | 874 | ||
@@ -1004,7 +920,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1004 | if (Joint == IntPtr.Zero) | 920 | if (Joint == IntPtr.Zero) |
1005 | break; | 921 | break; |
1006 | 922 | ||
1007 | d.JointAttach(Joint, b1, b2); | 923 | SafeNativeMethods.JointAttach(Joint, b1, b2); |
1008 | 924 | ||
1009 | ncontacts++; | 925 | ncontacts++; |
1010 | 926 | ||
@@ -1152,12 +1068,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1152 | continue; | 1068 | continue; |
1153 | 1069 | ||
1154 | // do colisions with static space | 1070 | // do colisions with static space |
1155 | d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback); | 1071 | SafeNativeMethods.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback); |
1156 | 1072 | ||
1157 | // no coll with gnd | 1073 | // no coll with gnd |
1158 | } | 1074 | } |
1159 | // chars with chars | 1075 | // chars with chars |
1160 | d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback); | 1076 | SafeNativeMethods.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback); |
1161 | 1077 | ||
1162 | } | 1078 | } |
1163 | catch (AccessViolationException) | 1079 | catch (AccessViolationException) |
@@ -1173,7 +1089,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1173 | { | 1089 | { |
1174 | aprim.CollisionScore = 0; | 1090 | aprim.CollisionScore = 0; |
1175 | aprim.IsColliding = false; | 1091 | aprim.IsColliding = false; |
1176 | if(!aprim.m_outbounds && d.BodyIsEnabled(aprim.Body)) | 1092 | if(!aprim.m_outbounds && SafeNativeMethods.BodyIsEnabled(aprim.Body)) |
1177 | aprim.clearSleeperCollisions(); | 1093 | aprim.clearSleeperCollisions(); |
1178 | } | 1094 | } |
1179 | } | 1095 | } |
@@ -1184,11 +1100,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1184 | { | 1100 | { |
1185 | foreach (OdePrim aprim in _activegroups) | 1101 | foreach (OdePrim aprim in _activegroups) |
1186 | { | 1102 | { |
1187 | if(!aprim.m_outbounds && d.BodyIsEnabled(aprim.Body) && | 1103 | if(!aprim.m_outbounds && SafeNativeMethods.BodyIsEnabled(aprim.Body) && |
1188 | aprim.collide_geom != IntPtr.Zero) | 1104 | aprim.collide_geom != IntPtr.Zero) |
1189 | { | 1105 | { |
1190 | d.SpaceCollide2(StaticSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); | 1106 | SafeNativeMethods.SpaceCollide2(StaticSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); |
1191 | d.SpaceCollide2(GroundSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); | 1107 | SafeNativeMethods.SpaceCollide2(GroundSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); |
1192 | } | 1108 | } |
1193 | } | 1109 | } |
1194 | } | 1110 | } |
@@ -1201,7 +1117,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1201 | // colide active amoung them | 1117 | // colide active amoung them |
1202 | try | 1118 | try |
1203 | { | 1119 | { |
1204 | d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); | 1120 | SafeNativeMethods.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); |
1205 | } | 1121 | } |
1206 | catch (Exception e) | 1122 | catch (Exception e) |
1207 | { | 1123 | { |
@@ -1211,7 +1127,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1211 | // and with chars | 1127 | // and with chars |
1212 | try | 1128 | try |
1213 | { | 1129 | { |
1214 | d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback); | 1130 | SafeNativeMethods.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback); |
1215 | } | 1131 | } |
1216 | catch (Exception e) | 1132 | catch (Exception e) |
1217 | { | 1133 | { |
@@ -1306,9 +1222,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1306 | public override void RemoveAvatar(PhysicsActor actor) | 1222 | public override void RemoveAvatar(PhysicsActor actor) |
1307 | { | 1223 | { |
1308 | //m_log.Debug("[PHYSICS]:ODELOCK"); | 1224 | //m_log.Debug("[PHYSICS]:ODELOCK"); |
1225 | if (world == IntPtr.Zero) | ||
1226 | return; | ||
1227 | |||
1309 | lock (OdeLock) | 1228 | lock (OdeLock) |
1310 | { | 1229 | { |
1311 | d.AllocateODEDataForThread(0); | 1230 | SafeNativeMethods.AllocateODEDataForThread(0); |
1312 | ((OdeCharacter) actor).Destroy(); | 1231 | ((OdeCharacter) actor).Destroy(); |
1313 | } | 1232 | } |
1314 | } | 1233 | } |
@@ -1460,39 +1379,35 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1460 | 1379 | ||
1461 | /// <summary> | 1380 | /// <summary> |
1462 | /// Called when a static prim moves or becomes static | 1381 | /// Called when a static prim moves or becomes static |
1463 | /// Places the prim in a space one the static sub-spaces grid | 1382 | /// Places the prim in a space one the static space |
1464 | /// </summary> | 1383 | /// </summary> |
1465 | /// <param name="geom">the pointer to the geom that moved</param> | 1384 | /// <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> | 1385 | /// <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> | 1386 | /// <returns>a pointer to the new space it's in</returns> |
1469 | public IntPtr MoveGeomToStaticSpace(IntPtr geom, Vector3 pos, IntPtr currentspace) | 1387 | public IntPtr MoveGeomToStaticSpace(IntPtr geom, IntPtr currentspace) |
1470 | { | 1388 | { |
1471 | // moves a prim into another static sub-space or from another space into a static sub-space | 1389 | // moves a prim into static sub-space |
1472 | 1390 | ||
1473 | // Called ODEPrim so | 1391 | // Called ODEPrim so |
1474 | // it's already in locked space. | 1392 | // it's already in locked space. |
1475 | 1393 | ||
1476 | if (geom == IntPtr.Zero) // shouldn't happen | 1394 | if (geom == IntPtr.Zero) // shouldn't happen |
1477 | return IntPtr.Zero; | 1395 | return IntPtr.Zero; |
1478 | 1396 | ||
1479 | // get the static sub-space for current position | 1397 | if (StaticSpace == currentspace) // if we are there all done |
1480 | IntPtr newspace = calculateSpaceForGeom(pos); | 1398 | return StaticSpace; |
1481 | |||
1482 | if (newspace == currentspace) // if we are there all done | ||
1483 | return newspace; | ||
1484 | 1399 | ||
1485 | // else remove it from its current space | 1400 | // else remove it from its current space |
1486 | if (currentspace != IntPtr.Zero && d.SpaceQuery(currentspace, geom)) | 1401 | if (currentspace != IntPtr.Zero && SafeNativeMethods.SpaceQuery(currentspace, geom)) |
1487 | { | 1402 | { |
1488 | if (d.GeomIsSpace(currentspace)) | 1403 | if (SafeNativeMethods.GeomIsSpace(currentspace)) |
1489 | { | 1404 | { |
1490 | waitForSpaceUnlock(currentspace); | 1405 | waitForSpaceUnlock(currentspace); |
1491 | d.SpaceRemove(currentspace, geom); | 1406 | SafeNativeMethods.SpaceRemove(currentspace, geom); |
1492 | 1407 | ||
1493 | if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) | 1408 | if (SafeNativeMethods.SpaceGetSublevel(currentspace) > 2 && SafeNativeMethods.SpaceGetNumGeoms(currentspace) == 0) |
1494 | { | 1409 | { |
1495 | d.SpaceDestroy(currentspace); | 1410 | SafeNativeMethods.SpaceDestroy(currentspace); |
1496 | } | 1411 | } |
1497 | } | 1412 | } |
1498 | else | 1413 | else |
@@ -1501,59 +1416,33 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1501 | " Geom:" + geom); | 1416 | " Geom:" + geom); |
1502 | } | 1417 | } |
1503 | } | 1418 | } |
1504 | else // odd currentspace is null or doesn't contain the geom? lets try the geom ideia of current space | 1419 | else |
1505 | { | 1420 | { |
1506 | currentspace = d.GeomGetSpace(geom); | 1421 | currentspace = SafeNativeMethods.GeomGetSpace(geom); |
1507 | if (currentspace != IntPtr.Zero) | 1422 | if (currentspace != IntPtr.Zero) |
1508 | { | 1423 | { |
1509 | if (d.GeomIsSpace(currentspace)) | 1424 | if (SafeNativeMethods.GeomIsSpace(currentspace)) |
1510 | { | 1425 | { |
1511 | waitForSpaceUnlock(currentspace); | 1426 | waitForSpaceUnlock(currentspace); |
1512 | d.SpaceRemove(currentspace, geom); | 1427 | SafeNativeMethods.SpaceRemove(currentspace, geom); |
1513 | 1428 | ||
1514 | if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) | 1429 | if (SafeNativeMethods.SpaceGetSublevel(currentspace) > 2 && SafeNativeMethods.SpaceGetNumGeoms(currentspace) == 0) |
1515 | { | 1430 | { |
1516 | d.SpaceDestroy(currentspace); | 1431 | SafeNativeMethods.SpaceDestroy(currentspace); |
1517 | } | 1432 | } |
1518 | |||
1519 | } | 1433 | } |
1520 | } | 1434 | } |
1521 | } | 1435 | } |
1522 | 1436 | ||
1523 | // put the geom in the newspace | 1437 | // put the geom in the newspace |
1524 | waitForSpaceUnlock(newspace); | 1438 | waitForSpaceUnlock(StaticSpace); |
1525 | d.SpaceAdd(newspace, geom); | 1439 | if(SafeNativeMethods.SpaceQuery(StaticSpace, geom)) |
1526 | 1440 | m_log.Info("[Physics]: 'MoveGeomToStaticSpace' geom already in static space:" + geom); | |
1527 | // let caller know this newspace | 1441 | else |
1528 | return newspace; | 1442 | SafeNativeMethods.SpaceAdd(StaticSpace, geom); |
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 | 1443 | ||
1554 | return staticPrimspace[x, y]; | 1444 | return StaticSpace; |
1555 | } | 1445 | } |
1556 | |||
1557 | #endregion | 1446 | #endregion |
1558 | 1447 | ||
1559 | 1448 | ||
@@ -1592,7 +1481,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1592 | return; | 1481 | return; |
1593 | } | 1482 | } |
1594 | 1483 | ||
1595 | d.AllocateODEDataForThread(~0U); | 1484 | SafeNativeMethods.AllocateODEDataForThread(~0U); |
1596 | 1485 | ||
1597 | ODEchangeitem item; | 1486 | ODEchangeitem item; |
1598 | 1487 | ||
@@ -1641,6 +1530,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1641 | /// <returns></returns> | 1530 | /// <returns></returns> |
1642 | public override float Simulate(float reqTimeStep) | 1531 | public override float Simulate(float reqTimeStep) |
1643 | { | 1532 | { |
1533 | if (world == IntPtr.Zero) | ||
1534 | return 0; | ||
1535 | |||
1644 | double now = Util.GetTimeStamp(); | 1536 | double now = Util.GetTimeStamp(); |
1645 | double timeStep = now - m_lastframe; | 1537 | double timeStep = now - m_lastframe; |
1646 | m_lastframe = now; | 1538 | m_lastframe = now; |
@@ -1679,11 +1571,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1679 | double maxChangestime = (int)(reqTimeStep * 500f); // half the time | 1571 | double maxChangestime = (int)(reqTimeStep * 500f); // half the time |
1680 | double maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time | 1572 | double maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time |
1681 | 1573 | ||
1682 | // double collisionTime = 0; | 1574 | /* |
1683 | // double qstepTIme = 0; | 1575 | double collisionTime = 0; |
1684 | // double tmpTime = 0; | 1576 | double qstepTIme = 0; |
1685 | 1577 | double tmpTime = 0; | |
1686 | d.AllocateODEDataForThread(~0U); | 1578 | double changestot = 0; |
1579 | double collisonRepo = 0; | ||
1580 | double updatesTime = 0; | ||
1581 | double moveTime = 0; | ||
1582 | double rayTime = 0; | ||
1583 | */ | ||
1584 | SafeNativeMethods.AllocateODEDataForThread(~0U); | ||
1687 | 1585 | ||
1688 | if (ChangesQueue.Count > 0) | 1586 | if (ChangesQueue.Count > 0) |
1689 | { | 1587 | { |
@@ -1719,6 +1617,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1719 | m_global_contactcount = 0; | 1617 | m_global_contactcount = 0; |
1720 | 1618 | ||
1721 | 1619 | ||
1620 | // tmpTime = Util.GetTimeStampMS(); | ||
1621 | |||
1722 | // Move characters | 1622 | // Move characters |
1723 | lock (_characters) | 1623 | lock (_characters) |
1724 | { | 1624 | { |
@@ -1746,13 +1646,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1746 | aprim.Move(); | 1646 | aprim.Move(); |
1747 | } | 1647 | } |
1748 | } | 1648 | } |
1649 | // moveTime += Util.GetTimeStampMS() - tmpTime; | ||
1749 | 1650 | ||
1651 | // tmpTime = Util.GetTimeStampMS(); | ||
1750 | m_rayCastManager.ProcessQueuedRequests(); | 1652 | m_rayCastManager.ProcessQueuedRequests(); |
1653 | // rayTime += Util.GetTimeStampMS() - tmpTime; | ||
1751 | 1654 | ||
1752 | // tmpTime = Util.GetTimeStampMS(); | 1655 | // tmpTime = Util.GetTimeStampMS(); |
1753 | collision_optimized(); | 1656 | collision_optimized(); |
1754 | // collisionTime += Util.GetTimeStampMS() - tmpTime; | 1657 | // collisionTime += Util.GetTimeStampMS() - tmpTime; |
1755 | 1658 | ||
1659 | // tmpTime = Util.GetTimeStampMS(); | ||
1756 | lock(_collisionEventPrimRemove) | 1660 | lock(_collisionEventPrimRemove) |
1757 | { | 1661 | { |
1758 | foreach (PhysicsActor obj in _collisionEventPrimRemove) | 1662 | foreach (PhysicsActor obj in _collisionEventPrimRemove) |
@@ -1781,7 +1685,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1781 | pobj.SendCollisions((int)(odetimestepMS)); | 1685 | pobj.SendCollisions((int)(odetimestepMS)); |
1782 | if(pobj.Body != IntPtr.Zero && !pobj.m_isSelected && | 1686 | if(pobj.Body != IntPtr.Zero && !pobj.m_isSelected && |
1783 | !pobj.m_disabled && !pobj.m_building && | 1687 | !pobj.m_disabled && !pobj.m_building && |
1784 | !d.BodyIsEnabled(pobj.Body)) | 1688 | !SafeNativeMethods.BodyIsEnabled(pobj.Body)) |
1785 | sleepers.Add(pobj); | 1689 | sleepers.Add(pobj); |
1786 | } | 1690 | } |
1787 | break; | 1691 | break; |
@@ -1791,11 +1695,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1791 | foreach(OdePrim prm in sleepers) | 1695 | foreach(OdePrim prm in sleepers) |
1792 | prm.SleeperAddCollisionEvents(); | 1696 | prm.SleeperAddCollisionEvents(); |
1793 | sleepers.Clear(); | 1697 | sleepers.Clear(); |
1698 | // collisonRepo += Util.GetTimeStampMS() - tmpTime; | ||
1699 | |||
1794 | 1700 | ||
1795 | // do a ode simulation step | 1701 | // do a ode simulation step |
1796 | // tmpTime = Util.GetTimeStampMS(); | 1702 | // tmpTime = Util.GetTimeStampMS(); |
1797 | d.WorldQuickStep(world, ODE_STEPSIZE); | 1703 | SafeNativeMethods.WorldQuickStep(world, ODE_STEPSIZE); |
1798 | d.JointGroupEmpty(contactgroup); | 1704 | SafeNativeMethods.JointGroupEmpty(contactgroup); |
1799 | // qstepTIme += Util.GetTimeStampMS() - tmpTime; | 1705 | // qstepTIme += Util.GetTimeStampMS() - tmpTime; |
1800 | 1706 | ||
1801 | // update managed ideia of physical data and do updates to core | 1707 | // update managed ideia of physical data and do updates to core |
@@ -1814,7 +1720,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1814 | } | 1720 | } |
1815 | } | 1721 | } |
1816 | */ | 1722 | */ |
1817 | 1723 | // tmpTime = Util.GetTimeStampMS(); | |
1818 | lock (_activegroups) | 1724 | lock (_activegroups) |
1819 | { | 1725 | { |
1820 | { | 1726 | { |
@@ -1827,6 +1733,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1827 | } | 1733 | } |
1828 | } | 1734 | } |
1829 | } | 1735 | } |
1736 | // updatesTime += Util.GetTimeStampMS() - tmpTime; | ||
1830 | } | 1737 | } |
1831 | catch (Exception e) | 1738 | catch (Exception e) |
1832 | { | 1739 | { |
@@ -1834,10 +1741,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1834 | // ode.dunlock(world); | 1741 | // ode.dunlock(world); |
1835 | } | 1742 | } |
1836 | 1743 | ||
1744 | |||
1837 | step_time -= ODE_STEPSIZE; | 1745 | step_time -= ODE_STEPSIZE; |
1838 | nodeframes++; | 1746 | nodeframes++; |
1839 | 1747 | ||
1840 | looptimeMS = Util.GetTimeStampMS() - loopstartMS; | 1748 | looptimeMS = Util.GetTimeStampMS() - loopstartMS; |
1749 | |||
1841 | if (looptimeMS > maxLoopTime) | 1750 | if (looptimeMS > maxLoopTime) |
1842 | break; | 1751 | break; |
1843 | } | 1752 | } |
@@ -1854,9 +1763,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1854 | _badCharacter.Clear(); | 1763 | _badCharacter.Clear(); |
1855 | } | 1764 | } |
1856 | } | 1765 | } |
1857 | |||
1858 | // information block for in debug breakpoint only | ||
1859 | /* | 1766 | /* |
1767 | // information block for in debug breakpoint only | ||
1768 | |||
1860 | int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); | 1769 | int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); |
1861 | int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); | 1770 | int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); |
1862 | int ngroundgeoms = d.SpaceGetNumGeoms(GroundSpace); | 1771 | int ngroundgeoms = d.SpaceGetNumGeoms(GroundSpace); |
@@ -1898,33 +1807,23 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1898 | int nbodies = d.NTotalBodies; | 1807 | int nbodies = d.NTotalBodies; |
1899 | int ngeoms = d.NTotalGeoms; | 1808 | int ngeoms = d.NTotalGeoms; |
1900 | */ | 1809 | */ |
1810 | |||
1901 | /* | 1811 | /* |
1902 | looptimeMS /= nodeframes; | 1812 | looptimeMS /= nodeframes; |
1903 | if(looptimeMS > 0.080) | 1813 | collisionTime /= nodeframes; |
1904 | { | 1814 | qstepTIme /= nodeframes; |
1905 | collisionTime /= nodeframes; | 1815 | changestot /= nodeframes; |
1906 | qstepTIme /= nodeframes; | 1816 | collisonRepo /= nodeframes; |
1907 | } | 1817 | updatesTime /= nodeframes; |
1908 | */ | 1818 | moveTime /= nodeframes; |
1909 | // Finished with all sim stepping. If requested, dump world state to file for debugging. | 1819 | rayTime /= nodeframes; |
1910 | // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? | 1820 | |
1911 | // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? | 1821 | if(looptimeMS > .05) |
1912 | if (physics_logging && (physics_logging_interval > 0) && (framecount % physics_logging_interval == 0)) | ||
1913 | { | 1822 | { |
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 | 1823 | ||
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 | 1824 | ||
1925 | d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); | ||
1926 | } | 1825 | } |
1927 | 1826 | */ | |
1928 | fps = (float)nodeframes * ODE_STEPSIZE / reqTimeStep; | 1827 | fps = (float)nodeframes * ODE_STEPSIZE / reqTimeStep; |
1929 | 1828 | ||
1930 | if(step_time < HalfOdeStep) | 1829 | if(step_time < HalfOdeStep) |
@@ -2285,35 +2184,35 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2285 | 2184 | ||
2286 | lock (OdeLock) | 2185 | lock (OdeLock) |
2287 | { | 2186 | { |
2288 | d.AllocateODEDataForThread(~0U); | 2187 | SafeNativeMethods.AllocateODEDataForThread(~0U); |
2289 | 2188 | ||
2290 | if (TerrainGeom != IntPtr.Zero) | 2189 | if (TerrainGeom != IntPtr.Zero) |
2291 | { | 2190 | { |
2292 | actor_name_map.Remove(TerrainGeom); | 2191 | actor_name_map.Remove(TerrainGeom); |
2293 | d.GeomDestroy(TerrainGeom); | 2192 | SafeNativeMethods.GeomDestroy(TerrainGeom); |
2294 | 2193 | ||
2295 | } | 2194 | } |
2296 | 2195 | ||
2297 | if (TerrainHeightFieldHeightsHandler.IsAllocated) | 2196 | if (TerrainHeightFieldHeightsHandler.IsAllocated) |
2298 | TerrainHeightFieldHeightsHandler.Free(); | 2197 | TerrainHeightFieldHeightsHandler.Free(); |
2299 | 2198 | ||
2300 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); | 2199 | IntPtr HeightmapData = SafeNativeMethods.GeomHeightfieldDataCreate(); |
2301 | 2200 | ||
2302 | TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); | 2201 | TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); |
2303 | 2202 | ||
2304 | d.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, | 2203 | SafeNativeMethods.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, |
2305 | heightmapHeight, heightmapWidth , | 2204 | heightmapHeight, heightmapWidth , |
2306 | (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale, | 2205 | (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale, |
2307 | offset, thickness, wrap); | 2206 | offset, thickness, wrap); |
2308 | 2207 | ||
2309 | d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); | 2208 | SafeNativeMethods.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); |
2310 | 2209 | ||
2311 | TerrainGeom = d.CreateHeightfield(GroundSpace, HeightmapData, 1); | 2210 | TerrainGeom = SafeNativeMethods.CreateHeightfield(GroundSpace, HeightmapData, 1); |
2312 | 2211 | ||
2313 | if (TerrainGeom != IntPtr.Zero) | 2212 | if (TerrainGeom != IntPtr.Zero) |
2314 | { | 2213 | { |
2315 | d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); | 2214 | SafeNativeMethods.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); |
2316 | d.GeomSetCollideBits(TerrainGeom, 0); | 2215 | SafeNativeMethods.GeomSetCollideBits(TerrainGeom, 0); |
2317 | 2216 | ||
2318 | PhysicsActor pa = new NullPhysicsActor(); | 2217 | PhysicsActor pa = new NullPhysicsActor(); |
2319 | pa.Name = "Terrain"; | 2218 | pa.Name = "Terrain"; |
@@ -2322,14 +2221,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2322 | 2221 | ||
2323 | // geom_name_map[GroundGeom] = "Terrain"; | 2222 | // geom_name_map[GroundGeom] = "Terrain"; |
2324 | 2223 | ||
2325 | d.Quaternion q = new d.Quaternion(); | 2224 | SafeNativeMethods.Quaternion q = new SafeNativeMethods.Quaternion(); |
2326 | q.X = 0.5f; | 2225 | q.X = 0.5f; |
2327 | q.Y = 0.5f; | 2226 | q.Y = 0.5f; |
2328 | q.Z = 0.5f; | 2227 | q.Z = 0.5f; |
2329 | q.W = 0.5f; | 2228 | q.W = 0.5f; |
2330 | 2229 | ||
2331 | d.GeomSetQuaternion(TerrainGeom, ref q); | 2230 | SafeNativeMethods.GeomSetQuaternion(TerrainGeom, ref q); |
2332 | d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); | 2231 | SafeNativeMethods.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); |
2333 | TerrainHeightFieldHeight = _heightmap; | 2232 | TerrainHeightFieldHeight = _heightmap; |
2334 | } | 2233 | } |
2335 | else | 2234 | else |
@@ -2397,7 +2296,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2397 | if (TerrainGeom != IntPtr.Zero) | 2296 | if (TerrainGeom != IntPtr.Zero) |
2398 | { | 2297 | { |
2399 | actor_name_map.Remove(TerrainGeom); | 2298 | actor_name_map.Remove(TerrainGeom); |
2400 | d.GeomDestroy(TerrainGeom); | 2299 | SafeNativeMethods.GeomDestroy(TerrainGeom); |
2401 | } | 2300 | } |
2402 | 2301 | ||
2403 | if (TerrainHeightFieldHeightsHandler.IsAllocated) | 2302 | if (TerrainHeightFieldHeightsHandler.IsAllocated) |
@@ -2405,7 +2304,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2405 | 2304 | ||
2406 | TerrainHeightFieldHeight = null; | 2305 | TerrainHeightFieldHeight = null; |
2407 | 2306 | ||
2408 | IntPtr HeightmapData = d.GeomOSTerrainDataCreate(); | 2307 | IntPtr HeightmapData = SafeNativeMethods.GeomOSTerrainDataCreate(); |
2409 | 2308 | ||
2410 | const int wrap = 0; | 2309 | const int wrap = 0; |
2411 | float thickness = hfmin; | 2310 | float thickness = hfmin; |
@@ -2414,16 +2313,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2414 | 2313 | ||
2415 | TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); | 2314 | TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); |
2416 | 2315 | ||
2417 | d.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f, | 2316 | SafeNativeMethods.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f, |
2418 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, | 2317 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, |
2419 | thickness, wrap); | 2318 | thickness, wrap); |
2420 | 2319 | ||
2421 | // d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); | 2320 | // d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); |
2422 | TerrainGeom = d.CreateOSTerrain(GroundSpace, HeightmapData, 1); | 2321 | TerrainGeom = SafeNativeMethods.CreateOSTerrain(GroundSpace, HeightmapData, 1); |
2423 | if (TerrainGeom != IntPtr.Zero) | 2322 | if (TerrainGeom != IntPtr.Zero) |
2424 | { | 2323 | { |
2425 | d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); | 2324 | SafeNativeMethods.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); |
2426 | d.GeomSetCollideBits(TerrainGeom, 0); | 2325 | SafeNativeMethods.GeomSetCollideBits(TerrainGeom, 0); |
2427 | 2326 | ||
2428 | PhysicsActor pa = new NullPhysicsActor(); | 2327 | PhysicsActor pa = new NullPhysicsActor(); |
2429 | pa.Name = "Terrain"; | 2328 | pa.Name = "Terrain"; |
@@ -2432,7 +2331,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2432 | 2331 | ||
2433 | // geom_name_map[GroundGeom] = "Terrain"; | 2332 | // geom_name_map[GroundGeom] = "Terrain"; |
2434 | 2333 | ||
2435 | d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); | 2334 | SafeNativeMethods.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); |
2436 | TerrainHeightFieldHeight = _heightmap; | 2335 | TerrainHeightFieldHeight = _heightmap; |
2437 | } | 2336 | } |
2438 | else | 2337 | else |
@@ -2462,7 +2361,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2462 | if (world == IntPtr.Zero) | 2361 | if (world == IntPtr.Zero) |
2463 | return; | 2362 | return; |
2464 | 2363 | ||
2465 | d.AllocateODEDataForThread(~0U); | 2364 | SafeNativeMethods.AllocateODEDataForThread(~0U); |
2466 | 2365 | ||
2467 | if (m_meshWorker != null) | 2366 | if (m_meshWorker != null) |
2468 | m_meshWorker.Stop(); | 2367 | m_meshWorker.Stop(); |
@@ -2496,7 +2395,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2496 | ch.DoAChange(changes.Remove, null); | 2395 | ch.DoAChange(changes.Remove, null); |
2497 | 2396 | ||
2498 | if (TerrainGeom != IntPtr.Zero) | 2397 | if (TerrainGeom != IntPtr.Zero) |
2499 | d.GeomDestroy(TerrainGeom); | 2398 | SafeNativeMethods.GeomDestroy(TerrainGeom); |
2500 | TerrainGeom = IntPtr.Zero; | 2399 | TerrainGeom = IntPtr.Zero; |
2501 | 2400 | ||
2502 | if (TerrainHeightFieldHeightsHandler.IsAllocated) | 2401 | if (TerrainHeightFieldHeightsHandler.IsAllocated) |
@@ -2515,7 +2414,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2515 | GlobalContactsArray = IntPtr.Zero; | 2414 | GlobalContactsArray = IntPtr.Zero; |
2516 | } | 2415 | } |
2517 | 2416 | ||
2518 | d.WorldDestroy(world); | 2417 | SafeNativeMethods.WorldDestroy(world); |
2519 | world = IntPtr.Zero; | 2418 | world = IntPtr.Zero; |
2520 | //d.CloseODE(); | 2419 | //d.CloseODE(); |
2521 | } | 2420 | } |