Many changes to support per region configuration and project name change
parent
d75428a078
commit
d18d37faf6
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
{
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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 ||
|
||||
|
|
77
README.md
77
README.md
|
@ -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
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
Loading…
Reference in New Issue