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.cs830
1 files changed, 185 insertions, 645 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index 7650571..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,14 +91,14 @@ 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;
@@ -107,14 +107,14 @@ namespace OpenSim.Region.Physics.OdePlugin
107 private float m_PIDHoverHeight; 107 private float m_PIDHoverHeight;
108 private float m_PIDHoverTau; 108 private float m_PIDHoverTau;
109 private bool m_useHoverPID; 109 private bool m_useHoverPID;
110 private PIDHoverType m_PIDHoverType = PIDHoverType.Ground; 110 private PIDHoverType m_PIDHoverType;
111 private float m_targetHoverHeight; 111 private float m_targetHoverHeight;
112 private float m_groundHeight; 112 private float m_groundHeight;
113 private float m_waterHeight; 113 private float m_waterHeight;
114 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.
115 115
116 private int body_autodisable_frames = 5; 116 private int body_autodisable_frames;
117 public int bodydisablecontrol = 0; 117 public int bodydisablecontrol;
118 118
119 119
120 // Default we're a Geometry 120 // Default we're a Geometry
@@ -144,12 +144,16 @@ namespace OpenSim.Region.Physics.OdePlugin
144 private IMesh m_mesh; 144 private IMesh m_mesh;
145 private object m_meshlock = new object(); 145 private object m_meshlock = new object();
146 private PrimitiveBaseShape _pbs; 146 private PrimitiveBaseShape _pbs;
147
148 private UUID? m_assetID;
149 private AssetState m_assetState;
150
147 public OdeScene _parent_scene; 151 public OdeScene _parent_scene;
148 152
149 /// <summary> 153 /// <summary>
150 /// The physics space which contains prim geometry 154 /// The physics space which contains prim geometry
151 /// </summary> 155 /// </summary>
152 public IntPtr m_targetSpace = IntPtr.Zero; 156 public IntPtr m_targetSpace;
153 157
154 public IntPtr prim_geom; 158 public IntPtr prim_geom;
155 public IntPtr _triMeshData; 159 public IntPtr _triMeshData;
@@ -163,27 +167,32 @@ namespace OpenSim.Region.Physics.OdePlugin
163 167
164 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
165 169
166 private float m_density = 10.000006836f; // Aluminum g/cm3; 170 private float m_density;
167 private byte m_shapetype; 171 private byte m_shapetype;
168 public bool _zeroFlag; 172 public bool _zeroFlag;
169 private bool m_lastUpdateSent; 173 private bool m_lastUpdateSent;
170 174
171 public IntPtr Body = IntPtr.Zero; 175 public IntPtr Body;
172 176
173 private Vector3 _target_velocity; 177 private Vector3 _target_velocity;
174 178
175 public Vector3 primOOBsize; // prim real dimensions from mesh 179 public Vector3 m_OBBOffset;
176 public Vector3 primOOBoffset; // its centroid out of mesh or rest aabb 180 public Vector3 m_OBB;
177 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
178 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
179 float primMass; // prim own mass 189 float primMass; // prim own mass
180 float primVolume; // prim own volume; 190 float primVolume; // prim own volume;
181 float _mass; // object mass acording to case 191 float _mass; // object mass acording to case
182 private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb
183 192
184 public int givefakepos = 0; 193 public int givefakepos;
185 private Vector3 fakepos; 194 private Vector3 fakepos;
186 public int givefakeori = 0; 195 public int givefakeori;
187 private Quaternion fakeori; 196 private Quaternion fakeori;
188 197
189 private int m_eventsubscription; 198 private int m_eventsubscription;
@@ -391,9 +400,7 @@ namespace OpenSim.Region.Physics.OdePlugin
391 { 400 {
392 if (value.IsFinite()) 401 if (value.IsFinite())
393 { 402 {
394 AddChange(changes.Size, value); 403 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, value, m_shapetype);
395
396// _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, value, m_shapetype, MeshWorkerChange.size);
397 } 404 }
398 else 405 else
399 { 406 {
@@ -463,7 +470,7 @@ namespace OpenSim.Region.Physics.OdePlugin
463 q.Z = dq.Z; 470 q.Z = dq.Z;
464 q.W = dq.W; 471 q.W = dq.W;
465 472
466 Vector3 Ptot = primOOBoffset * q; 473 Vector3 Ptot = m_OBBOffset * q;
467 dtmp = d.GeomGetPosition(prim_geom); 474 dtmp = d.GeomGetPosition(prim_geom);
468 Ptot.X += dtmp.X; 475 Ptot.X += dtmp.X;
469 Ptot.Y += dtmp.Y; 476 Ptot.Y += dtmp.Y;
@@ -503,7 +510,7 @@ namespace OpenSim.Region.Physics.OdePlugin
503 { 510 {
504 get 511 get
505 { 512 {
506 return primOOBsize; 513 return m_OBB;
507 } 514 }
508 } 515 }
509 516
@@ -511,7 +518,7 @@ namespace OpenSim.Region.Physics.OdePlugin
511 { 518 {
512 get 519 get
513 { 520 {
514 return primOOBoffset; 521 return m_OBBOffset;
515 } 522 }
516 } 523 }
517 524
@@ -527,8 +534,8 @@ namespace OpenSim.Region.Physics.OdePlugin
527 { 534 {
528 set 535 set
529 { 536 {
530 AddChange(changes.Shape, value); 537// AddChange(changes.Shape, value);
531// _parent_scene.m_meshWorker.ChangeActorPhysRep(this, value, _size, m_shapetype, MeshWorkerChange.shape); 538 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, value, _size, m_shapetype);
532 } 539 }
533 } 540 }
534 541
@@ -541,8 +548,7 @@ 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// _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, _size, value, MeshWorkerChange.shapetype);
546 } 552 }
547 } 553 }
548 554
@@ -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,29 +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_mesh = _parent_scene.m_meshWorker.getMesh(this, pbs, _size, m_shapetype);
1101
1102 m_building = true; // control must set this to false when done 1086 m_building = true; // control must set this to false when done
1103 1087
1104 AddChange(changes.Add, null); 1088 _parent_scene.m_meshWorker.NewActorPhysRep(this, _pbs, _size, m_shapetype);
1105 } 1089 }
1106 1090
1107 private void resetCollisionAccounting() 1091 private void resetCollisionAccounting()
@@ -1325,83 +1309,34 @@ namespace OpenSim.Region.Physics.OdePlugin
1325 } 1309 }
1326 } 1310 }
1327 1311
1328 private bool setMesh(OdeScene parent_scene) 1312 private bool GetMeshGeom()
1329 { 1313 {
1330 IntPtr vertices, indices; 1314 IntPtr vertices, indices;
1331 int vertexCount, indexCount; 1315 int vertexCount, indexCount;
1332 int vertexStride, triStride; 1316 int vertexStride, triStride;
1333 1317
1334 if (Body != IntPtr.Zero) 1318 IMesh mesh = m_mesh;
1335 {
1336 if (childPrim)
1337 {
1338 if (_parent != null)
1339 {
1340 OdePrim parent = (OdePrim)_parent;
1341 parent.ChildDelink(this, false);
1342 }
1343 }
1344 else
1345 {
1346 DestroyBody();
1347 }
1348 }
1349
1350 IMesh mesh = null;
1351
1352 lock (m_meshlock)
1353 {
1354 if (m_mesh == null)
1355 {
1356/*
1357 bool convex;
1358 int clod = (int)LevelOfDetail.High;
1359
1360 if (m_shapetype == 0)
1361 convex = false;
1362 else
1363 {
1364 convex = true;
1365 if (_pbs.SculptType != (byte)SculptType.Mesh)
1366 clod = (int)LevelOfDetail.Low;
1367 }
1368
1369 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
1370*/
1371 mesh = _parent_scene.m_meshWorker.getMesh(this, _pbs, _size, m_shapetype);
1372 }
1373 else
1374 {
1375 mesh = m_mesh;
1376 }
1377
1378 if (mesh == null)
1379 {
1380 m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z);
1381 return false;
1382 }
1383
1384 1319
1385 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap 1320 if (mesh == null)
1386 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage 1321 return false;
1387
1388 if (vertexCount == 0 || indexCount == 0)
1389 {
1390 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}",
1391 Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString());
1392 mesh.releaseSourceMeshData();
1393 return false;
1394 }
1395
1396 primOOBoffset = mesh.GetCentroid();
1397 hasOOBoffsetFromMesh = true;
1398 1322
1399 mesh.releaseSourceMeshData(); 1323 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
1400 m_mesh = mesh; 1324 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
1325
1326 if (vertexCount == 0 || indexCount == 0)
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;
1401 } 1339 }
1402
1403 IntPtr geo = IntPtr.Zero;
1404
1405 try 1340 try
1406 { 1341 {
1407 _triMeshData = d.GeomTriMeshDataCreate(); 1342 _triMeshData = d.GeomTriMeshDataCreate();
@@ -1409,8 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1409 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 1344 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1410 d.GeomTriMeshDataPreprocess(_triMeshData); 1345 d.GeomTriMeshDataPreprocess(_triMeshData);
1411 1346
1412 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1347 prim_geom = d.CreateTriMesh(IntPtr.Zero, _triMeshData, null, null, null);
1413 geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
1414 } 1348 }
1415 1349
1416 catch (Exception e) 1350 catch (Exception e)
@@ -1418,85 +1352,56 @@ namespace OpenSim.Region.Physics.OdePlugin
1418 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);
1419 if (_triMeshData != IntPtr.Zero) 1353 if (_triMeshData != IntPtr.Zero)
1420 { 1354 {
1421 d.GeomTriMeshDataDestroy(_triMeshData); 1355 try
1422 _triMeshData = IntPtr.Zero;
1423 }
1424 return false;
1425 }
1426
1427 SetGeom(geo);
1428 return true;
1429 }
1430
1431 private void SetGeom(IntPtr geom)
1432 {
1433 prim_geom = geom;
1434 //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
1435 if (prim_geom != IntPtr.Zero)
1436 {
1437
1438 if (m_NoColide)
1439 {
1440 d.GeomSetCategoryBits(prim_geom, 0);
1441 if (m_isphysical)
1442 { 1356 {
1443 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land); 1357 d.GeomTriMeshDataDestroy(_triMeshData);
1444 } 1358 }
1445 else 1359 catch
1446 { 1360 {
1447 d.GeomSetCollideBits(prim_geom, 0);
1448 d.GeomDisable(prim_geom);
1449 } 1361 }
1450 } 1362 }
1451 else 1363 _triMeshData = IntPtr.Zero;
1452 { 1364 prim_geom = IntPtr.Zero;
1453 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1454 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1455 }
1456
1457 CalcPrimBodyData();
1458
1459 _parent_scene.actor_name_map[prim_geom] = this;
1460 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;
1461 } 1375 }
1462 else 1376 return true;
1463 m_log.Warn("Setting bad Geom");
1464 } 1377 }
1465 1378
1466
1467 /// <summary>
1468 /// Create a geometry for the given mesh in the given target space.
1469 /// </summary>
1470 /// <param name="m_targetSpace"></param>
1471 /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param>
1472 private void CreateGeom() 1379 private void CreateGeom()
1473 { 1380 {
1474 if (_triMeshData != IntPtr.Zero) 1381 IntPtr geo = IntPtr.Zero;
1475 { 1382 bool hasMesh = false;
1476 d.GeomTriMeshDataDestroy(_triMeshData);
1477 _triMeshData = IntPtr.Zero;
1478 }
1479 1383
1480 bool haveMesh = false;
1481 hasOOBoffsetFromMesh = false;
1482 m_NoColide = false; 1384 m_NoColide = false;
1483 1385
1484 if (_parent_scene.m_meshWorker.needsMeshing(_pbs)) 1386 if (m_assetState == AssetState.AssetFailed)
1387 m_NoColide = true;
1388
1389 else if (m_mesh != null)
1485 { 1390 {
1486 haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims 1391 if (GetMeshGeom())
1487 if (!haveMesh) 1392 hasMesh = true;
1393 else
1488 m_NoColide = true; 1394 m_NoColide = true;
1489 } 1395 }
1490 1396
1491 if (!haveMesh) 1397 if (!hasMesh)
1492 { 1398 {
1493 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 1399 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
1494 && _size.X == _size.Y && _size.Y == _size.Z) 1400 && _size.X == _size.Y && _size.Y == _size.Z)
1495 { // it's a sphere 1401 { // it's a sphere
1496 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1497 try 1402 try
1498 { 1403 {
1499 SetGeom(d.CreateSphere(m_targetSpace, _size.X * 0.5f)); 1404 geo = d.CreateSphere(IntPtr.Zero, _size.X * 0.5f);
1500 } 1405 }
1501 catch (Exception e) 1406 catch (Exception e)
1502 { 1407 {
@@ -1506,11 +1411,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1506 } 1411 }
1507 else 1412 else
1508 {// do it as a box 1413 {// do it as a box
1509 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1510 try 1414 try
1511 { 1415 {
1512 //Console.WriteLine(" CreateGeom 4"); 1416 geo = d.CreateBox(IntPtr.Zero, _size.X, _size.Y, _size.Z);
1513 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1514 } 1417 }
1515 catch (Exception e) 1418 catch (Exception e)
1516 { 1419 {
@@ -1518,18 +1421,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1518 return; 1421 return;
1519 } 1422 }
1520 } 1423 }
1424 m_physCost = 0.1f;
1425 m_streamCost = 1.0f;
1426 prim_geom = geo;
1521 } 1427 }
1522 } 1428 }
1523 1429
1524 /// <summary>
1525 /// Set a new geometry for this prim.
1526 /// </summary>
1527 /// <param name="geom"></param>
1528 private void RemoveGeom() 1430 private void RemoveGeom()
1529 { 1431 {
1530 if (prim_geom != IntPtr.Zero) 1432 if (prim_geom != IntPtr.Zero)
1531 { 1433 {
1532 _parent_scene.actor_name_map.Remove(prim_geom); 1434 _parent_scene.actor_name_map.Remove(prim_geom);
1435
1533 try 1436 try
1534 { 1437 {
1535 d.GeomDestroy(prim_geom); 1438 d.GeomDestroy(prim_geom);
@@ -1546,6 +1449,7 @@ 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 {
@@ -1562,7 +1466,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1562 } 1466 }
1563 1467
1564 Body = IntPtr.Zero; 1468 Body = IntPtr.Zero;
1565 hasOOBoffsetFromMesh = false; 1469 m_hasOBB = false;
1566 } 1470 }
1567 1471
1568 //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
@@ -2136,358 +2040,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2136 2040
2137 #region Mass Calculation 2041 #region Mass Calculation
2138 2042
2139 private float CalculatePrimVolume()
2140 {
2141 float volume = _size.X * _size.Y * _size.Z; // default
2142 float tmp;
2143
2144 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
2145 float hollowVolume = hollowAmount * hollowAmount;
2146
2147 switch (_pbs.ProfileShape)
2148 {
2149 case ProfileShape.Square:
2150 // default box
2151
2152 if (_pbs.PathCurve == (byte)Extrusion.Straight)
2153 {
2154 if (hollowAmount > 0.0)
2155 {
2156 switch (_pbs.HollowShape)
2157 {
2158 case HollowShape.Square:
2159 case HollowShape.Same:
2160 break;
2161
2162 case HollowShape.Circle:
2163
2164 hollowVolume *= 0.78539816339f;
2165 break;
2166
2167 case HollowShape.Triangle:
2168
2169 hollowVolume *= (0.5f * .5f);
2170 break;
2171
2172 default:
2173 hollowVolume = 0;
2174 break;
2175 }
2176 volume *= (1.0f - hollowVolume);
2177 }
2178 }
2179
2180 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2181 {
2182 //a tube
2183
2184 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
2185 tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY);
2186 volume -= volume * tmp * tmp;
2187
2188 if (hollowAmount > 0.0)
2189 {
2190 hollowVolume *= hollowAmount;
2191
2192 switch (_pbs.HollowShape)
2193 {
2194 case HollowShape.Square:
2195 case HollowShape.Same:
2196 break;
2197
2198 case HollowShape.Circle:
2199 hollowVolume *= 0.78539816339f;
2200 break;
2201
2202 case HollowShape.Triangle:
2203 hollowVolume *= 0.5f * 0.5f;
2204 break;
2205 default:
2206 hollowVolume = 0;
2207 break;
2208 }
2209 volume *= (1.0f - hollowVolume);
2210 }
2211 }
2212
2213 break;
2214
2215 case ProfileShape.Circle:
2216
2217 if (_pbs.PathCurve == (byte)Extrusion.Straight)
2218 {
2219 volume *= 0.78539816339f; // elipse base
2220
2221 if (hollowAmount > 0.0)
2222 {
2223 switch (_pbs.HollowShape)
2224 {
2225 case HollowShape.Same:
2226 case HollowShape.Circle:
2227 break;
2228
2229 case HollowShape.Square:
2230 hollowVolume *= 0.5f * 2.5984480504799f;
2231 break;
2232
2233 case HollowShape.Triangle:
2234 hollowVolume *= .5f * 1.27323954473516f;
2235 break;
2236
2237 default:
2238 hollowVolume = 0;
2239 break;
2240 }
2241 volume *= (1.0f - hollowVolume);
2242 }
2243 }
2244
2245 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2246 {
2247 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
2248 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
2249 volume *= (1.0f - tmp * tmp);
2250
2251 if (hollowAmount > 0.0)
2252 {
2253
2254 // calculate the hollow volume by it's shape compared to the prim shape
2255 hollowVolume *= hollowAmount;
2256
2257 switch (_pbs.HollowShape)
2258 {
2259 case HollowShape.Same:
2260 case HollowShape.Circle:
2261 break;
2262
2263 case HollowShape.Square:
2264 hollowVolume *= 0.5f * 2.5984480504799f;
2265 break;
2266
2267 case HollowShape.Triangle:
2268 hollowVolume *= .5f * 1.27323954473516f;
2269 break;
2270
2271 default:
2272 hollowVolume = 0;
2273 break;
2274 }
2275 volume *= (1.0f - hollowVolume);
2276 }
2277 }
2278 break;
2279
2280 case ProfileShape.HalfCircle:
2281 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2282 {
2283 volume *= 0.5236f;
2284
2285 if (hollowAmount > 0.0)
2286 {
2287 hollowVolume *= hollowAmount;
2288
2289 switch (_pbs.HollowShape)
2290 {
2291 case HollowShape.Circle:
2292 case HollowShape.Triangle: // diference in sl is minor and odd
2293 case HollowShape.Same:
2294 break;
2295
2296 case HollowShape.Square:
2297 hollowVolume *= 0.909f;
2298 break;
2299
2300 // case HollowShape.Triangle:
2301 // hollowVolume *= .827f;
2302 // break;
2303 default:
2304 hollowVolume = 0;
2305 break;
2306 }
2307 volume *= (1.0f - hollowVolume);
2308 }
2309
2310 }
2311 break;
2312
2313 case ProfileShape.EquilateralTriangle:
2314
2315 if (_pbs.PathCurve == (byte)Extrusion.Straight)
2316 {
2317 volume *= 0.32475953f;
2318
2319 if (hollowAmount > 0.0)
2320 {
2321
2322 // calculate the hollow volume by it's shape compared to the prim shape
2323 switch (_pbs.HollowShape)
2324 {
2325 case HollowShape.Same:
2326 case HollowShape.Triangle:
2327 hollowVolume *= .25f;
2328 break;
2329
2330 case HollowShape.Square:
2331 hollowVolume *= 0.499849f * 3.07920140172638f;
2332 break;
2333
2334 case HollowShape.Circle:
2335 // Hollow shape is a perfect cyllinder in respect to the cube's scale
2336 // Cyllinder hollow volume calculation
2337
2338 hollowVolume *= 0.1963495f * 3.07920140172638f;
2339 break;
2340
2341 default:
2342 hollowVolume = 0;
2343 break;
2344 }
2345 volume *= (1.0f - hollowVolume);
2346 }
2347 }
2348 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2349 {
2350 volume *= 0.32475953f;
2351 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
2352 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
2353 volume *= (1.0f - tmp * tmp);
2354
2355 if (hollowAmount > 0.0)
2356 {
2357
2358 hollowVolume *= hollowAmount;
2359
2360 switch (_pbs.HollowShape)
2361 {
2362 case HollowShape.Same:
2363 case HollowShape.Triangle:
2364 hollowVolume *= .25f;
2365 break;
2366
2367 case HollowShape.Square:
2368 hollowVolume *= 0.499849f * 3.07920140172638f;
2369 break;
2370
2371 case HollowShape.Circle:
2372
2373 hollowVolume *= 0.1963495f * 3.07920140172638f;
2374 break;
2375
2376 default:
2377 hollowVolume = 0;
2378 break;
2379 }
2380 volume *= (1.0f - hollowVolume);
2381 }
2382 }
2383 break;
2384
2385 default:
2386 break;
2387 }
2388
2389 float taperX1;
2390 float taperY1;
2391 float taperX;
2392 float taperY;
2393 float pathBegin;
2394 float pathEnd;
2395 float profileBegin;
2396 float profileEnd;
2397
2398 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
2399 {
2400 taperX1 = _pbs.PathScaleX * 0.01f;
2401 if (taperX1 > 1.0f)
2402 taperX1 = 2.0f - taperX1;
2403 taperX = 1.0f - taperX1;
2404
2405 taperY1 = _pbs.PathScaleY * 0.01f;
2406 if (taperY1 > 1.0f)
2407 taperY1 = 2.0f - taperY1;
2408 taperY = 1.0f - taperY1;
2409 }
2410 else
2411 {
2412 taperX = _pbs.PathTaperX * 0.01f;
2413 if (taperX < 0.0f)
2414 taperX = -taperX;
2415 taperX1 = 1.0f - taperX;
2416
2417 taperY = _pbs.PathTaperY * 0.01f;
2418 if (taperY < 0.0f)
2419 taperY = -taperY;
2420 taperY1 = 1.0f - taperY;
2421 }
2422
2423 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
2424
2425 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
2426 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
2427 volume *= (pathEnd - pathBegin);
2428
2429 // this is crude aproximation
2430 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
2431 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
2432 volume *= (profileEnd - profileBegin);
2433
2434 return volume;
2435 }
2436
2437
2438 private void CalcPrimBodyData()
2439 {
2440 float volume;
2441
2442 if (prim_geom == IntPtr.Zero)
2443 {
2444 // Ubit let's have a initial basic OOB
2445 primOOBsize.X = _size.X;
2446 primOOBsize.Y = _size.Y;
2447 primOOBsize.Z = _size.Z;
2448 primOOBoffset = Vector3.Zero;
2449 }
2450 else
2451 {
2452 d.AABB AABB;
2453 d.GeomGetAABB(prim_geom, out AABB); // get the AABB from engine geom
2454
2455 primOOBsize.X = (AABB.MaxX - AABB.MinX);
2456 primOOBsize.Y = (AABB.MaxY - AABB.MinY);
2457 primOOBsize.Z = (AABB.MaxZ - AABB.MinZ);
2458 if (!hasOOBoffsetFromMesh)
2459 {
2460 primOOBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f;
2461 primOOBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f;
2462 primOOBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f;
2463 }
2464 }
2465
2466 // also its own inertia and mass
2467 // keep using basic shape mass for now
2468 volume = CalculatePrimVolume();
2469
2470 primVolume = volume;
2471 primMass = m_density * volume;
2472
2473 if (primMass <= 0)
2474 primMass = 0.0001f;//ckrinke: Mass must be greater then zero.
2475 if (primMass > _parent_scene.maximumMassObject)
2476 primMass = _parent_scene.maximumMassObject;
2477
2478 _mass = primMass; // just in case
2479
2480 d.MassSetBoxTotal(out primdMass, primMass, primOOBsize.X, primOOBsize.Y, primOOBsize.Z);
2481
2482 d.MassTranslate(ref primdMass,
2483 primOOBoffset.X,
2484 primOOBoffset.Y,
2485 primOOBoffset.Z);
2486
2487 primOOBsize *= 0.5f; // let obb size be a corner coords
2488 primOOBradiusSQ = primOOBsize.LengthSquared();
2489 }
2490
2491 private void UpdatePrimBodyData() 2043 private void UpdatePrimBodyData()
2492 { 2044 {
2493 primMass = m_density * primVolume; 2045 primMass = m_density * primVolume;
@@ -2499,14 +2051,14 @@ namespace OpenSim.Region.Physics.OdePlugin
2499 2051
2500 _mass = primMass; // just in case 2052 _mass = primMass; // just in case
2501 2053
2502 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);
2503 2055
2504 d.MassTranslate(ref primdMass, 2056 d.MassTranslate(ref primdMass,
2505 primOOBoffset.X, 2057 m_OBBOffset.X,
2506 primOOBoffset.Y, 2058 m_OBBOffset.Y,
2507 primOOBoffset.Z); 2059 m_OBBOffset.Z);
2508 2060
2509 primOOBradiusSQ = primOOBsize.LengthSquared(); 2061 primOOBradiusSQ = m_OBBOffset.LengthSquared();
2510 } 2062 }
2511 2063
2512 #endregion 2064 #endregion
@@ -2697,27 +2249,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2697 2249
2698 private void changeadd() 2250 private void changeadd()
2699 { 2251 {
2700 CreateGeom();
2701
2702 if (prim_geom != IntPtr.Zero)
2703 {
2704 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2705 d.Quaternion myrot = new d.Quaternion();
2706 myrot.X = _orientation.X;
2707 myrot.Y = _orientation.Y;
2708 myrot.Z = _orientation.Z;
2709 myrot.W = _orientation.W;
2710 d.GeomSetQuaternion(prim_geom, ref myrot);
2711
2712 if (!m_isphysical)
2713 {
2714 SetInStaticSpace(this);
2715 UpdateCollisionCatFlags();
2716 ApplyCollisionCatFlags();
2717 }
2718 else
2719 MakeBody();
2720 }
2721 } 2252 }
2722 2253
2723 private void changeAngularLock(Vector3 newLock) 2254 private void changeAngularLock(Vector3 newLock)
@@ -3161,41 +2692,45 @@ namespace OpenSim.Region.Physics.OdePlugin
3161 resetCollisionAccounting(); 2692 resetCollisionAccounting();
3162 } 2693 }
3163 2694
3164 private void changeprimsizeshape() 2695 private void changeSize(Vector3 newSize)
3165 { 2696 {
3166 CheckDelaySelect(); 2697 }
3167 2698
3168 OdePrim parent = (OdePrim)_parent; 2699 private void changeShape(PrimitiveBaseShape newShape)
2700 {
2701 }
3169 2702
3170 bool chp = childPrim; 2703
3171 2704
3172 if (chp) 2705 private void changeAddPhysRep(ODEPhysRepData repData)
3173 { 2706 {
3174 if (parent != null) 2707 _size = repData.size; //??
3175 { 2708 _pbs = repData.pbs;
3176 parent.DestroyBody(); 2709 m_shapetype = repData.shapetype;
3177 }
3178 }
3179 else
3180 {
3181 DestroyBody();
3182 }
3183 2710
3184 RemoveGeom(); 2711 m_mesh = repData.mesh;
3185 2712
3186 // we don't need to do space calculation because the client sends a position update also. 2713 m_assetID = repData.assetID;
3187 if (_size.X <= 0) 2714 m_assetState = repData.assetState;
3188 _size.X = 0.01f; 2715
3189 if (_size.Y <= 0) 2716 m_hasOBB = repData.hasOBB;
3190 _size.Y = 0.01f; 2717 m_OBBOffset = repData.OBBOffset;
3191 if (_size.Z <= 0) 2718 m_OBB = repData.OBB;
3192 _size.Z = 0.01f; 2719
3193 // Construction of new prim 2720// m_NoColide = repData.NoColide;
2721 m_physCost = repData.physCost;
2722 m_streamCost = repData.streamCost;
2723
2724 primVolume = repData.volume;
3194 2725
3195 CreateGeom(); 2726 CreateGeom();
3196 2727
3197 if (prim_geom != IntPtr.Zero) 2728 if (prim_geom != IntPtr.Zero)
3198 { 2729 {
2730 UpdatePrimBodyData();
2731
2732 _parent_scene.actor_name_map[prim_geom] = this;
2733
3199 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 2734 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3200 d.Quaternion myrot = new d.Quaternion(); 2735 d.Quaternion myrot = new d.Quaternion();
3201 myrot.X = _orientation.X; 2736 myrot.X = _orientation.X;
@@ -3203,44 +2738,26 @@ namespace OpenSim.Region.Physics.OdePlugin
3203 myrot.Z = _orientation.Z; 2738 myrot.Z = _orientation.Z;
3204 myrot.W = _orientation.W; 2739 myrot.W = _orientation.W;
3205 d.GeomSetQuaternion(prim_geom, ref myrot); 2740 d.GeomSetQuaternion(prim_geom, ref myrot);
3206 }
3207 2741
3208 if (m_isphysical) 2742 if (!m_isphysical)
3209 {
3210 if (chp)
3211 { 2743 {
3212 if (parent != null) 2744 SetInStaticSpace(this);
3213 { 2745 UpdateCollisionCatFlags();
3214 parent.MakeBody(); 2746 ApplyCollisionCatFlags();
3215 }
3216 } 2747 }
3217 else 2748 else
3218 MakeBody(); 2749 MakeBody();
3219 }
3220 2750
3221 else 2751 if (m_assetState == AssetState.needAsset)
3222 { 2752 {
3223 UpdateCollisionCatFlags(); 2753 repData.size = _size;
3224 ApplyCollisionCatFlags(); 2754 repData.pbs = _pbs;
2755 repData.shapetype = m_shapetype;
2756 _parent_scene.m_meshWorker.RequestMeshAsset(repData);
2757 }
3225 } 2758 }
3226
3227 resetCollisionAccounting();
3228 }
3229
3230 private void changeSize(Vector3 newSize)
3231 {
3232 _size = newSize;
3233 changeprimsizeshape();
3234 } 2759 }
3235 2760
3236 private void changeShape(PrimitiveBaseShape newShape)
3237 {
3238 if(newShape != null)
3239 _pbs = newShape;
3240 changeprimsizeshape();
3241 }
3242
3243
3244 private void changePhysRepData(ODEPhysRepData repData) 2761 private void changePhysRepData(ODEPhysRepData repData)
3245 { 2762 {
3246 CheckDelaySelect(); 2763 CheckDelaySelect();
@@ -3261,32 +2778,43 @@ namespace OpenSim.Region.Physics.OdePlugin
3261 DestroyBody(); 2778 DestroyBody();
3262 } 2779 }
3263 2780
3264 RemoveGeom(); 2781 RemoveGeom();
3265 2782
3266 prim_geom = repData.geo;
3267 _triMeshData = repData.triMeshData;
3268 _size = repData.size; 2783 _size = repData.size;
3269 _pbs = repData.pbs; 2784 _pbs = repData.pbs;
3270 m_mesh = repData.mesh;
3271 m_shapetype = repData.shapetype; 2785 m_shapetype = repData.shapetype;
3272 2786
3273 hasOOBoffsetFromMesh = repData.hasOBB; 2787 m_mesh = repData.mesh;
3274 primOOBoffset = repData.OBBOffset; 2788
3275 primOOBsize = repData.OBB; 2789 m_assetID = repData.assetID;
2790 m_assetState = repData.assetState;
3276 2791
3277 m_NoColide = repData.NoColide; 2792 m_hasOBB = repData.hasOBB;
3278// m_physCost = repData.physCost; 2793 m_OBBOffset = repData.OBBOffset;
3279// m_streamCost = repData.streamCost; 2794 m_OBB = repData.OBB;
3280 2795
3281 primVolume = repData.volume; 2796 m_physCost = repData.physCost;
3282 m_targetSpace = repData.curSpace; 2797 m_streamCost = repData.streamCost;
3283 2798
3284 UpdatePrimBodyData(); 2799 primVolume = repData.volume;
3285 2800
3286 _parent_scene.actor_name_map[prim_geom] = this; 2801 CreateGeom();
3287 2802
3288 if (prim_geom != IntPtr.Zero) 2803 if (prim_geom != IntPtr.Zero)
3289 { 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
3290 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 2818 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3291 d.Quaternion myrot = new d.Quaternion(); 2819 d.Quaternion myrot = new d.Quaternion();
3292 myrot.X = _orientation.X; 2820 myrot.X = _orientation.X;
@@ -3294,32 +2822,39 @@ namespace OpenSim.Region.Physics.OdePlugin
3294 myrot.Z = _orientation.Z; 2822 myrot.Z = _orientation.Z;
3295 myrot.W = _orientation.W; 2823 myrot.W = _orientation.W;
3296 d.GeomSetQuaternion(prim_geom, ref myrot); 2824 d.GeomSetQuaternion(prim_geom, ref myrot);
3297 }
3298 2825
3299 if (m_isphysical) 2826
3300 { 2827 if (m_isphysical)
3301 if (chp)
3302 { 2828 {
3303 if (parent != null) 2829 if (chp)
3304 { 2830 {
3305 parent.MakeBody(); 2831 if (parent != null)
2832 {
2833 parent.MakeBody();
2834 }
3306 } 2835 }
2836 else
2837 MakeBody();
3307 } 2838 }
2839
3308 else 2840 else
3309 MakeBody(); 2841 {
3310 } 2842 SetInStaticSpace(this);
2843 UpdateCollisionCatFlags();
2844 ApplyCollisionCatFlags();
2845 }
3311 2846
3312 else 2847 resetCollisionAccounting();
3313 { 2848 if (m_assetState == AssetState.needAsset)
3314 SetInStaticSpace(this); 2849 {
3315 UpdateCollisionCatFlags(); 2850 repData.size = _size;
3316 ApplyCollisionCatFlags(); 2851 repData.pbs = _pbs;
2852 repData.shapetype = m_shapetype;
2853 _parent_scene.m_meshWorker.RequestMeshAsset(repData);
2854 }
3317 } 2855 }
3318
3319 resetCollisionAccounting();
3320 } 2856 }
3321 2857
3322
3323 private void changeFloatOnWater(bool newval) 2858 private void changeFloatOnWater(bool newval)
3324 { 2859 {
3325 m_collidesWater = newval; 2860 m_collidesWater = newval;
@@ -3984,7 +3519,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3984 3519
3985 public bool DoAChange(changes what, object arg) 3520 public bool DoAChange(changes what, object arg)
3986 { 3521 {
3987 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)
3988 { 3523 {
3989 return false; 3524 return false;
3990 } 3525 }
@@ -3995,6 +3530,11 @@ namespace OpenSim.Region.Physics.OdePlugin
3995 case changes.Add: 3530 case changes.Add:
3996 changeadd(); 3531 changeadd();
3997 break; 3532 break;
3533
3534 case changes.AddPhysRep:
3535 changeAddPhysRep((ODEPhysRepData)arg);
3536 break;
3537
3998 case changes.Remove: 3538 case changes.Remove:
3999 //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...
4000 //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