29 #define SYSTEM_DRAWING
32 using System.Collections.Generic;
38 using System.Drawing.Imaging;
51 public List<UVCoord>
uvs;
59 Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName);
66 public SculptMesh(
string fileName,
int sculptType,
int lod,
int viewerMode,
int mirror,
int invert)
68 Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName);
69 _SculptMesh(bitmap, (
SculptType)sculptType, lod, viewerMode != 0, mirror != 0, invert != 0);
84 public SculptMesh(
float[,] zMap,
float xBegin,
float xEnd,
float yBegin,
float yEnd,
bool viewerMode)
89 int numYElements = zMap.GetLength(0);
90 int numXElements = zMap.GetLength(1);
94 xStep = (xEnd - xBegin) / (
float)(numXElements - 1);
95 yStep = (yEnd - yBegin) / (
float)(numYElements - 1);
97 uStep = 1.0f / (numXElements - 1);
98 vStep = 1.0f / (numYElements - 1);
100 catch (DivideByZeroException)
105 coords =
new List<Coord>();
106 faces =
new List<Face>();
108 uvs =
new List<UVCoord>();
115 int xStart = 0, yStart = 0;
117 for (y = yStart; y < numYElements; y++)
119 int rowOffset = y * numXElements;
121 for (x = xStart; x < numXElements; x++)
134 p2 = p4 - numXElements;
135 p1 = p3 - numXElements;
137 Coord c =
new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]);
141 this.normals.Add(
new Coord());
142 this.uvs.Add(
new UVCoord(uStep * x, 1.0f - vStep * y));
151 f1 =
new Face(p1, p4, p3, p1, p4, p3);
156 f2 =
new Face(p1, p2, p4, p1, p2, p4);
163 f1 =
new Face(p1, p4, p3);
164 f2 =
new Face(p1, p2, p4);
174 calcVertexNormals(
SculptType.plane, numXElements, numYElements);
180 _SculptMesh(sculptBitmap, sculptType, lod, viewerMode,
false,
false);
183 public SculptMesh(Bitmap sculptBitmap,
SculptType sculptType,
int lod,
bool viewerMode,
bool mirror,
bool invert)
185 _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert);
191 _SculptMesh(rows, sculptType, viewerMode, mirror, invert);
195 private List<List<Coord>> bitmap2Coords(Bitmap bitmap,
int scale,
bool mirror)
207 int numRows = bitmap.Height / scale;
208 int numCols = bitmap.Width / scale;
209 List<List<Coord>> rows =
new List<List<Coord>>(numRows);
211 float pixScale = 1.0f / (scale * scale);
214 int imageX, imageY = 0;
218 for (rowNdx = 0; rowNdx < numRows; rowNdx++)
220 List<Coord> row =
new List<Coord>(numCols);
221 for (colNdx = 0; colNdx < numCols; colNdx++)
223 imageX = colNdx * scale;
224 int imageYStart = rowNdx * scale;
225 int imageYEnd = imageYStart + scale;
226 int imageXEnd = imageX + scale;
230 for (; imageX < imageXEnd; imageX++)
232 for (imageY = imageYStart; imageY < imageYEnd; imageY++)
234 Color c = bitmap.GetPixel(imageX, imageY);
237 bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B));
238 c = bitmap.GetPixel(imageX, imageY);
246 row.Add(
new Coord(-(rSum * pixScale - 0.5f), gSum * pixScale - 0.5f, bSum * pixScale - 0.5f));
248 row.Add(
new Coord(rSum * pixScale - 0.5f, gSum * pixScale - 0.5f, bSum * pixScale - 0.5f));
256 private List<List<Coord>> bitmap2CoordsSampled(Bitmap bitmap,
int scale,
bool mirror)
258 int numRows = bitmap.Height / scale;
259 int numCols = bitmap.Width / scale;
260 List<List<Coord>> rows =
new List<List<Coord>>(numRows);
262 float pixScale = 1.0f / 256.0f;
264 int imageX, imageY = 0;
268 for (rowNdx = 0; rowNdx <= numRows; rowNdx++)
270 List<Coord> row =
new List<Coord>(numCols);
271 imageY = rowNdx * scale;
272 if (rowNdx == numRows) imageY--;
273 for (colNdx = 0; colNdx <= numCols; colNdx++)
275 imageX = colNdx * scale;
276 if (colNdx == numCols) imageX--;
278 Color c = bitmap.GetPixel(imageX, imageY);
281 bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B));
282 c = bitmap.GetPixel(imageX, imageY);
286 row.Add(
new Coord(-(c.R * pixScale - 0.5f), c.G * pixScale - 0.5f, c.B * pixScale - 0.5f));
288 row.Add(
new Coord(c.R * pixScale - 0.5f, c.G * pixScale - 0.5f, c.B * pixScale - 0.5f));
297 void _SculptMesh(Bitmap sculptBitmap,
SculptType sculptType,
int lod,
bool viewerMode,
bool mirror,
bool invert)
299 _SculptMesh(
new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert);
303 void _SculptMesh(List<List<Coord>> rows,
SculptType sculptType,
bool viewerMode,
bool mirror,
bool invert)
305 coords =
new List<Coord>();
306 faces =
new List<Face>();
308 uvs =
new List<UVCoord>();
310 sculptType = (
SculptType)(((
int)sculptType) & 0x07);
317 int width = rows[0].Count;
325 if (rows.Count % 2 == 0)
327 for (
int rowNdx = 0; rowNdx < rows.Count; rowNdx++)
328 rows[rowNdx].
Add(rows[rowNdx][0]);
332 int lastIndex = rows[0].Count - 1;
334 for (
int i = 0; i < rows.Count; i++)
335 rows[i][0] = rows[i][lastIndex];
339 Coord topPole = rows[0][width / 2];
340 Coord bottomPole = rows[rows.Count - 1][width / 2];
344 if (rows.Count % 2 == 0)
346 int count = rows[0].Count;
347 List<Coord> topPoleRow =
new List<Coord>(count);
348 List<Coord> bottomPoleRow =
new List<Coord>(count);
350 for (
int i = 0; i < count; i++)
352 topPoleRow.Add(topPole);
353 bottomPoleRow.Add(bottomPole);
355 rows.Insert(0, topPoleRow);
356 rows.Add(bottomPoleRow);
360 int count = rows[0].Count;
362 List<Coord> topPoleRow = rows[0];
363 List<Coord> bottomPoleRow = rows[rows.Count - 1];
365 for (
int i = 0; i < count; i++)
367 topPoleRow[i] = topPole;
368 bottomPoleRow[i] = bottomPole;
376 int coordsDown = rows.Count;
377 int coordsAcross = rows[0].Count;
380 float widthUnit = 1.0f / (coordsAcross - 1);
381 float heightUnit = 1.0f / (coordsDown - 1);
383 for (imageY = 0; imageY < coordsDown; imageY++)
385 int rowOffset = imageY * coordsAcross;
387 for (imageX = 0; imageX < coordsAcross; imageX++)
397 p4 = rowOffset + imageX;
400 p2 = p4 - coordsAcross;
401 p1 = p3 - coordsAcross;
403 this.coords.Add(rows[imageY][imageX]);
406 this.normals.Add(
new Coord());
407 this.uvs.Add(
new UVCoord(widthUnit * imageX, heightUnit * imageY));
410 if (imageY > 0 && imageX > 0)
418 f1 =
new Face(p1, p4, p3, p1, p4, p3);
423 f2 =
new Face(p1, p2, p4, p1, p2, p4);
430 f1 =
new Face(p1, p3, p4, p1, p3, p4);
435 f2 =
new Face(p1, p4, p2, p1, p4, p2);
445 f1 =
new Face(p1, p4, p3);
446 f2 =
new Face(p1, p2, p4);
450 f1 =
new Face(p1, p3, p4);
451 f2 =
new Face(p1, p4, p2);
462 calcVertexNormals(sculptType, coordsAcross, coordsDown);
476 coords =
new List<Coord>(sm.coords);
477 faces =
new List<Face>(sm.faces);
478 viewerFaces =
new List<ViewerFace>(sm.viewerFaces);
479 normals =
new List<Coord>(sm.normals);
480 uvs =
new List<UVCoord>(sm.uvs);
483 private void calcVertexNormals(
SculptType sculptType,
int xSize,
int ySize)
486 int numFaces = this.faces.Count;
487 for (
int i = 0; i < numFaces; i++)
489 Face face = this.faces[i];
490 Coord surfaceNormal = face.SurfaceNormal(this.coords);
491 this.normals[face.n1] += surfaceNormal;
492 this.normals[face.n2] += surfaceNormal;
493 this.normals[face.n3] += surfaceNormal;
496 int numNormals = this.normals.Count;
497 for (
int i = 0; i < numNormals; i++)
498 this.normals[i] = this.normals[i].Normalize();
502 for (
int y = 0; y < ySize; y++)
504 int rowOffset = y * xSize;
506 this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize();
510 foreach (Face face
in this.faces)
512 ViewerFace vf =
new ViewerFace(0);
513 vf.v1 = this.coords[face.v1];
514 vf.v2 = this.coords[face.v2];
515 vf.v3 = this.coords[face.v3];
517 vf.coordIndex1 = face.v1;
518 vf.coordIndex2 = face.v2;
519 vf.coordIndex3 = face.v3;
521 vf.n1 = this.normals[face.n1];
522 vf.n2 = this.normals[face.n2];
523 vf.n3 = this.normals[face.n3];
525 vf.uv1 = this.uvs[face.uv1];
526 vf.uv2 = this.uvs[face.uv2];
527 vf.uv3 = this.uvs[face.uv3];
529 this.viewerFaces.Add(vf);
539 public void AddPos(
float x,
float y,
float z)
542 int numVerts = this.coords.Count;
545 for (i = 0; i < numVerts; i++)
547 vert = this.coords[i];
551 this.coords[i] = vert;
556 int numViewerFaces = this.viewerFaces.Count;
558 for (i = 0; i < numViewerFaces; i++)
562 this.viewerFaces[i] = v;
574 int numVerts = this.coords.Count;
576 for (i = 0; i < numVerts; i++)
579 int numNormals = this.normals.Count;
580 for (i = 0; i < numNormals; i++)
581 this.normals[i] *= q;
585 int numViewerFaces = this.viewerFaces.Count;
587 for (i = 0; i < numViewerFaces; i++)
598 this.viewerFaces[i] = v;
603 public void Scale(
float x,
float y,
float z)
606 int numVerts = this.coords.Count;
609 for (i = 0; i < numVerts; i++)
614 int numViewerFaces = this.viewerFaces.Count;
615 for (i = 0; i < numViewerFaces; i++)
621 this.viewerFaces[i] = v;
626 public void DumpRaw(String path, String name, String title)
630 String fileName = name +
"_" + title +
".raw";
631 String completePath = System.IO.Path.Combine(path, fileName);
632 StreamWriter sw =
new StreamWriter(completePath);
634 for (
int i = 0; i < this.faces.Count; i++)
636 string s = this.coords[this.faces[i].v1].ToString();
637 s +=
" " + this.coords[this.faces[i].v2].ToString();
638 s +=
" " + this.coords[this.faces[i].v3].ToString();
void DumpRaw(String path, String name, String title)
List< ViewerFace > viewerFaces
SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode)
SculptMesh(List< List< Coord >> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert)
SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd, bool viewerMode)
** Experimental ** May disappear from future versions ** not recommeneded for use in applications Con...
void AddRot(Quat q)
Rotates the mesh
OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType SculptType
SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
void AddPos(float x, float y, float z)
Adds a value to each XYZ vertex coordinate in the mesh
SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert)
void Scale(float x, float y, float z)
SculptMesh(SculptMesh sm)
SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode)
SculptMesh Copy()
Duplicates a SculptMesh object. All object properties are copied by value, including lists...