6 using System.Threading;
7 using System.Collections.Generic;
9 using System.Reflection;
10 using System.Runtime.InteropServices;
12 using OpenSim.Framework;
13 using OpenSim.Region.PhysicsModules.SharedBase;
19 namespace OpenSim.
Region.PhysicsModule.ubOde
77 public bool meshSculptedPrim =
true;
78 public bool forceSimplePrimMeshing =
false;
79 public float meshSculptLOD = 32;
80 public float MeshSculptphysicalLOD = 32;
84 private bool m_running;
96 forceSimplePrimMeshing = pConfig.GetBoolean(
"force_simple_prim_meshing", forceSimplePrimMeshing);
97 meshSculptedPrim = pConfig.GetBoolean(
"mesh_sculpted_prim", meshSculptedPrim);
98 meshSculptLOD = pConfig.GetFloat(
"mesh_lod", meshSculptLOD);
99 MeshSculptphysicalLOD = pConfig.GetFloat(
"mesh_physical_lod", MeshSculptphysicalLOD);
102 m_thread =
new Thread(DoWork);
103 m_thread.Name =
"OdeMeshWorker";
107 private void DoWork()
109 m_mesher.ExpireFileCache();
118 if (m_scene.haveActor(nextRep.
actor))
122 case meshWorkerCmnds.changefull:
123 case meshWorkerCmnds.changeshapetype:
124 case meshWorkerCmnds.changesize:
126 if (CreateActorPhysRep(nextRep) && m_scene.haveActor(nextRep.
actor))
127 m_scene.AddChange(nextRep.
actor,
changes.PhysRepData, nextRep);
129 case meshWorkerCmnds.getmesh:
130 DoRepDataGetMesh(nextRep);
150 Vector3 size, byte shapetype)
153 repData.actor = actor;
156 repData.shapetype = shapetype;
159 CalcVolumeData(repData);
160 m_scene.AddChange(actor, changes.PhysRepData, repData);
165 Vector3 size, byte shapetype)
168 repData.actor = actor;
171 repData.shapetype = shapetype;
174 CalcVolumeData(repData);
175 m_scene.AddChange(actor, changes.AddPhysRep, repData);
191 repData.meshState = MeshState.noNeed;
195 repData.assetID = pbs.SculptTexture;
196 repData.meshState = MeshState.loadingAsset;
198 repData.comand = meshWorkerCmnds.getmesh;
199 createqueue.Enqueue(repData);
206 IMesh mesh = repData.mesh;
210 IntPtr vertices, indices;
211 int vertexCount, indexCount;
212 int vertexStride, triStride;
214 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
215 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
217 if (vertexCount == 0 || indexCount == 0)
219 m_log.WarnFormat(
"[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}",
220 repData.actor.Name, repData.pbs.SculptTexture.ToString());
221 repData.meshState = MeshState.MeshFailed;
222 repData.hasOBB =
false;
224 m_scene.mesher.ReleaseMesh(mesh);
228 repData.OBBOffset = mesh.GetCentroid();
229 repData.OBB = mesh.GetOBB();
230 repData.hasOBB =
true;
231 mesh.releaseSourceMeshData();
234 CalcVolumeData(repData);
240 if (m_scene.haveActor(repData.
actor))
242 if (needsMeshing(repData.
pbs))
244 repData.comand = meshWorkerCmnds.changefull;
245 createqueue.Enqueue(repData);
249 repData.pbs.SculptData = Utils.EmptyBytes;
270 CreateActorPhysRep(repData);
271 m_scene.AddChange(repData.actor, changes.PhysRepData, repData);
276 if (assetProvider == null)
292 if (meshSculptedPrim)
301 if (forceSimplePrimMeshing)
327 int iPropertiesNotSupportedDefault = 0;
330 iPropertiesNotSupportedDefault++;
333 iPropertiesNotSupportedDefault++;
336 iPropertiesNotSupportedDefault++;
339 iPropertiesNotSupportedDefault++;
342 iPropertiesNotSupportedDefault++;
345 iPropertiesNotSupportedDefault++;
348 iPropertiesNotSupportedDefault++;
351 iPropertiesNotSupportedDefault++;
354 iPropertiesNotSupportedDefault++;
361 iPropertiesNotSupportedDefault++;
368 iPropertiesNotSupportedDefault++;
374 iPropertiesNotSupportedDefault++;
381 iPropertiesNotSupportedDefault++;
388 iPropertiesNotSupportedDefault++;
392 iPropertiesNotSupportedDefault++;
396 if (iPropertiesNotSupportedDefault == 0)
410 if (!needsMeshing(pbs))
412 repData.meshState = MeshState.noNeed;
413 repData.hasOBB =
false;
419 Vector3 size = repData.size;
420 byte shapetype = repData.shapetype;
431 clod = (
int)LevelOfDetail.Low;
434 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod,
true, convex);
440 if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero)
442 repData.assetID = pbs.SculptTexture;
443 repData.meshState = MeshState.needAsset;
446 repData.meshState = MeshState.MeshFailed;
452 repData.meshState = MeshState.needMesh;
453 mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod,
true, convex,
true);
456 repData.meshState = MeshState.MeshFailed;
462 repData.meshState = MeshState.AssetOK;
464 repData.OBB = mesh.GetOBB();
465 repData.OBBOffset = mesh.GetCentroid();
466 repData.hasOBB =
true;
470 repData.assetID = pbs.SculptTexture;
473 pbs.SculptData = Utils.EmptyBytes;
484 repData.hasOBB =
false;
486 if (!needsMeshing(pbs))
488 repData.meshState = MeshState.noNeed;
504 repData.meshState = MeshState.noNeed;
507 Vector3 size = repData.size;
508 byte shapetype = repData.shapetype;
518 clod = (
int)LevelOfDetail.Low;
521 mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod,
true, convex,
true);
527 if (pbs.SculptTexture == UUID.Zero)
530 repData.assetID = pbs.SculptTexture;
532 if (pbs.SculptData == null || pbs.SculptData.Length == 0)
534 repData.meshState = MeshState.needAsset;
541 repData.pbs.SculptData = Utils.EmptyBytes;
546 repData.meshState = MeshState.AssetFailed;
548 repData.meshState = MeshState.MeshFailed;
553 repData.meshState = MeshState.AssetOK;
561 Vector3 _size = repData.size;
563 float volume = _size.X * _size.Y * _size.Z;
567 float hollowVolume = hollowAmount * hollowAmount;
571 case ProfileShape.Square:
574 if (_pbs.
PathCurve == (byte)Extrusion.Straight)
576 if (hollowAmount > 0.0)
580 case HollowShape.Square:
581 case HollowShape.Same:
584 case HollowShape.Circle:
586 hollowVolume *= 0.78539816339f;
589 case HollowShape.Triangle:
591 hollowVolume *= (0.5f * .5f);
598 volume *= (1.0f - hollowVolume);
602 else if (_pbs.
PathCurve == (byte)Extrusion.Curve1)
606 volume *= 0.78539816339e-2f * (float)(200 - _pbs.
PathScaleX);
607 tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.
PathScaleY);
608 volume -= volume * tmp * tmp;
610 if (hollowAmount > 0.0)
612 hollowVolume *= hollowAmount;
616 case HollowShape.Square:
617 case HollowShape.Same:
620 case HollowShape.Circle:
621 hollowVolume *= 0.78539816339f;
624 case HollowShape.Triangle:
625 hollowVolume *= 0.5f * 0.5f;
631 volume *= (1.0f - hollowVolume);
637 case ProfileShape.Circle:
639 if (_pbs.
PathCurve == (byte)Extrusion.Straight)
641 volume *= 0.78539816339f;
643 if (hollowAmount > 0.0)
647 case HollowShape.Same:
648 case HollowShape.Circle:
651 case HollowShape.Square:
652 hollowVolume *= 0.5f * 2.5984480504799f;
655 case HollowShape.Triangle:
656 hollowVolume *= .5f * 1.27323954473516f;
663 volume *= (1.0f - hollowVolume);
667 else if (_pbs.
PathCurve == (byte)Extrusion.Curve1)
669 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.
PathScaleX);
670 tmp = 1.0f - .02f * (float)(200 - _pbs.
PathScaleY);
671 volume *= (1.0f - tmp * tmp);
673 if (hollowAmount > 0.0)
677 hollowVolume *= hollowAmount;
681 case HollowShape.Same:
682 case HollowShape.Circle:
685 case HollowShape.Square:
686 hollowVolume *= 0.5f * 2.5984480504799f;
689 case HollowShape.Triangle:
690 hollowVolume *= .5f * 1.27323954473516f;
697 volume *= (1.0f - hollowVolume);
702 case ProfileShape.HalfCircle:
703 if (_pbs.
PathCurve == (byte)Extrusion.Curve1)
707 if (hollowAmount > 0.0)
709 hollowVolume *= hollowAmount;
713 case HollowShape.Circle:
714 case HollowShape.Triangle:
715 case HollowShape.Same:
718 case HollowShape.Square:
719 hollowVolume *= 0.909f;
729 volume *= (1.0f - hollowVolume);
735 case ProfileShape.EquilateralTriangle:
737 if (_pbs.
PathCurve == (byte)Extrusion.Straight)
739 volume *= 0.32475953f;
741 if (hollowAmount > 0.0)
747 case HollowShape.Same:
748 case HollowShape.Triangle:
749 hollowVolume *= .25f;
752 case HollowShape.Square:
753 hollowVolume *= 0.499849f * 3.07920140172638f;
756 case HollowShape.Circle:
760 hollowVolume *= 0.1963495f * 3.07920140172638f;
767 volume *= (1.0f - hollowVolume);
770 else if (_pbs.
PathCurve == (byte)Extrusion.Curve1)
772 volume *= 0.32475953f;
773 volume *= 0.01f * (float)(200 - _pbs.
PathScaleX);
774 tmp = 1.0f - .02f * (float)(200 - _pbs.
PathScaleY);
775 volume *= (1.0f - tmp * tmp);
777 if (hollowAmount > 0.0)
780 hollowVolume *= hollowAmount;
784 case HollowShape.Same:
785 case HollowShape.Triangle:
786 hollowVolume *= .25f;
789 case HollowShape.Square:
790 hollowVolume *= 0.499849f * 3.07920140172638f;
793 case HollowShape.Circle:
795 hollowVolume *= 0.1963495f * 3.07920140172638f;
802 volume *= (1.0f - hollowVolume);
820 if (_pbs.
PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)
Extrusion.Flexible)
822 taperX1 = _pbs.PathScaleX * 0.01f;
824 taperX1 = 2.0f - taperX1;
825 taperX = 1.0f - taperX1;
827 taperY1 = _pbs.PathScaleY * 0.01f;
829 taperY1 = 2.0f - taperY1;
830 taperY = 1.0f - taperY1;
834 taperX = _pbs.PathTaperX * 0.01f;
837 taperX1 = 1.0f - taperX;
839 taperY = _pbs.PathTaperY * 0.01f;
842 taperY1 = 1.0f - taperY;
845 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
847 pathBegin = (float)_pbs.
PathBegin * 2.0e-5f;
848 pathEnd = 1.0f - (
float)_pbs.PathEnd * 2.0e-5f;
849 volume *= (pathEnd - pathBegin);
853 profileEnd = 1.0f - (
float)_pbs.ProfileEnd * 2.0e-5f;
854 volume *= (profileEnd - profileBegin);
856 repData.volume = volume;
859 private void CalcVolumeData(ODEPhysRepData repData)
863 Vector3 OBB = repData.OBB;
867 Vector3 OBB = repData.size;
873 repData.OBBOffset = Vector3.Zero;
876 CalculateBasicPrimVolume(repData);
893 repData.meshState = MeshState.AssetFailed;
894 if (provider == null)
900 UUID assetID = (UUID) repData.
assetID;
901 if (assetID == UUID.Zero)
904 repData.meshState = MeshState.loadingAsset;
905 provider(assetID, ODEassetReceived);
910 repData.meshState = MeshState.AssetFailed;
913 if (asset.
Data != null && asset.
Data.Length > 0)
915 repData.meshState = MeshState.noNeed;
924 repData.pbs.SculptData = asset.Data;
925 repData.meshState = MeshState.AssetOK;
926 m_worker.AssetLoaded(repData);
929 m_log.WarnFormat(
"[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.",
930 repData.actor.Name, asset.ID.ToString());
933 m_log.WarnFormat(
"[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.",
bool needsMeshing(PrimitiveBaseShape pbs)
Routine to figure out if we need to mesh this prim with our mesher
ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider, ODEPhysRepData pRepData, ILog plog)
void CheckMesh(ODEPhysRepData repData)
void GetMesh(ODEPhysRepData repData)
void DoRepDataGetMesh(ODEPhysRepData repData)
ODEPhysRepData NewActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs, Vector3 size, byte shapetype)
void AssetLoaded(ODEPhysRepData repData)
ODEMeshWorker(ODEScene pScene, ILog pLog, IMesher pMesher, IConfig pConfig)
Asset class. All Assets are reference by this class or a class derived from this class ...
void RequestMesh(ODEPhysRepData repData)
void ChangeActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs, Vector3 size, byte shapetype)
ProfileShape ProfileShape
OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType SculptType
delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback)
bool CreateActorPhysRep(ODEPhysRepData repData)