diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs | 150 |
1 files changed, 78 insertions, 72 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs index 6bdc089..024835c 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs | |||
@@ -18,6 +18,23 @@ using OpenMetaverse; | |||
18 | 18 | ||
19 | namespace OpenSim.Region.Physics.OdePlugin | 19 | namespace OpenSim.Region.Physics.OdePlugin |
20 | { | 20 | { |
21 | public enum MeshState : byte | ||
22 | { | ||
23 | noNeed = 0, | ||
24 | |||
25 | loadingAsset = 1, | ||
26 | |||
27 | AssetOK = 0x0f, // 00001111 | ||
28 | |||
29 | NeedMask = 0x30, // 00110000 | ||
30 | needMesh = 0x10, // 00010000 | ||
31 | needAsset = 0x20, // 00100000 | ||
32 | |||
33 | FailMask = 0xC0, // 11000000 | ||
34 | AssetFailed = 0x40, // 01000000 | ||
35 | MeshFailed = 0x80 // 10000000 | ||
36 | } | ||
37 | |||
21 | public enum meshWorkerCmnds : byte | 38 | public enum meshWorkerCmnds : byte |
22 | { | 39 | { |
23 | nop = 0, | 40 | nop = 0, |
@@ -43,13 +60,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
43 | public byte shapetype; | 60 | public byte shapetype; |
44 | public bool hasOBB; | 61 | public bool hasOBB; |
45 | public bool hasMeshVolume; | 62 | public bool hasMeshVolume; |
46 | public AssetState assetState; | 63 | public MeshState meshState; |
47 | public UUID? assetID; | 64 | public UUID? assetID; |
48 | public meshWorkerCmnds comand; | 65 | public meshWorkerCmnds comand; |
49 | } | 66 | } |
50 | 67 | ||
51 | |||
52 | |||
53 | public class ODEMeshWorker | 68 | public class ODEMeshWorker |
54 | { | 69 | { |
55 | 70 | ||
@@ -138,16 +153,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
138 | repData.size = size; | 153 | repData.size = size; |
139 | repData.shapetype = shapetype; | 154 | repData.shapetype = shapetype; |
140 | 155 | ||
141 | // if (CheckMeshDone(repData)) | 156 | CheckMeshDone(repData); |
142 | { | 157 | CalcVolumeData(repData); |
143 | CheckMeshDone(repData); | 158 | m_scene.AddChange(actor, changes.PhysRepData, repData); |
144 | CalcVolumeData(repData); | 159 | return; |
145 | m_scene.AddChange(actor, changes.PhysRepData, repData); | ||
146 | return; | ||
147 | } | ||
148 | |||
149 | // repData.comand = meshWorkerCmnds.changefull; | ||
150 | // createqueue.Enqueue(repData); | ||
151 | } | 160 | } |
152 | 161 | ||
153 | public void NewActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs, | 162 | public void NewActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs, |
@@ -159,39 +168,43 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
159 | repData.size = size; | 168 | repData.size = size; |
160 | repData.shapetype = shapetype; | 169 | repData.shapetype = shapetype; |
161 | 170 | ||
162 | // bool done = CheckMeshDone(repData); | ||
163 | |||
164 | CheckMeshDone(repData); | 171 | CheckMeshDone(repData); |
165 | CalcVolumeData(repData); | 172 | CalcVolumeData(repData); |
166 | m_scene.AddChange(actor, changes.AddPhysRep, repData); | 173 | m_scene.AddChange(actor, changes.AddPhysRep, repData); |
167 | // if (done) | ||
168 | return; | ||
169 | |||
170 | // repData.comand = meshWorkerCmnds.addnew; | ||
171 | // createqueue.Enqueue(repData); | ||
172 | } | 174 | } |
173 | 175 | ||
174 | public void RequestMeshAsset(ODEPhysRepData repData) | 176 | public void RequestMesh(ODEPhysRepData repData) |
175 | { | 177 | { |
176 | if (repData.assetState != AssetState.needAsset) | ||
177 | return; | ||
178 | |||
179 | repData.mesh = null; | 178 | repData.mesh = null; |
180 | 179 | ||
181 | if (repData.assetID == null || repData.assetID == UUID.Zero) | 180 | if (repData.meshState == MeshState.needMesh) |
182 | { | 181 | { |
183 | repData.assetState = AssetState.noNeedAsset; | ||
184 | repData.comand = meshWorkerCmnds.changefull; | 182 | repData.comand = meshWorkerCmnds.changefull; |
185 | createqueue.Enqueue(repData); | 183 | createqueue.Enqueue(repData); |
186 | return; | ||
187 | } | 184 | } |
185 | else if (repData.meshState == MeshState.needAsset) | ||
186 | { | ||
187 | PrimitiveBaseShape pbs = repData.pbs; | ||
188 | |||
189 | // check if we got outdated | ||
190 | |||
191 | if (!pbs.SculptEntry || pbs.SculptTexture == UUID.Zero) | ||
192 | { | ||
193 | repData.meshState = MeshState.noNeed; | ||
194 | return; | ||
195 | } | ||
196 | |||
197 | if (pbs.SculptTexture != repData.assetID) | ||
198 | return; | ||
188 | 199 | ||
189 | repData.assetState = AssetState.loadingAsset; | 200 | repData.meshState = MeshState.loadingAsset; |
190 | 201 | ||
191 | repData.comand = meshWorkerCmnds.getmesh; | 202 | repData.comand = meshWorkerCmnds.getmesh; |
192 | createqueue.Enqueue(repData); | 203 | createqueue.Enqueue(repData); |
204 | } | ||
193 | } | 205 | } |
194 | 206 | ||
207 | // creates and prepares a mesh to use and calls parameters estimation | ||
195 | public bool CreateActorPhysRep(ODEPhysRepData repData) | 208 | public bool CreateActorPhysRep(ODEPhysRepData repData) |
196 | { | 209 | { |
197 | getMesh(repData); | 210 | getMesh(repData); |
@@ -210,7 +223,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
210 | { | 223 | { |
211 | m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}", | 224 | m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}", |
212 | repData.actor.Name, repData.pbs.SculptTexture.ToString()); | 225 | repData.actor.Name, repData.pbs.SculptTexture.ToString()); |
213 | repData.assetState = AssetState.AssetFailed; | 226 | repData.meshState = MeshState.MeshFailed; |
214 | repData.hasOBB = false; | 227 | repData.hasOBB = false; |
215 | repData.mesh = null; | 228 | repData.mesh = null; |
216 | m_scene.mesher.ReleaseMesh(mesh); | 229 | m_scene.mesher.ReleaseMesh(mesh); |
@@ -237,6 +250,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
237 | createqueue.Enqueue(repData); | 250 | createqueue.Enqueue(repData); |
238 | } | 251 | } |
239 | } | 252 | } |
253 | else | ||
254 | repData.pbs.SculptData = Utils.EmptyBytes; | ||
240 | } | 255 | } |
241 | 256 | ||
242 | public void DoRepDataGetMesh(ODEPhysRepData repData) | 257 | public void DoRepDataGetMesh(ODEPhysRepData repData) |
@@ -244,7 +259,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
244 | if (!repData.pbs.SculptEntry) | 259 | if (!repData.pbs.SculptEntry) |
245 | return; | 260 | return; |
246 | 261 | ||
247 | if (repData.assetState != AssetState.loadingAsset) | 262 | if (repData.meshState != MeshState.loadingAsset) |
248 | return; | 263 | return; |
249 | 264 | ||
250 | if (repData.assetID == null || repData.assetID == UUID.Zero) | 265 | if (repData.assetID == null || repData.assetID == UUID.Zero) |
@@ -381,34 +396,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
381 | return true; | 396 | return true; |
382 | } | 397 | } |
383 | 398 | ||
399 | // see if we need a mesh and if so if we have a cached one | ||
400 | // called with a new repData | ||
384 | public bool CheckMeshDone(ODEPhysRepData repData) | 401 | public bool CheckMeshDone(ODEPhysRepData repData) |
385 | { | 402 | { |
386 | PhysicsActor actor = repData.actor; | 403 | PhysicsActor actor = repData.actor; |
387 | PrimitiveBaseShape pbs = repData.pbs; | 404 | PrimitiveBaseShape pbs = repData.pbs; |
388 | 405 | ||
389 | repData.mesh = null; | ||
390 | repData.hasOBB = false; | ||
391 | |||
392 | if (!needsMeshing(pbs)) | 406 | if (!needsMeshing(pbs)) |
393 | { | 407 | { |
394 | repData.assetState = AssetState.noNeedAsset; | 408 | repData.meshState = MeshState.noNeed; |
395 | return true; | 409 | return true; |
396 | } | 410 | } |
397 | 411 | ||
398 | if (pbs.SculptEntry) | ||
399 | { | ||
400 | if (repData.assetState == AssetState.AssetFailed) | ||
401 | { | ||
402 | if (pbs.SculptTexture == repData.assetID) | ||
403 | return true; | ||
404 | } | ||
405 | } | ||
406 | else | ||
407 | { | ||
408 | repData.assetState = AssetState.noNeedAsset; | ||
409 | repData.assetID = null; | ||
410 | } | ||
411 | |||
412 | IMesh mesh = null; | 412 | IMesh mesh = null; |
413 | 413 | ||
414 | Vector3 size = repData.size; | 414 | Vector3 size = repData.size; |
@@ -425,7 +425,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
425 | if (pbs.SculptType != (byte)SculptType.Mesh) | 425 | if (pbs.SculptType != (byte)SculptType.Mesh) |
426 | clod = (int)LevelOfDetail.Low; | 426 | clod = (int)LevelOfDetail.Low; |
427 | } | 427 | } |
428 | |||
428 | mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); | 429 | mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); |
430 | |||
429 | if (mesh == null) | 431 | if (mesh == null) |
430 | { | 432 | { |
431 | if (pbs.SculptEntry) | 433 | if (pbs.SculptEntry) |
@@ -433,13 +435,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
433 | if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero) | 435 | if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero) |
434 | { | 436 | { |
435 | repData.assetID = pbs.SculptTexture; | 437 | repData.assetID = pbs.SculptTexture; |
436 | repData.assetState = AssetState.needAsset; | 438 | repData.meshState = MeshState.needAsset; |
437 | } | 439 | } |
438 | else | 440 | else |
439 | repData.assetState = AssetState.AssetFailed; | 441 | repData.meshState = MeshState.MeshFailed; |
440 | } | 442 | } |
441 | else | 443 | else |
442 | repData.assetState = AssetState.needAsset; | 444 | repData.meshState = MeshState.needMesh; |
443 | 445 | ||
444 | return false; | 446 | return false; |
445 | } | 447 | } |
@@ -447,14 +449,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
447 | repData.mesh = mesh; | 449 | repData.mesh = mesh; |
448 | if (pbs.SculptEntry) | 450 | if (pbs.SculptEntry) |
449 | { | 451 | { |
450 | repData.assetState = AssetState.AssetOK; | 452 | repData.meshState = MeshState.AssetOK; |
451 | repData.assetID = pbs.SculptTexture; | 453 | repData.assetID = pbs.SculptTexture; |
452 | pbs.SculptData = Utils.EmptyBytes; | ||
453 | } | 454 | } |
455 | |||
456 | pbs.SculptData = Utils.EmptyBytes; | ||
454 | return true; | 457 | return true; |
455 | } | 458 | } |
456 | 459 | ||
457 | |||
458 | public bool getMesh(ODEPhysRepData repData) | 460 | public bool getMesh(ODEPhysRepData repData) |
459 | { | 461 | { |
460 | PhysicsActor actor = repData.actor; | 462 | PhysicsActor actor = repData.actor; |
@@ -467,16 +469,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
467 | if (!needsMeshing(pbs)) | 469 | if (!needsMeshing(pbs)) |
468 | return false; | 470 | return false; |
469 | 471 | ||
472 | if (repData.meshState == MeshState.MeshFailed) | ||
473 | return false; | ||
474 | |||
470 | if (pbs.SculptEntry) | 475 | if (pbs.SculptEntry) |
471 | { | 476 | { |
472 | if (repData.assetState == AssetState.AssetFailed) | 477 | if (repData.meshState == MeshState.AssetFailed) |
473 | { | 478 | { |
474 | if (pbs.SculptTexture == repData.assetID) | 479 | if (pbs.SculptTexture == repData.assetID) |
475 | return true; | 480 | return true; |
476 | } | 481 | } |
477 | } | 482 | } |
478 | 483 | ||
479 | repData.assetState = AssetState.noNeedAsset; | 484 | repData.meshState = MeshState.noNeed; |
480 | 485 | ||
481 | IMesh mesh = null; | 486 | IMesh mesh = null; |
482 | Vector3 size = repData.size; | 487 | Vector3 size = repData.size; |
@@ -492,7 +497,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
492 | if (pbs.SculptType != (byte)SculptType.Mesh) | 497 | if (pbs.SculptType != (byte)SculptType.Mesh) |
493 | clod = (int)LevelOfDetail.Low; | 498 | clod = (int)LevelOfDetail.Low; |
494 | } | 499 | } |
500 | |||
501 | // check cached | ||
495 | mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); | 502 | mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); |
503 | |||
496 | if (mesh == null) | 504 | if (mesh == null) |
497 | { | 505 | { |
498 | if (pbs.SculptEntry) | 506 | if (pbs.SculptEntry) |
@@ -501,17 +509,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
501 | return false; | 509 | return false; |
502 | 510 | ||
503 | repData.assetID = pbs.SculptTexture; | 511 | repData.assetID = pbs.SculptTexture; |
504 | repData.assetState = AssetState.AssetOK; | 512 | repData.meshState = MeshState.AssetOK; |
505 | 513 | ||
506 | if (pbs.SculptData == null || pbs.SculptData.Length == 0) | 514 | if (pbs.SculptData == null || pbs.SculptData.Length == 0) |
507 | { | 515 | { |
508 | repData.assetState = AssetState.needAsset; | 516 | repData.meshState = MeshState.needAsset; |
509 | return false; | 517 | return false; |
510 | } | 518 | } |
511 | } | 519 | } |
512 | 520 | ||
513 | mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex); | 521 | mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex); |
514 | |||
515 | } | 522 | } |
516 | 523 | ||
517 | repData.mesh = mesh; | 524 | repData.mesh = mesh; |
@@ -520,13 +527,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
520 | if (mesh == null) | 527 | if (mesh == null) |
521 | { | 528 | { |
522 | if (pbs.SculptEntry) | 529 | if (pbs.SculptEntry) |
523 | repData.assetState = AssetState.AssetFailed; | 530 | repData.meshState = MeshState.AssetFailed; |
531 | else | ||
532 | repData.meshState = MeshState.MeshFailed; | ||
524 | 533 | ||
525 | return false; | 534 | return false; |
526 | } | 535 | } |
527 | 536 | ||
528 | if (pbs.SculptEntry) | 537 | repData.meshState = MeshState.AssetOK; |
529 | repData.assetState = AssetState.AssetOK; | ||
530 | 538 | ||
531 | return true; | 539 | return true; |
532 | } | 540 | } |
@@ -866,7 +874,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
866 | m_log = plog; | 874 | m_log = plog; |
867 | repData = pRepData; | 875 | repData = pRepData; |
868 | 876 | ||
869 | repData.assetState = AssetState.AssetFailed; | 877 | repData.meshState = MeshState.AssetFailed; |
870 | if (provider == null) | 878 | if (provider == null) |
871 | return; | 879 | return; |
872 | 880 | ||
@@ -877,29 +885,27 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
877 | if (assetID == UUID.Zero) | 885 | if (assetID == UUID.Zero) |
878 | return; | 886 | return; |
879 | 887 | ||
880 | repData.assetState = AssetState.loadingAsset; | 888 | repData.meshState = MeshState.loadingAsset; |
881 | provider(assetID, ODEassetReceived); | 889 | provider(assetID, ODEassetReceived); |
882 | } | 890 | } |
883 | 891 | ||
884 | void ODEassetReceived(AssetBase asset) | 892 | void ODEassetReceived(AssetBase asset) |
885 | { | 893 | { |
886 | repData.assetState = AssetState.AssetFailed; | 894 | repData.meshState = MeshState.AssetFailed; |
887 | if (asset != null) | 895 | if (asset != null) |
888 | { | 896 | { |
889 | if (asset.Data != null && asset.Data.Length > 0) | 897 | if (asset.Data != null && asset.Data.Length > 0) |
890 | { | 898 | { |
899 | repData.meshState = MeshState.noNeed; | ||
900 | |||
891 | if (!repData.pbs.SculptEntry) | 901 | if (!repData.pbs.SculptEntry) |
892 | return; | 902 | return; |
893 | if (repData.pbs.SculptTexture != repData.assetID) | 903 | if (repData.pbs.SculptTexture != repData.assetID) |
894 | return; | 904 | return; |
895 | 905 | ||
896 | // asset get may return a pointer to the same asset data | ||
897 | // for similar prims and we destroy with it | ||
898 | // so waste a lot of time stressing gc and hoping it clears things | ||
899 | // TODO avoid this | ||
900 | repData.pbs.SculptData = new byte[asset.Data.Length]; | 906 | repData.pbs.SculptData = new byte[asset.Data.Length]; |
901 | asset.Data.CopyTo(repData.pbs.SculptData,0); | 907 | asset.Data.CopyTo(repData.pbs.SculptData,0); |
902 | repData.assetState = AssetState.AssetOK; | 908 | repData.meshState = MeshState.AssetOK; |
903 | m_worker.AssetLoaded(repData); | 909 | m_worker.AssetLoaded(repData); |
904 | } | 910 | } |
905 | else | 911 | else |