Committing more work towards implementing vertex normals. Also added some (hopefully) helpful messages for identifying corrupt prims and some fixup code for corrupt profile cut data.

This commit is contained in:
Dahlia Trimble
2008-10-13 22:52:39 +00:00
parent a351d3a22f
commit 138a3924e0
2 changed files with 175 additions and 64 deletions

View File

@@ -1626,6 +1626,14 @@ namespace OpenSim.Region.Physics.Meshing
}
}
private void ReportPrimError(string message, string primName, PrimMesh primMesh)
{
Console.WriteLine(message);
Console.WriteLine("\nPrim Name: " + primName);
Console.WriteLine("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
}
public Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
{
Mesh mesh = new Mesh();
@@ -1676,6 +1684,13 @@ namespace OpenSim.Region.Physics.Meshing
primMesh.twistEnd = primShape.PathTwist * 18 / 10;
primMesh.taperX = pathScaleX;
primMesh.taperY = pathScaleY;
if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
{
ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
if (profileBegin < 0.0f) profileBegin = 0.0f;
if (profileEnd > 1.0f) profileEnd = 1.0f;
}
#if SPAM
Console.WriteLine("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
#endif
@@ -1685,9 +1700,7 @@ namespace OpenSim.Region.Physics.Meshing
}
catch (Exception ex)
{
Console.WriteLine("Extrusion failure: exception: " + ex.ToString());
Console.WriteLine("\n Prim Name: " + primName);
Console.WriteLine("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
return null;
}
}
@@ -1702,6 +1715,13 @@ namespace OpenSim.Region.Physics.Meshing
primMesh.twistEnd = primShape.PathTwist * 36 / 10;
primMesh.taperX = primShape.PathTaperX * 0.01f;
primMesh.taperY = primShape.PathTaperY * 0.01f;
if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
{
ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
if (profileBegin < 0.0f) profileBegin = 0.0f;
if (profileEnd > 1.0f) profileEnd = 1.0f;
}
#if SPAM
Console.WriteLine("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
#endif
@@ -1711,9 +1731,7 @@ namespace OpenSim.Region.Physics.Meshing
}
catch (Exception ex)
{
Console.WriteLine("Extrusion failure: exception: " + ex.ToString());
Console.WriteLine("\n Prim Name: " + primName);
Console.WriteLine("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
return null;
}
}

View File

@@ -415,7 +415,7 @@ namespace PrimMesher
internal List<Coord> coords;
internal List<Face> faces;
internal List<Coord> normals;
internal List<Coord> edgeNormals;
internal bool calcVertexNormals = false;
@@ -423,7 +423,7 @@ namespace PrimMesher
{
this.coords = new List<Coord>();
this.faces = new List<Face>();
this.normals = new List<Coord>();
this.edgeNormals = new List<Coord>();
}
public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals)
@@ -431,9 +431,14 @@ namespace PrimMesher
this.calcVertexNormals = calcVertexNormals;
this.coords = new List<Coord>();
this.faces = new List<Face>();
this.normals = new List<Coord>();
this.edgeNormals = new List<Coord>();
Coord center = new Coord(0.0f, 0.0f, 0.0f);
List<Coord> hollowCoords = new List<Coord>();
List<Coord> hollowNormals = new List<Coord>();
bool hasHollow = (hollow > 0.0f);
bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f);
AngleList angles = new AngleList();
AngleList hollowAngles = new AngleList();
@@ -458,25 +463,10 @@ namespace PrimMesher
return;
}
bool simpleFace = false; // flag to create as few triangles as possible for 3 or 4 side profile
if (sides < 5 && hollow == 0.0f && profileStart == 0.0f && profileEnd == 1.0f)
simpleFace = true;
// flag to create as few triangles as possible for 3 or 4 side profile
bool simpleFace = (sides < 5 && !(hasHollow || hasProfileCut));
if (this.calcVertexNormals)
{
if (sides > 4)
foreach (Angle a in angles.angles)
normals.Add(new Coord(a.X, a.Y, 0.0f));
else
for (int i = 0; i < angles.angles.Count - 1; i++)
{
Angle a1 = angles.angles[i];
Angle a2 = angles.angles[i + 1];
normals.Add(new Coord(0.5f * (a1.X + a2.X), 0.5f * (a1.Y + a2.Y), 0.0f).Normalize());
}
}
if (hollow > 0.001f)
if (hasHollow)
{
if (sides == hollowSides)
hollowAngles = angles;
@@ -490,33 +480,19 @@ namespace PrimMesher
return;
}
}
if (this.calcVertexNormals)
{
if (hollowSides > 4)
foreach (Angle a in hollowAngles.angles)
normals.Add(new Coord(-a.X, -a.Y, 0.0f));
else
for (int i = 0; i < hollowAngles.angles.Count - 1; i++)
{
Angle a1 = hollowAngles.angles[i];
Angle a2 = hollowAngles.angles[i + 1];
normals.Add(new Coord(-0.5f * (a1.X + a2.X), -0.5f * (a1.Y + a2.Y), 0.0f).Normalize());
}
}
}
else if (!simpleFace)
{
this.coords.Add(center);
if (this.calcVertexNormals && sides > 4)
this.normals.Add(new Coord(0.0f, 0.0f, 1.0f));
this.edgeNormals.Add(new Coord(0.0f, 0.0f, 1.0f));
}
float z = 0.0f;
Angle angle;
Coord newVert = new Coord();
if (hollow > 0.001f && hollowSides != sides)
if (hasHollow && hollowSides != sides)
{
int numHollowAngles = hollowAngles.angles.Count;
for (int i = 0; i < numHollowAngles; i++)
@@ -527,6 +503,8 @@ namespace PrimMesher
newVert.Z = z;
hollowCoords.Add(newVert);
if (this.calcVertexNormals)
hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
}
}
@@ -539,6 +517,8 @@ namespace PrimMesher
newVert.Y = angle.Y * yScale;
newVert.Z = z;
this.coords.Add(newVert);
if (this.calcVertexNormals)
this.edgeNormals.Add(new Coord(angle.X, angle.Y, 0.0f));
if (hollow > 0.0f)
{
@@ -548,6 +528,8 @@ namespace PrimMesher
newVert.Y *= hollow;
newVert.Z = z;
hollowCoords.Add(newVert);
if (this.calcVertexNormals)
hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
}
}
else if (!simpleFace && createFaces && angle.angle > 0.0001f)
@@ -556,14 +538,22 @@ namespace PrimMesher
newFace.v1 = 0;
newFace.v2 = index;
newFace.v3 = index + 1;
//if (this.calcVertexNormals)
//{
// newFace.n1 = newFace.v1;
// newFace.n2 = newFace.v2;
// newFace.n3 = newFace.v3;
//}
this.faces.Add(newFace);
}
index += 1;
}
if (hollow > 0.0f)
if (hasHollow)
{
hollowCoords.Reverse();
if (this.calcVertexNormals)
hollowNormals.Reverse();
if (createFaces)
{
@@ -580,11 +570,23 @@ namespace PrimMesher
newFace.v1 = coordIndex;
newFace.v2 = coordIndex + 1;
newFace.v3 = numTotalVerts - coordIndex - 1;
//if (this.calcVertexNormals)
//{
// newFace.n1 = newFace.v1;
// newFace.n2 = newFace.v2;
// newFace.n3 = newFace.v3;
//}
this.faces.Add(newFace);
newFace.v1 = coordIndex + 1;
newFace.v2 = numTotalVerts - coordIndex - 2;
newFace.v3 = numTotalVerts - coordIndex - 1;
//if (this.calcVertexNormals)
//{
// newFace.n1 = newFace.v1;
// newFace.n2 = newFace.v2;
// newFace.n3 = newFace.v3;
//}
this.faces.Add(newFace);
}
}
@@ -603,6 +605,12 @@ namespace PrimMesher
newFace.v1 = numTotalVerts - i - 1;
newFace.v2 = j;
newFace.v3 = j + 1;
//if (this.calcVertexNormals)
//{
// newFace.n1 = newFace.v1;
// newFace.n2 = newFace.v2;
// newFace.n3 = newFace.v3;
//}
this.faces.Add(newFace);
j += 1;
@@ -611,6 +619,12 @@ namespace PrimMesher
newFace.v1 = j;
newFace.v2 = numTotalVerts - i - 2;
newFace.v3 = numTotalVerts - i - 1;
//if (this.calcVertexNormals)
//{
// newFace.n1 = newFace.v1;
// newFace.n2 = newFace.v2;
// newFace.n3 = newFace.v3;
//}
this.faces.Add(newFace);
}
@@ -628,6 +642,12 @@ namespace PrimMesher
newFace.v1 = i;
newFace.v2 = numTotalVerts - j - 2;
newFace.v3 = numTotalVerts - j - 1;
//if (this.calcVertexNormals)
//{
// newFace.n1 = newFace.v1;
// newFace.n2 = newFace.v2;
// newFace.n3 = newFace.v3;
//}
this.faces.Add(newFace);
j += 1;
@@ -636,6 +656,12 @@ namespace PrimMesher
newFace.v1 = numTotalVerts - j - 1;
newFace.v2 = i;
newFace.v3 = i + 1;
//if (this.calcVertexNormals)
//{
// newFace.n1 = newFace.v1;
// newFace.n2 = newFace.v2;
// newFace.n3 = newFace.v3;
//}
this.faces.Add(newFace);
}
@@ -644,6 +670,11 @@ namespace PrimMesher
}
this.coords.AddRange(hollowCoords);
if (this.calcVertexNormals)
this.edgeNormals.AddRange(hollowNormals);
hollowCoords = null;
hollowNormals = null;
}
if (simpleFace && createFaces)
@@ -671,7 +702,7 @@ namespace PrimMesher
clone.coords.AddRange(this.coords);
if (needFaces)
clone.faces.AddRange(this.faces);
clone.normals.AddRange(this.normals);
clone.edgeNormals.AddRange(this.edgeNormals);
return clone;
}
@@ -714,16 +745,16 @@ namespace PrimMesher
this.coords[i] = c;
}
int numNormals = this.normals.Count;
int numNormals = this.edgeNormals.Count;
for (i = 0; i < numNormals; i++)
{
c = this.normals[i];
c = this.edgeNormals[i];
Coord n = new Coord(c.X, c.Y, c.Z) * q;
c.X = n.X;
c.Y = n.Y;
c.Z = n.Z;
this.normals[i] = c;
this.edgeNormals[i] = c;
}
}
@@ -763,12 +794,12 @@ namespace PrimMesher
if (this.calcVertexNormals)
{
int normalCount = this.normals.Count;
int normalCount = this.edgeNormals.Count;
if (normalCount > 0)
{
Coord n = this.normals[normalCount - 1];
n.Z *= 1.0f;
this.normals[normalCount - 1] = n;
Coord n = this.edgeNormals[normalCount - 1];
n.Z = -n.Z;
this.edgeNormals[normalCount - 1] = n;
}
}
}
@@ -858,6 +889,9 @@ namespace PrimMesher
public int stepsPerRevolution = 24;
public bool calcVertexNormals = false;
private bool normalsProcessed = false;
private List<Coord> edgeNormals;
public string ParamsToDisplayString()
{
@@ -922,10 +956,16 @@ namespace PrimMesher
this.coords = new List<Coord>();
this.faces = new List<Face>();
if (this.calcVertexNormals)
this.normals = new List<Coord>();
int step = 0;
int steps = 1;
float length = this.pathCutEnd - this.pathCutBegin;
normalsProcessed = false;
if (this.calcVertexNormals)
this.edgeNormals = new List<Coord>();
#if VIEWER
if (this.sides == 3)
@@ -1026,6 +1066,12 @@ namespace PrimMesher
this.coords.AddRange(newLayer.coords);
if (this.calcVertexNormals)
{
newLayer.AddValue2FaceNormalIndices(this.normals.Count);
this.normals.AddRange(newLayer.edgeNormals);
}
if (percentOfPath <= this.pathCutBegin || percentOfPath >= this.pathCutEnd)
this.faces.AddRange(newLayer.faces);
@@ -1047,10 +1093,21 @@ namespace PrimMesher
newFace.v1 = i;
newFace.v2 = i - numVerts;
newFace.v3 = i - numVerts + 1;
if (this.calcVertexNormals)
{
newFace.n1 = newFace.v1;
newFace.n2 = newFace.v2;
newFace.n3 = newFace.v3;
}
this.faces.Add(newFace);
newFace.v2 = i - numVerts + 1;
newFace.v3 = i + 1;
if (this.calcVertexNormals)
{
newFace.n2 = newFace.v2;
newFace.n3 = newFace.v3;
}
this.faces.Add(newFace);
}
@@ -1059,11 +1116,25 @@ namespace PrimMesher
newFace.v1 = coordsLen - 1;
newFace.v2 = coordsLen - numVerts;
newFace.v3 = coordsLen;
if (this.calcVertexNormals)
{
Coord n1 = SurfaceNormal(newFace);
this.normals.Add(n1);
newFace.n1 = newFace.n2 = newFace.n3 = this.normals.Count - 1;
}
this.faces.Add(newFace);
newFace.v1 = coordsLen + numVerts - 1;
newFace.v2 = coordsLen - 1;
newFace.v3 = coordsLen;
if (this.calcVertexNormals)
{
Coord n1 = SurfaceNormal(newFace);
this.normals.Add(n1);
newFace.n1 = newFace.n2 = newFace.n3 = this.normals.Count - 1;
}
this.faces.Add(newFace);
}
@@ -1084,8 +1155,8 @@ namespace PrimMesher
else done = true;
}
if (calcVertexNormals && sides < 5 && twistBegin == 0.0f && twistEnd == 0.0f)
this.CalcNormals();
//if (calcVertexNormals && sides < 5 && twistBegin == 0.0f && twistEnd == 0.0f)
// this.CalcNormals();
}
public void ExtrudeCircular()
@@ -1093,9 +1164,14 @@ namespace PrimMesher
this.coords = new List<Coord>();
this.faces = new List<Face>();
if (this.calcVertexNormals)
this.normals = new List<Coord>();
int step = 0;
int steps = 24;
normalsProcessed = false;
float twistBegin = this.twistBegin / 360.0f * twoPi;
float twistEnd = this.twistEnd / 360.0f * twoPi;
float twistTotal = twistEnd - twistBegin;
@@ -1248,6 +1324,12 @@ namespace PrimMesher
this.coords.AddRange(newLayer.coords);
if (this.calcVertexNormals)
{
newLayer.AddValue2FaceNormalIndices(this.normals.Count);
this.normals.AddRange(newLayer.edgeNormals);
}
if (isEndLayer)
this.faces.AddRange(newLayer.faces);
@@ -1305,15 +1387,8 @@ namespace PrimMesher
}
}
public Coord SurfaceNormal(int faceIndex)
private Coord SurfaceNormal(Face face)
{
int numFaces = faces.Count;
if (faceIndex < 0 || faceIndex >= faces.Count)
throw new Exception("faceIndex out of range");
//return new Coord(0.0f, 0.0f, 0.0f);
Face face = faces[faceIndex];
Coord c1 = coords[face.v1];
Coord c2 = coords[face.v2];
Coord c3 = coords[face.v3];
@@ -1328,10 +1403,28 @@ namespace PrimMesher
return normal;
}
public void CalcNormals()
public Coord SurfaceNormal(int faceIndex)
{
int numFaces = faces.Count;
this.normals = new List<Coord>();
if (faceIndex < 0 || faceIndex >= faces.Count)
throw new Exception("faceIndex out of range");
//return new Coord(0.0f, 0.0f, 0.0f);
return SurfaceNormal(faces[faceIndex]);
}
public void CalcNormals()
{
if (normalsProcessed)
return;
normalsProcessed = true;
int numFaces = faces.Count;
if (!this.calcVertexNormals)
this.normals = new List<Coord>();
for (int i = 0; i < numFaces; i++)
{