WORK in progress!! Now it reads the simple hull shape to use if convex shape is selected for a prim. Due to ODE limitations on convex hulls colisions, it creates a mesh. Being work in progress it is hardcoded to only read that simple convex hull for now. It writes a file named "lixo_lixo.raw" that can be imported into blender for examination of the created mesh (the last one loaded and also hardcoded). To play with put in opensim.ini "meshing = UbitMeshmerizer"

avinationmerge
UbitUmarov 2012-03-20 19:24:45 +00:00
parent efd7ff3146
commit 8c1550b58e
2 changed files with 164 additions and 124 deletions

View File

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

View File

@ -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<Vertex> vertices = new List<Vertex>();
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<Coord>();
faces = new List<Face>();
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<float3> vs = new List<float3>();
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<int> hsizes = new List<int>();
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;