diff options
author | Diva Canto | 2010-03-15 19:34:14 -0700 |
---|---|---|
committer | Diva Canto | 2010-03-15 19:34:14 -0700 |
commit | 76106e39d9cd48f136caf061ef9d19641bbdfd31 (patch) | |
tree | 9f310a95e508320a46fc9d91d4b79d2b1f7adaba /OpenSim/Region/Physics/Meshing/SculptMesh.cs | |
parent | Merge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff) | |
download | opensim-SC-76106e39d9cd48f136caf061ef9d19641bbdfd31.zip opensim-SC-76106e39d9cd48f136caf061ef9d19641bbdfd31.tar.gz opensim-SC-76106e39d9cd48f136caf061ef9d19641bbdfd31.tar.bz2 opensim-SC-76106e39d9cd48f136caf061ef9d19641bbdfd31.tar.xz |
Restoring LoadPlugin as it was before. Justin's last change made it throw.
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/SculptMesh.cs')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/SculptMesh.cs | 1290 |
1 files changed, 645 insertions, 645 deletions
diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs index 11b6cd4..ebc5be6 100644 --- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs +++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs | |||
@@ -1,645 +1,645 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors | 2 | * Copyright (c) Contributors |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | // to build without references to System.Drawing, comment this out | 28 | // to build without references to System.Drawing, comment this out |
29 | #define SYSTEM_DRAWING | 29 | #define SYSTEM_DRAWING |
30 | 30 | ||
31 | using System; | 31 | using System; |
32 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
33 | using System.Text; | 33 | using System.Text; |
34 | using System.IO; | 34 | using System.IO; |
35 | 35 | ||
36 | #if SYSTEM_DRAWING | 36 | #if SYSTEM_DRAWING |
37 | using System.Drawing; | 37 | using System.Drawing; |
38 | using System.Drawing.Imaging; | 38 | using System.Drawing.Imaging; |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | namespace PrimMesher | 41 | namespace PrimMesher |
42 | { | 42 | { |
43 | 43 | ||
44 | public class SculptMesh | 44 | public class SculptMesh |
45 | { | 45 | { |
46 | public List<Coord> coords; | 46 | public List<Coord> coords; |
47 | public List<Face> faces; | 47 | public List<Face> faces; |
48 | 48 | ||
49 | public List<ViewerFace> viewerFaces; | 49 | public List<ViewerFace> viewerFaces; |
50 | public List<Coord> normals; | 50 | public List<Coord> normals; |
51 | public List<UVCoord> uvs; | 51 | public List<UVCoord> uvs; |
52 | 52 | ||
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) | 56 | private Bitmap ScaleImage(Bitmap srcImage, float scale, bool removeAlpha) |
57 | { | 57 | { |
58 | int sourceWidth = srcImage.Width; | 58 | int sourceWidth = srcImage.Width; |
59 | int sourceHeight = srcImage.Height; | 59 | int sourceHeight = srcImage.Height; |
60 | int sourceX = 0; | 60 | int sourceX = 0; |
61 | int sourceY = 0; | 61 | int sourceY = 0; |
62 | 62 | ||
63 | int destX = 0; | 63 | int destX = 0; |
64 | int destY = 0; | 64 | int destY = 0; |
65 | int destWidth = (int)(srcImage.Width * scale); | 65 | int destWidth = (int)(srcImage.Width * scale); |
66 | int destHeight = (int)(srcImage.Height * scale); | 66 | int destHeight = (int)(srcImage.Height * scale); |
67 | 67 | ||
68 | Bitmap scaledImage; | 68 | Bitmap scaledImage; |
69 | 69 | ||
70 | if (removeAlpha) | 70 | if (removeAlpha) |
71 | { | 71 | { |
72 | if (srcImage.PixelFormat == PixelFormat.Format32bppArgb) | 72 | if (srcImage.PixelFormat == PixelFormat.Format32bppArgb) |
73 | for (int y = 0; y < srcImage.Height; y++) | 73 | for (int y = 0; y < srcImage.Height; y++) |
74 | for (int x = 0; x < srcImage.Width; x++) | 74 | for (int x = 0; x < srcImage.Width; x++) |
75 | { | 75 | { |
76 | Color c = srcImage.GetPixel(x, y); | 76 | Color c = srcImage.GetPixel(x, y); |
77 | srcImage.SetPixel(x, y, Color.FromArgb(255, c.R, c.G, c.B)); | 77 | srcImage.SetPixel(x, y, Color.FromArgb(255, c.R, c.G, c.B)); |
78 | } | 78 | } |
79 | 79 | ||
80 | scaledImage = new Bitmap(destWidth, destHeight, | 80 | scaledImage = new Bitmap(destWidth, destHeight, |
81 | PixelFormat.Format24bppRgb); | 81 | PixelFormat.Format24bppRgb); |
82 | } | 82 | } |
83 | else | 83 | else |
84 | scaledImage = new Bitmap(srcImage, destWidth, destHeight); | 84 | scaledImage = new Bitmap(srcImage, destWidth, destHeight); |
85 | 85 | ||
86 | scaledImage.SetResolution(96.0f, 96.0f); | 86 | scaledImage.SetResolution(96.0f, 96.0f); |
87 | 87 | ||
88 | Graphics grPhoto = Graphics.FromImage(scaledImage); | 88 | Graphics grPhoto = Graphics.FromImage(scaledImage); |
89 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low; | 89 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low; |
90 | 90 | ||
91 | grPhoto.DrawImage(srcImage, | 91 | grPhoto.DrawImage(srcImage, |
92 | new Rectangle(destX, destY, destWidth, destHeight), | 92 | new Rectangle(destX, destY, destWidth, destHeight), |
93 | new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), | 93 | new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), |
94 | GraphicsUnit.Pixel); | 94 | GraphicsUnit.Pixel); |
95 | 95 | ||
96 | grPhoto.Dispose(); | 96 | grPhoto.Dispose(); |
97 | return scaledImage; | 97 | return scaledImage; |
98 | } | 98 | } |
99 | 99 | ||
100 | 100 | ||
101 | public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) | 101 | public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) |
102 | { | 102 | { |
103 | Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); | 103 | Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); |
104 | SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode); | 104 | SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode); |
105 | bitmap.Dispose(); | 105 | bitmap.Dispose(); |
106 | return sculptMesh; | 106 | return sculptMesh; |
107 | } | 107 | } |
108 | 108 | ||
109 | public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert) | 109 | public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert) |
110 | { | 110 | { |
111 | Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); | 111 | Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); |
112 | _SculptMesh(bitmap, (SculptType)sculptType, lod, viewerMode != 0, mirror != 0, invert != 0); | 112 | _SculptMesh(bitmap, (SculptType)sculptType, lod, viewerMode != 0, mirror != 0, invert != 0); |
113 | bitmap.Dispose(); | 113 | bitmap.Dispose(); |
114 | } | 114 | } |
115 | #endif | 115 | #endif |
116 | 116 | ||
117 | /// <summary> | 117 | /// <summary> |
118 | /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications | 118 | /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications |
119 | /// Construct a sculpt mesh from a 2D array of floats | 119 | /// Construct a sculpt mesh from a 2D array of floats |
120 | /// </summary> | 120 | /// </summary> |
121 | /// <param name="zMap"></param> | 121 | /// <param name="zMap"></param> |
122 | /// <param name="xBegin"></param> | 122 | /// <param name="xBegin"></param> |
123 | /// <param name="xEnd"></param> | 123 | /// <param name="xEnd"></param> |
124 | /// <param name="yBegin"></param> | 124 | /// <param name="yBegin"></param> |
125 | /// <param name="yEnd"></param> | 125 | /// <param name="yEnd"></param> |
126 | /// <param name="viewerMode"></param> | 126 | /// <param name="viewerMode"></param> |
127 | public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd, bool viewerMode) | 127 | public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd, bool viewerMode) |
128 | { | 128 | { |
129 | float xStep, yStep; | 129 | float xStep, yStep; |
130 | float uStep, vStep; | 130 | float uStep, vStep; |
131 | 131 | ||
132 | int numYElements = zMap.GetLength(0); | 132 | int numYElements = zMap.GetLength(0); |
133 | int numXElements = zMap.GetLength(1); | 133 | int numXElements = zMap.GetLength(1); |
134 | 134 | ||
135 | try | 135 | try |
136 | { | 136 | { |
137 | xStep = (xEnd - xBegin) / (float)(numXElements - 1); | 137 | xStep = (xEnd - xBegin) / (float)(numXElements - 1); |
138 | yStep = (yEnd - yBegin) / (float)(numYElements - 1); | 138 | yStep = (yEnd - yBegin) / (float)(numYElements - 1); |
139 | 139 | ||
140 | uStep = 1.0f / (numXElements - 1); | 140 | uStep = 1.0f / (numXElements - 1); |
141 | vStep = 1.0f / (numYElements - 1); | 141 | vStep = 1.0f / (numYElements - 1); |
142 | } | 142 | } |
143 | catch (DivideByZeroException) | 143 | catch (DivideByZeroException) |
144 | { | 144 | { |
145 | return; | 145 | return; |
146 | } | 146 | } |
147 | 147 | ||
148 | coords = new List<Coord>(); | 148 | coords = new List<Coord>(); |
149 | faces = new List<Face>(); | 149 | faces = new List<Face>(); |
150 | normals = new List<Coord>(); | 150 | normals = new List<Coord>(); |
151 | uvs = new List<UVCoord>(); | 151 | uvs = new List<UVCoord>(); |
152 | 152 | ||
153 | viewerFaces = new List<ViewerFace>(); | 153 | viewerFaces = new List<ViewerFace>(); |
154 | 154 | ||
155 | int p1, p2, p3, p4; | 155 | int p1, p2, p3, p4; |
156 | 156 | ||
157 | int x, y; | 157 | int x, y; |
158 | int xStart = 0, yStart = 0; | 158 | int xStart = 0, yStart = 0; |
159 | 159 | ||
160 | for (y = yStart; y < numYElements; y++) | 160 | for (y = yStart; y < numYElements; y++) |
161 | { | 161 | { |
162 | int rowOffset = y * numXElements; | 162 | int rowOffset = y * numXElements; |
163 | 163 | ||
164 | for (x = xStart; x < numXElements; x++) | 164 | for (x = xStart; x < numXElements; x++) |
165 | { | 165 | { |
166 | /* | 166 | /* |
167 | * p1-----p2 | 167 | * p1-----p2 |
168 | * | \ f2 | | 168 | * | \ f2 | |
169 | * | \ | | 169 | * | \ | |
170 | * | f1 \| | 170 | * | f1 \| |
171 | * p3-----p4 | 171 | * p3-----p4 |
172 | */ | 172 | */ |
173 | 173 | ||
174 | p4 = rowOffset + x; | 174 | p4 = rowOffset + x; |
175 | p3 = p4 - 1; | 175 | p3 = p4 - 1; |
176 | 176 | ||
177 | p2 = p4 - numXElements; | 177 | p2 = p4 - numXElements; |
178 | p1 = p3 - numXElements; | 178 | p1 = p3 - numXElements; |
179 | 179 | ||
180 | Coord c = new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]); | 180 | Coord c = new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]); |
181 | this.coords.Add(c); | 181 | this.coords.Add(c); |
182 | if (viewerMode) | 182 | if (viewerMode) |
183 | { | 183 | { |
184 | this.normals.Add(new Coord()); | 184 | this.normals.Add(new Coord()); |
185 | this.uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y)); | 185 | this.uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y)); |
186 | } | 186 | } |
187 | 187 | ||
188 | if (y > 0 && x > 0) | 188 | if (y > 0 && x > 0) |
189 | { | 189 | { |
190 | Face f1, f2; | 190 | Face f1, f2; |
191 | 191 | ||
192 | if (viewerMode) | 192 | if (viewerMode) |
193 | { | 193 | { |
194 | f1 = new Face(p1, p4, p3, p1, p4, p3); | 194 | f1 = new Face(p1, p4, p3, p1, p4, p3); |
195 | f1.uv1 = p1; | 195 | f1.uv1 = p1; |
196 | f1.uv2 = p4; | 196 | f1.uv2 = p4; |
197 | f1.uv3 = p3; | 197 | f1.uv3 = p3; |
198 | 198 | ||
199 | f2 = new Face(p1, p2, p4, p1, p2, p4); | 199 | f2 = new Face(p1, p2, p4, p1, p2, p4); |
200 | f2.uv1 = p1; | 200 | f2.uv1 = p1; |
201 | f2.uv2 = p2; | 201 | f2.uv2 = p2; |
202 | f2.uv3 = p4; | 202 | f2.uv3 = p4; |
203 | } | 203 | } |
204 | else | 204 | else |
205 | { | 205 | { |
206 | f1 = new Face(p1, p4, p3); | 206 | f1 = new Face(p1, p4, p3); |
207 | f2 = new Face(p1, p2, p4); | 207 | f2 = new Face(p1, p2, p4); |
208 | } | 208 | } |
209 | 209 | ||
210 | this.faces.Add(f1); | 210 | this.faces.Add(f1); |
211 | this.faces.Add(f2); | 211 | this.faces.Add(f2); |
212 | } | 212 | } |
213 | } | 213 | } |
214 | } | 214 | } |
215 | 215 | ||
216 | if (viewerMode) | 216 | if (viewerMode) |
217 | calcVertexNormals(SculptType.plane, numXElements, numYElements); | 217 | calcVertexNormals(SculptType.plane, numXElements, numYElements); |
218 | } | 218 | } |
219 | 219 | ||
220 | #if SYSTEM_DRAWING | 220 | #if SYSTEM_DRAWING |
221 | public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) | 221 | public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) |
222 | { | 222 | { |
223 | _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false); | 223 | _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false); |
224 | } | 224 | } |
225 | 225 | ||
226 | public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) | 226 | public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) |
227 | { | 227 | { |
228 | _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert); | 228 | _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert); |
229 | } | 229 | } |
230 | #endif | 230 | #endif |
231 | 231 | ||
232 | public SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) | 232 | public SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) |
233 | { | 233 | { |
234 | _SculptMesh(rows, sculptType, viewerMode, mirror, invert); | 234 | _SculptMesh(rows, sculptType, viewerMode, mirror, invert); |
235 | } | 235 | } |
236 | 236 | ||
237 | #if SYSTEM_DRAWING | 237 | #if SYSTEM_DRAWING |
238 | /// <summary> | 238 | /// <summary> |
239 | /// converts a bitmap to a list of lists of coords, while scaling the image. | 239 | /// converts a bitmap to a list of lists of coords, while scaling the image. |
240 | /// the scaling is done in floating point so as to allow for reduced vertex position | 240 | /// the scaling is done in floating point so as to allow for reduced vertex position |
241 | /// quantization as the position will be averaged between pixel values. this routine will | 241 | /// quantization as the position will be averaged between pixel values. this routine will |
242 | /// likely fail if the bitmap width and height are not powers of 2. | 242 | /// likely fail if the bitmap width and height are not powers of 2. |
243 | /// </summary> | 243 | /// </summary> |
244 | /// <param name="bitmap"></param> | 244 | /// <param name="bitmap"></param> |
245 | /// <param name="scale"></param> | 245 | /// <param name="scale"></param> |
246 | /// <param name="mirror"></param> | 246 | /// <param name="mirror"></param> |
247 | /// <returns></returns> | 247 | /// <returns></returns> |
248 | private List<List<Coord>> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) | 248 | private List<List<Coord>> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) |
249 | { | 249 | { |
250 | int numRows = bitmap.Height / scale; | 250 | int numRows = bitmap.Height / scale; |
251 | int numCols = bitmap.Width / scale; | 251 | int numCols = bitmap.Width / scale; |
252 | List<List<Coord>> rows = new List<List<Coord>>(numRows); | 252 | List<List<Coord>> rows = new List<List<Coord>>(numRows); |
253 | 253 | ||
254 | float pixScale = 1.0f / (scale * scale); | 254 | float pixScale = 1.0f / (scale * scale); |
255 | pixScale /= 255; | 255 | pixScale /= 255; |
256 | 256 | ||
257 | int imageX, imageY = 0; | 257 | int imageX, imageY = 0; |
258 | 258 | ||
259 | int rowNdx, colNdx; | 259 | int rowNdx, colNdx; |
260 | 260 | ||
261 | for (rowNdx = 0; rowNdx < numRows; rowNdx++) | 261 | for (rowNdx = 0; rowNdx < numRows; rowNdx++) |
262 | { | 262 | { |
263 | List<Coord> row = new List<Coord>(numCols); | 263 | List<Coord> row = new List<Coord>(numCols); |
264 | for (colNdx = 0; colNdx < numCols; colNdx++) | 264 | for (colNdx = 0; colNdx < numCols; colNdx++) |
265 | { | 265 | { |
266 | imageX = colNdx * scale; | 266 | imageX = colNdx * scale; |
267 | int imageYStart = rowNdx * scale; | 267 | int imageYStart = rowNdx * scale; |
268 | int imageYEnd = imageYStart + scale; | 268 | int imageYEnd = imageYStart + scale; |
269 | int imageXEnd = imageX + scale; | 269 | int imageXEnd = imageX + scale; |
270 | float rSum = 0.0f; | 270 | float rSum = 0.0f; |
271 | float gSum = 0.0f; | 271 | float gSum = 0.0f; |
272 | float bSum = 0.0f; | 272 | float bSum = 0.0f; |
273 | for (; imageX < imageXEnd; imageX++) | 273 | for (; imageX < imageXEnd; imageX++) |
274 | { | 274 | { |
275 | for (imageY = imageYStart; imageY < imageYEnd; imageY++) | 275 | for (imageY = imageYStart; imageY < imageYEnd; imageY++) |
276 | { | 276 | { |
277 | Color c = bitmap.GetPixel(imageX, imageY); | 277 | Color c = bitmap.GetPixel(imageX, imageY); |
278 | if (c.A != 255) | 278 | if (c.A != 255) |
279 | { | 279 | { |
280 | bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B)); | 280 | bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B)); |
281 | c = bitmap.GetPixel(imageX, imageY); | 281 | c = bitmap.GetPixel(imageX, imageY); |
282 | } | 282 | } |
283 | rSum += c.R; | 283 | rSum += c.R; |
284 | gSum += c.G; | 284 | gSum += c.G; |
285 | bSum += c.B; | 285 | bSum += c.B; |
286 | } | 286 | } |
287 | } | 287 | } |
288 | if (mirror) | 288 | if (mirror) |
289 | row.Add(new Coord(-(rSum * pixScale - 0.5f), gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); | 289 | row.Add(new Coord(-(rSum * pixScale - 0.5f), gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); |
290 | else | 290 | else |
291 | row.Add(new Coord(rSum * pixScale - 0.5f, gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); | 291 | row.Add(new Coord(rSum * pixScale - 0.5f, gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); |
292 | 292 | ||
293 | } | 293 | } |
294 | rows.Add(row); | 294 | rows.Add(row); |
295 | } | 295 | } |
296 | return rows; | 296 | return rows; |
297 | } | 297 | } |
298 | 298 | ||
299 | 299 | ||
300 | void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) | 300 | void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) |
301 | { | 301 | { |
302 | coords = new List<Coord>(); | 302 | coords = new List<Coord>(); |
303 | faces = new List<Face>(); | 303 | faces = new List<Face>(); |
304 | normals = new List<Coord>(); | 304 | normals = new List<Coord>(); |
305 | uvs = new List<UVCoord>(); | 305 | uvs = new List<UVCoord>(); |
306 | 306 | ||
307 | sculptType = (SculptType)(((int)sculptType) & 0x07); | 307 | sculptType = (SculptType)(((int)sculptType) & 0x07); |
308 | 308 | ||
309 | if (mirror) | 309 | if (mirror) |
310 | if (sculptType == SculptType.plane) | 310 | if (sculptType == SculptType.plane) |
311 | invert = !invert; | 311 | invert = !invert; |
312 | 312 | ||
313 | float sculptBitmapLod = (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height); | 313 | float sculptBitmapLod = (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height); |
314 | 314 | ||
315 | float sourceScaleFactor = (float)(lod) / sculptBitmapLod; | 315 | float sourceScaleFactor = (float)(lod) / sculptBitmapLod; |
316 | 316 | ||
317 | float fScale = 1.0f / sourceScaleFactor; | 317 | float fScale = 1.0f / sourceScaleFactor; |
318 | 318 | ||
319 | int iScale = (int)fScale; | 319 | int iScale = (int)fScale; |
320 | if (iScale < 1) iScale = 1; | 320 | if (iScale < 1) iScale = 1; |
321 | if (iScale > 2 && iScale % 2 == 0) | 321 | if (iScale > 2 && iScale % 2 == 0) |
322 | _SculptMesh(bitmap2Coords(ScaleImage(sculptBitmap, 64.0f / sculptBitmapLod, true), 64 / lod, mirror), sculptType, viewerMode, mirror, invert); | 322 | _SculptMesh(bitmap2Coords(ScaleImage(sculptBitmap, 64.0f / sculptBitmapLod, true), 64 / lod, mirror), sculptType, viewerMode, mirror, invert); |
323 | else | 323 | else |
324 | _SculptMesh(bitmap2Coords(sculptBitmap, iScale, mirror), sculptType, viewerMode, mirror, invert); | 324 | _SculptMesh(bitmap2Coords(sculptBitmap, iScale, mirror), sculptType, viewerMode, mirror, invert); |
325 | } | 325 | } |
326 | #endif | 326 | #endif |
327 | 327 | ||
328 | 328 | ||
329 | void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) | 329 | void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) |
330 | { | 330 | { |
331 | coords = new List<Coord>(); | 331 | coords = new List<Coord>(); |
332 | faces = new List<Face>(); | 332 | faces = new List<Face>(); |
333 | normals = new List<Coord>(); | 333 | normals = new List<Coord>(); |
334 | uvs = new List<UVCoord>(); | 334 | uvs = new List<UVCoord>(); |
335 | 335 | ||
336 | sculptType = (SculptType)(((int)sculptType) & 0x07); | 336 | sculptType = (SculptType)(((int)sculptType) & 0x07); |
337 | 337 | ||
338 | if (mirror) | 338 | if (mirror) |
339 | if (sculptType == SculptType.plane) | 339 | if (sculptType == SculptType.plane) |
340 | invert = !invert; | 340 | invert = !invert; |
341 | 341 | ||
342 | viewerFaces = new List<ViewerFace>(); | 342 | viewerFaces = new List<ViewerFace>(); |
343 | 343 | ||
344 | int width = rows[0].Count; | 344 | int width = rows[0].Count; |
345 | 345 | ||
346 | int p1, p2, p3, p4; | 346 | int p1, p2, p3, p4; |
347 | 347 | ||
348 | int imageX, imageY; | 348 | int imageX, imageY; |
349 | 349 | ||
350 | if (sculptType != SculptType.plane) | 350 | if (sculptType != SculptType.plane) |
351 | { | 351 | { |
352 | for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++) | 352 | for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++) |
353 | rows[rowNdx].Add(rows[rowNdx][0]); | 353 | rows[rowNdx].Add(rows[rowNdx][0]); |
354 | } | 354 | } |
355 | 355 | ||
356 | Coord topPole = rows[0][width / 2]; | 356 | Coord topPole = rows[0][width / 2]; |
357 | Coord bottomPole = rows[rows.Count - 1][width / 2]; | 357 | Coord bottomPole = rows[rows.Count - 1][width / 2]; |
358 | 358 | ||
359 | if (sculptType == SculptType.sphere) | 359 | if (sculptType == SculptType.sphere) |
360 | { | 360 | { |
361 | int count = rows[0].Count; | 361 | int count = rows[0].Count; |
362 | List<Coord> topPoleRow = new List<Coord>(count); | 362 | List<Coord> topPoleRow = new List<Coord>(count); |
363 | List<Coord> bottomPoleRow = new List<Coord>(count); | 363 | List<Coord> bottomPoleRow = new List<Coord>(count); |
364 | 364 | ||
365 | for (int i = 0; i < count; i++) | 365 | for (int i = 0; i < count; i++) |
366 | { | 366 | { |
367 | topPoleRow.Add(topPole); | 367 | topPoleRow.Add(topPole); |
368 | bottomPoleRow.Add(bottomPole); | 368 | bottomPoleRow.Add(bottomPole); |
369 | } | 369 | } |
370 | rows.Insert(0, topPoleRow); | 370 | rows.Insert(0, topPoleRow); |
371 | rows.Add(bottomPoleRow); | 371 | rows.Add(bottomPoleRow); |
372 | } | 372 | } |
373 | else if (sculptType == SculptType.torus) | 373 | else if (sculptType == SculptType.torus) |
374 | rows.Add(rows[0]); | 374 | rows.Add(rows[0]); |
375 | 375 | ||
376 | int coordsDown = rows.Count; | 376 | int coordsDown = rows.Count; |
377 | int coordsAcross = rows[0].Count; | 377 | int coordsAcross = rows[0].Count; |
378 | 378 | ||
379 | float widthUnit = 1.0f / (coordsAcross - 1); | 379 | float widthUnit = 1.0f / (coordsAcross - 1); |
380 | float heightUnit = 1.0f / (coordsDown - 1); | 380 | float heightUnit = 1.0f / (coordsDown - 1); |
381 | 381 | ||
382 | for (imageY = 0; imageY < coordsDown; imageY++) | 382 | for (imageY = 0; imageY < coordsDown; imageY++) |
383 | { | 383 | { |
384 | int rowOffset = imageY * coordsAcross; | 384 | int rowOffset = imageY * coordsAcross; |
385 | 385 | ||
386 | for (imageX = 0; imageX < coordsAcross; imageX++) | 386 | for (imageX = 0; imageX < coordsAcross; imageX++) |
387 | { | 387 | { |
388 | /* | 388 | /* |
389 | * p1-----p2 | 389 | * p1-----p2 |
390 | * | \ f2 | | 390 | * | \ f2 | |
391 | * | \ | | 391 | * | \ | |
392 | * | f1 \| | 392 | * | f1 \| |
393 | * p3-----p4 | 393 | * p3-----p4 |
394 | */ | 394 | */ |
395 | 395 | ||
396 | p4 = rowOffset + imageX; | 396 | p4 = rowOffset + imageX; |
397 | p3 = p4 - 1; | 397 | p3 = p4 - 1; |
398 | 398 | ||
399 | p2 = p4 - coordsAcross; | 399 | p2 = p4 - coordsAcross; |
400 | p1 = p3 - coordsAcross; | 400 | p1 = p3 - coordsAcross; |
401 | 401 | ||
402 | this.coords.Add(rows[imageY][imageX]); | 402 | this.coords.Add(rows[imageY][imageX]); |
403 | if (viewerMode) | 403 | if (viewerMode) |
404 | { | 404 | { |
405 | this.normals.Add(new Coord()); | 405 | this.normals.Add(new Coord()); |
406 | this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY)); | 406 | this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY)); |
407 | } | 407 | } |
408 | 408 | ||
409 | if (imageY > 0 && imageX > 0) | 409 | if (imageY > 0 && imageX > 0) |
410 | { | 410 | { |
411 | Face f1, f2; | 411 | Face f1, f2; |
412 | 412 | ||
413 | if (viewerMode) | 413 | if (viewerMode) |
414 | { | 414 | { |
415 | if (invert) | 415 | if (invert) |
416 | { | 416 | { |
417 | f1 = new Face(p1, p4, p3, p1, p4, p3); | 417 | f1 = new Face(p1, p4, p3, p1, p4, p3); |
418 | f1.uv1 = p1; | 418 | f1.uv1 = p1; |
419 | f1.uv2 = p4; | 419 | f1.uv2 = p4; |
420 | f1.uv3 = p3; | 420 | f1.uv3 = p3; |
421 | 421 | ||
422 | f2 = new Face(p1, p2, p4, p1, p2, p4); | 422 | f2 = new Face(p1, p2, p4, p1, p2, p4); |
423 | f2.uv1 = p1; | 423 | f2.uv1 = p1; |
424 | f2.uv2 = p2; | 424 | f2.uv2 = p2; |
425 | f2.uv3 = p4; | 425 | f2.uv3 = p4; |
426 | } | 426 | } |
427 | else | 427 | else |
428 | { | 428 | { |
429 | f1 = new Face(p1, p3, p4, p1, p3, p4); | 429 | f1 = new Face(p1, p3, p4, p1, p3, p4); |
430 | f1.uv1 = p1; | 430 | f1.uv1 = p1; |
431 | f1.uv2 = p3; | 431 | f1.uv2 = p3; |
432 | f1.uv3 = p4; | 432 | f1.uv3 = p4; |
433 | 433 | ||
434 | f2 = new Face(p1, p4, p2, p1, p4, p2); | 434 | f2 = new Face(p1, p4, p2, p1, p4, p2); |
435 | f2.uv1 = p1; | 435 | f2.uv1 = p1; |
436 | f2.uv2 = p4; | 436 | f2.uv2 = p4; |
437 | f2.uv3 = p2; | 437 | f2.uv3 = p2; |
438 | } | 438 | } |
439 | } | 439 | } |
440 | else | 440 | else |
441 | { | 441 | { |
442 | if (invert) | 442 | if (invert) |
443 | { | 443 | { |
444 | f1 = new Face(p1, p4, p3); | 444 | f1 = new Face(p1, p4, p3); |
445 | f2 = new Face(p1, p2, p4); | 445 | f2 = new Face(p1, p2, p4); |
446 | } | 446 | } |
447 | else | 447 | else |
448 | { | 448 | { |
449 | f1 = new Face(p1, p3, p4); | 449 | f1 = new Face(p1, p3, p4); |
450 | f2 = new Face(p1, p4, p2); | 450 | f2 = new Face(p1, p4, p2); |
451 | } | 451 | } |
452 | } | 452 | } |
453 | 453 | ||
454 | this.faces.Add(f1); | 454 | this.faces.Add(f1); |
455 | this.faces.Add(f2); | 455 | this.faces.Add(f2); |
456 | } | 456 | } |
457 | } | 457 | } |
458 | } | 458 | } |
459 | 459 | ||
460 | if (viewerMode) | 460 | if (viewerMode) |
461 | calcVertexNormals(sculptType, coordsAcross, coordsDown); | 461 | calcVertexNormals(sculptType, coordsAcross, coordsDown); |
462 | } | 462 | } |
463 | 463 | ||
464 | /// <summary> | 464 | /// <summary> |
465 | /// Duplicates a SculptMesh object. All object properties are copied by value, including lists. | 465 | /// Duplicates a SculptMesh object. All object properties are copied by value, including lists. |
466 | /// </summary> | 466 | /// </summary> |
467 | /// <returns></returns> | 467 | /// <returns></returns> |
468 | public SculptMesh Copy() | 468 | public SculptMesh Copy() |
469 | { | 469 | { |
470 | return new SculptMesh(this); | 470 | return new SculptMesh(this); |
471 | } | 471 | } |
472 | 472 | ||
473 | public SculptMesh(SculptMesh sm) | 473 | public SculptMesh(SculptMesh sm) |
474 | { | 474 | { |
475 | coords = new List<Coord>(sm.coords); | 475 | coords = new List<Coord>(sm.coords); |
476 | faces = new List<Face>(sm.faces); | 476 | faces = new List<Face>(sm.faces); |
477 | viewerFaces = new List<ViewerFace>(sm.viewerFaces); | 477 | viewerFaces = new List<ViewerFace>(sm.viewerFaces); |
478 | normals = new List<Coord>(sm.normals); | 478 | normals = new List<Coord>(sm.normals); |
479 | uvs = new List<UVCoord>(sm.uvs); | 479 | uvs = new List<UVCoord>(sm.uvs); |
480 | } | 480 | } |
481 | 481 | ||
482 | private void calcVertexNormals(SculptType sculptType, int xSize, int ySize) | 482 | private void calcVertexNormals(SculptType sculptType, int xSize, int ySize) |
483 | { // compute vertex normals by summing all the surface normals of all the triangles sharing | 483 | { // compute vertex normals by summing all the surface normals of all the triangles sharing |
484 | // each vertex and then normalizing | 484 | // each vertex and then normalizing |
485 | int numFaces = this.faces.Count; | 485 | int numFaces = this.faces.Count; |
486 | for (int i = 0; i < numFaces; i++) | 486 | for (int i = 0; i < numFaces; i++) |
487 | { | 487 | { |
488 | Face face = this.faces[i]; | 488 | Face face = this.faces[i]; |
489 | Coord surfaceNormal = face.SurfaceNormal(this.coords); | 489 | Coord surfaceNormal = face.SurfaceNormal(this.coords); |
490 | this.normals[face.n1] += surfaceNormal; | 490 | this.normals[face.n1] += surfaceNormal; |
491 | this.normals[face.n2] += surfaceNormal; | 491 | this.normals[face.n2] += surfaceNormal; |
492 | this.normals[face.n3] += surfaceNormal; | 492 | this.normals[face.n3] += surfaceNormal; |
493 | } | 493 | } |
494 | 494 | ||
495 | int numNormals = this.normals.Count; | 495 | int numNormals = this.normals.Count; |
496 | for (int i = 0; i < numNormals; i++) | 496 | for (int i = 0; i < numNormals; i++) |
497 | this.normals[i] = this.normals[i].Normalize(); | 497 | this.normals[i] = this.normals[i].Normalize(); |
498 | 498 | ||
499 | if (sculptType != SculptType.plane) | 499 | if (sculptType != SculptType.plane) |
500 | { // blend the vertex normals at the cylinder seam | 500 | { // blend the vertex normals at the cylinder seam |
501 | for (int y = 0; y < ySize; y++) | 501 | for (int y = 0; y < ySize; y++) |
502 | { | 502 | { |
503 | int rowOffset = y * xSize; | 503 | int rowOffset = y * xSize; |
504 | 504 | ||
505 | this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize(); | 505 | this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize(); |
506 | } | 506 | } |
507 | } | 507 | } |
508 | 508 | ||
509 | foreach (Face face in this.faces) | 509 | foreach (Face face in this.faces) |
510 | { | 510 | { |
511 | ViewerFace vf = new ViewerFace(0); | 511 | ViewerFace vf = new ViewerFace(0); |
512 | vf.v1 = this.coords[face.v1]; | 512 | vf.v1 = this.coords[face.v1]; |
513 | vf.v2 = this.coords[face.v2]; | 513 | vf.v2 = this.coords[face.v2]; |
514 | vf.v3 = this.coords[face.v3]; | 514 | vf.v3 = this.coords[face.v3]; |
515 | 515 | ||
516 | vf.coordIndex1 = face.v1; | 516 | vf.coordIndex1 = face.v1; |
517 | vf.coordIndex2 = face.v2; | 517 | vf.coordIndex2 = face.v2; |
518 | vf.coordIndex3 = face.v3; | 518 | vf.coordIndex3 = face.v3; |
519 | 519 | ||
520 | vf.n1 = this.normals[face.n1]; | 520 | vf.n1 = this.normals[face.n1]; |
521 | vf.n2 = this.normals[face.n2]; | 521 | vf.n2 = this.normals[face.n2]; |
522 | vf.n3 = this.normals[face.n3]; | 522 | vf.n3 = this.normals[face.n3]; |
523 | 523 | ||
524 | vf.uv1 = this.uvs[face.uv1]; | 524 | vf.uv1 = this.uvs[face.uv1]; |
525 | vf.uv2 = this.uvs[face.uv2]; | 525 | vf.uv2 = this.uvs[face.uv2]; |
526 | vf.uv3 = this.uvs[face.uv3]; | 526 | vf.uv3 = this.uvs[face.uv3]; |
527 | 527 | ||
528 | this.viewerFaces.Add(vf); | 528 | this.viewerFaces.Add(vf); |
529 | } | 529 | } |
530 | } | 530 | } |
531 | 531 | ||
532 | /// <summary> | 532 | /// <summary> |
533 | /// Adds a value to each XYZ vertex coordinate in the mesh | 533 | /// Adds a value to each XYZ vertex coordinate in the mesh |
534 | /// </summary> | 534 | /// </summary> |
535 | /// <param name="x"></param> | 535 | /// <param name="x"></param> |
536 | /// <param name="y"></param> | 536 | /// <param name="y"></param> |
537 | /// <param name="z"></param> | 537 | /// <param name="z"></param> |
538 | public void AddPos(float x, float y, float z) | 538 | public void AddPos(float x, float y, float z) |
539 | { | 539 | { |
540 | int i; | 540 | int i; |
541 | int numVerts = this.coords.Count; | 541 | int numVerts = this.coords.Count; |
542 | Coord vert; | 542 | Coord vert; |
543 | 543 | ||
544 | for (i = 0; i < numVerts; i++) | 544 | for (i = 0; i < numVerts; i++) |
545 | { | 545 | { |
546 | vert = this.coords[i]; | 546 | vert = this.coords[i]; |
547 | vert.X += x; | 547 | vert.X += x; |
548 | vert.Y += y; | 548 | vert.Y += y; |
549 | vert.Z += z; | 549 | vert.Z += z; |
550 | this.coords[i] = vert; | 550 | this.coords[i] = vert; |
551 | } | 551 | } |
552 | 552 | ||
553 | if (this.viewerFaces != null) | 553 | if (this.viewerFaces != null) |
554 | { | 554 | { |
555 | int numViewerFaces = this.viewerFaces.Count; | 555 | int numViewerFaces = this.viewerFaces.Count; |
556 | 556 | ||
557 | for (i = 0; i < numViewerFaces; i++) | 557 | for (i = 0; i < numViewerFaces; i++) |
558 | { | 558 | { |
559 | ViewerFace v = this.viewerFaces[i]; | 559 | ViewerFace v = this.viewerFaces[i]; |
560 | v.AddPos(x, y, z); | 560 | v.AddPos(x, y, z); |
561 | this.viewerFaces[i] = v; | 561 | this.viewerFaces[i] = v; |
562 | } | 562 | } |
563 | } | 563 | } |
564 | } | 564 | } |
565 | 565 | ||
566 | /// <summary> | 566 | /// <summary> |
567 | /// Rotates the mesh | 567 | /// Rotates the mesh |
568 | /// </summary> | 568 | /// </summary> |
569 | /// <param name="q"></param> | 569 | /// <param name="q"></param> |
570 | public void AddRot(Quat q) | 570 | public void AddRot(Quat q) |
571 | { | 571 | { |
572 | int i; | 572 | int i; |
573 | int numVerts = this.coords.Count; | 573 | int numVerts = this.coords.Count; |
574 | 574 | ||
575 | for (i = 0; i < numVerts; i++) | 575 | for (i = 0; i < numVerts; i++) |
576 | this.coords[i] *= q; | 576 | this.coords[i] *= q; |
577 | 577 | ||
578 | int numNormals = this.normals.Count; | 578 | int numNormals = this.normals.Count; |
579 | for (i = 0; i < numNormals; i++) | 579 | for (i = 0; i < numNormals; i++) |
580 | this.normals[i] *= q; | 580 | this.normals[i] *= q; |
581 | 581 | ||
582 | if (this.viewerFaces != null) | 582 | if (this.viewerFaces != null) |
583 | { | 583 | { |
584 | int numViewerFaces = this.viewerFaces.Count; | 584 | int numViewerFaces = this.viewerFaces.Count; |
585 | 585 | ||
586 | for (i = 0; i < numViewerFaces; i++) | 586 | for (i = 0; i < numViewerFaces; i++) |
587 | { | 587 | { |
588 | ViewerFace v = this.viewerFaces[i]; | 588 | ViewerFace v = this.viewerFaces[i]; |
589 | v.v1 *= q; | 589 | v.v1 *= q; |
590 | v.v2 *= q; | 590 | v.v2 *= q; |
591 | v.v3 *= q; | 591 | v.v3 *= q; |
592 | 592 | ||
593 | v.n1 *= q; | 593 | v.n1 *= q; |
594 | v.n2 *= q; | 594 | v.n2 *= q; |
595 | v.n3 *= q; | 595 | v.n3 *= q; |
596 | 596 | ||
597 | this.viewerFaces[i] = v; | 597 | this.viewerFaces[i] = v; |
598 | } | 598 | } |
599 | } | 599 | } |
600 | } | 600 | } |
601 | 601 | ||
602 | public void Scale(float x, float y, float z) | 602 | public void Scale(float x, float y, float z) |
603 | { | 603 | { |
604 | int i; | 604 | int i; |
605 | int numVerts = this.coords.Count; | 605 | int numVerts = this.coords.Count; |
606 | 606 | ||
607 | Coord m = new Coord(x, y, z); | 607 | Coord m = new Coord(x, y, z); |
608 | for (i = 0; i < numVerts; i++) | 608 | for (i = 0; i < numVerts; i++) |
609 | this.coords[i] *= m; | 609 | this.coords[i] *= m; |
610 | 610 | ||
611 | if (this.viewerFaces != null) | 611 | if (this.viewerFaces != null) |
612 | { | 612 | { |
613 | int numViewerFaces = this.viewerFaces.Count; | 613 | int numViewerFaces = this.viewerFaces.Count; |
614 | for (i = 0; i < numViewerFaces; i++) | 614 | for (i = 0; i < numViewerFaces; i++) |
615 | { | 615 | { |
616 | ViewerFace v = this.viewerFaces[i]; | 616 | ViewerFace v = this.viewerFaces[i]; |
617 | v.v1 *= m; | 617 | v.v1 *= m; |
618 | v.v2 *= m; | 618 | v.v2 *= m; |
619 | v.v3 *= m; | 619 | v.v3 *= m; |
620 | this.viewerFaces[i] = v; | 620 | this.viewerFaces[i] = v; |
621 | } | 621 | } |
622 | } | 622 | } |
623 | } | 623 | } |
624 | 624 | ||
625 | public void DumpRaw(String path, String name, String title) | 625 | public void DumpRaw(String path, String name, String title) |
626 | { | 626 | { |
627 | if (path == null) | 627 | if (path == null) |
628 | return; | 628 | return; |
629 | String fileName = name + "_" + title + ".raw"; | 629 | String fileName = name + "_" + title + ".raw"; |
630 | String completePath = System.IO.Path.Combine(path, fileName); | 630 | String completePath = System.IO.Path.Combine(path, fileName); |
631 | StreamWriter sw = new StreamWriter(completePath); | 631 | StreamWriter sw = new StreamWriter(completePath); |
632 | 632 | ||
633 | for (int i = 0; i < this.faces.Count; i++) | 633 | for (int i = 0; i < this.faces.Count; i++) |
634 | { | 634 | { |
635 | string s = this.coords[this.faces[i].v1].ToString(); | 635 | string s = this.coords[this.faces[i].v1].ToString(); |
636 | s += " " + this.coords[this.faces[i].v2].ToString(); | 636 | s += " " + this.coords[this.faces[i].v2].ToString(); |
637 | s += " " + this.coords[this.faces[i].v3].ToString(); | 637 | s += " " + this.coords[this.faces[i].v3].ToString(); |
638 | 638 | ||
639 | sw.WriteLine(s); | 639 | sw.WriteLine(s); |
640 | } | 640 | } |
641 | 641 | ||
642 | sw.Close(); | 642 | sw.Close(); |
643 | } | 643 | } |
644 | } | 644 | } |
645 | } | 645 | } |