From dce9e323f4f0fdccd2f34266e870de9cbcebd2f0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 5 Feb 2013 16:51:02 -0800 Subject: 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. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 18 +++-- .../Physics/BulletSPlugin/BSShapeCollection.cs | 81 ++++++++++++---------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 + OpenSim/Region/Physics/Manager/IMesher.cs | 1 + OpenSim/Region/Physics/Meshing/Mesh.cs | 2 +- bin/OpenSimDefaults.ini | 16 +---- 6 files changed, 61 insertions(+), 59 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 { // Level of Detail values kept as float because that's what the Meshmerizer wants public static float MeshLOD { get; private set; } + public static float MeshCircularLOD { get; private set; } public static float MeshMegaPrimLOD { get; private set; } public static float MeshMegaPrimThreshold { get; private set; } public static float SculptLOD { get; private set; } @@ -219,20 +220,25 @@ public static class BSParam (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", - 8f, + 32f, (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, (s) => { return MeshLOD; }, (s,p,l,v) => { MeshLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", - 16f, - (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return MeshMegaPrimLOD; }, - (s,p,l,v) => { MeshMegaPrimLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailCircular", "Level of detail for prims with circular cuts or shapes", + 32f, + (s,cf,p,v) => { MeshCircularLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshCircularLOD; }, + (s,p,l,v) => { MeshCircularLOD = v; } ), new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", 10f, (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, (s) => { return MeshMegaPrimThreshold; }, (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", + 32f, + (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshMegaPrimLOD; }, + (s,p,l,v) => { MeshMegaPrimLOD = v; } ), new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", 32f, (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 if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) return false; - if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", - prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2},size={3},lod={4}", + prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod); // Since we're recreating new, get rid of the reference to the previous shape DereferenceShape(prim.PhysShape, shapeCallback); @@ -631,50 +631,50 @@ public sealed class BSShapeCollection : IDisposable } else { - IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); + IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, + false, // say it is not physical so a bounding box is not built + false // do not cache the mesh and do not use previously built versions + ); if (meshData != null) { - int[] indices = meshData.getIndexListAsInt(); - List vertices = meshData.getVertexList(); - - float[] verticesAsFloats = new float[vertices.Count * 3]; - int vi = 0; - foreach (OMV.Vector3 vv in vertices) - { - verticesAsFloats[vi++] = vv.X; - verticesAsFloats[vi++] = vv.Y; - verticesAsFloats[vi++] = vv.Z; - } - // DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,key={1},lod={2},size={3},indices={4},vertices={5}", - // BSScene.DetailLogZero, newMeshKey.ToString("X"), lod, size, indices.Length, vertices.Count); - - /* - // DEBUG DEBUG - for (int ii = 0; ii < indices.Length; ii += 3) + int[] indices = meshData.getIndexListAsInt(); + // int realIndicesIndex = indices.Length; + float[] verticesAsFloats = meshData.getVertexListAsFloat(); + + // Remove degenerate triangles. These are triangles with two of the vertices + // are the same. This is complicated by the problem that vertices are not + // made unique in sculpties so we have to compare the values in the vertex. + int realIndicesIndex = 0; + for (int tri = 0; tri < indices.Length; tri += 3) { - 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}>", - ii / 3, - indices[ii + 0], - indices[ii + 1], - indices[ii + 2], - verticesAsFloats[indices[ii+0] + 0], - verticesAsFloats[indices[ii+0] + 1], - verticesAsFloats[indices[ii+0] + 2], - verticesAsFloats[indices[ii+1] + 0], - verticesAsFloats[indices[ii+1] + 1], - verticesAsFloats[indices[ii+1] + 2], - verticesAsFloats[indices[ii+2] + 0], - verticesAsFloats[indices[ii+2] + 1], - verticesAsFloats[indices[ii+2] + 2] - ); + int v1 = indices[tri + 0] * 3; + int v2 = indices[tri + 1] * 3; + int v3 = indices[tri + 2] * 3; + if (!( ( verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] + && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] + && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2] ) + || ( verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] + && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] + && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2] ) + || ( verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] + && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] + && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2] ) ) + ) + { + // None of the vertices of the triangles are the same. This is a good triangle; + indices[realIndicesIndex + 0] = indices[tri + 0]; + indices[realIndicesIndex + 1] = indices[tri + 1]; + indices[realIndicesIndex + 2] = indices[tri + 2]; + realIndicesIndex += 3; + } } - // END DEBUG DEBUG - */ + DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}", + BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3); newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, - indices.GetLength(0), indices, vertices.Count, verticesAsFloats); + realIndicesIndex, indices, verticesAsFloats.Length/3, verticesAsFloats); } } newShape.shapeKey = newMeshKey; @@ -853,6 +853,11 @@ public sealed class BSShapeCollection : IDisposable { // level of detail based on size and type of the object float lod = BSParam.MeshLOD; + + // prims with curvy internal cuts need higher lod + if (pbs.HollowShape == HollowShape.Circle) + lod = BSParam.MeshCircularLOD; + if (pbs.SculptEntry) lod = BSParam.SculptLOD; 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 GENERAL TODO LIST: ================================================= +Level-of-detail for mesh creation. Prims with circular interiors require lod of 32. + Is much saved with lower LODs? At the moment, all set to 32. Collisions are inconsistant: arrows are supposed to hit and report collision. Often don't. If arrow show at prim, collision reported about 1/3 of time. If collision reported, 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 List getVertexList(); int[] getIndexListAsInt(); int[] getIndexListAsIntLocked(); + float[] getVertexListAsFloat(); float[] getVertexListAsFloatLocked(); void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount); 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 return result; } - private float[] getVertexListAsFloat() + public float[] getVertexListAsFloat() { if (m_vertices == null) throw new NotSupportedException(); diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 9119273..7bdfd1c 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -916,13 +916,9 @@ ; Terrain Implementation {1|0} 0 for HeightField, 1 for Mesh terrain. If you're using the bulletxna engine, ; you will want to switch to the heightfield option - TerrainImplementation = 1 ; TerrainImplementation = 0 - DefaultFriction = 0.20 - DefaultDensity = 10.000006836 - DefaultRestitution = 0.0 Gravity = -9.80665 TerrainFriction = 0.30 @@ -931,7 +927,7 @@ TerrainCollisionMargin = 0.04 AvatarFriction = 0.2 - AvatarStandingFriction = 10.0 + AvatarStandingFriction = 0.95 AvatarRestitution = 0.0 AvatarDensity = 3.5 AvatarCapsuleWidth = 0.6 @@ -943,7 +939,7 @@ CollisionMargin = 0.04 - ; Linkset constraint parameters + ; Linkset implmentation LinkImplementation = 1 ; 0=constraint, 1=compound ; Whether to mesh sculpties @@ -952,14 +948,6 @@ ; If 'true', force simple prims (box and sphere) to be meshed ForceSimplePrimMeshing = false - ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail - MeshLevelOfDetail = 8 - ; if mesh size is > threshold meters, we need to add more detail because people will notice - MeshLevelOfDetailMegaPrimThreshold = 10 - MeshLevelOfDetailMegaPrim = 16 - ; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies - SculptLevelOfDetail = 32 - ; Bullet step parameters MaxSubSteps = 10 FixedTimeStep = .01667 -- cgit v1.1