diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs | 381 |
1 files changed, 240 insertions, 141 deletions
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index 383a67f..d094bee 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs | |||
@@ -35,14 +35,14 @@ using System.Reflection; | |||
35 | using CSJ2K; | 35 | using CSJ2K; |
36 | using Nini.Config; | 36 | using Nini.Config; |
37 | using log4net; | 37 | using log4net; |
38 | using Rednettle.Warp3D; | 38 | using Warp3D; |
39 | using Mono.Addins; | 39 | using Mono.Addins; |
40 | 40 | ||
41 | using OpenSim.Framework; | 41 | using OpenSim.Framework; |
42 | using OpenSim.Region.Framework.Interfaces; | 42 | using OpenSim.Region.Framework.Interfaces; |
43 | using OpenSim.Region.Framework.Scenes; | 43 | using OpenSim.Region.Framework.Scenes; |
44 | using OpenSim.Region.PhysicsModules.SharedBase; | 44 | //using OpenSim.Region.PhysicsModules.SharedBase; |
45 | using OpenSim.Services.Interfaces; | 45 | //using OpenSim.Services.Interfaces; |
46 | 46 | ||
47 | using OpenMetaverse; | 47 | using OpenMetaverse; |
48 | using OpenMetaverse.Assets; | 48 | using OpenMetaverse.Assets; |
@@ -51,6 +51,7 @@ using OpenMetaverse.Rendering; | |||
51 | using OpenMetaverse.StructuredData; | 51 | using OpenMetaverse.StructuredData; |
52 | 52 | ||
53 | using WarpRenderer = global::Warp3D.Warp3D; | 53 | using WarpRenderer = global::Warp3D.Warp3D; |
54 | using System.Drawing.Drawing2D; | ||
54 | 55 | ||
55 | namespace OpenSim.Region.CoreModules.World.Warp3DMap | 56 | namespace OpenSim.Region.CoreModules.World.Warp3DMap |
56 | { | 57 | { |
@@ -76,10 +77,19 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
76 | private bool m_texturePrims = true; // true if should texture the rendered prims | 77 | private bool m_texturePrims = true; // true if should texture the rendered prims |
77 | private float m_texturePrimSize = 48f; // size of prim before we consider texturing it | 78 | private float m_texturePrimSize = 48f; // size of prim before we consider texturing it |
78 | private bool m_renderMeshes = false; // true if to render meshes rather than just bounding boxes | 79 | private bool m_renderMeshes = false; // true if to render meshes rather than just bounding boxes |
79 | private bool m_useAntiAliasing = false; // true if to anti-alias the rendered image | 80 | private String m_cacheDirectory = ""; |
80 | |||
81 | private bool m_Enabled = false; | 81 | private bool m_Enabled = false; |
82 | 82 | ||
83 | // private bool m_enable_date = false; | ||
84 | // private bool m_enable_regionName = false; | ||
85 | private bool m_enable_regionPosition = false; | ||
86 | private bool m_enable_refreshEveryMonth = false; | ||
87 | // private bool m_enable_HostedBy = false; | ||
88 | // private String m_enable_HostedByText = ""; | ||
89 | |||
90 | // private Bitmap lastImage = null; | ||
91 | private DateTime lastImageTime = DateTime.MinValue; | ||
92 | |||
83 | #region Region Module interface | 93 | #region Region Module interface |
84 | 94 | ||
85 | public void Initialise(IConfigSource source) | 95 | public void Initialise(IConfigSource source) |
@@ -94,9 +104,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
94 | 104 | ||
95 | m_Enabled = true; | 105 | m_Enabled = true; |
96 | 106 | ||
97 | m_drawPrimVolume | 107 | m_drawPrimVolume |
98 | = Util.GetConfigVarFromSections<bool>(m_config, "DrawPrimOnMapTile", configSections, m_drawPrimVolume); | 108 | = Util.GetConfigVarFromSections<bool>(m_config, "DrawPrimOnMapTile", configSections, m_drawPrimVolume); |
99 | m_textureTerrain | 109 | m_textureTerrain |
100 | = Util.GetConfigVarFromSections<bool>(m_config, "TextureOnMapTile", configSections, m_textureTerrain); | 110 | = Util.GetConfigVarFromSections<bool>(m_config, "TextureOnMapTile", configSections, m_textureTerrain); |
101 | m_texturePrims | 111 | m_texturePrims |
102 | = Util.GetConfigVarFromSections<bool>(m_config, "TexturePrims", configSections, m_texturePrims); | 112 | = Util.GetConfigVarFromSections<bool>(m_config, "TexturePrims", configSections, m_texturePrims); |
@@ -104,9 +114,19 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
104 | = Util.GetConfigVarFromSections<float>(m_config, "TexturePrimSize", configSections, m_texturePrimSize); | 114 | = Util.GetConfigVarFromSections<float>(m_config, "TexturePrimSize", configSections, m_texturePrimSize); |
105 | m_renderMeshes | 115 | m_renderMeshes |
106 | = Util.GetConfigVarFromSections<bool>(m_config, "RenderMeshes", configSections, m_renderMeshes); | 116 | = Util.GetConfigVarFromSections<bool>(m_config, "RenderMeshes", configSections, m_renderMeshes); |
107 | m_useAntiAliasing | 117 | m_cacheDirectory |
108 | = Util.GetConfigVarFromSections<bool>(m_config, "UseAntiAliasing", configSections, m_useAntiAliasing); | 118 | = Util.GetConfigVarFromSections<string>(m_config, "CacheDirectory", configSections, System.IO.Path.Combine(Util.cacheDir(), "MapImageCache")); |
109 | 119 | ||
120 | |||
121 | // m_enable_date = Util.GetConfigVarFromSections<bool>(m_config, "enableDate", configSections, false); | ||
122 | // m_enable_regionName = Util.GetConfigVarFromSections<bool>(m_config, "enableName", configSections, false); | ||
123 | m_enable_regionPosition = Util.GetConfigVarFromSections<bool>(m_config, "enablePosition", configSections, false); | ||
124 | m_enable_refreshEveryMonth = Util.GetConfigVarFromSections<bool>(m_config, "RefreshEveryMonth", configSections, true); | ||
125 | // m_enable_HostedBy = Util.GetConfigVarFromSections<bool>(m_config, "enableHostedBy", configSections, false); | ||
126 | // m_enable_HostedByText = Util.GetConfigVarFromSections<String>(m_config, "HosterText", configSections, String.Empty); | ||
127 | |||
128 | if (!Directory.Exists(m_cacheDirectory)) | ||
129 | Directory.CreateDirectory(m_cacheDirectory); | ||
110 | } | 130 | } |
111 | 131 | ||
112 | public void AddRegion(Scene scene) | 132 | public void AddRegion(Scene scene) |
@@ -118,14 +138,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
118 | 138 | ||
119 | List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); | 139 | List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); |
120 | if (renderers.Count > 0) | 140 | if (renderers.Count > 0) |
121 | { | 141 | m_log.Info("[MAPTILE]: Loaded prim mesher " + renderers[0]); |
122 | m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); | ||
123 | m_log.DebugFormat("[WARP 3D IMAGE MODULE]: Loaded prim mesher {0}", m_primMesher); | ||
124 | } | ||
125 | else | 142 | else |
126 | { | 143 | m_log.Info("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled"); |
127 | m_log.Debug("[WARP 3D IMAGE MODULE]: No prim mesher loaded, prim rendering will be disabled"); | ||
128 | } | ||
129 | 144 | ||
130 | m_scene.RegisterModuleInterface<IMapImageGenerator>(this); | 145 | m_scene.RegisterModuleInterface<IMapImageGenerator>(this); |
131 | } | 146 | } |
@@ -155,21 +170,149 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
155 | #endregion | 170 | #endregion |
156 | 171 | ||
157 | #region IMapImageGenerator Members | 172 | #region IMapImageGenerator Members |
173 | /* | ||
174 | public static string fillInt(int _i, int _l) | ||
175 | { | ||
176 | String _return = _i.ToString(); | ||
177 | |||
178 | while(_return.Length < _l) | ||
179 | { | ||
180 | _return = 0 + _return; | ||
181 | } | ||
182 | |||
183 | return _return; | ||
184 | } | ||
185 | |||
186 | public static int getCurrentUnixTime() | ||
187 | { | ||
188 | return (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; | ||
189 | } | ||
190 | |||
191 | public static String unixTimeToDateString(int unixTime) | ||
192 | { | ||
193 | DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); | ||
194 | long unixTimeStampInTicks = (long)(unixTime * TimeSpan.TicksPerSecond); | ||
195 | DateTime _date = new DateTime(unixStart.Ticks + unixTimeStampInTicks, System.DateTimeKind.Utc); | ||
158 | 196 | ||
197 | return fillInt(_date.Day, 2) + "." + fillInt(_date.Month, 2) + "." + fillInt(_date.Year, 4) + " " + fillInt(_date.Hour, 2) + ":" + fillInt(_date.Minute, 2); | ||
198 | } | ||
199 | |||
200 | private void writeDateOnMap(ref Bitmap _map) | ||
201 | { | ||
202 | RectangleF rectf = new RectangleF(2, 1, 200, 25); | ||
203 | |||
204 | Graphics g = Graphics.FromImage(_map); | ||
205 | g.SmoothingMode = SmoothingMode.AntiAlias; | ||
206 | g.InterpolationMode = InterpolationMode.HighQualityBicubic; | ||
207 | g.PixelOffsetMode = PixelOffsetMode.HighQuality; | ||
208 | g.DrawString(unixTimeToDateString(getCurrentUnixTime()), new Font("Arial", 8), Brushes.White, rectf); | ||
209 | g.Flush(); | ||
210 | } | ||
211 | |||
212 | private void writeNameOnMap(ref Bitmap _map) | ||
213 | { | ||
214 | RectangleF rectf = new RectangleF(2, m_scene.RegionInfo.RegionSizeX - 15, 200, 25); | ||
215 | |||
216 | Graphics g = Graphics.FromImage(_map); | ||
217 | g.SmoothingMode = SmoothingMode.AntiAlias; | ||
218 | g.InterpolationMode = InterpolationMode.HighQualityBicubic; | ||
219 | g.PixelOffsetMode = PixelOffsetMode.HighQuality; | ||
220 | g.DrawString(m_scene.Name, new Font("Arial", 8), Brushes.White, rectf); | ||
221 | g.Flush(); | ||
222 | } | ||
223 | */ | ||
224 | private void writePositionOnMap(ref Bitmap _map) | ||
225 | { | ||
226 | RectangleF rectf = new RectangleF(m_scene.RegionInfo.RegionSizeY - 75, m_scene.RegionInfo.RegionSizeX - 15, 80, 25); | ||
227 | |||
228 | Graphics g = Graphics.FromImage(_map); | ||
229 | g.SmoothingMode = SmoothingMode.AntiAlias; | ||
230 | g.InterpolationMode = InterpolationMode.HighQualityBicubic; | ||
231 | g.PixelOffsetMode = PixelOffsetMode.HighQuality; | ||
232 | g.DrawString("<" + m_scene.RegionInfo.RegionLocX + " " + m_scene.RegionInfo.RegionLocY + ">", new Font("Arial", 8), Brushes.White, rectf); | ||
233 | g.Flush(); | ||
234 | } | ||
235 | /* | ||
236 | private void writeHostedByOnMap(ref Bitmap _map) | ||
237 | { | ||
238 | RectangleF rectf = new RectangleF(2, m_scene.RegionInfo.RegionSizeX - 15, 200, 25); | ||
239 | |||
240 | Graphics g = Graphics.FromImage(_map); | ||
241 | g.SmoothingMode = SmoothingMode.AntiAlias; | ||
242 | g.InterpolationMode = InterpolationMode.HighQualityBicubic; | ||
243 | g.PixelOffsetMode = PixelOffsetMode.HighQuality; | ||
244 | g.DrawString(m_enable_HostedByText, new Font("Arial", 8), Brushes.Gray, rectf); | ||
245 | g.Flush(); | ||
246 | } | ||
247 | */ | ||
248 | public Bitmap CreateMapTileForce() | ||
249 | { | ||
250 | m_log.Info("[MAPTILE]: Forcing a map tile regenerate."); | ||
251 | File.Delete(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp")); | ||
252 | return CreateMapTile(); | ||
253 | } | ||
159 | public Bitmap CreateMapTile() | 254 | public Bitmap CreateMapTile() |
160 | { | 255 | { |
161 | // Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f); | 256 | if ((File.GetCreationTime(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp")).Month != DateTime.Now.Month) && (m_enable_refreshEveryMonth == true)) |
162 | // Camera above the middle of the region | 257 | { |
163 | Vector3 camPos = new Vector3( | 258 | m_log.InfoFormat("[MAPTILE]: Clearing old map tile out of cache {0} {1}.", |
164 | m_scene.RegionInfo.RegionSizeX/2 - 0.5f, | 259 | File.GetCreationTime(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp")).Month, DateTime.Now.Month); |
165 | m_scene.RegionInfo.RegionSizeY/2 - 0.5f, | 260 | File.Delete(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp")); |
166 | 221.7025033688163f); | 261 | } |
167 | // Viewport viewing down onto the region | 262 | |
168 | Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, | 263 | if(File.Exists(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp"))) |
169 | (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY, | 264 | { |
170 | (float)m_scene.RegionInfo.RegionSizeX, (float)m_scene.RegionInfo.RegionSizeY ); | 265 | return new Bitmap(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp")); |
171 | // Fill the viewport and return the image | 266 | } |
172 | return CreateMapTile(viewport, false); | 267 | else |
268 | { | ||
269 | m_log.Info("[MAPTILE]: Actually generating a map tile."); | ||
270 | /* this must be on all map, not just its image | ||
271 | if ((DateTime.Now - lastImageTime).TotalSeconds < 3600) | ||
272 | { | ||
273 | return (Bitmap)lastImage.Clone(); | ||
274 | } | ||
275 | */ | ||
276 | |||
277 | List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); | ||
278 | if (renderers.Count > 0) | ||
279 | { | ||
280 | m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); | ||
281 | } | ||
282 | |||
283 | Vector3 camPos = new Vector3( | ||
284 | m_scene.RegionInfo.RegionSizeX / 2 - 0.5f, | ||
285 | m_scene.RegionInfo.RegionSizeY / 2 - 0.5f, | ||
286 | 221.7025033688163f); | ||
287 | // Viewport viewing down onto the region | ||
288 | Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, | ||
289 | (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY, | ||
290 | (float)m_scene.RegionInfo.RegionSizeX, (float)m_scene.RegionInfo.RegionSizeY); | ||
291 | |||
292 | Bitmap tile = CreateMapTile(viewport, false); | ||
293 | |||
294 | // if (m_enable_date) | ||
295 | // writeDateOnMap(ref tile); | ||
296 | |||
297 | // if (m_enable_regionName) | ||
298 | // writeNameOnMap(ref tile); | ||
299 | |||
300 | if (m_enable_regionPosition) | ||
301 | writePositionOnMap(ref tile); | ||
302 | |||
303 | // if (m_enable_HostedBy) | ||
304 | // writeHostedByOnMap(ref tile); | ||
305 | |||
306 | tile.Save(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp")); | ||
307 | m_primMesher = null; | ||
308 | return tile; | ||
309 | |||
310 | /* | ||
311 | lastImage = tile; | ||
312 | lastImageTime = DateTime.Now; | ||
313 | return (Bitmap)lastImage.Clone(); | ||
314 | */ | ||
315 | } | ||
173 | } | 316 | } |
174 | 317 | ||
175 | public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) | 318 | public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) |
@@ -185,21 +328,14 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
185 | int width = viewport.Width; | 328 | int width = viewport.Width; |
186 | int height = viewport.Height; | 329 | int height = viewport.Height; |
187 | 330 | ||
188 | if (m_useAntiAliasing) | ||
189 | { | ||
190 | width *= 2; | ||
191 | height *= 2; | ||
192 | } | ||
193 | |||
194 | WarpRenderer renderer = new WarpRenderer(); | 331 | WarpRenderer renderer = new WarpRenderer(); |
195 | 332 | ||
196 | renderer.CreateScene(width, height); | 333 | if(!renderer.CreateScene(width, height)) |
197 | renderer.Scene.autoCalcNormals = false; | 334 | return new Bitmap(width,height); |
198 | 335 | ||
199 | #region Camera | 336 | #region Camera |
200 | 337 | ||
201 | warp_Vector pos = ConvertVector(viewport.Position); | 338 | warp_Vector pos = ConvertVector(viewport.Position); |
202 | pos.z -= 0.001f; // Works around an issue with the Warp3D camera | ||
203 | warp_Vector lookat = warp_Vector.add(ConvertVector(viewport.Position), ConvertVector(viewport.LookDirection)); | 339 | warp_Vector lookat = warp_Vector.add(ConvertVector(viewport.Position), ConvertVector(viewport.LookDirection)); |
204 | 340 | ||
205 | renderer.Scene.defaultCamera.setPos(pos); | 341 | renderer.Scene.defaultCamera.setPos(pos); |
@@ -207,9 +343,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
207 | 343 | ||
208 | if (viewport.Orthographic) | 344 | if (viewport.Orthographic) |
209 | { | 345 | { |
210 | renderer.Scene.defaultCamera.isOrthographic = true; | 346 | renderer.Scene.defaultCamera.setOrthographic(true,viewport.OrthoWindowWidth, viewport.OrthoWindowHeight); |
211 | renderer.Scene.defaultCamera.orthoViewWidth = viewport.OrthoWindowWidth; | ||
212 | renderer.Scene.defaultCamera.orthoViewHeight = viewport.OrthoWindowHeight; | ||
213 | } | 347 | } |
214 | else | 348 | else |
215 | { | 349 | { |
@@ -231,24 +365,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
231 | renderer.Render(); | 365 | renderer.Render(); |
232 | Bitmap bitmap = renderer.Scene.getImage(); | 366 | Bitmap bitmap = renderer.Scene.getImage(); |
233 | 367 | ||
234 | if (m_useAntiAliasing) | 368 | renderer.Scene.destroy(); |
235 | { | 369 | renderer.Reset(); |
236 | using (Bitmap origBitmap = bitmap) | ||
237 | bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); | ||
238 | } | ||
239 | |||
240 | // XXX: It shouldn't really be necesary to force a GC here as one should occur anyway pretty shortly | ||
241 | // afterwards. It's generally regarded as a bad idea to manually GC. If Warp3D is using lots of memory | ||
242 | // then this may be some issue with the Warp3D code itself, though it's also quite possible that generating | ||
243 | // this map tile simply takes a lot of memory. | ||
244 | foreach (var o in renderer.Scene.objectData.Values) | ||
245 | { | ||
246 | warp_Object obj = (warp_Object)o; | ||
247 | obj.vertexData = null; | ||
248 | obj.triangleData = null; | ||
249 | } | ||
250 | |||
251 | renderer.Scene.removeAllObjects(); | ||
252 | renderer = null; | 370 | renderer = null; |
253 | viewport = null; | 371 | viewport = null; |
254 | 372 | ||
@@ -284,16 +402,20 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
284 | { | 402 | { |
285 | float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; | 403 | float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; |
286 | 404 | ||
287 | renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f); | ||
288 | renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX/2 - 0.5f, | ||
289 | waterHeight, | ||
290 | m_scene.RegionInfo.RegionSizeY/2 - 0.5f ); | ||
291 | |||
292 | warp_Material waterColorMaterial = new warp_Material(ConvertColor(WATER_COLOR)); | 405 | warp_Material waterColorMaterial = new warp_Material(ConvertColor(WATER_COLOR)); |
293 | waterColorMaterial.setReflectivity(0); // match water color with standard map module thanks lkalif | 406 | waterColorMaterial.setReflectivity(0); // match water color with standard map module thanks lkalif |
294 | waterColorMaterial.setTransparency((byte)((1f - WATER_COLOR.A) * 255f)); | 407 | waterColorMaterial.setTransparency((byte)((1f - WATER_COLOR.A) * 255f)); |
295 | renderer.Scene.addMaterial("WaterColor", waterColorMaterial); | 408 | renderer.Scene.addMaterial("WaterColor", waterColorMaterial); |
296 | renderer.SetObjectMaterial("Water", "WaterColor"); | 409 | |
410 | for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / 256; x++) | ||
411 | { | ||
412 | for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / 256; y++) | ||
413 | { | ||
414 | renderer.AddPlane("Water-" + x + "-" + y, 256); | ||
415 | renderer.Scene.sceneobject("Water-" + x + "-" + y).setPos(256 * x, waterHeight, 256 * y); | ||
416 | renderer.SetObjectMaterial("Water-" + x + "-" + y, "WaterColor"); | ||
417 | } | ||
418 | } | ||
297 | } | 419 | } |
298 | 420 | ||
299 | // Add a terrain to the renderer. | 421 | // Add a terrain to the renderer. |
@@ -303,53 +425,53 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
303 | { | 425 | { |
304 | ITerrainChannel terrain = m_scene.Heightmap; | 426 | ITerrainChannel terrain = m_scene.Heightmap; |
305 | 427 | ||
428 | float regionsx = m_scene.RegionInfo.RegionSizeX; | ||
429 | float regionsy = m_scene.RegionInfo.RegionSizeY; | ||
430 | |||
306 | // 'diff' is the difference in scale between the real region size and the size of terrain we're buiding | 431 | // 'diff' is the difference in scale between the real region size and the size of terrain we're buiding |
307 | float diff = (float)m_scene.RegionInfo.RegionSizeX / 256f; | 432 | float diff = regionsx / 256f; |
433 | |||
434 | int npointsx =(int)(regionsx / diff); | ||
435 | int npointsy =(int)(regionsy / diff); | ||
308 | 436 | ||
309 | warp_Object obj = new warp_Object(256 * 256, 255 * 255 * 2); | 437 | float invsx = 1.0f / regionsx; |
438 | float invsy = 1.0f / (float)m_scene.RegionInfo.RegionSizeY; | ||
310 | 439 | ||
311 | // Create all the vertices for the terrain | 440 | // Create all the vertices for the terrain |
312 | for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff) | 441 | warp_Object obj = new warp_Object(); |
442 | for (float y = 0; y < regionsy; y += diff) | ||
313 | { | 443 | { |
314 | for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff) | 444 | for (float x = 0; x < regionsx; x += diff) |
315 | { | 445 | { |
316 | warp_Vector pos = ConvertVector(x, y, (float)terrain[(int)x, (int)y]); | 446 | warp_Vector pos = ConvertVector(x , y , (float)terrain[(int)x, (int)y]); |
317 | obj.addVertex(new warp_Vertex(pos, | 447 | obj.addVertex(new warp_Vertex(pos, x * invsx, 1.0f - y * invsy)); |
318 | x / (float)m_scene.RegionInfo.RegionSizeX, | ||
319 | (((float)m_scene.RegionInfo.RegionSizeY) - y) / m_scene.RegionInfo.RegionSizeY) ); | ||
320 | } | 448 | } |
321 | } | 449 | } |
322 | 450 | ||
323 | // Now that we have all the vertices, make another pass and create | 451 | // Now that we have all the vertices, make another pass and |
324 | // the normals for each of the surface triangles and | 452 | // create the list of triangle indices. |
325 | // create the list of triangle indices. | 453 | float invdiff = 1.0f / diff; |
326 | for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff) | 454 | int limx = npointsx - 1; |
455 | int limy = npointsy - 1; | ||
456 | for (float y = 0; y < regionsy; y += diff) | ||
327 | { | 457 | { |
328 | for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff) | 458 | for (float x = 0; x < regionsx; x += diff) |
329 | { | 459 | { |
330 | float newX = x / diff; | 460 | float newX = x * invdiff; |
331 | float newY = y / diff; | 461 | float newY = y * invdiff; |
332 | if (newX < 255 && newY < 255) | 462 | if (newX < limx && newY < limy) |
333 | { | 463 | { |
334 | int v = (int)newY * 256 + (int)newX; | 464 | int v = (int)newY * npointsx + (int)newX; |
335 | |||
336 | // Normal for a triangle made up of three adjacent vertices | ||
337 | Vector3 v1 = new Vector3(newX, newY, (float)terrain[(int)x, (int)y]); | ||
338 | Vector3 v2 = new Vector3(newX + 1, newY, (float)terrain[(int)(x + 1), (int)y]); | ||
339 | Vector3 v3 = new Vector3(newX, newY + 1, (float)terrain[(int)x, ((int)(y + 1))]); | ||
340 | warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3)); | ||
341 | norm = norm.reverse(); | ||
342 | obj.vertex(v).n = norm; | ||
343 | 465 | ||
344 | // Make two triangles for each of the squares in the grid of vertices | 466 | // Make two triangles for each of the squares in the grid of vertices |
345 | obj.addTriangle( | 467 | obj.addTriangle( |
346 | v, | 468 | v, |
347 | v + 1, | 469 | v + 1, |
348 | v + 256); | 470 | v + npointsx); |
349 | 471 | ||
350 | obj.addTriangle( | 472 | obj.addTriangle( |
351 | v + 256 + 1, | 473 | v + npointsx + 1, |
352 | v + 256, | 474 | v + npointsx, |
353 | v + 1); | 475 | v + 1); |
354 | } | 476 | } |
355 | } | 477 | } |
@@ -382,18 +504,15 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
382 | Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); | 504 | Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); |
383 | 505 | ||
384 | warp_Texture texture; | 506 | warp_Texture texture; |
385 | using ( | 507 | using (Bitmap image = TerrainSplat.Splat( |
386 | Bitmap image | 508 | terrain, textureIDs, startHeights, heightRanges, |
387 | = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges, | ||
388 | new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) | 509 | new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) |
389 | { | ||
390 | texture = new warp_Texture(image); | 510 | texture = new warp_Texture(image); |
391 | } | ||
392 | 511 | ||
393 | warp_Material material = new warp_Material(texture); | 512 | warp_Material material = new warp_Material(texture); |
394 | material.setReflectivity(50); | 513 | material.setReflectivity(50); |
395 | renderer.Scene.addMaterial("TerrainColor", material); | 514 | renderer.Scene.addMaterial("TerrainColor", material); |
396 | renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif | 515 | renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif |
397 | renderer.SetObjectMaterial("Terrain", "TerrainColor"); | 516 | renderer.SetObjectMaterial("Terrain", "TerrainColor"); |
398 | } | 517 | } |
399 | 518 | ||
@@ -414,11 +533,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
414 | private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim, | 533 | private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim, |
415 | bool useTextures) | 534 | bool useTextures) |
416 | { | 535 | { |
417 | const float MIN_SIZE = 2f; | 536 | const float MIN_SIZE_SQUARE = 4f; |
418 | 537 | ||
419 | if ((PCode)prim.Shape.PCode != PCode.Prim) | 538 | if ((PCode)prim.Shape.PCode != PCode.Prim) |
420 | return; | 539 | return; |
421 | if (prim.Scale.LengthSquared() < MIN_SIZE * MIN_SIZE) | 540 | float primScaleLenSquared = prim.Scale.LengthSquared(); |
541 | |||
542 | if (primScaleLenSquared < MIN_SIZE_SQUARE) | ||
422 | return; | 543 | return; |
423 | 544 | ||
424 | FacetedMesh renderMesh = null; | 545 | FacetedMesh renderMesh = null; |
@@ -454,11 +575,11 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
454 | sculpt.Dispose(); | 575 | sculpt.Dispose(); |
455 | } | 576 | } |
456 | } | 577 | } |
457 | catch (Exception e) | 578 | catch /*(Exception e)*/ |
458 | { | 579 | { |
459 | Vector3 objectPos = prim.ParentGroup.RootPart.AbsolutePosition; | 580 | Vector3 objectPos = prim.ParentGroup.RootPart.AbsolutePosition; |
460 | //// TODO - print out owner of SceneObjectPart prim. | 581 | //// TODO - print out owner of SceneObjectPart prim. |
461 | m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0} @ {1},{2},{3} - {4}.", | 582 | m_log.Error(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0} @ {1},{2},{3} - {4}.", |
462 | omvPrim.Sculpt.SculptTexture, objectPos.X, objectPos.Y, objectPos.Z, | 583 | omvPrim.Sculpt.SculptTexture, objectPos.X, objectPos.Y, objectPos.Z, |
463 | prim.ParentGroup.RootPart.Name)); | 584 | prim.ParentGroup.RootPart.Name)); |
464 | } | 585 | } |
@@ -477,20 +598,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
477 | if (renderMesh == null) | 598 | if (renderMesh == null) |
478 | return; | 599 | return; |
479 | 600 | ||
480 | warp_Vector primPos = ConvertVector(prim.GetWorldPosition()); | ||
481 | warp_Quaternion primRot = ConvertQuaternion(prim.RotationOffset); | ||
482 | |||
483 | warp_Matrix m = warp_Matrix.quaternionMatrix(primRot); | ||
484 | |||
485 | if (prim.ParentID != 0) | ||
486 | { | ||
487 | SceneObjectGroup group = m_scene.SceneGraph.GetGroupByPrim(prim.LocalId); | ||
488 | if (group != null) | ||
489 | m.transform(warp_Matrix.quaternionMatrix(ConvertQuaternion(group.RootPart.RotationOffset))); | ||
490 | } | ||
491 | |||
492 | warp_Vector primScale = ConvertVector(prim.Scale); | ||
493 | |||
494 | string primID = prim.UUID.ToString(); | 601 | string primID = prim.UUID.ToString(); |
495 | 602 | ||
496 | // Create the prim faces | 603 | // Create the prim faces |
@@ -498,27 +605,18 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
498 | for (int i = 0; i < renderMesh.Faces.Count; i++) | 605 | for (int i = 0; i < renderMesh.Faces.Count; i++) |
499 | { | 606 | { |
500 | Face face = renderMesh.Faces[i]; | 607 | Face face = renderMesh.Faces[i]; |
501 | string meshName = primID + "-Face-" + i.ToString(); | 608 | string meshName = primID + i.ToString(); |
502 | 609 | ||
503 | // Avoid adding duplicate meshes to the scene | 610 | // Avoid adding duplicate meshes to the scene |
504 | if (renderer.Scene.objectData.ContainsKey(meshName)) | 611 | if (renderer.Scene.objectData.ContainsKey(meshName)) |
505 | { | ||
506 | continue; | 612 | continue; |
507 | } | ||
508 | |||
509 | warp_Object faceObj = new warp_Object(face.Vertices.Count, face.Indices.Count / 3); | ||
510 | 613 | ||
614 | warp_Object faceObj = new warp_Object(); | ||
511 | for (int j = 0; j < face.Vertices.Count; j++) | 615 | for (int j = 0; j < face.Vertices.Count; j++) |
512 | { | 616 | { |
513 | Vertex v = face.Vertices[j]; | 617 | Vertex v = face.Vertices[j]; |
514 | |||
515 | warp_Vector pos = ConvertVector(v.Position); | 618 | warp_Vector pos = ConvertVector(v.Position); |
516 | warp_Vector norm = ConvertVector(v.Normal); | 619 | warp_Vertex vert = new warp_Vertex(pos, v.TexCoord.X, v.TexCoord.Y); |
517 | |||
518 | if (prim.Shape.SculptTexture == UUID.Zero) | ||
519 | norm = norm.reverse(); | ||
520 | warp_Vertex vert = new warp_Vertex(pos, norm, v.TexCoord.X, v.TexCoord.Y); | ||
521 | |||
522 | faceObj.addVertex(vert); | 620 | faceObj.addVertex(vert); |
523 | } | 621 | } |
524 | 622 | ||
@@ -533,17 +631,19 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
533 | Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i); | 631 | Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i); |
534 | Color4 faceColor = GetFaceColor(teFace); | 632 | Color4 faceColor = GetFaceColor(teFace); |
535 | string materialName = String.Empty; | 633 | string materialName = String.Empty; |
536 | if (m_texturePrims && prim.Scale.LengthSquared() > m_texturePrimSize*m_texturePrimSize) | 634 | if (m_texturePrims && primScaleLenSquared > m_texturePrimSize*m_texturePrimSize) |
537 | materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID); | 635 | materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID); |
538 | else | 636 | else |
539 | materialName = GetOrCreateMaterial(renderer, faceColor); | 637 | materialName = GetOrCreateMaterial(renderer, faceColor); |
540 | 638 | ||
639 | warp_Vector primPos = ConvertVector(prim.GetWorldPosition()); | ||
640 | warp_Quaternion primRot = ConvertQuaternion(prim.GetWorldRotation()); | ||
641 | warp_Matrix m = warp_Matrix.quaternionMatrix(primRot); | ||
541 | faceObj.transform(m); | 642 | faceObj.transform(m); |
542 | faceObj.setPos(primPos); | 643 | faceObj.setPos(primPos); |
543 | faceObj.scaleSelf(primScale.x, primScale.y, primScale.z); | 644 | faceObj.scaleSelf(prim.Scale.X, prim.Scale.Z, prim.Scale.Y); |
544 | 645 | ||
545 | renderer.Scene.addObject(meshName, faceObj); | 646 | renderer.Scene.addObject(meshName, faceObj); |
546 | |||
547 | renderer.SetObjectMaterial(meshName, materialName); | 647 | renderer.SetObjectMaterial(meshName, materialName); |
548 | } | 648 | } |
549 | } | 649 | } |
@@ -576,7 +676,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
576 | 676 | ||
577 | if (!fetched) | 677 | if (!fetched) |
578 | { | 678 | { |
579 | // Fetch the texture, decode and get the average color, | 679 | // Fetch the texture, decode and get the average color, |
580 | // then save it to a temporary metadata asset | 680 | // then save it to a temporary metadata asset |
581 | AssetBase textureAsset = m_scene.AssetService.Get(face.TextureID.ToString()); | 681 | AssetBase textureAsset = m_scene.AssetService.Get(face.TextureID.ToString()); |
582 | if (textureAsset != null) | 682 | if (textureAsset != null) |
@@ -659,9 +759,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
659 | using (Bitmap img = (Bitmap)imgDecoder.DecodeToImage(asset)) | 759 | using (Bitmap img = (Bitmap)imgDecoder.DecodeToImage(asset)) |
660 | ret = new warp_Texture(img); | 760 | ret = new warp_Texture(img); |
661 | } | 761 | } |
662 | catch (Exception e) | 762 | catch /*(Exception e)*/ |
663 | { | 763 | { |
664 | m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception ", id), e); | 764 | m_log.Debug(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception ", id)); |
665 | } | 765 | } |
666 | } | 766 | } |
667 | 767 | ||
@@ -671,7 +771,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
671 | #endregion Rendering Methods | 771 | #endregion Rendering Methods |
672 | 772 | ||
673 | #region Static Helpers | 773 | #region Static Helpers |
674 | |||
675 | // Note: axis change. | 774 | // Note: axis change. |
676 | private static warp_Vector ConvertVector(float x, float y, float z) | 775 | private static warp_Vector ConvertVector(float x, float y, float z) |
677 | { | 776 | { |
@@ -725,10 +824,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
725 | { | 824 | { |
726 | width = bitmap.Width; | 825 | width = bitmap.Width; |
727 | height = bitmap.Height; | 826 | height = bitmap.Height; |
728 | 827 | ||
729 | BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); | 828 | BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); |
730 | pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; | 829 | pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; |
731 | 830 | ||
732 | // Sum up the individual channels | 831 | // Sum up the individual channels |
733 | unsafe | 832 | unsafe |
734 | { | 833 | { |
@@ -737,7 +836,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
737 | for (int y = 0; y < height; y++) | 836 | for (int y = 0; y < height; y++) |
738 | { | 837 | { |
739 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); | 838 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); |
740 | 839 | ||
741 | for (int x = 0; x < width; x++) | 840 | for (int x = 0; x < width; x++) |
742 | { | 841 | { |
743 | b += row[x * pixelBytes + 0]; | 842 | b += row[x * pixelBytes + 0]; |
@@ -752,7 +851,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
752 | for (int y = 0; y < height; y++) | 851 | for (int y = 0; y < height; y++) |
753 | { | 852 | { |
754 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); | 853 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); |
755 | 854 | ||
756 | for (int x = 0; x < width; x++) | 855 | for (int x = 0; x < width; x++) |
757 | { | 856 | { |
758 | b += row[x * pixelBytes + 0]; | 857 | b += row[x * pixelBytes + 0]; |
@@ -780,7 +879,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
780 | } | 879 | } |
781 | catch (Exception ex) | 880 | catch (Exception ex) |
782 | { | 881 | { |
783 | m_log.WarnFormat( | 882 | m_log.DebugFormat( |
784 | "[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", | 883 | "[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", |
785 | textureID, j2kData.Length, ex.Message); | 884 | textureID, j2kData.Length, ex.Message); |
786 | 885 | ||