Add more vertex normals and UV coordinates. Sync with primmesher.dll forge project.

0.6.0-stable
Dahlia Trimble 2008-11-05 10:22:41 +00:00
parent d664192dfe
commit 5fffc04ae6
1 changed files with 125 additions and 51 deletions

View File

@ -121,6 +121,15 @@ namespace PrimMesher
return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z); return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z);
} }
public Coord Invert()
{
this.X = -this.X;
this.Y = -this.Y;
this.Z = -this.Z;
return this;
}
public Coord Normalize() public Coord Normalize()
{ {
const float MAG_THRESHOLD = 0.0000001f; const float MAG_THRESHOLD = 0.0000001f;
@ -369,6 +378,14 @@ namespace PrimMesher
new Angle(1.0f, 1.0f, 0.0f) new Angle(1.0f, 1.0f, 0.0f)
}; };
private Coord[] normals3 =
{
new Coord(0.25f, 0.4330127019f, 0.0f).Normalize(),
new Coord(-0.5f, 0.0f, 0.0f).Normalize(),
new Coord(0.25f, -0.4330127019f, 0.0f).Normalize(),
new Coord(0.25f, 0.4330127019f, 0.0f).Normalize()
};
private Angle[] angles4 = private Angle[] angles4 =
{ {
new Angle(0.0f, 1.0f, 0.0f), new Angle(0.0f, 1.0f, 0.0f),
@ -378,6 +395,15 @@ namespace PrimMesher
new Angle(1.0f, 1.0f, 0.0f) new Angle(1.0f, 1.0f, 0.0f)
}; };
private Coord[] normals4 =
{
new Coord(0.5f, 0.5f, 0.0f).Normalize(),
new Coord(-0.5f, 0.5f, 0.0f).Normalize(),
new Coord(-0.5f, -0.5f, 0.0f).Normalize(),
new Coord(0.5f, -0.5f, 0.0f).Normalize(),
new Coord(0.5f, 0.5f, 0.0f).Normalize()
};
private Angle[] angles24 = private Angle[] angles24 =
{ {
new Angle(0.0f, 1.0f, 0.0f), new Angle(0.0f, 1.0f, 0.0f),
@ -427,10 +453,13 @@ namespace PrimMesher
} }
internal List<Angle> angles; internal List<Angle> angles;
internal List<Coord> normals;
internal void makeAngles(int sides, float startAngle, float stopAngle) internal void makeAngles(int sides, float startAngle, float stopAngle)
{ {
angles = new List<Angle>(); angles = new List<Angle>();
normals = new List<Coord>();
double twoPi = System.Math.PI * 2.0; double twoPi = System.Math.PI * 2.0;
float twoPiInv = 1.0f / (float)twoPi; float twoPiInv = 1.0f / (float)twoPi;
@ -459,7 +488,13 @@ namespace PrimMesher
endAngleIndex++; endAngleIndex++;
for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++)
{
angles.Add(sourceAngles[angleIndex]); angles.Add(sourceAngles[angleIndex]);
if (sides == 3)
normals.Add(normals3[angleIndex]);
else if (sides == 4)
normals.Add(normals4[angleIndex]);
}
if (startAngle > 0.0f) if (startAngle > 0.0f)
angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); angles[0] = interpolatePoints(startAngle, angles[0], angles[1]);
@ -639,8 +674,12 @@ namespace PrimMesher
hollowCoords.Add(newVert); hollowCoords.Add(newVert);
if (this.calcVertexNormals) if (this.calcVertexNormals)
{ {
hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); if (sides < 5)
hollowUs.Add(angle.angle); hollowNormals.Add(hollowAngles.normals[i].Invert());
else
hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
hollowUs.Add(angle.angle * hollow);
} }
} }
} }
@ -650,6 +689,7 @@ namespace PrimMesher
for (int i = 0; i < numAngles; i++) for (int i = 0; i < numAngles; i++)
{ {
int iNext = i == numAngles ? i + 1 : 0;
angle = angles.angles[i]; angle = angles.angles[i];
newVert.X = angle.X * xScale; newVert.X = angle.X * xScale;
newVert.Y = angle.Y * yScale; newVert.Y = angle.Y * yScale;
@ -657,14 +697,18 @@ namespace PrimMesher
this.coords.Add(newVert); this.coords.Add(newVert);
if (this.calcVertexNormals) if (this.calcVertexNormals)
{ {
this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f));
if (sides < 5) if (sides < 5)
{ {
this.vertexNormals.Add(angles.normals[i]);
float u = angle.angle; float u = angle.angle;
this.us.Add(u); this.us.Add(u);
} }
else else
{
this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f));
this.us.Add(angle.angle); this.us.Add(angle.angle);
}
} }
if (hollow > 0.0f) if (hollow > 0.0f)
@ -677,8 +721,15 @@ namespace PrimMesher
hollowCoords.Add(newVert); hollowCoords.Add(newVert);
if (this.calcVertexNormals) if (this.calcVertexNormals)
{ {
hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); if (sides < 5)
hollowUs.Add(angle.angle); {
hollowNormals.Add(angles.normals[i].Invert());
}
else
hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
hollowUs.Add(angle.angle * hollow);
} }
} }
} }
@ -805,20 +856,22 @@ namespace PrimMesher
{ {
if (hasHollow) if (hasHollow)
{ {
this.cutNormal1.X = -this.vertexNormals[0].Y - this.vertexNormals[this.vertexNormals.Count - 1].Y;
this.cutNormal1.Y = this.vertexNormals[0].X - this.vertexNormals[this.vertexNormals.Count - 1].X;
int lastOuterVertIndex = this.numOuterVerts - 1; int lastOuterVertIndex = this.numOuterVerts - 1;
this.cutNormal2.X = -this.vertexNormals[lastOuterVertIndex].Y - this.vertexNormals[lastOuterVertIndex + 1].Y;
this.cutNormal2.Y = this.vertexNormals[lastOuterVertIndex].X - this.vertexNormals[lastOuterVertIndex + 1].X; this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y;
this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X);
this.cutNormal2.X = this.coords[lastOuterVertIndex + 1].Y - this.coords[lastOuterVertIndex].Y;
this.cutNormal2.Y = -(this.coords[lastOuterVertIndex + 1].X - this.coords[lastOuterVertIndex].X);
} }
else else
{ {
this.cutNormal1.X = this.vertexNormals[1].Y; this.cutNormal1.X = this.vertexNormals[1].Y;
this.cutNormal1.Y = -this.vertexNormals[1].X; this.cutNormal1.Y = -this.vertexNormals[1].X;
this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 1].Y; this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 2].Y;
this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 1].X; this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 2].X;
} }
this.cutNormal1.Normalize(); this.cutNormal1.Normalize();
@ -837,7 +890,7 @@ namespace PrimMesher
{ {
this.faceUVs = new List<UVCoord>(); this.faceUVs = new List<UVCoord>();
foreach (Coord c in this.coords) foreach (Coord c in this.coords)
this.faceUVs.Add(new UVCoord(0.5f + c.X, 0.5f - c.Y)); this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y)));
} }
public Profile Clone() public Profile Clone()
@ -963,7 +1016,7 @@ namespace PrimMesher
for (i = 0; i < numfaceUVs; i++) for (i = 0; i < numfaceUVs; i++)
{ {
UVCoord uv = this.faceUVs[i]; UVCoord uv = this.faceUVs[i];
uv.U = 1.0f - uv.U; uv.V = 1.0f - uv.V;
this.faceUVs[i] = uv; this.faceUVs[i] = uv;
} }
} }
@ -1250,8 +1303,7 @@ namespace PrimMesher
if (this.viewerMode) if (this.viewerMode)
{ {
Coord faceNormal = newLayer.faceNormal; Coord faceNormal = newLayer.faceNormal;
ViewerFace newViewerFace = new ViewerFace(); ViewerFace newViewerFace = new ViewerFace(0);
newViewerFace.primFaceNumber = 0;
foreach (Face face in newLayer.faces) foreach (Face face in newLayer.faces)
{ {
newViewerFace.v1 = newLayer.coords[face.v1]; newViewerFace.v1 = newLayer.coords[face.v1];
@ -1325,28 +1377,29 @@ namespace PrimMesher
primFaceNum = 2; primFaceNum = 2;
ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); ViewerFace newViewerFace1 = new ViewerFace(primFaceNum);
ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); ViewerFace newViewerFace2 = new ViewerFace(primFaceNum);
float u1 = newLayer.us[whichVert]; float u1 = newLayer.us[whichVert];
float u2 = 1.0f; float u2 = 1.0f;
if (whichVert < newLayer.us.Count - 1) if (whichVert < newLayer.us.Count - 1)
u2 = newLayer.us[whichVert + 1]; u2 = newLayer.us[whichVert + 1];
int whichOuterVert = (hasProfileCut && hasHollow) ? whichVert - 1 : whichVert;
if (sides < 5 && whichOuterVert < sides)
{
u1 *= sides;
u2 *= sides;
u1 -= whichOuterVert;
u2 -= whichOuterVert;
if (u2 < 0.1f)
u2 = 1.0f;
newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
}
if (whichVert == cut1Vert || whichVert == cut2Vert) if (whichVert == cut1Vert || whichVert == cut2Vert)
{ {
u1 = 0.0f; u1 = 0.0f;
u2 = 1.0f; u2 = 1.0f;
} }
else if (sides < 5)
{ // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
// to reflect the entire texture width
u1 *= sides;
u2 *= sides;
u2 -= (int)u1;
u1 -= (int)u1;
if (u2 < 0.1f)
u2 = 1.0f;
newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
}
newViewerFace1.uv1.U = u1; newViewerFace1.uv1.U = u1;
newViewerFace1.uv2.U = u1; newViewerFace1.uv2.U = u1;
@ -1375,27 +1428,24 @@ namespace PrimMesher
// profile cut faces // profile cut faces
if (whichVert == cut1Vert) if (whichVert == cut1Vert)
{ {
newViewerFace1.n1 = newLayer.cutNormal1;
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
newViewerFace1.n2 = newViewerFace1.n1 = lastCutNormal1; newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
newViewerFace1.n3 = newLayer.cutNormal1;
newViewerFace2.n3 = newViewerFace2.n1 = newLayer.cutNormal1;
newViewerFace2.n2 = lastCutNormal1; newViewerFace2.n2 = lastCutNormal1;
} }
else if (whichVert == cut2Vert) else if (whichVert == cut2Vert)
{ {
newViewerFace1.n1 = newLayer.cutNormal2;
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
newViewerFace1.n2 = newViewerFace1.n1 = lastCutNormal2; newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
newViewerFace1.n3 = newLayer.cutNormal2;
newViewerFace2.n3 = newViewerFace2.n1 = newLayer.cutNormal2;
newViewerFace2.n2 = lastCutNormal2; newViewerFace2.n2 = lastCutNormal2;
} }
else // outer and hollow faces else // outer and hollow faces
{ {
//if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts))
if (sides < 5)
{ {
newViewerFace1.CalcSurfaceNormal(); newViewerFace1.CalcSurfaceNormal();
newViewerFace2.CalcSurfaceNormal(); newViewerFace2.CalcSurfaceNormal();
@ -1727,6 +1777,18 @@ namespace PrimMesher
u1 = 0.0f; u1 = 0.0f;
u2 = 1.0f; u2 = 1.0f;
} }
else if (sides < 5)
{ // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
// to reflect the entire texture width
u1 *= sides;
u2 *= sides;
u2 -= (int)u1;
u1 -= (int)u1;
if (u2 < 0.1f)
u2 = 1.0f;
newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
}
newViewerFace1.uv1.U = u1; newViewerFace1.uv1.U = u1;
newViewerFace1.uv2.U = u1; newViewerFace1.uv2.U = u1;
@ -1752,32 +1814,44 @@ namespace PrimMesher
newViewerFace2.v2 = this.coords[iNext - numVerts]; newViewerFace2.v2 = this.coords[iNext - numVerts];
newViewerFace2.v3 = this.coords[iNext]; newViewerFace2.v3 = this.coords[iNext];
// profile cut faces
if (whichVert == cut1Vert) if (whichVert == cut1Vert)
{ {
newViewerFace1.n1 = newLayer.cutNormal1;
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
newViewerFace1.n2 = newViewerFace1.n1 = lastCutNormal1; newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
newViewerFace1.n3 = newLayer.cutNormal1;
newViewerFace2.n3 = newViewerFace2.n1 = newLayer.cutNormal1;
newViewerFace2.n2 = lastCutNormal1; newViewerFace2.n2 = lastCutNormal1;
} }
else if (whichVert == cut2Vert) else if (whichVert == cut2Vert)
{ {
newViewerFace1.n1 = newLayer.cutNormal2;
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
newViewerFace1.n2 = newViewerFace1.n1 = lastCutNormal2; newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
newViewerFace1.n3 = newLayer.cutNormal2;
newViewerFace2.n3 = newViewerFace2.n1 = newLayer.cutNormal2;
newViewerFace2.n2 = lastCutNormal2; newViewerFace2.n2 = lastCutNormal2;
} }
else // periphery faces else // periphery faces
{ {
//if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) if (sides < 5 && whichVert < newLayer.numOuterVerts)
if (sides < 5)
{ {
newViewerFace1.CalcSurfaceNormal(); newViewerFace1.n1 = this.normals[i];
newViewerFace2.CalcSurfaceNormal(); newViewerFace1.n2 = this.normals[i - numVerts];
newViewerFace1.n3 = this.normals[i - numVerts];
newViewerFace2.n1 = this.normals[i];
newViewerFace2.n2 = this.normals[i - numVerts];
newViewerFace2.n3 = this.normals[i];
}
else if (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)
{
newViewerFace1.n1 = this.normals[iNext];
newViewerFace1.n2 = this.normals[iNext - numVerts];
newViewerFace1.n3 = this.normals[iNext - numVerts];
newViewerFace2.n1 = this.normals[iNext];
newViewerFace2.n2 = this.normals[iNext - numVerts];
newViewerFace2.n3 = this.normals[iNext];
} }
else else
{ {