aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Terrain/MapImageModule.cs
blob: 458d7810c6bd00c3b37609732244bdd5ba72598d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System;
using System.Collections.Generic;
using System.Drawing;
using libsecondlife;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.Environment.Modules.ModuleFramework;

namespace OpenSim.Region.Environment.Modules.Terrain
{
    class MapImageModule : IMapImageGenerator, IRegionModule
    {
        private Scene m_scene;
        #region IRegionModule Members

        public void Initialise(Scene scene, IConfigSource source)
        {
            m_scene = scene;
            m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
        }

        public void PostInitialise()
        {
        }

        public void Close()
        {
        }

        public string Name
        {
            get { return "MapImageModule"; }
        }

        public bool IsSharedModule
        {
            get { return false; }
        }


        public byte[] WriteJpeg2000Image(string gradientmap)
        {
            byte[] imageData = null;

            Bitmap bmp = TerrainToBitmap(gradientmap);

            try
            {
                imageData = OpenJPEGNet.OpenJPEG.EncodeFromImage(bmp, true);
            }
            catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke
            {
                Console.WriteLine("Failed generating terrain map: " + e.ToString());
            }

            return imageData;
        }

        private void ShadeBuildings(ref Bitmap map)
        {
            lock (map)
            {
                lock (m_scene.Entities)
                {
                    foreach (EntityBase entity in m_scene.Entities.Values)
                    {
                        if (entity is SceneObjectGroup)
                        {
                            SceneObjectGroup sog = (SceneObjectGroup)entity;

                            foreach (SceneObjectPart primitive in sog.Children.Values)
                            {
                                int x, y, w, h, dx, dy;
                                x = (int)(primitive.AbsolutePosition.X - (primitive.Scale.X / 2));
                                y = (int)(primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2));
                                w = (int)primitive.Scale.X;
                                h = (int)primitive.Scale.Y;

                                for (dx = x; dx < x + w; dx++)
                                {
                                    for (dy = y; dy < y + h; dy++)
                                    {
                                        if (x < 0 || y < 0)
                                            continue;
                                        if (x >= map.Width || y >= map.Height)
                                            continue;

                                        map.SetPixel(dx, dy, Color.DarkGray);
                                    }
                                }


                            }
                        }
                    }
                }
            }
        }

        private Bitmap TerrainToBitmap(string gradientmap)
        {
            Bitmap gradientmapLd = new Bitmap(gradientmap);

            int pallete = gradientmapLd.Height;

            Bitmap bmp = new Bitmap(m_scene.Heightmap.Width, m_scene.Heightmap.Height);
            Color[] colours = new Color[pallete];

            for (int i = 0; i < pallete; i++)
            {
                colours[i] = gradientmapLd.GetPixel(0, i);
            }

            lock (m_scene.Heightmap)
            {
                ITerrainChannel copy = m_scene.Heightmap;
                for (int y = 0; y < copy.Height; y++)
                {
                    for (int x = 0; x < copy.Width; x++)
                    {
                        // 512 is the largest possible height before colours clamp
                        int colorindex = (int)(Math.Max(Math.Min(1.0, copy[x, y] / 512.0), 0.0) * (pallete - 1));

                        // Handle error conditions
                        if (colorindex > pallete - 1 || colorindex < 0)
                            bmp.SetPixel(x, copy.Height - y - 1, Color.Red);
                        else
                            bmp.SetPixel(x, copy.Height - y - 1, colours[colorindex]);
                    }
                }
                ShadeBuildings(ref bmp);
                return bmp;
            }
        }


        #endregion
    }
}