opensim-development – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | eva | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ |
||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
||
4 | * |
||
5 | * Redistribution and use in source and binary forms, with or without |
||
6 | * modification, are permitted provided that the following conditions are met: |
||
7 | * * Redistributions of source code must retain the above copyright |
||
8 | * notice, this list of conditions and the following disclaimer. |
||
9 | * * Redistributions in binary form must reproduce the above copyright |
||
10 | * notice, this list of conditions and the following disclaimer in the |
||
11 | * documentation and/or other materials provided with the distribution. |
||
12 | * * Neither the name of the OpenSimulator Project nor the |
||
13 | * names of its contributors may be used to endorse or promote products |
||
14 | * derived from this software without specific prior written permission. |
||
15 | * |
||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
26 | */ |
||
27 | |||
28 | using System; |
||
29 | using System.Collections.Generic; |
||
30 | using System.Drawing; |
||
31 | using System.Reflection; |
||
32 | using log4net; |
||
33 | using Mono.Addins; |
||
34 | using Nini.Config; |
||
35 | using OpenMetaverse; |
||
36 | using OpenMetaverse.Imaging; |
||
37 | using OpenSim.Framework; |
||
38 | using OpenSim.Region.Framework.Interfaces; |
||
39 | using OpenSim.Region.Framework.Scenes; |
||
40 | |||
41 | namespace OpenSim.Region.CoreModules.World.LegacyMap |
||
42 | { |
||
43 | public enum DrawRoutine |
||
44 | { |
||
45 | Rectangle, |
||
46 | Polygon, |
||
47 | Ellipse |
||
48 | } |
||
49 | |||
50 | public struct face |
||
51 | { |
||
52 | public Point[] pts; |
||
53 | } |
||
54 | |||
55 | public struct DrawStruct |
||
56 | { |
||
57 | public DrawRoutine dr; |
||
58 | // public Rectangle rect; |
||
59 | public SolidBrush brush; |
||
60 | public face[] trns; |
||
61 | } |
||
62 | |||
63 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MapImageModule")] |
||
64 | public class MapImageModule : IMapImageGenerator, INonSharedRegionModule |
||
65 | { |
||
66 | private static readonly ILog m_log = |
||
67 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
||
68 | |||
69 | private Scene m_scene; |
||
70 | private IConfigSource m_config; |
||
71 | private IMapTileTerrainRenderer terrainRenderer; |
||
72 | private bool m_Enabled = false; |
||
73 | |||
74 | #region IMapImageGenerator Members |
||
75 | |||
76 | public Bitmap CreateMapTile() |
||
77 | { |
||
78 | bool drawPrimVolume = true; |
||
79 | bool textureTerrain = false; |
||
80 | bool generateMaptiles = true; |
||
81 | Bitmap mapbmp; |
||
82 | |||
83 | string[] configSections = new string[] { "Map", "Startup" }; |
||
84 | |||
85 | drawPrimVolume |
||
86 | = Util.GetConfigVarFromSections<bool>(m_config, "DrawPrimOnMapTile", configSections, drawPrimVolume); |
||
87 | textureTerrain |
||
88 | = Util.GetConfigVarFromSections<bool>(m_config, "TextureOnMapTile", configSections, textureTerrain); |
||
89 | generateMaptiles |
||
90 | = Util.GetConfigVarFromSections<bool>(m_config, "GenerateMaptiles", configSections, generateMaptiles); |
||
91 | |||
92 | if (generateMaptiles) |
||
93 | { |
||
94 | if (textureTerrain) |
||
95 | { |
||
96 | terrainRenderer = new TexturedMapTileRenderer(); |
||
97 | } |
||
98 | else |
||
99 | { |
||
100 | terrainRenderer = new ShadedMapTileRenderer(); |
||
101 | } |
||
102 | |||
103 | terrainRenderer.Initialise(m_scene, m_config); |
||
104 | |||
105 | mapbmp = new Bitmap((int)m_scene.Heightmap.Width, (int)m_scene.Heightmap.Height, |
||
106 | System.Drawing.Imaging.PixelFormat.Format24bppRgb); |
||
107 | //long t = System.Environment.TickCount; |
||
108 | //for (int i = 0; i < 10; ++i) { |
||
109 | terrainRenderer.TerrainToBitmap(mapbmp); |
||
110 | //} |
||
111 | //t = System.Environment.TickCount - t; |
||
112 | //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t); |
||
113 | |||
114 | if (drawPrimVolume) |
||
115 | { |
||
116 | DrawObjectVolume(m_scene, mapbmp); |
||
117 | } |
||
118 | } |
||
119 | else |
||
120 | { |
||
121 | mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); |
||
122 | } |
||
123 | |||
124 | return mapbmp; |
||
125 | } |
||
126 | |||
127 | public byte[] WriteJpeg2000Image() |
||
128 | { |
||
129 | try |
||
130 | { |
||
131 | using (Bitmap mapbmp = CreateMapTile()) |
||
132 | { |
||
133 | if (mapbmp != null) |
||
134 | return OpenJPEG.EncodeFromImage(mapbmp, true); |
||
135 | } |
||
136 | } |
||
137 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke |
||
138 | { |
||
139 | m_log.Error("Failed generating terrain map: " + e); |
||
140 | } |
||
141 | |||
142 | return null; |
||
143 | } |
||
144 | |||
145 | #endregion |
||
146 | |||
147 | #region Region Module interface |
||
148 | |||
149 | public void Initialise(IConfigSource source) |
||
150 | { |
||
151 | m_config = source; |
||
152 | |||
153 | if (Util.GetConfigVarFromSections<string>( |
||
154 | m_config, "MapImageModule", new string[] { "Startup", "Map" }, "MapImageModule") != "MapImageModule") |
||
155 | return; |
||
156 | |||
157 | m_Enabled = true; |
||
158 | } |
||
159 | |||
160 | public void AddRegion(Scene scene) |
||
161 | { |
||
162 | if (!m_Enabled) |
||
163 | return; |
||
164 | |||
165 | m_scene = scene; |
||
166 | |||
167 | m_scene.RegisterModuleInterface<IMapImageGenerator>(this); |
||
168 | } |
||
169 | |||
170 | public void RegionLoaded(Scene scene) |
||
171 | { |
||
172 | } |
||
173 | |||
174 | public void RemoveRegion(Scene scene) |
||
175 | { |
||
176 | } |
||
177 | |||
178 | public void Close() |
||
179 | { |
||
180 | } |
||
181 | |||
182 | public string Name |
||
183 | { |
||
184 | get { return "MapImageModule"; } |
||
185 | } |
||
186 | |||
187 | public Type ReplaceableInterface |
||
188 | { |
||
189 | get { return null; } |
||
190 | } |
||
191 | |||
192 | #endregion |
||
193 | |||
194 | // TODO: unused: |
||
195 | // private void ShadeBuildings(Bitmap map) |
||
196 | // { |
||
197 | // lock (map) |
||
198 | // { |
||
199 | // lock (m_scene.Entities) |
||
200 | // { |
||
201 | // foreach (EntityBase entity in m_scene.Entities.Values) |
||
202 | // { |
||
203 | // if (entity is SceneObjectGroup) |
||
204 | // { |
||
205 | // SceneObjectGroup sog = (SceneObjectGroup) entity; |
||
206 | // |
||
207 | // foreach (SceneObjectPart primitive in sog.Children.Values) |
||
208 | // { |
||
209 | // int x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2)); |
||
210 | // int y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2)); |
||
211 | // int w = (int) primitive.Scale.X; |
||
212 | // int h = (int) primitive.Scale.Y; |
||
213 | // |
||
214 | // int dx; |
||
215 | // for (dx = x; dx < x + w; dx++) |
||
216 | // { |
||
217 | // int dy; |
||
218 | // for (dy = y; dy < y + h; dy++) |
||
219 | // { |
||
220 | // if (x < 0 || y < 0) |
||
221 | // continue; |
||
222 | // if (x >= map.Width || y >= map.Height) |
||
223 | // continue; |
||
224 | // |
||
225 | // map.SetPixel(dx, dy, Color.DarkGray); |
||
226 | // } |
||
227 | // } |
||
228 | // } |
||
229 | // } |
||
230 | // } |
||
231 | // } |
||
232 | // } |
||
233 | // } |
||
234 | |||
235 | private Bitmap FetchTexture(UUID id) |
||
236 | { |
||
237 | AssetBase asset = m_scene.AssetService.Get(id.ToString()); |
||
238 | |||
239 | if (asset != null) |
||
240 | { |
||
241 | m_log.DebugFormat("[MAPTILE]: Static map image texture {0} found for {1}", id, m_scene.Name); |
||
242 | } |
||
243 | else |
||
244 | { |
||
245 | m_log.WarnFormat("[MAPTILE]: Static map image texture {0} not found for {1}", id, m_scene.Name); |
||
246 | return null; |
||
247 | } |
||
248 | |||
249 | ManagedImage managedImage; |
||
250 | Image image; |
||
251 | |||
252 | try |
||
253 | { |
||
254 | if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image)) |
||
255 | return new Bitmap(image); |
||
256 | else |
||
257 | return null; |
||
258 | } |
||
259 | catch (DllNotFoundException) |
||
260 | { |
||
261 | m_log.ErrorFormat("[MAPTILE]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id); |
||
262 | |||
263 | } |
||
264 | catch (IndexOutOfRangeException) |
||
265 | { |
||
266 | m_log.ErrorFormat("[MAPTILE]: OpenJpeg was unable to decode this. Asset Data is empty for {0}", id); |
||
267 | |||
268 | } |
||
269 | catch (Exception) |
||
270 | { |
||
271 | m_log.ErrorFormat("[MAPTILE]: OpenJpeg was unable to decode this. Asset Data is empty for {0}", id); |
||
272 | |||
273 | } |
||
274 | return null; |
||
275 | |||
276 | } |
||
277 | |||
278 | private Bitmap DrawObjectVolume(Scene whichScene, Bitmap mapbmp) |
||
279 | { |
||
280 | int tc = 0; |
||
281 | ITerrainChannel hm = whichScene.Heightmap; |
||
282 | tc = Environment.TickCount; |
||
283 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); |
||
284 | EntityBase[] objs = whichScene.GetEntities(); |
||
285 | List<float> z_sortheights = new List<float>(); |
||
286 | List<uint> z_localIDs = new List<uint>(); |
||
287 | Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); |
||
288 | |||
289 | try |
||
290 | { |
||
291 | lock (objs) |
||
292 | { |
||
293 | foreach (EntityBase obj in objs) |
||
294 | { |
||
295 | // Only draw the contents of SceneObjectGroup |
||
296 | if (obj is SceneObjectGroup) |
||
297 | { |
||
298 | SceneObjectGroup mapdot = (SceneObjectGroup)obj; |
||
299 | Color mapdotspot = Color.Gray; // Default color when prim color is white |
||
300 | // Loop over prim in group |
||
301 | foreach (SceneObjectPart part in mapdot.Parts) |
||
302 | { |
||
303 | if (part == null) |
||
304 | continue; |
||
305 | |||
306 | // Draw if the object is at least 1 meter wide in any direction |
||
307 | if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) |
||
308 | { |
||
309 | // Try to get the RGBA of the default texture entry.. |
||
310 | // |
||
311 | try |
||
312 | { |
||
313 | // get the null checks out of the way |
||
314 | // skip the ones that break |
||
315 | if (part == null) |
||
316 | continue; |
||
317 | |||
318 | if (part.Shape == null) |
||
319 | continue; |
||
320 | |||
321 | if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) |
||
322 | continue; // eliminates trees from this since we don't really have a good tree representation |
||
323 | // if you want tree blocks on the map comment the above line and uncomment the below line |
||
324 | //mapdotspot = Color.PaleGreen; |
||
325 | |||
326 | Primitive.TextureEntry textureEntry = part.Shape.Textures; |
||
327 | |||
328 | if (textureEntry == null || textureEntry.DefaultTexture == null) |
||
329 | continue; |
||
330 | |||
331 | Color4 texcolor = textureEntry.DefaultTexture.RGBA; |
||
332 | |||
333 | // Not sure why some of these are null, oh well. |
||
334 | |||
335 | int colorr = 255 - (int)(texcolor.R * 255f); |
||
336 | int colorg = 255 - (int)(texcolor.G * 255f); |
||
337 | int colorb = 255 - (int)(texcolor.B * 255f); |
||
338 | |||
339 | if (!(colorr == 255 && colorg == 255 && colorb == 255)) |
||
340 | { |
||
341 | //Try to set the map spot color |
||
342 | try |
||
343 | { |
||
344 | // If the color gets goofy somehow, skip it *shakes fist at Color4 |
||
345 | mapdotspot = Color.FromArgb(colorr, colorg, colorb); |
||
346 | } |
||
347 | catch (ArgumentException) |
||
348 | { |
||
349 | } |
||
350 | } |
||
351 | } |
||
352 | catch (IndexOutOfRangeException) |
||
353 | { |
||
354 | // Windows Array |
||
355 | } |
||
356 | catch (ArgumentOutOfRangeException) |
||
357 | { |
||
358 | // Mono Array |
||
359 | } |
||
360 | |||
361 | Vector3 pos = part.GetWorldPosition(); |
||
362 | |||
363 | // skip prim outside of retion |
||
364 | if (!m_scene.PositionIsInCurrentRegion(pos)) |
||
365 | continue; |
||
366 | |||
367 | // skip prim in non-finite position |
||
368 | if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || |
||
369 | Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) |
||
370 | continue; |
||
371 | |||
372 | // Figure out if object is under 256m above the height of the terrain |
||
373 | bool isBelow256AboveTerrain = false; |
||
374 | |||
375 | try |
||
376 | { |
||
377 | isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); |
||
378 | } |
||
379 | catch (Exception) |
||
380 | { |
||
381 | } |
||
382 | |||
383 | if (isBelow256AboveTerrain) |
||
384 | { |
||
385 | // Translate scale by rotation so scale is represented properly when object is rotated |
||
386 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); |
||
387 | Vector3 scale = new Vector3(); |
||
388 | Vector3 tScale = new Vector3(); |
||
389 | Vector3 axPos = new Vector3(pos.X, pos.Y, pos.Z); |
||
390 | |||
391 | Quaternion llrot = part.GetWorldRotation(); |
||
392 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); |
||
393 | scale = lscale * rot; |
||
394 | |||
395 | // negative scales don't work in this situation |
||
396 | scale.X = Math.Abs(scale.X); |
||
397 | scale.Y = Math.Abs(scale.Y); |
||
398 | scale.Z = Math.Abs(scale.Z); |
||
399 | |||
400 | // This scaling isn't very accurate and doesn't take into account the face rotation :P |
||
401 | int mapdrawstartX = (int)(pos.X - scale.X); |
||
402 | int mapdrawstartY = (int)(pos.Y - scale.Y); |
||
403 | int mapdrawendX = (int)(pos.X + scale.X); |
||
404 | int mapdrawendY = (int)(pos.Y + scale.Y); |
||
405 | |||
406 | // If object is beyond the edge of the map, don't draw it to avoid errors |
||
407 | if (mapdrawstartX < 0 |
||
408 | || mapdrawstartX > (hm.Width - 1) |
||
409 | || mapdrawendX < 0 |
||
410 | || mapdrawendX > (hm.Width - 1) |
||
411 | || mapdrawstartY < 0 |
||
412 | || mapdrawstartY > (hm.Height - 1) |
||
413 | || mapdrawendY < 0 |
||
414 | || mapdrawendY > (hm.Height - 1)) |
||
415 | continue; |
||
416 | |||
417 | #region obb face reconstruction part duex |
||
418 | Vector3[] vertexes = new Vector3[8]; |
||
419 | |||
420 | // float[] distance = new float[6]; |
||
421 | Vector3[] FaceA = new Vector3[6]; // vertex A for Facei |
||
422 | Vector3[] FaceB = new Vector3[6]; // vertex B for Facei |
||
423 | Vector3[] FaceC = new Vector3[6]; // vertex C for Facei |
||
424 | Vector3[] FaceD = new Vector3[6]; // vertex D for Facei |
||
425 | |||
426 | tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); |
||
427 | scale = ((tScale * rot)); |
||
428 | vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
429 | // vertexes[0].x = pos.X + vertexes[0].x; |
||
430 | //vertexes[0].y = pos.Y + vertexes[0].y; |
||
431 | //vertexes[0].z = pos.Z + vertexes[0].z; |
||
432 | |||
433 | FaceA[0] = vertexes[0]; |
||
434 | FaceB[3] = vertexes[0]; |
||
435 | FaceA[4] = vertexes[0]; |
||
436 | |||
437 | tScale = lscale; |
||
438 | scale = ((tScale * rot)); |
||
439 | vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
440 | |||
441 | // vertexes[1].x = pos.X + vertexes[1].x; |
||
442 | // vertexes[1].y = pos.Y + vertexes[1].y; |
||
443 | //vertexes[1].z = pos.Z + vertexes[1].z; |
||
444 | |||
445 | FaceB[0] = vertexes[1]; |
||
446 | FaceA[1] = vertexes[1]; |
||
447 | FaceC[4] = vertexes[1]; |
||
448 | |||
449 | tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); |
||
450 | scale = ((tScale * rot)); |
||
451 | |||
452 | vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
453 | |||
454 | //vertexes[2].x = pos.X + vertexes[2].x; |
||
455 | //vertexes[2].y = pos.Y + vertexes[2].y; |
||
456 | //vertexes[2].z = pos.Z + vertexes[2].z; |
||
457 | |||
458 | FaceC[0] = vertexes[2]; |
||
459 | FaceD[3] = vertexes[2]; |
||
460 | FaceC[5] = vertexes[2]; |
||
461 | |||
462 | tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); |
||
463 | scale = ((tScale * rot)); |
||
464 | vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
465 | |||
466 | //vertexes[3].x = pos.X + vertexes[3].x; |
||
467 | // vertexes[3].y = pos.Y + vertexes[3].y; |
||
468 | // vertexes[3].z = pos.Z + vertexes[3].z; |
||
469 | |||
470 | FaceD[0] = vertexes[3]; |
||
471 | FaceC[1] = vertexes[3]; |
||
472 | FaceA[5] = vertexes[3]; |
||
473 | |||
474 | tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); |
||
475 | scale = ((tScale * rot)); |
||
476 | vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
477 | |||
478 | // vertexes[4].x = pos.X + vertexes[4].x; |
||
479 | // vertexes[4].y = pos.Y + vertexes[4].y; |
||
480 | // vertexes[4].z = pos.Z + vertexes[4].z; |
||
481 | |||
482 | FaceB[1] = vertexes[4]; |
||
483 | FaceA[2] = vertexes[4]; |
||
484 | FaceD[4] = vertexes[4]; |
||
485 | |||
486 | tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); |
||
487 | scale = ((tScale * rot)); |
||
488 | vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
489 | |||
490 | // vertexes[5].x = pos.X + vertexes[5].x; |
||
491 | // vertexes[5].y = pos.Y + vertexes[5].y; |
||
492 | // vertexes[5].z = pos.Z + vertexes[5].z; |
||
493 | |||
494 | FaceD[1] = vertexes[5]; |
||
495 | FaceC[2] = vertexes[5]; |
||
496 | FaceB[5] = vertexes[5]; |
||
497 | |||
498 | tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); |
||
499 | scale = ((tScale * rot)); |
||
500 | vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
501 | |||
502 | // vertexes[6].x = pos.X + vertexes[6].x; |
||
503 | // vertexes[6].y = pos.Y + vertexes[6].y; |
||
504 | // vertexes[6].z = pos.Z + vertexes[6].z; |
||
505 | |||
506 | FaceB[2] = vertexes[6]; |
||
507 | FaceA[3] = vertexes[6]; |
||
508 | FaceB[4] = vertexes[6]; |
||
509 | |||
510 | tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); |
||
511 | scale = ((tScale * rot)); |
||
512 | vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
513 | |||
514 | // vertexes[7].x = pos.X + vertexes[7].x; |
||
515 | // vertexes[7].y = pos.Y + vertexes[7].y; |
||
516 | // vertexes[7].z = pos.Z + vertexes[7].z; |
||
517 | |||
518 | FaceD[2] = vertexes[7]; |
||
519 | FaceC[3] = vertexes[7]; |
||
520 | FaceD[5] = vertexes[7]; |
||
521 | #endregion |
||
522 | |||
523 | //int wy = 0; |
||
524 | |||
525 | //bool breakYN = false; // If we run into an error drawing, break out of the |
||
526 | // loop so we don't lag to death on error handling |
||
527 | DrawStruct ds = new DrawStruct(); |
||
528 | ds.brush = new SolidBrush(mapdotspot); |
||
529 | //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); |
||
530 | |||
531 | ds.trns = new face[FaceA.Length]; |
||
532 | |||
533 | for (int i = 0; i < FaceA.Length; i++) |
||
534 | { |
||
535 | Point[] working = new Point[5]; |
||
536 | working[0] = project(hm, FaceA[i], axPos); |
||
537 | working[1] = project(hm, FaceB[i], axPos); |
||
538 | working[2] = project(hm, FaceD[i], axPos); |
||
539 | working[3] = project(hm, FaceC[i], axPos); |
||
540 | working[4] = project(hm, FaceA[i], axPos); |
||
541 | |||
542 | face workingface = new face(); |
||
543 | workingface.pts = working; |
||
544 | |||
545 | ds.trns[i] = workingface; |
||
546 | } |
||
547 | |||
548 | z_sort.Add(part.LocalId, ds); |
||
549 | z_localIDs.Add(part.LocalId); |
||
550 | z_sortheights.Add(pos.Z); |
||
551 | |||
552 | // for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) |
||
553 | // { |
||
554 | // for (wy = mapdrawstartY; wy < mapdrawendY; wy++) |
||
555 | // { |
||
556 | // m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); |
||
557 | // try |
||
558 | // { |
||
559 | // // Remember, flip the y! |
||
560 | // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); |
||
561 | // } |
||
562 | // catch (ArgumentException) |
||
563 | // { |
||
564 | // breakYN = true; |
||
565 | // } |
||
566 | // } |
||
567 | // if (breakYN) |
||
568 | // break; |
||
569 | // } |
||
570 | // } |
||
571 | //} |
||
572 | } // Object is within 256m Z of terrain |
||
573 | } // object is at least a meter wide |
||
574 | } // loop over group children |
||
575 | } // entitybase is sceneobject group |
||
576 | } // foreach loop over entities |
||
577 | |||
578 | float[] sortedZHeights = z_sortheights.ToArray(); |
||
579 | uint[] sortedlocalIds = z_localIDs.ToArray(); |
||
580 | |||
581 | // Sort prim by Z position |
||
582 | Array.Sort(sortedZHeights, sortedlocalIds); |
||
583 | |||
584 | using (Graphics g = Graphics.FromImage(mapbmp)) |
||
585 | { |
||
586 | for (int s = 0; s < sortedZHeights.Length; s++) |
||
587 | { |
||
588 | if (z_sort.ContainsKey(sortedlocalIds[s])) |
||
589 | { |
||
590 | DrawStruct rectDrawStruct = z_sort[sortedlocalIds[s]]; |
||
591 | for (int r = 0; r < rectDrawStruct.trns.Length; r++) |
||
592 | { |
||
593 | g.FillPolygon(rectDrawStruct.brush,rectDrawStruct.trns[r].pts); |
||
594 | } |
||
595 | //g.FillRectangle(rectDrawStruct.brush , rectDrawStruct.rect); |
||
596 | } |
||
597 | } |
||
598 | } |
||
599 | } // lock entities objs |
||
600 | |||
601 | } |
||
602 | finally |
||
603 | { |
||
604 | foreach (DrawStruct ds in z_sort.Values) |
||
605 | ds.brush.Dispose(); |
||
606 | } |
||
607 | |||
608 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); |
||
609 | |||
610 | return mapbmp; |
||
611 | } |
||
612 | |||
613 | private Point project(ITerrainChannel hm, Vector3 point3d, Vector3 originpos) |
||
614 | { |
||
615 | Point returnpt = new Point(); |
||
616 | //originpos = point3d; |
||
617 | //int d = (int)(256f / 1.5f); |
||
618 | |||
619 | //Vector3 topos = new Vector3(0, 0, 0); |
||
620 | // float z = -point3d.z - topos.z; |
||
621 | |||
622 | returnpt.X = (int)point3d.X;//(int)((topos.x - point3d.x) / z * d); |
||
623 | returnpt.Y = (int)((hm.Width - 1) - point3d.Y);//(int)(255 - (((topos.y - point3d.y) / z * d))); |
||
624 | |||
625 | return returnpt; |
||
626 | } |
||
627 | |||
628 | public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) |
||
629 | { |
||
630 | return null; |
||
631 | } |
||
632 | } |
||
633 | } |