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.
user_profiles
Robert Adams 2013-02-05 16:51:02 -08:00
parent 13233da66c
commit dce9e323f4
6 changed files with 60 additions and 58 deletions

View File

@ -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); },

View File

@ -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<OMV.Vector3> vertices = meshData.getVertexList();
// int realIndicesIndex = indices.Length;
float[] verticesAsFloats = meshData.getVertexListAsFloat();
float[] verticesAsFloats = new float[vertices.Count * 3];
int vi = 0;
foreach (OMV.Vector3 vv in vertices)
// 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)
{
verticesAsFloats[vi++] = vv.X;
verticesAsFloats[vi++] = vv.Y;
verticesAsFloats[vi++] = vv.Z;
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;
}
}
// 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)
{
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]
);
}
// 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;

View File

@ -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.

View File

@ -59,6 +59,7 @@ namespace OpenSim.Region.Physics.Manager
List<Vector3> 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);

View File

@ -152,7 +152,7 @@ namespace OpenSim.Region.Physics.Meshing
return result;
}
private float[] getVertexListAsFloat()
public float[] getVertexListAsFloat()
{
if (m_vertices == null)
throw new NotSupportedException();

View File

@ -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