diff options
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/SculptMesh.cs')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/SculptMesh.cs | 152 |
1 files changed, 77 insertions, 75 deletions
diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs index ebc5be6..6aa8fe4 100644 --- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs +++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs | |||
@@ -53,50 +53,6 @@ namespace PrimMesher | |||
53 | public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; | 53 | public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; |
54 | 54 | ||
55 | #if SYSTEM_DRAWING | 55 | #if SYSTEM_DRAWING |
56 | private Bitmap ScaleImage(Bitmap srcImage, float scale, bool removeAlpha) | ||
57 | { | ||
58 | int sourceWidth = srcImage.Width; | ||
59 | int sourceHeight = srcImage.Height; | ||
60 | int sourceX = 0; | ||
61 | int sourceY = 0; | ||
62 | |||
63 | int destX = 0; | ||
64 | int destY = 0; | ||
65 | int destWidth = (int)(srcImage.Width * scale); | ||
66 | int destHeight = (int)(srcImage.Height * scale); | ||
67 | |||
68 | Bitmap scaledImage; | ||
69 | |||
70 | if (removeAlpha) | ||
71 | { | ||
72 | if (srcImage.PixelFormat == PixelFormat.Format32bppArgb) | ||
73 | for (int y = 0; y < srcImage.Height; y++) | ||
74 | for (int x = 0; x < srcImage.Width; x++) | ||
75 | { | ||
76 | Color c = srcImage.GetPixel(x, y); | ||
77 | srcImage.SetPixel(x, y, Color.FromArgb(255, c.R, c.G, c.B)); | ||
78 | } | ||
79 | |||
80 | scaledImage = new Bitmap(destWidth, destHeight, | ||
81 | PixelFormat.Format24bppRgb); | ||
82 | } | ||
83 | else | ||
84 | scaledImage = new Bitmap(srcImage, destWidth, destHeight); | ||
85 | |||
86 | scaledImage.SetResolution(96.0f, 96.0f); | ||
87 | |||
88 | Graphics grPhoto = Graphics.FromImage(scaledImage); | ||
89 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low; | ||
90 | |||
91 | grPhoto.DrawImage(srcImage, | ||
92 | new Rectangle(destX, destY, destWidth, destHeight), | ||
93 | new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), | ||
94 | GraphicsUnit.Pixel); | ||
95 | |||
96 | grPhoto.Dispose(); | ||
97 | return scaledImage; | ||
98 | } | ||
99 | |||
100 | 56 | ||
101 | public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) | 57 | public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) |
102 | { | 58 | { |
@@ -106,6 +62,7 @@ namespace PrimMesher | |||
106 | return sculptMesh; | 62 | return sculptMesh; |
107 | } | 63 | } |
108 | 64 | ||
65 | |||
109 | public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert) | 66 | public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert) |
110 | { | 67 | { |
111 | Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); | 68 | Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); |
@@ -296,36 +253,53 @@ namespace PrimMesher | |||
296 | return rows; | 253 | return rows; |
297 | } | 254 | } |
298 | 255 | ||
299 | 256 | private List<List<Coord>> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool mirror) | |
300 | void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) | ||
301 | { | 257 | { |
302 | coords = new List<Coord>(); | 258 | int numRows = bitmap.Height / scale; |
303 | faces = new List<Face>(); | 259 | int numCols = bitmap.Width / scale; |
304 | normals = new List<Coord>(); | 260 | List<List<Coord>> rows = new List<List<Coord>>(numRows); |
305 | uvs = new List<UVCoord>(); | ||
306 | 261 | ||
307 | sculptType = (SculptType)(((int)sculptType) & 0x07); | 262 | float pixScale = 1.0f / 256.0f; |
308 | 263 | ||
309 | if (mirror) | 264 | int imageX, imageY = 0; |
310 | if (sculptType == SculptType.plane) | 265 | |
311 | invert = !invert; | 266 | int rowNdx, colNdx; |
312 | 267 | ||
313 | float sculptBitmapLod = (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height); | 268 | for (rowNdx = 0; rowNdx <= numRows; rowNdx++) |
269 | { | ||
270 | List<Coord> row = new List<Coord>(numCols); | ||
271 | imageY = rowNdx * scale; | ||
272 | if (rowNdx == numRows) imageY--; | ||
273 | for (colNdx = 0; colNdx <= numCols; colNdx++) | ||
274 | { | ||
275 | imageX = colNdx * scale; | ||
276 | if (colNdx == numCols) imageX--; | ||
314 | 277 | ||
315 | float sourceScaleFactor = (float)(lod) / sculptBitmapLod; | 278 | Color c = bitmap.GetPixel(imageX, imageY); |
279 | if (c.A != 255) | ||
280 | { | ||
281 | bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B)); | ||
282 | c = bitmap.GetPixel(imageX, imageY); | ||
283 | } | ||
316 | 284 | ||
317 | float fScale = 1.0f / sourceScaleFactor; | 285 | if (mirror) |
286 | row.Add(new Coord(-(c.R * pixScale - 0.5f), c.G * pixScale - 0.5f, c.B * pixScale - 0.5f)); | ||
287 | else | ||
288 | row.Add(new Coord(c.R * pixScale - 0.5f, c.G * pixScale - 0.5f, c.B * pixScale - 0.5f)); | ||
318 | 289 | ||
319 | int iScale = (int)fScale; | 290 | } |
320 | if (iScale < 1) iScale = 1; | 291 | rows.Add(row); |
321 | if (iScale > 2 && iScale % 2 == 0) | 292 | } |
322 | _SculptMesh(bitmap2Coords(ScaleImage(sculptBitmap, 64.0f / sculptBitmapLod, true), 64 / lod, mirror), sculptType, viewerMode, mirror, invert); | 293 | return rows; |
323 | else | ||
324 | _SculptMesh(bitmap2Coords(sculptBitmap, iScale, mirror), sculptType, viewerMode, mirror, invert); | ||
325 | } | 294 | } |
326 | #endif | ||
327 | 295 | ||
328 | 296 | ||
297 | void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) | ||
298 | { | ||
299 | _SculptMesh(new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert); | ||
300 | } | ||
301 | #endif | ||
302 | |||
329 | void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) | 303 | void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) |
330 | { | 304 | { |
331 | coords = new List<Coord>(); | 305 | coords = new List<Coord>(); |
@@ -349,8 +323,18 @@ namespace PrimMesher | |||
349 | 323 | ||
350 | if (sculptType != SculptType.plane) | 324 | if (sculptType != SculptType.plane) |
351 | { | 325 | { |
352 | for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++) | 326 | if (rows.Count % 2 == 0) |
353 | rows[rowNdx].Add(rows[rowNdx][0]); | 327 | { |
328 | for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++) | ||
329 | rows[rowNdx].Add(rows[rowNdx][0]); | ||
330 | } | ||
331 | else | ||
332 | { | ||
333 | int lastIndex = rows[0].Count - 1; | ||
334 | |||
335 | for (int i = 0; i < rows.Count; i++) | ||
336 | rows[i][0] = rows[i][lastIndex]; | ||
337 | } | ||
354 | } | 338 | } |
355 | 339 | ||
356 | Coord topPole = rows[0][width / 2]; | 340 | Coord topPole = rows[0][width / 2]; |
@@ -358,23 +342,41 @@ namespace PrimMesher | |||
358 | 342 | ||
359 | if (sculptType == SculptType.sphere) | 343 | if (sculptType == SculptType.sphere) |
360 | { | 344 | { |
361 | int count = rows[0].Count; | 345 | if (rows.Count % 2 == 0) |
362 | List<Coord> topPoleRow = new List<Coord>(count); | 346 | { |
363 | List<Coord> bottomPoleRow = new List<Coord>(count); | 347 | int count = rows[0].Count; |
348 | List<Coord> topPoleRow = new List<Coord>(count); | ||
349 | List<Coord> bottomPoleRow = new List<Coord>(count); | ||
364 | 350 | ||
365 | for (int i = 0; i < count; i++) | 351 | for (int i = 0; i < count; i++) |
352 | { | ||
353 | topPoleRow.Add(topPole); | ||
354 | bottomPoleRow.Add(bottomPole); | ||
355 | } | ||
356 | rows.Insert(0, topPoleRow); | ||
357 | rows.Add(bottomPoleRow); | ||
358 | } | ||
359 | else | ||
366 | { | 360 | { |
367 | topPoleRow.Add(topPole); | 361 | int count = rows[0].Count; |
368 | bottomPoleRow.Add(bottomPole); | 362 | |
363 | List<Coord> topPoleRow = rows[0]; | ||
364 | List<Coord> bottomPoleRow = rows[rows.Count - 1]; | ||
365 | |||
366 | for (int i = 0; i < count; i++) | ||
367 | { | ||
368 | topPoleRow[i] = topPole; | ||
369 | bottomPoleRow[i] = bottomPole; | ||
370 | } | ||
369 | } | 371 | } |
370 | rows.Insert(0, topPoleRow); | ||
371 | rows.Add(bottomPoleRow); | ||
372 | } | 372 | } |
373 | else if (sculptType == SculptType.torus) | 373 | |
374 | if (sculptType == SculptType.torus) | ||
374 | rows.Add(rows[0]); | 375 | rows.Add(rows[0]); |
375 | 376 | ||
376 | int coordsDown = rows.Count; | 377 | int coordsDown = rows.Count; |
377 | int coordsAcross = rows[0].Count; | 378 | int coordsAcross = rows[0].Count; |
379 | int lastColumn = coordsAcross - 1; | ||
378 | 380 | ||
379 | float widthUnit = 1.0f / (coordsAcross - 1); | 381 | float widthUnit = 1.0f / (coordsAcross - 1); |
380 | float heightUnit = 1.0f / (coordsDown - 1); | 382 | float heightUnit = 1.0f / (coordsDown - 1); |