initial commit

stable0711
Jon Cundill 2011-07-08 18:57:07 +01:00
commit bcca860e88
17 changed files with 1045 additions and 0 deletions

4
CONTRIBUTORS.txt Normal file
View File

@ -0,0 +1,4 @@
The following people have contributed to the development of the osboids module
* Jon Cundill - initial implementation

340
Flocking/Boid.cs Normal file
View File

@ -0,0 +1,340 @@
/*
* 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 System.Collections.Generic;
using OpenMetaverse;
namespace Flocking
{
public class Boid
{
private string m_id;
private Vector3 m_loc;
private Quaternion m_rotation;
private Vector3 m_vel;
private Vector3 m_acc;
private Random m_rndnums = new Random (Environment.TickCount);
private float m_tolerance; // how close can we get to things witout being edgy
private float m_maxForce; // Maximum steering force
private float m_maxSpeed; // Maximum speed
private float m_width = 255f;
private float m_height = 255f;
private float m_neighborDist = 25.0f;
private float m_desiredSeparation = 20.0f;
/// <summary>
/// Initializes a new instance of the <see cref="Flocking.Boid"/> class.
/// </summary>
/// <param name='l'>
/// L. the initial position of this boid
/// </param>
/// <param name='ms'>
/// Ms. max speed this boid can attain
/// </param>
/// <param name='mf'>
/// Mf. max force / acceleration this boid can extert
/// </param>
public Boid (string id, float ms, float mf)
{
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_tolerance = 2.0f;
m_maxSpeed = ms;
m_maxForce = mf;
}
public Vector3 Location {
get { return m_loc;}
set { m_loc = value; }
}
public Vector3 Velocity {
get { return m_vel;}
}
public Quaternion Rotation {
get { return m_rotation; }
}
public String Id {
get {return m_id;}
}
/// <summary>
/// Moves our boid in the scene relative to the rest of the flock.
/// </summary>
/// <param name='boids'>
/// Boids. all the other chaps in the scene
/// </param>
public void MoveInSceneRelativeToFlock (List<Boid> boids)
{
Vector3 previousLoc = new Vector3( m_loc );
Flock (boids);
UpdatePositionInScene ();
AvoidBorders ();
m_rotation = Vector3.RotationBetween( previousLoc, m_loc );
//render();
}
/// <summary>
/// Move within our flock
///
/// We accumulate a new acceleration each time based on three rules
/// these are:
/// our separation from our closest neighbours,
/// our desire to keep travelling within the local flock,
/// our desire to move towards the flock centre
///
/// </summary>
void Flock (List<Boid> boids)
{
// calc the force vectors on this boid
Vector3 sep = Separate (boids); // Separation
Vector3 ali = Align (boids); // Alignment
Vector3 coh = Cohesion (boids); // Cohesion
// Arbitrarily weight these forces
//TODO: expose these consts
sep *= 1.5f; //.mult(1.5);
//ali.mult(1.0);
ali *= 1.0f;
//coh.mult(1.0);
coh *= 1.0f;
// Add the force vectors to the current acceleration of the boid
//acc.add(sep);
m_acc += sep;
//acc.add(ali);
m_acc += ali;
//acc.add(coh);
m_acc += coh;
}
/// <summary>
/// Method to update our location within the scene.
/// update our location in the world based on our
/// current location, velocity and acceleration
/// taking into account our max speed
///
/// </summary>
void UpdatePositionInScene ()
{
// Update velocity
//vel.add(acc);
m_vel += m_acc;
// Limit speed
//m_vel.limit(maxspeed);
m_vel = Util.Limit (m_vel, m_maxSpeed);
m_loc += m_vel;
// Reset accelertion to 0 each cycle
m_acc *= 0.0f;
}
/// <summary>
/// Seek the specified target. Move into that flock
/// Accelerate us towards where we want to go
/// </summary>
/// <param name='target'>
/// Target. the position within the flock we would like to achieve
/// </param>
void Seek (Vector3 target)
{
m_acc += Steer (target, false);
}
/// <summary>
/// Arrive the specified target. Slow us down, as we are almost there
/// </summary>
/// <param name='target'>
/// Target. the flock we would like to think ourselves part of
/// </param>
void arrive (Vector3 target)
{
m_acc += Steer (target, true);
}
/// A method that calculates a steering vector towards a target
/// Takes a second argument, if true, it slows down as it approaches the target
Vector3 Steer (Vector3 target, bool slowdown)
{
Vector3 steer; // The steering vector
Vector3 desired = Vector3.Subtract(target, m_loc); // A vector pointing from the location to the target
float d = desired.Length (); // Distance from the target is the magnitude of the vector
// If the distance is greater than 0, calc steering (otherwise return zero vector)
if (d > 0) {
// Normalize desired
desired.Normalize ();
// Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed)
if ((slowdown) && (d < 100.0f)) {
desired *= (m_maxSpeed * (d / 100.0f)); // This damping is somewhat arbitrary
} else {
desired *= m_maxSpeed;
}
// Steering = Desired minus Velocity
//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_maxForce);
} else {
steer = Vector3.Zero;
}
return steer;
}
/// <summary>
/// Borders this instance.
/// if we get too close wrap us around
/// CHANGE THIS to navigate away from whatever it is we are too close to
/// </summary>
void AvoidBorders ()
{
if (m_loc.X < 5 || m_loc.X > 250)
m_vel.X = -m_vel.X;
if (m_loc.Y < 5 || m_loc.Y > 250)
m_vel.Y = -m_vel.Y;
if (m_loc.Z < 21 || m_loc.Z > 271 )
m_vel.Z = -m_vel.Z;
}
/// <summary>
/// Separate ourselves from the specified boids.
/// 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>
Vector3 Separate (List<Boid> boids)
{
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) {
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_desiredSeparation)) {
// Calculate vector pointing away from neighbor
Vector3 diff = Vector3.Subtract (m_loc, other.Location);
diff.Normalize ();
diff = Vector3.Divide (diff, d);
steer = Vector3.Add (steer, diff);
count++; // Keep track of how many
}
}
// Average -- divide by how many
if (count > 0) {
steer /= (float)count;
}
// As long as the vector is greater than 0
if (steer.Length () > 0) {
// Implement Reynolds: Steering = Desired - Velocity
steer.Normalize ();
steer *= m_maxSpeed;
steer -= m_vel;
//steer.limit(maxforce);
steer = Util.Limit (steer, m_maxForce);
}
return steer;
}
/// <summary>
/// Align our boid within the flock.
/// For every nearby boid 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>
Vector3 Align (List<Boid> boids)
{
Vector3 steer = new Vector3 (0, 0, 0);
int count = 0;
foreach (Boid other in boids) {
float d = Vector3.Distance (m_loc, other.Location);
if ((d > 0) && (d < m_neighborDist)) {
steer += other.Velocity;
count++;
}
}
if (count > 0) {
steer /= (float)count;
}
// As long as the vector is greater than 0
if (steer.Length () > 0) {
// Implement Reynolds: Steering = Desired - Velocity
steer.Normalize ();
steer *= m_maxSpeed;
steer -= m_vel;
//steer.limit(maxforce);
steer = Util.Limit (steer, m_maxForce);
}
return steer;
}
/// <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
/// </summary>
/// <param name='boids'>
/// Boids. the boids in the scene
/// </param>
Vector3 Cohesion (List<Boid> boids)
{
Vector3 sum = Vector3.Zero; // Start with empty vector to accumulate all locations
int count = 0;
foreach (Boid other in boids) {
float d = Vector3.Distance (m_loc, other.Location);
if ((d > 0) && (d < m_neighborDist)) {
sum += other.Location; // Add location
count++;
}
}
if (count > 0) {
sum /= (float)count;
return Steer (sum, false); // Steer towards the location
}
return sum;
}
}
}

138
Flocking/Flocking.csproj Normal file
View File

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{7BC283D1-0000-0000-0000-000000000000}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<AssemblyKeyContainerName>
</AssemblyKeyContainerName>
<AssemblyName>Flocking</AssemblyName>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
<DelaySign>false</DelaySign>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<OutputType>Library</OutputType>
<AppDesignerFolder>
</AppDesignerFolder>
<RootNamespace>Flocking</RootNamespace>
<StartArguments>
</StartArguments>
<FileUpgradeFlags>
</FileUpgradeFlags>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<BaseAddress>285212672</BaseAddress>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>false</Optimize>
<OutputPath>..\..\..\bin\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>full</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<BaseAddress>285212672</BaseAddress>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<FileAlignment>4096</FileAlignment>
<Optimize>true</Optimize>
<OutputPath>..\..\..\bin\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<Reference Include="System">
<Name>System</Name>
<Private>False</Private>
</Reference>
<Reference Include="System.Drawing">
<Name>System.Drawing</Name>
<Private>False</Private>
</Reference>
<Reference Include="System.Xml">
<Name>System.Xml</Name>
<Private>False</Private>
</Reference>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821">
<HintPath>..\..\..\bin\log4net.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Nini, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\bin\Nini.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="OpenMetaverse, Version=0.9.0.29631, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\bin\OpenMetaverse.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="OpenMetaverseTypes, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\bin\OpenMetaverseTypes.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\OpenSim\Framework\OpenSim.Framework.csproj">
<Project>{7404933D-0000-0000-0000-000000000000}</Project>
<Name>OpenSim.Framework</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\OpenSim\Framework\Communications\OpenSim.Framework.Communications.csproj">
<Project>{7667FA4E-0000-0000-0000-000000000000}</Project>
<Name>OpenSim.Framework.Communications</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\OpenSim\Framework\Console\OpenSim.Framework.Console.csproj">
<Project>{16759386-0000-0000-0000-000000000000}</Project>
<Name>OpenSim.Framework.Console</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\OpenSim\Region\Framework\OpenSim.Region.Framework.csproj">
<Project>{9169B545-0000-0000-0000-000000000000}</Project>
<Name>OpenSim.Region.Framework</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="Boid.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="FlockingModel.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="FlockingModule.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="FlockingView.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Util.cs">
<SubType>Code</SubType>
</Compile>
<EmbeddedResource Include="Resources\Flocking.addin.xml">
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,12 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ReferencePath>/Users/jon/osim/opensim/bin/</ReferencePath>
<LastOpenVersion>9.0.21022</LastOpenVersion>
<ProjectView>ProjectFiles</ProjectView>
<ProjectTrust>0</ProjectTrust>
</PropertyGroup>
<PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
</Project>

View File

@ -0,0 +1,60 @@
<?xml version="1.0" ?>
<project name="Flocking" default="build">
<target name="build">
<echo message="Build Directory is ${project::get-base-directory()}/${build.dir}" />
<mkdir dir="${project::get-base-directory()}/${build.dir}" />
<copy todir="${project::get-base-directory()}/${build.dir}" flatten="true">
<fileset basedir="${project::get-base-directory()}">
</fileset>
</copy>
<copy todir="${project::get-base-directory()}/${build.dir}">
<fileset basedir=".">
</fileset>
</copy>
<csc target="library" debug="${build.debug}" platform="${build.platform}" unsafe="False" warnaserror="False" define="TRACE;DEBUG" nostdlib="False" main="" output="${project::get-base-directory()}/${build.dir}/${project::get-name()}.dll" noconfig="true">
<resources prefix="Flocking" dynamicprefix="true" >
<include name="Resources/Flocking.addin.xml" />
</resources>
<sources failonempty="true">
<include name="Boid.cs" />
<include name="FlockingModel.cs" />
<include name="FlockingModule.cs" />
<include name="FlockingView.cs" />
<include name="Util.cs" />
</sources>
<references basedir="${project::get-base-directory()}">
<lib>
<include name="${project::get-base-directory()}" />
<include name="${project::get-base-directory()}/../../../bin" />
</lib>
<include name="../../../bin/log4net.dll"/>
<include name="../../../bin/Nini.dll"/>
<include name="../../../bin/OpenMetaverse.dll"/>
<include name="../../../bin/OpenMetaverseTypes.dll"/>
<include name="../../../bin/OpenSim.Framework.dll"/>
<include name="../../../bin/OpenSim.Framework.Communications.dll"/>
<include name="../../../bin/OpenSim.Framework.Console.dll"/>
<include name="../../../bin/OpenSim.Region.Framework.dll"/>
<include name="System.dll" />
<include name="System.Drawing.dll" />
<include name="System.Xml.dll" />
</references>
</csc>
<echo message="Copying from [${project::get-base-directory()}/${build.dir}/] to [${project::get-base-directory()}/../../../bin/" />
<mkdir dir="${project::get-base-directory()}/../../../bin/"/>
<copy todir="${project::get-base-directory()}/../../../bin/">
<fileset basedir="${project::get-base-directory()}/${build.dir}/" >
<include name="*.dll"/>
<include name="*.exe"/>
<include name="*.mdb" if='${build.debug}'/>
<include name="*.pdb" if='${build.debug}'/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${bin.dir}" failonerror="false" />
<delete dir="${obj.dir}" failonerror="false" />
</target>
<target name="doc" description="Creates documentation.">
</target>
</project>

BIN
Flocking/Flocking.pidb Normal file

Binary file not shown.

58
Flocking/FlockingModel.cs Normal file
View File

@ -0,0 +1,58 @@
/*
* 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 System.Collections.Generic;
using OpenMetaverse;
namespace Flocking
{
public class FlockingModel
{
private List<Boid> flock = new List<Boid>();
public void Initialise (int num, int xRange, int yRange, int zRange)
{
//TODO: fill in the initial Flock array properly
for (int i = 0; i < num; i++) {
Boid boid = new Boid ("boid"+i, 3.0f, 0.05f);
boid.Location = new Vector3 (xRange / 2f, yRange / 2f, zRange / 2f);
flock.Add (boid);
}
}
public List<Boid> UpdateFlockPos ()
{
foreach (Boid b in flock) {
b.MoveInSceneRelativeToFlock(flock); // Passing the entire list of boids to each boid individually
}
return flock;
}
}
}

155
Flocking/FlockingModule.cs Normal file
View File

@ -0,0 +1,155 @@
/*
* 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 System.Timers;
using System.Collections.Generic;
using OpenMetaverse;
using System.IO;
using Nini.Config;
using System.Threading;
using log4net;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Framework;
using OpenSim.Framework.Console;
namespace Flocking
{
public class FlockingModule : INonSharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType);
private Scene m_scene;
private FlockingModel m_model;
private FlockingView m_view;
private bool m_enabled = false;
private bool m_ready = false;
private uint m_frame = 0;
private int m_frameUpdateRate = 1;
#region IRegionModule Members
public void Initialise (IConfigSource source)
{
//TODO: check if we are in the ini files
//TODO: if so get some physical constants out of them and pass into the model
m_enabled = true;
}
public void AddRegion (Scene scene)
{
m_log.Info("ADDING FLOCKING");
m_scene = scene;
if (m_enabled) {
m_scene.EventManager.OnFrame += FlockUpdate;
m_model = new FlockingModel();
m_view = new FlockingView (m_scene);
m_scene.AddCommand (this, "flocking", "I haz got a Flocking Module", "wotever" , null);
}
}
public void RegionLoaded (Scene scene)
{
if (m_enabled) {
// Generate initial flock values
m_model.Initialise( 200, 255, 255, 255);
m_view.PostInitialize();
// Mark Module Ready for duty
m_ready = true;
}
}
public void RemoveRegion (Scene scene)
{
if (m_enabled) {
m_scene.EventManager.OnFrame -= FlockUpdate;
}
}
public string Name {
get { return "FlockingModule"; }
}
public bool IsSharedModule {
get { return false; }
}
#endregion
#region EventHandlers
public void FlockUpdate()
{
if (((m_frame++ % m_frameUpdateRate) != 0) || !m_ready)
{
return;
}
//m_log.InfoFormat("update my boids");
// work out where everyone has moved to
// and tell the scene to render the new positions
List<Boid> boids = m_model.UpdateFlockPos();
m_view.Render(boids);
}
#endregion
#region IRegionModuleBase Members
public void Close ()
{
}
public Type ReplaceableInterface {
get { return null; }
}
#endregion
}
}

145
Flocking/FlockingView.cs Normal file
View File

@ -0,0 +1,145 @@
/*
* 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 System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
namespace Flocking
{
public class FlockingView
{
private const float DEG_TO_RAD = 0.01745329238f;
private Scene m_scene;
private UUID m_owner;
private Dictionary<string, SceneObjectGroup> m_sogMap = new Dictionary<string, SceneObjectGroup> ();
public FlockingView (Scene scene)
{
m_scene = scene;
}
public void PostInitialize ()
{
m_owner = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
public void Render (List<Boid> boids)
{
foreach (Boid boid in boids) {
SceneObjectGroup sog = DrawBoid (boid);
//sog.ScheduleGroupForTerseUpdate ();
}
}
private SceneObjectGroup DrawBoid (Boid boid)
{
SceneObjectPart existing = m_scene.GetSceneObjectPart (boid.Id);
SceneObjectGroup copy;
if (existing == null) {
SceneObjectGroup group = findByName ("boidPrim");
copy = CopyPrim (group, boid.Id);
m_sogMap [boid.Id] = copy;
m_scene.AddNewSceneObject (copy, false);
} else {
copy = existing.ParentGroup;
}
Quaternion rotation = CalcRotationToEndpoint (copy, copy.AbsolutePosition, boid.Location);
copy.UpdateGroupRotationPR (boid.Location, rotation);
return copy;
}
private static Quaternion CalcRotationToEndpoint (SceneObjectGroup copy, Vector3 sv, Vector3 ev)
{
Vector3 currDirVec = Vector3.UnitX;
float angle = 0f;
copy.GroupRotation.GetAxisAngle (out currDirVec, out angle);
currDirVec.Normalize ();
Vector3 desiredDirVec = Vector3.Subtract (ev, sv);
desiredDirVec.Normalize ();
Quaternion rot = Vector3.RotationBetween (currDirVec, desiredDirVec);
//Quaternion x90 = Quaternion.CreateFromEulers (90f * DEG_TO_RAD, 0f, 0f);
//rot = rot * x90;
return rot;
}
private SceneObjectGroup CopyPrim (SceneObjectGroup prim, string name)
{
SceneObjectGroup copy = prim.Copy (true);
copy.Name = name;
copy.DetachFromBackup ();
return copy;
}
private SceneObjectGroup findByName (string name)
{
SceneObjectGroup retVal = null;
foreach (EntityBase e in m_scene.GetEntities()) {
if (e.Name == name) {
retVal = (SceneObjectGroup)e;
break;
}
}
// can't find it so make a default one
if (retVal == null) {
retVal = MakeDefaultPrim (name);
}
return retVal;
}
private SceneObjectGroup MakeDefaultPrim (string name)
{
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere ();
shape.Scale = new Vector3 (0.5f, 0.5f, 2.5f);
SceneObjectGroup prim = new SceneObjectGroup (m_owner, new Vector3 (128f, 128f, 25f), shape);
prim.Name = name;
prim.DetachFromBackup ();
m_scene.AddNewSceneObject (prim, false);
return prim;
}
}
}

51
Flocking/Util.cs Normal file
View File

@ -0,0 +1,51 @@
/*
* 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 OpenMetaverse;
namespace Flocking
{
public class Util
{
public static Vector3 Limit (Vector3 initial, float maxLen)
{
float currLen = initial.Length ();
float ratio = 1.0f;
if (currLen > maxLen) {
ratio = currLen / maxLen;
}
return initial /= ratio;
}
}
}

View File

@ -0,0 +1,13 @@
<Addin id="Flocking" version="0.1">
<Runtime>
<Import assembly="Flocking.dll"/>
</Runtime>
<Dependencies>
<Addin id="OpenSim" version="0.5" />
</Dependencies>
<Extension path = "/OpenSim/RegionModules">
<RegionModule id="Flocking" type="Flocking.FlockingModule" />
</Extension>
</Addin>

View File

@ -0,0 +1,5 @@
/Users/jon/osim/opensim/bin/Flocking.dll.mdb
/Users/jon/osim/opensim/bin/Flocking.dll
/Users/jon/osim/opensim/addon-modules/flocking/Flocking/obj/Debug/Flocking.dll
/Users/jon/osim/opensim/addon-modules/flocking/Flocking/obj/Debug/Flocking.dll.mdb
/Users/jon/osim/opensim/addon-modules/flocking/Flocking/obj/Debug/Flocking.Resources.Flocking.addin.xml

BIN
Flocking/obj/Debug/Flocking.dll Executable file

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,13 @@
<Addin id="Flocking" version="0.1">
<Runtime>
<Import assembly="Flocking.dll"/>
</Runtime>
<Dependencies>
<Addin id="OpenSim" version="0.5" />
</Dependencies>
<Extension path = "/OpenSim/RegionModules">
<RegionModule id="Flocking" type="Flocking.FlockingModule" />
</Extension>
</Addin>

16
README Normal file
View File

@ -0,0 +1,16 @@
Placeholder.... - preliminary commit
Region Module - ability to control flocks within an OpenSim scene
Build instructions
Add source tree under opensim/addon-modules
./runprebuild.sh to build the module into a local server
Prebuilt binaries etc.. to follow
Currently only tested against opensim master
Status: pre alpha
Licence: all files released under a BSD licence

35
prebuild.xml Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Core TerrainTools Project -->
<Project name="Flocking" path="addon-modules/flocking/Flocking/" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="log4net" path="../../../bin/" />
<Reference name="System"/>
<Reference name="System.Drawing" />
<Reference name="System.Xml"/>
<Reference name="Nini" path="../../../bin/" />
<!--Reference name="Mono.Cecil" path="../../../bin/" /-->
<Reference name="OpenSim.Framework" path="../../../bin/" />
<Reference name="OpenSim.Framework.Communications" path="../../../bin/" />
<Reference name="OpenSim.Region.Framework" path="../../../bin/" />
<Reference name="OpenSim.Framework.Console" path="../../../bin/" />
<Reference name="OpenMetaverseTypes" path="../../../bin/" />
<Reference name="OpenMetaverse" path="../../../bin/" />
<Files>
<Match pattern="*.cs" recurse="true"/>
<Match pattern="*.addin.xml" path="Resources" buildAction="EmbeddedResource" recurse="true"/>
</Files>
</Project>