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; /// /// Initializes a new instance of the class. /// /// /// Scene. /// /// /// Centre. /// /// /// Width. /// /// /// Depth. /// /// /// Height. /// /// 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(); } /// /// build a flow field on the scene at the specified centre /// position in the scene and of extent given by width, depth and height. /// public void Initialize() { foreach( SceneObjectGroup sog in m_scene.Entities.GetAllByType() ) { 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; } } }