aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs858
1 files changed, 294 insertions, 564 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index f2f4725..ce67cc4 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 MeshState m_meshState;
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;
@@ -271,7 +277,23 @@ namespace OpenSim.Region.Physics.OdePlugin
271 cdata.mu *= veh.FrictionFactor; 277 cdata.mu *= veh.FrictionFactor;
272// cdata.mu *= 0; 278// cdata.mu *= 0;
273 } 279 }
274 } 280 }
281
282 public override float PhysicsCost
283 {
284 get
285 {
286 return m_physCost;
287 }
288 }
289
290 public override float StreamCost
291 {
292 get
293 {
294 return m_streamCost;
295 }
296 }
275 297
276 public override int PhysicsActorType 298 public override int PhysicsActorType
277 { 299 {
@@ -394,7 +416,7 @@ namespace OpenSim.Region.Physics.OdePlugin
394 { 416 {
395 if (value.IsFinite()) 417 if (value.IsFinite())
396 { 418 {
397 AddChange(changes.Size, value); 419 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, value, m_shapetype);
398 } 420 }
399 else 421 else
400 { 422 {
@@ -464,7 +486,7 @@ namespace OpenSim.Region.Physics.OdePlugin
464 q.Z = dq.Z; 486 q.Z = dq.Z;
465 q.W = dq.W; 487 q.W = dq.W;
466 488
467 Vector3 Ptot = primOOBoffset * q; 489 Vector3 Ptot = m_OBBOffset * q;
468 dtmp = d.GeomGetPosition(prim_geom); 490 dtmp = d.GeomGetPosition(prim_geom);
469 Ptot.X += dtmp.X; 491 Ptot.X += dtmp.X;
470 Ptot.Y += dtmp.Y; 492 Ptot.Y += dtmp.Y;
@@ -504,7 +526,7 @@ namespace OpenSim.Region.Physics.OdePlugin
504 { 526 {
505 get 527 get
506 { 528 {
507 return primOOBsize; 529 return m_OBB;
508 } 530 }
509 } 531 }
510 532
@@ -512,7 +534,7 @@ namespace OpenSim.Region.Physics.OdePlugin
512 { 534 {
513 get 535 get
514 { 536 {
515 return primOOBoffset; 537 return m_OBBOffset;
516 } 538 }
517 } 539 }
518 540
@@ -528,7 +550,8 @@ namespace OpenSim.Region.Physics.OdePlugin
528 { 550 {
529 set 551 set
530 { 552 {
531 AddChange(changes.Shape, value); 553// AddChange(changes.Shape, value);
554 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, value, _size, m_shapetype);
532 } 555 }
533 } 556 }
534 557
@@ -541,11 +564,10 @@ namespace OpenSim.Region.Physics.OdePlugin
541 set 564 set
542 { 565 {
543 m_shapetype = value; 566 m_shapetype = value;
544 AddChange(changes.Shape, null); 567 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, _size, value);
545 } 568 }
546 } 569 }
547 570
548
549 public override Vector3 Velocity 571 public override Vector3 Velocity
550 { 572 {
551 get 573 get
@@ -619,6 +641,9 @@ namespace OpenSim.Region.Physics.OdePlugin
619 { 641 {
620 fakeori = value; 642 fakeori = value;
621 givefakeori++; 643 givefakeori++;
644
645 value.Normalize();
646
622 AddChange(changes.Orientation, value); 647 AddChange(changes.Orientation, value);
623 } 648 }
624 else 649 else
@@ -1012,7 +1037,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1012 m_invTimeStep = 1f / m_timeStep; 1037 m_invTimeStep = 1f / m_timeStep;
1013 1038
1014 m_density = parent_scene.geomDefaultDensity; 1039 m_density = parent_scene.geomDefaultDensity;
1015 // m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
1016 body_autodisable_frames = parent_scene.bodyFramesAutoDisable; 1040 body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
1017 1041
1018 prim_geom = IntPtr.Zero; 1042 prim_geom = IntPtr.Zero;
@@ -1064,7 +1088,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1064 m_colliderfilter = 0; 1088 m_colliderfilter = 0;
1065 m_NoColide = false; 1089 m_NoColide = false;
1066 1090
1067 hasOOBoffsetFromMesh = false;
1068 _triMeshData = IntPtr.Zero; 1091 _triMeshData = IntPtr.Zero;
1069 1092
1070 m_shapetype = _shapeType; 1093 m_shapetype = _shapeType;
@@ -1079,27 +1102,14 @@ namespace OpenSim.Region.Physics.OdePlugin
1079 mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; 1102 mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
1080 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; 1103 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
1081 1104
1082 CalcPrimBodyData(); 1105 m_building = true; // control must set this to false when done
1083 1106
1084 m_mesh = null; 1107 // get basic mass parameters
1085 if (_parent_scene.needsMeshing(pbs) && (pbs.SculptData.Length > 0)) 1108 ODEPhysRepData repData = _parent_scene.m_meshWorker.NewActorPhysRep(this, _pbs, _size, m_shapetype);
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 1109
1100 m_building = true; // control must set this to false when done 1110 primVolume = repData.volume;
1101 1111
1102 AddChange(changes.Add, null); 1112 UpdatePrimBodyData();
1103 } 1113 }
1104 1114
1105 private void resetCollisionAccounting() 1115 private void resetCollisionAccounting()
@@ -1323,76 +1333,88 @@ namespace OpenSim.Region.Physics.OdePlugin
1323 } 1333 }
1324 } 1334 }
1325 1335
1326 private bool setMesh(OdeScene parent_scene)
1327 {
1328 IntPtr vertices, indices;
1329 int vertexCount, indexCount;
1330 int vertexStride, triStride;
1331 1336
1332 if (Body != IntPtr.Zero) 1337 private void SetGeom(IntPtr geom)
1338 {
1339 prim_geom = geom;
1340 //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
1341 if (prim_geom != IntPtr.Zero)
1333 { 1342 {
1334 if (childPrim) 1343
1344 if (m_NoColide)
1335 { 1345 {
1336 if (_parent != null) 1346 d.GeomSetCategoryBits(prim_geom, 0);
1347 if (m_isphysical)
1337 { 1348 {
1338 OdePrim parent = (OdePrim)_parent; 1349 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
1339 parent.ChildDelink(this, false); 1350 }
1351 else
1352 {
1353 d.GeomSetCollideBits(prim_geom, 0);
1354 d.GeomDisable(prim_geom);
1340 } 1355 }
1341 } 1356 }
1342 else 1357 else
1343 { 1358 {
1344 DestroyBody(); 1359 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1360 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1345 } 1361 }
1346 }
1347 1362
1348 IMesh mesh = null; 1363 UpdatePrimBodyData();
1364 _parent_scene.actor_name_map[prim_geom] = this;
1349 1365
1350 lock (m_meshlock) 1366/*
1351 { 1367// debug
1352 if (m_mesh == null) 1368 d.AABB aabb;
1353 { 1369 d.GeomGetAABB(prim_geom, out aabb);
1354 bool convex; 1370 float x = aabb.MaxX - aabb.MinX;
1355 int clod = (int)LevelOfDetail.High; 1371 float y = aabb.MaxY - aabb.MinY;
1372 float z = aabb.MaxZ - aabb.MinZ;
1373 if( x > 60.0f || y > 60.0f || z > 60.0f)
1374 m_log.WarnFormat("[PHYSICS]: large prim geo {0},size {1}, AABBsize <{2},{3},{4}, mesh {5} at {6}",
1375 Name, _size.ToString(), x, y, z, _pbs.SculptEntry ? _pbs.SculptTexture.ToString() : "primMesh", _position.ToString());
1376 else if (x < 0.001f || y < 0.001f || z < 0.001f)
1377 m_log.WarnFormat("[PHYSICS]: small prim geo {0},size {1}, AABBsize <{2},{3},{4}, mesh {5} at {6}",
1378 Name, _size.ToString(), x, y, z, _pbs.SculptEntry ? _pbs.SculptTexture.ToString() : "primMesh", _position.ToString());
1379
1380//
1381*/
1356 1382
1357 if (m_shapetype == 0) 1383 }
1358 convex = false; 1384 else
1359 else 1385 m_log.Warn("Setting bad Geom");
1360 { 1386 }
1361 convex = true;
1362 if (_pbs.SculptType != (byte)SculptType.Mesh)
1363 clod = (int)LevelOfDetail.Low;
1364 }
1365 1387
1366 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex); 1388 private bool GetMeshGeom()
1367 } 1389 {
1368 else 1390 IntPtr vertices, indices;
1369 { 1391 int vertexCount, indexCount;
1370 mesh = m_mesh; 1392 int vertexStride, triStride;
1371 } 1393
1394 IMesh mesh = m_mesh;
1372 1395
1373 if (mesh == null) 1396 if (mesh == null)
1374 { 1397 return false;
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 1398
1399 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
1400 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
1379 1401
1380 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap 1402 if (vertexCount == 0 || indexCount == 0)
1381 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage 1403 {
1404 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on OdePrim {0}, mesh {1}",
1405 Name, _pbs.SculptEntry ? _pbs.SculptTexture.ToString() : "primMesh");
1382 1406
1383 if (vertexCount == 0 || indexCount == 0) 1407 m_hasOBB = false;
1384 { 1408 m_OBBOffset = Vector3.Zero;
1385 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}", 1409 m_OBB = _size * 0.5f;
1386 Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString());
1387 mesh.releaseSourceMeshData();
1388 return false;
1389 }
1390 1410
1391 primOOBoffset = mesh.GetCentroid(); 1411 m_physCost = 0.1f;
1392 hasOOBoffsetFromMesh = true; 1412 m_streamCost = 1.0f;
1393 1413
1394 mesh.releaseSourceMeshData(); 1414 _parent_scene.mesher.ReleaseMesh(mesh);
1395 m_mesh = mesh; 1415 m_meshState = MeshState.MeshFailed;
1416 m_mesh = null;
1417 return false;
1396 } 1418 }
1397 1419
1398 IntPtr geo = IntPtr.Zero; 1420 IntPtr geo = IntPtr.Zero;
@@ -1404,7 +1426,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1404 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 1426 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1405 d.GeomTriMeshDataPreprocess(_triMeshData); 1427 d.GeomTriMeshDataPreprocess(_triMeshData);
1406 1428
1407 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1408 geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null); 1429 geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
1409 } 1430 }
1410 1431
@@ -1413,85 +1434,65 @@ namespace OpenSim.Region.Physics.OdePlugin
1413 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e); 1434 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e);
1414 if (_triMeshData != IntPtr.Zero) 1435 if (_triMeshData != IntPtr.Zero)
1415 { 1436 {
1416 d.GeomTriMeshDataDestroy(_triMeshData); 1437 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 { 1438 {
1438 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land); 1439 d.GeomTriMeshDataDestroy(_triMeshData);
1439 } 1440 }
1440 else 1441 catch
1441 { 1442 {
1442 d.GeomSetCollideBits(prim_geom, 0);
1443 d.GeomDisable(prim_geom);
1444 } 1443 }
1445 } 1444 }
1446 else 1445 _triMeshData = IntPtr.Zero;
1447 {
1448 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1449 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1450 }
1451 1446
1452 CalcPrimBodyData(); 1447 m_hasOBB = false;
1448 m_OBBOffset = Vector3.Zero;
1449 m_OBB = _size * 0.5f;
1450 m_physCost = 0.1f;
1451 m_streamCost = 1.0f;
1452
1453 _parent_scene.mesher.ReleaseMesh(mesh);
1454 m_meshState = MeshState.MeshFailed;
1455 m_mesh = null;
1456 return false;
1457 }
1453 1458
1454 _parent_scene.actor_name_map[prim_geom] = this; 1459 m_physCost = 0.0013f * (float)indexCount;
1460 // todo
1461 m_streamCost = 1.0f;
1455 1462
1456 } 1463 SetGeom(geo);
1457 else
1458 m_log.Warn("Setting bad Geom");
1459 }
1460 1464
1465 return true;
1466 }
1461 1467
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() 1468 private void CreateGeom()
1468 { 1469 {
1469 if (_triMeshData != IntPtr.Zero) 1470 bool hasMesh = false;
1470 {
1471 d.GeomTriMeshDataDestroy(_triMeshData);
1472 _triMeshData = IntPtr.Zero;
1473 }
1474 1471
1475 bool haveMesh = false;
1476 hasOOBoffsetFromMesh = false;
1477 m_NoColide = false; 1472 m_NoColide = false;
1478 1473
1479 if (_parent_scene.needsMeshing(_pbs)) 1474 if ((m_meshState & MeshState.MeshNoColide) != 0)
1475 m_NoColide = true;
1476
1477 else if(m_mesh != null)
1480 { 1478 {
1481 haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims 1479 if (GetMeshGeom())
1482 if (!haveMesh) 1480 hasMesh = true;
1481 else
1483 m_NoColide = true; 1482 m_NoColide = true;
1484 } 1483 }
1485 1484
1486 if (!haveMesh) 1485
1486 if (!hasMesh)
1487 { 1487 {
1488 IntPtr geo = IntPtr.Zero;
1489
1488 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 1490 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
1489 && _size.X == _size.Y && _size.Y == _size.Z) 1491 && _size.X == _size.Y && _size.Y == _size.Z)
1490 { // it's a sphere 1492 { // it's a sphere
1491 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1492 try 1493 try
1493 { 1494 {
1494 SetGeom(d.CreateSphere(m_targetSpace, _size.X * 0.5f)); 1495 geo = d.CreateSphere(m_targetSpace, _size.X * 0.5f);
1495 } 1496 }
1496 catch (Exception e) 1497 catch (Exception e)
1497 { 1498 {
@@ -1501,11 +1502,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1501 } 1502 }
1502 else 1503 else
1503 {// do it as a box 1504 {// do it as a box
1504 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1505 try 1505 try
1506 { 1506 {
1507 //Console.WriteLine(" CreateGeom 4"); 1507 geo = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1508 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1509 } 1508 }
1510 catch (Exception e) 1509 catch (Exception e)
1511 { 1510 {
@@ -1513,19 +1512,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1513 return; 1512 return;
1514 } 1513 }
1515 } 1514 }
1515 m_physCost = 0.1f;
1516 m_streamCost = 1.0f;
1517 SetGeom(geo);
1516 } 1518 }
1517 } 1519 }
1518 1520
1519 /// <summary>
1520 /// Set a new geometry for this prim.
1521 /// </summary>
1522 /// <param name="geom"></param>
1523 private void RemoveGeom() 1521 private void RemoveGeom()
1524 { 1522 {
1525 if (prim_geom != IntPtr.Zero) 1523 if (prim_geom != IntPtr.Zero)
1526 { 1524 {
1527// _parent_scene.geom_name_map.Remove(prim_geom);
1528 _parent_scene.actor_name_map.Remove(prim_geom); 1525 _parent_scene.actor_name_map.Remove(prim_geom);
1526
1529 try 1527 try
1530 { 1528 {
1531 d.GeomDestroy(prim_geom); 1529 d.GeomDestroy(prim_geom);
@@ -1534,11 +1532,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1534 d.GeomTriMeshDataDestroy(_triMeshData); 1532 d.GeomTriMeshDataDestroy(_triMeshData);
1535 _triMeshData = IntPtr.Zero; 1533 _triMeshData = IntPtr.Zero;
1536 } 1534 }
1537
1538 } 1535 }
1539
1540
1541 // catch (System.AccessViolationException)
1542 catch (Exception e) 1536 catch (Exception e)
1543 { 1537 {
1544 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e); 1538 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e);
@@ -1546,29 +1540,26 @@ namespace OpenSim.Region.Physics.OdePlugin
1546 1540
1547 prim_geom = IntPtr.Zero; 1541 prim_geom = IntPtr.Zero;
1548 collide_geom = IntPtr.Zero; 1542 collide_geom = IntPtr.Zero;
1543 m_targetSpace = IntPtr.Zero;
1549 } 1544 }
1550 else 1545 else
1551 { 1546 {
1552 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name); 1547 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name);
1553 } 1548 }
1554 1549
1555 if (m_mesh != null) 1550 lock (m_meshlock)
1556 { 1551 {
1557 _parent_scene.mesher.ReleaseMesh(m_mesh); 1552 if (m_mesh != null)
1558 m_mesh = null; 1553 {
1554 _parent_scene.mesher.ReleaseMesh(m_mesh);
1555 m_mesh = null;
1556 }
1559 } 1557 }
1560 1558
1561 Body = IntPtr.Zero; 1559 Body = IntPtr.Zero;
1562 hasOOBoffsetFromMesh = false; 1560 m_hasOBB = false;
1563 } 1561 }
1564/* 1562
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 1563 //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 1564 // should only be called for non physical prims unless they are becoming non physical
1574 private void SetInStaticSpace(OdePrim prim) 1565 private void SetInStaticSpace(OdePrim prim)
@@ -1631,9 +1622,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1631 1622
1632 if (Body != IntPtr.Zero) 1623 if (Body != IntPtr.Zero)
1633 { 1624 {
1634// d.BodyDestroy(Body);
1635// Body = IntPtr.Zero;
1636 // do a more complet destruction
1637 DestroyBody(); 1625 DestroyBody();
1638 m_log.Warn("[PHYSICS]: MakeBody called having a body"); 1626 m_log.Warn("[PHYSICS]: MakeBody called having a body");
1639 } 1627 }
@@ -2143,339 +2131,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2143 2131
2144 #region Mass Calculation 2132 #region Mass Calculation
2145 2133
2146 private float CalculatePrimVolume() 2134 private void UpdatePrimBodyData()
2147 { 2135 {
2148 float volume = _size.X * _size.Y * _size.Z; // default 2136 primMass = m_density * primVolume;
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 {
2447 float volume;
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 2137
2480 if (primMass <= 0) 2138 if (primMass <= 0)
2481 primMass = 0.0001f;//ckrinke: Mass must be greater then zero. 2139 primMass = 0.0001f;//ckrinke: Mass must be greater then zero.
@@ -2484,17 +2142,31 @@ namespace OpenSim.Region.Physics.OdePlugin
2484 2142
2485 _mass = primMass; // just in case 2143 _mass = primMass; // just in case
2486 2144
2487 d.MassSetBoxTotal(out primdMass, primMass, primOOBsize.X, primOOBsize.Y, primOOBsize.Z); 2145 d.MassSetBoxTotal(out primdMass, primMass, m_OBB.X, m_OBB.Y, m_OBB.Z);
2488 2146
2489 d.MassTranslate(ref primdMass, 2147 d.MassTranslate(ref primdMass,
2490 primOOBoffset.X, 2148 m_OBBOffset.X,
2491 primOOBoffset.Y, 2149 m_OBBOffset.Y,
2492 primOOBoffset.Z); 2150 m_OBBOffset.Z);
2493 2151
2494 primOOBsize *= 0.5f; // let obb size be a corner coords 2152 primOOBradiusSQ = m_OBB.LengthSquared();
2495 primOOBradiusSQ = primOOBsize.LengthSquared();
2496 }
2497 2153
2154 if (_triMeshData != IntPtr.Zero)
2155 {
2156 float pc = m_physCost;
2157 float psf = primOOBradiusSQ;
2158 psf *= 1.33f * .2f;
2159 pc *= psf;
2160 if (pc < 0.1f)
2161 pc = 0.1f;
2162
2163 m_physCost = pc;
2164 }
2165 else
2166 m_physCost = 0.1f;
2167
2168 m_streamCost = 1.0f;
2169 }
2498 2170
2499 #endregion 2171 #endregion
2500 2172
@@ -2575,6 +2247,14 @@ namespace OpenSim.Region.Physics.OdePlugin
2575 _orientation.Y = qtmp.Y; 2247 _orientation.Y = qtmp.Y;
2576 _orientation.Z = qtmp.Z; 2248 _orientation.Z = qtmp.Z;
2577 _orientation.W = qtmp.W; 2249 _orientation.W = qtmp.W;
2250/*
2251// Debug
2252 float qlen = _orientation.Length();
2253 if (qlen > 1.01f || qlen < 0.99)
2254 m_log.WarnFormat("[PHYSICS]: Got nonnorm quaternion from geom in Object {0} norm {1}", Name, qlen);
2255//
2256*/
2257 _orientation.Normalize();
2578 2258
2579 d.Vector3 lpos = d.GeomGetPosition(prim_geom); 2259 d.Vector3 lpos = d.GeomGetPosition(prim_geom);
2580 _position.X = lpos.X; 2260 _position.X = lpos.X;
@@ -2684,27 +2364,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2684 2364
2685 private void changeadd() 2365 private void changeadd()
2686 { 2366 {
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 } 2367 }
2709 2368
2710 private void changeAngularLock(Vector3 newLock) 2369 private void changeAngularLock(Vector3 newLock)
@@ -2774,6 +2433,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2774 _target_velocity = Vector3.Zero; 2433 _target_velocity = Vector3.Zero;
2775 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) 2434 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
2776 m_vehicle.Stop(); 2435 m_vehicle.Stop();
2436
2437 _zeroFlag = false;
2438 base.RequestPhysicsterseUpdate();
2777 } 2439 }
2778 2440
2779 if (Body != IntPtr.Zero) 2441 if (Body != IntPtr.Zero)
@@ -3148,7 +2810,63 @@ namespace OpenSim.Region.Physics.OdePlugin
3148 resetCollisionAccounting(); 2810 resetCollisionAccounting();
3149 } 2811 }
3150 2812
3151 private void changeprimsizeshape() 2813 private void changeSize(Vector3 newSize)
2814 {
2815 }
2816
2817 private void changeShape(PrimitiveBaseShape newShape)
2818 {
2819 }
2820
2821 private void changeAddPhysRep(ODEPhysRepData repData)
2822 {
2823 _size = repData.size; //??
2824 _pbs = repData.pbs;
2825 m_shapetype = repData.shapetype;
2826
2827 m_mesh = repData.mesh;
2828
2829 m_assetID = repData.assetID;
2830 m_meshState = repData.meshState;
2831
2832 m_hasOBB = repData.hasOBB;
2833 m_OBBOffset = repData.OBBOffset;
2834 m_OBB = repData.OBB;
2835
2836 primVolume = repData.volume;
2837
2838 CreateGeom();
2839
2840 if (prim_geom != IntPtr.Zero)
2841 {
2842 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2843 d.Quaternion myrot = new d.Quaternion();
2844 myrot.X = _orientation.X;
2845 myrot.Y = _orientation.Y;
2846 myrot.Z = _orientation.Z;
2847 myrot.W = _orientation.W;
2848 d.GeomSetQuaternion(prim_geom, ref myrot);
2849 }
2850
2851 if (!m_isphysical)
2852 {
2853 SetInStaticSpace(this);
2854 UpdateCollisionCatFlags();
2855 ApplyCollisionCatFlags();
2856 }
2857 else
2858 MakeBody();
2859
2860 if ((m_meshState & MeshState.NeedMask) != 0)
2861 {
2862 repData.size = _size;
2863 repData.pbs = _pbs;
2864 repData.shapetype = m_shapetype;
2865 _parent_scene.m_meshWorker.RequestMesh(repData);
2866 }
2867 }
2868
2869 private void changePhysRepData(ODEPhysRepData repData)
3152 { 2870 {
3153 CheckDelaySelect(); 2871 CheckDelaySelect();
3154 2872
@@ -3170,16 +2888,22 @@ namespace OpenSim.Region.Physics.OdePlugin
3170 2888
3171 RemoveGeom(); 2889 RemoveGeom();
3172 2890
3173 // we don't need to do space calculation because the client sends a position update also. 2891 _size = repData.size;
3174 if (_size.X <= 0) 2892 _pbs = repData.pbs;
3175 _size.X = 0.01f; 2893 m_shapetype = repData.shapetype;
3176 if (_size.Y <= 0)
3177 _size.Y = 0.01f;
3178 if (_size.Z <= 0)
3179 _size.Z = 0.01f;
3180 // Construction of new prim
3181 2894
3182 CreateGeom(); 2895 m_mesh = repData.mesh;
2896
2897 m_assetID = repData.assetID;
2898 m_meshState = repData.meshState;
2899
2900 m_hasOBB = repData.hasOBB;
2901 m_OBBOffset = repData.OBBOffset;
2902 m_OBB = repData.OBB;
2903
2904 primVolume = repData.volume;
2905
2906 CreateGeom();
3183 2907
3184 if (prim_geom != IntPtr.Zero) 2908 if (prim_geom != IntPtr.Zero)
3185 { 2909 {
@@ -3202,29 +2926,24 @@ namespace OpenSim.Region.Physics.OdePlugin
3202 } 2926 }
3203 } 2927 }
3204 else 2928 else
3205 MakeBody(); 2929 MakeBody();
3206 } 2930 }
3207
3208 else 2931 else
3209 { 2932 {
2933 SetInStaticSpace(this);
3210 UpdateCollisionCatFlags(); 2934 UpdateCollisionCatFlags();
3211 ApplyCollisionCatFlags(); 2935 ApplyCollisionCatFlags();
3212 } 2936 }
3213 2937
3214 resetCollisionAccounting(); 2938 resetCollisionAccounting();
3215 }
3216
3217 private void changeSize(Vector3 newSize)
3218 {
3219 _size = newSize;
3220 changeprimsizeshape();
3221 }
3222 2939
3223 private void changeShape(PrimitiveBaseShape newShape) 2940 if ((m_meshState & MeshState.NeedMask) != 0)
3224 { 2941 {
3225 if(newShape != null) 2942 repData.size = _size;
3226 _pbs = newShape; 2943 repData.pbs = _pbs;
3227 changeprimsizeshape(); 2944 repData.shapetype = m_shapetype;
2945 _parent_scene.m_meshWorker.RequestMesh(repData);
2946 }
3228 } 2947 }
3229 2948
3230 private void changeFloatOnWater(bool newval) 2949 private void changeFloatOnWater(bool newval)
@@ -3891,7 +3610,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3891 3610
3892 public bool DoAChange(changes what, object arg) 3611 public bool DoAChange(changes what, object arg)
3893 { 3612 {
3894 if (prim_geom == IntPtr.Zero && what != changes.Add && what != changes.Remove) 3613 if (prim_geom == IntPtr.Zero && what != changes.Add && what != changes.AddPhysRep && what != changes.Remove)
3895 { 3614 {
3896 return false; 3615 return false;
3897 } 3616 }
@@ -3902,6 +3621,11 @@ namespace OpenSim.Region.Physics.OdePlugin
3902 case changes.Add: 3621 case changes.Add:
3903 changeadd(); 3622 changeadd();
3904 break; 3623 break;
3624
3625 case changes.AddPhysRep:
3626 changeAddPhysRep((ODEPhysRepData)arg);
3627 break;
3628
3905 case changes.Remove: 3629 case changes.Remove:
3906 //If its being removed, we don't want to rebuild the physical rep at all, so ignore this stuff... 3630 //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 3631 //When we return true, it destroys all of the prims in the linkset anyway
@@ -3984,6 +3708,10 @@ namespace OpenSim.Region.Physics.OdePlugin
3984 changeShape((PrimitiveBaseShape)arg); 3708 changeShape((PrimitiveBaseShape)arg);
3985 break; 3709 break;
3986 3710
3711 case changes.PhysRepData:
3712 changePhysRepData((ODEPhysRepData) arg);
3713 break;
3714
3987 case changes.CollidesWater: 3715 case changes.CollidesWater:
3988 changeFloatOnWater((bool)arg); 3716 changeFloatOnWater((bool)arg);
3989 break; 3717 break;
@@ -4072,6 +3800,8 @@ namespace OpenSim.Region.Physics.OdePlugin
4072 donullchange(); 3800 donullchange();
4073 break; 3801 break;
4074 3802
3803
3804
4075 default: 3805 default:
4076 donullchange(); 3806 donullchange();
4077 break; 3807 break;