<commit_before>﻿// OBBRenderer.cs
//
// Author:
//       <NAME> <<EMAIL>>
//
// Copyright (c) 2017 <NAME>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Reflection;
using DataReader;
using log4net;
using Nini.Config;
using OpenMetaverse;

namespace Anaximander {
	public class OBBRenderer : RegionRendererInterface {
		private static readonly ILog LOG = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

		private Color _waterColor;
		private Color _beachColor;
		private Color[,] _waterOverlay;

		public struct DrawStruct {
			public float sort_order;
			public SolidBrush brush;
			public Point[] vertices;
		}

		public OBBRenderer(IConfigSource config) {
			var tileInfo = config.Configs["MapTileInfo"];

			_waterColor = Color.FromArgb(
				tileInfo?.GetInt("OceanColorRed", Constants.OceanColor.R) ?? Constants.OceanColor.R,
				tileInfo?.GetInt("OceanColorGreen", Constants.OceanColor.G) ?? Constants.OceanColor.G,
				tileInfo?.GetInt("OceanColorBlue", Constants.OceanColor.B) ?? Constants.OceanColor.B
			);
			_beachColor = Color.FromArgb(
				tileInfo?.GetInt("BeachColorRed", Constants.BeachColor.R) ?? Constants.BeachColor.R,
				tileInfo?.GetInt("BeachColorGreen", Constants.BeachColor.G) ?? Constants.BeachColor.G,
				tileInfo?.GetInt("BeachColorBlue", Constants.BeachColor.B) ?? Constants.BeachColor.B
			);

			var waterOverlayPath = tileInfo?.GetString("WaterOverlay", Constants.WaterOverlay) ?? Constants.WaterOverlay;

			var pixelScale = tileInfo?.GetInt("PixelScale", Constants.PixelScale) ?? Constants.PixelScale;

			DirectBitmap waterOverlay;

			if (!string.IsNullOrWhiteSpace(waterOverlayPath)) {
				try {
					var overlay = new Bitmap(Image.FromFile(waterOverlayPath));
					//overlay.MakeTransparent();

					waterOverlay = new DirectBitmap(pixelScale, pixelScale);
					using (var gfx = Graphics.FromImage(waterOverlay.Bitmap)) {
						gfx.CompositingMode = CompositingMode.SourceCopy;
						gfx.DrawImage(overlay, 0, 0, pixelScale, pixelScale);
					}
				}
				catch (Exception e) {
					LOG.Warn($"[RENDER] Error loading water overlay file '{waterOverlayPath}', skipping.", e);
					waterOverlay = null;
				}

				if (waterOverlay != null) {
					_waterOverlay = new Color[waterOverlay.Bitmap.Width, waterOverlay.Bitmap.Height];

					// Convert to premultiplied alpha
					for (int y = 0; y < waterOverlay.Bitmap.Height; y++) {
						for (int x = 0; x < waterOverlay.Bitmap.Width; x++) {
							var c = waterOverlay.Bitmap.GetPixel(x, y);

							var r = c.R * c.A / 255;
							var g = c.G * c.A / 255;
							var b = c.B * c.A / 255;

							var result = Color.FromArgb(c.A, r, g, b);

							_waterOverlay[x, y] = result;
						}
					}
				}
			}
		}

		public DirectBitmap RenderTileFrom(DataReader.Region region, DirectBitmap bitmap) {
			var watch = System.Diagnostics.Stopwatch.StartNew();

			// Draw the terrain.
			LOG.Debug($"[RENDER] Rendering Maptile Terrain (Textured) for region {region.Id} named '{region.Name}'");
			watch.Restart();
			var terrain = TerrainToBitmap(region, bitmap);
			watch.Stop();
			LOG.Info($"[RENDER] Completed terrain for region {region.Id} named '{region.Name}' in {watch.ElapsedMilliseconds}ms");

			// Get the prims
			LOG.Debug($"[RENDER] Getting prims for region {region.Id} named '{region.Name}'");
			watch.Restart();
			var prims = region.GetPrims();
			watch.Stop();
			LOG.Debug($"[RENDER] Completed getting {prims.Count()} prims for region {region.Id} named '{region.Name}' in {watch.ElapsedMilliseconds}ms");

			// Draw the prims.
			LOG.Debug($"[RENDER] Rendering OBB prims for region {region.Id} named '{region.Name}'");
			watch.Restart();
			DrawObjects(prims, terrain, bitmap);
			watch.Stop();
			LOG.Debug($"[RENDER] Completed OBB prims for region {region.Id} named '{region.Name}' in {watch.ElapsedMilliseconds}ms");

			return bitmap;
		}

		private Terrain TerrainToBitmap(DataReader.Region region, DirectBitmap mapbmp) {
			var terrain = region.GetTerrain();

			var textures = new Texture[4];
			try {<commit_msg>Fix a couple of NREs<commit_after>﻿// OBBRenderer.cs
//
// Author:
//       <NAME> <<EMAIL>>
//
// Copyright (c) 2017 <NAME>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Reflection;
using DataReader;
using log4net;
using Nini.Config;
using OpenMetaverse;

namespace Anaximander {
	public class OBBRenderer : RegionRendererInterface {
		private static readonly ILog LOG = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

		private Color _waterColor;
		private Color _beachColor;
		private Color[,] _waterOverlay;

		public struct DrawStruct {
			public float sort_order;
			public SolidBrush brush;
			public Point[] vertices;
		}

		public OBBRenderer(IConfigSource config) {
			var tileInfo = config.Configs["MapTileInfo"];

			_waterColor = Color.FromArgb(
				tileInfo?.GetInt("OceanColorRed", Constants.OceanColor.R) ?? Constants.OceanColor.R,
				tileInfo?.GetInt("OceanColorGreen", Constants.OceanColor.G) ?? Constants.OceanColor.G,
				tileInfo?.GetInt("OceanColorBlue", Constants.OceanColor.B) ?? Constants.OceanColor.B
			);
			_beachColor = Color.FromArgb(
				tileInfo?.GetInt("BeachColorRed", Constants.BeachColor.R) ?? Constants.BeachColor.R,
				tileInfo?.GetInt("BeachColorGreen", Constants.BeachColor.G) ?? Constants.BeachColor.G,
				tileInfo?.GetInt("BeachColorBlue", Constants.BeachColor.B) ?? Constants.BeachColor.B
			);

			var waterOverlayPath = tileInfo?.GetString("WaterOverlay", Constants.WaterOverlay) ?? Constants.WaterOverlay;

			var pixelScale = tileInfo?.GetInt("PixelScale", Constants.PixelScale) ?? Constants.PixelScale;

			DirectBitmap waterOverlay;

			if (!string.IsNullOrWhiteSpace(waterOverlayPath)) {
				try {
					var overlay = new Bitmap(Image.FromFile(waterOverlayPath));
					//overlay.MakeTransparent();

					waterOverlay = new DirectBitmap(pixelScale, pixelScale);
					using (var gfx = Graphics.FromImage(waterOverlay.Bitmap)) {
						gfx.CompositingMode = CompositingMode.SourceCopy;
						gfx.DrawImage(overlay, 0, 0, pixelScale, pixelScale);
					}
				}
				catch (Exception e) {
					LOG.Warn($"[RENDER] Error loading water overlay file '{waterOverlayPath}', skipping.", e);
					waterOverlay = null;
				}

				if (waterOverlay != null) {
					_waterOverlay = new Color[waterOverlay.Bitmap.Width, waterOverlay.Bitmap.Height];

					// Convert to premultiplied alpha
					for (int y = 0; y < waterOverlay.Bitmap.Height; y++) {
						for (int x = 0; x < waterOverlay.Bitmap.Width; x++) {
							var c = waterOverlay.Bitmap.GetPixel(x, y);

							var r = c.R * c.A / 255;
							var g = c.G * c.A / 255;
							var b = c.B * c.A / 255;

							var result = Color.FromArgb(c.A, r, g, b);

							_waterOverlay[x, y] = result;
						}
					}
				}
			}
		}

		public DirectBitmap RenderTileFrom(DataReader.Region region, DirectBitmap bitmap) {
			var watch = System.Diagnostics.Stopwatch.StartNew();

			// Draw the terrain.
			LOG.Debug($"[RENDER] Rendering Maptile Terrain (Textured) for region {region.Id} named '{region.Name}'");
			watch.Restart();
			var terrain = TerrainToBitmap(region, bitmap);
			watch.Stop();
			LOG.Info($"[RENDER] Completed terrain for region {region.Id} named '{region.Name}' in {watch.ElapsedMilliseconds}ms");

			// Get the prims
			LOG.Debug($"[RENDER] Getting prims for region {region.Id} named '{region.Name}'");
			watch.Restart();
			var prims = region.GetPrims();
			watch.Stop();
			LOG.Debug($"[RENDER] Completed getting {prims?.Count()} prims for region {region.Id} named '{region.Name}' in {watch.ElapsedMilliseconds}ms");

			if (prims != null) {
				// Draw the prims.
				LOG.Debug($"[RENDER] Rendering OBB prims for region {region.Id} named '{region.Name}'");
				watch.Restart();
				DrawObjects(prims, terrain, bitmap);
				watch.Stop();
				LOG.Debug($"[RENDER] Completed OBB prims for region {region.Id} named '{region.Name}' in {watch.ElapsedMilliseconds}ms");
			}
			else {
				LOG.Debug($"[RENDER] Unable to render OBB prims for region {region.Id} named '{region.Name}': there was a problem getting the prims from the DB.");
			}

			return bitmap;
		}

		private Terrain TerrainToBitmap(DataReader.Region region, DirectBitmap mapbmp) {
			var terrain = region.GetTerrain();

			var textures = new Texture[4];
			try {
{'fraction_non_alphanumeric': 0.11858974358974358, 'fraction_numerical': 0.003770739064856712, 'mean_word_length': 3.8288575329995447, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7387782', 'n_tokens_mistral': 3740, 'n_tokens_neox': 3202, 'n_words': 957}