2007-04-04 16:31:35 +00:00
using System ;
using System.Collections.Generic ;
using System.Text ;
using libsecondlife ;
using libsecondlife.Packets ;
namespace OpenSim.world
{
partial class Avatar
{
public override void update ( )
{
2007-04-22 17:31:51 +00:00
if ( this . _physActor = = null )
{
//HACKHACK: Note to work out why this entity does not have a physics actor
// and prehaps create one.
return ;
}
2007-04-04 16:31:35 +00:00
libsecondlife . LLVector3 pos2 = new LLVector3 ( this . _physActor . Position . X , this . _physActor . Position . Y , this . _physActor . Position . Z ) ;
if ( this . updateflag )
{
//need to send movement info
//so create the improvedterseobjectupdate packet
//use CreateTerseBlock()
ImprovedTerseObjectUpdatePacket . ObjectDataBlock terseBlock = CreateTerseBlock ( ) ;
ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket ( ) ;
terse . RegionData . RegionHandle = m_regionHandle ; // FIXME
terse . RegionData . TimeDilation = 64096 ;
terse . ObjectData = new ImprovedTerseObjectUpdatePacket . ObjectDataBlock [ 1 ] ;
terse . ObjectData [ 0 ] = terseBlock ;
foreach ( SimClient client in m_clientThreads . Values )
{
client . OutPacket ( terse ) ;
}
updateflag = false ;
//this._updateCount = 0;
}
else
{
if ( ( pos2 ! = this . positionLastFrame ) | | ( this . movementflag = = 16 ) )
{
_updateCount + + ;
if ( ( ( ! PhysicsEngineFlying ) & & ( _updateCount > 3 ) ) | | ( PhysicsEngineFlying ) & & ( _updateCount > 0 ) )
{
//It has been a while since last update was sent so lets send one.
ImprovedTerseObjectUpdatePacket . ObjectDataBlock terseBlock = CreateTerseBlock ( ) ;
ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket ( ) ;
terse . RegionData . RegionHandle = m_regionHandle ; // FIXME
terse . RegionData . TimeDilation = 64096 ;
terse . ObjectData = new ImprovedTerseObjectUpdatePacket . ObjectDataBlock [ 1 ] ;
terse . ObjectData [ 0 ] = terseBlock ;
foreach ( SimClient client in m_clientThreads . Values )
{
client . OutPacket ( terse ) ;
}
_updateCount = 0 ;
}
if ( this . movementflag = = 16 )
{
movementflag = 0 ;
}
}
}
2007-04-17 12:03:52 +00:00
this . positionLastFrame = pos2 ;
if ( ! this . ControllingClient . m_sandboxMode )
{
if ( pos2 . X < 0 )
{
ControllingClient . CrossSimBorder ( new LLVector3 ( this . _physActor . Position . X , this . _physActor . Position . Y , this . _physActor . Position . Z ) ) ;
}
if ( pos2 . Y < 0 )
{
ControllingClient . CrossSimBorder ( new LLVector3 ( this . _physActor . Position . X , this . _physActor . Position . Y , this . _physActor . Position . Z ) ) ;
}
if ( pos2 . X > 255 )
{
ControllingClient . CrossSimBorder ( new LLVector3 ( this . _physActor . Position . X , this . _physActor . Position . Y , this . _physActor . Position . Z ) ) ;
}
if ( pos2 . Y > 255 )
{
ControllingClient . CrossSimBorder ( new LLVector3 ( this . _physActor . Position . X , this . _physActor . Position . Y , this . _physActor . Position . Z ) ) ;
}
}
2007-04-04 16:31:35 +00:00
}
public ObjectUpdatePacket CreateUpdatePacket ( )
{
System . Text . Encoding _enc = System . Text . Encoding . ASCII ;
//send a objectupdate packet with information about the clients avatar
ObjectUpdatePacket objupdate = new ObjectUpdatePacket ( ) ;
objupdate . RegionData . RegionHandle = m_regionHandle ;
objupdate . RegionData . TimeDilation = 64096 ;
objupdate . ObjectData = new libsecondlife . Packets . ObjectUpdatePacket . ObjectDataBlock [ 1 ] ;
objupdate . ObjectData [ 0 ] = AvatarTemplate ;
//give this avatar object a local id and assign the user a name
objupdate . ObjectData [ 0 ] . ID = this . localid ;
objupdate . ObjectData [ 0 ] . FullID = ControllingClient . AgentID ;
objupdate . ObjectData [ 0 ] . NameValue = _enc . GetBytes ( "FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0" ) ;
libsecondlife . LLVector3 pos2 = new LLVector3 ( ( float ) this . _physActor . Position . X , ( float ) this . _physActor . Position . Y , ( float ) this . _physActor . Position . Z ) ;
byte [ ] pb = pos2 . GetBytes ( ) ;
Array . Copy ( pb , 0 , objupdate . ObjectData [ 0 ] . ObjectData , 16 , pb . Length ) ;
return objupdate ;
}
public void SendInitialPosition ( )
{
System . Text . Encoding _enc = System . Text . Encoding . ASCII ;
//send a objectupdate packet with information about the clients avatar
2007-04-17 12:03:52 +00:00
ObjectUpdatePacket objupdate = new ObjectUpdatePacket ( ) ;
2007-04-04 16:31:35 +00:00
objupdate . RegionData . RegionHandle = m_regionHandle ;
objupdate . RegionData . TimeDilation = 64096 ;
objupdate . ObjectData = new libsecondlife . Packets . ObjectUpdatePacket . ObjectDataBlock [ 1 ] ;
objupdate . ObjectData [ 0 ] = AvatarTemplate ;
//give this avatar object a local id and assign the user a name
2007-04-26 12:56:14 +00:00
2007-04-04 16:31:35 +00:00
objupdate . ObjectData [ 0 ] . ID = this . localid ;
this . uuid = objupdate . ObjectData [ 0 ] . FullID = ControllingClient . AgentID ;
objupdate . ObjectData [ 0 ] . NameValue = _enc . GetBytes ( "FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0" ) ;
libsecondlife . LLVector3 pos2 = new LLVector3 ( ( float ) this . Pos . X , ( float ) this . Pos . Y , ( float ) this . Pos . Z ) ;
byte [ ] pb = pos2 . GetBytes ( ) ;
Array . Copy ( pb , 0 , objupdate . ObjectData [ 0 ] . ObjectData , 16 , pb . Length ) ;
m_world . _localNumber + + ;
foreach ( SimClient client in m_clientThreads . Values )
{
client . OutPacket ( objupdate ) ;
if ( client . AgentID ! = ControllingClient . AgentID )
{
2007-04-10 10:45:46 +00:00
//the below line is already in Simclient.cs at line number 245 , directly below the call to this method
//if there is a problem/bug with that , then lets fix it there rather than duplicating it here
//client.ClientAvatar.SendAppearanceToOtherAgent(this.ControllingClient);
SendAppearanceToOtherAgent ( client ) ;
2007-04-04 16:31:35 +00:00
}
}
}
public void SendInitialAppearance ( )
{
AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket ( ) ;
aw . AgentData . AgentID = this . ControllingClient . AgentID ;
aw . AgentData . SerialNum = 0 ;
aw . AgentData . SessionID = ControllingClient . SessionID ;
aw . WearableData = new AgentWearablesUpdatePacket . WearableDataBlock [ 13 ] ;
AgentWearablesUpdatePacket . WearableDataBlock awb ;
for ( int i = 0 ; i < 13 ; i + + )
{
awb = new AgentWearablesUpdatePacket . WearableDataBlock ( ) ;
awb . WearableType = ( byte ) i ;
awb . AssetID = this . Wearables [ i ] . AssetID ;
awb . ItemID = this . Wearables [ i ] . ItemID ;
aw . WearableData [ i ] = awb ;
}
ControllingClient . OutPacket ( aw ) ;
}
public void SendAppearanceToOtherAgent ( SimClient userInfo )
{
AvatarAppearancePacket avp = new AvatarAppearancePacket ( ) ;
avp . VisualParam = new AvatarAppearancePacket . VisualParamBlock [ 218 ] ;
avp . ObjectData . TextureEntry = this . avatarAppearanceTexture . ToBytes ( ) ;
2007-04-10 10:45:46 +00:00
//a wearable update packets should only be sent about the viewers/agents own avatar not for other avatars
//but it seems that the following code only created the packets and never actually sent them anyway
/ * AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket ( ) ;
2007-04-10 02:03:47 +00:00
aw . AgentData . AgentID = this . ControllingClient . AgentID ;
2007-04-10 10:45:46 +00:00
aw . AgentData . SessionID = userInfo . SessionID ;
aw . AgentData . SerialNum = 0 ; //removed the use of a random number as a random number could be less than the last number, should have a counter variable for this
2007-04-10 02:03:47 +00:00
aw . WearableData = new AgentWearablesUpdatePacket . WearableDataBlock [ 13 ] ;
AgentWearablesUpdatePacket . WearableDataBlock awb ;
for ( int i = 0 ; i < 13 ; i + + )
{
awb = new AgentWearablesUpdatePacket . WearableDataBlock ( ) ;
awb . WearableType = ( byte ) i ;
awb . AssetID = this . Wearables [ i ] . AssetID ;
awb . ItemID = this . Wearables [ i ] . ItemID ;
aw . WearableData [ i ] = awb ;
2007-04-10 10:45:46 +00:00
} * /
2007-04-04 16:31:35 +00:00
AvatarAppearancePacket . VisualParamBlock avblock = null ;
for ( int i = 0 ; i < 218 ; i + + )
{
avblock = new AvatarAppearancePacket . VisualParamBlock ( ) ;
avblock . ParamValue = visualParams [ i ] ;
avp . VisualParam [ i ] = avblock ;
}
avp . Sender . IsTrial = false ;
avp . Sender . ID = ControllingClient . AgentID ;
userInfo . OutPacket ( avp ) ;
}
public void SetAppearance ( AgentSetAppearancePacket appear )
{
LLObject . TextureEntry tex = new LLObject . TextureEntry ( appear . ObjectData . TextureEntry , 0 , appear . ObjectData . TextureEntry . Length ) ;
this . avatarAppearanceTexture = tex ;
for ( int i = 0 ; i < appear . VisualParam . Length ; i + + )
{
this . visualParams [ i ] = appear . VisualParam [ i ] . ParamValue ;
}
foreach ( SimClient client in m_clientThreads . Values )
{
if ( client . AgentID ! = ControllingClient . AgentID )
{
SendAppearanceToOtherAgent ( client ) ;
}
}
}
public ImprovedTerseObjectUpdatePacket . ObjectDataBlock CreateTerseBlock ( )
{
byte [ ] bytes = new byte [ 60 ] ;
int i = 0 ;
ImprovedTerseObjectUpdatePacket . ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket . ObjectDataBlock ( ) ;
dat . TextureEntry = new byte [ 0 ] ; // AvatarTemplate.TextureEntry;
libsecondlife . LLVector3 pos2 = new LLVector3 ( 0 , 0 , 0 ) ;
lock ( m_world . LockPhysicsEngine )
{
pos2 = new LLVector3 ( this . _physActor . Position . X , this . _physActor . Position . Y , this . _physActor . Position . Z ) ;
}
uint ID = this . localid ;
bytes [ i + + ] = ( byte ) ( ID % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ID > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ID > > 16 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ID > > 24 ) % 256 ) ;
bytes [ i + + ] = 0 ;
bytes [ i + + ] = 1 ;
i + = 14 ;
bytes [ i + + ] = 128 ;
bytes [ i + + ] = 63 ;
byte [ ] pb = pos2 . GetBytes ( ) ;
Array . Copy ( pb , 0 , bytes , i , pb . Length ) ;
i + = 12 ;
ushort InternVelocityX ;
ushort InternVelocityY ;
ushort InternVelocityZ ;
Axiom . MathLib . Vector3 internDirec = new Axiom . MathLib . Vector3 ( 0 , 0 , 0 ) ;
lock ( m_world . LockPhysicsEngine )
{
internDirec = new Axiom . MathLib . Vector3 ( this . _physActor . Velocity . X , this . _physActor . Velocity . Y , this . _physActor . Velocity . Z ) ;
}
internDirec = internDirec / 128.0f ;
internDirec . x + = 1 ;
internDirec . y + = 1 ;
internDirec . z + = 1 ;
InternVelocityX = ( ushort ) ( 32768 * internDirec . x ) ;
InternVelocityY = ( ushort ) ( 32768 * internDirec . y ) ;
InternVelocityZ = ( ushort ) ( 32768 * internDirec . z ) ;
ushort ac = 32767 ;
bytes [ i + + ] = ( byte ) ( InternVelocityX % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( InternVelocityX > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( InternVelocityY % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( InternVelocityY > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( InternVelocityZ % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( InternVelocityZ > > 8 ) % 256 ) ;
//accel
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
//rot
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
//rotation vel
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
bytes [ i + + ] = ( byte ) ( ac % 256 ) ;
bytes [ i + + ] = ( byte ) ( ( ac > > 8 ) % 256 ) ;
dat . Data = bytes ;
return ( dat ) ;
}
// Sends animation update
public void SendAnimPack ( )
{
AvatarAnimationPacket ani = new AvatarAnimationPacket ( ) ;
ani . AnimationSourceList = new AvatarAnimationPacket . AnimationSourceListBlock [ 1 ] ;
ani . AnimationSourceList [ 0 ] = new AvatarAnimationPacket . AnimationSourceListBlock ( ) ;
ani . AnimationSourceList [ 0 ] . ObjectID = ControllingClient . AgentID ;
ani . Sender = new AvatarAnimationPacket . SenderBlock ( ) ;
ani . Sender . ID = ControllingClient . AgentID ;
ani . AnimationList = new AvatarAnimationPacket . AnimationListBlock [ 1 ] ;
ani . AnimationList [ 0 ] = new AvatarAnimationPacket . AnimationListBlock ( ) ;
ani . AnimationList [ 0 ] . AnimID = this . current_anim ;
ani . AnimationList [ 0 ] . AnimSequenceID = this . anim_seq ;
//ControllingClient.OutPacket(ani);
foreach ( SimClient client in m_clientThreads . Values )
{
client . OutPacket ( ani ) ;
}
}
}
}