aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs454
1 files changed, 201 insertions, 253 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index f126644..b98f177 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -60,6 +60,7 @@ namespace OpenSim.Region.Physics.OdePlugin
60 public int lastframe; 60 public int lastframe;
61 } 61 }
62 62
63
63 // colision flags of things others can colide with 64 // colision flags of things others can colide with
64 // rays, sensors, probes removed since can't be colided with 65 // rays, sensors, probes removed since can't be colided with
65 // The top space where things are placed provided further selection 66 // The top space where things are placed provided further selection
@@ -109,7 +110,7 @@ namespace OpenSim.Region.Physics.OdePlugin
109 110
110 light = 7 // compatibility with old viewers 111 light = 7 // compatibility with old viewers
111 } 112 }
112 113
113 public enum changes : int 114 public enum changes : int
114 { 115 {
115 Add = 0, // arg null. finishs the prim creation. should be used internally only ( to remove later ?) 116 Add = 0, // arg null. finishs the prim creation. should be used internally only ( to remove later ?)
@@ -147,6 +148,8 @@ namespace OpenSim.Region.Physics.OdePlugin
147 148
148 Size, 149 Size,
149 Shape, 150 Shape,
151 PhysRepData,
152 AddPhysRep,
150 153
151 CollidesWater, 154 CollidesWater,
152 VolumeDtc, 155 VolumeDtc,
@@ -230,11 +233,6 @@ namespace OpenSim.Region.Physics.OdePlugin
230 private float minimumGroundFlightOffset = 3f; 233 private float minimumGroundFlightOffset = 3f;
231 public float maximumMassObject = 10000.01f; 234 public float maximumMassObject = 10000.01f;
232 235
233 public bool meshSculptedPrim = true;
234 public bool forceSimplePrimMeshing = false;
235
236 public float meshSculptLOD = 32;
237 public float MeshSculptphysicalLOD = 32;
238 236
239 public float geomDefaultDensity = 10.000006836f; 237 public float geomDefaultDensity = 10.000006836f;
240 238
@@ -302,6 +300,7 @@ namespace OpenSim.Region.Physics.OdePlugin
302 public IntPtr TopSpace; // the global space 300 public IntPtr TopSpace; // the global space
303 public IntPtr ActiveSpace; // space for active prims 301 public IntPtr ActiveSpace; // space for active prims
304 public IntPtr StaticSpace; // space for the static things around 302 public IntPtr StaticSpace; // space for the static things around
303 public IntPtr GroundSpace; // space for ground
305 304
306 // some speedup variables 305 // some speedup variables
307 private int spaceGridMaxX; 306 private int spaceGridMaxX;
@@ -313,7 +312,7 @@ namespace OpenSim.Region.Physics.OdePlugin
313 private IntPtr[] staticPrimspaceOffRegion; 312 private IntPtr[] staticPrimspaceOffRegion;
314 313
315 public Object OdeLock; 314 public Object OdeLock;
316 private static Object SimulationLock; 315 public static Object SimulationLock;
317 316
318 public IMesher mesher; 317 public IMesher mesher;
319 318
@@ -328,7 +327,7 @@ namespace OpenSim.Region.Physics.OdePlugin
328 private PhysicsScene m_parentScene = null; 327 private PhysicsScene m_parentScene = null;
329 328
330 private ODERayCastRequestManager m_rayCastManager; 329 private ODERayCastRequestManager m_rayCastManager;
331 330 public ODEMeshWorker m_meshWorker;
332 331
333/* maybe needed if ode uses tls 332/* maybe needed if ode uses tls
334 private void checkThread() 333 private void checkThread()
@@ -361,6 +360,8 @@ namespace OpenSim.Region.Physics.OdePlugin
361 nearCallback = near; 360 nearCallback = near;
362 361
363 m_rayCastManager = new ODERayCastRequestManager(this); 362 m_rayCastManager = new ODERayCastRequestManager(this);
363
364
364 lock (OdeLock) 365 lock (OdeLock)
365 { 366 {
366 // Create the world and the first space 367 // Create the world and the first space
@@ -372,6 +373,7 @@ namespace OpenSim.Region.Physics.OdePlugin
372 // now the major subspaces 373 // now the major subspaces
373 ActiveSpace = d.HashSpaceCreate(TopSpace); 374 ActiveSpace = d.HashSpaceCreate(TopSpace);
374 StaticSpace = d.HashSpaceCreate(TopSpace); 375 StaticSpace = d.HashSpaceCreate(TopSpace);
376 GroundSpace = d.HashSpaceCreate(TopSpace);
375 } 377 }
376 catch 378 catch
377 { 379 {
@@ -381,10 +383,12 @@ namespace OpenSim.Region.Physics.OdePlugin
381 d.HashSpaceSetLevels(TopSpace, -2, 8); 383 d.HashSpaceSetLevels(TopSpace, -2, 8);
382 d.HashSpaceSetLevels(ActiveSpace, -2, 8); 384 d.HashSpaceSetLevels(ActiveSpace, -2, 8);
383 d.HashSpaceSetLevels(StaticSpace, -2, 8); 385 d.HashSpaceSetLevels(StaticSpace, -2, 8);
386 d.HashSpaceSetLevels(GroundSpace, 0, 8);
384 387
385 // demote to second level 388 // demote to second level
386 d.SpaceSetSublevel(ActiveSpace, 1); 389 d.SpaceSetSublevel(ActiveSpace, 1);
387 d.SpaceSetSublevel(StaticSpace, 1); 390 d.SpaceSetSublevel(StaticSpace, 1);
391 d.SpaceSetSublevel(GroundSpace, 1);
388 392
389 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | 393 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
390 CollisionCategories.Geom | 394 CollisionCategories.Geom |
@@ -402,6 +406,9 @@ namespace OpenSim.Region.Physics.OdePlugin
402 )); 406 ));
403 d.GeomSetCollideBits(StaticSpace, 0); 407 d.GeomSetCollideBits(StaticSpace, 0);
404 408
409 d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land));
410 d.GeomSetCollideBits(GroundSpace, 0);
411
405 contactgroup = d.JointGroupCreate(0); 412 contactgroup = d.JointGroupCreate(0);
406 //contactgroup 413 //contactgroup
407 414
@@ -440,9 +447,11 @@ namespace OpenSim.Region.Physics.OdePlugin
440 447
441 int contactsPerCollision = 80; 448 int contactsPerCollision = 80;
442 449
450 IConfig physicsconfig = null;
451
443 if (m_config != null) 452 if (m_config != null)
444 { 453 {
445 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; 454 physicsconfig = m_config.Configs["ODEPhysicsSettings"];
446 if (physicsconfig != null) 455 if (physicsconfig != null)
447 { 456 {
448 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx); 457 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
@@ -469,27 +478,7 @@ namespace OpenSim.Region.Physics.OdePlugin
469 478
470 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); 479 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
471 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); 480 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
472/* 481
473 bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", bodyPIDD);
474 bodyPIDG = physicsconfig.GetFloat("body_pid_gain", bodyPIDG);
475*/
476 forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
477 meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
478 meshSculptLOD = physicsconfig.GetFloat("mesh_lod", meshSculptLOD);
479 MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
480/*
481 if (Environment.OSVersion.Platform == PlatformID.Unix)
482 {
483 avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", avPIDD);
484 avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", avPIDP);
485 }
486 else
487 {
488
489 avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", avPIDD);
490 avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", avPIDP);
491 }
492*/
493 physics_logging = physicsconfig.GetBoolean("physics_logging", false); 482 physics_logging = physicsconfig.GetBoolean("physics_logging", false);
494 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); 483 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
495 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); 484 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
@@ -499,6 +488,8 @@ namespace OpenSim.Region.Physics.OdePlugin
499 } 488 }
500 } 489 }
501 490
491 m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, physicsconfig);
492
502 HalfOdeStep = ODE_STEPSIZE * 0.5f; 493 HalfOdeStep = ODE_STEPSIZE * 0.5f;
503 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f); 494 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f);
504 495
@@ -727,6 +718,32 @@ namespace OpenSim.Region.Physics.OdePlugin
727 718
728 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 719 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
729 return; 720 return;
721/*
722// debug
723 PhysicsActor dp2;
724 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
725 {
726 d.AABB aabb;
727 d.GeomGetAABB(g2, out aabb);
728 float x = aabb.MaxX - aabb.MinX;
729 float y = aabb.MaxY - aabb.MinY;
730 float z = aabb.MaxZ - aabb.MinZ;
731 if (x > 60.0f || y > 60.0f || z > 60.0f)
732 {
733 if (!actor_name_map.TryGetValue(g2, out dp2))
734 m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2");
735 else
736 m_log.WarnFormat("[PHYSICS]: land versus large prim geo {0},size {1}, AABBsize <{2},{3},{4}>, at {5} ori {6},({7})",
737 dp2.Name, dp2.Size, x, y, z,
738 dp2.Position.ToString(),
739 dp2.Orientation.ToString(),
740 dp2.Orientation.Length());
741 return;
742 }
743 }
744//
745*/
746
730 747
731 if(d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || 748 if(d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc ||
732 d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc) 749 d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc)
@@ -1225,6 +1242,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1225 chr.CollidingObj = false; 1242 chr.CollidingObj = false;
1226 // do colisions with static space 1243 // do colisions with static space
1227 d.SpaceCollide2(StaticSpace, chr.Shell, IntPtr.Zero, nearCallback); 1244 d.SpaceCollide2(StaticSpace, chr.Shell, IntPtr.Zero, nearCallback);
1245 // no coll with gnd
1228 } 1246 }
1229 } 1247 }
1230 catch (AccessViolationException) 1248 catch (AccessViolationException)
@@ -1253,7 +1271,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1253 if (!prm.m_outbounds) 1271 if (!prm.m_outbounds)
1254 { 1272 {
1255 if (d.BodyIsEnabled(prm.Body)) 1273 if (d.BodyIsEnabled(prm.Body))
1274 {
1256 d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback); 1275 d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback);
1276 d.SpaceCollide2(GroundSpace, prm.collide_geom, IntPtr.Zero, nearCallback);
1277 }
1257 } 1278 }
1258 } 1279 }
1259 } 1280 }
@@ -1295,6 +1316,15 @@ namespace OpenSim.Region.Physics.OdePlugin
1295 _collisionEventPrimRemove.Add(obj); 1316 _collisionEventPrimRemove.Add(obj);
1296 } 1317 }
1297 1318
1319 public override float TimeDilation
1320 {
1321 get { return m_timeDilation; }
1322 }
1323
1324 public override bool SupportsNINJAJoints
1325 {
1326 get { return false; }
1327 }
1298 1328
1299 #region Add/Remove Entities 1329 #region Add/Remove Entities
1300 1330
@@ -1350,117 +1380,59 @@ namespace OpenSim.Region.Physics.OdePlugin
1350 ((OdeCharacter) actor).Destroy(); 1380 ((OdeCharacter) actor).Destroy();
1351 } 1381 }
1352 1382
1353 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
1354 PrimitiveBaseShape pbs, bool isphysical, uint localID)
1355 {
1356 Vector3 pos = position;
1357 Vector3 siz = size;
1358 Quaternion rot = rotation;
1359 1383
1360 OdePrim newPrim; 1384 public void addActivePrim(OdePrim activatePrim)
1361 lock (OdeLock) 1385 {
1386 // adds active prim..
1387 lock (_activeprims)
1362 { 1388 {
1363 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical,false,0,localID); 1389 if (!_activeprims.Contains(activatePrim))
1364 1390 _activeprims.Add(activatePrim);
1365 lock (_prims)
1366 _prims.Add(newPrim);
1367 } 1391 }
1368 return newPrim;
1369 } 1392 }
1370 1393
1371 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, 1394 public void addActiveGroups(OdePrim activatePrim)
1372 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, uint localID)
1373 { 1395 {
1374 Vector3 pos = position; 1396 lock (_activegroups)
1375 Vector3 siz = size;
1376 Quaternion rot = rotation;
1377
1378 OdePrim newPrim;
1379 lock (OdeLock)
1380 { 1397 {
1381 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, isPhantom, 0, localID); 1398 if (!_activegroups.Contains(activatePrim))
1382 1399 _activegroups.Add(activatePrim);
1383 lock (_prims)
1384 _prims.Add(newPrim);
1385 } 1400 }
1386 return newPrim;
1387 } 1401 }
1388 1402
1389 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, 1403 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
1390 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID) 1404 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID)
1391 { 1405 {
1392 Vector3 pos = position;
1393 Vector3 siz = size;
1394 Quaternion rot = rotation;
1395
1396 OdePrim newPrim; 1406 OdePrim newPrim;
1397 lock (OdeLock) 1407 lock (OdeLock)
1398 { 1408 {
1399 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, isPhantom, shapeType, localID); 1409 newPrim = new OdePrim(name, this, position, size, rotation, pbs, isphysical, isPhantom, shapeType, localID);
1400
1401 lock (_prims) 1410 lock (_prims)
1402 _prims.Add(newPrim); 1411 _prims.Add(newPrim);
1403 } 1412 }
1404 return newPrim; 1413 return newPrim;
1405 } 1414 }
1406 1415
1407 public void addActivePrim(OdePrim activatePrim)
1408 {
1409 // adds active prim..
1410 lock (_activeprims)
1411 {
1412 if (!_activeprims.Contains(activatePrim))
1413 _activeprims.Add(activatePrim);
1414 }
1415 }
1416
1417 public void addActiveGroups(OdePrim activatePrim)
1418 {
1419 lock (_activegroups)
1420 {
1421 if (!_activegroups.Contains(activatePrim))
1422 _activegroups.Add(activatePrim);
1423 }
1424 }
1425
1426 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1416 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1427 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid) 1417 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid)
1428 { 1418 {
1429 return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, localid); 1419 return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, 0 , localid);
1430 } 1420 }
1431 1421
1432 1422
1433 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1423 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1434 Vector3 size, Quaternion rotation, bool isPhysical, uint localid) 1424 Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
1435 { 1425 {
1436#if SPAM 1426 return AddPrim(primName, position, size, rotation, pbs, isPhysical,false, 0, localid);
1437 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
1438#endif
1439
1440 return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid);
1441 } 1427 }
1442 1428
1443 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1429 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1444 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid) 1430 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid)
1445 { 1431 {
1446#if SPAM
1447 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
1448#endif
1449 1432
1450 return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid); 1433 return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid);
1451 } 1434 }
1452 1435
1453 public override float TimeDilation
1454 {
1455 get { return m_timeDilation; }
1456 }
1457
1458 public override bool SupportsNINJAJoints
1459 {
1460 get { return false; }
1461 }
1462
1463
1464 public void remActivePrim(OdePrim deactivatePrim) 1436 public void remActivePrim(OdePrim deactivatePrim)
1465 { 1437 {
1466 lock (_activeprims) 1438 lock (_activeprims)
@@ -1513,6 +1485,28 @@ namespace OpenSim.Region.Physics.OdePlugin
1513 } 1485 }
1514 1486
1515 } 1487 }
1488
1489 public bool havePrim(OdePrim prm)
1490 {
1491 lock (_prims)
1492 return _prims.Contains(prm);
1493 }
1494
1495 public bool haveActor(PhysicsActor actor)
1496 {
1497 if (actor is OdePrim)
1498 {
1499 lock (_prims)
1500 return _prims.Contains((OdePrim)actor);
1501 }
1502 else if (actor is OdeCharacter)
1503 {
1504 lock (_characters)
1505 return _characters.Contains((OdeCharacter)actor);
1506 }
1507 return false;
1508 }
1509
1516 #endregion 1510 #endregion
1517 1511
1518 #region Space Separation Calculation 1512 #region Space Separation Calculation
@@ -1615,135 +1609,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1615 1609
1616 #endregion 1610 #endregion
1617 1611
1618 /// <summary>
1619 /// Routine to figure out if we need to mesh this prim with our mesher
1620 /// </summary>
1621 /// <param name="pbs"></param>
1622 /// <returns></returns>
1623 public bool needsMeshing(PrimitiveBaseShape pbs)
1624 {
1625 // check sculpts or meshs
1626 if (pbs.SculptEntry)
1627 {
1628 if (meshSculptedPrim)
1629 return true;
1630
1631 if (pbs.SculptType == (byte)SculptType.Mesh) // always do meshs
1632 return true;
1633
1634 return false;
1635 }
1636
1637 if (forceSimplePrimMeshing)
1638 return true;
1639
1640 // 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
1641
1642 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
1643 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
1644 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
1645 {
1646
1647 if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
1648 && pbs.ProfileHollow == 0
1649 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
1650 && pbs.PathBegin == 0 && pbs.PathEnd == 0
1651 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
1652 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
1653 && pbs.PathShearX == 0 && pbs.PathShearY == 0)
1654 {
1655#if SPAM
1656 m_log.Warn("NonMesh");
1657#endif
1658 return false;
1659 }
1660 }
1661
1662 // following code doesn't give meshs to boxes and spheres ever
1663 // and it's odd.. so for now just return true if asked to force meshs
1664 // hopefully mesher will fail if doesn't suport so things still get basic boxes
1665
1666 int iPropertiesNotSupportedDefault = 0;
1667
1668 if (pbs.ProfileHollow != 0)
1669 iPropertiesNotSupportedDefault++;
1670
1671 if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
1672 iPropertiesNotSupportedDefault++;
1673
1674 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
1675 iPropertiesNotSupportedDefault++;
1676
1677 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
1678 iPropertiesNotSupportedDefault++;
1679
1680 if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
1681 iPropertiesNotSupportedDefault++;
1682
1683 if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
1684 iPropertiesNotSupportedDefault++;
1685
1686 if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
1687 iPropertiesNotSupportedDefault++;
1688
1689 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))
1690 iPropertiesNotSupportedDefault++;
1691
1692 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1)
1693 iPropertiesNotSupportedDefault++;
1694
1695 // test for torus
1696 if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
1697 {
1698 if (pbs.PathCurve == (byte)Extrusion.Curve1)
1699 {
1700 iPropertiesNotSupportedDefault++;
1701 }
1702 }
1703 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
1704 {
1705 if (pbs.PathCurve == (byte)Extrusion.Straight)
1706 {
1707 iPropertiesNotSupportedDefault++;
1708 }
1709
1710 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
1711 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
1712 {
1713 iPropertiesNotSupportedDefault++;
1714 }
1715 }
1716 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
1717 {
1718 if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
1719 {
1720 iPropertiesNotSupportedDefault++;
1721 }
1722 }
1723 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
1724 {
1725 if (pbs.PathCurve == (byte)Extrusion.Straight)
1726 {
1727 iPropertiesNotSupportedDefault++;
1728 }
1729 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
1730 {
1731 iPropertiesNotSupportedDefault++;
1732 }
1733 }
1734
1735 if (iPropertiesNotSupportedDefault == 0)
1736 {
1737#if SPAM
1738 m_log.Warn("NonMesh");
1739#endif
1740 return false;
1741 }
1742#if SPAM
1743 m_log.Debug("Mesh");
1744#endif
1745 return true;
1746 }
1747 1612
1748 /// <summary> 1613 /// <summary>
1749 /// Called to queue a change to a actor 1614 /// Called to queue a change to a actor
@@ -1766,8 +1631,52 @@ namespace OpenSim.Region.Physics.OdePlugin
1766 /// </summary> 1631 /// </summary>
1767 /// <param name="prim"></param> 1632 /// <param name="prim"></param>
1768 public override void AddPhysicsActorTaint(PhysicsActor prim) 1633 public override void AddPhysicsActorTaint(PhysicsActor prim)
1634 {
1635 }
1636
1637 // does all pending changes generated during region load process
1638 public override void PrepareSimulation()
1639 {
1640 lock (OdeLock)
1769 { 1641 {
1642 if (world == IntPtr.Zero)
1643 {
1644 ChangesQueue.Clear();
1645 return;
1646 }
1647
1648 ODEchangeitem item;
1649
1650 int donechanges = 0;
1651 if (ChangesQueue.Count > 0)
1652 {
1653 m_log.InfoFormat("[ODE] start processing pending actor operations");
1654 int tstart = Util.EnvironmentTickCount();
1655
1656 while (ChangesQueue.Dequeue(out item))
1657 {
1658 if (item.actor != null)
1659 {
1660 try
1661 {
1662 if (item.actor is OdeCharacter)
1663 ((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
1664 else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
1665 RemovePrimThreadLocked((OdePrim)item.actor);
1666 }
1667 catch
1668 {
1669 m_log.WarnFormat("[PHYSICS]: Operation failed for a actor {0} {1}",
1670 item.actor.Name, item.what.ToString());
1671 }
1672 }
1673 donechanges++;
1674 }
1675 int time = Util.EnvironmentTickCountSubtract(tstart);
1676 m_log.InfoFormat("[ODE] finished {0} operations in {1}ms", donechanges, time);
1677 }
1770 } 1678 }
1679 }
1771 1680
1772 /// <summary> 1681 /// <summary>
1773 /// This is our main simulate loop 1682 /// This is our main simulate loop
@@ -1813,21 +1722,17 @@ namespace OpenSim.Region.Physics.OdePlugin
1813 lock(OdeLock) 1722 lock(OdeLock)
1814 { 1723 {
1815 if (world == IntPtr.Zero) 1724 if (world == IntPtr.Zero)
1725 {
1726 ChangesQueue.Clear();
1816 return 0; 1727 return 0;
1728 }
1817 1729
1818 // adjust number of iterations per step 1730 ODEchangeitem item;
1731
1732
1733
1734 d.WorldSetQuickStepNumIterations(world, curphysiteractions);
1819 1735
1820// try
1821// {
1822 d.WorldSetQuickStepNumIterations(world, curphysiteractions);
1823/* }
1824 catch (StackOverflowException)
1825 {
1826 m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim.");
1827// ode.drelease(world);
1828 base.TriggerPhysicsBasedRestart();
1829 }
1830*/
1831 while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever 1736 while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever
1832 { 1737 {
1833 try 1738 try
@@ -1835,14 +1740,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1835 // clear pointer/counter to contacts to pass into joints 1740 // clear pointer/counter to contacts to pass into joints
1836 m_global_contactcount = 0; 1741 m_global_contactcount = 0;
1837 1742
1838 ODEchangeitem item; 1743 if (ChangesQueue.Count > 0)
1839
1840 if(ChangesQueue.Count >0)
1841 { 1744 {
1842 int ttmpstart = Util.EnvironmentTickCount(); 1745 int ttmpstart = Util.EnvironmentTickCount();
1843 int ttmp; 1746 int ttmp;
1844 1747
1845 while(ChangesQueue.Dequeue(out item)) 1748 while (ChangesQueue.Dequeue(out item))
1846 { 1749 {
1847 if (item.actor != null) 1750 if (item.actor != null)
1848 { 1751 {
@@ -1851,12 +1754,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1851 if (item.actor is OdeCharacter) 1754 if (item.actor is OdeCharacter)
1852 ((OdeCharacter)item.actor).DoAChange(item.what, item.arg); 1755 ((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
1853 else if (((OdePrim)item.actor).DoAChange(item.what, item.arg)) 1756 else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
1854 RemovePrimThreadLocked((OdePrim)item.actor); 1757 RemovePrimThreadLocked((OdePrim)item.actor);
1855 } 1758 }
1856 catch 1759 catch
1857 { 1760 {
1858 m_log.Warn("[PHYSICS]: doChange failed for a actor"); 1761 m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}",
1859 }; 1762 item.actor.Name, item.what.ToString());
1763 }
1860 } 1764 }
1861 ttmp = Util.EnvironmentTickCountSubtract(ttmpstart); 1765 ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
1862 if (ttmp > 20) 1766 if (ttmp > 20)
@@ -1994,10 +1898,47 @@ namespace OpenSim.Region.Physics.OdePlugin
1994 mesher.ExpireReleaseMeshs(); 1898 mesher.ExpireReleaseMeshs();
1995 m_lastMeshExpire = now; 1899 m_lastMeshExpire = now;
1996 } 1900 }
1901
1902// information block running in debug only
1997/* 1903/*
1998 int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); 1904 int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace);
1999 int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); 1905 int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);
1906 int ngroundgeoms = d.SpaceGetNumGeoms(GroundSpace);
1907
1908 int nactivegeoms = 0;
1909 int nactivespaces = 0;
1910
1911 int nstaticgeoms = 0;
1912 int nstaticspaces = 0;
1913 IntPtr sp;
1914
1915 for (int i = 0; i < ntopactivegeoms; i++)
1916 {
1917 sp = d.SpaceGetGeom(ActiveSpace, i);
1918 if (d.GeomIsSpace(sp))
1919 {
1920 nactivespaces++;
1921 nactivegeoms += d.SpaceGetNumGeoms(sp);
1922 }
1923 else
1924 nactivegeoms++;
1925 }
1926
1927 for (int i = 0; i < ntopstaticgeoms; i++)
1928 {
1929 sp = d.SpaceGetGeom(StaticSpace, i);
1930 if (d.GeomIsSpace(sp))
1931 {
1932 nstaticspaces++;
1933 nstaticgeoms += d.SpaceGetNumGeoms(sp);
1934 }
1935 else
1936 nstaticgeoms++;
1937 }
1938
2000 int ntopgeoms = d.SpaceGetNumGeoms(TopSpace); 1939 int ntopgeoms = d.SpaceGetNumGeoms(TopSpace);
1940
1941 int totgeoms = nstaticgeoms + nactivegeoms + ngroundgeoms + 1; // one ray
2001 int nbodies = d.NTotalBodies; 1942 int nbodies = d.NTotalBodies;
2002 int ngeoms = d.NTotalGeoms; 1943 int ngeoms = d.NTotalGeoms;
2003*/ 1944*/
@@ -2294,7 +2235,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2294 offset, thickness, wrap); 2235 offset, thickness, wrap);
2295 2236
2296 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); 2237 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
2297 GroundGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1); 2238
2239 GroundGeom = d.CreateHeightfield(GroundSpace, HeightmapData, 1);
2240
2298 if (GroundGeom != IntPtr.Zero) 2241 if (GroundGeom != IntPtr.Zero)
2299 { 2242 {
2300 d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land)); 2243 d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
@@ -2415,12 +2358,13 @@ namespace OpenSim.Region.Physics.OdePlugin
2415 thickness, wrap); 2358 thickness, wrap);
2416 2359
2417// d.GeomUbitTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); 2360// d.GeomUbitTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
2418 GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1); 2361 GroundGeom = d.CreateUbitTerrain(GroundSpace, HeightmapData, 1);
2419 if (GroundGeom != IntPtr.Zero) 2362 if (GroundGeom != IntPtr.Zero)
2420 { 2363 {
2421 d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land)); 2364 d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
2422 d.GeomSetCollideBits(GroundGeom, 0); 2365 d.GeomSetCollideBits(GroundGeom, 0);
2423 2366
2367
2424 PhysicsActor pa = new NullPhysicsActor(); 2368 PhysicsActor pa = new NullPhysicsActor();
2425 pa.Name = "Terrain"; 2369 pa.Name = "Terrain";
2426 pa.PhysicsActorType = (int)ActorTypes.Ground; 2370 pa.PhysicsActorType = (int)ActorTypes.Ground;
@@ -2599,6 +2543,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2599*/ 2543*/
2600 public override void Dispose() 2544 public override void Dispose()
2601 { 2545 {
2546 if (m_meshWorker != null)
2547 m_meshWorker.Stop();
2548
2602 lock (OdeLock) 2549 lock (OdeLock)
2603 { 2550 {
2604 m_rayCastManager.Dispose(); 2551 m_rayCastManager.Dispose();
@@ -2633,6 +2580,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2633 d.GeomDestroy(GroundGeom); 2580 d.GeomDestroy(GroundGeom);
2634 } 2581 }
2635 2582
2583
2636 RegionTerrain.Clear(); 2584 RegionTerrain.Clear();
2637 2585
2638 if (TerrainHeightFieldHeightsHandlers.Count > 0) 2586 if (TerrainHeightFieldHeightsHandlers.Count > 0)