diff --git a/Flocking/Boid.cs b/Flocking/Boid.cs index 310a9ec..c1d69b9 100644 --- a/Flocking/Boid.cs +++ b/Flocking/Boid.cs @@ -136,7 +136,7 @@ namespace Flocking m_acc += sep; m_acc += ali; m_acc += coh; - m_acc += ori; + //m_acc += ori; } diff --git a/Flocking/FlockingCommand.cs b/Flocking/FlockingCommand.cs new file mode 100644 index 0000000..6242e96 --- /dev/null +++ b/Flocking/FlockingCommand.cs @@ -0,0 +1,220 @@ +/* + * Copyright (c) Contributors, https://github.com/jonc/osboids + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using log4net; +using OpenMetaverse; +using OpenSim.Region.Framework.Scenes; + +namespace Flocking +{ + public abstract class FlockingCommand + { + protected static readonly ILog m_log = LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType); + protected FlockingController m_controller; + protected string m_name; + protected string m_args; + protected string m_description; + + public FlockingCommand( string name, string args, string description ) { + m_name = name; + m_args = args; + m_description = description; + } + + public void Handle (string module, string[] args) { + if( ShouldHandleCmd() ) { + Invoke( args ); + } + } + + private bool ShouldHandleCmd () + { + return View.Scene.ConsoleScene () == View.Scene; + } + + public abstract void Invoke( string[] args ); + + public string Name { + get{ return m_name;} + } + + public string Params { + get{ return m_args; } + } + + public string Description { + get{ return m_description;} + } + + public FlockingController Controller { + get{ return m_controller; } + set{ m_controller = value; } + } + + public FlockingModel Model { + get { return Controller.Model; } + } + + public FlockingView View { + get { return Controller.View; } + } + } + + public class RoostCommand : FlockingCommand { + + public RoostCommand() : base( "roost", "", "return all the boids to the start position and remove them from the scene") {} + + public override void Invoke (string[] args) { + if( Model.Active ) { + Model.Goal = FlockGoal.Roost; + } else { + Controller.ShowResponse ("Flock is not active, roost has no effect", args); + } + } + } + + public class StopCommand : FlockingCommand { + + public StopCommand() : base("stop", "", "stop all Flocking"){} + + public override void Invoke (string[] args) { + m_log.Info ("stopping the flocking activity"); + Model.Active = false; + View.Clear (); + } + } + + public class SetPositionCommand : FlockingCommand { + public SetPositionCommand() : base("position", "x,y,z", "location that the boids will start flocking from") {} + + public override void Invoke (string[] args) + { + float x = Convert.ToSingle (args [1]); + float y = Convert.ToSingle (args [2]); + float z = Convert.ToSingle (args [3]); + Vector3 startPos = new Vector3 (x, y, z); + if (Model.ContainsPoint (startPos)) { + Model.StartPosition = startPos; + } else { + Controller.ShowResponse (startPos + "is not within the flow field", args); + } + } + } + + public class SetParameterCommand : FlockingCommand { + public SetParameterCommand() : base("set", "name, value", "change the flock behaviour properties"){} + + public override void Invoke (string[] args) + { + string name = args [1]; + string newVal = args [2]; + + BoidBehaviour behaviour = Model.Behaviour; + + if (behaviour.IsValidParameter (name)) { + behaviour.SetParameter (name, newVal); + } else { + Controller.ShowResponse (name + "is not a valid flock parameter", args); + Controller.ShowResponse ("valid parameters are: " + behaviour.GetList (), args); + } + } + } + + public class SetFrameRateCommand : FlockingCommand { + public SetFrameRateCommand() : base("framerate", "num", "[debugging] only update boids every frames") {} + + public override void Invoke (string[] args) + { + int frameRate = Convert.ToInt32 (args [1]); + Controller.FrameUpdateRate = frameRate; + } + } + + public class SetBoundsCommand : FlockingCommand { + public SetBoundsCommand() : base("bounds", "xMin,xMax,yMin,yMax,zMin,zMax", "Bounds of the 3D space that the flock will be confined to") {} + + public override void Invoke (string[] args) + { + //TODO: + } + } + + public class SetSizeCommand : FlockingCommand { + public SetSizeCommand() : base("size", "num", "Adjust the size of the flock ") {} + + public override void Invoke (string [] args) + { + lock (Controller.UI_SYNC) { + int newSize = Convert.ToInt32 (args [1]); + Model.Size = newSize; + View.Clear (); + } + } + } + + public class SetPrimCommand : FlockingCommand { + public SetPrimCommand() : base("prim", "name", "set the prim used for each boid to that passed in") {} + + public override void Invoke (string[] args) + { + string primName = args [1]; + lock (Controller.UI_SYNC) { + View.BoidPrim = primName; + View.Clear (); + } + } + } + + public class ShowStatsCommand : FlockingCommand { + public ShowStatsCommand() : base("stats", "", "show flocking stats") {} + + public override void Invoke (string[] args) + { + string str = Model.ToString (); + Controller.ShowResponse (str, args); + } + } + + public class StartCommand : FlockingCommand { + public StartCommand() : base("start", "", "Start Flocking") {} + + public override void Invoke(string[] args) { + if( Model.Active ) { + Controller.ShowResponse("Already active, restarting", args); + Model.Active = false; + View.Clear(); + } + + m_log.Info ("start the flocking capability"); + Model.Goal = FlockGoal.Flock; + Controller.Start (); + Model.Active = true; + //m_module.FlockUpdate (); + } + } +} + diff --git a/Flocking/FlockingCommandParser.cs b/Flocking/FlockingController.cs similarity index 70% rename from Flocking/FlockingCommandParser.cs rename to Flocking/FlockingController.cs index 2411081..e92c318 100644 --- a/Flocking/FlockingCommandParser.cs +++ b/Flocking/FlockingController.cs @@ -63,31 +63,86 @@ namespace Flocking } } - public class FlockingCommandParser + public class FlockingController { private static readonly ILog m_log = LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType); - private IRegionModuleBase m_module; + public object UI_SYNC = new object (); + private Scene m_scene; + private FlockingModel m_model; + private FlockingView m_view; private int m_chatChannel; private UUID m_owner; private Dictionary m_commandMap = new Dictionary (); private Dictionary m_syntaxMap = new Dictionary (); + private uint m_frame = 0; + private int m_frameUpdateRate = 1; + private Vector3 m_startPos = new Vector3 (128f, 128f, 128f); + private int m_minX = 0; + private int m_maxX = 256; + private int m_minY = 0; + private int m_maxY = 256; + private int m_minZ = 0; + private int m_maxZ = 256; + - public FlockingCommandParser (IRegionModuleBase module, Scene scene, int channel) + public FlockingController (Scene scene, BoidBehaviour behaviour, int channel, string prim, int flockSize) { - m_module = module; + //make the view + // who is the owner for the flock in this region + UUID owner = scene.RegionInfo.EstateSettings.EstateOwner; + m_view = new FlockingView (scene); + m_view.PostInitialize (owner); + m_view.BoidPrim = prim; + + //make the model + FlowField field = new FlowField( scene, m_minX, m_maxX, m_minY, m_maxY, m_minZ, m_maxZ); + FlockingModel model = new FlockingModel(field, behaviour, m_startPos); + Vector3 startPos = new Vector3(128f, 128f, 128f);//scene.GetSceneObjectPart (View.BoidPrim).ParentGroup.AbsolutePosition; + model.StartPosition = startPos; // TODO: by default start from the prim + + m_model = model; m_scene = scene; m_chatChannel = channel; // who do we respond to in send messages - m_owner = scene.RegionInfo.EstateSettings.EstateOwner; + m_owner = m_scene.RegionInfo.EstateSettings.EstateOwner; // register our event handlers - m_scene.EventManager.OnChatFromClient += ProcessChatCommand; //listen for commands sent from the client - - IScriptModuleComms commsMod = scene.RequestModuleInterface(); - commsMod.OnScriptCommand += ProcessScriptCommand; + m_scene.EventManager.OnFrame += FlockUpdate; // plug in to the game loop + m_scene.EventManager.OnChatFromClient += ProcessChatCommand; //listen for commands sent from the client + IScriptModuleComms commsMod = m_scene.RequestModuleInterface(); + commsMod.OnScriptCommand += ProcessScriptCommand; // listen to scripts + } + + public void Start() + { + //ask the view how big the boid prim is + Vector3 scale = View.GetBoidSize (); + + FlowField field = new FlowField( m_scene, m_minX, m_maxX, m_minY, m_maxY, m_minZ, m_maxZ); + // init model + m_log.Info ("creating model"); + // Generate initial flock values + m_model.BoidSize = scale; + m_model.Initialise (field); + m_log.Info ("done"); + + } + + + public int FrameUpdateRate { + get { return m_frameUpdateRate; } + set { m_frameUpdateRate = value; } + } + + public FlockingModel Model { + get { return m_model; } + } + + public FlockingView View { + get { return m_view; } } public void Deregister () @@ -95,26 +150,48 @@ namespace Flocking m_scene.EventManager.OnChatFromClient -= ProcessChatCommand; IScriptModuleComms commsMod = m_scene.RequestModuleInterface(); commsMod.OnScriptCommand -= ProcessScriptCommand; + m_scene.EventManager.OnFrame -= FlockUpdate; } - public void AddCommand (string cmd, string args, string help, CommandDelegate fn) + public void AddCommand (IRegionModuleBase module, FlockingCommand cmd) { + cmd.Controller = this; + string name = cmd.Name; + string args = cmd.Params; + string help = cmd.Description; + CommandDelegate fn =cmd.Handle; + string argStr = ""; if (args.Trim ().Length > 0) { argStr = " <" + args + "> "; } - m_commandMap.Add (cmd, new BoidCmdDelegate (fn)); - m_syntaxMap.Add (cmd, new BoidCmdDefn (cmd, args, help)); + m_commandMap.Add (name, new BoidCmdDelegate (fn)); + m_syntaxMap.Add (name, new BoidCmdDefn (name, args, help)); // register this command with the console - m_scene.AddCommand (m_module, "flock-" + cmd, "flock-" + cmd + argStr, help, fn); + m_scene.AddCommand (module, "flock-" + name, "flock-" + name + argStr, help, fn); } #region handlers + public void FlockUpdate () + { + if (((m_frame++ % m_frameUpdateRate) != 0) || !m_model.Active) { + return; + } + // work out where everyone has moved to + // and tell the scene to render the new positions + lock (UI_SYNC) { + List boids = m_model.UpdateFlockPos (); + m_view.Render (boids); + } + } + + + public void ProcessScriptCommand (UUID scriptId, string reqId, string module, string input, string key) { - if (m_module.Name != module) { + if (FlockingModule.NAME != module) { return; } @@ -173,7 +250,7 @@ namespace Flocking // we got the signature of the command right BoidCmdDelegate del = null; if (m_commandMap.TryGetValue (args [0], out del)) { - del (m_module.Name, args); + del (FlockingModule.NAME, args); } else { // we don't understand this command // shouldn't happen diff --git a/Flocking/FlockingModel.cs b/Flocking/FlockingModel.cs index d742c20..b96723e 100644 --- a/Flocking/FlockingModel.cs +++ b/Flocking/FlockingModel.cs @@ -31,15 +31,30 @@ using Utils = OpenSim.Framework.Util; namespace Flocking { + public enum FlockGoal + { + Roost = 0x01, + Perch = 0x02, + Flock = 0x04, + } + public class FlockingModel { private List m_flock = new List(); private FlowField m_flowField; private BoidBehaviour m_behaviour; - private Random m_rnd = new Random(Environment.TickCount); - private int m_flockSize; + private int m_flockSize = 100; private Vector3 m_boidSize; private Vector3 m_startPos; + private FlockGoal m_goal = FlockGoal.Flock; + private bool m_active = false; + private int m_minX = 0; + private int m_maxX = 256; + private int m_minY = 0; + private int m_maxY = 256; + private int m_minZ = 0; + private int m_maxZ = 256; + public int Size { get {return m_flockSize;} @@ -52,7 +67,86 @@ namespace Flocking } } - public FlockingModel( BoidBehaviour behaviour, Vector3 startPos ) { + public FlockGoal Goal { + get { return m_goal; } + set { m_goal = value; } + } + + public int MaxX { + get { + return this.m_maxX; + } + set { + m_maxX = value; + } + } + + public int MaxY { + get { + return this.m_maxY; + } + set { + m_maxY = value; + } + } + + public int MaxZ { + get { + return this.m_maxZ; + } + set { + m_maxZ = value; + } + } + + public int MinX { + get { + return this.m_minX; + } + set { + m_minX = value; + } + } + + public int MinY { + get { + return this.m_minY; + } + set { + m_minY = value; + } + } + + public int MinZ { + get { + return this.m_minZ; + } + set { + m_minZ = value; + } + } + public bool Active { + get { return m_active; } + set { m_active = value; } + } + + public Vector3 StartPosition { + get { return m_startPos; } + set { m_startPos = value; } + } + + public BoidBehaviour Behaviour { + get { return m_behaviour; } + set { m_behaviour = value; } + } + + public Vector3 BoidSize { + set { m_boidSize = value; } + } + + + public FlockingModel( FlowField field, BoidBehaviour behaviour, Vector3 startPos ) { + m_flowField = field; m_behaviour = behaviour; m_startPos = startPos; } @@ -60,21 +154,26 @@ namespace Flocking void AddBoid (string name) { Boid boid = new Boid (name, m_boidSize, m_behaviour); - - boid.Location = m_startPos; + double d1 = ( Utils.RandomClass.NextDouble() - 0.5 ) * 20; + double d2 = ( Utils.RandomClass.NextDouble() - 0.5 ) * 20; + double d3 = ( Utils.RandomClass.NextDouble() - 0.5 ) * 20; + boid.Location = m_startPos + new Vector3( (float)d1, (float)d2, (float)d3 ); boid.Velocity = Vector3.UnitX; m_flock.Add (boid); } + + public bool ContainsPoint (Vector3 position) + { + return m_flowField.ContainsPoint( position ); + } - public void Initialise (int flockSize, Vector3 boidSize, FlowField flowField) + public void Initialise (FlowField flowField) { m_flowField = flowField; - m_flockSize = flockSize; - m_boidSize = boidSize; for (int i = 0; i < m_flockSize; i++) { AddBoid ("boid"+i ); - UpdateFlockPos(); + //UpdateFlockPos(); } } @@ -88,9 +187,11 @@ namespace Flocking public List UpdateFlockPos () { - m_flock.ForEach( delegate(Boid boid) { - boid.MoveInSceneRelativeToFlock(GetNeighbours(boid), m_flowField); - } ); + if( m_active ) { + m_flock.ForEach( delegate(Boid boid) { + boid.MoveInSceneRelativeToFlock(GetNeighbours(boid), m_flowField); + } ); + } return m_flock; } @@ -99,7 +200,8 @@ namespace Flocking public override string ToString () { string retVal = "Num Boids: " + m_flockSize + Environment.NewLine - + m_behaviour.ToString(); + + m_behaviour.ToString() + Environment.NewLine + + m_flowField.ToString(); return retVal; } diff --git a/Flocking/FlockingModule.cs b/Flocking/FlockingModule.cs index 3fac531..46e69c5 100644 --- a/Flocking/FlockingModule.cs +++ b/Flocking/FlockingModule.cs @@ -38,54 +38,42 @@ using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Services.Interfaces; - namespace Flocking { public class FlockingModule : INonSharedRegionModule { - private static readonly ILog m_log = LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType); - static object m_sync = new object(); + public static string NAME = "FlockingModule"; - private Scene m_scene; - private FlockingModel m_model; - private FlockingView m_view; private bool m_enabled = false; - private bool m_active = false; - private uint m_frame = 0; - private int m_frameUpdateRate = 1; private int m_chatChannel = 118; private string m_boidPrim = "boid-prim"; - private FlockingCommandParser m_commandParser; + private FlockingController m_controller; private BoidBehaviour m_behaviour; private int m_flockSize = 100; - private UUID m_owner; - #region IRegionModule Members - - public void Initialise (IConfigSource source) { //check if we are in the ini files - //if so get some physical constants out of them and pass into the model + //if so get some default values out of them and pass them onto the controller IConfig config = source.Configs ["Boids"]; if (config != null) { m_chatChannel = config.GetInt ("chat-channel", 118); m_boidPrim = config.GetString ("boid-prim", "boidPrim"); m_flockSize = config.GetInt ("flock-size", 100); - m_behaviour = new BoidBehaviour(); - m_behaviour.maxSpeed = config.GetFloat("max-speed", 3f); - m_behaviour.maxForce = config.GetFloat("max-force", 0.25f); - m_behaviour.neighbourDistance = config.GetFloat("neighbour-dist", 25f); - m_behaviour.desiredSeparation = config.GetFloat("desired-separation", 20f); - m_behaviour.tolerance = config.GetFloat("tolerance", 5f); - m_behaviour.separationWeighting = config.GetFloat("separation-weighting", 1.5f); - m_behaviour.alignmentWeighting = config.GetFloat("alignment-weighting", 1f); - m_behaviour.cohesionWeighting = config.GetFloat("cohesion-weighting", 1f); - m_behaviour.lookaheadDistance = config.GetFloat("lookahead-dist", 100f); + m_behaviour = new BoidBehaviour (); + m_behaviour.maxSpeed = config.GetFloat ("max-speed", 1f); + m_behaviour.maxForce = config.GetFloat ("max-force", 0.25f); + m_behaviour.neighbourDistance = config.GetFloat ("neighbour-dist", 25f); + m_behaviour.desiredSeparation = config.GetFloat ("desired-separation", 20f); + m_behaviour.tolerance = config.GetFloat ("tolerance", 5f); + m_behaviour.separationWeighting = config.GetFloat ("separation-weighting", 1.5f); + m_behaviour.alignmentWeighting = config.GetFloat ("alignment-weighting", 1f); + m_behaviour.cohesionWeighting = config.GetFloat ("cohesion-weighting", 1f); + m_behaviour.lookaheadDistance = config.GetFloat ("lookahead-dist", 100f); // we're in the config - so turn on this module m_enabled = true; @@ -94,42 +82,42 @@ namespace Flocking public void AddRegion (Scene scene) { - //m_log.Info ("ADDING FLOCKING"); - m_scene = scene; - if (m_enabled) { - - //register handlers - m_scene.EventManager.OnFrame += FlockUpdate; - } } public void RegionLoaded (Scene scene) { if (m_enabled) { - // who is the owner for the flock in this region - m_owner = scene.RegionInfo.EstateSettings.EstateOwner; - - //register command handler - m_commandParser = new FlockingCommandParser(this, scene, m_chatChannel); - RegisterCommands (); - - // init view - m_view = new FlockingView (scene); - m_view.PostInitialize (m_owner); - m_view.BoidPrim = m_boidPrim; + //set up the boid module + m_controller = new FlockingController (scene, m_behaviour, m_chatChannel, m_boidPrim, m_flockSize); + RegisterCommand (new RoostCommand()); + RegisterCommand (new StopCommand()); + RegisterCommand (new StartCommand()); + RegisterCommand (new SetSizeCommand()); + RegisterCommand (new ShowStatsCommand()); + RegisterCommand (new SetPrimCommand()); + RegisterCommand (new SetPositionCommand()); + RegisterCommand (new SetBoundsCommand()); + RegisterCommand (new SetFrameRateCommand()); + RegisterCommand (new SetParameterCommand()); } } + public void RegisterCommand (FlockingCommand cmd) + { + m_controller.AddCommand( this, cmd); + } + + + public void RemoveRegion (Scene scene) { if (m_enabled) { - m_scene.EventManager.OnFrame -= FlockUpdate; - m_commandParser.Deregister(); + m_controller.Deregister (); } } public string Name { - get { return "FlockingModule"; } + get { return NAME; } } public bool IsSharedModule { @@ -138,141 +126,8 @@ namespace Flocking #endregion - #region EventHandlers - - public void FlockUpdate () - { - if (((m_frame++ % m_frameUpdateRate) != 0) || !m_active || !m_enabled) { - return; - } - // work out where everyone has moved to - // and tell the scene to render the new positions - lock( m_sync ) { - List boids = m_model.UpdateFlockPos (); - m_view.Render (boids); - } - } - - #endregion - - - private void BuildFlowField(Vector3 centre, int width, int depth, int height) { - m_log.Info("building flow field"); - //build a flow field based on the scene - FlowField field = new FlowField(m_scene, centre, width, depth, height); - m_log.Info("built"); - //ask the view how big the boid prim is - Vector3 scale = m_view.GetBoidSize(); - - Vector3 startPos = m_scene.GetSceneObjectPart(m_view.BoidPrim).ParentGroup.AbsolutePosition; - // init model - m_log.Info("creating model"); - m_model = new FlockingModel (m_behaviour, startPos ); - // Generate initial flock values - m_model.Initialise (m_flockSize, scale, field); - m_log.Info("done"); - - } - - #region Command Handling - - - private void RegisterCommands () - { - m_commandParser.AddCommand ("stop", "", "Stop all Flocking", HandleStopCmd); - m_commandParser.AddCommand ("start", "", "Start Flocking", HandleStartCmd); - m_commandParser.AddCommand ("size", "num", "Adjust the size of the flock ", HandleSetSizeCmd); - m_commandParser.AddCommand ("stats", "", "show flocking stats", HandleShowStatsCmd); - m_commandParser.AddCommand ("prim", "name", "set the prim used for each boid to that passed in", HandleSetPrimCmd); - m_commandParser.AddCommand ("framerate", "num", "[debugging] only update boids every frames", HandleSetFrameRateCmd); - m_commandParser.AddCommand ("set", "name, value", "change the flock behaviour properties", HandleSetParameterCmd); - } - - private bool ShouldHandleCmd () - { - return m_scene.ConsoleScene () == m_scene; - } - - public void HandleSetParameterCmd(string module, string[] args) - { - if (ShouldHandleCmd ()) { - string name = args[1]; - string newVal = args[2]; - - if( m_behaviour.IsValidParameter( name ) ) { - m_behaviour.SetParameter(name, newVal); - } else { - m_commandParser.ShowResponse( name + "is not a valid flock parameter", args ); - m_commandParser.ShowResponse( "valid parameters are: " + m_behaviour.GetList(), args); - } - } - } - - public void HandleStopCmd (string module, string[] args) - { - if (ShouldHandleCmd ()) { - m_log.Info ("stop the flocking capability"); - m_active = false; - m_view.Clear (); - } - } - - void HandleSetFrameRateCmd (string module, string[] args) - { - if (ShouldHandleCmd ()) { - int frameRate = Convert.ToInt32( args[1] ); - m_frameUpdateRate = frameRate; - } - } - - public void HandleStartCmd (string module, string[] args) - { - if (ShouldHandleCmd ()) { - m_log.Info ("start the flocking capability"); - BuildFlowField(new Vector3(128f, 128f, 128f), 200, 200, 200); - m_active = true; - FlockUpdate (); - } - } - - public void HandleSetSizeCmd (string module, string[] args) - { - if (ShouldHandleCmd ()) { - lock( m_sync ) { - int newSize = Convert.ToInt32(args[1]); - m_model.Size = newSize; - m_view.Clear(); - } - } - } - - public void HandleShowStatsCmd (string module, string[] args) - { - if (ShouldHandleCmd ()) { - string str = m_model.ToString(); - m_commandParser.ShowResponse (str, args); - } - } - - public void HandleSetPrimCmd (string module, string[] args) - { - if (ShouldHandleCmd ()) { - string primName = args[1]; - lock(m_sync) { - m_view.BoidPrim = primName; - m_view.Clear(); - } - } - } - - #endregion - - - #region IRegionModuleBase Members - - public void Close () { } diff --git a/Flocking/FlockingView.cs b/Flocking/FlockingView.cs index 5805a3d..5cabd31 100644 --- a/Flocking/FlockingView.cs +++ b/Flocking/FlockingView.cs @@ -58,6 +58,11 @@ namespace Flocking get{ return m_boidPrim; } set{ m_boidPrim = value; } } + + public Scene Scene { + get {return m_scene;} + } + public Vector3 GetBoidSize () { diff --git a/Flocking/FlowField.cs b/Flocking/FlowField.cs index 265f13b..d111bc0 100644 --- a/Flocking/FlowField.cs +++ b/Flocking/FlowField.cs @@ -63,16 +63,16 @@ namespace Flocking /// Height. /// /// - public FlowField (Scene scene, Vector3 centre, int width, int depth, int height) + public FlowField (Scene scene, int minX, int maxX, int minY, int maxY, int minZ, int maxZ) { m_scene = scene; - m_startX = Math.Max (BUFFER, centre.X - width / 2f); - m_startY = Math.Max (BUFFER, centre.Y - depth / 2f); - m_startZ = Math.Max (BUFFER, centre.Z - height / 2f); - m_endX = Math.Min (Util.SCENE_SIZE - BUFFER, centre.X + width / 2f); - m_endY = Math.Min (Util.SCENE_SIZE - BUFFER, centre.Y + depth / 2f); - m_endZ = Math.Min (Util.SCENE_SIZE - BUFFER, centre.Z + height / 2f); + m_startX = Math.Max (BUFFER, minX); + m_startY = Math.Max (BUFFER, minY); + m_startZ = Math.Max (BUFFER, minZ); + m_endX = Math.Min (Util.SCENE_SIZE - BUFFER, maxX); + m_endY = Math.Min (Util.SCENE_SIZE - BUFFER, maxY); + m_endZ = Math.Min (Util.SCENE_SIZE - BUFFER, maxZ); // build the flow field over the given bounds Initialize (); @@ -142,6 +142,16 @@ namespace Flocking } } + public bool ContainsPoint (Vector3 p) + { + return p.X > m_startX && + p.X < m_endX && + p.Y > m_startY && + p.Y < m_endY && + p.Z > m_startZ && + p.Z < m_endZ; + } + private bool inBounds (int x, int y, int z) { return x >= 0 && x < 256 && y >= 0 && y < 256 && z >= 0; @@ -238,6 +248,17 @@ namespace Flocking { return m_field [(int)loc.X, (int)loc.Y, (int)loc.Z]; } + + public override string ToString () + { + return string.Format ("[FlowField]" + Environment.NewLine + + "startX = {0}" + Environment.NewLine + + "endX = {1}" + Environment.NewLine + + "startY = {2}" + Environment.NewLine + + "endY = {3}" + Environment.NewLine + + "startZ = {4}" + Environment.NewLine + + "endZ = {5}", m_startX, m_endX, m_startY, m_endY, m_startZ, m_endZ); + } } } diff --git a/prebuild.xml b/prebuild.xml index 839b00c..5289f1b 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -25,6 +25,7 @@ +