OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
SculptMap.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.Text;
31 
32 using System.Drawing;
33 using System.Drawing.Imaging;
34 
35 namespace PrimMesher
36 {
37  public class SculptMap
38  {
39  public int width;
40  public int height;
41  public byte[] redBytes;
42  public byte[] greenBytes;
43  public byte[] blueBytes;
44 
45  public SculptMap()
46  {
47  }
48 
49  public SculptMap(Bitmap bm, int lod)
50  {
51  int bmW = bm.Width;
52  int bmH = bm.Height;
53 
54  if (bmW == 0 || bmH == 0)
55  throw new Exception("SculptMap: bitmap has no data");
56 
57  int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
58 
59  bool needsScaling = false;
60  bool smallMap = false;
61 
62  width = bmW;
63  height = bmH;
64 
65  while (width * height > numLodPixels * 4)
66  {
67  width >>= 1;
68  height >>= 1;
69  needsScaling = true;
70  }
71 
72  try
73  {
74  if (needsScaling)
75  bm = ScaleImage(bm, width, height);
76  }
77 
78  catch (Exception e)
79  {
80  throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
81  }
82 
83  if (width * height > numLodPixels)
84  {
85  smallMap = false;
86  width >>= 1;
87  height >>= 1;
88  }
89  else
90  smallMap = true;
91 
92  int numBytes = (width + 1) * (height + 1);
93  redBytes = new byte[numBytes];
94  greenBytes = new byte[numBytes];
95  blueBytes = new byte[numBytes];
96 
97  int byteNdx = 0;
98  Color c;
99 
100  try
101  {
102  for (int y = 0; y <= height; y++)
103  {
104  for (int x = 0; x < width; x++)
105  {
106  if (smallMap)
107  c = bm.GetPixel(x, y < height ? y : y - 1);
108  else
109  c = bm.GetPixel(x * 2, y < height ? y * 2 : y * 2 - 1);
110 
111  redBytes[byteNdx] = c.R;
112  greenBytes[byteNdx] = c.G;
113  blueBytes[byteNdx] = c.B;
114 
115  ++byteNdx;
116  }
117 
118  if (smallMap)
119  c = bm.GetPixel(width - 1, y < height ? y : y - 1);
120  else
121  c = bm.GetPixel(width * 2 - 1, y < height ? y * 2 : y * 2 - 1);
122 
123  redBytes[byteNdx] = c.R;
124  greenBytes[byteNdx] = c.G;
125  blueBytes[byteNdx] = c.B;
126 
127  ++byteNdx;
128  }
129  }
130  catch (Exception e)
131  {
132  throw new Exception("Caught exception processing byte arrays in SculptMap(): e: " + e.ToString());
133  }
134 
135  width++;
136  height++;
137  }
138 
139  public List<List<Coord>> ToRows(bool mirror)
140  {
141  int numRows = height;
142  int numCols = width;
143 
144  List<List<Coord>> rows = new List<List<Coord>>(numRows);
145 
146  float pixScale = 1.0f / 255;
147 
148  int rowNdx, colNdx;
149  int smNdx = 0;
150 
151  for (rowNdx = 0; rowNdx < numRows; rowNdx++)
152  {
153  List<Coord> row = new List<Coord>(numCols);
154  for (colNdx = 0; colNdx < numCols; colNdx++)
155  {
156 
157  if (mirror)
158  row.Add(new Coord(-((float)redBytes[smNdx] * pixScale - 0.5f), ((float)greenBytes[smNdx] * pixScale - 0.5f), (float)blueBytes[smNdx] * pixScale - 0.5f));
159  else
160  row.Add(new Coord((float)redBytes[smNdx] * pixScale - 0.5f, (float)greenBytes[smNdx] * pixScale - 0.5f, (float)blueBytes[smNdx] * pixScale - 0.5f));
161 
162  ++smNdx;
163  }
164  rows.Add(row);
165  }
166  return rows;
167  }
168 
169  private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight)
170  {
171 
172  Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
173 
174  Color c;
175 
176 
177  // will let last step to be eventually diferent, as seems to be in sl
178 
179  float xscale = (float)srcImage.Width / (float)destWidth;
180  float yscale = (float)srcImage.Height / (float)destHeight;
181 
182  int lastsx = srcImage.Width - 1;
183  int lastsy = srcImage.Height - 1;
184  int lastdx = destWidth - 1;
185  int lastdy = destHeight - 1;
186 
187  float sy = 0.5f;
188  float sx;
189 
190  for (int y = 0; y < lastdy; y++)
191  {
192  sx = 0.5f;
193  for (int x = 0; x < lastdx; x++)
194  {
195  try
196  {
197  c = srcImage.GetPixel((int)(sx), (int)(sy));
198  scaledImage.SetPixel(x, y, Color.FromArgb(c.R, c.G, c.B));
199  }
200  catch (IndexOutOfRangeException)
201  {
202  }
203  sx += xscale;
204  }
205  try
206  {
207  c = srcImage.GetPixel(lastsx, (int)(sy));
208  scaledImage.SetPixel(lastdx, y, Color.FromArgb(c.R, c.G, c.B));
209  }
210  catch (IndexOutOfRangeException)
211  {
212  }
213 
214  sy += yscale;
215  }
216 
217  sx = 0.5f;
218  for (int x = 0; x < lastdx; x++)
219  {
220  try
221  {
222  c = srcImage.GetPixel((int)(sx), lastsy);
223  scaledImage.SetPixel(x, lastdy, Color.FromArgb(c.R, c.G, c.B));
224  }
225  catch (IndexOutOfRangeException)
226  {
227  }
228 
229  sx += xscale;
230  }
231  try
232  {
233  c = srcImage.GetPixel(lastsx, lastsy);
234  scaledImage.SetPixel(lastdx, lastdy, Color.FromArgb(c.R, c.G, c.B));
235  }
236  catch (IndexOutOfRangeException)
237  {
238  }
239 
240  srcImage.Dispose();
241  return scaledImage;
242  }
243  }
244 }
SculptMap(Bitmap bm, int lod)
Definition: SculptMap.cs:49
List< List< Coord > > ToRows(bool mirror)
Definition: SculptMap.cs:139