sync with primmesher r26 on forge

0.6.2-post-fixes
Dahlia Trimble 2009-01-04 19:09:31 +00:00
parent f0864b5154
commit 20670ff0c8
1 changed files with 164 additions and 38 deletions

View File

@ -84,6 +84,128 @@ namespace PrimMesher
return sculptMesh; return sculptMesh;
} }
/// <summary>
/// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications
/// Construct a sculpt mesh from a 2D array of floats
/// </summary>
/// <param name="zMap"></param>
/// <param name="xBegin"></param>
/// <param name="xEnd"></param>
/// <param name="yBegin"></param>
/// <param name="yEnd"></param>
/// <param name="viewerMode"></param>
public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd, bool viewerMode)
{
float xStep, yStep;
float uStep, vStep;
int numYElements = zMap.GetLength(0);
int numXElements = zMap.GetLength(1);
try
{
xStep = (xEnd - xBegin) / (float)(numXElements - 1);
yStep = (yEnd - yBegin) / (float)(numYElements - 1);
uStep = 1.0f / (numXElements - 1);
vStep = 1.0f / (numYElements - 1);
}
catch (DivideByZeroException)
{
return;
}
coords = new List<Coord>();
faces = new List<Face>();
normals = new List<Coord>();
uvs = new List<UVCoord>();
viewerFaces = new List<ViewerFace>();
int p1, p2, p3, p4;
int x, y;
int xStart = 0, yStart = 0;
for (y = yStart; y < numYElements; y++)
{
int rowOffset = y * numXElements;
for (x = xStart; x < numXElements; x++)
{
/*
* p1-----p2
* | \ f2 |
* | \ |
* | f1 \|
* p3-----p4
*/
p4 = rowOffset + x;
p3 = p4 - 1;
p2 = p4 - numXElements;
p1 = p3 - numXElements;
Coord c = new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]);
this.coords.Add(c);
if (viewerMode)
{
this.normals.Add(new Coord());
this.uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y));
}
if (y > 0 && x > 0)
{
Face f1, f2;
//if (viewerMode)
//{
// f1 = new Face(p1, p3, p4, p1, p3, p4);
// f1.uv1 = p1;
// f1.uv2 = p3;
// f1.uv3 = p4;
// f2 = new Face(p1, p4, p2, p1, p4, p2);
// f2.uv1 = p1;
// f2.uv2 = p4;
// f2.uv3 = p2;
//}
//else
//{
// f1 = new Face(p1, p3, p4);
// f2 = new Face(p1, p4, p2);
//}
if (viewerMode)
{
f1 = new Face(p1, p4, p3, p1, p4, p3);
f1.uv1 = p1;
f1.uv2 = p4;
f1.uv3 = p3;
f2 = new Face(p1, p2, p4, p1, p2, p4);
f2.uv1 = p1;
f2.uv2 = p2;
f2.uv3 = p4;
}
else
{
f1 = new Face(p1, p4, p3);
f2 = new Face(p1, p2, p4);
}
this.faces.Add(f1);
this.faces.Add(f2);
}
}
}
if (viewerMode)
calcVertexNormals(SculptType.plane, numXElements, numYElements);
}
public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode)
{ {
coords = new List<Coord>(); coords = new List<Coord>();
@ -142,6 +264,7 @@ namespace PrimMesher
bitmap.SetPixel(imageX, 0, newC1); bitmap.SetPixel(imageX, 0, newC1);
bitmap.SetPixel(imageX, lastRow, newC2); bitmap.SetPixel(imageX, lastRow, newC2);
} }
} }
@ -222,50 +345,53 @@ namespace PrimMesher
bitmap.Dispose(); bitmap.Dispose();
if (viewerMode) if (viewerMode)
{ // compute vertex normals by summing all the surface normals of all the triangles sharing calcVertexNormals(sculptType, width, height);
// each vertex and then normalizing }
int numFaces = this.faces.Count;
for (int i = 0; i < numFaces; i++) private void calcVertexNormals(SculptType sculptType, int xSize, int ySize)
{ // compute vertex normals by summing all the surface normals of all the triangles sharing
// each vertex and then normalizing
int numFaces = this.faces.Count;
for (int i = 0; i < numFaces; i++)
{
Face face = this.faces[i];
Coord surfaceNormal = face.SurfaceNormal(this.coords);
this.normals[face.v1] += surfaceNormal;
this.normals[face.v2] += surfaceNormal;
this.normals[face.v3] += surfaceNormal;
}
int numCoords = this.coords.Count;
for (int i = 0; i < numCoords; i++)
this.coords[i].Normalize();
if (sculptType != SculptType.plane)
{ // blend the vertex normals at the cylinder seam
int pixelsAcross = xSize + 1;
for (int y = 0; y < ySize; y++)
{ {
Face face = this.faces[i]; int rowOffset = y * pixelsAcross;
Coord surfaceNormal = face.SurfaceNormal(this.coords);
this.normals[face.v1] += surfaceNormal; this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize();
this.normals[face.v2] += surfaceNormal;
this.normals[face.v3] += surfaceNormal;
} }
}
int numCoords = this.coords.Count; foreach (Face face in this.faces)
for (int i = 0; i < numCoords; i++) {
this.coords[i].Normalize(); ViewerFace vf = new ViewerFace(0);
vf.v1 = this.coords[face.v1];
vf.v2 = this.coords[face.v2];
vf.v3 = this.coords[face.v3];
if (sculptType != SculptType.plane) vf.n1 = this.normals[face.n1];
{ // blend the vertex normals at the cylinder seam vf.n2 = this.normals[face.n2];
pixelsAcross = width + 1; vf.n3 = this.normals[face.n3];
for (imageY = 0; imageY < height; imageY++)
{
int rowOffset = imageY * pixelsAcross;
this.normals[rowOffset] = this.normals[rowOffset + width - 1] = (this.normals[rowOffset] + this.normals[rowOffset + width - 1]).Normalize(); vf.uv1 = this.uvs[face.uv1];
} vf.uv2 = this.uvs[face.uv2];
} vf.uv3 = this.uvs[face.uv3];
foreach (Face face in this.faces) this.viewerFaces.Add(vf);
{
ViewerFace vf = new ViewerFace(0);
vf.v1 = this.coords[face.v1];
vf.v2 = this.coords[face.v2];
vf.v3 = this.coords[face.v3];
vf.n1 = this.normals[face.n1];
vf.n2 = this.normals[face.n2];
vf.n3 = this.normals[face.n3];
vf.uv1 = this.uvs[face.uv1];
vf.uv2 = this.uvs[face.uv2];
vf.uv3 = this.uvs[face.uv3];
this.viewerFaces.Add(vf);
}
} }
} }