diff options
author | UbitUmarov | 2012-10-07 01:20:52 +0100 |
---|---|---|
committer | UbitUmarov | 2012-10-07 01:20:52 +0100 |
commit | 78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100 (patch) | |
tree | d73921adb6a2e7f9c518a50a65c843ef7d95b539 /OpenSim/Region/Physics | |
parent | Merge branch 'avination' into ubitwork (diff) | |
download | opensim-SC_OLD-78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100.zip opensim-SC_OLD-78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100.tar.gz opensim-SC_OLD-78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100.tar.bz2 opensim-SC_OLD-78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100.tar.xz |
[DANGER UNTESTED] ODE mesh assets. Other plugins will not do meshs/sculpts
now
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 64 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs | 560 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 830 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 187 |
5 files changed, 609 insertions, 1033 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 44c8972..2933d86 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | |||
@@ -74,10 +74,6 @@ namespace OpenSim.Region.Physics.Meshing | |||
74 | private const string baseDir = null; //"rawFiles"; | 74 | private const string baseDir = null; //"rawFiles"; |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | private bool cacheSculptMaps = true; | ||
78 | private bool cacheSculptAlphaMaps = true; | ||
79 | |||
80 | private string decodedSculptMapPath = null; | ||
81 | private bool useMeshiesPhysicsMesh = false; | 77 | private bool useMeshiesPhysicsMesh = false; |
82 | 78 | ||
83 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh | 79 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh |
@@ -92,29 +88,9 @@ namespace OpenSim.Region.Physics.Meshing | |||
92 | IConfig start_config = config.Configs["Startup"]; | 88 | IConfig start_config = config.Configs["Startup"]; |
93 | IConfig mesh_config = config.Configs["Mesh"]; | 89 | IConfig mesh_config = config.Configs["Mesh"]; |
94 | 90 | ||
95 | decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); | ||
96 | |||
97 | cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); | ||
98 | |||
99 | if (Environment.OSVersion.Platform == PlatformID.Unix) | ||
100 | { | ||
101 | cacheSculptAlphaMaps = false; | ||
102 | } | ||
103 | else | ||
104 | cacheSculptAlphaMaps = cacheSculptMaps; | ||
105 | |||
106 | if(mesh_config != null) | 91 | if(mesh_config != null) |
107 | useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); | 92 | useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); |
108 | 93 | ||
109 | try | ||
110 | { | ||
111 | if (!Directory.Exists(decodedSculptMapPath)) | ||
112 | Directory.CreateDirectory(decodedSculptMapPath); | ||
113 | } | ||
114 | catch (Exception e) | ||
115 | { | ||
116 | m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedSculptMapPath, e.Message); | ||
117 | } | ||
118 | } | 94 | } |
119 | 95 | ||
120 | /// <summary> | 96 | /// <summary> |
@@ -444,7 +420,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
444 | // physics_shape is an array of OSDMaps, one for each submesh | 420 | // physics_shape is an array of OSDMaps, one for each submesh |
445 | if (decodedMeshOsd is OSDArray) | 421 | if (decodedMeshOsd is OSDArray) |
446 | { | 422 | { |
447 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); | 423 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); |
448 | 424 | ||
449 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; | 425 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; |
450 | foreach (OSD subMeshOsd in decodedMeshOsdArray) | 426 | foreach (OSD subMeshOsd in decodedMeshOsdArray) |
@@ -717,29 +693,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
717 | faces = new List<Face>(); | 693 | faces = new List<Face>(); |
718 | PrimMesher.SculptMesh sculptMesh; | 694 | PrimMesher.SculptMesh sculptMesh; |
719 | Image idata = null; | 695 | Image idata = null; |
720 | string decodedSculptFileName = ""; | ||
721 | 696 | ||
722 | if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) | ||
723 | { | ||
724 | decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); | ||
725 | try | ||
726 | { | ||
727 | if (File.Exists(decodedSculptFileName)) | ||
728 | { | ||
729 | idata = Image.FromFile(decodedSculptFileName); | ||
730 | } | ||
731 | } | ||
732 | catch (Exception e) | ||
733 | { | ||
734 | m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message); | ||
735 | |||
736 | } | ||
737 | //if (idata != null) | ||
738 | // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString()); | ||
739 | } | ||
740 | |||
741 | if (idata == null) | ||
742 | { | ||
743 | if (primShape.SculptData == null || primShape.SculptData.Length == 0) | 697 | if (primShape.SculptData == null || primShape.SculptData.Length == 0) |
744 | return false; | 698 | return false; |
745 | 699 | ||
@@ -748,25 +702,15 @@ namespace OpenSim.Region.Physics.Meshing | |||
748 | OpenMetaverse.Imaging.ManagedImage unusedData; | 702 | OpenMetaverse.Imaging.ManagedImage unusedData; |
749 | OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); | 703 | OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); |
750 | 704 | ||
705 | unusedData = null; | ||
706 | |||
751 | if (idata == null) | 707 | if (idata == null) |
752 | { | 708 | { |
753 | // In some cases it seems that the decode can return a null bitmap without throwing | 709 | // In some cases it seems that the decode can return a null bitmap without throwing |
754 | // an exception | 710 | // an exception |
755 | m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); | 711 | m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); |
756 | |||
757 | return false; | 712 | return false; |
758 | } | 713 | } |
759 | |||
760 | unusedData = null; | ||
761 | |||
762 | //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); | ||
763 | |||
764 | if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0))) | ||
765 | // don't cache images with alpha channel in linux since mono can't load them correctly) | ||
766 | { | ||
767 | try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } | ||
768 | catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } | ||
769 | } | ||
770 | } | 714 | } |
771 | catch (DllNotFoundException) | 715 | catch (DllNotFoundException) |
772 | { | 716 | { |
@@ -783,7 +727,6 @@ namespace OpenSim.Region.Physics.Meshing | |||
783 | m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); | 727 | m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); |
784 | return false; | 728 | return false; |
785 | } | 729 | } |
786 | } | ||
787 | 730 | ||
788 | PrimMesher.SculptMesh.SculptType sculptType; | 731 | PrimMesher.SculptMesh.SculptType sculptType; |
789 | // remove mirror and invert bits | 732 | // remove mirror and invert bits |
@@ -1048,7 +991,6 @@ namespace OpenSim.Region.Physics.Meshing | |||
1048 | return ((hash << 5) + hash) + (ulong)(c >> 8); | 991 | return ((hash << 5) + hash) + (ulong)(c >> 8); |
1049 | } | 992 | } |
1050 | 993 | ||
1051 | |||
1052 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) | 994 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) |
1053 | { | 995 | { |
1054 | return CreateMesh(primName, primShape, size, lod, false,false); | 996 | return CreateMesh(primName, primShape, size, lod, false,false); |
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 | ||
19 | namespace OpenSim.Region.Physics.OdePlugin | 19 | namespace 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(); |