Merge branch 'master' of ssh://diva@opensimulator.org/var/git/opensim

remotes/origin/0.6.7-post-fixes
Diva Canto 2009-09-24 18:25:28 -07:00
commit a792933cba
4 changed files with 213 additions and 186 deletions

View File

@ -204,7 +204,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
tempAngularVelocity2 = new btVector3(0, 0, 0); tempAngularVelocity2 = new btVector3(0, 0, 0);
tempInertia1 = new btVector3(0, 0, 0); tempInertia1 = new btVector3(0, 0, 0);
tempInertia2 = new btVector3(0, 0, 0); tempInertia2 = new btVector3(0, 0, 0);
tempOrientation1 = new btQuaternion(0,0,0,1); tempOrientation1 = new btQuaternion(0, 0, 0, 1);
tempOrientation2 = new btQuaternion(0, 0, 0, 1); tempOrientation2 = new btQuaternion(0, 0, 0, 1);
_parent_scene = parent_scene; _parent_scene = parent_scene;
tempTransform1 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero); tempTransform1 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero);
@ -218,7 +218,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
AxisLockLinearLow = new btVector3(-1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize); AxisLockLinearLow = new btVector3(-1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize);
int regionsize = (int) Constants.RegionSize; int regionsize = (int)Constants.RegionSize;
if (regionsize == 256) if (regionsize == 256)
regionsize = 512; regionsize = 512;
@ -1012,7 +1012,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
{ {
if (_parent_scene.needsMeshing(_pbs)) if (_parent_scene.needsMeshing(_pbs))
{ {
ProcessGeomCreationAsTriMesh(PhysicsVector.Zero,Quaternion.Identity); ProcessGeomCreationAsTriMesh(PhysicsVector.Zero, Quaternion.Identity);
// createmesh returns null when it doesn't mesh. // createmesh returns null when it doesn't mesh.
CreateGeom(IntPtr.Zero, _mesh); CreateGeom(IntPtr.Zero, _mesh);
} }
@ -1038,7 +1038,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
meshlod = _parent_scene.MeshSculptphysicalLOD; meshlod = _parent_scene.MeshSculptphysicalLOD;
IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical); IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical);
if (!positionOffset.IsIdentical(PhysicsVector.Zero,0.001f) || orientation != Quaternion.Identity) if (!positionOffset.IsIdentical(PhysicsVector.Zero, 0.001f) || orientation != Quaternion.Identity)
{ {
float[] xyz = new float[3]; float[] xyz = new float[3];
@ -1048,7 +1048,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
Matrix4 m4 = Matrix4.CreateFromQuaternion(orientation); Matrix4 m4 = Matrix4.CreateFromQuaternion(orientation);
float[,] matrix = new float[3,3]; float[,] matrix = new float[3, 3];
matrix[0, 0] = m4.M11; matrix[0, 0] = m4.M11;
matrix[0, 1] = m4.M12; matrix[0, 1] = m4.M12;
@ -1627,7 +1627,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
{ {
if (m_zeroPosition == null) if (m_zeroPosition == null)
m_zeroPosition = new PhysicsVector(0, 0, 0); m_zeroPosition = new PhysicsVector(0, 0, 0);
m_zeroPosition.setValues(_position.X,_position.Y,_position.Z); m_zeroPosition.setValues(_position.X, _position.Y, _position.Z);
return; return;
} }
} }
@ -1994,15 +1994,15 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
//SetGeom to a Regular Sphere //SetGeom to a Regular Sphere
if (tempSize1 == null) if (tempSize1 == null)
tempSize1 = new btVector3(0, 0, 0); tempSize1 = new btVector3(0, 0, 0);
tempSize1.setValue(_size.X * 0.5f,_size.Y * 0.5f, _size.Z * 0.5f); tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
SetCollisionShape(new btSphereShape(_size.X*0.5f)); SetCollisionShape(new btSphereShape(_size.X * 0.5f));
} }
else else
{ {
// uses halfextents // uses halfextents
if (tempSize1 == null) if (tempSize1 == null)
tempSize1 = new btVector3(0, 0, 0); tempSize1 = new btVector3(0, 0, 0);
tempSize1.setValue(_size.X*0.5f, _size.Y*0.5f, _size.Z*0.5f); tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
SetCollisionShape(new btBoxShape(tempSize1)); SetCollisionShape(new btBoxShape(tempSize1));
} }
} }
@ -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);
@ -2068,17 +2078,17 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
btshapeArray.Dispose(); btshapeArray.Dispose();
//Array.Reverse(indexList); //Array.Reverse(indexList);
btshapeArray = new btTriangleIndexVertexArray(IndexCount / 3, indexList, (3 * sizeof(int)), btshapeArray = new btTriangleIndexVertexArray(IndexCount / 3, indexList, (3 * sizeof(int)),
VertexCount, vertexList, 3*sizeof (float)); VertexCount, vertexList, 3 * sizeof(float));
SetCollisionShape(new btGImpactMeshShape(btshapeArray)); SetCollisionShape(new btGImpactMeshShape(btshapeArray));
//((btGImpactMeshShape) prim_geom).updateBound(); //((btGImpactMeshShape) prim_geom).updateBound();
((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;
} //}
} }
@ -2143,8 +2153,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
if (prim_geom is btGImpactMeshShape) if (prim_geom is btGImpactMeshShape)
{ {
((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();
} }
//Body.setCollisionFlags(Body.getCollisionFlags() | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK); //Body.setCollisionFlags(Body.getCollisionFlags() | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK);
//Body.setUserPointer((IntPtr) (int)m_localID); //Body.setUserPointer((IntPtr) (int)m_localID);
@ -2252,7 +2262,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
if (Body.Handle != IntPtr.Zero) if (Body.Handle != IntPtr.Zero)
{ {
DisableAxisMotor(); DisableAxisMotor();
_parent_scene.removeFromWorld(this,Body); _parent_scene.removeFromWorld(this, Body);
Body.Dispose(); Body.Dispose();
} }
Body = null; Body = null;
@ -2587,10 +2597,10 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
_velocity.Y = tempLinearVelocity1.getY(); _velocity.Y = tempLinearVelocity1.getY();
_velocity.Z = tempLinearVelocity1.getZ(); _velocity.Z = tempLinearVelocity1.getZ();
_acceleration = ((_velocity - m_lastVelocity)/0.1f); _acceleration = ((_velocity - m_lastVelocity) / 0.1f);
_acceleration = new PhysicsVector(_velocity.X - m_lastVelocity.X/0.1f, _acceleration = new PhysicsVector(_velocity.X - m_lastVelocity.X / 0.1f,
_velocity.Y - m_lastVelocity.Y/0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f,
_velocity.Z - m_lastVelocity.Z/0.1f); _velocity.Z - m_lastVelocity.Z / 0.1f);
//m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString()); //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString());
if (_velocity.IsIdentical(pv, 0.5f)) if (_velocity.IsIdentical(pv, 0.5f))

View File

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

View File

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

View File

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