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.

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

View File

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