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')

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;
         }
 
+        /// <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)
         {
             coords = new List<Coord>();
@@ -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