diff options
author | Dahlia Trimble | 2008-11-29 11:02:14 +0000 |
---|---|---|
committer | Dahlia Trimble | 2008-11-29 11:02:14 +0000 |
commit | fdd238833163eb947986bfcdd09da82f6949a5f2 (patch) | |
tree | 6b90177758405f6106f4f5d4d75e3b98bf08053c /OpenSim/Region/Physics/Meshing/SculptMesh.cs | |
parent | Comment the ScriptSponsor and restore the indefinite lifetime for (diff) | |
download | opensim-SC-fdd238833163eb947986bfcdd09da82f6949a5f2.zip opensim-SC-fdd238833163eb947986bfcdd09da82f6949a5f2.tar.gz opensim-SC-fdd238833163eb947986bfcdd09da82f6949a5f2.tar.bz2 opensim-SC-fdd238833163eb947986bfcdd09da82f6949a5f2.tar.xz |
Update meshing code to sync with current PrimMesher.cs on forge.
Migrate sculpt meshing code to primMesher version. This should result in more accurate physical sculpted prim proxies.
Remove much obsolete code from Region/Physics/Meshing
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 | } |