OpenSimBirds/Flocking/FlowField.cs

107 lines
3.0 KiB
C#
Raw Normal View History

2011-07-16 07:56:20 +00:00
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++ ) {
}
}
}
}
}
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;
}
}
}