Added support for movements

standalone
MW 2007-02-17 21:29:53 +00:00
parent 10956993b7
commit d6bf4ede92
13 changed files with 360 additions and 46 deletions

View File

@ -49,29 +49,34 @@ namespace OpenSim
public AgentName GetAgentName(LLUUID AgentID)
{
AgentName name;
if(AgentList.ContainsKey(AgentID))
lock(AgentList)
{
name=AgentList[AgentID].Name;
}
else
{
name = new AgentName();
if(AgentList.ContainsKey(AgentID))
{
name=AgentList[AgentID].Name;
}
else
{
name = new AgentName();
}
}
return(name);
}
public AgentProfile GetAgent(LLUUID id)
{
if(!this.AgentList.ContainsKey(id))
lock(AgentList)
{
return null;
}
else
{
AgentProfile avatar = this.AgentList[id];
return avatar;
if(!this.AgentList.ContainsKey(id))
{
return null;
}
else
{
AgentProfile avatar = this.AgentList[id];
return avatar;
}
}
}
/// <summary>
@ -193,6 +198,28 @@ namespace OpenSim
_server.SendPacket(packet, true, kp.Value.Avatar.NetInfo);
}
}
public void SendTerseUpdateLists()
{
foreach (KeyValuePair<libsecondlife.LLUUID, AgentProfile> kp in this.AgentList)
{
if(kp.Value.Avatar.TerseUpdateList.Count > 0)
{
ImprovedTerseObjectUpdatePacket im = new ImprovedTerseObjectUpdatePacket();
im.RegionData.RegionHandle = Globals.Instance.RegionHandle;;
im.RegionData.TimeDilation = 64096;
im.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[kp.Value.Avatar.TerseUpdateList.Count];
for(int i = 0; i < kp.Value.Avatar.TerseUpdateList.Count; i++)
{
im.ObjectData[i] = kp.Value.Avatar.TerseUpdateList[i];
}
_server.SendPacket(im, true, kp.Value.Avatar.NetInfo);
kp.Value.Avatar.TerseUpdateList.Clear();
}
}
}
}
public struct AgentName
@ -219,7 +246,7 @@ namespace OpenSim
public NetworkInfo NetInfo;
public LLUUID FullID;
public uint LocalID;
//public LLQuaternion Rotation;
public LLQuaternion BodyRotation;
public bool Walk = false;
public bool Started = false;
//public TextureEntry TextureEntry;
@ -248,8 +275,8 @@ namespace OpenSim
public class AvatarWearable
{
public LLUUID AssetID;
public LLUUID ItemID;
public LLUUID AssetID = new LLUUID("00000000-0000-0000-0000-000000000000");
public LLUUID ItemID = new LLUUID("00000000-0000-0000-0000-000000000000");
public AvatarWearable()
{

View File

@ -41,7 +41,6 @@ namespace OpenSim
public sbyte InvType;
public string Name;
public string Description;
public string Filename;
public AssetBase()
{
@ -58,9 +57,10 @@ namespace OpenSim
this.PrimData = new PrimData();
}
}
public class PrimData
public class PrimData : Node
{
public LLUUID OwnerID;
public uint LocalID;
public byte PCode;
public byte PathBegin;
public byte PathEnd;
@ -82,6 +82,16 @@ namespace OpenSim
{
}
public void FromBytes(byte[] bytes)
{
}
public byte[] ToBytes()
{
return null;
}
}
//a hangover from the old code, so is it needed for future use?

View File

@ -71,7 +71,6 @@ namespace OpenSim
public void Open(string dbDir, string appName, Stream errStream) {
this.dbDir = dbDir;
//Remove();
// open local prim database
Db db = new Db(DbCreateFlags.None);
@ -152,7 +151,11 @@ namespace OpenSim
protected override void SerializeValue(PrimAsset value) {
Formatter.Serialize<string>(value.Name);
Formatter.Serialize<string>(value.Description);
Formatter.Serialize<int>((int?)value.Data.Length);
for( int i = 0; i < value.Data.Length; i++)
{
Formatter.Serialize<byte>((byte?)value.Data[i]);
}
}
protected override void DeserializeInstance(ref PrimAsset instance) {
@ -163,12 +166,22 @@ namespace OpenSim
protected override void DeserializeMembers(PrimAsset instance) {
Formatter.Deserialize<string>(ref instance.Name);
Formatter.Deserialize<string>(ref instance.Description);
int dataLength;
dataLength =(int) Formatter.Deserialize<int>();
instance.Data = new byte[dataLength];
for( int i = 0; i < dataLength; i++)
{
instance.Data[i] =(byte) Formatter.Deserialize<byte>();
}
}
protected override void SkipValue() {
if (Formatter.Skip<string>())
Formatter.Skip<string>();
if (Formatter.Skip<string>())
if ( Formatter.Skip<int>())
Formatter.Skip<byte[]>();
}
}
@ -179,7 +192,11 @@ namespace OpenSim
protected override void SerializeValue(AssetBase value) {
Formatter.Serialize<string>(value.Name);
Formatter.Serialize<string>(value.Description);
Formatter.Serialize<int>((int?)value.Data.Length);
for( int i = 0; i < value.Data.Length; i++)
{
Formatter.Serialize<byte>((byte?)value.Data[i]);
}
}
protected override void DeserializeInstance(ref AssetBase instance) {
@ -190,12 +207,21 @@ namespace OpenSim
protected override void DeserializeMembers(AssetBase instance) {
Formatter.Deserialize<string>(ref instance.Name);
Formatter.Deserialize<string>(ref instance.Description);
int dataLength;
dataLength =(int) Formatter.Deserialize<int>();
instance.Data = new byte[dataLength];
for( int i = 0; i < dataLength; i++)
{
instance.Data[i] =(byte) Formatter.Deserialize<byte>();
}
}
protected override void SkipValue() {
if (Formatter.Skip<string>())
Formatter.Skip<string>();
if (Formatter.Skip<string>())
if ( Formatter.Skip<int>())
Formatter.Skip<byte[]>();
}
}
}

View File

@ -105,7 +105,13 @@ namespace OpenSim
Console.WriteLine("RegionHandshake reply");
Scene.SendTerrainData(this.NetInfo);
Scene.AddNewAvatar(AgentManager.GetAgent(this.NetInfo.User.AgentID).Avatar);
// send current avatars and prims data
break;
case PacketType.AgentWearablesRequest:
AgentManager.RequestWearables(this.NetInfo);
break;
case PacketType.AgentUpdate:
AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
Scene.AvatarMovementCommand(this.NetInfo, agentUpdate);
break;
default:
break;

View File

@ -27,6 +27,7 @@ Copyright (c) OpenSim project, http://sim.opensecondlife.org/
using System;
using System.Timers;
using System.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
@ -43,6 +44,7 @@ namespace OpenSim
private AssetManager _assetManager;
private SceneGraph _scene;
private PrimManager _primManager;
private Timer timer1 = new Timer();
public static void Main(string[] args)
{
@ -50,14 +52,11 @@ namespace OpenSim
bool Run = true;
while( Run )
{
string input = Console.ReadLine();
if(input == "Exit")
{
Run = false;
}
}
}
BerkeleyDatabases.Instance.Close();
@ -84,6 +83,9 @@ namespace OpenSim
_loginServer = new LoginServer(_backboneServers.UserServer);
_loginServer.Startup();
}
timer1.Enabled = true;
timer1.Interval = 200;
timer1.Elapsed +=new ElapsedEventHandler( this.Timer1Tick );
}
@ -98,6 +100,12 @@ namespace OpenSim
}
void Timer1Tick( object sender, System.EventArgs e )
{
//this.time++;
this._scene.Update();
// this._assetManager.DoWork( time );
}
}
public class BackboneServers

View File

@ -241,7 +241,7 @@ namespace OpenSim
XmlNode nodes = root.FirstChild;
if (nodes.Name != "Grid")
throw new Exception("Error: Invalid File. <project> first child should be <Grid>");
throw new Exception("Error: Invalid File. <Root> first child should be <Grid>");
if (nodes.HasChildNodes) {
foreach( XmlNode xmlnc in nodes.ChildNodes)

View File

@ -52,10 +52,16 @@ namespace OpenSim
public List<InventoryFolder> Folders;
public int LastCached; //time this was last stored/compared to user server
public LLUUID AgentID;
public AvatarWearable[] Wearables;
public AgentInventory()
{
Folders = new List<InventoryFolder>();
Wearables = new AvatarWearable[2];
for(int i = 0; i < 2; i++)
{
Wearables[i] = new AvatarWearable();
}
}
}

View File

@ -50,6 +50,7 @@ namespace OpenSim
}
public void CreateNewPrimStorage(PrimAsset prim)
{
Console.WriteLine("prim data length is: "+prim.Data.Length);
byte[] dataBuffer = new byte[4096];
byte[] keyBuffer = new byte[256];
int index;

View File

@ -39,6 +39,14 @@
<HintPath>bin\Debug\Kds.Serialization.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="Axiom.MathLib">
<HintPath>bin\Debug\Axiom.MathLib.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="log4net">
<HintPath>bin\Debug\log4net.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Controller.cs" />

View File

@ -40,5 +40,23 @@ namespace OpenSim
{
_sceneGraph=sceneGraph;
}
public void UpdatePhysics()
{
lock(this._sceneGraph.RootNode)
{
for (int i = 0; i < _sceneGraph.RootNode.ChildrenCount; i++)
{
if(_sceneGraph.RootNode.GetChild(i).SceneType == 1) //check it is a avatar node
{
AvatarData avatar = (AvatarData)_sceneGraph.RootNode.GetChild(i);
avatar.Position.X += (avatar.Velocity.X * 0.2f);
avatar.Position.Y += (avatar.Velocity.Y * 0.2f);
avatar.Position.Z += (avatar.Velocity.Z * 0.2f);
}
}
}
}
}
}

View File

@ -41,17 +41,23 @@ namespace OpenSim
{
this._localPrimDB = new LocalPrimDb();
//database test
/*PrimAsset prim = new PrimAsset();
prim.Name="happy now";
prim.Description= "test";
prim.FullID = new LLUUID("00000000-0000-0000-0000-000000000008");
prim.Data= new byte[10];
prim.Data[0]=5;
prim.Data[1]=4;
prim.Data[2]=5;
prim.Data[3]=6;
prim.Data[4]=5;
this._localPrimDB.CreateNewPrimStorage(prim);
PrimAsset prim1 = this._localPrimDB.GetPrimFromStroage( new LLUUID("00000000-0000-0000-0000-000000000008"));
Console.WriteLine("prim recieved : "+prim1.Name + " "+ prim1.Description);
Console.WriteLine("prim received : "+prim1.Name + " "+ prim1.Description);
Console.WriteLine("received prims data length is: "+prim1.Data.Length);
Console.WriteLine(Helpers.FieldToString(prim1.Data));
//this._localPrimDB.ReadWholedatabase();
*/
}

View File

@ -31,6 +31,7 @@ using System.Collections.Generic;
using System.Threading;
using libsecondlife;
using libsecondlife.Packets;
using Axiom.MathLib;
namespace OpenSim
{
@ -98,6 +99,7 @@ namespace OpenSim
public void Update()
{
// run physics engine to update positions etc since last frame
this._physics.UpdatePhysics();
// process command list
lock(this.Commands) //do we want to stop new commands being added while we process?
@ -108,6 +110,21 @@ namespace OpenSim
switch(command.CommandType)
{
case 1:
//movement command
if(command.SObject.SceneType == 1)
{
AvatarData avatar =(AvatarData) command.SObject;
avatar.Walk = !avatar.Walk;
command.SObject.InternVelocityX = command.InternVelocityX;
command.SObject.InternVelocityY = command.InternVelocityY;
command.SObject.InternVelocityZ = command.InternVelocityZ;
command.SObject.Velocity = command.Velocity;
if((command.SObject.UpdateFlag & (1)) != 1)
{
command.SObject.UpdateFlag += 1;
}
}
break;
default:
break;
@ -128,15 +145,16 @@ namespace OpenSim
int updatemask = avatar.UpdateFlag & (128);
if(updatemask == 128) //is a new avatar?
{
Console.WriteLine("new avatar has been added to scene so update it on the current scene");
this.SendAvatarDataToAll(avatar);
//should send a avatar appearance to other clients except the avatar's owner
this.SendAvatarAppearanceToAllExcept(avatar);
//and send complete scene update to the new avatar's owner
this.SendCompleteSceneTo(avatar);
//reset new avatar flag
//avatar.UpdateFlag -= 128;
avatar.Started = true;
}
}
}
@ -167,9 +185,11 @@ namespace OpenSim
{
AvatarData avatar2 =(AvatarData) this.RootNode.GetChild(i);
int newmask = avatar2.UpdateFlag & (128);
if(newmask != 128) //is a new avatar?
if(newmask != 128)
//is a new avatar?
//if it is then we don't need to tell it about updates as it has already received a full update of the scene
{
//no its not so let add to its updatelist
//but if it is not then we add to its updatelist
avatar2.TerseUpdateList.Add(this.CreateTerseBlock(avatar));
}
}
@ -187,6 +207,81 @@ namespace OpenSim
this.RootNode.GetChild(i).UpdateFlag = 0;
}
}
this._agentManager.SendTerseUpdateLists();
}
public void AvatarMovementCommand(NetworkInfo userInfo, AgentUpdatePacket updatePacket)
{
uint mask = updatePacket.AgentData.ControlFlags & (1);
AvatarData avatar = _agentManager.GetAgent(userInfo.User.AgentID).Avatar;
if (avatar != null)
{
if (avatar.Started)
{
if (mask == (1))
{
if (!avatar.Walk)
{
UpdateCommand newCommand = new UpdateCommand();
newCommand.CommandType = 1;
newCommand.SObject = avatar;
//start walking
Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(1, 0, 0);
Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(updatePacket.AgentData.BodyRotation.W, updatePacket.AgentData.BodyRotation.X, updatePacket.AgentData.BodyRotation.Y, updatePacket.AgentData.BodyRotation.Z);
Axiom.MathLib.Vector3 direc = q * v3;
direc.Normalize();
Axiom.MathLib.Vector3 internDirec = new Vector3(direc.x, direc.y, direc.z);
//work out velocity for sim physics system
direc = direc * ((0.03f) * 128f);
//because of us using a frame based system we can't update the avatar directly
//so we need to add the command to the list and let the update loop deal with it
newCommand.Velocity = new libsecondlife.LLVector3(0, 0 , 0);
newCommand.Velocity.X = direc.x;
newCommand.Velocity.Y = direc.y;
newCommand.Velocity.Z = direc.z;
//avatar.Walk = true;
//work out velocity for internal clients movement commands
internDirec = internDirec * (0.03f);
internDirec.x += 1;
internDirec.y += 1;
internDirec.z += 1;
newCommand.InternVelocityX = (ushort)(32768 * internDirec.x);
newCommand.InternVelocityY = (ushort)(32768 * internDirec.y);
newCommand.InternVelocityZ = (ushort)(32768 * internDirec.z);
lock(this.Commands)
{
this.Commands.Enqueue(newCommand);
}
}
}
else
{
if (avatar.Walk)
{
UpdateCommand newCommand = new UpdateCommand();
newCommand.CommandType = 1;
newCommand.SObject = avatar;
//walking but key not pressed so need to stop
//avatar.Walk = false;
newCommand.Velocity.X = 0;
newCommand.Velocity.Y = 0;
newCommand.Velocity.Z = 0;
newCommand.InternVelocityX = (ushort)(32768 );
newCommand.InternVelocityY = (ushort)(32768 );
newCommand.InternVelocityZ = (ushort)(32768 );
lock(this.Commands)
{
this.Commands.Enqueue(newCommand);
}
}
}
}
}
}
#region send terrain data
@ -207,7 +302,7 @@ namespace OpenSim
Console.WriteLine("Sent terrain data");
//test
this.SendAvatarData(userInfo);
//this.SendAvatarData(userInfo);
}
}
@ -246,9 +341,11 @@ namespace OpenSim
public void AddNewAvatar(AvatarData avatar)
{
Console.WriteLine("adding avatar to scene");
lock(this.RootNode)
{
avatar.SceneName = "Avatar" + this._objectCount.ToString("00000");
avatar.Position = new LLVector3(100f, 100f, 22f);
this._objectCount++;
this.RootNode.AddChild(avatar);
}
@ -316,6 +413,7 @@ namespace OpenSim
#endregion
private void SendAvatarDataToAll(AvatarData avatar)
{
Console.WriteLine("sending avatar data");
ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle;
objupdate.RegionData.TimeDilation = 0;
@ -326,7 +424,7 @@ namespace OpenSim
objupdate.ObjectData[0].FullID = avatar.NetInfo.User.AgentID;
objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + avatar.NetInfo.User.FirstName + "\nLastName STRING RW SV " + avatar.NetInfo.User.LastName + " \0");
libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100.0f, 22.0f);
libsecondlife.LLVector3 pos2 = avatar.Position;
byte[] pb = pos2.GetBytes();
Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
@ -345,12 +443,109 @@ namespace OpenSim
public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateTerseBlock(AvatarData avatar)
{
return(null);
byte[] bytes = new byte[60];
int i=0;
ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
dat.TextureEntry = _avatarTemplate.TextureEntry;
libsecondlife.LLVector3 pos2 = new LLVector3(avatar.Position.X, avatar.Position.Y, avatar.Position.Z);
uint ID = avatar.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 ac = 32767;
bytes[i++] = (byte)(avatar.InternVelocityX % 256);
bytes[i++] = (byte)((avatar.InternVelocityX >> 8) % 256);
bytes[i++] = (byte)(avatar.InternVelocityY % 256);
bytes[i++] = (byte)((avatar.InternVelocityY>> 8) % 256);
bytes[i++] = (byte)(avatar.InternVelocityZ % 256);
bytes[i++] = (byte)((avatar.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);
}
public void SendAvatarAppearanceToAllExcept(AvatarData avatar)
{
AvatarAppearancePacket avp = new AvatarAppearancePacket();
avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
//avp.ObjectData.TextureEntry=this.avatar_template.TextureEntry;// br.ReadBytes((int)numBytes);
FileInfo fInfo = new FileInfo("Avatar_texture3.dat");
long numBytes = fInfo.Length;
FileStream fStream = new FileStream("Avatar_texture3.dat", FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fStream);
avp.ObjectData.TextureEntry = br.ReadBytes((int)numBytes);
br.Close();
fStream.Close();
AvatarAppearancePacket.VisualParamBlock avblock = null;
for(int i = 0; i < 218; i++)
{
avblock = new AvatarAppearancePacket.VisualParamBlock();
avblock.ParamValue = (byte)avatar.VisParams.Params[i];
avp.VisualParam[i] = avblock;
}
avp.Sender.IsTrial = false;
avp.Sender.ID = avatar.NetInfo.User.AgentID;
SendInfo send = new SendInfo();
send.Incr = true;
send.NetInfo = avatar.NetInfo;
send.Packet = avp;
send.SentTo = 2; //to all clients except avatar
this._updateSender.SendList.Enqueue(send);
}
}
@ -365,6 +560,9 @@ namespace OpenSim
public LLVector3 Position;
public LLVector3 Velocity = new LLVector3(0,0,0);
public byte UpdateFlag;
public ushort InternVelocityX = 32768;
public ushort InternVelocityY = 32768;
public ushort InternVelocityZ = 32768;
public List<Node> ChildNodes
{
@ -529,6 +727,9 @@ namespace OpenSim
public Node SObject;
public LLVector3 Position;
public LLVector3 Velocity;
public ushort InternVelocityX;
public ushort InternVelocityY;
public ushort InternVelocityZ;
public LLQuaternion Rotation;
public UpdateCommand()

View File

@ -209,6 +209,7 @@ namespace OpenSim
/// <param name="incrementSequence">Increment sequence number?</param>
public void SendPacket(Packet packet, bool incrementSequence, NetworkInfo User_info)
{
lock(this._sendPacketSync)
{
byte[] buffer;
@ -459,7 +460,6 @@ namespace OpenSim
{
temp_agent=(NetworkInfo)this.User_agents[ii];
IPEndPoint ag_ip=(IPEndPoint)temp_agent.endpoint;
//this.callback_object.error("searching: address is "+ag_ip.Address +"port number is: "+ag_ip.Port.ToString());
if((ag_ip.Address.ToString()==send_ip.Address.ToString()) && (ag_ip.Port.ToString()==send_ip.Port.ToString()))
{
@ -486,14 +486,12 @@ namespace OpenSim
{
//error finding agent
//this.CallbackObject.ErrorCallback("no user found");
return;
}
// Fail-safe check
if (packet == null)
{
//this.CallbackObject.ErrorCallback("couldn't build packet");
// Client.Log("Couldn't build a message from the incoming data", Helpers.LogLevel.Warning);
return;
}
@ -525,7 +523,6 @@ namespace OpenSim
}
// Avoid firing a callback twice for the same packet
// this.callback_object.error("avoiding callback");
return;
}
else