clockwerk-opensim – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 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 (String.IsNullOrEmpty(m_scene.RegionInfo.MaptileStaticFile)) |
||
95 | { |
||
96 | if (textureTerrain) |
||
97 | { |
||
98 | terrainRenderer = new TexturedMapTileRenderer(); |
||
99 | } |
||
100 | else |
||
101 | { |
||
102 | terrainRenderer = new ShadedMapTileRenderer(); |
||
103 | } |
||
104 | |||
105 | terrainRenderer.Initialise(m_scene, m_config); |
||
106 | |||
107 | mapbmp = new Bitmap((int)m_scene.Heightmap.Width, (int)m_scene.Heightmap.Height, |
||
108 | System.Drawing.Imaging.PixelFormat.Format24bppRgb); |
||
109 | //long t = System.Environment.TickCount; |
||
110 | //for (int i = 0; i < 10; ++i) { |
||
111 | terrainRenderer.TerrainToBitmap(mapbmp); |
||
112 | //} |
||
113 | //t = System.Environment.TickCount - t; |
||
114 | //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t); |
||
115 | |||
116 | if (drawPrimVolume) |
||
117 | { |
||
118 | DrawObjectVolume(m_scene, mapbmp); |
||
119 | } |
||
120 | } |
||
121 | else |
||
122 | { |
||
123 | try |
||
124 | { |
||
125 | mapbmp = new Bitmap(m_scene.RegionInfo.MaptileStaticFile); |
||
126 | } |
||
127 | catch (Exception) |
||
128 | { |
||
129 | m_log.ErrorFormat( |
||
130 | "[MAPTILE]: Failed to load Static map image texture file: {0} for {1}", |
||
131 | m_scene.RegionInfo.MaptileStaticFile, m_scene.Name); |
||
132 | //mapbmp = new Bitmap((int)m_scene.Heightmap.Width, (int)m_scene.Heightmap.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); |
||
133 | mapbmp = null; |
||
134 | } |
||
135 | |||
136 | if (mapbmp != null) |
||
137 | m_log.DebugFormat( |
||
138 | "[MAPTILE]: Static map image texture file {0} found for {1}", |
||
139 | m_scene.RegionInfo.MaptileStaticFile, m_scene.Name); |
||
140 | } |
||
141 | } |
||
142 | else |
||
143 | { |
||
144 | mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); |
||
145 | } |
||
146 | |||
147 | return mapbmp; |
||
148 | } |
||
149 | |||
150 | public byte[] WriteJpeg2000Image() |
||
151 | { |
||
152 | try |
||
153 | { |
||
154 | using (Bitmap mapbmp = CreateMapTile()) |
||
155 | { |
||
156 | if (mapbmp != null) |
||
157 | return OpenJPEG.EncodeFromImage(mapbmp, true); |
||
158 | } |
||
159 | } |
||
160 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke |
||
161 | { |
||
162 | m_log.Error("Failed generating terrain map: " + e); |
||
163 | } |
||
164 | |||
165 | return null; |
||
166 | } |
||
167 | |||
168 | #endregion |
||
169 | |||
170 | #region Region Module interface |
||
171 | |||
172 | public void Initialise(IConfigSource source) |
||
173 | { |
||
174 | m_config = source; |
||
175 | |||
176 | if (Util.GetConfigVarFromSections<string>( |
||
177 | m_config, "MapImageModule", new string[] { "Startup", "Map" }, "MapImageModule") != "MapImageModule") |
||
178 | return; |
||
179 | |||
180 | m_Enabled = true; |
||
181 | } |
||
182 | |||
183 | public void AddRegion(Scene scene) |
||
184 | { |
||
185 | if (!m_Enabled) |
||
186 | return; |
||
187 | |||
188 | m_scene = scene; |
||
189 | |||
190 | m_scene.RegisterModuleInterface<IMapImageGenerator>(this); |
||
191 | } |
||
192 | |||
193 | public void RegionLoaded(Scene scene) |
||
194 | { |
||
195 | } |
||
196 | |||
197 | public void RemoveRegion(Scene scene) |
||
198 | { |
||
199 | } |
||
200 | |||
201 | public void Close() |
||
202 | { |
||
203 | } |
||
204 | |||
205 | public string Name |
||
206 | { |
||
207 | get { return "MapImageModule"; } |
||
208 | } |
||
209 | |||
210 | public Type ReplaceableInterface |
||
211 | { |
||
212 | get { return null; } |
||
213 | } |
||
214 | |||
215 | #endregion |
||
216 | |||
217 | // TODO: unused: |
||
218 | // private void ShadeBuildings(Bitmap map) |
||
219 | // { |
||
220 | // lock (map) |
||
221 | // { |
||
222 | // lock (m_scene.Entities) |
||
223 | // { |
||
224 | // foreach (EntityBase entity in m_scene.Entities.Values) |
||
225 | // { |
||
226 | // if (entity is SceneObjectGroup) |
||
227 | // { |
||
228 | // SceneObjectGroup sog = (SceneObjectGroup) entity; |
||
229 | // |
||
230 | // foreach (SceneObjectPart primitive in sog.Children.Values) |
||
231 | // { |
||
232 | // int x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2)); |
||
233 | // int y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2)); |
||
234 | // int w = (int) primitive.Scale.X; |
||
235 | // int h = (int) primitive.Scale.Y; |
||
236 | // |
||
237 | // int dx; |
||
238 | // for (dx = x; dx < x + w; dx++) |
||
239 | // { |
||
240 | // int dy; |
||
241 | // for (dy = y; dy < y + h; dy++) |
||
242 | // { |
||
243 | // if (x < 0 || y < 0) |
||
244 | // continue; |
||
245 | // if (x >= map.Width || y >= map.Height) |
||
246 | // continue; |
||
247 | // |
||
248 | // map.SetPixel(dx, dy, Color.DarkGray); |
||
249 | // } |
||
250 | // } |
||
251 | // } |
||
252 | // } |
||
253 | // } |
||
254 | // } |
||
255 | // } |
||
256 | // } |
||
257 | |||
258 | private Bitmap FetchTexture(UUID id) |
||
259 | { |
||
260 | AssetBase asset = m_scene.AssetService.Get(id.ToString()); |
||
261 | |||
262 | if (asset != null) |
||
263 | { |
||
264 | m_log.DebugFormat("[MAPTILE]: Static map image texture {0} found for {1}", id, m_scene.Name); |
||
265 | } |
||
266 | else |
||
267 | { |
||
268 | m_log.WarnFormat("[MAPTILE]: Static map image texture {0} not found for {1}", id, m_scene.Name); |
||
269 | return null; |
||
270 | } |
||
271 | |||
272 | ManagedImage managedImage; |
||
273 | Image image; |
||
274 | |||
275 | try |
||
276 | { |
||
277 | if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image)) |
||
278 | return new Bitmap(image); |
||
279 | else |
||
280 | return null; |
||
281 | } |
||
282 | catch (DllNotFoundException) |
||
283 | { |
||
284 | m_log.ErrorFormat("[MAPTILE]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id); |
||
285 | |||
286 | } |
||
287 | catch (IndexOutOfRangeException) |
||
288 | { |
||
289 | m_log.ErrorFormat("[MAPTILE]: OpenJpeg was unable to decode this. Asset Data is empty for {0}", id); |
||
290 | |||
291 | } |
||
292 | catch (Exception) |
||
293 | { |
||
294 | m_log.ErrorFormat("[MAPTILE]: OpenJpeg was unable to decode this. Asset Data is empty for {0}", id); |
||
295 | |||
296 | } |
||
297 | return null; |
||
298 | |||
299 | } |
||
300 | |||
301 | private Bitmap DrawObjectVolume(Scene whichScene, Bitmap mapbmp) |
||
302 | { |
||
303 | int tc = 0; |
||
304 | ITerrainChannel hm = whichScene.Heightmap; |
||
305 | tc = Environment.TickCount; |
||
306 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); |
||
307 | EntityBase[] objs = whichScene.GetEntities(); |
||
308 | List<float> z_sortheights = new List<float>(); |
||
309 | List<uint> z_localIDs = new List<uint>(); |
||
310 | Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); |
||
311 | |||
312 | try |
||
313 | { |
||
314 | lock (objs) |
||
315 | { |
||
316 | foreach (EntityBase obj in objs) |
||
317 | { |
||
318 | // Only draw the contents of SceneObjectGroup |
||
319 | if (obj is SceneObjectGroup) |
||
320 | { |
||
321 | SceneObjectGroup mapdot = (SceneObjectGroup)obj; |
||
322 | Color mapdotspot = Color.Gray; // Default color when prim color is white |
||
323 | // Loop over prim in group |
||
324 | foreach (SceneObjectPart part in mapdot.Parts) |
||
325 | { |
||
326 | if (part == null) |
||
327 | continue; |
||
328 | |||
329 | // Draw if the object is at least 1 meter wide in any direction |
||
330 | if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) |
||
331 | { |
||
332 | // Try to get the RGBA of the default texture entry.. |
||
333 | // |
||
334 | try |
||
335 | { |
||
336 | // get the null checks out of the way |
||
337 | // skip the ones that break |
||
338 | if (part == null) |
||
339 | continue; |
||
340 | |||
341 | if (part.Shape == null) |
||
342 | continue; |
||
343 | |||
344 | if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) |
||
345 | continue; // eliminates trees from this since we don't really have a good tree representation |
||
346 | // if you want tree blocks on the map comment the above line and uncomment the below line |
||
347 | //mapdotspot = Color.PaleGreen; |
||
348 | |||
349 | Primitive.TextureEntry textureEntry = part.Shape.Textures; |
||
350 | |||
351 | if (textureEntry == null || textureEntry.DefaultTexture == null) |
||
352 | continue; |
||
353 | |||
354 | Color4 texcolor = textureEntry.DefaultTexture.RGBA; |
||
355 | |||
356 | // Not sure why some of these are null, oh well. |
||
357 | |||
358 | int colorr = 255 - (int)(texcolor.R * 255f); |
||
359 | int colorg = 255 - (int)(texcolor.G * 255f); |
||
360 | int colorb = 255 - (int)(texcolor.B * 255f); |
||
361 | |||
362 | if (!(colorr == 255 && colorg == 255 && colorb == 255)) |
||
363 | { |
||
364 | //Try to set the map spot color |
||
365 | try |
||
366 | { |
||
367 | // If the color gets goofy somehow, skip it *shakes fist at Color4 |
||
368 | mapdotspot = Color.FromArgb(colorr, colorg, colorb); |
||
369 | } |
||
370 | catch (ArgumentException) |
||
371 | { |
||
372 | } |
||
373 | } |
||
374 | } |
||
375 | catch (IndexOutOfRangeException) |
||
376 | { |
||
377 | // Windows Array |
||
378 | } |
||
379 | catch (ArgumentOutOfRangeException) |
||
380 | { |
||
381 | // Mono Array |
||
382 | } |
||
383 | |||
384 | Vector3 pos = part.GetWorldPosition(); |
||
385 | |||
386 | // skip prim outside of retion |
||
387 | if (!m_scene.PositionIsInCurrentRegion(pos)) |
||
388 | continue; |
||
389 | |||
390 | // skip prim in non-finite position |
||
391 | if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || |
||
392 | Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) |
||
393 | continue; |
||
394 | |||
395 | // Figure out if object is under 256m above the height of the terrain |
||
396 | bool isBelow256AboveTerrain = false; |
||
397 | |||
398 | try |
||
399 | { |
||
400 | isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); |
||
401 | } |
||
402 | catch (Exception) |
||
403 | { |
||
404 | } |
||
405 | |||
406 | if (isBelow256AboveTerrain) |
||
407 | { |
||
408 | // Translate scale by rotation so scale is represented properly when object is rotated |
||
409 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); |
||
410 | Vector3 scale = new Vector3(); |
||
411 | Vector3 tScale = new Vector3(); |
||
412 | Vector3 axPos = new Vector3(pos.X, pos.Y, pos.Z); |
||
413 | |||
414 | Quaternion llrot = part.GetWorldRotation(); |
||
415 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); |
||
416 | scale = lscale * rot; |
||
417 | |||
418 | // negative scales don't work in this situation |
||
419 | scale.X = Math.Abs(scale.X); |
||
420 | scale.Y = Math.Abs(scale.Y); |
||
421 | scale.Z = Math.Abs(scale.Z); |
||
422 | |||
423 | // This scaling isn't very accurate and doesn't take into account the face rotation :P |
||
424 | int mapdrawstartX = (int)(pos.X - scale.X); |
||
425 | int mapdrawstartY = (int)(pos.Y - scale.Y); |
||
426 | int mapdrawendX = (int)(pos.X + scale.X); |
||
427 | int mapdrawendY = (int)(pos.Y + scale.Y); |
||
428 | |||
429 | // If object is beyond the edge of the map, don't draw it to avoid errors |
||
430 | if (mapdrawstartX < 0 |
||
431 | || mapdrawstartX > (hm.Width - 1) |
||
432 | || mapdrawendX < 0 |
||
433 | || mapdrawendX > (hm.Width - 1) |
||
434 | || mapdrawstartY < 0 |
||
435 | || mapdrawstartY > (hm.Height - 1) |
||
436 | || mapdrawendY < 0 |
||
437 | || mapdrawendY > (hm.Height - 1)) |
||
438 | continue; |
||
439 | |||
440 | #region obb face reconstruction part duex |
||
441 | Vector3[] vertexes = new Vector3[8]; |
||
442 | |||
443 | // float[] distance = new float[6]; |
||
444 | Vector3[] FaceA = new Vector3[6]; // vertex A for Facei |
||
445 | Vector3[] FaceB = new Vector3[6]; // vertex B for Facei |
||
446 | Vector3[] FaceC = new Vector3[6]; // vertex C for Facei |
||
447 | Vector3[] FaceD = new Vector3[6]; // vertex D for Facei |
||
448 | |||
449 | tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); |
||
450 | scale = ((tScale * rot)); |
||
451 | vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
452 | // vertexes[0].x = pos.X + vertexes[0].x; |
||
453 | //vertexes[0].y = pos.Y + vertexes[0].y; |
||
454 | //vertexes[0].z = pos.Z + vertexes[0].z; |
||
455 | |||
456 | FaceA[0] = vertexes[0]; |
||
457 | FaceB[3] = vertexes[0]; |
||
458 | FaceA[4] = vertexes[0]; |
||
459 | |||
460 | tScale = lscale; |
||
461 | scale = ((tScale * rot)); |
||
462 | vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
463 | |||
464 | // vertexes[1].x = pos.X + vertexes[1].x; |
||
465 | // vertexes[1].y = pos.Y + vertexes[1].y; |
||
466 | //vertexes[1].z = pos.Z + vertexes[1].z; |
||
467 | |||
468 | FaceB[0] = vertexes[1]; |
||
469 | FaceA[1] = vertexes[1]; |
||
470 | FaceC[4] = vertexes[1]; |
||
471 | |||
472 | tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); |
||
473 | scale = ((tScale * rot)); |
||
474 | |||
475 | vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
476 | |||
477 | //vertexes[2].x = pos.X + vertexes[2].x; |
||
478 | //vertexes[2].y = pos.Y + vertexes[2].y; |
||
479 | //vertexes[2].z = pos.Z + vertexes[2].z; |
||
480 | |||
481 | FaceC[0] = vertexes[2]; |
||
482 | FaceD[3] = vertexes[2]; |
||
483 | FaceC[5] = vertexes[2]; |
||
484 | |||
485 | tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); |
||
486 | scale = ((tScale * rot)); |
||
487 | vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
488 | |||
489 | //vertexes[3].x = pos.X + vertexes[3].x; |
||
490 | // vertexes[3].y = pos.Y + vertexes[3].y; |
||
491 | // vertexes[3].z = pos.Z + vertexes[3].z; |
||
492 | |||
493 | FaceD[0] = vertexes[3]; |
||
494 | FaceC[1] = vertexes[3]; |
||
495 | FaceA[5] = vertexes[3]; |
||
496 | |||
497 | tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); |
||
498 | scale = ((tScale * rot)); |
||
499 | vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
500 | |||
501 | // vertexes[4].x = pos.X + vertexes[4].x; |
||
502 | // vertexes[4].y = pos.Y + vertexes[4].y; |
||
503 | // vertexes[4].z = pos.Z + vertexes[4].z; |
||
504 | |||
505 | FaceB[1] = vertexes[4]; |
||
506 | FaceA[2] = vertexes[4]; |
||
507 | FaceD[4] = vertexes[4]; |
||
508 | |||
509 | tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); |
||
510 | scale = ((tScale * rot)); |
||
511 | vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
512 | |||
513 | // vertexes[5].x = pos.X + vertexes[5].x; |
||
514 | // vertexes[5].y = pos.Y + vertexes[5].y; |
||
515 | // vertexes[5].z = pos.Z + vertexes[5].z; |
||
516 | |||
517 | FaceD[1] = vertexes[5]; |
||
518 | FaceC[2] = vertexes[5]; |
||
519 | FaceB[5] = vertexes[5]; |
||
520 | |||
521 | tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); |
||
522 | scale = ((tScale * rot)); |
||
523 | vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
524 | |||
525 | // vertexes[6].x = pos.X + vertexes[6].x; |
||
526 | // vertexes[6].y = pos.Y + vertexes[6].y; |
||
527 | // vertexes[6].z = pos.Z + vertexes[6].z; |
||
528 | |||
529 | FaceB[2] = vertexes[6]; |
||
530 | FaceA[3] = vertexes[6]; |
||
531 | FaceB[4] = vertexes[6]; |
||
532 | |||
533 | tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); |
||
534 | scale = ((tScale * rot)); |
||
535 | vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
||
536 | |||
537 | // vertexes[7].x = pos.X + vertexes[7].x; |
||
538 | // vertexes[7].y = pos.Y + vertexes[7].y; |
||
539 | // vertexes[7].z = pos.Z + vertexes[7].z; |
||
540 | |||
541 | FaceD[2] = vertexes[7]; |
||
542 | FaceC[3] = vertexes[7]; |
||
543 | FaceD[5] = vertexes[7]; |
||
544 | #endregion |
||
545 | |||
546 | //int wy = 0; |
||
547 | |||
548 | //bool breakYN = false; // If we run into an error drawing, break out of the |
||
549 | // loop so we don't lag to death on error handling |
||
550 | DrawStruct ds = new DrawStruct(); |
||
551 | ds.brush = new SolidBrush(mapdotspot); |
||
552 | //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); |
||
553 | |||
554 | ds.trns = new face[FaceA.Length]; |
||
555 | |||
556 | for (int i = 0; i < FaceA.Length; i++) |
||
557 | { |
||
558 | Point[] working = new Point[5]; |
||
559 | working[0] = project(hm, FaceA[i], axPos); |
||
560 | working[1] = project(hm, FaceB[i], axPos); |
||
561 | working[2] = project(hm, FaceD[i], axPos); |
||
562 | working[3] = project(hm, FaceC[i], axPos); |
||
563 | working[4] = project(hm, FaceA[i], axPos); |
||
564 | |||
565 | face workingface = new face(); |
||
566 | workingface.pts = working; |
||
567 | |||
568 | ds.trns[i] = workingface; |
||
569 | } |
||
570 | |||
571 | z_sort.Add(part.LocalId, ds); |
||
572 | z_localIDs.Add(part.LocalId); |
||
573 | z_sortheights.Add(pos.Z); |
||
574 | |||
575 | // for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) |
||
576 | // { |
||
577 | // for (wy = mapdrawstartY; wy < mapdrawendY; wy++) |
||
578 | // { |
||
579 | // m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); |
||
580 | // try |
||
581 | // { |
||
582 | // // Remember, flip the y! |
||
583 | // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); |
||
584 | // } |
||
585 | // catch (ArgumentException) |
||
586 | // { |
||
587 | // breakYN = true; |
||
588 | // } |
||
589 | // } |
||
590 | // if (breakYN) |
||
591 | // break; |
||
592 | // } |
||
593 | // } |
||
594 | //} |
||
595 | } // Object is within 256m Z of terrain |
||
596 | } // object is at least a meter wide |
||
597 | } // loop over group children |
||
598 | } // entitybase is sceneobject group |
||
599 | } // foreach loop over entities |
||
600 | |||
601 | float[] sortedZHeights = z_sortheights.ToArray(); |
||
602 | uint[] sortedlocalIds = z_localIDs.ToArray(); |
||
603 | |||
604 | // Sort prim by Z position |
||
605 | Array.Sort(sortedZHeights, sortedlocalIds); |
||
606 | |||
607 | using (Graphics g = Graphics.FromImage(mapbmp)) |
||
608 | { |
||
609 | for (int s = 0; s < sortedZHeights.Length; s++) |
||
610 | { |
||
611 | if (z_sort.ContainsKey(sortedlocalIds[s])) |
||
612 | { |
||
613 | DrawStruct rectDrawStruct = z_sort[sortedlocalIds[s]]; |
||
614 | for (int r = 0; r < rectDrawStruct.trns.Length; r++) |
||
615 | { |
||
616 | g.FillPolygon(rectDrawStruct.brush,rectDrawStruct.trns[r].pts); |
||
617 | } |
||
618 | //g.FillRectangle(rectDrawStruct.brush , rectDrawStruct.rect); |
||
619 | } |
||
620 | } |
||
621 | } |
||
622 | } // lock entities objs |
||
623 | |||
624 | } |
||
625 | finally |
||
626 | { |
||
627 | foreach (DrawStruct ds in z_sort.Values) |
||
628 | ds.brush.Dispose(); |
||
629 | } |
||
630 | |||
631 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); |
||
632 | |||
633 | return mapbmp; |
||
634 | } |
||
635 | |||
636 | private Point project(ITerrainChannel hm, Vector3 point3d, Vector3 originpos) |
||
637 | { |
||
638 | Point returnpt = new Point(); |
||
639 | //originpos = point3d; |
||
640 | //int d = (int)(256f / 1.5f); |
||
641 | |||
642 | //Vector3 topos = new Vector3(0, 0, 0); |
||
643 | // float z = -point3d.z - topos.z; |
||
644 | |||
645 | returnpt.X = (int)point3d.X;//(int)((topos.x - point3d.x) / z * d); |
||
646 | returnpt.Y = (int)((hm.Width - 1) - point3d.Y);//(int)(255 - (((topos.y - point3d.y) / z * d))); |
||
647 | |||
648 | return returnpt; |
||
649 | } |
||
650 | |||
651 | public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) |
||
652 | { |
||
653 | return null; |
||
654 | } |
||
655 | } |
||
656 | } |