Numerous changes to make module more versatile
parent
2541527cd7
commit
ca41de0286
|
@ -40,7 +40,8 @@ namespace Flocking
|
|||
private float m_neighbourDistance;
|
||||
private float m_desiredSeparation;
|
||||
private float m_tolerance;
|
||||
private float m_border;
|
||||
private float m_border;
|
||||
private string m_name;
|
||||
|
||||
private Random m_rnd = new Random(Environment.TickCount);
|
||||
|
||||
|
@ -50,13 +51,14 @@ namespace Flocking
|
|||
if( value < m_flock.Count ) {
|
||||
m_flock.RemoveRange( 0, m_flock.Count - value );
|
||||
} else while( value > m_flock.Count ) {
|
||||
AddBird( "Bird"+m_flock.Count);
|
||||
AddBird(m_name + m_flock.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FlockingModel( float maxSpeed, float maxForce, float neighbourDistance, float desiredSeparation, float tolerance, float border) {
|
||||
m_maxSpeed = maxSpeed;
|
||||
public FlockingModel(string moduleName, float maxSpeed, float maxForce, float neighbourDistance, float desiredSeparation, float tolerance, float border) {
|
||||
m_name = moduleName;
|
||||
m_maxSpeed = maxSpeed;
|
||||
m_maxForce = maxForce;
|
||||
m_neighbourDistance = neighbourDistance;
|
||||
m_desiredSeparation = desiredSeparation;
|
||||
|
|
|
@ -42,7 +42,7 @@ using OpenSim.Framework.Console;
|
|||
using Mono.Addins;
|
||||
|
||||
[assembly: Addin("OpenSimBirds", "0.2")]
|
||||
[assembly: AddinDependency("OpenSim", "0.5")]
|
||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
||||
|
||||
namespace Flocking
|
||||
{
|
||||
|
@ -54,6 +54,7 @@ namespace Flocking
|
|||
|
||||
public string m_name = "OpenSimBirds";
|
||||
private Scene m_scene;
|
||||
private ICommandConsole m_console;
|
||||
private FlockingModel m_model;
|
||||
private FlockingView m_view;
|
||||
private bool m_enabled = false;
|
||||
|
@ -91,25 +92,11 @@ namespace Flocking
|
|||
public void AddRegion (Scene scene)
|
||||
{
|
||||
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_log.InfoFormat("[{0}]: No region section [{1}] found in configuration. Birds in this region are set to Disabled", m_name, scene.RegionInfo.RegionName);
|
||||
m_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
@ -128,45 +115,38 @@ namespace Flocking
|
|||
m_tolerance = cnf.GetFloat("BirdsTolerance", 5f);
|
||||
m_borderSize = cnf.GetFloat("BirdsRegionBorderSize", 5f);
|
||||
m_maxHeight = cnf.GetInt("BirdsMaxHeight", 256);
|
||||
m_frameUpdateRate = cnf.GetInt("BirdsUpdateEveryNFrames", 1);
|
||||
|
||||
m_log.InfoFormat("[{0}] Enabled on channel {1} with Flock Size {2}", m_name, m_chatChannel, m_flockSize);
|
||||
|
||||
m_log.InfoFormat("[{0}] Enabled on channel {1} with Flock Size {2}", m_name, m_chatChannel, m_flockSize);
|
||||
|
||||
m_scene = scene;
|
||||
m_console = MainConsole.Instance;
|
||||
|
||||
//register commands with the scene
|
||||
RegisterCommands();
|
||||
|
||||
//register handlers
|
||||
scene.EventManager.OnFrame += FlockUpdate;
|
||||
scene.EventManager.OnChatFromClient += SimChatSent; //listen for commands sent from the client
|
||||
m_scene.EventManager.OnFrame += FlockUpdate;
|
||||
m_scene.EventManager.OnChatFromClient += SimChatSent; //listen for commands sent from the client
|
||||
|
||||
// init module
|
||||
m_model = new FlockingModel(m_maxSpeed, m_maxForce, m_neighbourDistance, m_desiredSeparation, m_tolerance, m_borderSize);
|
||||
m_view = new FlockingView(scene);
|
||||
m_model = new FlockingModel(m_name, m_maxSpeed, m_maxForce, m_neighbourDistance, m_desiredSeparation, m_tolerance, m_borderSize);
|
||||
m_view = new FlockingView(m_name, m_scene);
|
||||
m_view.BirdPrim = m_birdPrim;
|
||||
m_frame = 0;
|
||||
|
||||
FlockInitialise();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void RegionLoaded (Scene scene)
|
||||
{
|
||||
if (m_enabled) {
|
||||
|
||||
//make a flow map for this scene
|
||||
FlowMap flowMap = new FlowMap(scene, m_maxHeight, m_borderSize);
|
||||
flowMap.Initialise();
|
||||
|
||||
// Generate initial flock values
|
||||
m_model.Initialise (m_flockSize, flowMap);
|
||||
|
||||
// who is the owner for the flock in this region
|
||||
m_owner = scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
m_view.PostInitialize (m_owner);
|
||||
|
||||
// Mark Module Ready for duty
|
||||
//m_scene = scene;
|
||||
if (m_enabled) {
|
||||
// Mark Module Ready for duty
|
||||
m_ready = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRegion (Scene scene)
|
||||
|
@ -190,10 +170,28 @@ namespace Flocking
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region EventHandlers
|
||||
|
||||
public void FlockUpdate ()
|
||||
|
||||
#region Helpers
|
||||
|
||||
public void FlockInitialise()
|
||||
{
|
||||
//make a flow map for this scene
|
||||
FlowMap flowMap = new FlowMap(m_scene, m_maxHeight, m_borderSize);
|
||||
flowMap.Initialise();
|
||||
|
||||
// Generate initial flock values
|
||||
m_model.Initialise(m_flockSize, flowMap);
|
||||
|
||||
// who is the owner for the flock in this region
|
||||
m_owner = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
m_view.PostInitialize(m_owner);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region EventHandlers
|
||||
|
||||
public void FlockUpdate ()
|
||||
{
|
||||
if (((m_frame++ % m_frameUpdateRate) != 0) || !m_ready || !m_enabled) {
|
||||
return;
|
||||
|
@ -247,13 +245,17 @@ namespace Flocking
|
|||
if (args.Trim ().Length > 0) {
|
||||
argStr = " <" + args + "> ";
|
||||
}
|
||||
m_scene.AddCommand (this, "flock-" + cmd, "flock-" + cmd + argStr, help, fn);
|
||||
}
|
||||
m_log.InfoFormat("[{0}]: Adding command {1} - {2} to region '{3}'", m_name, "birds-" + cmd + argStr, help, m_scene.RegionInfo.RegionName);
|
||||
//m_scene.AddCommand (this, "birds-" + cmd, "birds-" + cmd + argStr, help, fn);
|
||||
m_console.Commands.AddCommand(m_name, false, "birds-" + cmd, "birds-" + cmd + argStr, help, fn);
|
||||
}
|
||||
|
||||
private void RegisterCommands ()
|
||||
{
|
||||
AddCommand ("stop", "", "Stop all Flocking", HandleStopCmd);
|
||||
AddCommand ("start", "", "Start Flocking", HandleStartCmd);
|
||||
AddCommand ("stop", "", "Stop Birds Flocking", HandleStopCmd);
|
||||
AddCommand ("start", "", "Start Birds Flocking", HandleStartCmd);
|
||||
AddCommand ("enable", "", "Enable Birds Flocking", HandleEnableCmd);
|
||||
AddCommand ("disable", "", "Disable Birds Flocking", HandleDisableCmd);
|
||||
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 bird to that passed in", HandleSetPrimCmd);
|
||||
|
@ -262,7 +264,14 @@ namespace Flocking
|
|||
|
||||
private bool ShouldHandleCmd ()
|
||||
{
|
||||
return m_scene.ConsoleScene () == m_scene;
|
||||
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
|
||||
{
|
||||
m_log.InfoFormat("[{0}]: Command Ignored!", m_name);
|
||||
return false;
|
||||
} else {
|
||||
m_log.InfoFormat("[{0}]: Command Executed!", m_name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsInWorldCmd (ref string [] args)
|
||||
|
@ -286,16 +295,47 @@ namespace Flocking
|
|||
MainConsole.Instance.Output (response);
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleDisableCmd(string module, string[] args)
|
||||
{
|
||||
if (m_ready && ShouldHandleCmd ()) {
|
||||
m_log.InfoFormat("[{0}]: Bird flocking is disabled.", m_name);
|
||||
m_enabled = false;
|
||||
m_ready = false;
|
||||
m_view.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleEnableCmd(string module, string[] args)
|
||||
{
|
||||
if (!m_ready && ShouldHandleCmd())
|
||||
{
|
||||
m_log.InfoFormat("[{0}]: Bird flocking is enabled.", m_name);
|
||||
FlockInitialise();
|
||||
m_enabled = true;
|
||||
m_ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleStopCmd (string module, string[] args)
|
||||
{
|
||||
if (ShouldHandleCmd ()) {
|
||||
m_log.Info ("stop the flocking capability");
|
||||
if (m_enabled && m_ready && ShouldHandleCmd())
|
||||
{
|
||||
m_log.InfoFormat("[{0}]: Bird flocking is stopped.", m_name);
|
||||
m_enabled = false;
|
||||
m_view.Clear ();
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleStartCmd(string module, string[] args)
|
||||
{
|
||||
if (!m_enabled && m_ready && ShouldHandleCmd())
|
||||
{
|
||||
m_log.InfoFormat("[{0}]: Bird flocking is started.", m_name);
|
||||
m_enabled = true;
|
||||
FlockUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSetFrameRateCmd (string module, string[] args)
|
||||
{
|
||||
if (ShouldHandleCmd ()) {
|
||||
|
@ -304,15 +344,6 @@ namespace Flocking
|
|||
}
|
||||
}
|
||||
|
||||
public void HandleStartCmd (string module, string[] args)
|
||||
{
|
||||
if (ShouldHandleCmd ()) {
|
||||
m_log.Info ("start the flocking capability");
|
||||
m_enabled = true;
|
||||
FlockUpdate ();
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleSetSizeCmd (string module, string[] args)
|
||||
{
|
||||
if (ShouldHandleCmd ()) {
|
||||
|
|
|
@ -29,21 +29,25 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using log4net;
|
||||
|
||||
namespace Flocking
|
||||
{
|
||||
public class FlockingView
|
||||
{
|
||||
private Scene m_scene;
|
||||
private UUID m_owner;
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Scene m_scene;
|
||||
private UUID m_owner;
|
||||
private String m_name;
|
||||
private String m_birdPrim;
|
||||
|
||||
private Dictionary<string, SceneObjectGroup> m_sogMap = new Dictionary<string, SceneObjectGroup> ();
|
||||
|
||||
public FlockingView (Scene scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
public FlockingView (String moduleName, Scene scene)
|
||||
{
|
||||
m_name = moduleName;
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
public void PostInitialize (UUID owner)
|
||||
|
@ -59,7 +63,8 @@ namespace Flocking
|
|||
{
|
||||
//trash everything we have
|
||||
foreach (string name in m_sogMap.Keys)
|
||||
{
|
||||
{
|
||||
m_log.InfoFormat("[{0}]: Removing prim {1} from region {2}", m_name, name, m_scene.RegionInfo.RegionName);
|
||||
RemoveSOGFromScene(name);
|
||||
}
|
||||
m_sogMap.Clear();
|
||||
|
@ -77,18 +82,32 @@ namespace Flocking
|
|||
SceneObjectPart existing = m_scene.GetSceneObjectPart (bird.Id);
|
||||
|
||||
|
||||
SceneObjectGroup sog;
|
||||
SceneObjectGroup sog;
|
||||
SceneObjectPart rootPart;
|
||||
|
||||
if (existing == null) {
|
||||
SceneObjectGroup group = findByName (m_birdPrim);
|
||||
sog = CopyPrim (group, bird.Id);
|
||||
m_sogMap [bird.Id] = sog;
|
||||
sog = CopyPrim (group, bird.Id);
|
||||
rootPart = sog.RootPart;
|
||||
//set prim to phantom
|
||||
sog.UpdatePrimFlags(rootPart.LocalId, false, false, true, false);
|
||||
m_sogMap [bird.Id] = sog;
|
||||
m_log.InfoFormat("[{0}]: Adding prim {1} from region {2}", m_name, bird.Id, m_scene.RegionInfo.RegionName);
|
||||
m_scene.AddNewSceneObject (sog, false);
|
||||
} else {
|
||||
sog = existing.ParentGroup;
|
||||
sog = existing.ParentGroup;
|
||||
rootPart = sog.RootPart;
|
||||
//set prim to phantom
|
||||
sog.UpdatePrimFlags(rootPart.LocalId, false, false, true, false);
|
||||
}
|
||||
|
||||
Quaternion rotation = CalcRotationToEndpoint (sog, sog.AbsolutePosition, bird.Location);
|
||||
sog.UpdateGroupRotationPR( bird.Location, rotation);
|
||||
sog.UpdateGroupRotationPR( bird.Location, rotation);
|
||||
|
||||
// Fire script on_rez
|
||||
sog.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 1);
|
||||
rootPart.ParentGroup.ResumeScripts();
|
||||
rootPart.ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
private static Quaternion CalcRotationToEndpoint (SceneObjectGroup copy, Vector3 sv, Vector3 ev)
|
||||
|
@ -106,7 +125,7 @@ namespace Flocking
|
|||
|
||||
private SceneObjectGroup CopyPrim (SceneObjectGroup prim, string name)
|
||||
{
|
||||
SceneObjectGroup copy = prim.Copy (true);
|
||||
SceneObjectGroup copy = prim.Copy (true);
|
||||
copy.Name = name;
|
||||
copy.DetachFromBackup ();
|
||||
return copy;
|
||||
|
@ -133,9 +152,9 @@ 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);
|
||||
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 ();
|
||||
m_scene.AddNewSceneObject (prim, false);
|
||||
|
|
30
README.md
30
README.md
|
@ -1,4 +1,6 @@
|
|||
INonSharedRegion Module - ability to control flocks of prims within an OpenSim scene
|
||||
INonSharedRegion Module - ability to control flocks of prims within an OpenSim scene.
|
||||
|
||||
***This module is currently broken, removing prims from the scene on disable does not work****
|
||||
|
||||
|
||||
To build from source
|
||||
|
@ -6,7 +8,8 @@ To build from source
|
|||
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
|
||||
then xbuild, or build within Visual Studio / Monodevelop to produce the binaries.
|
||||
Remember you need an .ini file in bin/addon-modules/OpenSimBirds/config/
|
||||
|
||||
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
|
||||
|
@ -19,12 +22,13 @@ If you are running multiple regions on one simulator you can have different Bird
|
|||
settings per region in the configuration file, in the exact same way you can
|
||||
customize per Region setting in Regions.ini
|
||||
|
||||
The configuration file for this module is in:
|
||||
The configuration file for this module should be placed in:
|
||||
|
||||
addon-modules/OpenSimBirds/config/OpenSimBirds.ini
|
||||
bin/addon-modules/OpenSimBirds/config/OpenSimBirds.ini
|
||||
|
||||
and follows the same format as a Regions.ini file, where you specify setting for
|
||||
each region using the [Region Name] section heading.
|
||||
and follows the similar format as a Regions.ini file, where you specify setting for
|
||||
each region using the [Region Name] section heading. There is an example .ini file
|
||||
provided which should be edited and copied to the correct place above.
|
||||
|
||||
Here is an example config:
|
||||
|
||||
|
@ -76,22 +80,10 @@ 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 birds - this is not written yet however.
|
||||
|
||||
|
||||
Please Note
|
||||
|
||||
This module is currently only tested against opensim master. If it is found to work against a stable release,
|
||||
then that behaviour ought to be considered as a bug - which I will attempt to fix in the next git push.
|
||||
|
||||
|
||||
|
||||
Next Steps
|
||||
|
||||
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.
|
||||
|
||||
|
||||
This module is currently only tested against opensim master.
|
||||
|
||||
Licence: all files released under a BSD licence
|
||||
If you have any question please contact Jak Daniels, jak@ateb.co.uk
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
;; 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