diff options
author | Robert Adams | 2013-02-05 16:51:02 -0800 |
---|---|---|
committer | Robert Adams | 2013-02-05 16:56:33 -0800 |
commit | dce9e323f4f0fdccd2f34266e870de9cbcebd2f0 (patch) | |
tree | e8e5e245d6b2e18b709e297b60875c16f7a78225 /OpenSim/Region/Physics | |
parent | BulletSim: add debugging looking for doorway sculpty problems (diff) | |
download | opensim-SC-dce9e323f4f0fdccd2f34266e870de9cbcebd2f0.zip opensim-SC-dce9e323f4f0fdccd2f34266e870de9cbcebd2f0.tar.gz opensim-SC-dce9e323f4f0fdccd2f34266e870de9cbcebd2f0.tar.bz2 opensim-SC-dce9e323f4f0fdccd2f34266e870de9cbcebd2f0.tar.xz |
BulletSim: remove degenerate triangles from meshes. This fixes the
invisible barriers in sculptie doorways (Mantis 6529).
Bump up level-of-detail for physical meshes to 32 (the max). This
fixes the invisible barriers that showed up in prim cut arches.
NOTE: the default LOD values are removed from OpenSimDefaults.ini.
If you don't change your OpenSimDefaults.ini, you will continue
to see the arch problem.
Diffstat (limited to 'OpenSim/Region/Physics')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 18 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 81 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Manager/IMesher.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Mesh.cs | 2 |
5 files changed, 59 insertions, 45 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index fbef7e7..bdd9ce4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -39,6 +39,7 @@ public static class BSParam | |||
39 | { | 39 | { |
40 | // Level of Detail values kept as float because that's what the Meshmerizer wants | 40 | // Level of Detail values kept as float because that's what the Meshmerizer wants |
41 | public static float MeshLOD { get; private set; } | 41 | public static float MeshLOD { get; private set; } |
42 | public static float MeshCircularLOD { get; private set; } | ||
42 | public static float MeshMegaPrimLOD { get; private set; } | 43 | public static float MeshMegaPrimLOD { get; private set; } |
43 | public static float MeshMegaPrimThreshold { get; private set; } | 44 | public static float MeshMegaPrimThreshold { get; private set; } |
44 | public static float SculptLOD { get; private set; } | 45 | public static float SculptLOD { get; private set; } |
@@ -219,20 +220,25 @@ public static class BSParam | |||
219 | (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), | 220 | (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), |
220 | 221 | ||
221 | new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", | 222 | new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", |
222 | 8f, | 223 | 32f, |
223 | (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, | 224 | (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, |
224 | (s) => { return MeshLOD; }, | 225 | (s) => { return MeshLOD; }, |
225 | (s,p,l,v) => { MeshLOD = v; } ), | 226 | (s,p,l,v) => { MeshLOD = v; } ), |
226 | new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", | 227 | new ParameterDefn("MeshLevelOfDetailCircular", "Level of detail for prims with circular cuts or shapes", |
227 | 16f, | 228 | 32f, |
228 | (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, | 229 | (s,cf,p,v) => { MeshCircularLOD = (float)cf.GetInt(p, (int)v); }, |
229 | (s) => { return MeshMegaPrimLOD; }, | 230 | (s) => { return MeshCircularLOD; }, |
230 | (s,p,l,v) => { MeshMegaPrimLOD = v; } ), | 231 | (s,p,l,v) => { MeshCircularLOD = v; } ), |
231 | new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", | 232 | new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", |
232 | 10f, | 233 | 10f, |
233 | (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, | 234 | (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, |
234 | (s) => { return MeshMegaPrimThreshold; }, | 235 | (s) => { return MeshMegaPrimThreshold; }, |
235 | (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), | 236 | (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), |
237 | new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", | ||
238 | 32f, | ||
239 | (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, | ||
240 | (s) => { return MeshMegaPrimLOD; }, | ||
241 | (s,p,l,v) => { MeshMegaPrimLOD = v; } ), | ||
236 | new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", | 242 | new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", |
237 | 32f, | 243 | 32f, |
238 | (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); }, | 244 | (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); }, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 0af8e13..f17e513 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -602,8 +602,8 @@ public sealed class BSShapeCollection : IDisposable | |||
602 | if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) | 602 | if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) |
603 | return false; | 603 | return false; |
604 | 604 | ||
605 | if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", | 605 | if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2},size={3},lod={4}", |
606 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); | 606 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod); |
607 | 607 | ||
608 | // Since we're recreating new, get rid of the reference to the previous shape | 608 | // Since we're recreating new, get rid of the reference to the previous shape |
609 | DereferenceShape(prim.PhysShape, shapeCallback); | 609 | DereferenceShape(prim.PhysShape, shapeCallback); |
@@ -631,50 +631,50 @@ public sealed class BSShapeCollection : IDisposable | |||
631 | } | 631 | } |
632 | else | 632 | else |
633 | { | 633 | { |
634 | IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); | 634 | IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, |
635 | false, // say it is not physical so a bounding box is not built | ||
636 | false // do not cache the mesh and do not use previously built versions | ||
637 | ); | ||
635 | 638 | ||
636 | if (meshData != null) | 639 | if (meshData != null) |
637 | { | 640 | { |
638 | int[] indices = meshData.getIndexListAsInt(); | ||
639 | List<OMV.Vector3> vertices = meshData.getVertexList(); | ||
640 | |||
641 | float[] verticesAsFloats = new float[vertices.Count * 3]; | ||
642 | int vi = 0; | ||
643 | foreach (OMV.Vector3 vv in vertices) | ||
644 | { | ||
645 | verticesAsFloats[vi++] = vv.X; | ||
646 | verticesAsFloats[vi++] = vv.Y; | ||
647 | verticesAsFloats[vi++] = vv.Z; | ||
648 | } | ||
649 | 641 | ||
650 | // DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,key={1},lod={2},size={3},indices={4},vertices={5}", | 642 | int[] indices = meshData.getIndexListAsInt(); |
651 | // BSScene.DetailLogZero, newMeshKey.ToString("X"), lod, size, indices.Length, vertices.Count); | 643 | // int realIndicesIndex = indices.Length; |
652 | 644 | float[] verticesAsFloats = meshData.getVertexListAsFloat(); | |
653 | /* | 645 | |
654 | // DEBUG DEBUG | 646 | // Remove degenerate triangles. These are triangles with two of the vertices |
655 | for (int ii = 0; ii < indices.Length; ii += 3) | 647 | // are the same. This is complicated by the problem that vertices are not |
648 | // made unique in sculpties so we have to compare the values in the vertex. | ||
649 | int realIndicesIndex = 0; | ||
650 | for (int tri = 0; tri < indices.Length; tri += 3) | ||
656 | { | 651 | { |
657 | DetailLog("{0,3}: {1,3},{2,3},{3,3}: <{4,10},{5,10},{6,10}>, <{7,10},{8,10},{9,10}>, <{10,10},{11,10},{12,10}>", | 652 | int v1 = indices[tri + 0] * 3; |
658 | ii / 3, | 653 | int v2 = indices[tri + 1] * 3; |
659 | indices[ii + 0], | 654 | int v3 = indices[tri + 2] * 3; |
660 | indices[ii + 1], | 655 | if (!( ( verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] |
661 | indices[ii + 2], | 656 | && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] |
662 | verticesAsFloats[indices[ii+0] + 0], | 657 | && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2] ) |
663 | verticesAsFloats[indices[ii+0] + 1], | 658 | || ( verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] |
664 | verticesAsFloats[indices[ii+0] + 2], | 659 | && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] |
665 | verticesAsFloats[indices[ii+1] + 0], | 660 | && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2] ) |
666 | verticesAsFloats[indices[ii+1] + 1], | 661 | || ( verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] |
667 | verticesAsFloats[indices[ii+1] + 2], | 662 | && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] |
668 | verticesAsFloats[indices[ii+2] + 0], | 663 | && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2] ) ) |
669 | verticesAsFloats[indices[ii+2] + 1], | 664 | ) |
670 | verticesAsFloats[indices[ii+2] + 2] | 665 | { |
671 | ); | 666 | // None of the vertices of the triangles are the same. This is a good triangle; |
667 | indices[realIndicesIndex + 0] = indices[tri + 0]; | ||
668 | indices[realIndicesIndex + 1] = indices[tri + 1]; | ||
669 | indices[realIndicesIndex + 2] = indices[tri + 2]; | ||
670 | realIndicesIndex += 3; | ||
671 | } | ||
672 | } | 672 | } |
673 | // END DEBUG DEBUG | 673 | DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}", |
674 | */ | 674 | BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3); |
675 | 675 | ||
676 | newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, | 676 | newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, |
677 | indices.GetLength(0), indices, vertices.Count, verticesAsFloats); | 677 | realIndicesIndex, indices, verticesAsFloats.Length/3, verticesAsFloats); |
678 | } | 678 | } |
679 | } | 679 | } |
680 | newShape.shapeKey = newMeshKey; | 680 | newShape.shapeKey = newMeshKey; |
@@ -853,6 +853,11 @@ public sealed class BSShapeCollection : IDisposable | |||
853 | { | 853 | { |
854 | // level of detail based on size and type of the object | 854 | // level of detail based on size and type of the object |
855 | float lod = BSParam.MeshLOD; | 855 | float lod = BSParam.MeshLOD; |
856 | |||
857 | // prims with curvy internal cuts need higher lod | ||
858 | if (pbs.HollowShape == HollowShape.Circle) | ||
859 | lod = BSParam.MeshCircularLOD; | ||
860 | |||
856 | if (pbs.SculptEntry) | 861 | if (pbs.SculptEntry) |
857 | lod = BSParam.SculptLOD; | 862 | lod = BSParam.SculptLOD; |
858 | 863 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 1eaa523..bda7c47 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | |||
@@ -65,6 +65,8 @@ Vehicle attributes are not restored when a vehicle is rezzed on region creation | |||
65 | 65 | ||
66 | GENERAL TODO LIST: | 66 | GENERAL TODO LIST: |
67 | ================================================= | 67 | ================================================= |
68 | Level-of-detail for mesh creation. Prims with circular interiors require lod of 32. | ||
69 | Is much saved with lower LODs? At the moment, all set to 32. | ||
68 | Collisions are inconsistant: arrows are supposed to hit and report collision. Often don't. | 70 | Collisions are inconsistant: arrows are supposed to hit and report collision. Often don't. |
69 | If arrow show at prim, collision reported about 1/3 of time. If collision reported, | 71 | If arrow show at prim, collision reported about 1/3 of time. If collision reported, |
70 | both arrow and prim report it. The arrow bounces off the prim 9 out of 10 times. | 72 | both arrow and prim report it. The arrow bounces off the prim 9 out of 10 times. |
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index 10c4bd3..2e7bb5d 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs | |||
@@ -59,6 +59,7 @@ namespace OpenSim.Region.Physics.Manager | |||
59 | List<Vector3> getVertexList(); | 59 | List<Vector3> getVertexList(); |
60 | int[] getIndexListAsInt(); | 60 | int[] getIndexListAsInt(); |
61 | int[] getIndexListAsIntLocked(); | 61 | int[] getIndexListAsIntLocked(); |
62 | float[] getVertexListAsFloat(); | ||
62 | float[] getVertexListAsFloatLocked(); | 63 | float[] getVertexListAsFloatLocked(); |
63 | void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount); | 64 | void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount); |
64 | void getVertexListAsPtrToFloatArray(out IntPtr vertexList, out int vertexStride, out int vertexCount); | 65 | void getVertexListAsPtrToFloatArray(out IntPtr vertexList, out int vertexStride, out int vertexCount); |
diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs index f781ff9..bd8e306 100644 --- a/OpenSim/Region/Physics/Meshing/Mesh.cs +++ b/OpenSim/Region/Physics/Meshing/Mesh.cs | |||
@@ -152,7 +152,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
152 | return result; | 152 | return result; |
153 | } | 153 | } |
154 | 154 | ||
155 | private float[] getVertexListAsFloat() | 155 | public float[] getVertexListAsFloat() |
156 | { | 156 | { |
157 | if (m_vertices == null) | 157 | if (m_vertices == null) |
158 | throw new NotSupportedException(); | 158 | throw new NotSupportedException(); |