diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 858 |
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; |