diff --git a/src/BasicPathFinding.cs b/src/BasicPathFinding.cs index 05e8713..bb36682 100644 --- a/src/BasicPathFinding.cs +++ b/src/BasicPathFinding.cs @@ -30,8 +30,6 @@ namespace OpenSim.Modules.PathFinding private bool m_enabled = true; private string m_dataDirectory = "./PathFindingData"; private IScriptModuleComms m_scriptModule; - private AsyncCommandManager m_asyncCommands = null; - private IScriptEngine m_scriptEngine = null; public string Name { @@ -103,8 +101,7 @@ namespace OpenSim.Modules.PathFinding try { m_scriptModule.RegisterScriptInvocation(this, "osCreateNewPathFindingScene"); - //m_scriptModule.RegisterScriptInvocation(this, "osAddObjectToPathFindingScene"); - //m_scriptModule.RegisterScriptInvocation(this, "osGetPath"); + m_scriptModule.RegisterScriptInvocation(this, "osGetPath"); } catch (Exception e) { @@ -112,17 +109,6 @@ namespace OpenSim.Modules.PathFinding m_enabled = false; } - m_scriptEngine = m_scene.RequestModuleInterface(); - - if (m_scriptEngine != null) - { - m_asyncCommands = new AsyncCommandManager(m_scriptEngine); - } - else - { - m_log.Error("[" + Name + "]: Error while loading AsyncCommandManager"); - } - m_log.Info("[" + Name + "]: Region loading done!"); } } @@ -136,83 +122,23 @@ namespace OpenSim.Modules.PathFinding #region Script Funktions - private void createPathFindingScene(UUID script, String imageName, Vector3 start, Vector3 target) + private void createPathFindingScene(UUID script, UUID requestID, bool terrain) { - List _pixels = new List(); - - try - { - Bitmap _map = new Bitmap((int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY); - - for (int X = 0; X < m_scene.RegionInfo.RegionSizeX; X++) - { - for (int Y = 0; Y < m_scene.RegionInfo.RegionSizeY; Y++) - { - int _imageX = ((int)m_scene.RegionInfo.RegionSizeX - 1) - X; - int _imageY = ((int)m_scene.RegionInfo.RegionSizeY - 1) - Y; - - _pixels.Add(new PixelInfo(new Vector2(_imageX, _imageY))); - - float baseheight = (float)m_scene.Heightmap[X, Y]; - - if (baseheight <= m_scene.RegionInfo.RegionSettings.WaterHeight) - _map.SetPixel(_imageX, _imageY, Color.Black); - - if (baseheight > m_scene.RegionInfo.RegionSettings.WaterHeight) - _map.SetPixel(_imageX, _imageY, Color.White); - } - } - - PathFindingSceneGenerator.DrawObjectVolume(m_scene, ref _map); - - - - - _map.Save(imageName + ".png", ImageFormat.Png); - - m_scriptModule.DispatchReply(script, 0, "done", imageName); - } - catch(Exception _error) - { - m_log.Error(_error.Message); - m_scriptModule.DispatchReply(script, 0, "failed", imageName); - } + PathFinder _worker = new PathFinder(requestID, m_scene); + _worker.preparePathFindingScene(terrain); + m_scriptModule.DispatchReply(script, 0, "", requestID.ToString()); } [ScriptInvocation] - public string osCreateNewPathFindingScene(UUID hostID, UUID scriptID, Vector3 start, Vector3 target) + public string osCreateNewPathFindingScene(UUID hostID, UUID scriptID, bool terrain, Vector3 start, Vector3 target) { - m_log.Info("[" + Name + "]: Create new path scene!"); + UUID requestKey = UUID.Random(); - String imageName = UUID.Random().ToString(); - - try - { - SceneObjectGroup _host = m_scene.GetSceneObjectGroup(hostID); - - if (_host != null) - { - //createPathFindingScene(imageName); - - //UUID tid = m_asyncCommands.DataserverPlugin.RegisterRequest(_host.LocalId, _host.GroupID, imageName); - - (new Thread(delegate () { createPathFindingScene(scriptID, imageName, start, target); })).Start(); - - } - else - { - m_log.ErrorFormat("[" + Name + "]: Host is null"); - } - } - catch(Exception _error) - { - m_log.Error(_error.Message); - m_log.Error(_error.StackTrace); - } - - return imageName; + SceneObjectGroup _host = m_scene.GetSceneObjectGroup(hostID); + (new Thread(delegate () { createPathFindingScene(scriptID, requestKey, terrain); })).Start(); + return requestKey.ToString(); } #endregion diff --git a/src/PixelInfo.cs b/src/NodeInfo.cs similarity index 77% rename from src/PixelInfo.cs rename to src/NodeInfo.cs index 7e0d32d..d58ea63 100644 --- a/src/PixelInfo.cs +++ b/src/NodeInfo.cs @@ -7,12 +7,13 @@ using System.Threading.Tasks; namespace OpenSim.Modules.PathFinding { - class PixelInfo + class NodeInfo { public Vector2 Position = new Vector2(0, 0); public int Counter = 0; + public bool Blocked = false; - public PixelInfo(Vector2 position) + public NodeInfo(Vector2 position) { Position = position; } diff --git a/src/PathFinder.cs b/src/PathFinder.cs new file mode 100644 index 0000000..e3b5bb7 --- /dev/null +++ b/src/PathFinder.cs @@ -0,0 +1,142 @@ +using OpenMetaverse; +using OpenSim.Region.Framework.Scenes; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenSim.Modules.PathFinding +{ + class PathFinder + { + private List m_nodes = new List(); + private UUID m_requestID = UUID.Zero; + + private Scene m_scene = null; + + public PathFinder(UUID requestID, Scene localScene) + { + m_requestID = requestID; + + m_scene = localScene; + } + + public void preparePathFindingScene(bool terrain) + { + generateEmptryNodeGrid(new Vector2((int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY)); + convertRegionToNodeList(terrain); + saveDebugImageToDisc(); + } + + public void generatePath(Vector2 start, Vector2 target) + { + + + } + + private void convertRegionToNodeList(bool terrain) + { + if (terrain == true) + { + for (int X = 0; X < m_scene.RegionInfo.RegionSizeX; X++) + { + for (int Y = 0; Y < m_scene.RegionInfo.RegionSizeY; Y++) + { + float baseheight = (float)m_scene.Heightmap[X, Y]; + + //Block the position then water is on this place. + if (baseheight <= m_scene.RegionInfo.RegionSettings.WaterHeight) + setNoteBlocked(new Vector2(X, Y), true); + + //Allow all positions they have terrain over the water height. + if (baseheight > m_scene.RegionInfo.RegionSettings.WaterHeight) + setNoteBlocked(new Vector2(X, Y), false); + } + } + } + + Bitmap _objectData = new Bitmap((int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY); + PathFindingSceneGenerator.DrawObjectVolume(m_scene, ref _objectData); + convertBitmapToNodeList(ref _objectData); + } + + private void setNoteBlocked(Vector2 position, bool state) + { + NodeInfo _infoNode = m_nodes.Find(X => X.Position.X.Equals(position.X) && X.Position.Y.Equals(position.Y)); + + if(_infoNode != null) + _infoNode.Blocked = state; + } + + private bool getNoteBlocked(Vector2 position) + { + NodeInfo _infoNode = m_nodes.Find(X => X.Position.X.Equals(position.X) && X.Position.Y.Equals(position.Y)); + + if (_infoNode != null) + return _infoNode.Blocked; + + return false; + } + + private void generateEmptryNodeGrid(Vector2 size) + { + for (int X = 0; X <= size.X; X++) + { + for (int Y = 0; Y <= size.Y; Y++) + { + m_nodes.Add(new NodeInfo(new Vector2(X, Y))); + } + } + } + + private void convertBitmapToNodeList(ref Bitmap bitmap) + { + for (int X = 0; X < bitmap.Width; X++) + { + for (int Y = 0; Y < bitmap.Height; Y++) + { + Color _pixelColor = bitmap.GetPixel(X, Y); + + if (_pixelColor.Equals(Color.Black)) + setNoteBlocked(new Vector2(X, Y), true); + + if (_pixelColor.Equals(Color.White)) + setNoteBlocked(new Vector2(X, Y), false); + } + } + } + + private Bitmap convertNodeListToBitmap() + { + Bitmap _bitmap = new Bitmap((int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY); + + for (int X = 0; X < _bitmap.Width; X++) + { + for (int Y = 0; Y < _bitmap.Height; Y++) + { + bool _nodeState = getNoteBlocked(new Vector2(X, Y)); + + if(_nodeState == true) + { + _bitmap.SetPixel(X, Y, Color.Black); + } + else + { + _bitmap.SetPixel(X, Y, Color.White); + } + } + } + + return _bitmap; + } + + private void saveDebugImageToDisc() + { + Bitmap _bitmap = convertNodeListToBitmap(); + _bitmap.Save(m_requestID + ".png", ImageFormat.Png); + } + } +}