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..a04df811f7 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 { @@ -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; } @@ -329,6 +328,10 @@ namespace OpenSim.Region.Physics.Meshing { // m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); + + bool convex = true; // this will be a input + bool usemesh = false; + coords = new List(); faces = new List(); OSD meshOsd = null; @@ -365,14 +368,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 +430,142 @@ 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(); + Mesh m = new Mesh(); + + Vector3 range; + Vector3 min; + + 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")) + if (cmap.ContainsKey("HullList")) + { + List hsizes = new List(); + + data = cmap["HullList"].AsBinary(); + for (i = 0; i < data.Length; i++) + { + t1 = data[i]; + if (t1 == 0) + t1 = 256; + hsizes.Add(t1); + } + +bla bla + + + + } + */ + + 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 (!HullUtils.ComputeHull(vs, ref hullr, 300, 0.0f)) + return false; + + int nverts = hullr.Vertices.Count; + int nindexs = hullr.Indices.Count; + + if (nindexs % 3 != 0) + return false; + + Coord c; + 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); + } + + Face f; + + 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;