Merge branch 'master' of ssh://diva@opensimulator.org/var/git/opensim
commit
a792933cba
|
@ -2052,14 +2052,24 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//IMesh oldMesh = primMesh;
|
||||||
|
|
||||||
|
//primMesh = mesh;
|
||||||
|
|
||||||
|
//float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
|
||||||
|
//int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
|
||||||
|
////Array.Reverse(indexList);
|
||||||
|
//primMesh.releaseSourceMeshData(); // free up the original mesh data to save memory
|
||||||
|
|
||||||
IMesh oldMesh = primMesh;
|
IMesh oldMesh = primMesh;
|
||||||
|
|
||||||
primMesh = mesh;
|
primMesh = mesh;
|
||||||
|
|
||||||
float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
|
float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
|
||||||
int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
|
int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
|
||||||
//Array.Reverse(indexList);
|
//Array.Reverse(indexList);
|
||||||
primMesh.releaseSourceMeshData(); // free up the original mesh data to save memory
|
mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
|
||||||
|
|
||||||
|
|
||||||
int VertexCount = vertexList.GetLength(0) / 3;
|
int VertexCount = vertexList.GetLength(0) / 3;
|
||||||
int IndexCount = indexList.GetLength(0);
|
int IndexCount = indexList.GetLength(0);
|
||||||
|
@ -2074,11 +2084,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
|
||||||
((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
|
((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
|
||||||
((btGImpactMeshShape)prim_geom).updateBound();
|
((btGImpactMeshShape)prim_geom).updateBound();
|
||||||
_parent_scene.SetUsingGImpact();
|
_parent_scene.SetUsingGImpact();
|
||||||
if (oldMesh != null)
|
//if (oldMesh != null)
|
||||||
{
|
//{
|
||||||
oldMesh.releasePinned();
|
// oldMesh.releasePinned();
|
||||||
oldMesh = null;
|
// oldMesh = null;
|
||||||
}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
private List<Triangle> triangles;
|
private List<Triangle> triangles;
|
||||||
GCHandle pinnedVirtexes;
|
GCHandle pinnedVirtexes;
|
||||||
GCHandle pinnedIndex;
|
GCHandle pinnedIndex;
|
||||||
public PrimMesh primMesh = null;
|
|
||||||
public float[] normals;
|
public float[] normals;
|
||||||
|
|
||||||
public Mesh()
|
public Mesh()
|
||||||
|
@ -63,6 +62,8 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
public void Add(Triangle triangle)
|
public void Add(Triangle triangle)
|
||||||
{
|
{
|
||||||
|
if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated)
|
||||||
|
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
|
||||||
// If a vertex of the triangle is not yet in the vertices list,
|
// If a vertex of the triangle is not yet in the vertices list,
|
||||||
// add it and set its index to the current index count
|
// add it and set its index to the current index count
|
||||||
if (!vertices.ContainsKey(triangle.v1))
|
if (!vertices.ContainsKey(triangle.v1))
|
||||||
|
@ -148,10 +149,10 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
public float[] getVertexListAsFloatLocked()
|
public float[] getVertexListAsFloatLocked()
|
||||||
{
|
{
|
||||||
|
if( pinnedVirtexes.IsAllocated )
|
||||||
|
return (float[])(pinnedVirtexes.Target);
|
||||||
float[] result;
|
float[] result;
|
||||||
|
|
||||||
if (primMesh == null)
|
|
||||||
{
|
|
||||||
//m_log.WarnFormat("vertices.Count = {0}", vertices.Count);
|
//m_log.WarnFormat("vertices.Count = {0}", vertices.Count);
|
||||||
result = new float[vertices.Count * 3];
|
result = new float[vertices.Count * 3];
|
||||||
foreach (KeyValuePair<Vertex, int> kvp in vertices)
|
foreach (KeyValuePair<Vertex, int> kvp in vertices)
|
||||||
|
@ -164,24 +165,6 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
result[3 * i + 2] = v.Z;
|
result[3 * i + 2] = v.Z;
|
||||||
}
|
}
|
||||||
pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned);
|
pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int count = primMesh.coords.Count;
|
|
||||||
result = new float[count * 3];
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
Coord c = primMesh.coords[i];
|
|
||||||
{
|
|
||||||
int resultIndex = 3 * i;
|
|
||||||
result[resultIndex] = c.X;
|
|
||||||
result[resultIndex + 1] = c.Y;
|
|
||||||
result[resultIndex + 2] = c.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +172,6 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
{
|
{
|
||||||
int[] result;
|
int[] result;
|
||||||
|
|
||||||
if (primMesh == null)
|
|
||||||
{
|
|
||||||
result = new int[triangles.Count * 3];
|
result = new int[triangles.Count * 3];
|
||||||
for (int i = 0; i < triangles.Count; i++)
|
for (int i = 0; i < triangles.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -199,24 +180,6 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
result[3 * i + 1] = vertices[t.v2];
|
result[3 * i + 1] = vertices[t.v2];
|
||||||
result[3 * i + 2] = vertices[t.v3];
|
result[3 * i + 2] = vertices[t.v3];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int numFaces = primMesh.faces.Count;
|
|
||||||
result = new int[numFaces * 3];
|
|
||||||
for (int i = 0; i < numFaces; i++)
|
|
||||||
{
|
|
||||||
Face f = primMesh.faces[i];
|
|
||||||
// Coord c1 = primMesh.coords[f.v1];
|
|
||||||
// Coord c2 = primMesh.coords[f.v2];
|
|
||||||
// Coord c3 = primMesh.coords[f.v3];
|
|
||||||
|
|
||||||
int resultIndex = i * 3;
|
|
||||||
result[resultIndex] = f.v1;
|
|
||||||
result[resultIndex + 1] = f.v2;
|
|
||||||
result[resultIndex + 2] = f.v3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +189,9 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public int[] getIndexListAsIntLocked()
|
public int[] getIndexListAsIntLocked()
|
||||||
{
|
{
|
||||||
|
if (pinnedIndex.IsAllocated)
|
||||||
|
return (int[])(pinnedIndex.Target);
|
||||||
|
|
||||||
int[] result = getIndexListAsInt();
|
int[] result = getIndexListAsInt();
|
||||||
pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
|
pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
|
||||||
|
|
||||||
|
@ -245,11 +211,13 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
{
|
{
|
||||||
triangles = null;
|
triangles = null;
|
||||||
vertices = null;
|
vertices = null;
|
||||||
primMesh = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Append(IMesh newMesh)
|
public void Append(IMesh newMesh)
|
||||||
{
|
{
|
||||||
|
if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated)
|
||||||
|
throw new NotSupportedException("Attempt to Append to a pinned Mesh");
|
||||||
|
|
||||||
if (!(newMesh is Mesh))
|
if (!(newMesh is Mesh))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -260,6 +228,9 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
// Do a linear transformation of mesh.
|
// Do a linear transformation of mesh.
|
||||||
public void TransformLinear(float[,] matrix, float[] offset)
|
public void TransformLinear(float[,] matrix, float[] offset)
|
||||||
{
|
{
|
||||||
|
if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated)
|
||||||
|
throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh");
|
||||||
|
|
||||||
foreach (Vertex v in vertices.Keys)
|
foreach (Vertex v in vertices.Keys)
|
||||||
{
|
{
|
||||||
if (v == null)
|
if (v == null)
|
||||||
|
|
|
@ -76,6 +76,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
|
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
|
||||||
|
|
||||||
|
private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may
|
/// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may
|
||||||
|
@ -170,9 +171,62 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
|
private ulong GetMeshKey( PrimitiveBaseShape pbs, PhysicsVector size, float lod )
|
||||||
|
{
|
||||||
|
ulong hash = 5381;
|
||||||
|
|
||||||
|
hash = djb2(hash, pbs.PathCurve);
|
||||||
|
hash = djb2(hash, (byte)((byte)pbs.HollowShape | (byte)pbs.ProfileShape));
|
||||||
|
hash = djb2(hash, pbs.PathBegin);
|
||||||
|
hash = djb2(hash, pbs.PathEnd);
|
||||||
|
hash = djb2(hash, pbs.PathScaleX);
|
||||||
|
hash = djb2(hash, pbs.PathScaleY);
|
||||||
|
hash = djb2(hash, pbs.PathShearX);
|
||||||
|
hash = djb2(hash, pbs.PathShearY);
|
||||||
|
hash = djb2(hash, (byte)pbs.PathTwist);
|
||||||
|
hash = djb2(hash, (byte)pbs.PathTwistBegin);
|
||||||
|
hash = djb2(hash, (byte)pbs.PathRadiusOffset);
|
||||||
|
hash = djb2(hash, (byte)pbs.PathTaperX);
|
||||||
|
hash = djb2(hash, (byte)pbs.PathTaperY);
|
||||||
|
hash = djb2(hash, pbs.PathRevolutions);
|
||||||
|
hash = djb2(hash, (byte)pbs.PathSkew);
|
||||||
|
hash = djb2(hash, pbs.ProfileBegin);
|
||||||
|
hash = djb2(hash, pbs.ProfileEnd);
|
||||||
|
hash = djb2(hash, pbs.ProfileHollow);
|
||||||
|
|
||||||
|
// TODO: Separate scale out from the primitive shape data (after
|
||||||
|
// scaling is supported at the physics engine level)
|
||||||
|
byte[] scaleBytes = size.GetBytes();
|
||||||
|
for (int i = 0; i < scaleBytes.Length; i++)
|
||||||
|
hash = djb2(hash, scaleBytes[i]);
|
||||||
|
|
||||||
|
// Include LOD in hash, accounting for endianness
|
||||||
|
byte[] lodBytes = new byte[4];
|
||||||
|
Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
|
||||||
|
if (!BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
Array.Reverse(lodBytes, 0, 4);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < lodBytes.Length; i++)
|
||||||
|
hash = djb2(hash, lodBytes[i]);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ulong djb2(ulong hash, byte c)
|
||||||
|
{
|
||||||
|
return ((hash << 5) + hash) + (ulong)c;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ulong djb2(ulong hash, ushort c)
|
||||||
|
{
|
||||||
|
hash = ((hash << 5) + hash) + (ulong)((byte)c);
|
||||||
|
return ((hash << 5) + hash) + (ulong)(c >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
|
||||||
{
|
{
|
||||||
Mesh mesh = new Mesh();
|
|
||||||
PrimMesh primMesh;
|
PrimMesh primMesh;
|
||||||
PrimMesher.SculptMesh sculptMesh;
|
PrimMesher.SculptMesh sculptMesh;
|
||||||
|
|
||||||
|
@ -385,8 +439,6 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
coords = primMesh.coords;
|
coords = primMesh.coords;
|
||||||
faces = primMesh.faces;
|
faces = primMesh.faces;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -401,13 +453,13 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
vertices.Add(new Vertex(c.X, c.Y, c.Z));
|
vertices.Add(new Vertex(c.X, c.Y, c.Z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mesh mesh = new Mesh();
|
||||||
// Add the corresponding triangles to the mesh
|
// Add the corresponding triangles to the mesh
|
||||||
for (int i = 0; i < numFaces; i++)
|
for (int i = 0; i < numFaces; i++)
|
||||||
{
|
{
|
||||||
Face f = faces[i];
|
Face f = faces[i];
|
||||||
mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
|
mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +470,12 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod, bool isPhysical)
|
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod, bool isPhysical)
|
||||||
{
|
{
|
||||||
|
// If this mesh has been created already, return it instead of creating another copy
|
||||||
|
// For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
|
||||||
|
ulong key = GetMeshKey(primShape, size, lod);
|
||||||
Mesh mesh = null;
|
Mesh mesh = null;
|
||||||
|
if (m_uniqueMeshes.TryGetValue(key, out mesh))
|
||||||
|
return mesh;
|
||||||
|
|
||||||
if (size.X < 0.01f) size.X = 0.01f;
|
if (size.X < 0.01f) size.X = 0.01f;
|
||||||
if (size.Y < 0.01f) size.Y = 0.01f;
|
if (size.Y < 0.01f) size.Y = 0.01f;
|
||||||
|
@ -441,7 +498,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
// trim the vertex and triangle lists to free up memory
|
// trim the vertex and triangle lists to free up memory
|
||||||
mesh.TrimExcess();
|
mesh.TrimExcess();
|
||||||
}
|
}
|
||||||
|
m_uniqueMeshes.Add(key, mesh);
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
// private float m_tensor = 5f;
|
// private float m_tensor = 5f;
|
||||||
private int body_autodisable_frames = 20;
|
private int body_autodisable_frames = 20;
|
||||||
private IMesh primMesh = null;
|
|
||||||
|
|
||||||
|
|
||||||
private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
|
private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
|
||||||
|
@ -814,14 +813,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMesh oldMesh = primMesh;
|
float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
|
||||||
|
int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
|
||||||
|
|
||||||
primMesh = mesh;
|
mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
|
||||||
|
|
||||||
float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
|
|
||||||
int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
|
|
||||||
|
|
||||||
primMesh.releaseSourceMeshData(); // free up the original mesh data to save memory
|
|
||||||
|
|
||||||
int VertexCount = vertexList.GetLength(0)/3;
|
int VertexCount = vertexList.GetLength(0)/3;
|
||||||
int IndexCount = indexList.GetLength(0);
|
int IndexCount = indexList.GetLength(0);
|
||||||
|
@ -847,12 +842,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldMesh != null)
|
|
||||||
{
|
|
||||||
oldMesh.releasePinned();
|
|
||||||
oldMesh = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (IsPhysical && Body == (IntPtr) 0)
|
// if (IsPhysical && Body == (IntPtr) 0)
|
||||||
// {
|
// {
|
||||||
// Recreate the body
|
// Recreate the body
|
||||||
|
|
Loading…
Reference in New Issue