diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
index cc9248450a..c32cf38e5d 100644
--- a/OpenSim/Region/Physics/Manager/IMesher.cs
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -36,6 +36,7 @@ namespace OpenSim.Region.Physics.Manager
{
IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod);
IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical);
+ IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical,bool convex);
}
// Values for level of detail to be passed to the mesher.
diff --git a/OpenSim/Region/Physics/Manager/ZeroMesher.cs b/OpenSim/Region/Physics/Manager/ZeroMesher.cs
index ba19db6c18..8a3b50bdad 100644
--- a/OpenSim/Region/Physics/Manager/ZeroMesher.cs
+++ b/OpenSim/Region/Physics/Manager/ZeroMesher.cs
@@ -67,6 +67,11 @@ namespace OpenSim.Region.Physics.Manager
return CreateMesh(primName, primShape, size, lod, false);
}
+ public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
+ {
+ return CreateMesh(primName, primShape, size, lod, false);
+ }
+
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical)
{
// Remove the reference to the encoded JPEG2000 data so it can be GCed
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 79e50d29af..75fa1efd45 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -717,6 +717,11 @@ namespace OpenSim.Region.Physics.Meshing
return CreateMesh(primName, primShape, size, lod, false);
}
+ public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
+ {
+ return CreateMesh(primName, primShape, size, lod, false);
+ }
+
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical)
{
#if SPAM
diff --git a/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs b/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs
index 8cd8dcf6ff..293825779e 100644
--- a/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs
@@ -270,116 +270,20 @@ public class Triangle
public Vertex v2;
public Vertex v3;
- private float radius_square;
- private float cx;
- private float cy;
-
public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
{
v1 = _v1;
v2 = _v2;
v3 = _v3;
-
- CalcCircle();
}
- public bool isInCircle(float x, float y)
+ public Triangle(float _v1x,float _v1y,float _v1z,
+ float _v2x,float _v2y,float _v2z,
+ float _v3x,float _v3y,float _v3z)
{
- float dx, dy;
- float dd;
-
- dx = x - cx;
- dy = y - cy;
-
- dd = dx*dx + dy*dy;
- if (dd < radius_square)
- return true;
- else
- return false;
- }
-
- public bool isDegraded()
- {
- // This means, the vertices of this triangle are somewhat strange.
- // They either line up or at least two of them are identical
- return (radius_square == 0.0);
- }
-
- private void CalcCircle()
- {
- // Calculate the center and the radius of a circle given by three points p1, p2, p3
- // It is assumed, that the triangles vertices are already set correctly
- double p1x, p2x, p1y, p2y, p3x, p3y;
-
- // Deviation of this routine:
- // A circle has the general equation (M-p)^2=r^2, where M and p are vectors
- // this gives us three equations f(p)=r^2, each for one point p1, p2, p3
- // putting respectively two equations together gives two equations
- // f(p1)=f(p2) and f(p1)=f(p3)
- // bringing all constant terms to one side brings them to the form
- // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
- // and c1, c2 are scalars (Naming conventions like the variables below)
- // Now using the equations that are formed by the components of the vectors
- // and isolate Mx lets you make one equation that only holds My
- // The rest is straight forward and eaasy :-)
- //
-
- /* helping variables for temporary results */
- double c1, c2;
- double v1x, v1y, v2x, v2y;
-
- double z, n;
-
- double rx, ry;
-
- // Readout the three points, the triangle consists of
- p1x = v1.X;
- p1y = v1.Y;
-
- p2x = v2.X;
- p2y = v2.Y;
-
- p3x = v3.X;
- p3y = v3.Y;
-
- /* calc helping values first */
- c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
- c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
-
- v1x = p1x - p2x;
- v1y = p1y - p2y;
-
- v2x = p1x - p3x;
- v2y = p1y - p3y;
-
- z = (c1*v2x - c2*v1x);
- n = (v1y*v2x - v2y*v1x);
-
- if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
- {
- radius_square = 0.0f;
- return;
- }
-
- cy = (float) (z/n);
-
- if (v2x != 0.0)
- {
- cx = (float) ((c2 - v2y*cy)/v2x);
- }
- else if (v1x != 0.0)
- {
- cx = (float) ((c1 - v1y*cy)/v1x);
- }
- else
- {
- Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
- }
-
- rx = (p1x - cx);
- ry = (p1y - cy);
-
- radius_square = (float) (rx*rx + ry*ry);
+ v1 = new Vertex(_v1x, _v1y, _v1z);
+ v2 = new Vertex(_v2x, _v2y, _v2z);
+ v3 = new Vertex(_v3x, _v3y, _v3z);
}
public override String ToString()
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
index c9c52c0fba..7667e91f62 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
@@ -41,6 +41,7 @@ using Nini.Config;
using System.Reflection;
using System.IO;
using ComponentAce.Compression.Libs.zlib;
+using OpenSim.Region.Physics.ConvexDecompositionDotNet;
namespace OpenSim.Region.Physics.Meshing
{
@@ -256,7 +257,7 @@ namespace OpenSim.Region.Physics.Meshing
///
///
///
- private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
+ private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool convex)
{
// m_log.DebugFormat(
// "[MESH]: Creating physics proxy for {0}, shape {1}",
@@ -272,7 +273,7 @@ namespace OpenSim.Region.Physics.Meshing
if (!useMeshiesPhysicsMesh)
return null;
- if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces))
+ if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces, convex))
return null;
}
else
@@ -296,22 +297,20 @@ namespace OpenSim.Region.Physics.Meshing
int numCoords = coords.Count;
int numFaces = faces.Count;
- // Create the list of vertices
- List vertices = new List();
- for (int i = 0; i < numCoords; i++)
- {
- Coord c = coords[i];
- vertices.Add(new Vertex(c.X, c.Y, c.Z));
- }
-
Mesh mesh = new Mesh();
// Add the corresponding triangles to the mesh
for (int i = 0; i < numFaces; i++)
{
Face f = faces[i];
- mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
+ mesh.Add(new Triangle(coords[f.v1].X, coords[f.v1].Y, coords[f.v1].Z,
+ coords[f.v2].X, coords[f.v2].Y, coords[f.v2].Z,
+ coords[f.v3].X, coords[f.v3].Y, coords[f.v3].Z));
}
+
+// mesh.DumpRaw("c:\\lixo", "lixo", "lixo");
+ mesh.DumpRaw(".", "lixo", "lixo");
+
return mesh;
}
@@ -325,10 +324,12 @@ namespace OpenSim.Region.Physics.Meshing
/// Faces are added to this list by the method.
/// true if coords and faces were successfully generated, false if not
private bool GenerateCoordsAndFacesFromPrimMeshData(
- string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces)
+ string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces, bool convex)
{
// m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
+ bool usemesh = false;
+
coords = new List();
faces = new List();
OSD meshOsd = null;
@@ -365,14 +366,25 @@ namespace OpenSim.Region.Physics.Meshing
{
OSDMap physicsParms = null;
OSDMap map = (OSDMap)meshOsd;
- if (map.ContainsKey("physics_shape"))
- physicsParms = (OSDMap)map["physics_shape"]; // old asset format
- else if (map.ContainsKey("physics_mesh"))
- physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
+
+ if (!convex)
+ {
+ if (map.ContainsKey("physics_shape"))
+ physicsParms = (OSDMap)map["physics_shape"]; // old asset format
+ else if (map.ContainsKey("physics_mesh"))
+ physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
+
+ if (physicsParms != null)
+ usemesh = true;
+ }
+
+ if(!usemesh && (map.ContainsKey("physics_convex")))
+ physicsParms = (OSDMap)map["physics_convex"];
+
if (physicsParms == null)
{
- m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset");
+ m_log.Warn("[MESH]: unknown mesh type");
return false;
}
@@ -416,20 +428,270 @@ namespace OpenSim.Region.Physics.Meshing
return false;
}
- OSDArray decodedMeshOsdArray = null;
-
- // physics_shape is an array of OSDMaps, one for each submesh
- if (decodedMeshOsd is OSDArray)
+ if (usemesh)
{
-// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
+ OSDArray decodedMeshOsdArray = null;
- decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
- foreach (OSD subMeshOsd in decodedMeshOsdArray)
+ // physics_shape is an array of OSDMaps, one for each submesh
+ if (decodedMeshOsd is OSDArray)
{
- if (subMeshOsd is OSDMap)
- AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
+ // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
+
+ decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
+ foreach (OSD subMeshOsd in decodedMeshOsdArray)
+ {
+ if (subMeshOsd is OSDMap)
+ AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
+ }
}
}
+ else
+ {
+ OSDMap cmap = (OSDMap)decodedMeshOsd;
+ if (cmap == null)
+ return false;
+
+ byte[] data;
+ const float invMaxU16 = 1.0f / 65535f;
+ int t1;
+ int t2;
+ int t3;
+ int i;
+
+ List vs = new List();
+
+ float3 f3;
+ PHullResult hullr = new PHullResult();
+
+ Coord c;
+ Face f;
+
+ Vector3 range;
+ Vector3 min;
+ int nverts;
+ int nindexs;
+
+ if (cmap.ContainsKey("Max"))
+ range = cmap["Max"].AsVector3();
+ else
+ range = new Vector3(0.5f, 0.5f, 0.5f);
+
+ if (cmap.ContainsKey("Min"))
+ min = cmap["Min"].AsVector3();
+ else
+ min = new Vector3(-0.5f, -0.5f, -0.5f);
+
+ range = range - min;
+ range *= invMaxU16;
+
+ if (!convex && cmap.ContainsKey("HullList") && cmap.ContainsKey("Positions"))
+ {
+ List hsizes = new List();
+ int totalpoints = 0;
+ data = cmap["HullList"].AsBinary();
+ for (i = 0; i < data.Length; i++)
+ {
+ t1 = data[i];
+ if (t1 == 0)
+ t1 = 256;
+ totalpoints += t1;
+ hsizes.Add(t1);
+ }
+
+ data = cmap["Positions"].AsBinary();
+ int ptr = 0;
+ int vertsoffset = 0;
+
+ if (totalpoints == data.Length / 6) // 2 bytes per coord, 3 coords per point
+ {
+ foreach (int hullsize in hsizes)
+ {
+ for (i = 0; i < hullsize; i++ )
+ {
+ t1 = data[ptr++];
+ t1 += data[ptr++] << 8;
+ t2 = data[ptr++];
+ t2 += data[ptr++] << 8;
+ t3 = data[ptr++];
+ t3 += data[ptr++] << 8;
+
+ f3 = new float3((t1 * range.X + min.X) * size.X,
+ (t2 * range.Y + min.Y) * size.Y,
+ (t3 * range.Z + min.Z) * size.Z);
+ vs.Add(f3);
+ }
+
+ if(hullsize <3)
+ {
+ vs.Clear();
+ continue;
+ }
+
+ if (hullsize <5)
+ {
+ foreach (float3 point in vs)
+ {
+ c.X = point.x;
+ c.Y = point.y;
+ c.Z = point.z;
+ coords.Add(c);
+ }
+ f = new Face(vertsoffset, vertsoffset + 1, vertsoffset + 2);
+ faces.Add(f);
+
+ if (hullsize == 4)
+ {
+ // not sure about orientation..
+ f = new Face(vertsoffset, vertsoffset + 2, vertsoffset + 3);
+ faces.Add(f);
+ f = new Face(vertsoffset, vertsoffset + 3, vertsoffset + 1);
+ faces.Add(f);
+ f = new Face(vertsoffset + 3, vertsoffset + 2, vertsoffset + 1);
+ faces.Add(f);
+ }
+ vertsoffset += vs.Count;
+ vs.Clear();
+ continue;
+ }
+
+ if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
+ {
+ vs.Clear();
+ continue;
+ }
+
+ nverts = hullr.Vertices.Count;
+ nindexs = hullr.Indices.Count;
+
+ if (nindexs % 3 != 0)
+ {
+ vs.Clear();
+ continue;
+ }
+
+ for (i = 0; i < nverts; i++)
+ {
+ c.X = hullr.Vertices[i].x;
+ c.Y = hullr.Vertices[i].y;
+ c.Z = hullr.Vertices[i].z;
+ coords.Add(c);
+ }
+
+
+ for (i = 0; i < nindexs; i += 3)
+ {
+ t1 = hullr.Indices[i];
+ if (t1 > nverts)
+ break;
+ t2 = hullr.Indices[i + 1];
+ if (t2 > nverts)
+ break;
+ t3 = hullr.Indices[i + 2];
+ if (t3 > nverts)
+ break;
+ f = new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3);
+ faces.Add(f);
+ }
+ vertsoffset += nverts;
+ vs.Clear();
+ }
+ }
+ if (coords.Count > 0 && faces.Count > 0)
+ return true;
+
+ }
+
+ vs.Clear();
+
+ if (cmap.ContainsKey("BoundingVerts"))
+ {
+ data = cmap["BoundingVerts"].AsBinary();
+
+ for (i = 0; i < data.Length; )
+ {
+ t1 = data[i++];
+ t1 += data[i++] << 8;
+ t2 = data[i++];
+ t2 += data[i++] << 8;
+ t3 = data[i++];
+ t3 += data[i++] << 8;
+
+ f3 = new float3((t1 * range.X + min.X) * size.X,
+ (t2 * range.Y + min.Y) * size.Y,
+ (t3 * range.Z + min.Z) * size.Z);
+ vs.Add(f3);
+ }
+
+ if (vs.Count < 3)
+ {
+ vs.Clear();
+ return false;
+ }
+
+ if (vs.Count < 5)
+ {
+ foreach (float3 point in vs)
+ {
+ c.X = point.x;
+ c.Y = point.y;
+ c.Z = point.z;
+ coords.Add(c);
+ }
+ f = new Face(0, 1, 2);
+ faces.Add(f);
+
+ if (vs.Count == 4)
+ {
+ // not sure about orientation..
+ f = new Face(0, 2, 3);
+ faces.Add(f);
+ f = new Face(0, 3, 1);
+ faces.Add(f);
+ f = new Face( 3, 2, 1);
+ faces.Add(f);
+ }
+ vs.Clear();
+ return true;
+ }
+
+ if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
+ return false;
+
+ nverts = hullr.Vertices.Count;
+ nindexs = hullr.Indices.Count;
+
+ if (nindexs % 3 != 0)
+ return false;
+
+ for (i = 0; i < nverts; i++)
+ {
+ c.X = hullr.Vertices[i].x;
+ c.Y = hullr.Vertices[i].y;
+ c.Z = hullr.Vertices[i].z;
+ coords.Add(c);
+ }
+ for (i = 0; i < nindexs; i += 3)
+ {
+ t1 = hullr.Indices[i];
+ if (t1 > nverts)
+ break;
+ t2 = hullr.Indices[i + 1];
+ if (t2 > nverts)
+ break;
+ t3 = hullr.Indices[i + 2];
+ if (t3 > nverts)
+ break;
+ f = new Face(t1, t2, t3);
+ faces.Add(f);
+ }
+
+ if (coords.Count > 0 && faces.Count > 0)
+ return true;
+ }
+ else
+ return false;
+
+ }
}
return true;
@@ -714,11 +976,16 @@ namespace OpenSim.Region.Physics.Meshing
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
{
- return CreateMesh(primName, primShape, size, lod, false);
+ return CreateMesh(primName, primShape, size, lod, false,false);
}
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical)
{
+ return CreateMesh(primName, primShape, size, lod, false,false);
+ }
+
+ public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
+ {
#if SPAM
m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName);
#endif
@@ -736,7 +1003,7 @@ namespace OpenSim.Region.Physics.Meshing
if (size.Y < 0.01f) size.Y = 0.01f;
if (size.Z < 0.01f) size.Z = 0.01f;
- mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);
+ mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex);
if (mesh != null)
{