aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
diff options
context:
space:
mode:
authorUbitUmarov2012-10-04 04:55:53 +0100
committerUbitUmarov2012-10-04 04:55:53 +0100
commit51e1830f86cd0253879f4f60470a3b5fa2b3db7c (patch)
tree834792c6c8315694219f03590037e9f70dd3e1e4 /OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
parent missing changed file (diff)
downloadopensim-SC-51e1830f86cd0253879f4f60470a3b5fa2b3db7c.zip
opensim-SC-51e1830f86cd0253879f4f60470a3b5fa2b3db7c.tar.gz
opensim-SC-51e1830f86cd0253879f4f60470a3b5fa2b3db7c.tar.bz2
opensim-SC-51e1830f86cd0253879f4f60470a3b5fa2b3db7c.tar.xz
more changes. Most code not in use
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs521
1 files changed, 512 insertions, 9 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
index b0231e9..9bf3667 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
@@ -24,16 +24,20 @@ namespace OpenSim.Region.Physics.OdePlugin
24 private OdeScene m_scene; 24 private OdeScene m_scene;
25 private IMesher m_mesher; 25 private IMesher m_mesher;
26 26
27
27 public bool meshSculptedPrim = true; 28 public bool meshSculptedPrim = true;
28 public bool forceSimplePrimMeshing = false; 29 public bool forceSimplePrimMeshing = false;
29 public float meshSculptLOD = 32; 30 public float meshSculptLOD = 32;
30 public float MeshSculptphysicalLOD = 32; 31 public float MeshSculptphysicalLOD = 32;
31 32
32 public ODEMeshWorker(OdeScene pScene, ILog pLog, IMesher pMesher, IConfig pConfig) 33 private IntPtr m_workODEspace = IntPtr.Zero;
34
35 public ODEMeshWorker(OdeScene pScene, ILog pLog, IMesher pMesher, IntPtr pWorkSpace, IConfig pConfig)
33 { 36 {
34 m_scene = pScene; 37 m_scene = pScene;
35 m_log = pLog; 38 m_log = pLog;
36 m_mesher = pMesher; 39 m_mesher = pMesher;
40 m_workODEspace = pWorkSpace;
37 41
38 if (pConfig != null) 42 if (pConfig != null)
39 { 43 {
@@ -196,24 +200,508 @@ namespace OpenSim.Region.Physics.OdePlugin
196 if (pbs.SculptTexture == UUID.Zero) 200 if (pbs.SculptTexture == UUID.Zero)
197 return null; 201 return null;
198 202
199 if(pbs.SculptType != (byte)SculptType.Mesh) 203 if (pbs.SculptType != (byte)SculptType.Mesh)
200 { // check for sculpt decoded image on cache) 204 { // check for sculpt decoded image on cache)
201 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + pbs.SculptTexture.ToString()))) 205 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + pbs.SculptTexture.ToString())))
202 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex); 206 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
203 } 207 }
204 208
205 if(pbs.SculptData != null && pbs.SculptData.Length >0) 209 if (pbs.SculptData != null && pbs.SculptData.Length > 0)
206 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex); 210 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
207 211
208 ODEAssetRequest asr; 212 ODEAssetRequest asr;
209 RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod; 213 RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod;
210 if (assetProvider != null) 214 if (assetProvider != null)
211 asr = new ODEAssetRequest(this, assetProvider, actor, pbs); 215 asr = new ODEAssetRequest(this, assetProvider, actor, pbs, m_log);
216
212 return null; 217 return null;
213 } 218 }
214 } 219 }
215 return mesh; 220 return mesh;
216 } 221 }
222
223 private bool GetTriMeshGeo(ODEPhysRepData repData)
224 {
225 IntPtr vertices, indices;
226 IntPtr triMeshData = IntPtr.Zero;
227 IntPtr geo = IntPtr.Zero;
228 int vertexCount, indexCount;
229 int vertexStride, triStride;
230
231 PhysicsActor actor = repData.actor;
232
233 IMesh mesh = repData.mesh;
234
235 if (mesh == null)
236 {
237 mesh = getMesh(repData.actor, repData.pbs, repData.size, repData.shapetype);
238 }
239
240 if (mesh == null)
241 return false;
242
243 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
244 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
245
246 if (vertexCount == 0 || indexCount == 0)
247 {
248 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}",
249 actor.Name, repData.pbs.SculptTexture.ToString());
250 mesh.releaseSourceMeshData();
251 return false;
252 }
253
254 repData.OBBOffset = mesh.GetCentroid();
255 repData.OBB = mesh.GetOBB();
256 repData.hasOBB = true;
257 repData.physCost = 0.0013f * (float)indexCount;
258
259 mesh.releaseSourceMeshData();
260
261 try
262 {
263 triMeshData = d.GeomTriMeshDataCreate();
264
265 d.GeomTriMeshDataBuildSimple(triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
266 d.GeomTriMeshDataPreprocess(triMeshData);
267
268 m_scene.waitForSpaceUnlock(m_workODEspace);
269 geo = d.CreateTriMesh(m_workODEspace, triMeshData, null, null, null);
270 }
271
272 catch (Exception e)
273 {
274 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", actor.Name, e);
275 if (triMeshData != IntPtr.Zero)
276 {
277 d.GeomTriMeshDataDestroy(triMeshData);
278 repData.triMeshData = IntPtr.Zero;
279 }
280 repData.geo = IntPtr.Zero;
281 return false;
282 }
283
284 repData.geo = geo;
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
294 repData.actor = actor;
295 repData.pbs = pbs;
296 repData.mesh = pMesh;
297 repData.size = size;
298 repData.shapetype = shapetype;
299
300 IntPtr geo = IntPtr.Zero;
301 bool hasMesh = false;
302 if (needsMeshing(pbs))
303 {
304 if (GetTriMeshGeo(repData))
305 hasMesh = true;
306 else
307 repData.canColide = false;
308 }
309
310 if (!hasMesh)
311 {
312 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
313 && size.X == size.Y && size.Y == size.Z)
314 { // it's a sphere
315 m_scene.waitForSpaceUnlock(m_workODEspace);
316 try
317 {
318 geo = d.CreateSphere(m_workODEspace, size.X * 0.5f);
319 }
320 catch (Exception e)
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 {
336 m_log.Warn("[PHYSICS]: Create box failed: {0}", e);
337 return null;
338 }
339 }
340
341 repData.physCost = 0.1f;
342 repData.streamCost = 1.0f;
343 repData.geo = geo;
344 }
345
346 repData.curSpace = m_workODEspace;
347
348 CalcVolumeData(repData);
349
350 return repData;
351 }
352
353 private void CalculateBasicPrimVolume(ODEPhysRepData repData)
354 {
355 PrimitiveBaseShape _pbs = repData.pbs;
356 Vector3 _size = repData.size;
357
358 float volume = _size.X * _size.Y * _size.Z; // default
359 float tmp;
360
361 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
362 float hollowVolume = hollowAmount * hollowAmount;
363
364 switch (_pbs.ProfileShape)
365 {
366 case ProfileShape.Square:
367 // default box
368
369 if (_pbs.PathCurve == (byte)Extrusion.Straight)
370 {
371 if (hollowAmount > 0.0)
372 {
373 switch (_pbs.HollowShape)
374 {
375 case HollowShape.Square:
376 case HollowShape.Same:
377 break;
378
379 case HollowShape.Circle:
380
381 hollowVolume *= 0.78539816339f;
382 break;
383
384 case HollowShape.Triangle:
385
386 hollowVolume *= (0.5f * .5f);
387 break;
388
389 default:
390 hollowVolume = 0;
391 break;
392 }
393 volume *= (1.0f - hollowVolume);
394 }
395 }
396
397 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
398 {
399 //a tube
400
401 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
402 tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY);
403 volume -= volume * tmp * tmp;
404
405 if (hollowAmount > 0.0)
406 {
407 hollowVolume *= hollowAmount;
408
409 switch (_pbs.HollowShape)
410 {
411 case HollowShape.Square:
412 case HollowShape.Same:
413 break;
414
415 case HollowShape.Circle:
416 hollowVolume *= 0.78539816339f;
417 break;
418
419 case HollowShape.Triangle:
420 hollowVolume *= 0.5f * 0.5f;
421 break;
422 default:
423 hollowVolume = 0;
424 break;
425 }
426 volume *= (1.0f - hollowVolume);
427 }
428 }
429
430 break;
431
432 case ProfileShape.Circle:
433
434 if (_pbs.PathCurve == (byte)Extrusion.Straight)
435 {
436 volume *= 0.78539816339f; // elipse base
437
438 if (hollowAmount > 0.0)
439 {
440 switch (_pbs.HollowShape)
441 {
442 case HollowShape.Same:
443 case HollowShape.Circle:
444 break;
445
446 case HollowShape.Square:
447 hollowVolume *= 0.5f * 2.5984480504799f;
448 break;
449
450 case HollowShape.Triangle:
451 hollowVolume *= .5f * 1.27323954473516f;
452 break;
453
454 default:
455 hollowVolume = 0;
456 break;
457 }
458 volume *= (1.0f - hollowVolume);
459 }
460 }
461
462 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
463 {
464 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
465 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
466 volume *= (1.0f - tmp * tmp);
467
468 if (hollowAmount > 0.0)
469 {
470
471 // calculate the hollow volume by it's shape compared to the prim shape
472 hollowVolume *= hollowAmount;
473
474 switch (_pbs.HollowShape)
475 {
476 case HollowShape.Same:
477 case HollowShape.Circle:
478 break;
479
480 case HollowShape.Square:
481 hollowVolume *= 0.5f * 2.5984480504799f;
482 break;
483
484 case HollowShape.Triangle:
485 hollowVolume *= .5f * 1.27323954473516f;
486 break;
487
488 default:
489 hollowVolume = 0;
490 break;
491 }
492 volume *= (1.0f - hollowVolume);
493 }
494 }
495 break;
496
497 case ProfileShape.HalfCircle:
498 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
499 {
500 volume *= 0.5236f;
501
502 if (hollowAmount > 0.0)
503 {
504 hollowVolume *= hollowAmount;
505
506 switch (_pbs.HollowShape)
507 {
508 case HollowShape.Circle:
509 case HollowShape.Triangle: // diference in sl is minor and odd
510 case HollowShape.Same:
511 break;
512
513 case HollowShape.Square:
514 hollowVolume *= 0.909f;
515 break;
516
517 // case HollowShape.Triangle:
518 // hollowVolume *= .827f;
519 // break;
520 default:
521 hollowVolume = 0;
522 break;
523 }
524 volume *= (1.0f - hollowVolume);
525 }
526
527 }
528 break;
529
530 case ProfileShape.EquilateralTriangle:
531
532 if (_pbs.PathCurve == (byte)Extrusion.Straight)
533 {
534 volume *= 0.32475953f;
535
536 if (hollowAmount > 0.0)
537 {
538
539 // calculate the hollow volume by it's shape compared to the prim shape
540 switch (_pbs.HollowShape)
541 {
542 case HollowShape.Same:
543 case HollowShape.Triangle:
544 hollowVolume *= .25f;
545 break;
546
547 case HollowShape.Square:
548 hollowVolume *= 0.499849f * 3.07920140172638f;
549 break;
550
551 case HollowShape.Circle:
552 // Hollow shape is a perfect cyllinder in respect to the cube's scale
553 // Cyllinder hollow volume calculation
554
555 hollowVolume *= 0.1963495f * 3.07920140172638f;
556 break;
557
558 default:
559 hollowVolume = 0;
560 break;
561 }
562 volume *= (1.0f - hollowVolume);
563 }
564 }
565 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
566 {
567 volume *= 0.32475953f;
568 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
569 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
570 volume *= (1.0f - tmp * tmp);
571
572 if (hollowAmount > 0.0)
573 {
574
575 hollowVolume *= hollowAmount;
576
577 switch (_pbs.HollowShape)
578 {
579 case HollowShape.Same:
580 case HollowShape.Triangle:
581 hollowVolume *= .25f;
582 break;
583
584 case HollowShape.Square:
585 hollowVolume *= 0.499849f * 3.07920140172638f;
586 break;
587
588 case HollowShape.Circle:
589
590 hollowVolume *= 0.1963495f * 3.07920140172638f;
591 break;
592
593 default:
594 hollowVolume = 0;
595 break;
596 }
597 volume *= (1.0f - hollowVolume);
598 }
599 }
600 break;
601
602 default:
603 break;
604 }
605
606 float taperX1;
607 float taperY1;
608 float taperX;
609 float taperY;
610 float pathBegin;
611 float pathEnd;
612 float profileBegin;
613 float profileEnd;
614
615 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
616 {
617 taperX1 = _pbs.PathScaleX * 0.01f;
618 if (taperX1 > 1.0f)
619 taperX1 = 2.0f - taperX1;
620 taperX = 1.0f - taperX1;
621
622 taperY1 = _pbs.PathScaleY * 0.01f;
623 if (taperY1 > 1.0f)
624 taperY1 = 2.0f - taperY1;
625 taperY = 1.0f - taperY1;
626 }
627 else
628 {
629 taperX = _pbs.PathTaperX * 0.01f;
630 if (taperX < 0.0f)
631 taperX = -taperX;
632 taperX1 = 1.0f - taperX;
633
634 taperY = _pbs.PathTaperY * 0.01f;
635 if (taperY < 0.0f)
636 taperY = -taperY;
637 taperY1 = 1.0f - taperY;
638 }
639
640 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
641
642 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
643 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
644 volume *= (pathEnd - pathBegin);
645
646 // this is crude aproximation
647 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
648 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
649 volume *= (profileEnd - profileBegin);
650
651 repData.volume = volume;
652 }
653
654 private void CalcVolumeData(ODEPhysRepData repData)
655 {
656 float volume;
657 Vector3 OBB = repData.size;
658 Vector3 OBBoffset;
659 IntPtr geo = repData.geo;
660
661 if (geo == IntPtr.Zero || repData.triMeshData == IntPtr.Zero)
662 {
663 OBB.X *= 0.5f;
664 OBB.Y *= 0.5f;
665 OBB.Z *= 0.5f;
666
667 repData.OBB = OBB;
668 repData.OBBOffset = Vector3.Zero;
669 }
670 else if (!repData.hasOBB) // should this happen?
671 {
672 d.AABB AABB;
673 d.GeomGetAABB(geo, out AABB); // get the AABB from engine geom
674
675 OBB.X = (AABB.MaxX - AABB.MinX) * 0.5f;
676 OBB.Y = (AABB.MaxY - AABB.MinY) * 0.5f;
677 OBB.Z = (AABB.MaxZ - AABB.MinZ) * 0.5f;
678 repData.OBB = OBB;
679 OBBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f;
680 OBBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f;
681 OBBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f;
682 repData.OBBOffset = Vector3.Zero;
683 }
684
685 // also its own inertia and mass
686 // keep using basic shape mass for now
687 CalculateBasicPrimVolume(repData);
688
689 if (repData.hasOBB)
690 {
691 OBB = repData.OBB;
692 float pc = repData.physCost;
693 float psf = OBB.X * (OBB.Y + OBB.Z) + OBB.Y * OBB.Z;
694 psf *= 1.33f * .2f;
695
696 pc *= psf;
697 if (pc < 0.1f)
698 pc = 0.1f;
699
700 repData.physCost = pc;
701 }
702 else
703 repData.physCost = 0.1f;
704 }
217 } 705 }
218 706
219 public class ODEAssetRequest 707 public class ODEAssetRequest
@@ -221,12 +709,15 @@ namespace OpenSim.Region.Physics.OdePlugin
221 PhysicsActor m_actor; 709 PhysicsActor m_actor;
222 ODEMeshWorker m_worker; 710 ODEMeshWorker m_worker;
223 PrimitiveBaseShape m_pbs; 711 PrimitiveBaseShape m_pbs;
712 private ILog m_log;
224 713
225 public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider, PhysicsActor pActor, PrimitiveBaseShape ppbs) 714 public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider,
715 PhysicsActor pActor, PrimitiveBaseShape ppbs, ILog plog)
226 { 716 {
227 m_actor = pActor; 717 m_actor = pActor;
228 m_worker = pWorker; 718 m_worker = pWorker;
229 m_pbs = ppbs; 719 m_pbs = ppbs;
720 m_log = plog;
230 721
231 if (provider == null) 722 if (provider == null)
232 return; 723 return;
@@ -240,10 +731,22 @@ namespace OpenSim.Region.Physics.OdePlugin
240 731
241 void ODEassetReceived(AssetBase asset) 732 void ODEassetReceived(AssetBase asset)
242 { 733 {
243 if (m_actor != null && m_pbs != null && asset != null && asset.Data != null && asset.Data.Length > 0) 734 if (m_actor != null && m_pbs != null)
244 { 735 {
245 m_pbs.SculptData = asset.Data; 736 if (asset != null)
246 m_actor.Shape = m_pbs; 737 {
738 if (asset.Data != null && asset.Data.Length > 0)
739 {
740 m_pbs.SculptData = asset.Data;
741 m_actor.Shape = m_pbs;
742 }
743 else
744 m_log.WarnFormat("[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.",
745 m_actor.Name, asset.ID.ToString());
746 }
747 else
748 m_log.WarnFormat("[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.",
749 m_actor.Name);
247 } 750 }
248 } 751 }
249 } 752 }