From 20670ff0c88f7744bb1e7b1395837f537c83ea86 Mon Sep 17 00:00:00 2001 From: Dahlia Trimble Date: Sun, 4 Jan 2009 19:09:31 +0000 Subject: sync with primmesher r26 on forge --- OpenSim/Region/Physics/Meshing/SculptMesh.cs | 198 ++++++++++++++++++++++----- 1 file changed, 162 insertions(+), 36 deletions(-) (limited to 'OpenSim/Region/Physics/Meshing') diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs index 9a5a776..9da74e6 100644 --- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs +++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs @@ -84,6 +84,128 @@ namespace PrimMesher return sculptMesh; } + /// + /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications + /// Construct a sculpt mesh from a 2D array of floats + /// + /// + /// + /// + /// + /// + /// + 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(); + faces = new List(); + normals = new List(); + uvs = new List(); + + viewerFaces = new List(); + + 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) { coords = new List(); @@ -142,6 +264,7 @@ namespace PrimMesher bitmap.SetPixel(imageX, 0, newC1); bitmap.SetPixel(imageX, lastRow, newC2); } + } @@ -222,50 +345,53 @@ namespace PrimMesher bitmap.Dispose(); if (viewerMode) - { // 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; - } + calcVertexNormals(sculptType, width, height); + } - int numCoords = this.coords.Count; - for (int i = 0; i < numCoords; i++) - this.coords[i].Normalize(); + 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; + } - if (sculptType != SculptType.plane) - { // blend the vertex normals at the cylinder seam - pixelsAcross = width + 1; - for (imageY = 0; imageY < height; imageY++) - { - int rowOffset = imageY * pixelsAcross; + int numCoords = this.coords.Count; + for (int i = 0; i < numCoords; i++) + this.coords[i].Normalize(); - this.normals[rowOffset] = this.normals[rowOffset + width - 1] = (this.normals[rowOffset] + this.normals[rowOffset + width - 1]).Normalize(); - } + if (sculptType != SculptType.plane) + { // blend the vertex normals at the cylinder seam + int pixelsAcross = xSize + 1; + for (int y = 0; y < ySize; y++) + { + int rowOffset = y * pixelsAcross; + + this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize(); } + } - foreach (Face face in this.faces) - { - ViewerFace vf = new ViewerFace(0); - vf.v1 = this.coords[face.v1]; - vf.v2 = this.coords[face.v2]; - vf.v3 = this.coords[face.v3]; + foreach (Face face in this.faces) + { + 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.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]; + vf.uv1 = this.uvs[face.uv1]; + vf.uv2 = this.uvs[face.uv2]; + vf.uv3 = this.uvs[face.uv3]; - this.viewerFaces.Add(vf); - } + this.viewerFaces.Add(vf); } } -- cgit v1.1