public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedBlock() { uint ID = this.localid; byte[] bytes = new byte[60]; int i = 0; ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); //dat.TextureEntry = this.OurPacket.ObjectData[0].TextureEntry; dat.TextureEntry = new byte[0]; //Console.WriteLine("texture-entry length in improvedterse block is " + this.OurPacket.ObjectData[0].TextureEntry.Length); 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++] = 0; LLVector3 lPos; Axiom.MathLib.Quaternion lRot; if (this._physActor != null && this.physicsEnabled) { PhysicsVector pPos = this._physActor.Position; lPos = new LLVector3(pPos.X, pPos.Y, pPos.Z); lRot = this._physActor.Orientation; } else { lPos = this.Pos; lRot = this.rotation; } byte[] pb = lPos.GetBytes(); Array.Copy(pb, 0, bytes, i, pb.Length); i += 12; ushort ac = 32767; //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); //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); ushort rw, rx, ry, rz; rw = (ushort)(32768 * (lRot.w + 1)); rx = (ushort)(32768 * (lRot.x + 1)); ry = (ushort)(32768 * (lRot.y + 1)); rz = (ushort)(32768 * (lRot.z + 1)); //rot bytes[i++] = (byte)(rx % 256); bytes[i++] = (byte)((rx >> 8) % 256); bytes[i++] = (byte)(ry % 256); bytes[i++] = (byte)((ry >> 8) % 256); bytes[i++] = (byte)(rz % 256); bytes[i++] = (byte)((rz >> 8) % 256); bytes[i++] = (byte)(rw % 256); bytes[i++] = (byte)((rw >> 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 override void update() { if (this._physActor == null) { //HACKHACK: Note to work out why this entity does not have a physics actor // and prehaps create one. return; } 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; } } } 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)); } } }
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); }
private ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateTerseUpdateBlock(ISceneEntity entity, bool withTexture) { bool isAvatar = (entity is IScenePresence); LLPrimitive prim = entity as LLPrimitive; Quaternion rotation = entity.RelativeRotation; Vector3 velocity; Vector3 acceleration; Vector3 angularVelocity; int pos = 0; byte[] data = new byte[isAvatar ? 60 : 44]; // LocalID Utils.UIntToBytes(entity.LocalID, data, pos); pos += 4; // State byte state = 0; if (prim != null) state = prim.Prim.PrimData.State; data[pos++] = state; // Avatar/CollisionPlane if (isAvatar) { Vector4 collisionPlane = (entity is IPhysicalPresence) ? ((IPhysicalPresence)entity).CollisionPlane : Vector4.UnitW; if (collisionPlane == Vector4.Zero) collisionPlane = Vector4.UnitW; data[pos++] = 1; collisionPlane.ToBytes(data, pos); pos += 16; } else { ++pos; } if (entity is IPhysical) { IPhysical physical = (IPhysical)entity; velocity = physical.Velocity; acceleration = physical.Acceleration; angularVelocity = physical.AngularVelocity; } else { velocity = Vector3.Zero; acceleration = Vector3.Zero; angularVelocity = Vector3.Zero; } // Damp small values if (velocity.ApproxEquals(Vector3.Zero, 2f)) velocity = Vector3.Zero; if (angularVelocity.ApproxEquals(Vector3.Zero, 2f)) angularVelocity = Vector3.Zero; // Position entity.RelativePosition.ToBytes(data, pos); pos += 12; // Velocity Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2; // Acceleration Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2; // Rotation Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.X, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Y, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Z, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2; // Angular Velocity Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); block.Data = data; if (withTexture && prim != null) { byte[] textureBytes = prim.Prim.Textures.GetBytes(); byte[] textureEntry = new byte[textureBytes.Length + 4]; // Texture Length Utils.IntToBytes(textureBytes.Length, textureEntry, 0); // Texture Buffer.BlockCopy(textureBytes, 0, textureEntry, 4, textureBytes.Length); block.TextureEntry = textureEntry; } else { block.TextureEntry = Utils.EmptyBytes; } return block; }
/// <summary> /// A terse object update, used when a transformation matrix or /// velocity/acceleration for an object changes but nothing else /// (scale/position/rotation/acceleration/velocity). (From OpenMetaverse, with edits) /// </summary> /// <param name="packet"></param> /// <param name="simulator"></param> private Packet TerseUpdateHandler(Packet packet, IPEndPoint simulator) { ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)packet; //UpdateDilation(simulator, terse.RegionData.TimeDilation); for (int i = 0; i < terse.ObjectData.Length; i++) { ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = terse.ObjectData[i]; try { int pos = 4; uint localid = Utils.BytesToUInt(block.Data, 0); // Check if we are interested in this update //if (!Client.Settings.ALWAYS_DECODE_OBJECTS && localid != Client.Self.localID && OnObjectUpdated == null) //continue; #region Decode update data ObjectUpdate update = new ObjectUpdate(); // LocalID update.LocalID = localid; // State update.State = block.Data[pos++]; // Avatar boolean update.Avatar = (block.Data[pos++] != 0); // Collision normal for avatar if (update.Avatar) { update.CollisionPlane = new Vector4(block.Data, pos); pos += 16; } // Position update.Position = new Vector3(block.Data, pos); pos += 12; // Velocity update.Velocity = new Vector3( Utils.UInt16ToFloat(block.Data, pos, -128.0f, 128.0f), Utils.UInt16ToFloat(block.Data, pos + 2, -128.0f, 128.0f), Utils.UInt16ToFloat(block.Data, pos + 4, -128.0f, 128.0f)); pos += 6; // Acceleration update.Acceleration = new Vector3( Utils.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f), Utils.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f), Utils.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f)); pos += 6; // Rotation (theta) update.Rotation = new Quaternion( Utils.UInt16ToFloat(block.Data, pos, -1.0f, 1.0f), Utils.UInt16ToFloat(block.Data, pos + 2, -1.0f, 1.0f), Utils.UInt16ToFloat(block.Data, pos + 4, -1.0f, 1.0f), Utils.UInt16ToFloat(block.Data, pos + 6, -1.0f, 1.0f)); pos += 8; // Angular velocity update.AngularVelocity = new Vector3( Utils.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f), Utils.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f), Utils.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f)); pos += 6; // Textures // FIXME: Why are we ignoring the first four bytes here? if (block.TextureEntry.Length != 0) { update.Textures = new Primitive.TextureEntry(block.TextureEntry, 4, block.TextureEntry.Length - 4); } #endregion Decode update data //Primitive obj = (update.Avatar) ? //(Primitive)GetAvatar(simulator, update.LocalID, UUID.Zero) : //(Primitive)GetPrimitive(simulator, update.LocalID, UUID.Zero); #region Update Client.Self /* * if (update.LocalID == Client.Self.localID) * { * Client.Self.collisionPlane = update.CollisionPlane; * Client.Self.relativePosition = update.Position; * Client.Self.velocity = update.Velocity; * Client.Self.acceleration = update.Acceleration; * Client.Self.relativeRotation = update.Rotation; * Client.Self.angularVelocity = update.AngularVelocity; * } * */ #endregion Update Client.Self if (update.LocalID == mid) { mpos = update.Position; } else { ObjectWithVel(update.Position, update.Velocity); } } catch { //Logger.Log(e.Message, Helpers.LogLevel.Warning, Client, e); } } return(packet); }
public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedBlock() { uint ID = this.localid; byte[] bytes = new byte[60]; int i = 0; ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); //dat.TextureEntry = this.OurPacket.ObjectData[0].TextureEntry; dat.TextureEntry = new byte[0]; //Console.WriteLine("texture-entry length in improvedterse block is " + this.OurPacket.ObjectData[0].TextureEntry.Length); 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++] = 0; LLVector3 lPos; Axiom.MathLib.Quaternion lRot; if (this._physActor != null && this.physicsEnabled) { PhysicsVector pPos = this._physActor.Position; lPos = new LLVector3(pPos.X, pPos.Y, pPos.Z); lRot = this._physActor.Orientation; } else { lPos = this.Pos; lRot = this.rotation; } byte[] pb = lPos.GetBytes(); Array.Copy(pb, 0, bytes, i, pb.Length); i += 12; ushort ac = 32767; //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); //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); ushort rw, rx, ry, rz; rw = (ushort)(32768 * (lRot.w + 1)); rx = (ushort)(32768 * (lRot.x + 1)); ry = (ushort)(32768 * (lRot.y + 1)); rz = (ushort)(32768 * (lRot.z + 1)); //rot bytes[i++] = (byte)(rx % 256); bytes[i++] = (byte)((rx >> 8) % 256); bytes[i++] = (byte)(ry % 256); bytes[i++] = (byte)((ry >> 8) % 256); bytes[i++] = (byte)(rz % 256); bytes[i++] = (byte)((rz >> 8) % 256); bytes[i++] = (byte)(rw % 256); bytes[i++] = (byte)((rw >> 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 AddTerseUpdateToViewersList(ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock) { }
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); }