diff options
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/SculptMesh.cs')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/SculptMesh.cs | 523 |
1 files changed, 263 insertions, 260 deletions
diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs index 0dc7ef2..826030b 100644 --- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs +++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 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 |
@@ -27,314 +27,317 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Text; | ||
31 | using System.IO; | ||
30 | using System.Drawing; | 32 | using System.Drawing; |
31 | using System.Drawing.Imaging; | 33 | using System.Drawing.Imaging; |
32 | using System.Text; | ||
33 | using OpenMetaverse.Imaging; | ||
34 | 34 | ||
35 | namespace OpenSim.Region.Physics.Meshing | 35 | namespace PrimMesher |
36 | { | 36 | { |
37 | // This functionality based on the XNA SculptPreview by John Hurliman. | ||
38 | public class SculptMesh : Mesh | ||
39 | { | ||
40 | Image idata = null; | ||
41 | Bitmap bLOD = null; | ||
42 | Bitmap bBitmap = null; | ||
43 | 37 | ||
44 | Vertex northpole = new Vertex(0, 0, 0); | 38 | public class SculptMesh |
45 | Vertex southpole = new Vertex(0, 0, 0); | 39 | { |
40 | public List<Coord> coords; | ||
41 | public List<Face> faces; | ||
46 | 42 | ||
47 | private int lod = 32; | 43 | public List<ViewerFace> viewerFaces; |
48 | private const float RANGE = 128.0f; | 44 | public List<Coord> normals; |
45 | public List<UVCoord> uvs; | ||
49 | 46 | ||
50 | public SculptMesh(byte[] jpegData, float _lod) | 47 | public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; |
48 | private const float pixScale = 0.00390625f; // 1.0 / 256 | ||
49 | |||
50 | private Bitmap ScaleImage(Bitmap srcImage, float scale) | ||
51 | { | 51 | { |
52 | if (_lod == 2f || _lod == 4f || _lod == 8f || _lod == 16f || _lod == 32f || _lod == 64f) | 52 | int sourceWidth = srcImage.Width; |
53 | lod = (int)_lod; | 53 | int sourceHeight = srcImage.Height; |
54 | int sourceX = 0; | ||
55 | int sourceY = 0; | ||
56 | |||
57 | int destX = 0; | ||
58 | int destY = 0; | ||
59 | int destWidth = (int)(sourceWidth * scale); | ||
60 | int destHeight = (int)(sourceHeight * scale); | ||
61 | |||
62 | Bitmap scaledImage = new Bitmap(destWidth, destHeight, | ||
63 | PixelFormat.Format24bppRgb); | ||
64 | scaledImage.SetResolution(srcImage.HorizontalResolution, | ||
65 | srcImage.VerticalResolution); | ||
66 | |||
67 | Graphics grPhoto = Graphics.FromImage(scaledImage); | ||
68 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear; | ||
69 | |||
70 | grPhoto.DrawImage(srcImage, | ||
71 | new Rectangle(destX, destY, destWidth, destHeight), | ||
72 | new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), | ||
73 | GraphicsUnit.Pixel); | ||
74 | |||
75 | grPhoto.Dispose(); | ||
76 | return scaledImage; | ||
77 | } | ||
54 | 78 | ||
55 | try | 79 | public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) |
56 | { | 80 | { |
57 | ManagedImage managedImage; // we never use this | 81 | Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); |
58 | OpenJPEG.DecodeToImage(jpegData, out managedImage, out idata); | 82 | SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode); |
59 | //int i = 0; | 83 | bitmap.Dispose(); |
60 | //i = i / i; | 84 | return sculptMesh; |
61 | } | 85 | } |
62 | catch (Exception) | ||
63 | { | ||
64 | System.Console.WriteLine("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed!"); | ||
65 | return; | ||
66 | } | ||
67 | 86 | ||
68 | if (idata != null) | 87 | public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) |
69 | { | 88 | { |
70 | bBitmap = new Bitmap(idata); | 89 | coords = new List<Coord>(); |
71 | if (bBitmap.Width == bBitmap.Height) | 90 | faces = new List<Face>(); |
72 | { | 91 | normals = new List<Coord>(); |
73 | DoLOD(); | 92 | uvs = new List<UVCoord>(); |
74 | 93 | ||
75 | LoadPoles(); | 94 | float sourceScaleFactor = (float)lod / (float)Math.Max(sculptBitmap.Width, sculptBitmap.Height); |
95 | bool scaleSourceImage = sourceScaleFactor < 1.0f ? true : false; | ||
76 | 96 | ||
77 | processSculptTexture(); | 97 | Bitmap bitmap; |
98 | if (scaleSourceImage) | ||
99 | bitmap = ScaleImage(sculptBitmap, sourceScaleFactor); | ||
100 | else | ||
101 | bitmap = sculptBitmap; | ||
78 | 102 | ||
79 | bLOD.Dispose(); | 103 | viewerFaces = new List<ViewerFace>(); |
80 | bBitmap.Dispose(); | ||
81 | idata.Dispose(); | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | private Vertex ColorToVertex(Color input) | ||
87 | { | ||
88 | return new Vertex( | ||
89 | ((float)input.R - 128) / RANGE, | ||
90 | ((float)input.G - 128) / RANGE, | ||
91 | ((float)input.B - 128) / RANGE); | ||
92 | } | ||
93 | |||
94 | private void LoadPoles() | ||
95 | { | ||
96 | northpole = new Vertex(0, 0, 0); | ||
97 | for (int x = 0; x < bLOD.Width; x++) | ||
98 | { | ||
99 | northpole += ColorToVertex(GetPixel(0, 0)); | ||
100 | } | ||
101 | northpole /= bLOD.Width; | ||
102 | 104 | ||
103 | southpole = new Vertex(0, 0, 0); | 105 | int width = bitmap.Width; |
104 | for (int x = 0; x < bLOD.Width; x++) | 106 | int height = bitmap.Height; |
105 | { | ||
106 | //System.Console.WriteLine("Height: " + bLOD.Height.ToString()); | ||
107 | southpole += ColorToVertex(GetPixel(bLOD.Height - 1, (bLOD.Height - 1))); | ||
108 | } | ||
109 | southpole /= bBitmap.Width; | ||
110 | } | ||
111 | 107 | ||
112 | private Color GetPixel(int x, int y) | 108 | float widthUnit = 1.0f / width; |
113 | { | 109 | float heightUnit = 1.0f / (height - 1); |
114 | return bLOD.GetPixel(x, y); | ||
115 | } | ||
116 | 110 | ||
117 | public int LOD | 111 | int p1, p2, p3, p4; |
118 | { | 112 | Color color; |
119 | get | 113 | float x, y, z; |
120 | { | ||
121 | return (int)Math.Log(Scale, 2); | ||
122 | } | ||
123 | set | ||
124 | { | ||
125 | int power = value; | ||
126 | if (power == 0) | ||
127 | power = 6; | ||
128 | if (power < 2) | ||
129 | power = 2; | ||
130 | if (power > 9) | ||
131 | power = 9; | ||
132 | int t = (int)Math.Pow(2, power); | ||
133 | if (t != Scale) | ||
134 | { | ||
135 | lod = t; | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | 114 | ||
140 | public int Scale | 115 | int imageX, imageY; |
141 | { | ||
142 | get | ||
143 | { | ||
144 | return lod; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | private void DoLOD() | ||
149 | { | ||
150 | int x_max = Math.Min(Scale, bBitmap.Width); | ||
151 | int y_max = Math.Min(Scale, bBitmap.Height); | ||
152 | if (bBitmap.Width == x_max && bBitmap.Height == y_max) | ||
153 | bLOD = bBitmap; | ||
154 | 116 | ||
155 | else if (bLOD == null || x_max != bLOD.Width || y_max != bLOD.Height)//don't resize if you don't need to. | 117 | if (sculptType == SculptType.sphere) |
156 | { | 118 | { // average the top and bottom row pixel values so the resulting vertices appear to converge |
157 | System.Drawing.Bitmap tile = new System.Drawing.Bitmap(bBitmap.Width * 2, bBitmap.Height, PixelFormat.Format24bppRgb); | 119 | int lastRow = height - 1; |
158 | System.Drawing.Bitmap tile_LOD = new System.Drawing.Bitmap(x_max * 2, y_max, PixelFormat.Format24bppRgb); | 120 | int r1 = 0, g1 = 0, b1 = 0; |
159 | 121 | int r2 = 0, g2 = 0, b2 = 0; | |
160 | bLOD = new System.Drawing.Bitmap(x_max, y_max, PixelFormat.Format24bppRgb); | 122 | for (imageX = 0; imageX < width; imageX++) |
161 | bLOD.SetResolution(bBitmap.HorizontalResolution, bBitmap.VerticalResolution); | 123 | { |
162 | 124 | Color c1 = bitmap.GetPixel(imageX, 0); | |
163 | System.Drawing.Graphics grPhoto = System.Drawing.Graphics.FromImage(tile); | 125 | Color c2 = bitmap.GetPixel(imageX, lastRow); |
164 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; | ||
165 | |||
166 | grPhoto.DrawImage(bBitmap, | ||
167 | new System.Drawing.Rectangle(0, 0, bBitmap.Width / 2, bBitmap.Height), | ||
168 | new System.Drawing.Rectangle(bBitmap.Width / 2, 0, bBitmap.Width / 2, bBitmap.Height), | ||
169 | System.Drawing.GraphicsUnit.Pixel); | ||
170 | |||
171 | grPhoto.DrawImage(bBitmap, | ||
172 | new System.Drawing.Rectangle((3 * bBitmap.Width) / 2, 0, bBitmap.Width / 2, bBitmap.Height), | ||
173 | new System.Drawing.Rectangle(0, 0, bBitmap.Width / 2, bBitmap.Height), | ||
174 | System.Drawing.GraphicsUnit.Pixel); | ||
175 | |||
176 | grPhoto.DrawImage(bBitmap, | ||
177 | new System.Drawing.Rectangle(bBitmap.Width / 2, 0, bBitmap.Width, bBitmap.Height), | ||
178 | new System.Drawing.Rectangle(0, 0, bBitmap.Width, bBitmap.Height), | ||
179 | System.Drawing.GraphicsUnit.Pixel); | ||
180 | |||
181 | grPhoto = System.Drawing.Graphics.FromImage(tile_LOD); | ||
182 | //grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; | ||
183 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear; | ||
184 | |||
185 | grPhoto.DrawImage(tile, | ||
186 | new System.Drawing.Rectangle(0, 0, tile_LOD.Width, tile_LOD.Height), | ||
187 | new System.Drawing.Rectangle(0, 0, tile.Width, tile.Height), | ||
188 | System.Drawing.GraphicsUnit.Pixel); | ||
189 | |||
190 | grPhoto = System.Drawing.Graphics.FromImage(bLOD); | ||
191 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; | ||
192 | |||
193 | grPhoto.DrawImage(tile_LOD, | ||
194 | new System.Drawing.Rectangle(0, 0, bLOD.Width, bLOD.Height), | ||
195 | new System.Drawing.Rectangle(tile_LOD.Width / 4, 0, tile_LOD.Width / 2, tile_LOD.Height), | ||
196 | System.Drawing.GraphicsUnit.Pixel); | ||
197 | |||
198 | grPhoto.Dispose(); | ||
199 | tile_LOD.Dispose(); | ||
200 | tile.Dispose(); | ||
201 | } | ||
202 | 126 | ||
203 | } | 127 | r1 += c1.R; |
204 | 128 | g1 += c1.G; | |
205 | public void clearStuff() | 129 | b1 += c1.B; |
206 | { | ||
207 | this.triangles.Clear(); | ||
208 | this.vertices.Clear(); | ||
209 | //normals = new float[0]; | ||
210 | } | ||
211 | |||
212 | public void processSculptTexture() | ||
213 | { | ||
214 | int x_max = Math.Min(Scale, bBitmap.Width); | ||
215 | int y_max = Math.Min(Scale, bBitmap.Height); | ||
216 | 130 | ||
217 | int COLUMNS = x_max + 1; | 131 | r2 += c2.R; |
132 | g2 += c2.G; | ||
133 | b2 += c2.B; | ||
134 | } | ||
218 | 135 | ||
219 | Vertex[] sVertices = new Vertex[COLUMNS * y_max]; | 136 | Color newC1 = Color.FromArgb(r1 / width, g1 / width, b1 / width); |
220 | //float[] indices = new float[COLUMNS * (y_max - 1) * 6]; | 137 | Color newC2 = Color.FromArgb(r2 / width, g2 / width, b2 / width); |
221 | 138 | ||
222 | for (int y = 0; y < y_max; y++) | 139 | for (imageX = 0; imageX < width; imageX++) |
223 | { | ||
224 | for (int x = 0; x < x_max; x++) | ||
225 | { | 140 | { |
226 | // Create the vertex | 141 | bitmap.SetPixel(imageX, 0, newC1); |
227 | Vertex v1 = new Vertex(0,0,0); | 142 | bitmap.SetPixel(imageX, lastRow, newC2); |
143 | } | ||
144 | } | ||
228 | 145 | ||
229 | // Create a vertex position from the RGB channels in the current pixel | ||
230 | // int ypos = y * bLOD.Width; | ||
231 | 146 | ||
147 | int pixelsAcross = sculptType == SculptType.plane ? width : width + 1; | ||
148 | int pixelsDown = sculptType == SculptType.sphere || sculptType == SculptType.cylinder ? height + 1 : height; | ||
232 | 149 | ||
233 | if (y == 0) | 150 | for (imageY = 0; imageY < pixelsDown; imageY++) |
234 | { | 151 | { |
235 | v1 = northpole; | 152 | int rowOffset = imageY * width; |
236 | } | 153 | |
237 | else if (y == y_max - 1) | 154 | for (imageX = 0; imageX < pixelsAcross; imageX++) |
155 | { | ||
156 | /* | ||
157 | * p1-----p2 | ||
158 | * | \ f2 | | ||
159 | * | \ | | ||
160 | * | f1 \| | ||
161 | * p3-----p4 | ||
162 | */ | ||
163 | |||
164 | if (imageX < width) | ||
238 | { | 165 | { |
239 | v1 = southpole; | 166 | p4 = rowOffset + imageX; |
167 | p3 = p4 - 1; | ||
240 | } | 168 | } |
241 | else | 169 | else |
242 | { | 170 | { |
243 | v1 = ColorToVertex(GetPixel(x, y)); | 171 | p4 = rowOffset; // wrap around to beginning |
172 | p3 = rowOffset + imageX - 1; | ||
244 | } | 173 | } |
245 | 174 | ||
246 | // Add the vertex for use later | 175 | p2 = p4 - width; |
247 | if (!vertices.Contains(v1)) | 176 | p1 = p3 - width; |
248 | Add(v1); | ||
249 | 177 | ||
250 | sVertices[y * COLUMNS + x] = v1; | 178 | color = bitmap.GetPixel(imageX == width ? 0 : imageX, imageY == height ? height - 1 : imageY); |
251 | //System.Console.WriteLine("adding: " + v1.ToString()); | ||
252 | } | ||
253 | //Vertex tempVertex = vertices[y * COLUMNS]; | ||
254 | // sVertices[y * COLUMNS + x_max] = tempVertex; | ||
255 | } | ||
256 | 179 | ||
257 | // Create the Triangles | 180 | x = (color.R - 128) * pixScale; |
258 | //int i = 0; | 181 | y = (color.G - 128) * pixScale; |
182 | z = (color.B - 128) * pixScale; | ||
259 | 183 | ||
260 | for (int y = 0; y < y_max - 1; y++) | 184 | Coord c = new Coord(x, y, z); |
261 | { | 185 | this.coords.Add(c); |
262 | int x; | 186 | if (viewerMode) |
263 | |||
264 | for (x = 0; x < x_max; x++) | ||
265 | { | ||
266 | Vertex vt11 = sVertices[(y * COLUMNS + x)]; | ||
267 | Vertex vt12 = sVertices[(y * COLUMNS + (x + 1))]; | ||
268 | Vertex vt13 = sVertices[((y + 1) * COLUMNS + (x + 1))]; | ||
269 | if (vt11 != null && vt12 != null && vt13 != null) | ||
270 | { | 187 | { |
271 | if (vt11 != vt12 && vt11 != vt13 && vt12 != vt13) | 188 | this.normals.Add(new Coord()); |
272 | { | 189 | this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY)); |
273 | Triangle tri1 = new Triangle(vt11, vt12, vt13); | ||
274 | //indices[i++] = (ushort)(y * COLUMNS + x); | ||
275 | //indices[i++] = (ushort)(y * COLUMNS + (x + 1)); | ||
276 | //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); | ||
277 | Add(tri1); | ||
278 | } | ||
279 | } | 190 | } |
280 | 191 | ||
281 | Vertex vt21 = sVertices[(y * COLUMNS + x)]; | 192 | if (imageY > 0 && imageX > 0) |
282 | Vertex vt22 = sVertices[((y + 1) * COLUMNS + (x + 1))]; | ||
283 | Vertex vt23 = sVertices[((y + 1) * COLUMNS + x)]; | ||
284 | if (vt21 != null && vt22 != null && vt23 != null) | ||
285 | { | 193 | { |
286 | if (vt21.Equals(vt22, 0.022f) || vt21.Equals(vt23, 0.022f) || vt22.Equals(vt23, 0.022f)) | 194 | Face f1, f2; |
195 | |||
196 | if (viewerMode) | ||
287 | { | 197 | { |
198 | f1 = new Face(p1, p3, p4, p1, p3, p4); | ||
199 | f1.uv1 = p1; | ||
200 | f1.uv2 = p3; | ||
201 | f1.uv3 = p4; | ||
202 | |||
203 | f2 = new Face(p1, p4, p2, p1, p4, p2); | ||
204 | f2.uv1 = p1; | ||
205 | f2.uv2 = p4; | ||
206 | f2.uv3 = p2; | ||
288 | } | 207 | } |
289 | else | 208 | else |
290 | { | 209 | { |
291 | Triangle tri2 = new Triangle(vt21, vt22, vt23); | 210 | f1 = new Face(p1, p3, p4); |
292 | //indices[i++] = (ushort)(y * COLUMNS + x); | 211 | f2 = new Face(p1, p4, p2); |
293 | //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); | ||
294 | //indices[i++] = (ushort)((y + 1) * COLUMNS + x); | ||
295 | Add(tri2); | ||
296 | } | 212 | } |
213 | |||
214 | this.faces.Add(f1); | ||
215 | this.faces.Add(f2); | ||
297 | } | 216 | } |
217 | } | ||
218 | } | ||
219 | |||
220 | if (scaleSourceImage) | ||
221 | bitmap.Dispose(); | ||
222 | |||
223 | if (viewerMode) | ||
224 | { // compute vertex normals by summing all the surface normals of all the triangles sharing | ||
225 | // each vertex and then normalizing | ||
226 | int numFaces = this.faces.Count; | ||
227 | for (int i = 0; i < numFaces; i++) | ||
228 | { | ||
229 | Face face = this.faces[i]; | ||
230 | Coord surfaceNormal = face.SurfaceNormal(this.coords); | ||
231 | this.normals[face.v1] += surfaceNormal; | ||
232 | this.normals[face.v2] += surfaceNormal; | ||
233 | this.normals[face.v3] += surfaceNormal; | ||
234 | } | ||
298 | 235 | ||
236 | int numCoords = this.coords.Count; | ||
237 | for (int i = 0; i < numCoords; i++) | ||
238 | this.coords[i].Normalize(); | ||
239 | |||
240 | if (sculptType != SculptType.plane) | ||
241 | { // blend the vertex normals at the cylinder seam | ||
242 | pixelsAcross = width + 1; | ||
243 | for (imageY = 0; imageY < height; imageY++) | ||
244 | { | ||
245 | int rowOffset = imageY * pixelsAcross; | ||
246 | |||
247 | this.normals[rowOffset] = this.normals[rowOffset + width - 1] = (this.normals[rowOffset] + this.normals[rowOffset + width - 1]).Normalize(); | ||
248 | } | ||
299 | } | 249 | } |
300 | //Vertex vt31 = sVertices[(y * x_max + x)]; | ||
301 | //Vertex vt32 = sVertices[(y * x_max + 0)]; | ||
302 | //Vertex vt33 = sVertices[((y + 1) * x_max + 0)]; | ||
303 | //if (vt31 != null && vt32 != null && vt33 != null) | ||
304 | //{ | ||
305 | //if (vt31.Equals(vt32, 0.022f) || vt31.Equals(vt33, 0.022f) || vt32.Equals(vt33, 0.022f)) | ||
306 | //{ | ||
307 | //} | ||
308 | //else | ||
309 | //{ | ||
310 | //Triangle tri3 = new Triangle(vt31, vt32, vt33); | ||
311 | // Wrap the last cell in the row around | ||
312 | //indices[i++] = (ushort)(y * x_max + x); //a | ||
313 | //indices[i++] = (ushort)(y * x_max + 0); //b | ||
314 | //indices[i++] = (ushort)((y + 1) * x_max + 0); //c | ||
315 | //Add(tri3); | ||
316 | // } | ||
317 | //} | ||
318 | |||
319 | //Vertex vt41 = sVertices[(y * x_max + x)]; | ||
320 | //Vertex vt42 = sVertices[((y + 1) * x_max + 0)]; | ||
321 | //Vertex vt43 = sVertices[((y + 1) * x_max + x)]; | ||
322 | //if (vt41 != null && vt42 != null && vt43 != null) | ||
323 | //{ | ||
324 | //if (vt41.Equals(vt42, 0.022f) || vt31.Equals(vt43, 0.022f) || vt32.Equals(vt43, 0.022f)) | ||
325 | //{ | ||
326 | //} | ||
327 | // else | ||
328 | // { | ||
329 | //Triangle tri4 = new Triangle(vt41, vt42, vt43); | ||
330 | //indices[i++] = (ushort)(y * x_max + x); //a | ||
331 | //indices[i++] = (ushort)((y + 1) * x_max + 0); //b | ||
332 | //indices[i++] = (ushort)((y + 1) * x_max + x); //c | ||
333 | //Add(tri4); | ||
334 | //} | ||
335 | //} | ||
336 | 250 | ||
251 | foreach (Face face in this.faces) | ||
252 | { | ||
253 | ViewerFace vf = new ViewerFace(0); | ||
254 | vf.v1 = this.coords[face.v1]; | ||
255 | vf.v2 = this.coords[face.v2]; | ||
256 | vf.v3 = this.coords[face.v3]; | ||
257 | |||
258 | vf.n1 = this.normals[face.n1]; | ||
259 | vf.n2 = this.normals[face.n2]; | ||
260 | vf.n3 = this.normals[face.n3]; | ||
261 | |||
262 | vf.uv1 = this.uvs[face.uv1]; | ||
263 | vf.uv2 = this.uvs[face.uv2]; | ||
264 | vf.uv3 = this.uvs[face.uv3]; | ||
265 | |||
266 | this.viewerFaces.Add(vf); | ||
267 | } | ||
337 | } | 268 | } |
338 | } | 269 | } |
270 | |||
271 | public void AddRot(Quat q) | ||
272 | { | ||
273 | int i; | ||
274 | int numVerts = this.coords.Count; | ||
275 | |||
276 | for (i = 0; i < numVerts; i++) | ||
277 | this.coords[i] *= q; | ||
278 | |||
279 | if (this.viewerFaces != null) | ||
280 | { | ||
281 | int numViewerFaces = this.viewerFaces.Count; | ||
282 | |||
283 | for (i = 0; i < numViewerFaces; i++) | ||
284 | { | ||
285 | ViewerFace v = this.viewerFaces[i]; | ||
286 | v.v1 *= q; | ||
287 | v.v2 *= q; | ||
288 | v.v3 *= q; | ||
289 | |||
290 | v.n1 *= q; | ||
291 | v.n2 *= q; | ||
292 | v.n3 *= q; | ||
293 | |||
294 | this.viewerFaces[i] = v; | ||
295 | } | ||
296 | } | ||
297 | } | ||
298 | |||
299 | public void Scale(float x, float y, float z) | ||
300 | { | ||
301 | int i; | ||
302 | int numVerts = this.coords.Count; | ||
303 | //Coord vert; | ||
304 | |||
305 | Coord m = new Coord(x, y, z); | ||
306 | for (i = 0; i < numVerts; i++) | ||
307 | this.coords[i] *= m; | ||
308 | |||
309 | if (this.viewerFaces != null) | ||
310 | { | ||
311 | int numViewerFaces = this.viewerFaces.Count; | ||
312 | for (i = 0; i < numViewerFaces; i++) | ||
313 | { | ||
314 | ViewerFace v = this.viewerFaces[i]; | ||
315 | v.v1 *= m; | ||
316 | v.v2 *= m; | ||
317 | v.v3 *= m; | ||
318 | this.viewerFaces[i] = v; | ||
319 | } | ||
320 | } | ||
321 | } | ||
322 | |||
323 | public void DumpRaw(String path, String name, String title) | ||
324 | { | ||
325 | if (path == null) | ||
326 | return; | ||
327 | String fileName = name + "_" + title + ".raw"; | ||
328 | String completePath = Path.Combine(path, fileName); | ||
329 | StreamWriter sw = new StreamWriter(completePath); | ||
330 | |||
331 | for (int i = 0; i < this.faces.Count; i++) | ||
332 | { | ||
333 | string s = this.coords[this.faces[i].v1].ToString(); | ||
334 | s += " " + this.coords[this.faces[i].v2].ToString(); | ||
335 | s += " " + this.coords[this.faces[i].v3].ToString(); | ||
336 | |||
337 | sw.WriteLine(s); | ||
338 | } | ||
339 | |||
340 | sw.Close(); | ||
341 | } | ||
339 | } | 342 | } |
340 | } | 343 | } |