aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs823
1 files changed, 231 insertions, 592 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index f2f4725..cbe129a 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.Physics.OdePlugin
79 private bool m_lastdoneSelected; 79 private bool m_lastdoneSelected;
80 internal bool m_outbounds; 80 internal bool m_outbounds;
81 81
82 private Quaternion m_lastorientation = new Quaternion(); 82 private Quaternion m_lastorientation;
83 private Quaternion _orientation; 83 private Quaternion _orientation;
84 84
85 private Vector3 _position; 85 private Vector3 _position;
@@ -91,33 +91,30 @@ namespace OpenSim.Region.Physics.OdePlugin
91 private Vector3 _size; 91 private Vector3 _size;
92 private Vector3 _acceleration; 92 private Vector3 _acceleration;
93 private Vector3 m_angularlock = Vector3.One; 93 private Vector3 m_angularlock = Vector3.One;
94 private IntPtr Amotor = IntPtr.Zero; 94 private IntPtr Amotor;
95 95
96 private Vector3 m_force; 96 private Vector3 m_force;
97 private Vector3 m_forceacc; 97 private Vector3 m_forceacc;
98 private Vector3 m_angularForceacc; 98 private Vector3 m_angularForceacc;
99 99
100 private float m_invTimeStep = 50.0f; 100 private float m_invTimeStep;
101 private float m_timeStep = .02f; 101 private float m_timeStep;
102 102
103 private Vector3 m_PIDTarget; 103 private Vector3 m_PIDTarget;
104 private float m_PIDTau; 104 private float m_PIDTau;
105 private bool m_usePID; 105 private bool m_usePID;
106 106
107 // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
108 // and are for non-VEHICLES only.
109
110 private float m_PIDHoverHeight; 107 private float m_PIDHoverHeight;
111 private float m_PIDHoverTau; 108 private float m_PIDHoverTau;
112 private bool m_useHoverPID; 109 private bool m_useHoverPID;
113 private PIDHoverType m_PIDHoverType = PIDHoverType.Ground; 110 private PIDHoverType m_PIDHoverType;
114 private float m_targetHoverHeight; 111 private float m_targetHoverHeight;
115 private float m_groundHeight; 112 private float m_groundHeight;
116 private float m_waterHeight; 113 private float m_waterHeight;
117 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. 114 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
118 115
119 private int body_autodisable_frames = 5; 116 private int body_autodisable_frames;
120 public int bodydisablecontrol = 0; 117 public int bodydisablecontrol;
121 118
122 119
123 // Default we're a Geometry 120 // Default we're a Geometry
@@ -147,12 +144,16 @@ namespace OpenSim.Region.Physics.OdePlugin
147 private IMesh m_mesh; 144 private IMesh m_mesh;
148 private object m_meshlock = new object(); 145 private object m_meshlock = new object();
149 private PrimitiveBaseShape _pbs; 146 private PrimitiveBaseShape _pbs;
147
148 private UUID? m_assetID;
149 private AssetState m_assetState;
150
150 public OdeScene _parent_scene; 151 public OdeScene _parent_scene;
151 152
152 /// <summary> 153 /// <summary>
153 /// The physics space which contains prim geometry 154 /// The physics space which contains prim geometry
154 /// </summary> 155 /// </summary>
155 public IntPtr m_targetSpace = IntPtr.Zero; 156 public IntPtr m_targetSpace;
156 157
157 public IntPtr prim_geom; 158 public IntPtr prim_geom;
158 public IntPtr _triMeshData; 159 public IntPtr _triMeshData;
@@ -166,27 +167,32 @@ namespace OpenSim.Region.Physics.OdePlugin
166 167
167 public IntPtr collide_geom; // for objects: geom if single prim space it linkset 168 public IntPtr collide_geom; // for objects: geom if single prim space it linkset
168 169
169 private float m_density = 10.000006836f; // Aluminum g/cm3; 170 private float m_density;
170 private byte m_shapetype; 171 private byte m_shapetype;
171 public bool _zeroFlag; 172 public bool _zeroFlag;
172 private bool m_lastUpdateSent; 173 private bool m_lastUpdateSent;
173 174
174 public IntPtr Body = IntPtr.Zero; 175 public IntPtr Body;
175 176
176 private Vector3 _target_velocity; 177 private Vector3 _target_velocity;
177 178
178 public Vector3 primOOBsize; // prim real dimensions from mesh 179 public Vector3 m_OBBOffset;
179 public Vector3 primOOBoffset; // its centroid out of mesh or rest aabb 180 public Vector3 m_OBB;
180 public float primOOBradiusSQ; 181 public float primOOBradiusSQ;
182
183 private bool m_hasOBB = true;
184
185 private float m_physCost;
186 private float m_streamCost;
187
181 public d.Mass primdMass; // prim inertia information on it's own referencial 188 public d.Mass primdMass; // prim inertia information on it's own referencial
182 float primMass; // prim own mass 189 float primMass; // prim own mass
183 float primVolume; // prim own volume; 190 float primVolume; // prim own volume;
184 float _mass; // object mass acording to case 191 float _mass; // object mass acording to case
185 private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb
186 192
187 public int givefakepos = 0; 193 public int givefakepos;
188 private Vector3 fakepos; 194 private Vector3 fakepos;
189 public int givefakeori = 0; 195 public int givefakeori;
190 private Quaternion fakeori; 196 private Quaternion fakeori;
191 197
192 private int m_eventsubscription; 198 private int m_eventsubscription;
@@ -394,7 +400,7 @@ namespace OpenSim.Region.Physics.OdePlugin
394 { 400 {
395 if (value.IsFinite()) 401 if (value.IsFinite())
396 { 402 {
397 AddChange(changes.Size, value); 403 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, value, m_shapetype);
398 } 404 }
399 else 405 else
400 { 406 {
@@ -464,7 +470,7 @@ namespace OpenSim.Region.Physics.OdePlugin
464 q.Z = dq.Z; 470 q.Z = dq.Z;
465 q.W = dq.W; 471 q.W = dq.W;
466 472
467 Vector3 Ptot = primOOBoffset * q; 473 Vector3 Ptot = m_OBBOffset * q;
468 dtmp = d.GeomGetPosition(prim_geom); 474 dtmp = d.GeomGetPosition(prim_geom);
469 Ptot.X += dtmp.X; 475 Ptot.X += dtmp.X;
470 Ptot.Y += dtmp.Y; 476 Ptot.Y += dtmp.Y;
@@ -504,7 +510,7 @@ namespace OpenSim.Region.Physics.OdePlugin
504 { 510 {
505 get 511 get
506 { 512 {
507 return primOOBsize; 513 return m_OBB;
508 } 514 }
509 } 515 }
510 516
@@ -512,7 +518,7 @@ namespace OpenSim.Region.Physics.OdePlugin
512 { 518 {
513 get 519 get
514 { 520 {
515 return primOOBoffset; 521 return m_OBBOffset;
516 } 522 }
517 } 523 }
518 524
@@ -528,7 +534,8 @@ namespace OpenSim.Region.Physics.OdePlugin
528 { 534 {
529 set 535 set
530 { 536 {
531 AddChange(changes.Shape, value); 537// AddChange(changes.Shape, value);
538 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, value, _size, m_shapetype);
532 } 539 }
533 } 540 }
534 541
@@ -541,11 +548,10 @@ namespace OpenSim.Region.Physics.OdePlugin
541 set 548 set
542 { 549 {
543 m_shapetype = value; 550 m_shapetype = value;
544 AddChange(changes.Shape, null); 551 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, _size, value);
545 } 552 }
546 } 553 }
547 554
548
549 public override Vector3 Velocity 555 public override Vector3 Velocity
550 { 556 {
551 get 557 get
@@ -1012,7 +1018,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1012 m_invTimeStep = 1f / m_timeStep; 1018 m_invTimeStep = 1f / m_timeStep;
1013 1019
1014 m_density = parent_scene.geomDefaultDensity; 1020 m_density = parent_scene.geomDefaultDensity;
1015 // m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
1016 body_autodisable_frames = parent_scene.bodyFramesAutoDisable; 1021 body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
1017 1022
1018 prim_geom = IntPtr.Zero; 1023 prim_geom = IntPtr.Zero;
@@ -1064,7 +1069,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1064 m_colliderfilter = 0; 1069 m_colliderfilter = 0;
1065 m_NoColide = false; 1070 m_NoColide = false;
1066 1071
1067 hasOOBoffsetFromMesh = false;
1068 _triMeshData = IntPtr.Zero; 1072 _triMeshData = IntPtr.Zero;
1069 1073
1070 m_shapetype = _shapeType; 1074 m_shapetype = _shapeType;
@@ -1079,27 +1083,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1079 mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; 1083 mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
1080 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; 1084 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
1081 1085
1082 CalcPrimBodyData();
1083
1084 m_mesh = null;
1085 if (_parent_scene.needsMeshing(pbs) && (pbs.SculptData.Length > 0))
1086 {
1087 bool convex;
1088 int clod = (int)LevelOfDetail.High;
1089 if (m_shapetype == 0)
1090 convex = false;
1091 else
1092 {
1093 convex = true;
1094 if (_pbs.SculptType != (byte)SculptType.Mesh)
1095 clod = (int)LevelOfDetail.Low;
1096 }
1097 m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
1098 }
1099
1100 m_building = true; // control must set this to false when done 1086 m_building = true; // control must set this to false when done
1101 1087
1102 AddChange(changes.Add, null); 1088 _parent_scene.m_meshWorker.NewActorPhysRep(this, _pbs, _size, m_shapetype);
1103 } 1089 }
1104 1090
1105 private void resetCollisionAccounting() 1091 private void resetCollisionAccounting()
@@ -1323,80 +1309,34 @@ namespace OpenSim.Region.Physics.OdePlugin
1323 } 1309 }
1324 } 1310 }
1325 1311
1326 private bool setMesh(OdeScene parent_scene) 1312 private bool GetMeshGeom()
1327 { 1313 {
1328 IntPtr vertices, indices; 1314 IntPtr vertices, indices;
1329 int vertexCount, indexCount; 1315 int vertexCount, indexCount;
1330 int vertexStride, triStride; 1316 int vertexStride, triStride;
1331 1317
1332 if (Body != IntPtr.Zero) 1318 IMesh mesh = m_mesh;
1333 {
1334 if (childPrim)
1335 {
1336 if (_parent != null)
1337 {
1338 OdePrim parent = (OdePrim)_parent;
1339 parent.ChildDelink(this, false);
1340 }
1341 }
1342 else
1343 {
1344 DestroyBody();
1345 }
1346 }
1347
1348 IMesh mesh = null;
1349
1350 lock (m_meshlock)
1351 {
1352 if (m_mesh == null)
1353 {
1354 bool convex;
1355 int clod = (int)LevelOfDetail.High;
1356
1357 if (m_shapetype == 0)
1358 convex = false;
1359 else
1360 {
1361 convex = true;
1362 if (_pbs.SculptType != (byte)SculptType.Mesh)
1363 clod = (int)LevelOfDetail.Low;
1364 }
1365
1366 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
1367 }
1368 else
1369 {
1370 mesh = m_mesh;
1371 }
1372
1373 if (mesh == null)
1374 {
1375 m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z);
1376 return false;
1377 }
1378
1379
1380 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
1381 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
1382 1319
1383 if (vertexCount == 0 || indexCount == 0) 1320 if (mesh == null)
1384 { 1321 return false;
1385 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}",
1386 Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString());
1387 mesh.releaseSourceMeshData();
1388 return false;
1389 }
1390 1322
1391 primOOBoffset = mesh.GetCentroid(); 1323 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
1392 hasOOBoffsetFromMesh = true; 1324 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
1393 1325
1394 mesh.releaseSourceMeshData(); 1326 if (vertexCount == 0 || indexCount == 0)
1395 m_mesh = mesh; 1327 {
1328 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on OdePrim {0} mesh UUID {1}",
1329 Name, _pbs.SculptTexture.ToString());
1330 m_hasOBB = false;
1331 m_OBBOffset = Vector3.Zero;
1332 m_OBB = _size * 0.5f;
1333 m_physCost = 0.1f;
1334 m_streamCost = 1.0f;
1335 _parent_scene.mesher.ReleaseMesh(mesh);
1336 m_assetState = AssetState.AssetFailed;
1337 m_mesh = null;
1338 return false;
1396 } 1339 }
1397
1398 IntPtr geo = IntPtr.Zero;
1399
1400 try 1340 try
1401 { 1341 {
1402 _triMeshData = d.GeomTriMeshDataCreate(); 1342 _triMeshData = d.GeomTriMeshDataCreate();
@@ -1404,8 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1404 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 1344 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1405 d.GeomTriMeshDataPreprocess(_triMeshData); 1345 d.GeomTriMeshDataPreprocess(_triMeshData);
1406 1346
1407 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1347 prim_geom = d.CreateTriMesh(IntPtr.Zero, _triMeshData, null, null, null);
1408 geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
1409 } 1348 }
1410 1349
1411 catch (Exception e) 1350 catch (Exception e)
@@ -1413,85 +1352,56 @@ namespace OpenSim.Region.Physics.OdePlugin
1413 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e); 1352 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e);
1414 if (_triMeshData != IntPtr.Zero) 1353 if (_triMeshData != IntPtr.Zero)
1415 { 1354 {
1416 d.GeomTriMeshDataDestroy(_triMeshData); 1355 try
1417 _triMeshData = IntPtr.Zero;
1418 }
1419 return false;
1420 }
1421
1422 SetGeom(geo);
1423 return true;
1424 }
1425
1426 private void SetGeom(IntPtr geom)
1427 {
1428 prim_geom = geom;
1429 //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
1430 if (prim_geom != IntPtr.Zero)
1431 {
1432
1433 if (m_NoColide)
1434 {
1435 d.GeomSetCategoryBits(prim_geom, 0);
1436 if (m_isphysical)
1437 { 1356 {
1438 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land); 1357 d.GeomTriMeshDataDestroy(_triMeshData);
1439 } 1358 }
1440 else 1359 catch
1441 { 1360 {
1442 d.GeomSetCollideBits(prim_geom, 0);
1443 d.GeomDisable(prim_geom);
1444 } 1361 }
1445 } 1362 }
1446 else 1363 _triMeshData = IntPtr.Zero;
1447 { 1364 prim_geom = IntPtr.Zero;
1448 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1449 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1450 }
1451
1452 CalcPrimBodyData();
1453
1454 _parent_scene.actor_name_map[prim_geom] = this;
1455 1365
1366 m_hasOBB = false;
1367 m_OBBOffset = Vector3.Zero;
1368 m_OBB = _size * 0.5f;
1369 m_physCost = 0.1f;
1370 m_streamCost = 1.0f;
1371 _parent_scene.mesher.ReleaseMesh(mesh);
1372 m_assetState = AssetState.AssetFailed;
1373 m_mesh = null;
1374 return false;
1456 } 1375 }
1457 else 1376 return true;
1458 m_log.Warn("Setting bad Geom");
1459 } 1377 }
1460 1378
1461
1462 /// <summary>
1463 /// Create a geometry for the given mesh in the given target space.
1464 /// </summary>
1465 /// <param name="m_targetSpace"></param>
1466 /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param>
1467 private void CreateGeom() 1379 private void CreateGeom()
1468 { 1380 {
1469 if (_triMeshData != IntPtr.Zero) 1381 IntPtr geo = IntPtr.Zero;
1470 { 1382 bool hasMesh = false;
1471 d.GeomTriMeshDataDestroy(_triMeshData);
1472 _triMeshData = IntPtr.Zero;
1473 }
1474 1383
1475 bool haveMesh = false;
1476 hasOOBoffsetFromMesh = false;
1477 m_NoColide = false; 1384 m_NoColide = false;
1478 1385
1479 if (_parent_scene.needsMeshing(_pbs)) 1386 if (m_assetState == AssetState.AssetFailed)
1387 m_NoColide = true;
1388
1389 else if (m_mesh != null)
1480 { 1390 {
1481 haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims 1391 if (GetMeshGeom())
1482 if (!haveMesh) 1392 hasMesh = true;
1393 else
1483 m_NoColide = true; 1394 m_NoColide = true;
1484 } 1395 }
1485 1396
1486 if (!haveMesh) 1397 if (!hasMesh)
1487 { 1398 {
1488 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 1399 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
1489 && _size.X == _size.Y && _size.Y == _size.Z) 1400 && _size.X == _size.Y && _size.Y == _size.Z)
1490 { // it's a sphere 1401 { // it's a sphere
1491 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1492 try 1402 try
1493 { 1403 {
1494 SetGeom(d.CreateSphere(m_targetSpace, _size.X * 0.5f)); 1404 geo = d.CreateSphere(IntPtr.Zero, _size.X * 0.5f);
1495 } 1405 }
1496 catch (Exception e) 1406 catch (Exception e)
1497 { 1407 {
@@ -1501,11 +1411,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1501 } 1411 }
1502 else 1412 else
1503 {// do it as a box 1413 {// do it as a box
1504 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1505 try 1414 try
1506 { 1415 {
1507 //Console.WriteLine(" CreateGeom 4"); 1416 geo = d.CreateBox(IntPtr.Zero, _size.X, _size.Y, _size.Z);
1508 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1509 } 1417 }
1510 catch (Exception e) 1418 catch (Exception e)
1511 { 1419 {
@@ -1513,19 +1421,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1513 return; 1421 return;
1514 } 1422 }
1515 } 1423 }
1424 m_physCost = 0.1f;
1425 m_streamCost = 1.0f;
1426 prim_geom = geo;
1516 } 1427 }
1517 } 1428 }
1518 1429
1519 /// <summary>
1520 /// Set a new geometry for this prim.
1521 /// </summary>
1522 /// <param name="geom"></param>
1523 private void RemoveGeom() 1430 private void RemoveGeom()
1524 { 1431 {
1525 if (prim_geom != IntPtr.Zero) 1432 if (prim_geom != IntPtr.Zero)
1526 { 1433 {
1527// _parent_scene.geom_name_map.Remove(prim_geom);
1528 _parent_scene.actor_name_map.Remove(prim_geom); 1434 _parent_scene.actor_name_map.Remove(prim_geom);
1435
1529 try 1436 try
1530 { 1437 {
1531 d.GeomDestroy(prim_geom); 1438 d.GeomDestroy(prim_geom);
@@ -1534,11 +1441,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1534 d.GeomTriMeshDataDestroy(_triMeshData); 1441 d.GeomTriMeshDataDestroy(_triMeshData);
1535 _triMeshData = IntPtr.Zero; 1442 _triMeshData = IntPtr.Zero;
1536 } 1443 }
1537
1538 } 1444 }
1539
1540
1541 // catch (System.AccessViolationException)
1542 catch (Exception e) 1445 catch (Exception e)
1543 { 1446 {
1544 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e); 1447 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e);
@@ -1546,29 +1449,26 @@ namespace OpenSim.Region.Physics.OdePlugin
1546 1449
1547 prim_geom = IntPtr.Zero; 1450 prim_geom = IntPtr.Zero;
1548 collide_geom = IntPtr.Zero; 1451 collide_geom = IntPtr.Zero;
1452 m_targetSpace = IntPtr.Zero;
1549 } 1453 }
1550 else 1454 else
1551 { 1455 {
1552 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name); 1456 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name);
1553 } 1457 }
1554 1458
1555 if (m_mesh != null) 1459 lock (m_meshlock)
1556 { 1460 {
1557 _parent_scene.mesher.ReleaseMesh(m_mesh); 1461 if (m_mesh != null)
1558 m_mesh = null; 1462 {
1463 _parent_scene.mesher.ReleaseMesh(m_mesh);
1464 m_mesh = null;
1465 }
1559 } 1466 }
1560 1467
1561 Body = IntPtr.Zero; 1468 Body = IntPtr.Zero;
1562 hasOOBoffsetFromMesh = false; 1469 m_hasOBB = false;
1563 } 1470 }
1564/* 1471
1565 private void ChildSetGeom(OdePrim odePrim)
1566 {
1567 // well..
1568 DestroyBody();
1569 MakeBody();
1570 }
1571*/
1572 //sets non physical prim m_targetSpace to right space in spaces grid for static prims 1472 //sets non physical prim m_targetSpace to right space in spaces grid for static prims
1573 // should only be called for non physical prims unless they are becoming non physical 1473 // should only be called for non physical prims unless they are becoming non physical
1574 private void SetInStaticSpace(OdePrim prim) 1474 private void SetInStaticSpace(OdePrim prim)
@@ -1631,9 +1531,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1631 1531
1632 if (Body != IntPtr.Zero) 1532 if (Body != IntPtr.Zero)
1633 { 1533 {
1634// d.BodyDestroy(Body);
1635// Body = IntPtr.Zero;
1636 // do a more complet destruction
1637 DestroyBody(); 1534 DestroyBody();
1638 m_log.Warn("[PHYSICS]: MakeBody called having a body"); 1535 m_log.Warn("[PHYSICS]: MakeBody called having a body");
1639 } 1536 }
@@ -2143,339 +2040,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2143 2040
2144 #region Mass Calculation 2041 #region Mass Calculation
2145 2042
2146 private float CalculatePrimVolume() 2043 private void UpdatePrimBodyData()
2147 {
2148 float volume = _size.X * _size.Y * _size.Z; // default
2149 float tmp;
2150
2151 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
2152 float hollowVolume = hollowAmount * hollowAmount;
2153
2154 switch (_pbs.ProfileShape)
2155 {
2156 case ProfileShape.Square:
2157 // default box
2158
2159 if (_pbs.PathCurve == (byte)Extrusion.Straight)
2160 {
2161 if (hollowAmount > 0.0)
2162 {
2163 switch (_pbs.HollowShape)
2164 {
2165 case HollowShape.Square:
2166 case HollowShape.Same:
2167 break;
2168
2169 case HollowShape.Circle:
2170
2171 hollowVolume *= 0.78539816339f;
2172 break;
2173
2174 case HollowShape.Triangle:
2175
2176 hollowVolume *= (0.5f * .5f);
2177 break;
2178
2179 default:
2180 hollowVolume = 0;
2181 break;
2182 }
2183 volume *= (1.0f - hollowVolume);
2184 }
2185 }
2186
2187 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2188 {
2189 //a tube
2190
2191 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
2192 tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY);
2193 volume -= volume * tmp * tmp;
2194
2195 if (hollowAmount > 0.0)
2196 {
2197 hollowVolume *= hollowAmount;
2198
2199 switch (_pbs.HollowShape)
2200 {
2201 case HollowShape.Square:
2202 case HollowShape.Same:
2203 break;
2204
2205 case HollowShape.Circle:
2206 hollowVolume *= 0.78539816339f;
2207 break;
2208
2209 case HollowShape.Triangle:
2210 hollowVolume *= 0.5f * 0.5f;
2211 break;
2212 default:
2213 hollowVolume = 0;
2214 break;
2215 }
2216 volume *= (1.0f - hollowVolume);
2217 }
2218 }
2219
2220 break;
2221
2222 case ProfileShape.Circle:
2223
2224 if (_pbs.PathCurve == (byte)Extrusion.Straight)
2225 {
2226 volume *= 0.78539816339f; // elipse base
2227
2228 if (hollowAmount > 0.0)
2229 {
2230 switch (_pbs.HollowShape)
2231 {
2232 case HollowShape.Same:
2233 case HollowShape.Circle:
2234 break;
2235
2236 case HollowShape.Square:
2237 hollowVolume *= 0.5f * 2.5984480504799f;
2238 break;
2239
2240 case HollowShape.Triangle:
2241 hollowVolume *= .5f * 1.27323954473516f;
2242 break;
2243
2244 default:
2245 hollowVolume = 0;
2246 break;
2247 }
2248 volume *= (1.0f - hollowVolume);
2249 }
2250 }
2251
2252 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2253 {
2254 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
2255 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
2256 volume *= (1.0f - tmp * tmp);
2257
2258 if (hollowAmount > 0.0)
2259 {
2260
2261 // calculate the hollow volume by it's shape compared to the prim shape
2262 hollowVolume *= hollowAmount;
2263
2264 switch (_pbs.HollowShape)
2265 {
2266 case HollowShape.Same:
2267 case HollowShape.Circle:
2268 break;
2269
2270 case HollowShape.Square:
2271 hollowVolume *= 0.5f * 2.5984480504799f;
2272 break;
2273
2274 case HollowShape.Triangle:
2275 hollowVolume *= .5f * 1.27323954473516f;
2276 break;
2277
2278 default:
2279 hollowVolume = 0;
2280 break;
2281 }
2282 volume *= (1.0f - hollowVolume);
2283 }
2284 }
2285 break;
2286
2287 case ProfileShape.HalfCircle:
2288 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2289 {
2290 volume *= 0.5236f;
2291
2292 if (hollowAmount > 0.0)
2293 {
2294 hollowVolume *= hollowAmount;
2295
2296 switch (_pbs.HollowShape)
2297 {
2298 case HollowShape.Circle:
2299 case HollowShape.Triangle: // diference in sl is minor and odd
2300 case HollowShape.Same:
2301 break;
2302
2303 case HollowShape.Square:
2304 hollowVolume *= 0.909f;
2305 break;
2306
2307 // case HollowShape.Triangle:
2308 // hollowVolume *= .827f;
2309 // break;
2310 default:
2311 hollowVolume = 0;
2312 break;
2313 }
2314 volume *= (1.0f - hollowVolume);
2315 }
2316
2317 }
2318 break;
2319
2320 case ProfileShape.EquilateralTriangle:
2321
2322 if (_pbs.PathCurve == (byte)Extrusion.Straight)
2323 {
2324 volume *= 0.32475953f;
2325
2326 if (hollowAmount > 0.0)
2327 {
2328
2329 // calculate the hollow volume by it's shape compared to the prim shape
2330 switch (_pbs.HollowShape)
2331 {
2332 case HollowShape.Same:
2333 case HollowShape.Triangle:
2334 hollowVolume *= .25f;
2335 break;
2336
2337 case HollowShape.Square:
2338 hollowVolume *= 0.499849f * 3.07920140172638f;
2339 break;
2340
2341 case HollowShape.Circle:
2342 // Hollow shape is a perfect cyllinder in respect to the cube's scale
2343 // Cyllinder hollow volume calculation
2344
2345 hollowVolume *= 0.1963495f * 3.07920140172638f;
2346 break;
2347
2348 default:
2349 hollowVolume = 0;
2350 break;
2351 }
2352 volume *= (1.0f - hollowVolume);
2353 }
2354 }
2355 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2356 {
2357 volume *= 0.32475953f;
2358 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
2359 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
2360 volume *= (1.0f - tmp * tmp);
2361
2362 if (hollowAmount > 0.0)
2363 {
2364
2365 hollowVolume *= hollowAmount;
2366
2367 switch (_pbs.HollowShape)
2368 {
2369 case HollowShape.Same:
2370 case HollowShape.Triangle:
2371 hollowVolume *= .25f;
2372 break;
2373
2374 case HollowShape.Square:
2375 hollowVolume *= 0.499849f * 3.07920140172638f;
2376 break;
2377
2378 case HollowShape.Circle:
2379
2380 hollowVolume *= 0.1963495f * 3.07920140172638f;
2381 break;
2382
2383 default:
2384 hollowVolume = 0;
2385 break;
2386 }
2387 volume *= (1.0f - hollowVolume);
2388 }
2389 }
2390 break;
2391
2392 default:
2393 break;
2394 }
2395
2396 float taperX1;
2397 float taperY1;
2398 float taperX;
2399 float taperY;
2400 float pathBegin;
2401 float pathEnd;
2402 float profileBegin;
2403 float profileEnd;
2404
2405 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
2406 {
2407 taperX1 = _pbs.PathScaleX * 0.01f;
2408 if (taperX1 > 1.0f)
2409 taperX1 = 2.0f - taperX1;
2410 taperX = 1.0f - taperX1;
2411
2412 taperY1 = _pbs.PathScaleY * 0.01f;
2413 if (taperY1 > 1.0f)
2414 taperY1 = 2.0f - taperY1;
2415 taperY = 1.0f - taperY1;
2416 }
2417 else
2418 {
2419 taperX = _pbs.PathTaperX * 0.01f;
2420 if (taperX < 0.0f)
2421 taperX = -taperX;
2422 taperX1 = 1.0f - taperX;
2423
2424 taperY = _pbs.PathTaperY * 0.01f;
2425 if (taperY < 0.0f)
2426 taperY = -taperY;
2427 taperY1 = 1.0f - taperY;
2428 }
2429
2430 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
2431
2432 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
2433 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
2434 volume *= (pathEnd - pathBegin);
2435
2436 // this is crude aproximation
2437 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
2438 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
2439 volume *= (profileEnd - profileBegin);
2440
2441 return volume;
2442 }
2443
2444
2445 private void CalcPrimBodyData()
2446 { 2044 {
2447 float volume; 2045 primMass = m_density * primVolume;
2448
2449 if (prim_geom == IntPtr.Zero)
2450 {
2451 // Ubit let's have a initial basic OOB
2452 primOOBsize.X = _size.X;
2453 primOOBsize.Y = _size.Y;
2454 primOOBsize.Z = _size.Z;
2455 primOOBoffset = Vector3.Zero;
2456 }
2457 else
2458 {
2459 d.AABB AABB;
2460 d.GeomGetAABB(prim_geom, out AABB); // get the AABB from engine geom
2461
2462 primOOBsize.X = (AABB.MaxX - AABB.MinX);
2463 primOOBsize.Y = (AABB.MaxY - AABB.MinY);
2464 primOOBsize.Z = (AABB.MaxZ - AABB.MinZ);
2465 if (!hasOOBoffsetFromMesh)
2466 {
2467 primOOBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f;
2468 primOOBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f;
2469 primOOBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f;
2470 }
2471 }
2472
2473 // also its own inertia and mass
2474 // keep using basic shape mass for now
2475 volume = CalculatePrimVolume();
2476
2477 primVolume = volume;
2478 primMass = m_density * volume;
2479 2046
2480 if (primMass <= 0) 2047 if (primMass <= 0)
2481 primMass = 0.0001f;//ckrinke: Mass must be greater then zero. 2048 primMass = 0.0001f;//ckrinke: Mass must be greater then zero.
@@ -2484,18 +2051,16 @@ namespace OpenSim.Region.Physics.OdePlugin
2484 2051
2485 _mass = primMass; // just in case 2052 _mass = primMass; // just in case
2486 2053
2487 d.MassSetBoxTotal(out primdMass, primMass, primOOBsize.X, primOOBsize.Y, primOOBsize.Z); 2054 d.MassSetBoxTotal(out primdMass, primMass, m_OBB.X, m_OBB.Y, m_OBB.Z);
2488 2055
2489 d.MassTranslate(ref primdMass, 2056 d.MassTranslate(ref primdMass,
2490 primOOBoffset.X, 2057 m_OBBOffset.X,
2491 primOOBoffset.Y, 2058 m_OBBOffset.Y,
2492 primOOBoffset.Z); 2059 m_OBBOffset.Z);
2493 2060
2494 primOOBsize *= 0.5f; // let obb size be a corner coords 2061 primOOBradiusSQ = m_OBBOffset.LengthSquared();
2495 primOOBradiusSQ = primOOBsize.LengthSquared();
2496 } 2062 }
2497 2063
2498
2499 #endregion 2064 #endregion
2500 2065
2501 2066
@@ -2684,27 +2249,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2684 2249
2685 private void changeadd() 2250 private void changeadd()
2686 { 2251 {
2687 CreateGeom();
2688
2689 if (prim_geom != IntPtr.Zero)
2690 {
2691 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2692 d.Quaternion myrot = new d.Quaternion();
2693 myrot.X = _orientation.X;
2694 myrot.Y = _orientation.Y;
2695 myrot.Z = _orientation.Z;
2696 myrot.W = _orientation.W;
2697 d.GeomSetQuaternion(prim_geom, ref myrot);
2698
2699 if (!m_isphysical)
2700 {
2701 SetInStaticSpace(this);
2702 UpdateCollisionCatFlags();
2703 ApplyCollisionCatFlags();
2704 }
2705 else
2706 MakeBody();
2707 }
2708 } 2252 }
2709 2253
2710 private void changeAngularLock(Vector3 newLock) 2254 private void changeAngularLock(Vector3 newLock)
@@ -3148,7 +2692,73 @@ namespace OpenSim.Region.Physics.OdePlugin
3148 resetCollisionAccounting(); 2692 resetCollisionAccounting();
3149 } 2693 }
3150 2694
3151 private void changeprimsizeshape() 2695 private void changeSize(Vector3 newSize)
2696 {
2697 }
2698
2699 private void changeShape(PrimitiveBaseShape newShape)
2700 {
2701 }
2702
2703
2704
2705 private void changeAddPhysRep(ODEPhysRepData repData)
2706 {
2707 _size = repData.size; //??
2708 _pbs = repData.pbs;
2709 m_shapetype = repData.shapetype;
2710
2711 m_mesh = repData.mesh;
2712
2713 m_assetID = repData.assetID;
2714 m_assetState = repData.assetState;
2715
2716 m_hasOBB = repData.hasOBB;
2717 m_OBBOffset = repData.OBBOffset;
2718 m_OBB = repData.OBB;
2719
2720// m_NoColide = repData.NoColide;
2721 m_physCost = repData.physCost;
2722 m_streamCost = repData.streamCost;
2723
2724 primVolume = repData.volume;
2725
2726 CreateGeom();
2727
2728 if (prim_geom != IntPtr.Zero)
2729 {
2730 UpdatePrimBodyData();
2731
2732 _parent_scene.actor_name_map[prim_geom] = this;
2733
2734 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2735 d.Quaternion myrot = new d.Quaternion();
2736 myrot.X = _orientation.X;
2737 myrot.Y = _orientation.Y;
2738 myrot.Z = _orientation.Z;
2739 myrot.W = _orientation.W;
2740 d.GeomSetQuaternion(prim_geom, ref myrot);
2741
2742 if (!m_isphysical)
2743 {
2744 SetInStaticSpace(this);
2745 UpdateCollisionCatFlags();
2746 ApplyCollisionCatFlags();
2747 }
2748 else
2749 MakeBody();
2750
2751 if (m_assetState == AssetState.needAsset)
2752 {
2753 repData.size = _size;
2754 repData.pbs = _pbs;
2755 repData.shapetype = m_shapetype;
2756 _parent_scene.m_meshWorker.RequestMeshAsset(repData);
2757 }
2758 }
2759 }
2760
2761 private void changePhysRepData(ODEPhysRepData repData)
3152 { 2762 {
3153 CheckDelaySelect(); 2763 CheckDelaySelect();
3154 2764
@@ -3170,19 +2780,41 @@ namespace OpenSim.Region.Physics.OdePlugin
3170 2780
3171 RemoveGeom(); 2781 RemoveGeom();
3172 2782
3173 // we don't need to do space calculation because the client sends a position update also. 2783 _size = repData.size;
3174 if (_size.X <= 0) 2784 _pbs = repData.pbs;
3175 _size.X = 0.01f; 2785 m_shapetype = repData.shapetype;
3176 if (_size.Y <= 0) 2786
3177 _size.Y = 0.01f; 2787 m_mesh = repData.mesh;
3178 if (_size.Z <= 0) 2788
3179 _size.Z = 0.01f; 2789 m_assetID = repData.assetID;
3180 // Construction of new prim 2790 m_assetState = repData.assetState;
2791
2792 m_hasOBB = repData.hasOBB;
2793 m_OBBOffset = repData.OBBOffset;
2794 m_OBB = repData.OBB;
2795
2796 m_physCost = repData.physCost;
2797 m_streamCost = repData.streamCost;
2798
2799 primVolume = repData.volume;
3181 2800
3182 CreateGeom(); 2801 CreateGeom();
3183 2802
3184 if (prim_geom != IntPtr.Zero) 2803 if (prim_geom != IntPtr.Zero)
3185 { 2804 {
2805 m_targetSpace = IntPtr.Zero;
2806
2807 UpdatePrimBodyData();
2808
2809 try
2810 {
2811 _parent_scene.actor_name_map[prim_geom] = this;
2812 }
2813 catch
2814 {
2815
2816 }
2817
3186 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 2818 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3187 d.Quaternion myrot = new d.Quaternion(); 2819 d.Quaternion myrot = new d.Quaternion();
3188 myrot.X = _orientation.X; 2820 myrot.X = _orientation.X;
@@ -3190,41 +2822,37 @@ namespace OpenSim.Region.Physics.OdePlugin
3190 myrot.Z = _orientation.Z; 2822 myrot.Z = _orientation.Z;
3191 myrot.W = _orientation.W; 2823 myrot.W = _orientation.W;
3192 d.GeomSetQuaternion(prim_geom, ref myrot); 2824 d.GeomSetQuaternion(prim_geom, ref myrot);
3193 }
3194 2825
3195 if (m_isphysical) 2826
3196 { 2827 if (m_isphysical)
3197 if (chp)
3198 { 2828 {
3199 if (parent != null) 2829 if (chp)
3200 { 2830 {
3201 parent.MakeBody(); 2831 if (parent != null)
2832 {
2833 parent.MakeBody();
2834 }
3202 } 2835 }
2836 else
2837 MakeBody();
3203 } 2838 }
2839
3204 else 2840 else
3205 MakeBody(); 2841 {
3206 } 2842 SetInStaticSpace(this);
2843 UpdateCollisionCatFlags();
2844 ApplyCollisionCatFlags();
2845 }
3207 2846
3208 else 2847 resetCollisionAccounting();
3209 { 2848 if (m_assetState == AssetState.needAsset)
3210 UpdateCollisionCatFlags(); 2849 {
3211 ApplyCollisionCatFlags(); 2850 repData.size = _size;
2851 repData.pbs = _pbs;
2852 repData.shapetype = m_shapetype;
2853 _parent_scene.m_meshWorker.RequestMeshAsset(repData);
2854 }
3212 } 2855 }
3213
3214 resetCollisionAccounting();
3215 }
3216
3217 private void changeSize(Vector3 newSize)
3218 {
3219 _size = newSize;
3220 changeprimsizeshape();
3221 }
3222
3223 private void changeShape(PrimitiveBaseShape newShape)
3224 {
3225 if(newShape != null)
3226 _pbs = newShape;
3227 changeprimsizeshape();
3228 } 2856 }
3229 2857
3230 private void changeFloatOnWater(bool newval) 2858 private void changeFloatOnWater(bool newval)
@@ -3891,7 +3519,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3891 3519
3892 public bool DoAChange(changes what, object arg) 3520 public bool DoAChange(changes what, object arg)
3893 { 3521 {
3894 if (prim_geom == IntPtr.Zero && what != changes.Add && what != changes.Remove) 3522 if (prim_geom == IntPtr.Zero && what != changes.Add && what != changes.AddPhysRep && what != changes.Remove)
3895 { 3523 {
3896 return false; 3524 return false;
3897 } 3525 }
@@ -3902,6 +3530,11 @@ namespace OpenSim.Region.Physics.OdePlugin
3902 case changes.Add: 3530 case changes.Add:
3903 changeadd(); 3531 changeadd();
3904 break; 3532 break;
3533
3534 case changes.AddPhysRep:
3535 changeAddPhysRep((ODEPhysRepData)arg);
3536 break;
3537
3905 case changes.Remove: 3538 case changes.Remove:
3906 //If its being removed, we don't want to rebuild the physical rep at all, so ignore this stuff... 3539 //If its being removed, we don't want to rebuild the physical rep at all, so ignore this stuff...
3907 //When we return true, it destroys all of the prims in the linkset anyway 3540 //When we return true, it destroys all of the prims in the linkset anyway
@@ -3984,6 +3617,10 @@ namespace OpenSim.Region.Physics.OdePlugin
3984 changeShape((PrimitiveBaseShape)arg); 3617 changeShape((PrimitiveBaseShape)arg);
3985 break; 3618 break;
3986 3619
3620 case changes.PhysRepData:
3621 changePhysRepData((ODEPhysRepData) arg);
3622 break;
3623
3987 case changes.CollidesWater: 3624 case changes.CollidesWater:
3988 changeFloatOnWater((bool)arg); 3625 changeFloatOnWater((bool)arg);
3989 break; 3626 break;
@@ -4072,6 +3709,8 @@ namespace OpenSim.Region.Physics.OdePlugin
4072 donullchange(); 3709 donullchange();
4073 break; 3710 break;
4074 3711
3712
3713
4075 default: 3714 default:
4076 donullchange(); 3715 donullchange();
4077 break; 3716 break;