diff options
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/SculptMesh.cs')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/SculptMesh.cs | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs new file mode 100644 index 0000000..ff9964e --- /dev/null +++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs | |||
@@ -0,0 +1,231 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Drawing; | ||
4 | using System.Drawing.Imaging; | ||
5 | using System.Text; | ||
6 | using OpenJPEGNet; | ||
7 | using Image = System.Drawing.Image; | ||
8 | |||
9 | namespace OpenSim.Region.Physics.Meshing | ||
10 | { | ||
11 | public class SculptMesh : Mesh | ||
12 | { | ||
13 | Image idata = null; | ||
14 | Bitmap bLOD = null; | ||
15 | Bitmap bBitmap = null; | ||
16 | |||
17 | Vertex northpole = (Vertex)Vertex.Zero; | ||
18 | Vertex southpole = (Vertex)Vertex.Zero; | ||
19 | |||
20 | private int lod = 64; | ||
21 | private const float RANGE = 128.0f; | ||
22 | |||
23 | public SculptMesh(byte[] jpegData) | ||
24 | { | ||
25 | idata = OpenJPEG.DecodeToImage(jpegData); | ||
26 | if (idata != null) | ||
27 | bBitmap = new Bitmap(idata); | ||
28 | |||
29 | |||
30 | } | ||
31 | private Vertex ColorToVertex(Color input) | ||
32 | { | ||
33 | return new Vertex( | ||
34 | ((float)input.R - 128) / RANGE, | ||
35 | ((float)input.G - 128) / RANGE, | ||
36 | ((float)input.B - 128) / RANGE); | ||
37 | } | ||
38 | private void LoadPoles() | ||
39 | { | ||
40 | northpole = (Vertex)Vertex.Zero; | ||
41 | for (int x = 0; x < bBitmap.Width; x++) | ||
42 | { | ||
43 | northpole += ColorToVertex(GetPixel(0, 0)); | ||
44 | } | ||
45 | northpole /= bBitmap.Width; | ||
46 | |||
47 | southpole = (Vertex)Vertex.Zero; | ||
48 | for (int x = 0; x < bBitmap.Width; x++) | ||
49 | { | ||
50 | southpole += ColorToVertex(GetPixel(bBitmap.Height - 1, (bBitmap.Height - 1))); | ||
51 | } | ||
52 | southpole /= bBitmap.Width; | ||
53 | } | ||
54 | |||
55 | private Color GetPixel(int x, int y) | ||
56 | { | ||
57 | return bLOD.GetPixel(x, y); | ||
58 | } | ||
59 | |||
60 | public int LOD | ||
61 | { | ||
62 | get | ||
63 | { | ||
64 | return (int)Math.Log(Scale, 2); | ||
65 | } | ||
66 | set | ||
67 | { | ||
68 | int power = value; | ||
69 | if (power == 0) | ||
70 | power = 6; | ||
71 | if (power < 2) | ||
72 | power = 2; | ||
73 | if (power > 9) | ||
74 | power = 9; | ||
75 | int t = (int)Math.Pow(2, power); | ||
76 | if (t != Scale) | ||
77 | { | ||
78 | lod = t; | ||
79 | } | ||
80 | } | ||
81 | } | ||
82 | |||
83 | public int Scale | ||
84 | { | ||
85 | get | ||
86 | { | ||
87 | return lod; | ||
88 | } | ||
89 | } | ||
90 | private void DoLOD() | ||
91 | { | ||
92 | int x_max = Math.Min(Scale, bBitmap.Width); | ||
93 | int y_max = Math.Min(Scale, bBitmap.Height); | ||
94 | if (bBitmap.Width == x_max && bBitmap.Height == y_max) | ||
95 | bLOD = bBitmap; | ||
96 | |||
97 | else if (bLOD == null || x_max != bLOD.Width || y_max != bLOD.Height)//don't resize if you don't need to. | ||
98 | { | ||
99 | System.Drawing.Bitmap tile = new System.Drawing.Bitmap(bBitmap.Width * 2, bBitmap.Height, PixelFormat.Format24bppRgb); | ||
100 | System.Drawing.Bitmap tile_LOD = new System.Drawing.Bitmap(x_max * 2, y_max, PixelFormat.Format24bppRgb); | ||
101 | |||
102 | bLOD = new System.Drawing.Bitmap(x_max, y_max, PixelFormat.Format24bppRgb); | ||
103 | bLOD.SetResolution(bBitmap.HorizontalResolution, bBitmap.VerticalResolution); | ||
104 | |||
105 | System.Drawing.Graphics grPhoto = System.Drawing.Graphics.FromImage(tile); | ||
106 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; | ||
107 | |||
108 | grPhoto.DrawImage(bBitmap, | ||
109 | new System.Drawing.Rectangle(0, 0, bBitmap.Width / 2, bBitmap.Height), | ||
110 | new System.Drawing.Rectangle(bBitmap.Width / 2, 0, bBitmap.Width / 2, bBitmap.Height), | ||
111 | System.Drawing.GraphicsUnit.Pixel); | ||
112 | |||
113 | grPhoto.DrawImage(bBitmap, | ||
114 | new System.Drawing.Rectangle((3 * bBitmap.Width) / 2, 0, bBitmap.Width / 2, bBitmap.Height), | ||
115 | new System.Drawing.Rectangle(0, 0, bBitmap.Width / 2, bBitmap.Height), | ||
116 | System.Drawing.GraphicsUnit.Pixel); | ||
117 | |||
118 | grPhoto.DrawImage(bBitmap, | ||
119 | new System.Drawing.Rectangle(bBitmap.Width / 2, 0, bBitmap.Width, bBitmap.Height), | ||
120 | new System.Drawing.Rectangle(0, 0, bBitmap.Width, bBitmap.Height), | ||
121 | System.Drawing.GraphicsUnit.Pixel); | ||
122 | |||
123 | grPhoto = System.Drawing.Graphics.FromImage(tile_LOD); | ||
124 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; | ||
125 | |||
126 | grPhoto.DrawImage(tile, | ||
127 | new System.Drawing.Rectangle(0, 0, tile_LOD.Width, tile_LOD.Height), | ||
128 | new System.Drawing.Rectangle(0, 0, tile.Width, tile.Height), | ||
129 | System.Drawing.GraphicsUnit.Pixel); | ||
130 | |||
131 | grPhoto = System.Drawing.Graphics.FromImage(bLOD); | ||
132 | grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; | ||
133 | |||
134 | grPhoto.DrawImage(tile_LOD, | ||
135 | new System.Drawing.Rectangle(0, 0, bLOD.Width, bLOD.Height), | ||
136 | new System.Drawing.Rectangle(tile_LOD.Width / 4, 0, tile_LOD.Width / 2, tile_LOD.Height), | ||
137 | System.Drawing.GraphicsUnit.Pixel); | ||
138 | |||
139 | grPhoto.Dispose(); | ||
140 | tile_LOD.Dispose(); | ||
141 | tile.Dispose(); | ||
142 | } | ||
143 | |||
144 | } | ||
145 | public void clearStuff() | ||
146 | { | ||
147 | this.triangles.Clear(); | ||
148 | this.vertices.Clear(); | ||
149 | normals = new float[0]; | ||
150 | |||
151 | } | ||
152 | public void processSculptTexture() | ||
153 | { | ||
154 | int x_max = Math.Min(Scale, bBitmap.Width); | ||
155 | int y_max = Math.Min(Scale, bBitmap.Height); | ||
156 | |||
157 | int COLUMNS = x_max + 1; | ||
158 | |||
159 | Vertex[] sVertices = new Vertex[COLUMNS * y_max]; | ||
160 | float[] indices = new float[COLUMNS * (y_max - 1) * 6]; | ||
161 | |||
162 | for (int y = 0; y < y_max; y++) | ||
163 | { | ||
164 | for (int x = 0; x < x_max; x++) | ||
165 | { | ||
166 | // Create the vertex | ||
167 | Vertex v1 = new Vertex(0,0,0); | ||
168 | |||
169 | // Create a vertex position from the RGB channels in the current pixel | ||
170 | int ypos = y * bLOD.Width; | ||
171 | |||
172 | |||
173 | if (y == 0) | ||
174 | { | ||
175 | v1 = northpole; | ||
176 | } | ||
177 | else if (y == y_max - 1) | ||
178 | { | ||
179 | v1 = southpole; | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | v1 = ColorToVertex(GetPixel(x, y)); | ||
184 | } | ||
185 | // Add the vertex for use later | ||
186 | Add(v1); | ||
187 | sVertices[y * COLUMNS + x] = v1; | ||
188 | } | ||
189 | Vertex tempVertex = vertices[y * COLUMNS]; | ||
190 | sVertices[y * COLUMNS + x_max] = tempVertex; | ||
191 | } | ||
192 | |||
193 | // Create the Triangles | ||
194 | int i = 0; | ||
195 | |||
196 | for (int y = 0; y < y_max - 1; y++) | ||
197 | { | ||
198 | int x; | ||
199 | |||
200 | for (x = 0; x < x_max; x++) | ||
201 | { | ||
202 | Triangle tri1 = new Triangle(sVertices[(y * COLUMNS + x)], sVertices[(y * COLUMNS + (x + 1))], | ||
203 | sVertices[((y + 1) * COLUMNS + (x + 1))]); | ||
204 | //indices[i++] = (ushort)(y * COLUMNS + x); | ||
205 | //indices[i++] = (ushort)(y * COLUMNS + (x + 1)); | ||
206 | //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); | ||
207 | Add(tri1); | ||
208 | Triangle tri2 = new Triangle(sVertices[(y * COLUMNS + x)],sVertices[((y + 1) * COLUMNS + (x + 1))], | ||
209 | sVertices[((y + 1) * COLUMNS + x)]); | ||
210 | |||
211 | Add(tri2); | ||
212 | //indices[i++] = (ushort)(y * COLUMNS + x); | ||
213 | //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); | ||
214 | //indices[i++] = (ushort)((y + 1) * COLUMNS + x); | ||
215 | } | ||
216 | Triangle tri3 = new Triangle(sVertices[(y * x_max + x)], sVertices[(y * x_max + 0)], sVertices[((y + 1) * x_max + 0)]); | ||
217 | Add(tri3); | ||
218 | // Wrap the last cell in the row around | ||
219 | //indices[i++] = (ushort)(y * x_max + x); //a | ||
220 | //indices[i++] = (ushort)(y * x_max + 0); //b | ||
221 | //indices[i++] = (ushort)((y + 1) * x_max + 0); //c | ||
222 | |||
223 | Triangle tri4 = new Triangle(sVertices[(y * x_max + x)], sVertices[((y + 1) * x_max + 0)], sVertices[((y + 1) * x_max + x)]); | ||
224 | Add(tri4); | ||
225 | //indices[i++] = (ushort)(y * x_max + x); //a | ||
226 | //indices[i++] = (ushort)((y + 1) * x_max + 0); //b | ||
227 | //indices[i++] = (ushort)((y + 1) * x_max + x); //c | ||
228 | } | ||
229 | } | ||
230 | } | ||
231 | } | ||