added tests - no sogs yet
parent
8f8da4ea10
commit
cdbac1c921
|
@ -42,7 +42,7 @@ namespace Flocking
|
||||||
private Random m_rndnums = new Random (Environment.TickCount);
|
private Random m_rndnums = new Random (Environment.TickCount);
|
||||||
|
|
||||||
private FlockingModel m_model;
|
private FlockingModel m_model;
|
||||||
private FlowMap m_flowMap;
|
private FlowField m_flowField;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -57,13 +57,13 @@ namespace Flocking
|
||||||
/// <param name='mf'>
|
/// <param name='mf'>
|
||||||
/// Mf. max force / acceleration this boid can extert
|
/// Mf. max force / acceleration this boid can extert
|
||||||
/// </param>
|
/// </param>
|
||||||
public Boid (string id, FlockingModel model, FlowMap flowMap)
|
public Boid (string id, FlockingModel model, FlowField flowField)
|
||||||
{
|
{
|
||||||
m_id = id;
|
m_id = id;
|
||||||
m_acc = Vector3.Zero;
|
m_acc = Vector3.Zero;
|
||||||
m_vel = new Vector3 (m_rndnums.Next (-1, 1), m_rndnums.Next (-1, 1), m_rndnums.Next (-1, 1));
|
m_vel = new Vector3 (m_rndnums.Next (-1, 1), m_rndnums.Next (-1, 1), m_rndnums.Next (-1, 1));
|
||||||
m_model = model;
|
m_model = model;
|
||||||
m_flowMap = flowMap;
|
m_flowField = flowField;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Location {
|
public Vector3 Location {
|
||||||
|
@ -91,6 +91,7 @@ namespace Flocking
|
||||||
Flock (boids);
|
Flock (boids);
|
||||||
|
|
||||||
// our first priority is to not hurt ourselves
|
// our first priority is to not hurt ourselves
|
||||||
|
// so adjust where we would like to go to avoid hitting things
|
||||||
AvoidObstacles ();
|
AvoidObstacles ();
|
||||||
|
|
||||||
// then we want to avoid any threats
|
// then we want to avoid any threats
|
||||||
|
@ -211,51 +212,14 @@ namespace Flocking
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Borders this instance.
|
/// navigate away from whatever it is we are too close to
|
||||||
/// if we get too close wrap us around
|
|
||||||
/// CHANGE THIS to navigate away from whatever it is we are too close to
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void AvoidObstacles ()
|
void AvoidObstacles ()
|
||||||
{
|
{
|
||||||
//look tolerance metres ahead
|
//look tolerance metres ahead
|
||||||
Vector3 normVel = Vector3.Normalize(m_vel);
|
m_acc += m_flowField.AdjustVelocity( m_loc, m_vel, m_model.Tolerance );
|
||||||
Vector3 inFront = m_loc + Vector3.Multiply(normVel, m_model.Tolerance);
|
|
||||||
if( m_flowMap.WouldHitObstacle( m_loc, inFront ) ) {
|
|
||||||
AdjustVelocityToAvoidObstacles ();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdjustVelocityToAvoidObstacles ()
|
|
||||||
{
|
|
||||||
for( int i = 1; i < 5; i++ ) {
|
|
||||||
Vector3 normVel = Vector3.Normalize(m_vel);
|
|
||||||
int xDelta = m_rndnums.Next (-i, i);
|
|
||||||
int yDelta = m_rndnums.Next (-i, i);
|
|
||||||
int zDelta = m_rndnums.Next (-i, i);
|
|
||||||
normVel.X += xDelta;
|
|
||||||
normVel.Y += yDelta;
|
|
||||||
normVel.Z += zDelta;
|
|
||||||
Vector3 inFront = m_loc + Vector3.Multiply(normVel, m_model.Tolerance);
|
|
||||||
if( !m_flowMap.WouldHitObstacle( m_loc, inFront ) ) {
|
|
||||||
m_vel.X += xDelta;
|
|
||||||
m_vel.Y += yDelta;
|
|
||||||
m_vel.Z += zDelta;
|
|
||||||
//m_log.Info("avoided");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//m_log.Info("didn't avoid");
|
|
||||||
// try increaing our acceleration
|
|
||||||
// or try decreasing our acceleration
|
|
||||||
// or turn around - coz where we came from was OK
|
|
||||||
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>
|
/// <summary>
|
||||||
/// Separate ourselves from the specified boids.
|
/// Separate ourselves from the specified boids.
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
<include name="FlockingModel.cs" />
|
<include name="FlockingModel.cs" />
|
||||||
<include name="FlockingModule.cs" />
|
<include name="FlockingModule.cs" />
|
||||||
<include name="FlockingView.cs" />
|
<include name="FlockingView.cs" />
|
||||||
|
<include name="FlowField.cs" />
|
||||||
|
<include name="FlowFieldTest.cs" />
|
||||||
<include name="FlowMap.cs" />
|
<include name="FlowMap.cs" />
|
||||||
<include name="Util.cs" />
|
<include name="Util.cs" />
|
||||||
</sources>
|
</sources>
|
||||||
|
@ -30,12 +32,14 @@
|
||||||
</lib>
|
</lib>
|
||||||
<include name="../../../bin/log4net.dll"/>
|
<include name="../../../bin/log4net.dll"/>
|
||||||
<include name="../../../bin/Nini.dll"/>
|
<include name="../../../bin/Nini.dll"/>
|
||||||
|
<include name="../../../bin/nunit.framework.dll"/>
|
||||||
<include name="../../../bin/OpenMetaverse.dll"/>
|
<include name="../../../bin/OpenMetaverse.dll"/>
|
||||||
<include name="../../../bin/OpenMetaverseTypes.dll"/>
|
<include name="../../../bin/OpenMetaverseTypes.dll"/>
|
||||||
<include name="../../../bin/OpenSim.Framework.dll"/>
|
<include name="../../../bin/OpenSim.Framework.dll"/>
|
||||||
<include name="../../../bin/OpenSim.Framework.Communications.dll"/>
|
<include name="../../../bin/OpenSim.Framework.Communications.dll"/>
|
||||||
<include name="../../../bin/OpenSim.Framework.Console.dll"/>
|
<include name="../../../bin/OpenSim.Framework.Console.dll"/>
|
||||||
<include name="../../../bin/OpenSim.Region.Framework.dll"/>
|
<include name="../../../bin/OpenSim.Region.Framework.dll"/>
|
||||||
|
<include name="../../../bin/OpenSim.Tests.Common.dll"/>
|
||||||
<include name="System.dll" />
|
<include name="System.dll" />
|
||||||
<include name="System.Drawing.dll" />
|
<include name="System.Drawing.dll" />
|
||||||
<include name="System.Xml.dll" />
|
<include name="System.Xml.dll" />
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace Flocking
|
||||||
public class FlockingModel
|
public class FlockingModel
|
||||||
{
|
{
|
||||||
private List<Boid> m_flock = new List<Boid>();
|
private List<Boid> m_flock = new List<Boid>();
|
||||||
private FlowMap m_flowMap;
|
private FlowField m_flowField;
|
||||||
private float m_maxSpeed;
|
private float m_maxSpeed;
|
||||||
private float m_maxForce;
|
private float m_maxForce;
|
||||||
private float m_neighbourDistance;
|
private float m_neighbourDistance;
|
||||||
|
@ -63,21 +63,15 @@ namespace Flocking
|
||||||
|
|
||||||
void AddBoid (string name)
|
void AddBoid (string name)
|
||||||
{
|
{
|
||||||
Boid boid = new Boid (name, this, m_flowMap);
|
Boid boid = new Boid (name, this, m_flowField);
|
||||||
|
|
||||||
// find an initial random location for this Boid
|
// find an initial random location for this Boid
|
||||||
// somewhere not within an obstacle
|
// somewhere not within an obstacle
|
||||||
int xInit = m_rnd.Next(m_flowMap.LengthX);
|
int xInit = m_rnd.Next(Util.SCENE_SIZE);
|
||||||
int yInit = m_rnd.Next(m_flowMap.LengthY);
|
int yInit = m_rnd.Next(Util.SCENE_SIZE);
|
||||||
int zInit = m_rnd.Next(m_flowMap.LengthZ);
|
int zInit = m_rnd.Next(Util.SCENE_SIZE);
|
||||||
|
Vector3 location = new Vector3 (Convert.ToSingle(xInit), Convert.ToSingle(yInit), Convert.ToSingle(zInit));
|
||||||
while( m_flowMap.IsWithinObstacle( xInit, yInit, zInit ) ){
|
boid.Location = location + m_flowField.AdjustVelocity(location, Vector3.UnitZ, 5f);
|
||||||
xInit = m_rnd.Next(m_flowMap.LengthX);
|
|
||||||
yInit = m_rnd.Next(m_flowMap.LengthY);
|
|
||||||
zInit = m_rnd.Next(m_flowMap.LengthZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
boid.Location = new Vector3 (Convert.ToSingle(xInit), Convert.ToSingle(yInit), Convert.ToSingle(zInit));
|
|
||||||
m_flock.Add (boid);
|
m_flock.Add (boid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,9 +96,9 @@ namespace Flocking
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Initialise (int num, FlowMap flowMap)
|
public void Initialise (int num, FlowField flowField)
|
||||||
{
|
{
|
||||||
m_flowMap = flowMap;
|
m_flowField = flowField;
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
AddBoid ("boid"+i );
|
AddBoid ("boid"+i );
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace Flocking
|
||||||
|
|
||||||
public void AddRegion (Scene scene)
|
public void AddRegion (Scene scene)
|
||||||
{
|
{
|
||||||
m_log.Info ("ADDING FLOCKING");
|
//m_log.Info ("ADDING FLOCKING");
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
if (m_enabled) {
|
if (m_enabled) {
|
||||||
//register commands
|
//register commands
|
||||||
|
@ -112,11 +112,14 @@ namespace Flocking
|
||||||
if (m_enabled) {
|
if (m_enabled) {
|
||||||
|
|
||||||
//make a flow map for this scene
|
//make a flow map for this scene
|
||||||
FlowMap flowMap = new FlowMap(scene );
|
//FlowMap flowMap = new FlowMap(scene );
|
||||||
flowMap.Initialise();
|
//flowMap.Initialise();
|
||||||
|
|
||||||
|
//build a proper flow field based on the scene
|
||||||
|
FlowField field = new FlowField(scene, new Vector3(128f, 128f, 128f), 200, 200, 200);
|
||||||
|
|
||||||
// Generate initial flock values
|
// Generate initial flock values
|
||||||
m_model.Initialise (m_flockSize, flowMap);
|
m_model.Initialise (m_flockSize, field);
|
||||||
|
|
||||||
// who is the owner for the flock in this region
|
// who is the owner for the flock in this region
|
||||||
m_owner = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
m_owner = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
|
@ -282,7 +285,8 @@ namespace Flocking
|
||||||
{
|
{
|
||||||
if (ShouldHandleCmd ()) {
|
if (ShouldHandleCmd ()) {
|
||||||
bool inWorld = IsInWorldCmd (ref args);
|
bool inWorld = IsInWorldCmd (ref args);
|
||||||
ShowResponse ("Num Boids = " + m_model.Size, inWorld);
|
string str = "Num Boids = " + m_model.Size;
|
||||||
|
ShowResponse (str, inWorld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
using System;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
|
||||||
|
namespace Flocking
|
||||||
|
{
|
||||||
|
public class FlowField
|
||||||
|
{
|
||||||
|
private const int BUFFER = 5;
|
||||||
|
private Scene m_scene;
|
||||||
|
private float m_startX;
|
||||||
|
private float m_startY;
|
||||||
|
private float m_startZ;
|
||||||
|
private float m_endX;
|
||||||
|
private float m_endY;
|
||||||
|
private float m_endZ;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Flocking.FlowField"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='scene'>
|
||||||
|
/// Scene.
|
||||||
|
/// </param>
|
||||||
|
/// <param name='centre'>
|
||||||
|
/// Centre.
|
||||||
|
/// </param>
|
||||||
|
/// <param name='width'>
|
||||||
|
/// Width.
|
||||||
|
/// </param>
|
||||||
|
/// <param name='depth'>
|
||||||
|
/// Depth.
|
||||||
|
/// </param>
|
||||||
|
/// <param name='height'>
|
||||||
|
/// Height.
|
||||||
|
/// </param>
|
||||||
|
///
|
||||||
|
public FlowField (Scene scene, Vector3 centre, int width, int depth, int height)
|
||||||
|
{
|
||||||
|
m_scene = scene;
|
||||||
|
|
||||||
|
m_startX = Math.Max( BUFFER, centre.X - width/2f);
|
||||||
|
m_startY = Math.Max( BUFFER, centre.Y - depth/2f);
|
||||||
|
m_startZ = Math.Max( BUFFER, centre.Z - height/2f);
|
||||||
|
m_endX = Math.Min( Util.SCENE_SIZE - BUFFER, centre.X + width/2f);
|
||||||
|
m_endY = Math.Min( Util.SCENE_SIZE - BUFFER, centre.Y + depth/2f);
|
||||||
|
m_endZ = Math.Min( Util.SCENE_SIZE - BUFFER, centre.Z + height/2f);
|
||||||
|
|
||||||
|
// build the flow field over the given bounds
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// build a flow field on the scene at the specified centre
|
||||||
|
/// position in the scene and of extent given by width, depth and height.
|
||||||
|
/// </summary>
|
||||||
|
public void Initialize() {
|
||||||
|
foreach( SceneObjectGroup sog in m_scene.Entities.GetAllByType<SceneObjectGroup>() ) {
|
||||||
|
float offsetHeight;
|
||||||
|
Vector3 size = sog.GetAxisAlignedBoundingBox( out offsetHeight );
|
||||||
|
Vector3 pos = sog.AbsolutePosition;
|
||||||
|
|
||||||
|
// color in the flow field with the strength at this pos due to
|
||||||
|
// this sog
|
||||||
|
for( int x = 0; x < size.X; x++ ) {
|
||||||
|
for( int y = 0; y < size.Y; y++ ) {
|
||||||
|
for( int z = 0; z < size.Z; z++ ) {
|
||||||
|
if( IsWithinFlowField(
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 AdjustVelocity (Vector3 loc, Vector3 vel, float lookAheadDist)
|
||||||
|
{
|
||||||
|
Vector3 normVel = Vector3.Normalize(vel);
|
||||||
|
Vector3 inFront = loc + normVel * lookAheadDist;
|
||||||
|
Vector3 adjustedDestintation = inFront + FieldStrength(inFront);
|
||||||
|
Vector3 newVel = Vector3.Normalize(adjustedDestintation - loc) * Vector3.Mag(vel);
|
||||||
|
return newVel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 FieldStrength (Vector3 inFront)
|
||||||
|
{
|
||||||
|
Vector3 retVal = Vector3.Zero;
|
||||||
|
|
||||||
|
//keep us in bounds
|
||||||
|
if( inFront.X > m_endX ) retVal.X -= inFront.X - m_endX;
|
||||||
|
if( inFront.Y > m_endY ) retVal.Y -= inFront.Y - m_endY;
|
||||||
|
if( inFront.Z > m_endZ ) retVal.Z -= inFront.Z - m_endZ;
|
||||||
|
if( inFront.X < m_startX ) retVal.X += m_startX - inFront.X;
|
||||||
|
if( inFront.Y < m_startY ) retVal.Y += m_startY - inFront.Y;
|
||||||
|
if( inFront.Z < m_startZ ) retVal.Z += m_startZ - inFront.Z;
|
||||||
|
|
||||||
|
//now get the field strength at the inbounds position
|
||||||
|
Vector3 strength = LookUp( inFront + retVal);
|
||||||
|
|
||||||
|
return retVal + strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 LookUp (Vector3 par1)
|
||||||
|
{
|
||||||
|
return Vector3.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
using System;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Tests.Common;
|
||||||
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Flocking
|
||||||
|
{
|
||||||
|
[TestFixture()]
|
||||||
|
public class FlowFieldTest
|
||||||
|
{
|
||||||
|
[Test()]
|
||||||
|
public void TestEmptyFlowField ()
|
||||||
|
{
|
||||||
|
Scene scene = SceneSetupHelpers.SetupScene();
|
||||||
|
|
||||||
|
Vector3 centre = new Vector3 (100f, 100f, 100f);
|
||||||
|
FlowField field = new FlowField(scene, centre, 50, 50, 50);
|
||||||
|
Vector3 strength = field.FieldStrength (centre);
|
||||||
|
Assert.That( strength == Vector3.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test()]
|
||||||
|
public void TestWeCanMoveFreely ()
|
||||||
|
{
|
||||||
|
Scene scene = SceneSetupHelpers.SetupScene();
|
||||||
|
|
||||||
|
Vector3 centre = new Vector3 (100f, 100f, 100f);
|
||||||
|
FlowField field = new FlowField(scene, centre, 50, 50, 50);
|
||||||
|
Vector3 pos = new Vector3(100f, 100f,100f);
|
||||||
|
Vector3 velocity = new Vector3(20f, 0f, 0f);
|
||||||
|
Vector3 newVel = field.AdjustVelocity (pos, velocity, 10);
|
||||||
|
Console.WriteLine( newVel );
|
||||||
|
Assert.That(newVel == velocity);
|
||||||
|
Vector3 newPos = pos+newVel;
|
||||||
|
Assert.That( newPos.X < 150f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test()]
|
||||||
|
public void TestWeDontFallOfTheEdge ()
|
||||||
|
{
|
||||||
|
Scene scene = SceneSetupHelpers.SetupScene();
|
||||||
|
|
||||||
|
Vector3 centre = new Vector3 (100f, 100f, 100f);
|
||||||
|
FlowField field = new FlowField(scene, centre, 50, 50, 50);
|
||||||
|
|
||||||
|
Vector3 pos = new Vector3(140f, 100f,100f);
|
||||||
|
Vector3 velocity = new Vector3(20f, 0f, 0f);
|
||||||
|
Vector3 newVel = field.AdjustVelocity (pos, velocity, 10);
|
||||||
|
Console.WriteLine( newVel );
|
||||||
|
Vector3 newPos = pos+newVel;
|
||||||
|
Assert.That( newPos.X < 150f);
|
||||||
|
Assert.That(velocity != newVel);
|
||||||
|
|
||||||
|
pos = new Vector3(60f, 100f, 100f);
|
||||||
|
velocity = new Vector3(-20f, 0f, 0f);
|
||||||
|
newVel = field.AdjustVelocity(pos, velocity, 10);
|
||||||
|
newPos = pos+newVel;
|
||||||
|
Assert.That( newPos.X > 50f );
|
||||||
|
Assert.That(velocity != newVel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test()]
|
||||||
|
public void TestWeCanCopeWithCorners ()
|
||||||
|
{
|
||||||
|
Scene scene = SceneSetupHelpers.SetupScene();
|
||||||
|
|
||||||
|
Vector3 centre = new Vector3 (100f, 100f, 100f);
|
||||||
|
FlowField field = new FlowField(scene, centre, 50, 50, 50);
|
||||||
|
Vector3 pos = new Vector3(140f, 140f,140f);
|
||||||
|
Vector3 velocity = new Vector3(20f, 20f, 20f); // going to hit the corner
|
||||||
|
Vector3 newVel = field.AdjustVelocity (pos, velocity, 10);
|
||||||
|
Console.WriteLine( newVel );
|
||||||
|
Vector3 newPos = pos+newVel;
|
||||||
|
Assert.That( newPos.X < 150f);
|
||||||
|
Assert.That( newPos.Y < 150f);
|
||||||
|
Assert.That( newPos.Z < 150f);
|
||||||
|
Assert.That(velocity != newVel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test()]
|
||||||
|
[Ignore()]
|
||||||
|
public void TestNonEmptyFlowField ()
|
||||||
|
{
|
||||||
|
Scene scene = SceneSetupHelpers.SetupScene();
|
||||||
|
Vector3 centre = new Vector3 (100f, 100f, 100f);
|
||||||
|
SceneObjectGroup sceneObjectGroup = AddSog (centre, new Vector3(10f,10f,10f));
|
||||||
|
scene.AddNewSceneObject(sceneObjectGroup, false);
|
||||||
|
|
||||||
|
FlowField field = new FlowField(scene, centre, 50, 50, 50);
|
||||||
|
Vector3 strength = field.FieldStrength (centre);
|
||||||
|
Assert.That( strength != Vector3.Zero);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SceneObjectGroup AddSog (Vector3 position, Vector3 size)
|
||||||
|
{
|
||||||
|
UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010");
|
||||||
|
string part1Name = "part1";
|
||||||
|
UUID part1Id = new UUID("00000000-0000-0000-0000-000000000001");
|
||||||
|
string part2Name = "part2";
|
||||||
|
UUID part2Id = new UUID("00000000-0000-0000-0000-000000000002");
|
||||||
|
|
||||||
|
SceneObjectPart part1
|
||||||
|
= new SceneObjectPart(ownerId, PrimitiveBaseShape.Default, position, Quaternion.Identity, Vector3.Zero)
|
||||||
|
{ Name = part1Name, UUID = part1Id };
|
||||||
|
part1.Scale =size;
|
||||||
|
SceneObjectGroup so = new SceneObjectGroup(part1);
|
||||||
|
|
||||||
|
return so;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,8 +29,11 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace Flocking
|
namespace Flocking
|
||||||
{
|
{
|
||||||
|
|
||||||
public class Util
|
public class Util
|
||||||
{
|
{
|
||||||
|
public const int SCENE_SIZE = 256;
|
||||||
|
|
||||||
public static Vector3 Limit (Vector3 initial, float maxLen)
|
public static Vector3 Limit (Vector3 initial, float maxLen)
|
||||||
{
|
{
|
||||||
float currLen = initial.Length ();
|
float currLen = initial.Length ();
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
<Reference name="System.Drawing" />
|
<Reference name="System.Drawing" />
|
||||||
<Reference name="System.Xml"/>
|
<Reference name="System.Xml"/>
|
||||||
<Reference name="Nini" path="../../../bin/" />
|
<Reference name="Nini" path="../../../bin/" />
|
||||||
|
<Reference name="nunit.framework" path="../../../bin/" />
|
||||||
<Reference name="OpenSim.Framework" path="../../../bin/" />
|
<Reference name="OpenSim.Framework" path="../../../bin/" />
|
||||||
|
<Reference name="OpenSim.Tests.Common" path="../../../bin/" />
|
||||||
<Reference name="OpenSim.Framework.Communications" path="../../../bin/" />
|
<Reference name="OpenSim.Framework.Communications" path="../../../bin/" />
|
||||||
<Reference name="OpenSim.Region.Framework" path="../../../bin/" />
|
<Reference name="OpenSim.Region.Framework" path="../../../bin/" />
|
||||||
<Reference name="OpenSim.Framework.Console" path="../../../bin/" />
|
<Reference name="OpenSim.Framework.Console" path="../../../bin/" />
|
||||||
|
|
Loading…
Reference in New Issue