aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin
diff options
context:
space:
mode:
authorUbitUmarov2012-10-07 01:20:52 +0100
committerUbitUmarov2012-10-07 01:20:52 +0100
commit78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100 (patch)
treed73921adb6a2e7f9c518a50a65c843ef7d95b539 /OpenSim/Region/Physics/UbitOdePlugin
parentMerge branch 'avination' into ubitwork (diff)
downloadopensim-SC-78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100.zip
opensim-SC-78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100.tar.gz
opensim-SC-78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100.tar.bz2
opensim-SC-78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100.tar.xz
[DANGER UNTESTED] ODE mesh assets. Other plugins will not do meshs/sculpts
now
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs1
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs560
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs830
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs187
4 files changed, 606 insertions, 972 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index c363310..f5bf05d 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -172,7 +172,6 @@ namespace OpenSim.Region.Physics.OdePlugin
172 // force lower density for testing 172 // force lower density for testing
173 m_density = 3.0f; 173 m_density = 3.0f;
174 174
175
176 mu = parent_scene.AvatarFriction; 175 mu = parent_scene.AvatarFriction;
177 176
178 walkDivisor = walk_divisor; 177 walkDivisor = walk_divisor;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
index 702c336..3fcbb1b 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
@@ -18,26 +18,63 @@ using OpenMetaverse;
18 18
19namespace OpenSim.Region.Physics.OdePlugin 19namespace OpenSim.Region.Physics.OdePlugin
20{ 20{
21 public enum meshWorkerCmnds : byte
22 {
23 nop = 0,
24 addnew,
25 changefull,
26 changesize,
27 changeshapetype,
28 getmesh,
29 }
30
31 public class ODEPhysRepData
32 {
33 public PhysicsActor actor;
34 public PrimitiveBaseShape pbs;
35 public IMesh mesh;
36
37 public Vector3 size;
38 public Vector3 OBB;
39 public Vector3 OBBOffset;
40
41 public float volume;
42
43 public float physCost;
44 public float streamCost;
45 public byte shapetype;
46 public bool hasOBB;
47 public bool hasMeshVolume;
48 public AssetState assetState;
49 public UUID? assetID;
50 public meshWorkerCmnds comand;
51 }
52
53
54
21 public class ODEMeshWorker 55 public class ODEMeshWorker
22 { 56 {
57
23 private ILog m_log; 58 private ILog m_log;
24 private OdeScene m_scene; 59 private OdeScene m_scene;
25 private IMesher m_mesher; 60 private IMesher m_mesher;
26 61
27
28 public bool meshSculptedPrim = true; 62 public bool meshSculptedPrim = true;
29 public bool forceSimplePrimMeshing = false; 63 public bool forceSimplePrimMeshing = false;
30 public float meshSculptLOD = 32; 64 public float meshSculptLOD = 32;
31 public float MeshSculptphysicalLOD = 32; 65 public float MeshSculptphysicalLOD = 32;
32 66
33 private IntPtr m_workODEspace = IntPtr.Zero;
34 67
35 public ODEMeshWorker(OdeScene pScene, ILog pLog, IMesher pMesher, IntPtr pWorkSpace, IConfig pConfig) 68 private OpenSim.Framework.BlockingQueue<ODEPhysRepData> createqueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>();
69 private bool m_running;
70
71 private Thread m_thread;
72
73 public ODEMeshWorker(OdeScene pScene, ILog pLog, IMesher pMesher, IConfig pConfig)
36 { 74 {
37 m_scene = pScene; 75 m_scene = pScene;
38 m_log = pLog; 76 m_log = pLog;
39 m_mesher = pMesher; 77 m_mesher = pMesher;
40 m_workODEspace = pWorkSpace;
41 78
42 if (pConfig != null) 79 if (pConfig != null)
43 { 80 {
@@ -46,8 +83,177 @@ namespace OpenSim.Region.Physics.OdePlugin
46 meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD); 83 meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
47 MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD); 84 MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
48 } 85 }
86 m_running = true;
87 m_thread = new Thread(DoWork);
88 m_thread.Start();
89 }
90
91 private void DoWork()
92 {
93 while(m_running)
94 {
95 ODEPhysRepData nextRep = createqueue.Dequeue();
96 if(!m_running)
97 return;
98 if (nextRep == null)
99 continue;
100 if (m_scene.haveActor(nextRep.actor))
101 {
102 switch (nextRep.comand)
103 {
104 case meshWorkerCmnds.changefull:
105 case meshWorkerCmnds.changeshapetype:
106 case meshWorkerCmnds.changesize:
107 if (CreateActorPhysRep(nextRep) && m_scene.haveActor(nextRep.actor))
108 m_scene.AddChange(nextRep.actor, changes.PhysRepData, nextRep);
109 break;
110 case meshWorkerCmnds.addnew:
111 if (CreateActorPhysRep(nextRep))
112 m_scene.AddChange(nextRep.actor, changes.AddPhysRep, nextRep);
113 break;
114 case meshWorkerCmnds.getmesh:
115 DoRepDataGetMesh(nextRep);
116 break;
117 }
118 }
119 }
120 }
121
122 public void Stop()
123 {
124 m_running = false;
125 m_thread.Abort();
126 }
127
128 public void ChangeActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
129 Vector3 size, byte shapetype)
130 {
131 ODEPhysRepData repData = new ODEPhysRepData();
132 repData.actor = actor;
133 repData.pbs = pbs;
134 repData.size = size;
135 repData.shapetype = shapetype;
136
137 // if (CheckMeshDone(repData))
138 {
139 CheckMeshDone(repData);
140 CalcVolumeData(repData);
141 m_scene.AddChange(actor, changes.PhysRepData, repData);
142 return;
143 }
144
145// repData.comand = meshWorkerCmnds.changefull;
146// createqueue.Enqueue(repData);
147 }
148
149 public void NewActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
150 Vector3 size, byte shapetype)
151 {
152 ODEPhysRepData repData = new ODEPhysRepData();
153 repData.actor = actor;
154 repData.pbs = pbs;
155 repData.size = size;
156 repData.shapetype = shapetype;
157
158 // bool done = CheckMeshDone(repData);
159
160 CheckMeshDone(repData);
161 CalcVolumeData(repData);
162 m_scene.AddChange(actor, changes.AddPhysRep, repData);
163// if (done)
164 return;
165
166// repData.comand = meshWorkerCmnds.addnew;
167// createqueue.Enqueue(repData);
168 }
169
170 public void RequestMeshAsset(ODEPhysRepData repData)
171 {
172 if (repData.assetState != AssetState.needAsset)
173 return;
174
175 if (repData.assetID == null || repData.assetID == UUID.Zero)
176 return;
177
178 repData.mesh = null;
179
180 repData.assetState = AssetState.loadingAsset;
181
182 repData.comand = meshWorkerCmnds.getmesh;
183 createqueue.Enqueue(repData);
184 }
185
186 public bool CreateActorPhysRep(ODEPhysRepData repData)
187 {
188 getMesh(repData);
189 IMesh mesh = repData.mesh;
190
191 if (mesh != null)
192 {
193 IntPtr vertices, indices;
194 int vertexCount, indexCount;
195 int vertexStride, triStride;
196
197 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
198 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
199
200 if (vertexCount == 0 || indexCount == 0)
201 {
202 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}",
203 repData.actor.Name, repData.pbs.SculptTexture.ToString());
204 repData.assetState = AssetState.AssetFailed;
205 repData.hasOBB = false;
206 repData.mesh = null;
207 m_scene.mesher.ReleaseMesh(mesh);
208 }
209 else
210 {
211 repData.OBBOffset = mesh.GetCentroid();
212 repData.OBB = mesh.GetOBB();
213 repData.hasOBB = true;
214 repData.physCost = 0.0013f * (float)indexCount;
215 // todo
216 repData.streamCost = 1.0f;
217 mesh.releaseSourceMeshData();
218 }
219 }
220 CalcVolumeData(repData);
221 return true;
222 }
223
224 public void AssetLoaded(ODEPhysRepData repData)
225 {
226 if (m_scene.haveActor(repData.actor))
227 {
228 if (needsMeshing(repData.pbs)) // no need for pbs now?
229 {
230 repData.comand = meshWorkerCmnds.changefull;
231 createqueue.Enqueue(repData);
232 }
233 }
49 } 234 }
50 235
236 public void DoRepDataGetMesh(ODEPhysRepData repData)
237 {
238 if (!repData.pbs.SculptEntry)
239 return;
240
241 if (repData.assetState != AssetState.loadingAsset)
242 return;
243
244 if (repData.assetID == null || repData.assetID == UUID.Zero)
245 return;
246
247 if (repData.assetID != repData.pbs.SculptTexture)
248 return;
249
250 RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod;
251 if (assetProvider == null)
252 return;
253 ODEAssetRequest asr = new ODEAssetRequest(this, assetProvider, repData, m_log);
254 }
255
256
51 /// <summary> 257 /// <summary>
52 /// Routine to figure out if we need to mesh this prim with our mesher 258 /// Routine to figure out if we need to mesh this prim with our mesher
53 /// </summary> 259 /// </summary>
@@ -169,194 +375,151 @@ namespace OpenSim.Region.Physics.OdePlugin
169 return true; 375 return true;
170 } 376 }
171 377
172 public IMesh getMesh(PhysicsActor actor, PrimitiveBaseShape ppbs, Vector3 psize, byte pshapetype) 378 public bool CheckMeshDone(ODEPhysRepData repData)
173 { 379 {
174 if (!(actor is OdePrim)) 380 PhysicsActor actor = repData.actor;
175 return null; 381 PrimitiveBaseShape pbs = repData.pbs;
176 382
177 IMesh mesh = null; 383 repData.mesh = null;
178 PrimitiveBaseShape pbs = ppbs; 384 repData.hasOBB = false;
179 Vector3 size = psize;
180 byte shapetype = pshapetype;
181 385
182 if (needsMeshing(pbs)) 386 if (!needsMeshing(pbs))
183 { 387 {
184 bool convex; 388 repData.assetState = AssetState.noNeedAsset;
185 int clod = (int)LevelOfDetail.High; 389 return true;
186 if (shapetype == 0) 390 }
187 convex = false;
188 else
189 {
190 convex = true;
191 if (pbs.SculptType != (byte)SculptType.Mesh)
192 clod = (int)LevelOfDetail.Low;
193 }
194 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
195 if (mesh == null)
196 {
197 if (!pbs.SculptEntry)
198 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
199
200 if (pbs.SculptTexture == UUID.Zero)
201 return null;
202
203 if (pbs.SculptType != (byte)SculptType.Mesh)
204 { // check for sculpt decoded image on cache)
205 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + pbs.SculptTexture.ToString())))
206 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
207 }
208
209 if (pbs.SculptData != null && pbs.SculptData.Length > 0)
210 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
211
212 ODEAssetRequest asr;
213 RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod;
214 if (assetProvider != null)
215 asr = new ODEAssetRequest(this, assetProvider, actor, pbs, m_log);
216 391
217 return null; 392 if (pbs.SculptEntry)
393 {
394 if (repData.assetState == AssetState.AssetFailed)
395 {
396 if (pbs.SculptTexture == repData.assetID)
397 return true;
218 } 398 }
219 } 399 }
220 return mesh; 400 else
221 } 401 {
402 repData.assetState = AssetState.noNeedAsset;
403 repData.assetID = null;
404 }
222 405
223 private bool GetTriMeshGeo(ODEPhysRepData repData) 406 IMesh mesh = null;
224 {
225 IntPtr vertices, indices;
226 IntPtr triMeshData = IntPtr.Zero;
227 IntPtr geo = IntPtr.Zero;
228 int vertexCount, indexCount;
229 int vertexStride, triStride;
230 407
231 PhysicsActor actor = repData.actor; 408 Vector3 size = repData.size;
409 byte shapetype = repData.shapetype;
232 410
233 IMesh mesh = repData.mesh; 411 bool convex;
234 412
235 if (mesh == null) 413 int clod = (int)LevelOfDetail.High;
414 if (shapetype == 0)
415 convex = false;
416 else
236 { 417 {
237 mesh = getMesh(repData.actor, repData.pbs, repData.size, repData.shapetype); 418 convex = true;
419 if (pbs.SculptType != (byte)SculptType.Mesh)
420 clod = (int)LevelOfDetail.Low;
238 } 421 }
239 422 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
240 if (mesh == null) 423 if (mesh == null)
424 {
425 if (pbs.SculptEntry)
426 {
427 if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero)
428 {
429 repData.assetID = pbs.SculptTexture;
430 repData.assetState = AssetState.needAsset;
431 }
432 else
433 repData.assetState = AssetState.AssetFailed;
434 }
241 return false; 435 return false;
436 }
242 437
243 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap 438 repData.mesh = mesh;
244 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage 439 if (pbs.SculptEntry)
245
246 if (vertexCount == 0 || indexCount == 0)
247 { 440 {
248 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}", 441 repData.assetState = AssetState.AssetOK;
249 actor.Name, repData.pbs.SculptTexture.ToString()); 442 repData.assetID = pbs.SculptTexture;
250 mesh.releaseSourceMeshData(); 443 pbs.SculptData = Utils.EmptyBytes;
251 return false;
252 } 444 }
445 return true;
446 }
253 447
254 repData.OBBOffset = mesh.GetCentroid();
255 repData.OBB = mesh.GetOBB();
256 repData.hasOBB = true;
257 repData.physCost = 0.0013f * (float)indexCount;
258 448
259 mesh.releaseSourceMeshData(); 449 public bool getMesh(ODEPhysRepData repData)
450 {
451 PhysicsActor actor = repData.actor;
260 452
261 try 453 PrimitiveBaseShape pbs = repData.pbs;
262 {
263 triMeshData = d.GeomTriMeshDataCreate();
264 454
265 d.GeomTriMeshDataBuildSimple(triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 455 repData.mesh = null;
266 d.GeomTriMeshDataPreprocess(triMeshData); 456 repData.hasOBB = false;
267 457
268 m_scene.waitForSpaceUnlock(m_workODEspace); 458 if (!needsMeshing(pbs))
269 geo = d.CreateTriMesh(m_workODEspace, triMeshData, null, null, null); 459 return false;
270 }
271 460
272 catch (Exception e) 461 if (pbs.SculptEntry)
273 { 462 {
274 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", actor.Name, e); 463 if (repData.assetState == AssetState.AssetFailed)
275 if (triMeshData != IntPtr.Zero)
276 { 464 {
277 d.GeomTriMeshDataDestroy(triMeshData); 465 if (pbs.SculptTexture == repData.assetID)
278 repData.triMeshData = IntPtr.Zero; 466 return true;
279 } 467 }
280 repData.geo = IntPtr.Zero;
281 return false;
282 } 468 }
283 469
284 repData.geo = geo; 470 repData.assetState = AssetState.noNeedAsset;
285 repData.triMeshData = triMeshData;
286 repData.curSpace = m_workODEspace;
287 return true;
288 }
289
290 public ODEPhysRepData CreateActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs, IMesh pMesh, Vector3 size, byte shapetype)
291 {
292 ODEPhysRepData repData = new ODEPhysRepData();
293 471
294 repData.actor = actor; 472 IMesh mesh = null;
295 repData.pbs = pbs; 473 Vector3 size = repData.size;
296 repData.mesh = pMesh; 474 byte shapetype = repData.shapetype;
297 repData.size = size;
298 repData.shapetype = shapetype;
299 475
300 IntPtr geo = IntPtr.Zero; 476 bool convex;
301 bool hasMesh = false; 477 int clod = (int)LevelOfDetail.High;
302 if (needsMeshing(pbs)) 478 if (shapetype == 0)
479 convex = false;
480 else
303 { 481 {
304 if (GetTriMeshGeo(repData)) 482 convex = true;
305 hasMesh = true; 483 if (pbs.SculptType != (byte)SculptType.Mesh)
306 else 484 clod = (int)LevelOfDetail.Low;
307 repData.NoColide = true;
308 } 485 }
309 486 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
310 if (!hasMesh) 487 if (mesh == null)
311 { 488 {
312 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 489 if (pbs.SculptEntry)
313 && size.X == size.Y && size.Y == size.Z) 490 {
314 { // it's a sphere 491 if (pbs.SculptTexture == UUID.Zero)
315 m_scene.waitForSpaceUnlock(m_workODEspace); 492 return false;
316 try 493
317 { 494 repData.assetID = pbs.SculptTexture;
318 geo = d.CreateSphere(m_workODEspace, size.X * 0.5f); 495 repData.assetState = AssetState.AssetOK;
319 } 496
320 catch (Exception e) 497 if (pbs.SculptData == null || pbs.SculptData.Length == 0)
321 {
322 m_log.WarnFormat("[PHYSICS]: Create sphere failed: {0}", e);
323 return null;
324 }
325 }
326 else
327 {// do it as a box
328 m_scene.waitForSpaceUnlock(m_workODEspace);
329 try
330 {
331 //Console.WriteLine(" CreateGeom 4");
332 geo = d.CreateBox(m_workODEspace, size.X, size.Y, size.Z);
333 }
334 catch (Exception e)
335 { 498 {
336 m_log.Warn("[PHYSICS]: Create box failed: {0}", e); 499 repData.assetState = AssetState.needAsset;
337 return null; 500 return false;
338 } 501 }
339 } 502 }
340 503
341 repData.physCost = 0.1f; 504 mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
342 repData.streamCost = 1.0f; 505
343 repData.geo = geo;
344 } 506 }
345
346 repData.curSpace = m_workODEspace;
347 507
348 CalcVolumeData(repData); 508 repData.mesh = mesh;
509 repData.pbs.SculptData = Utils.EmptyBytes;
349 510
350 return repData; 511 if (mesh == null)
351 } 512 {
513 if (pbs.SculptEntry)
514 repData.assetState = AssetState.AssetFailed;
352 515
353 public void ChangeActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs, 516 return false;
354 Vector3 size, byte shapetype, MeshWorkerChange what) 517 }
355 { 518
356 ODEPhysRepData repData = CreateActorPhysRep(actor, pbs, null, size, shapetype); 519 if (pbs.SculptEntry)
357 repData.changed |= what; 520 repData.assetState = AssetState.AssetOK;
358 if (repData != null && actor != null) 521
359 ((OdePrim)actor).AddChange(changes.PhysRepData, repData); 522 return true;
360 } 523 }
361 524
362 private void CalculateBasicPrimVolume(ODEPhysRepData repData) 525 private void CalculateBasicPrimVolume(ODEPhysRepData repData)
@@ -662,46 +825,12 @@ namespace OpenSim.Region.Physics.OdePlugin
662 825
663 private void CalcVolumeData(ODEPhysRepData repData) 826 private void CalcVolumeData(ODEPhysRepData repData)
664 { 827 {
665 float volume;
666 Vector3 OBB = repData.size;
667 Vector3 OBBoffset;
668 IntPtr geo = repData.geo;
669
670 if (geo == IntPtr.Zero || repData.triMeshData == IntPtr.Zero)
671 {
672 OBB.X *= 0.5f;
673 OBB.Y *= 0.5f;
674 OBB.Z *= 0.5f;
675
676 repData.OBB = OBB;
677 repData.OBBOffset = Vector3.Zero;
678 }
679 else if (!repData.hasOBB) // should this happen?
680 {
681 d.AABB AABB;
682 d.GeomGetAABB(geo, out AABB); // get the AABB from engine geom
683
684 OBB.X = (AABB.MaxX - AABB.MinX) * 0.5f;
685 OBB.Y = (AABB.MaxY - AABB.MinY) * 0.5f;
686 OBB.Z = (AABB.MaxZ - AABB.MinZ) * 0.5f;
687 repData.OBB = OBB;
688 OBBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f;
689 OBBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f;
690 OBBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f;
691 repData.OBBOffset = Vector3.Zero;
692 }
693
694 // also its own inertia and mass
695 // keep using basic shape mass for now
696 CalculateBasicPrimVolume(repData);
697
698 if (repData.hasOBB) 828 if (repData.hasOBB)
699 { 829 {
700 OBB = repData.OBB; 830 Vector3 OBB = repData.OBB;
701 float pc = repData.physCost; 831 float pc = repData.physCost;
702 float psf = OBB.X * (OBB.Y + OBB.Z) + OBB.Y * OBB.Z; 832 float psf = OBB.X * (OBB.Y + OBB.Z) + OBB.Y * OBB.Z;
703 psf *= 1.33f * .2f; 833 psf *= 1.33f * .2f;
704
705 pc *= psf; 834 pc *= psf;
706 if (pc < 0.1f) 835 if (pc < 0.1f)
707 pc = 0.1f; 836 pc = 0.1f;
@@ -709,54 +838,79 @@ namespace OpenSim.Region.Physics.OdePlugin
709 repData.physCost = pc; 838 repData.physCost = pc;
710 } 839 }
711 else 840 else
841 {
842 Vector3 OBB = repData.size;
843 OBB.X *= 0.5f;
844 OBB.Y *= 0.5f;
845 OBB.Z *= 0.5f;
846
847 repData.OBB = OBB;
848 repData.OBBOffset = Vector3.Zero;
849
712 repData.physCost = 0.1f; 850 repData.physCost = 0.1f;
851 repData.streamCost = 1.0f;
852 }
853
854 CalculateBasicPrimVolume(repData);
713 } 855 }
714 } 856 }
715 857
716 public class ODEAssetRequest 858 public class ODEAssetRequest
717 { 859 {
718 PhysicsActor m_actor;
719 ODEMeshWorker m_worker; 860 ODEMeshWorker m_worker;
720 PrimitiveBaseShape m_pbs;
721 private ILog m_log; 861 private ILog m_log;
862 ODEPhysRepData repData;
722 863
723 public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider, 864 public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider,
724 PhysicsActor pActor, PrimitiveBaseShape ppbs, ILog plog) 865 ODEPhysRepData pRepData, ILog plog)
725 { 866 {
726 m_actor = pActor;
727 m_worker = pWorker; 867 m_worker = pWorker;
728 m_pbs = ppbs;
729 m_log = plog; 868 m_log = plog;
869 repData = pRepData;
730 870
871 repData.assetState = AssetState.AssetFailed;
731 if (provider == null) 872 if (provider == null)
732 return; 873 return;
733 874
734 UUID assetID = m_pbs.SculptTexture; 875 if (repData.assetID == null)
876 return;
877
878 UUID assetID = (UUID) repData.assetID;
735 if (assetID == UUID.Zero) 879 if (assetID == UUID.Zero)
736 return; 880 return;
737 881
882 repData.assetState = AssetState.loadingAsset;
738 provider(assetID, ODEassetReceived); 883 provider(assetID, ODEassetReceived);
739 } 884 }
740 885
741 void ODEassetReceived(AssetBase asset) 886 void ODEassetReceived(AssetBase asset)
742 { 887 {
743 if (m_actor != null && m_pbs != null) 888 repData.assetState = AssetState.AssetFailed;
889 if (asset != null)
744 { 890 {
745 if (asset != null) 891 if (asset.Data != null && asset.Data.Length > 0)
746 { 892 {
747 if (asset.Data != null && asset.Data.Length > 0) 893 if (!repData.pbs.SculptEntry)
748 { 894 return;
749 m_pbs.SculptData = asset.Data; 895 if (repData.pbs.SculptTexture != repData.assetID)
750 m_actor.Shape = m_pbs; 896 return;
751 } 897
752 else 898 // asset get may return a pointer to the same asset data
753 m_log.WarnFormat("[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.", 899 // for similar prims and we destroy with it
754 m_actor.Name, asset.ID.ToString()); 900 // so waste a lot of time stressing gc and hoping it clears things
901 // TODO avoid this
902 repData.pbs.SculptData = new byte[asset.Data.Length];
903 asset.Data.CopyTo(repData.pbs.SculptData,0);
904 repData.assetState = AssetState.AssetOK;
905 m_worker.AssetLoaded(repData);
755 } 906 }
756 else 907 else
757 m_log.WarnFormat("[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.", 908 m_log.WarnFormat("[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.",
758 m_actor.Name); 909 repData.actor.Name, asset.ID.ToString());
759 } 910 }
911 else
912 m_log.WarnFormat("[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.",
913 repData.actor.Name);
760 } 914 }
761 } 915 }
762} \ No newline at end of file 916} \ No newline at end of file
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
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index d758c85..5e4c2a5 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -60,29 +60,6 @@ namespace OpenSim.Region.Physics.OdePlugin
60 public int lastframe; 60 public int lastframe;
61 } 61 }
62 62
63 public class ODEPhysRepData
64 {
65 public PhysicsActor actor;
66 public IntPtr geo = IntPtr.Zero;
67 public IntPtr triMeshData = IntPtr.Zero;
68 public IMesh mesh;
69 public IntPtr curSpace = IntPtr.Zero;
70 public PrimitiveBaseShape pbs;
71
72 public Vector3 size = Vector3.Zero;
73 public Vector3 OBB = Vector3.Zero;
74 public Vector3 OBBOffset = Vector3.Zero;
75
76 public float volume;
77
78 public float physCost = 0.0f;
79 public float streamCost = 0;
80 public MeshWorkerChange changed;
81 public byte shapetype = 0;
82 public bool NoColide = false;
83 public bool hasOBB = false;
84 public bool hasMeshVolume = false;
85 }
86 63
87 // colision flags of things others can colide with 64 // colision flags of things others can colide with
88 // rays, sensors, probes removed since can't be colided with 65 // rays, sensors, probes removed since can't be colided with
@@ -133,13 +110,16 @@ namespace OpenSim.Region.Physics.OdePlugin
133 110
134 light = 7 // compatibility with old viewers 111 light = 7 // compatibility with old viewers
135 } 112 }
136 [Flags] 113
137 public enum MeshWorkerChange : uint 114 public enum AssetState : byte
138 { 115 {
139 none = 0, 116 noNeedAsset = 0,
140 size = 1, 117 needAsset = 1,
141 shape = 2, 118 loadingAsset = 2,
142 shapetype = 3, 119 procAsset = 3,
120 AssetOK = 4,
121
122 AssetFailed = 0xff
143 } 123 }
144 124
145 public enum changes : int 125 public enum changes : int
@@ -180,6 +160,7 @@ namespace OpenSim.Region.Physics.OdePlugin
180 Size, 160 Size,
181 Shape, 161 Shape,
182 PhysRepData, 162 PhysRepData,
163 AddPhysRep,
183 164
184 CollidesWater, 165 CollidesWater,
185 VolumeDtc, 166 VolumeDtc,
@@ -330,7 +311,6 @@ namespace OpenSim.Region.Physics.OdePlugin
330 public IntPtr TopSpace; // the global space 311 public IntPtr TopSpace; // the global space
331 public IntPtr ActiveSpace; // space for active prims 312 public IntPtr ActiveSpace; // space for active prims
332 public IntPtr StaticSpace; // space for the static things around 313 public IntPtr StaticSpace; // space for the static things around
333 public IntPtr WorkSpace; // no collisions work space
334 314
335 // some speedup variables 315 // some speedup variables
336 private int spaceGridMaxX; 316 private int spaceGridMaxX;
@@ -342,7 +322,7 @@ namespace OpenSim.Region.Physics.OdePlugin
342 private IntPtr[] staticPrimspaceOffRegion; 322 private IntPtr[] staticPrimspaceOffRegion;
343 323
344 public Object OdeLock; 324 public Object OdeLock;
345 private static Object SimulationLock; 325 public static Object SimulationLock;
346 326
347 public IMesher mesher; 327 public IMesher mesher;
348 328
@@ -403,7 +383,6 @@ namespace OpenSim.Region.Physics.OdePlugin
403 // now the major subspaces 383 // now the major subspaces
404 ActiveSpace = d.HashSpaceCreate(TopSpace); 384 ActiveSpace = d.HashSpaceCreate(TopSpace);
405 StaticSpace = d.HashSpaceCreate(TopSpace); 385 StaticSpace = d.HashSpaceCreate(TopSpace);
406 WorkSpace = d.HashSpaceCreate(TopSpace);
407 } 386 }
408 catch 387 catch
409 { 388 {
@@ -413,12 +392,10 @@ namespace OpenSim.Region.Physics.OdePlugin
413 d.HashSpaceSetLevels(TopSpace, -2, 8); 392 d.HashSpaceSetLevels(TopSpace, -2, 8);
414 d.HashSpaceSetLevels(ActiveSpace, -2, 8); 393 d.HashSpaceSetLevels(ActiveSpace, -2, 8);
415 d.HashSpaceSetLevels(StaticSpace, -2, 8); 394 d.HashSpaceSetLevels(StaticSpace, -2, 8);
416 d.HashSpaceSetLevels(WorkSpace, -2, 8);
417 395
418 // demote to second level 396 // demote to second level
419 d.SpaceSetSublevel(ActiveSpace, 1); 397 d.SpaceSetSublevel(ActiveSpace, 1);
420 d.SpaceSetSublevel(StaticSpace, 1); 398 d.SpaceSetSublevel(StaticSpace, 1);
421 d.SpaceSetSublevel(WorkSpace, 1);
422 399
423 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | 400 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
424 CollisionCategories.Geom | 401 CollisionCategories.Geom |
@@ -436,8 +413,6 @@ namespace OpenSim.Region.Physics.OdePlugin
436 )); 413 ));
437 d.GeomSetCollideBits(StaticSpace, 0); 414 d.GeomSetCollideBits(StaticSpace, 0);
438 415
439 d.GeomSetCategoryBits(WorkSpace, 0);
440 d.GeomSetCollideBits(WorkSpace, 0);
441 416
442 contactgroup = d.JointGroupCreate(0); 417 contactgroup = d.JointGroupCreate(0);
443 //contactgroup 418 //contactgroup
@@ -518,7 +493,7 @@ namespace OpenSim.Region.Physics.OdePlugin
518 } 493 }
519 } 494 }
520 495
521 m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, WorkSpace, physicsconfig); 496 m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, physicsconfig);
522 497
523 HalfOdeStep = ODE_STEPSIZE * 0.5f; 498 HalfOdeStep = ODE_STEPSIZE * 0.5f;
524 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f); 499 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f);
@@ -1316,6 +1291,15 @@ namespace OpenSim.Region.Physics.OdePlugin
1316 _collisionEventPrimRemove.Add(obj); 1291 _collisionEventPrimRemove.Add(obj);
1317 } 1292 }
1318 1293
1294 public override float TimeDilation
1295 {
1296 get { return m_timeDilation; }
1297 }
1298
1299 public override bool SupportsNINJAJoints
1300 {
1301 get { return false; }
1302 }
1319 1303
1320 #region Add/Remove Entities 1304 #region Add/Remove Entities
1321 1305
@@ -1371,117 +1355,59 @@ namespace OpenSim.Region.Physics.OdePlugin
1371 ((OdeCharacter) actor).Destroy(); 1355 ((OdeCharacter) actor).Destroy();
1372 } 1356 }
1373 1357
1374 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
1375 PrimitiveBaseShape pbs, bool isphysical, uint localID)
1376 {
1377 Vector3 pos = position;
1378 Vector3 siz = size;
1379 Quaternion rot = rotation;
1380 1358
1381 OdePrim newPrim; 1359 public void addActivePrim(OdePrim activatePrim)
1382 lock (OdeLock) 1360 {
1361 // adds active prim..
1362 lock (_activeprims)
1383 { 1363 {
1384 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical,false,0,localID); 1364 if (!_activeprims.Contains(activatePrim))
1385 1365 _activeprims.Add(activatePrim);
1386 lock (_prims)
1387 _prims.Add(newPrim);
1388 } 1366 }
1389 return newPrim;
1390 } 1367 }
1391 1368
1392 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, 1369 public void addActiveGroups(OdePrim activatePrim)
1393 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, uint localID)
1394 { 1370 {
1395 Vector3 pos = position; 1371 lock (_activegroups)
1396 Vector3 siz = size;
1397 Quaternion rot = rotation;
1398
1399 OdePrim newPrim;
1400 lock (OdeLock)
1401 { 1372 {
1402 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, isPhantom, 0, localID); 1373 if (!_activegroups.Contains(activatePrim))
1403 1374 _activegroups.Add(activatePrim);
1404 lock (_prims)
1405 _prims.Add(newPrim);
1406 } 1375 }
1407 return newPrim;
1408 } 1376 }
1409 1377
1410 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, 1378 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
1411 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID) 1379 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID)
1412 { 1380 {
1413 Vector3 pos = position;
1414 Vector3 siz = size;
1415 Quaternion rot = rotation;
1416
1417 OdePrim newPrim; 1381 OdePrim newPrim;
1418 lock (OdeLock) 1382 lock (OdeLock)
1419 { 1383 {
1420 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, isPhantom, shapeType, localID); 1384 newPrim = new OdePrim(name, this, position, size, rotation, pbs, isphysical, isPhantom, shapeType, localID);
1421
1422 lock (_prims) 1385 lock (_prims)
1423 _prims.Add(newPrim); 1386 _prims.Add(newPrim);
1424 } 1387 }
1425 return newPrim; 1388 return newPrim;
1426 } 1389 }
1427 1390
1428 public void addActivePrim(OdePrim activatePrim)
1429 {
1430 // adds active prim..
1431 lock (_activeprims)
1432 {
1433 if (!_activeprims.Contains(activatePrim))
1434 _activeprims.Add(activatePrim);
1435 }
1436 }
1437
1438 public void addActiveGroups(OdePrim activatePrim)
1439 {
1440 lock (_activegroups)
1441 {
1442 if (!_activegroups.Contains(activatePrim))
1443 _activegroups.Add(activatePrim);
1444 }
1445 }
1446
1447 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1391 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1448 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid) 1392 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid)
1449 { 1393 {
1450 return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, localid); 1394 return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, 0 , localid);
1451 } 1395 }
1452 1396
1453 1397
1454 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1398 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1455 Vector3 size, Quaternion rotation, bool isPhysical, uint localid) 1399 Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
1456 { 1400 {
1457#if SPAM 1401 return AddPrim(primName, position, size, rotation, pbs, isPhysical,false, 0, localid);
1458 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
1459#endif
1460
1461 return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid);
1462 } 1402 }
1463 1403
1464 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1404 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1465 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid) 1405 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid)
1466 { 1406 {
1467#if SPAM
1468 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
1469#endif
1470 1407
1471 return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid); 1408 return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid);
1472 } 1409 }
1473 1410
1474 public override float TimeDilation
1475 {
1476 get { return m_timeDilation; }
1477 }
1478
1479 public override bool SupportsNINJAJoints
1480 {
1481 get { return false; }
1482 }
1483
1484
1485 public void remActivePrim(OdePrim deactivatePrim) 1411 public void remActivePrim(OdePrim deactivatePrim)
1486 { 1412 {
1487 lock (_activeprims) 1413 lock (_activeprims)
@@ -1534,6 +1460,28 @@ namespace OpenSim.Region.Physics.OdePlugin
1534 } 1460 }
1535 1461
1536 } 1462 }
1463
1464 public bool havePrim(OdePrim prm)
1465 {
1466 lock (_prims)
1467 return _prims.Contains(prm);
1468 }
1469
1470 public bool haveActor(PhysicsActor actor)
1471 {
1472 if (actor is OdePrim)
1473 {
1474 lock (_prims)
1475 return _prims.Contains((OdePrim)actor);
1476 }
1477 else if (actor is OdeCharacter)
1478 {
1479 lock (_characters)
1480 return _characters.Contains((OdeCharacter)actor);
1481 }
1482 return false;
1483 }
1484
1537 #endregion 1485 #endregion
1538 1486
1539 #region Space Separation Calculation 1487 #region Space Separation Calculation
@@ -1706,20 +1654,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1706 { 1654 {
1707 if (world == IntPtr.Zero) 1655 if (world == IntPtr.Zero)
1708 return 0; 1656 return 0;
1657
1658 d.WorldSetQuickStepNumIterations(world, curphysiteractions);
1709 1659
1710 // adjust number of iterations per step
1711
1712// try
1713// {
1714 d.WorldSetQuickStepNumIterations(world, curphysiteractions);
1715/* }
1716 catch (StackOverflowException)
1717 {
1718 m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim.");
1719// ode.drelease(world);
1720 base.TriggerPhysicsBasedRestart();
1721 }
1722*/
1723 while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever 1660 while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever
1724 { 1661 {
1725 try 1662 try
@@ -1747,8 +1684,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1747 } 1684 }
1748 catch 1685 catch
1749 { 1686 {
1750 m_log.Warn("[PHYSICS]: doChange failed for a actor"); 1687 m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}",
1751 }; 1688 item.actor.Name, item.what.ToString());
1689 }
1752 } 1690 }
1753 ttmp = Util.EnvironmentTickCountSubtract(ttmpstart); 1691 ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
1754 if (ttmp > 20) 1692 if (ttmp > 20)
@@ -2491,6 +2429,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2491*/ 2429*/
2492 public override void Dispose() 2430 public override void Dispose()
2493 { 2431 {
2432 if (m_meshWorker != null)
2433 m_meshWorker.Stop();
2434
2494 lock (OdeLock) 2435 lock (OdeLock)
2495 { 2436 {
2496 m_rayCastManager.Dispose(); 2437 m_rayCastManager.Dispose();