aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs')
-rw-r--r--OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs163
1 files changed, 98 insertions, 65 deletions
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
index 80c1277..0a4ebe4 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
@@ -704,6 +704,8 @@ namespace OpenSim.Region.Physics.OdePlugin
704 if (m_isphysical) 704 if (m_isphysical)
705 m_targetSpace = _parent_scene.space; 705 m_targetSpace = _parent_scene.space;
706 706
707 _triMeshData = IntPtr.Zero;
708
707 m_primName = primName; 709 m_primName = primName;
708 m_taintserial = null; 710 m_taintserial = null;
709 m_taintadd = true; 711 m_taintadd = true;
@@ -773,6 +775,8 @@ namespace OpenSim.Region.Physics.OdePlugin
773 m_targetSpace = _parent_scene.space; 775 m_targetSpace = _parent_scene.space;
774 } 776 }
775 777
778 _triMeshData = IntPtr.Zero;
779
776 m_taintserial = null; 780 m_taintserial = null;
777 m_primName = primName; 781 m_primName = primName;
778 m_taintadd = true; 782 m_taintadd = true;
@@ -1762,7 +1766,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1762 1766
1763 private static Dictionary<IMesh, IntPtr> m_MeshToTriMeshMap = new Dictionary<IMesh, IntPtr>(); 1767 private static Dictionary<IMesh, IntPtr> m_MeshToTriMeshMap = new Dictionary<IMesh, IntPtr>();
1764 1768
1765 public void setMesh(OdeScene parent_scene, IMesh mesh) 1769 public bool setMesh(OdeScene parent_scene, IMesh mesh)
1766 { 1770 {
1767 // This sleeper is there to moderate how long it takes between 1771 // This sleeper is there to moderate how long it takes between
1768 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object 1772 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
@@ -1785,24 +1789,48 @@ namespace OpenSim.Region.Physics.OdePlugin
1785 disableBody(); 1789 disableBody();
1786 } 1790 }
1787 } 1791 }
1792
1793// do it on caller instead
1794/*
1795 if (_triMeshData != IntPtr.Zero)
1796 {
1797 d.GeomTriMeshDataDestroy(_triMeshData);
1798 _triMeshData = IntPtr.Zero;
1799 }
1800*/
1788 IntPtr vertices, indices; 1801 IntPtr vertices, indices;
1789 int vertexCount, indexCount; 1802 int vertexCount, indexCount;
1790 int vertexStride, triStride; 1803 int vertexStride, triStride;
1791 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap 1804 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
1792 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage 1805 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
1793 1806
1807 // warning this destroys the mesh for eventual future use. Only pinned float arrays stay valid
1794 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory 1808 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
1809
1810 if (vertexCount == 0 || indexCount == 0)
1811 {
1812 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. It can be a sculp with alpha channel in map. Replacing it by a small box.", Name, _position.X, _position.Y, _position.Z);
1813 _size.X = 0.05f;
1814 _size.Y = 0.05f;
1815 _size.Z = 0.05f;
1816 return false;
1817 }
1818
1819/*
1795 if (m_MeshToTriMeshMap.ContainsKey(mesh)) 1820 if (m_MeshToTriMeshMap.ContainsKey(mesh))
1796 { 1821 {
1797 _triMeshData = m_MeshToTriMeshMap[mesh]; 1822 _triMeshData = m_MeshToTriMeshMap[mesh];
1798 } 1823 }
1799 else 1824 else
1825*/
1826
1827
1800 { 1828 {
1801 _triMeshData = d.GeomTriMeshDataCreate(); 1829 _triMeshData = d.GeomTriMeshDataCreate();
1802 1830
1803 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 1831 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1804 d.GeomTriMeshDataPreprocess(_triMeshData); 1832 d.GeomTriMeshDataPreprocess(_triMeshData);
1805 m_MeshToTriMeshMap[mesh] = _triMeshData; 1833// m_MeshToTriMeshMap[mesh] = _triMeshData;
1806 } 1834 }
1807 1835
1808 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1836 _parent_scene.waitForSpaceUnlock(m_targetSpace);
@@ -1810,13 +1838,23 @@ namespace OpenSim.Region.Physics.OdePlugin
1810 { 1838 {
1811 // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer 1839 // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer
1812 // { 1840 // {
1813 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); 1841 // SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
1842 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null));
1814 // } 1843 // }
1815 } 1844 }
1816 catch (AccessViolationException) 1845 catch (Exception e)
1817 { 1846 {
1818 m_log.Error("[PHYSICS]: MESH LOCKED"); 1847 m_log.ErrorFormat("[PHYSICS]: Create trimesh failed on prim {0} : {1}",Name,e.Message);
1819 return; 1848
1849 if (_triMeshData != IntPtr.Zero)
1850 {
1851 d.GeomTriMeshDataDestroy(_triMeshData);
1852 _triMeshData = IntPtr.Zero;
1853 }
1854 _size.X = 0.05f;
1855 _size.Y = 0.05f;
1856 _size.Z = 0.05f;
1857 return false;
1820 } 1858 }
1821 1859
1822 1860
@@ -1828,6 +1866,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1828 1866
1829 // enableBody(); 1867 // enableBody();
1830 // } 1868 // }
1869 return true;
1831 } 1870 }
1832 1871
1833 public void ProcessTaints(float timestep) //============================================================================= 1872 public void ProcessTaints(float timestep) //=============================================================================
@@ -1837,6 +1876,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1837 changeadd(timestep); 1876 changeadd(timestep);
1838 } 1877 }
1839 1878
1879 if (m_taintremove)
1880 return;
1881
1840 if (prim_geom != IntPtr.Zero) 1882 if (prim_geom != IntPtr.Zero)
1841 { 1883 {
1842 if (!_position.ApproxEquals(m_taintposition, 0f)) 1884 if (!_position.ApproxEquals(m_taintposition, 0f))
@@ -2286,75 +2328,62 @@ namespace OpenSim.Region.Physics.OdePlugin
2286 2328
2287 public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) 2329 public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh)
2288 { 2330 {
2331 bool gottrimesh = false;
2332
2333 if (_triMeshData != IntPtr.Zero)
2334 {
2335 d.GeomTriMeshDataDestroy(_triMeshData);
2336 _triMeshData = IntPtr.Zero;
2337 }
2338
2289 if (_mesh != null) // Special - make mesh 2339 if (_mesh != null) // Special - make mesh
2290 { 2340 {
2291 setMesh(_parent_scene, _mesh); 2341 gottrimesh = setMesh(_parent_scene, _mesh);
2292 } 2342 }
2293 else // not a mesh 2343
2344 if (!gottrimesh) // not a mesh
2294 { 2345 {
2295 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) // special profile?? 2346 IntPtr geo = IntPtr.Zero;
2347
2348 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
2349 && _size.X == _size.Y && _size.X == _size.Z)
2296 { 2350 {
2297 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) // Equi-size 2351 // its a sphere
2352 _parent_scene.waitForSpaceUnlock(m_targetSpace);
2353 try
2298 { 2354 {
2299 if (((_size.X / 2f) > 0f)) // Has size 2355 geo = d.CreateSphere(m_targetSpace, _size.X * 0.5f);
2300 {
2301 _parent_scene.waitForSpaceUnlock(m_targetSpace);
2302 try
2303 {
2304 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
2305 }
2306 catch (AccessViolationException)
2307 {
2308 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
2309 ode.dunlock(_parent_scene.world);
2310 return;
2311 }
2312 }
2313 else
2314 {
2315 _parent_scene.waitForSpaceUnlock(m_targetSpace);
2316 try
2317 {
2318 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
2319 }
2320 catch (AccessViolationException)
2321 {
2322 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
2323 ode.dunlock(_parent_scene.world);
2324 return;
2325 }
2326 }
2327 } 2356 }
2328 else // not equi-size 2357 catch (Exception e)
2329 { 2358 {
2330 _parent_scene.waitForSpaceUnlock(m_targetSpace); 2359 m_log.WarnFormat("[PHYSICS]: Unable to create basic sphere for object {0}", e.Message);
2331 try 2360 geo = IntPtr.Zero;
2332 { 2361 ode.dunlock(_parent_scene.world);
2333 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
2334 }
2335 catch (AccessViolationException)
2336 {
2337 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
2338 ode.dunlock(_parent_scene.world);
2339 return;
2340 }
2341 } 2362 }
2342 } 2363 }
2343 2364 else // make it a box
2344 else // not special profile
2345 { 2365 {
2346 _parent_scene.waitForSpaceUnlock(m_targetSpace); 2366 _parent_scene.waitForSpaceUnlock(m_targetSpace);
2347 try 2367 try
2348 { 2368 {
2349 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 2369 geo = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
2350 } 2370 }
2351 catch (AccessViolationException) 2371 catch (Exception e)
2352 { 2372 {
2353 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); 2373 m_log.WarnFormat("[PHYSICS]: Unable to create basic sphere for object {0}", e.Message);
2374 geo = IntPtr.Zero;
2354 ode.dunlock(_parent_scene.world); 2375 ode.dunlock(_parent_scene.world);
2355 return;
2356 } 2376 }
2357 } 2377 }
2378
2379 if (geo == IntPtr.Zero)
2380 {
2381 m_taintremove = true;
2382 _parent_scene.AddPhysicsActorTaint(this);
2383 return;
2384 }
2385
2386 SetGeom(geo);
2358 } 2387 }
2359 } 2388 }
2360 2389
@@ -2372,18 +2401,17 @@ namespace OpenSim.Region.Physics.OdePlugin
2372 { 2401 {
2373 if (_parent_scene.needsMeshing(_pbs)) 2402 if (_parent_scene.needsMeshing(_pbs))
2374 { 2403 {
2375 // Don't need to re-enable body.. it's done in SetMesh
2376 try 2404 try
2377 { 2405 {
2378 _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); 2406 _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, (int)LevelOfDetail.High, true);
2379 } 2407 }
2380 catch 2408 catch
2381 { 2409 {
2382 //Don't continuously try to mesh prims when meshing has failed 2410 //Don't continuously try to mesh prims when meshing has failed
2383 m_meshfailed = true; 2411 m_meshfailed = true;
2412 _mesh = null;
2413 m_log.WarnFormat("[PHYSICS]: changeAdd CreateMesh fail on prim {0} at <{1},{2},{3}>", Name, _position.X, _position.Y, _position.Z);
2384 } 2414 }
2385 // createmesh returns null when it's a shape that isn't a cube.
2386 // m_log.Debug(m_localID);
2387 } 2415 }
2388 } 2416 }
2389 2417
@@ -2630,17 +2658,17 @@ namespace OpenSim.Region.Physics.OdePlugin
2630 try 2658 try
2631 { 2659 {
2632 if (_parent_scene.needsMeshing(_pbs)) 2660 if (_parent_scene.needsMeshing(_pbs))
2633 mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 2661 mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, (int)LevelOfDetail.High, true);
2634 } 2662 }
2635 catch 2663 catch
2636 { 2664 {
2637 m_meshfailed = true; 2665 m_meshfailed = true;
2666 mesh = null;
2667 m_log.WarnFormat("[PHYSICS]: changeSize CreateMesh fail on prim {0} at <{1},{2},{3}>", Name, _position.X, _position.Y, _position.Z);
2638 } 2668 }
2639 2669
2640 //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 2670 //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
2641 CreateGeom(m_targetSpace, mesh); 2671 CreateGeom(m_targetSpace, mesh);
2642
2643
2644 } 2672 }
2645 else 2673 else
2646 { 2674 {
@@ -2732,18 +2760,23 @@ namespace OpenSim.Region.Physics.OdePlugin
2732 { 2760 {
2733 // Don't need to re-enable body.. it's done in SetMesh 2761 // Don't need to re-enable body.. it's done in SetMesh
2734 float meshlod = _parent_scene.meshSculptLOD; 2762 float meshlod = _parent_scene.meshSculptLOD;
2763 IMesh mesh;
2735 2764
2736 if (IsPhysical) 2765 if (IsPhysical)
2737 meshlod = _parent_scene.MeshSculptphysicalLOD; 2766 meshlod = _parent_scene.MeshSculptphysicalLOD;
2738 try 2767 try
2739 { 2768 {
2740 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 2769 mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, (int)LevelOfDetail.High, true);
2741 CreateGeom(m_targetSpace, mesh);
2742 } 2770 }
2743 catch 2771 catch
2744 { 2772 {
2773 mesh = null;
2745 m_meshfailed = true; 2774 m_meshfailed = true;
2775 m_log.WarnFormat("[PHYSICS]: changeAdd CreateMesh fail on prim {0} at <{1},{2},{3}>", Name, _position.X, _position.Y, _position.Z);
2746 } 2776 }
2777
2778 CreateGeom(m_targetSpace, mesh);
2779
2747 // createmesh returns null when it doesn't mesh. 2780 // createmesh returns null when it doesn't mesh.
2748 } 2781 }
2749 else 2782 else