Many changes to support per region configuration and project name change

pull/1/merge
Jak Daniels 2014-12-24 16:29:19 +00:00
parent d75428a078
commit d18d37faf6
11 changed files with 242 additions and 188 deletions

View File

@ -20,3 +20,8 @@
refactored the code
added some more config items to set the region border size (no go zone) and the max height
added support to the module for varregions
24/12/2014
renamed the modeul to OpenSimBirds, changed all references to [Bb]oids to [Bb]irds in code
change the configuration to use own ini file and to setup per region configurations
changed Util class to BirdsUtil to avoid clash with OpenSim.Util

View File

@ -1,5 +1,5 @@
The following people have contributed to the development of the OpenSimBoids module
The following people have contributed to the development of the OpenSimBirds module
* Jon Cundill - initial implementation
* Jak Daniels - refactor for opensim 0.8.x and varregions
* Jak Daniels - refactor for opensim 0.8.x and varregions and per region configuration

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Contributors, https://github.com/jonc/osboids
* Copyright (c) Contributors, https://github.com/jonc/osbirds
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
@ -31,7 +31,7 @@ using OpenMetaverse;
namespace Flocking
{
public class Boid
public class Bird
{
private static readonly ILog m_log = LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType);
private string m_id;
@ -43,33 +43,33 @@ namespace Flocking
private FlockingModel m_model;
private FlowMap m_flowMap;
private int m_regionX;
private int m_regionY;
private int m_regionZ;
private int m_regionX;
private int m_regionY;
private int m_regionZ;
private float m_regionBorder;
/// <summary>
/// Initializes a new instance of the <see cref="Flocking.Boid"/> class.
/// Initializes a new instance of the <see cref="Flocking.Bird"/> class.
/// </summary>
/// <param name='l'>
/// L. the initial position of this boid
/// L. the initial position of this bird
/// </param>
/// <param name='ms'>
/// Ms. max speed this boid can attain
/// Ms. max speed this bird can attain
/// </param>
/// <param name='mf'>
/// Mf. max force / acceleration this boid can extert
/// Mf. max force / acceleration this bird can extert
/// </param>
public Boid (string id, FlockingModel model, FlowMap flowMap)
public Bird (string id, FlockingModel model, FlowMap flowMap)
{
m_id = id;
m_acc = Vector3.Zero;
m_vel = new Vector3 (m_rndnums.Next (-1, 1), m_rndnums.Next (-1, 1), m_rndnums.Next (-1, 1));
m_model = model;
m_flowMap = flowMap;
m_regionX = m_flowMap.LengthX;
m_regionY = m_flowMap.LengthY;
m_regionZ = m_flowMap.LengthZ;
m_flowMap = flowMap;
m_regionX = m_flowMap.LengthX;
m_regionY = m_flowMap.LengthY;
m_regionZ = m_flowMap.LengthZ;
m_regionBorder = m_flowMap.Border;
}
@ -87,15 +87,15 @@ namespace Flocking
}
/// <summary>
/// Moves our boid in the scene relative to the rest of the flock.
/// Moves our bird in the scene relative to the rest of the flock.
/// </summary>
/// <param name='boids'>
/// Boids. all the other chaps in the scene
/// <param name='birds'>
/// Birds. all the other chaps in the scene
/// </param>
public void MoveInSceneRelativeToFlock (List<Boid> boids)
public void MoveInSceneRelativeToFlock (List<Bird> birds)
{
// we would like to stay with our mates
Flock (boids);
Flock (birds);
// our first priority is to not hurt ourselves
AvoidObstacles ();
@ -119,13 +119,13 @@ namespace Flocking
/// our desire to move towards the flock centre
///
/// </summary>
void Flock (List<Boid> boids)
void Flock (List<Bird> birds)
{
// calc the force vectors on this boid
Vector3 sep = Separate (boids); // Separation
Vector3 ali = Align (boids); // Alignment
Vector3 coh = Cohesion (boids); // Cohesion
// calc the force vectors on this bird
Vector3 sep = Separate (birds); // Separation
Vector3 ali = Align (birds); // Alignment
Vector3 coh = Cohesion (birds); // Cohesion
// Arbitrarily weight these forces
//TODO: expose these consts
@ -135,7 +135,7 @@ namespace Flocking
//coh.mult(1.0);
coh *= 1.0f;
// Add the force vectors to the current acceleration of the boid
// Add the force vectors to the current acceleration of the bird
//acc.add(sep);
m_acc += sep;
//acc.add(ali);
@ -159,7 +159,7 @@ namespace Flocking
m_vel += m_acc;
// Limit speed
//m_vel.limit(maxspeed);
m_vel = Util.Limit (m_vel, m_model.MaxSpeed);
m_vel = BirdsUtil.Limit (m_vel, m_model.MaxSpeed);
m_loc += m_vel;
// Reset accelertion to 0 each cycle
m_acc *= 0.0f;
@ -209,7 +209,7 @@ namespace Flocking
//steer = target.sub(desired,m_vel);
steer = Vector3.Subtract (desired, m_vel);
//steer.limit(maxforce); // Limit to maximum steering force
steer = Util.Limit (steer, m_model.MaxForce);
steer = BirdsUtil.Limit (steer, m_model.MaxForce);
} else {
steer = Vector3.Zero;
}
@ -257,7 +257,7 @@ namespace Flocking
// or try decreasing our acceleration
// or turn around - coz where we came from was OK
if (m_loc.X < m_regionBorder || m_loc.X > m_regionX - m_regionBorder)
m_vel.X = -m_vel.X;
m_vel.X = -m_vel.X;
if (m_loc.Y < m_regionBorder || m_loc.Y > m_regionY - m_regionBorder)
m_vel.Y = -m_vel.Y;
if (m_loc.Z < 21 || m_loc.Z > m_regionZ )
@ -265,19 +265,19 @@ namespace Flocking
}
/// <summary>
/// Separate ourselves from the specified boids.
/// Separate ourselves from the specified birds.
/// keeps us a respectable distance from our closest neighbours whilst still
/// being part of our local flock
/// </summary>
/// <param name='boids'>
/// Boids. all the boids in the scene
/// <param name='birds'>
/// Birds. all the birds in the scene
/// </param>
Vector3 Separate (List<Boid> boids)
Vector3 Separate (List<Bird> birds)
{
Vector3 steer = new Vector3 (0, 0, 0);
int count = 0;
// For every boid in the system, check if it's too close
foreach (Boid other in boids) {
// For every bird in the system, check if it's too close
foreach (Bird other in birds) {
float d = Vector3.Distance (m_loc, other.Location);
// If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
if ((d > 0) && (d < m_model.DesiredSeparation)) {
@ -301,24 +301,24 @@ namespace Flocking
steer *= m_model.MaxSpeed;
steer -= m_vel;
//steer.limit(maxforce);
steer = Util.Limit (steer, m_model.MaxForce);
steer = BirdsUtil.Limit (steer, m_model.MaxForce);
}
return steer;
}
/// <summary>
/// Align our boid within the flock.
/// For every nearby boid in the system, calculate the average velocity
/// Align our bird within the flock.
/// For every nearby bird in the system, calculate the average velocity
/// and move us towards that - this keeps us moving with the flock.
/// </summary>
/// <param name='boids'>
/// Boids. all the boids in the scene - we only really care about those in the neighbourdist
/// <param name='birds'>
/// Birds. all the birds in the scene - we only really care about those in the neighbourdist
/// </param>
Vector3 Align (List<Boid> boids)
Vector3 Align (List<Bird> birds)
{
Vector3 steer = new Vector3 (0, 0, 0);
int count = 0;
foreach (Boid other in boids) {
foreach (Bird other in birds) {
float d = Vector3.Distance (m_loc, other.Location);
if ((d > 0) && (d < m_model.NeighbourDistance)) {
steer += other.Velocity;
@ -336,7 +336,7 @@ namespace Flocking
steer *= m_model.MaxSpeed;
steer -= m_vel;
//steer.limit(maxforce);
steer = Util.Limit (steer, m_model.MaxForce);
steer = BirdsUtil.Limit (steer, m_model.MaxForce);
}
return steer;
@ -344,18 +344,18 @@ namespace Flocking
/// <summary>
/// MAintain the cohesion of our local flock
/// For the average location (i.e. center) of all nearby boids, calculate our steering vector towards that location
/// For the average location (i.e. center) of all nearby birds, calculate our steering vector towards that location
/// </summary>
/// <param name='boids'>
/// Boids. the boids in the scene
/// <param name='birds'>
/// Birds. the birds in the scene
/// </param>
Vector3 Cohesion (List<Boid> boids)
Vector3 Cohesion (List<Bird> birds)
{
Vector3 sum = Vector3.Zero; // Start with empty vector to accumulate all locations
int count = 0;
foreach (Boid other in boids) {
foreach (Bird other in birds) {
float d = Vector3.Distance (m_loc, other.Location);
if ((d > 0) && (d < m_model.NeighbourDistance)) {
sum += other.Location; // Add location

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) Contributors, https://github.com/jonc/osboids
* https://github.com/JakDaniels/OpenSimBirds
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
@ -29,7 +30,7 @@ using OpenMetaverse;
namespace Flocking
{
public class Util
public class BirdsUtil
{
public static Vector3 Limit (Vector3 initial, float maxLen)
{

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) Contributors, https://github.com/jonc/osboids
* https://github.com/JakDaniels/OpenSimBirds
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
@ -32,13 +33,13 @@ namespace Flocking
{
public class FlockingModel
{
private List<Boid> m_flock = new List<Boid>();
private List<Bird> m_flock = new List<Bird>();
private FlowMap m_flowMap;
private float m_maxSpeed;
private float m_maxForce;
private float m_neighbourDistance;
private float m_desiredSeparation;
private float m_tolerance;
private float m_tolerance;
private float m_border;
private Random m_rnd = new Random(Environment.TickCount);
@ -49,7 +50,7 @@ namespace Flocking
if( value < m_flock.Count ) {
m_flock.RemoveRange( 0, m_flock.Count - value );
} else while( value > m_flock.Count ) {
AddBoid( "boid"+m_flock.Count);
AddBird( "Bird"+m_flock.Count);
}
}
}
@ -59,15 +60,15 @@ namespace Flocking
m_maxForce = maxForce;
m_neighbourDistance = neighbourDistance;
m_desiredSeparation = desiredSeparation;
m_tolerance = tolerance;
m_tolerance = tolerance;
m_border = border;
}
void AddBoid (string name)
void AddBird (string name)
{
Boid boid = new Boid (name, this, m_flowMap);
Bird Bird = new Bird (name, this, m_flowMap);
// find an initial random location for this Boid
// find an initial random location for this Bird
// somewhere not within an obstacle
int xInit = m_rnd.Next(m_flowMap.LengthX);
int yInit = m_rnd.Next(m_flowMap.LengthY);
@ -79,8 +80,8 @@ namespace Flocking
zInit = m_rnd.Next(m_flowMap.LengthZ);
}
boid.Location = new Vector3 (Convert.ToSingle(xInit), Convert.ToSingle(yInit), Convert.ToSingle(zInit));
m_flock.Add (boid);
Bird.Location = new Vector3 (Convert.ToSingle(xInit), Convert.ToSingle(yInit), Convert.ToSingle(zInit));
m_flock.Add (Bird);
}
public float MaxSpeed {
@ -108,14 +109,14 @@ namespace Flocking
{
m_flowMap = flowMap;
for (int i = 0; i < num; i++) {
AddBoid ("boid"+i );
AddBird ("Bird"+i );
}
}
public List<Boid> UpdateFlockPos ()
public List<Bird> UpdateFlockPos ()
{
foreach (Boid b in m_flock) {
b.MoveInSceneRelativeToFlock(m_flock); // Passing the entire list of boids to each boid individually
foreach (Bird b in m_flock) {
b.MoveInSceneRelativeToFlock(m_flock); // Passing the entire list of Birds to each Bird individually
}
return m_flock;

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) Contributors, https://github.com/jonc/osboids
* https://github.com/JakDaniels/OpenSimBirds
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
@ -26,9 +27,11 @@
*/
using System;
using System.Timers;
using System.Net;
using System.IO;
using System.Text;
using System.Collections.Generic;
using OpenMetaverse;
using System.IO;
using Nini.Config;
using System.Threading;
using log4net;
@ -38,19 +41,18 @@ using OpenSim.Framework;
using OpenSim.Framework.Console;
using Mono.Addins;
[assembly: Addin("BoidsModule", "0.1")]
[assembly: Addin("OpenSimBirds", "0.2")]
[assembly: AddinDependency("OpenSim", "0.5")]
namespace Flocking
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "OpenSimBirds")]
public class FlockingModule : INonSharedRegionModule
{
#region Fields
private static readonly ILog m_log = LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType);
static object m_sync = new object();
public string m_name = "BoidsModule";
public string m_name = "OpenSimBirds";
private Scene m_scene;
private FlockingModel m_model;
private FlockingView m_view;
@ -59,7 +61,7 @@ namespace Flocking
private uint m_frame = 0;
private int m_frameUpdateRate = 1;
private int m_chatChannel = 118;
private string m_boidPrim;
private string m_birdPrim;
private int m_flockSize = 100;
private float m_maxSpeed;
private float m_maxForce;
@ -68,49 +70,67 @@ namespace Flocking
private float m_tolerance;
private float m_borderSize;
private int m_maxHeight;
static object m_sync = new object();
public IConfigSource m_config;
private UUID m_owner;
#endregion
#region IRegionModuleBase implementation
public string Name { get { return m_name; } }
public Type ReplaceableInterface { get { return null; } }
public bool IsSharedModule { get { return false; } }
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
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_maxSpeed = config.GetFloat("max-speed", 3f);
m_maxForce = config.GetFloat("max-force", 0.25f);
m_neighbourDistance = config.GetFloat("neighbour-dist", 25f);
m_desiredSeparation = config.GetFloat("desired-separation", 20f);
m_tolerance = config.GetFloat("tolerance", 5f);
m_borderSize = config.GetFloat("border-size", 5f);
m_maxHeight = config.GetInt("max-height", 256);
m_enabled = config.GetBoolean("enabled", false);
}
if (m_enabled)
{
m_log.InfoFormat("[BOIDS] Enabled on channel {0} with Flock Size {1}", m_chatChannel, m_flockSize);
//m_ready = true;
return;
}
m_config = source;
}
public void PostInitialise()
{
}
public void AddRegion (Scene scene)
{
m_scene = scene;
m_log.InfoFormat ("[BOIDS]: Adding {0}", scene.RegionInfo.RegionName);
m_log.InfoFormat("[{0}]: Adding region '{1}' to this module", m_name, scene.RegionInfo.RegionName);
string moduleConfigFile = Path.Combine(Util.configDir(), "../addon-modules/" + m_name + "/config/" + m_name + ".ini");
m_log.InfoFormat("[{0}]: Loading from config file {1}", m_name, moduleConfigFile);
try
{
m_config = new IniConfigSource(moduleConfigFile);
}
catch (Exception)
{
m_log.InfoFormat("[{0}]: No module config file '{1}' was found! Tide in this region is set to Disabled", m_name, moduleConfigFile);
m_enabled = false;
m_config = null;
return;
}
IConfig cnf = m_config.Configs[scene.RegionInfo.RegionName];
if (cnf == null)
{
m_log.InfoFormat("[{0}]: No region section [{1}] found in config file {2}. Tide in this region is set to Disabled", m_name, scene.RegionInfo.RegionName, moduleConfigFile);
m_enabled = false;
return;
}
m_enabled = cnf.GetBoolean("BirdsEnabled", false);
if (m_enabled)
{
m_chatChannel = cnf.GetInt("BirdsChatChannel", 118);
m_birdPrim = cnf.GetString("BirdsPrim", "birdPrim");
m_flockSize = cnf.GetInt("BirdsFlockSize", 100);
m_maxSpeed = cnf.GetFloat("BirdsMaxSpeed", 3f);
m_maxForce = cnf.GetFloat("BirdsMaxForce", 0.25f);
m_neighbourDistance = cnf.GetFloat("BirdsNeighbourDistance", 25f);
m_desiredSeparation = cnf.GetFloat("BirdsDesiredSeparation", 20f);
m_tolerance = cnf.GetFloat("BirdsTolerance", 5f);
m_borderSize = cnf.GetFloat("BirdsRegionBorderSize", 5f);
m_maxHeight = cnf.GetInt("BirdsMaxHeight", 256);
m_log.InfoFormat("[{0}] Enabled on channel {1} with Flock Size {2}", m_name, m_chatChannel, m_flockSize);
//register commands
RegisterCommands();
@ -121,7 +141,9 @@ namespace Flocking
// init module
m_model = new FlockingModel(m_maxSpeed, m_maxForce, m_neighbourDistance, m_desiredSeparation, m_tolerance, m_borderSize);
m_view = new FlockingView(scene);
m_view.BoidPrim = m_boidPrim;
m_view.BirdPrim = m_birdPrim;
m_frame = 0;
m_scene = scene;
}
}
@ -147,7 +169,8 @@ namespace Flocking
public void RemoveRegion (Scene scene)
{
if (m_enabled) {
m_log.InfoFormat("[{0}]: Removing region '{1}' from this module", m_name, scene.RegionInfo.RegionName);
if (m_enabled) {
m_ready = false;
scene.EventManager.OnFrame -= FlockUpdate;
scene.EventManager.OnChatFromClient -= SimChatSent;
@ -164,19 +187,6 @@ namespace Flocking
}
}
public string Name {
get { return m_name; }
}
public bool IsSharedModule {
get { return false; }
}
public Type ReplaceableInterface
{
get { return null; }
}
#endregion
#region EventHandlers
@ -187,13 +197,13 @@ namespace Flocking
return;
}
//m_log.InfoFormat("update my boids");
//m_log.InfoFormat("update my birds");
// 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);
List<Bird > birds = m_model.UpdateFlockPos ();
m_view.Render (birds);
}
}
@ -244,8 +254,8 @@ namespace Flocking
AddCommand ("start", "", "Start Flocking", HandleStartCmd);
AddCommand ("size", "num", "Adjust the size of the flock ", HandleSetSizeCmd);
AddCommand ("stats", "", "show flocking stats", HandleShowStatsCmd);
AddCommand ("prim", "name", "set the prim used for each boid to that passed in", HandleSetPrimCmd);
AddCommand ("framerate", "num", "[debugging] only update boids every <num> frames", HandleSetFrameRateCmd);
AddCommand ("prim", "name", "set the prim used for each bird to that passed in", HandleSetPrimCmd);
AddCommand ("framerate", "num", "[debugging] only update birds every <num> frames", HandleSetFrameRateCmd);
}
private bool ShouldHandleCmd ()
@ -268,7 +278,7 @@ namespace Flocking
if (inWorld) {
IClientAPI ownerAPI = null;
if (m_scene.TryGetClient (m_owner, out ownerAPI)) {
ownerAPI.SendBlueBoxMessage (m_owner, "Boids", response);
ownerAPI.SendBlueBoxMessage (m_owner, "Birds", response);
}
} else {
MainConsole.Instance.Output (response);
@ -316,7 +326,7 @@ namespace Flocking
{
if (ShouldHandleCmd ()) {
bool inWorld = IsInWorldCmd (ref args);
ShowResponse ("Num Boids = " + m_model.Size, inWorld);
ShowResponse ("Num Birds = " + m_model.Size, inWorld);
}
}
@ -325,7 +335,7 @@ namespace Flocking
if (ShouldHandleCmd ()) {
string primName = args[1];
lock(m_sync) {
m_view.BoidPrim = primName;
m_view.BirdPrim = primName;
m_view.Clear();
}
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) Contributors, https://github.com/jonc/osboids
* https://github.com/JakDaniels/OpenSimBirds
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
@ -36,7 +37,7 @@ namespace Flocking
{
private Scene m_scene;
private UUID m_owner;
private String m_boidPrim;
private String m_birdPrim;
private Dictionary<string, SceneObjectGroup> m_sogMap = new Dictionary<string, SceneObjectGroup> ();
@ -50,8 +51,8 @@ namespace Flocking
m_owner = owner;
}
public String BoidPrim {
set{ m_boidPrim = value;}
public String BirdPrim {
set{ m_birdPrim = value;}
}
public void Clear ()
@ -64,36 +65,36 @@ namespace Flocking
m_sogMap.Clear();
}
public void Render (List<Boid> boids)
public void Render (List<Bird> birds)
{
foreach (Boid boid in boids) {
DrawBoid (boid);
foreach (Bird bird in birds) {
DrawBird (bird);
}
}
private void DrawBoid (Boid boid)
private void DrawBird (Bird bird)
{
SceneObjectPart existing = m_scene.GetSceneObjectPart (boid.Id);
SceneObjectPart existing = m_scene.GetSceneObjectPart (bird.Id);
SceneObjectGroup sog;
if (existing == null) {
SceneObjectGroup group = findByName (m_boidPrim);
sog = CopyPrim (group, boid.Id);
m_sogMap [boid.Id] = sog;
SceneObjectGroup group = findByName (m_birdPrim);
sog = CopyPrim (group, bird.Id);
m_sogMap [bird.Id] = sog;
m_scene.AddNewSceneObject (sog, false);
} else {
sog = existing.ParentGroup;
}
Quaternion rotation = CalcRotationToEndpoint (sog, sog.AbsolutePosition, boid.Location);
sog.UpdateGroupRotationPR( boid.Location, rotation);
Quaternion rotation = CalcRotationToEndpoint (sog, sog.AbsolutePosition, bird.Location);
sog.UpdateGroupRotationPR( bird.Location, rotation);
}
private static Quaternion CalcRotationToEndpoint (SceneObjectGroup copy, Vector3 sv, Vector3 ev)
{
//llSetRot(llRotBetween(<1,0,0>,llVecNorm(targetPosition - llGetPos())));
// boid wil fly x forwards and Z up
// bird wil fly x forwards and Z up
Vector3 currDirVec = Vector3.UnitX;
Vector3 desiredDirVec = Vector3.Subtract (ev, sv);
@ -132,8 +133,8 @@ namespace Flocking
private SceneObjectGroup MakeDefaultPrim (string name)
{
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere ();
shape.Scale = new Vector3 (0.5f, 0.5f, 0.5f);
shape.Scale = new Vector3 (0.5f, 0.5f, 0.5f);
SceneObjectGroup prim = new SceneObjectGroup(m_owner, new Vector3((float)m_scene.RegionInfo.RegionSizeX / 2, (float)m_scene.RegionInfo.RegionSizeY / 2, 25f), shape);
prim.Name = name;
prim.DetachFromBackup ();

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) Contributors, https://github.com/jonc/osboids
* https://github.com/JakDaniels/OpenSimBirds
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
@ -33,20 +34,20 @@ namespace Flocking
{
public class FlowMap
{
private Scene m_scene;
private float[, ,] m_flowMap;
private uint regionX;
private uint regionY;
private uint regionZ;
private Scene m_scene;
private float[, ,] m_flowMap;
private uint regionX;
private uint regionY;
private uint regionZ;
private float regionBorder;
public FlowMap (Scene scene, int maxHeight, float borderSize)
{
m_scene = scene;
regionX = m_scene.RegionInfo.RegionSizeX;
regionY = m_scene.RegionInfo.RegionSizeY;
regionZ = (uint)maxHeight;
regionBorder = borderSize;
m_scene = scene;
regionX = m_scene.RegionInfo.RegionSizeX;
regionY = m_scene.RegionInfo.RegionSizeY;
regionZ = (uint)maxHeight;
regionBorder = borderSize;
m_flowMap = new float[regionX, regionY, regionZ];
}
@ -58,9 +59,9 @@ namespace Flocking
}
public int LengthZ {
get {return (int)regionZ;}
}
public int Border {
get {return (int)regionBorder;}
}
public int Border {
get {return (int)regionBorder;}
}
public void Initialise() {
@ -140,7 +141,7 @@ namespace Flocking
public bool IsOutOfBounds(Vector3 targetPos) {
bool retVal = false;
if( targetPos.X < regionBorder ||
targetPos.X > regionX - regionBorder ||
targetPos.X > regionX - regionBorder ||
targetPos.Y < regionBorder ||
targetPos.Y > regionY - regionBorder ||
targetPos.Z < regionBorder ||

View File

@ -1,45 +1,56 @@
Region Module - ability to control flocks of prims within an OpenSim scene
INonSharedRegion Module - ability to control flocks of prims within an OpenSim scene
To build from source
Add OpenSimBoids source tree under opensim/addon-modules
Add OpenSimBirds source tree under opensim/addon-modules
./runprebuild.sh against opensim root to build this module into the solution
then xbuild, or build within Visual Studio / Monodevelop to produce the binaries
OpenSimBoids has no external dependencies other than the dlls currently included in opensim.
The project generates a single dll - OpenSimBoids.Modules.dll which is copied into opensim/bin as part of the build step
OpenSimBirds has no external dependencies other than the dlls currently included in opensim.
The project generates a single dll - OpenSimBirds.Modules.dll which is copied into opensim/bin as part of the build step
Configuration
To become active, the module needs to be both referenced and enabled in the ini files. Otherwise it does nothing on startup
To become active, the module needs enabled in the ini file. Otherwise it does nothing on startup.
If you are running multiple regions on one simulator you can have different Birds
settings per region in the configuration file, in the exact same way you can
customize per Region setting in Regions.ini
Entry is as follows and in addition various config parameters are available to control the flock dynamics.
The configuration file for this module is in:
addon-modules/OpenSimBirds/config/OpenSimBirds.ini
[Boids]
enabled = true ;removing the Boids group or setting enabled=false will switch off the module
flock-size = 100 ;the number of Boids to flock
max-speed = 3 ;how far each boid can travel per update
max-force = 0.25 ;the maximum acceleration allowed to the current velocity of the boid
neighbour-dist = 25 ;max distance for other boids to be considered in the same flock as us
desired-separation = 20 ;how far away from other boids we would like to stay
tolerance = 5 ;how close to the edges of things can we get without being worried
border-size = 5 ;how close to the edge of a region can we get?
max-height = 256 ;how high are we allowed to flock
boid-prim = fish01 ;By default the module will create a flock of plain wooden spheres,
;however this can be overridden to the name of an existing prim that
;needs to already exist in the scene - i.e. be rezzed in the region.
and follows the same format as a Regions.ini file, where you specify setting for
each region using the [Region Name] section heading.
Here is an example config:
;; Set the Birds settings per named region
[Test Region 1]
BirdsEnabled = True ;set to false to disable the module in this region
BirdsFlockSize = 100 ;the number of birds to flock
BirdsMaxSpeed = 3 ;how far each bird can travel per update
BirdsMaxForce = 0.25 ;the maximum acceleration allowed to the current velocity of the bird
BirdsNeighbourDistance = 25 ;max distance for other birds to be considered in the same flock as us
BirdsDesiredSeparation = 20 ;how far away from other birds we would like to stay
BirdsTolerance = 5 ;how close to the edges of things can we get without being worried
BirdsBorderSize = 5 ;how close to the edge of a region can we get?
BirdsMaxHeight = 256 ;how high are we allowed to flock
BirdsPrim = seagull01 ;By default the module will create a flock of plain wooden spheres,
;however this can be overridden to the name of an existing prim that
;needs to already exist in the scene - i.e. be rezzed in the region.
Various runtime commands control the flocking module behaviour - described below. These can either be invoked
from the Console or in world by directing them to a chat channel. To specify which channel to use:
chat-channel = 118 the chat channel to listen for boid commands on
chat-channel = 118 the chat channel to listen for Bird commands on
@ -48,29 +59,24 @@ Runtime Commands
The following commands, which can either be issued on the Console, or via a chat channel in-world, control the behaviour
of the flock at runtime
flock-stop or /118 stop ;stop all flocking and remove boids from the region
flock-stop or /118 stop ;stop all flocking and remove birds from the region
flock-start or /118 start ;start the flocking simulation
flock-size <num> or /118 size <num> ;change the size of the flock
flock-prim <name> or /118 prim <name> ;change the boid prim to one already rezzed in the scene
flock-prim <name> or /118 prim <name> ;change the bird prim to one already rezzed in the scene
flock-framerate <num> or /118 framerate <num> ;only update the flock positions every <num> frames
;only really useful for photography and debugging boid
;only really useful for photography and debugging bird
;behaviour
Boid prims
Bird prims
Any currently rezzed in-scene-object can be used as the boid prim. However fps is very much affected by the
Any currently rezzed in-scene-object can be used as the bird prim. However fps is very much affected by the
complexity of the entity to use. It is easier to throw a single prim (or sculpty) around the scene than it is to
throw the constituent parts of a 200 linked prim dragon.
Tests show that <= 500 single prims can be flocked effectively - depending on system and network
However maybe <= 300 simple linksets can perform as well.
I intend to allow inventory items and UUIDs to represent the boids - this is not written yet however.
Prebuilt binaries etc.. to follow
I intend to allow inventory items and UUIDs to represent the birds - this is not written yet however.
Please Note
@ -79,16 +85,13 @@ This module is currently only tested against opensim master. If it is found to w
then that behaviour ought to be considered as a bug - which I will attempt to fix in the next git push.
Status
probably made it to alpha by now ...
Next Steps
I want to improve the ability of the boids to avoid obstacles within the scene. Current avoidance is pretty basic, and
I want to improve the ability of the birds to avoid obstacles within the scene. Current avoidance is pretty basic, and
only functions correctly about fifty percent of the time. Need to improve this without increasing computational cost.
Licence: all files released under a BSD licence
If you have any question please contact Jak Daniels, jak@ateb.co.uk

16
config/OpenSimBirds.ini Normal file
View File

@ -0,0 +1,16 @@
;; Set the Birds settings per named region
[Test Region 1]
BirdsEnabled = True ;set to false to disable the module in this region
BirdsFlockSize = 100 ;the number of birds to flock
BirdsMaxSpeed = 3 ;how far each bird can travel per update
BirdsMaxForce = 0.25 ;the maximum acceleration allowed to the current velocity of the bird
BirdsNeighbourDistance = 25 ;max distance for other birds to be considered in the same flock as us
BirdsDesiredSeparation = 20 ;how far away from other birds we would like to stay
BirdsTolerance = 5 ;how close to the edges of things can we get without being worried
BirdsBorderSize = 5 ;how close to the edge of a region can we get?
BirdsMaxHeight = 256 ;how high are we allowed to flock
BirdsPrim = seagull01 ;By default the module will create a flock of plain wooden spheres,
;however this can be overridden to the name of an existing prim that
;needs to already exist in the scene - i.e. be rezzed in the region.

View File

@ -0,0 +1,16 @@
;; Set the Birds settings per named region
[Test Region 1]
BirdsEnabled = True ;set to false to disable the module in this region
BirdsFlockSize = 100 ;the number of birds to flock
BirdsMaxSpeed = 3 ;how far each bird can travel per update
BirdsMaxForce = 0.25 ;the maximum acceleration allowed to the current velocity of the bird
BirdsNeighbourDistance = 25 ;max distance for other birds to be considered in the same flock as us
BirdsDesiredSeparation = 20 ;how far away from other birds we would like to stay
BirdsTolerance = 5 ;how close to the edges of things can we get without being worried
BirdsBorderSize = 5 ;how close to the edge of a region can we get?
BirdsMaxHeight = 256 ;how high are we allowed to flock
BirdsPrim = seagull01 ;By default the module will create a flock of plain wooden spheres,
;however this can be overridden to the name of an existing prim that
;needs to already exist in the scene - i.e. be rezzed in the region.