refactored command parsing

stable0711
Jon Cundill 2012-01-05 05:07:24 +00:00
parent 60cb5a018c
commit 99bc21499b
8 changed files with 496 additions and 215 deletions

View File

@ -136,7 +136,7 @@ namespace Flocking
m_acc += sep; m_acc += sep;
m_acc += ali; m_acc += ali;
m_acc += coh; m_acc += coh;
m_acc += ori; //m_acc += ori;
} }

220
Flocking/FlockingCommand.cs Normal file
View File

@ -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 <num> 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 ();
}
}
}

View File

@ -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 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 Scene m_scene;
private FlockingModel m_model;
private FlockingView m_view;
private int m_chatChannel; private int m_chatChannel;
private UUID m_owner; private UUID m_owner;
private Dictionary<string, BoidCmdDelegate> m_commandMap = new Dictionary<string, BoidCmdDelegate> (); private Dictionary<string, BoidCmdDelegate> m_commandMap = new Dictionary<string, BoidCmdDelegate> ();
private Dictionary<string, BoidCmdDefn> m_syntaxMap = new Dictionary<string, BoidCmdDefn> (); private Dictionary<string, BoidCmdDefn> m_syntaxMap = new Dictionary<string, BoidCmdDefn> ();
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_scene = scene;
m_chatChannel = channel; m_chatChannel = channel;
// who do we respond to in send messages // 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 // register our event handlers
m_scene.EventManager.OnFrame += FlockUpdate; // plug in to the game loop
m_scene.EventManager.OnChatFromClient += ProcessChatCommand; //listen for commands sent from the client m_scene.EventManager.OnChatFromClient += ProcessChatCommand; //listen for commands sent from the client
IScriptModuleComms commsMod = m_scene.RequestModuleInterface<IScriptModuleComms>();
commsMod.OnScriptCommand += ProcessScriptCommand; // listen to scripts
}
IScriptModuleComms commsMod = scene.RequestModuleInterface<IScriptModuleComms>(); public void Start()
commsMod.OnScriptCommand += ProcessScriptCommand; {
//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 () public void Deregister ()
@ -95,26 +150,48 @@ namespace Flocking
m_scene.EventManager.OnChatFromClient -= ProcessChatCommand; m_scene.EventManager.OnChatFromClient -= ProcessChatCommand;
IScriptModuleComms commsMod = m_scene.RequestModuleInterface<IScriptModuleComms>(); IScriptModuleComms commsMod = m_scene.RequestModuleInterface<IScriptModuleComms>();
commsMod.OnScriptCommand -= ProcessScriptCommand; 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 = ""; string argStr = "";
if (args.Trim ().Length > 0) { if (args.Trim ().Length > 0) {
argStr = " <" + args + "> "; argStr = " <" + args + "> ";
} }
m_commandMap.Add (cmd, new BoidCmdDelegate (fn)); m_commandMap.Add (name, new BoidCmdDelegate (fn));
m_syntaxMap.Add (cmd, new BoidCmdDefn (cmd, args, help)); m_syntaxMap.Add (name, new BoidCmdDefn (name, args, help));
// register this command with the console // 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 #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<Boid > boids = m_model.UpdateFlockPos ();
m_view.Render (boids);
}
}
public void ProcessScriptCommand (UUID scriptId, string reqId, string module, string input, string key) public void ProcessScriptCommand (UUID scriptId, string reqId, string module, string input, string key)
{ {
if (m_module.Name != module) { if (FlockingModule.NAME != module) {
return; return;
} }
@ -173,7 +250,7 @@ namespace Flocking
// we got the signature of the command right // we got the signature of the command right
BoidCmdDelegate del = null; BoidCmdDelegate del = null;
if (m_commandMap.TryGetValue (args [0], out del)) { if (m_commandMap.TryGetValue (args [0], out del)) {
del (m_module.Name, args); del (FlockingModule.NAME, args);
} else { } else {
// we don't understand this command // we don't understand this command
// shouldn't happen // shouldn't happen

View File

@ -31,15 +31,30 @@ using Utils = OpenSim.Framework.Util;
namespace Flocking namespace Flocking
{ {
public enum FlockGoal
{
Roost = 0x01,
Perch = 0x02,
Flock = 0x04,
}
public class FlockingModel public class FlockingModel
{ {
private List<Boid> m_flock = new List<Boid>(); private List<Boid> m_flock = new List<Boid>();
private FlowField m_flowField; private FlowField m_flowField;
private BoidBehaviour m_behaviour; private BoidBehaviour m_behaviour;
private Random m_rnd = new Random(Environment.TickCount); private int m_flockSize = 100;
private int m_flockSize;
private Vector3 m_boidSize; private Vector3 m_boidSize;
private Vector3 m_startPos; 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 { public int Size {
get {return m_flockSize;} 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_behaviour = behaviour;
m_startPos = startPos; m_startPos = startPos;
} }
@ -60,21 +154,26 @@ namespace Flocking
void AddBoid (string name) void AddBoid (string name)
{ {
Boid boid = new Boid (name, m_boidSize, m_behaviour); Boid boid = new Boid (name, m_boidSize, m_behaviour);
double d1 = ( Utils.RandomClass.NextDouble() - 0.5 ) * 20;
boid.Location = m_startPos; 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; boid.Velocity = Vector3.UnitX;
m_flock.Add (boid); 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_flowField = flowField;
m_flockSize = flockSize;
m_boidSize = boidSize;
for (int i = 0; i < m_flockSize; i++) { for (int i = 0; i < m_flockSize; i++) {
AddBoid ("boid"+i ); AddBoid ("boid"+i );
UpdateFlockPos(); //UpdateFlockPos();
} }
} }
@ -88,9 +187,11 @@ namespace Flocking
public List<Boid> UpdateFlockPos () public List<Boid> UpdateFlockPos ()
{ {
if( m_active ) {
m_flock.ForEach( delegate(Boid boid) { m_flock.ForEach( delegate(Boid boid) {
boid.MoveInSceneRelativeToFlock(GetNeighbours(boid), m_flowField); boid.MoveInSceneRelativeToFlock(GetNeighbours(boid), m_flowField);
} ); } );
}
return m_flock; return m_flock;
} }
@ -99,7 +200,8 @@ namespace Flocking
public override string ToString () public override string ToString ()
{ {
string retVal = "Num Boids: " + m_flockSize + Environment.NewLine string retVal = "Num Boids: " + m_flockSize + Environment.NewLine
+ m_behaviour.ToString(); + m_behaviour.ToString() + Environment.NewLine
+ m_flowField.ToString();
return retVal; return retVal;
} }

View File

@ -38,54 +38,42 @@ using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
namespace Flocking namespace Flocking
{ {
public class FlockingModule : INonSharedRegionModule public class FlockingModule : INonSharedRegionModule
{ {
private static readonly ILog m_log = LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType); public static string NAME = "FlockingModule";
static object m_sync = new object();
private Scene m_scene;
private FlockingModel m_model;
private FlockingView m_view;
private bool m_enabled = false; 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 int m_chatChannel = 118;
private string m_boidPrim = "boid-prim"; private string m_boidPrim = "boid-prim";
private FlockingCommandParser m_commandParser; private FlockingController m_controller;
private BoidBehaviour m_behaviour; private BoidBehaviour m_behaviour;
private int m_flockSize = 100; private int m_flockSize = 100;
private UUID m_owner;
#region IRegionModule Members #region IRegionModule Members
public void Initialise (IConfigSource source) public void Initialise (IConfigSource source)
{ {
//check if we are in the ini files //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"]; IConfig config = source.Configs ["Boids"];
if (config != null) { if (config != null) {
m_chatChannel = config.GetInt ("chat-channel", 118); m_chatChannel = config.GetInt ("chat-channel", 118);
m_boidPrim = config.GetString ("boid-prim", "boidPrim"); m_boidPrim = config.GetString ("boid-prim", "boidPrim");
m_flockSize = config.GetInt ("flock-size", 100); m_flockSize = config.GetInt ("flock-size", 100);
m_behaviour = new BoidBehaviour(); m_behaviour = new BoidBehaviour ();
m_behaviour.maxSpeed = config.GetFloat("max-speed", 3f); m_behaviour.maxSpeed = config.GetFloat ("max-speed", 1f);
m_behaviour.maxForce = config.GetFloat("max-force", 0.25f); m_behaviour.maxForce = config.GetFloat ("max-force", 0.25f);
m_behaviour.neighbourDistance = config.GetFloat("neighbour-dist", 25f); m_behaviour.neighbourDistance = config.GetFloat ("neighbour-dist", 25f);
m_behaviour.desiredSeparation = config.GetFloat("desired-separation", 20f); m_behaviour.desiredSeparation = config.GetFloat ("desired-separation", 20f);
m_behaviour.tolerance = config.GetFloat("tolerance", 5f); m_behaviour.tolerance = config.GetFloat ("tolerance", 5f);
m_behaviour.separationWeighting = config.GetFloat("separation-weighting", 1.5f); m_behaviour.separationWeighting = config.GetFloat ("separation-weighting", 1.5f);
m_behaviour.alignmentWeighting = config.GetFloat("alignment-weighting", 1f); m_behaviour.alignmentWeighting = config.GetFloat ("alignment-weighting", 1f);
m_behaviour.cohesionWeighting = config.GetFloat("cohesion-weighting", 1f); m_behaviour.cohesionWeighting = config.GetFloat ("cohesion-weighting", 1f);
m_behaviour.lookaheadDistance = config.GetFloat("lookahead-dist", 100f); m_behaviour.lookaheadDistance = config.GetFloat ("lookahead-dist", 100f);
// we're in the config - so turn on this module // we're in the config - so turn on this module
m_enabled = true; m_enabled = true;
@ -94,42 +82,42 @@ namespace Flocking
public void AddRegion (Scene scene) 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) public void RegionLoaded (Scene scene)
{ {
if (m_enabled) { if (m_enabled) {
// who is the owner for the flock in this region //set up the boid module
m_owner = scene.RegionInfo.EstateSettings.EstateOwner; m_controller = new FlockingController (scene, m_behaviour, m_chatChannel, m_boidPrim, m_flockSize);
RegisterCommand (new RoostCommand());
//register command handler RegisterCommand (new StopCommand());
m_commandParser = new FlockingCommandParser(this, scene, m_chatChannel); RegisterCommand (new StartCommand());
RegisterCommands (); RegisterCommand (new SetSizeCommand());
RegisterCommand (new ShowStatsCommand());
// init view RegisterCommand (new SetPrimCommand());
m_view = new FlockingView (scene); RegisterCommand (new SetPositionCommand());
m_view.PostInitialize (m_owner); RegisterCommand (new SetBoundsCommand());
m_view.BoidPrim = m_boidPrim; RegisterCommand (new SetFrameRateCommand());
RegisterCommand (new SetParameterCommand());
} }
} }
public void RegisterCommand (FlockingCommand cmd)
{
m_controller.AddCommand( this, cmd);
}
public void RemoveRegion (Scene scene) public void RemoveRegion (Scene scene)
{ {
if (m_enabled) { if (m_enabled) {
m_scene.EventManager.OnFrame -= FlockUpdate; m_controller.Deregister ();
m_commandParser.Deregister();
} }
} }
public string Name { public string Name {
get { return "FlockingModule"; } get { return NAME; }
} }
public bool IsSharedModule { public bool IsSharedModule {
@ -138,141 +126,8 @@ namespace Flocking
#endregion #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<Boid > 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 <num> 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 #region IRegionModuleBase Members
public void Close () public void Close ()
{ {
} }

View File

@ -59,6 +59,11 @@ namespace Flocking
set{ m_boidPrim = value; } set{ m_boidPrim = value; }
} }
public Scene Scene {
get {return m_scene;}
}
public Vector3 GetBoidSize () public Vector3 GetBoidSize ()
{ {
float offsetHeight; float offsetHeight;

View File

@ -63,16 +63,16 @@ namespace Flocking
/// Height. /// Height.
/// </param> /// </param>
/// ///
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_scene = scene;
m_startX = Math.Max (BUFFER, centre.X - width / 2f); m_startX = Math.Max (BUFFER, minX);
m_startY = Math.Max (BUFFER, centre.Y - depth / 2f); m_startY = Math.Max (BUFFER, minY);
m_startZ = Math.Max (BUFFER, centre.Z - height / 2f); m_startZ = Math.Max (BUFFER, minZ);
m_endX = Math.Min (Util.SCENE_SIZE - BUFFER, centre.X + width / 2f); m_endX = Math.Min (Util.SCENE_SIZE - BUFFER, maxX);
m_endY = Math.Min (Util.SCENE_SIZE - BUFFER, centre.Y + depth / 2f); m_endY = Math.Min (Util.SCENE_SIZE - BUFFER, maxY);
m_endZ = Math.Min (Util.SCENE_SIZE - BUFFER, centre.Z + height / 2f); m_endZ = Math.Min (Util.SCENE_SIZE - BUFFER, maxZ);
// build the flow field over the given bounds // build the flow field over the given bounds
Initialize (); 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) private bool inBounds (int x, int y, int z)
{ {
return x >= 0 && x < 256 && y >= 0 && y < 256 && z >= 0; 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]; 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);
}
} }
} }

View File

@ -25,6 +25,7 @@
<Reference name="OpenSim.Framework.Communications" path="../../../bin/" /> <Reference name="OpenSim.Framework.Communications" path="../../../bin/" />
<Reference name="OpenSim.Region.Framework" path="../../../bin/" /> <Reference name="OpenSim.Region.Framework" path="../../../bin/" />
<Reference name="OpenSim.Framework.Console" path="../../../bin/" /> <Reference name="OpenSim.Framework.Console" path="../../../bin/" />
<Reference name="OpenSim.Services.Interfaces" path="../../../bin/" />
<Reference name="OpenMetaverseTypes" path="../../../bin/" /> <Reference name="OpenMetaverseTypes" path="../../../bin/" />
<Reference name="OpenMetaverse" path="../../../bin/" /> <Reference name="OpenMetaverse" path="../../../bin/" />
<Files> <Files>