diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index dba06f6659..13260182cc 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -1,2125 +1,2501 @@
-/*
-* Copyright (c) Contributors, http://opensimulator.org/
-* See CONTRIBUTORS.TXT for a full list of copyright holders.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-* * Neither the name of the OpenSim Project nor the
-* names of its contributors may be used to endorse or promote products
-* derived from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
-* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-using System;
-using System.Text; // rex, StringBuilder needed
-using System.Collections.Generic;
-using System.Drawing;
-using System.Xml;
-using System.Xml.Serialization;
-using Axiom.Math;
-using libsecondlife;
-using libsecondlife.Packets;
-using OpenSim.Framework;
-using OpenSim.Framework.Console;
-using OpenSim.Region.Environment.Interfaces;
-using OpenSim.Region.Environment.Scenes.Scripting;
-using OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Environment.Scenes
-{
- public partial class SceneObjectPart : IScriptHost
- {
- private const LLObject.ObjectFlags OBJFULL_MASK_GENERAL =
- LLObject.ObjectFlags.ObjectCopy | LLObject.ObjectFlags.ObjectModify | LLObject.ObjectFlags.ObjectTransfer;
-
- private const LLObject.ObjectFlags OBJFULL_MASK_OWNER =
- LLObject.ObjectFlags.ObjectCopy | LLObject.ObjectFlags.ObjectModify | LLObject.ObjectFlags.ObjectOwnerModify |
- LLObject.ObjectFlags.ObjectTransfer | LLObject.ObjectFlags.ObjectYouOwner;
-
- private const uint OBJNEXT_OWNER = 2147483647;
-
- private const uint FULL_MASK_PERMISSIONS_GENERAL = 2147483647;
- private const uint FULL_MASK_PERMISSIONS_OWNER = 2147483647;
-
- [XmlIgnore] public PhysicsActor PhysActor = null;
-
- public LLUUID LastOwnerID;
- public LLUUID OwnerID;
- public LLUUID GroupID;
- public int OwnershipCost;
- public byte ObjectSaleType;
- public int SalePrice;
- public uint Category;
-
- public Int32 CreationDate;
- public uint ParentID = 0;
-
- private Vector3 m_sitTargetPosition = new Vector3(0, 0, 0);
- private Quaternion m_sitTargetOrientation = new Quaternion(0, 0, 0, 1);
- private LLUUID m_SitTargetAvatar = LLUUID.Zero;
-
- //
- // Main grid has default permissions as follows
- //
- public uint OwnerMask = FULL_MASK_PERMISSIONS_OWNER;
- public uint NextOwnerMask = OBJNEXT_OWNER;
- public uint GroupMask = (uint) LLObject.ObjectFlags.None;
- public uint EveryoneMask = (uint) LLObject.ObjectFlags.None;
- public uint BaseMask = FULL_MASK_PERMISSIONS_OWNER;
-
- protected byte[] m_particleSystem = new byte[0];
-
- [XmlIgnore] public uint TimeStampFull = 0;
- [XmlIgnore] public uint TimeStampTerse = 0;
- [XmlIgnore] public uint TimeStampLastActivity = 0; // Will be used for AutoReturn
-
- ///
- /// Only used internally to schedule client updates
- ///
- private byte m_updateFlag;
-
- // rex, extra parameters & their definitions
-
- // reX extra block parameters in easily readable format
- public string m_RexClassName = "";
- public byte m_RexFlags = 0;
- public byte m_RexCollisionType = 0;
- public float m_RexDrawDistance = 0.0F;
- public float m_RexLOD = 0.0F;
- public LLUUID m_RexMeshUUID = LLUUID.Zero;
- public LLUUID m_RexCollisionMeshUUID = LLUUID.Zero;
- public List m_RexMaterialUUID = new List();
- public byte m_RexFixedMaterial = 0;
- public LLUUID m_RexParticleScriptUUID = LLUUID.Zero;
-
- // reX extra parameter block defines
- public const int PARAMS_REX = 0x0100;
-
- // Bit values for flags
- public const int REXFLAGS_ISMESH = 0x01;
- public const int REXFLAGS_ISVISIBLE = 0x02;
- public const int REXFLAGS_CASTSHADOWS = 0x04;
- public const int REXFLAGS_SHOWTEXT = 0x08;
- public const int REXFLAGS_SCALEMESH = 0x10;
- public const int REXFLAGS_SOLIDALPHA = 0x20;
- public const int REXFLAGS_ISBILLBOARD = 0x40;
- public const int REXFLAGS_USEPARTICLESCRIPT = 0x80;
-
- // Collision type enumeration (still unused :))
- public const int REXCOLLISION_VOLUME = 0x01;
- public const int REXCOLLISION_TRIMESH = 0x02;
-
- // Attachment parameters
- private ScenePresence m_attachPresence = null;
- private byte m_attachPt;
- private LLQuaternion m_attachRot;
- private RegionInfo m_attachRegInfo;
- private LLUUID m_attachAgentId;
-
- // rexend
-
- #region Properties
-
- public LLUUID CreatorID;
-
- public LLUUID ObjectCreator
- {
- get { return CreatorID; }
- }
-
- protected LLUUID m_uuid;
-
- public LLUUID UUID
- {
- get { return m_uuid; }
- set { m_uuid = value; }
- }
-
- protected uint m_localID;
-
- public uint LocalID
- {
- get { return m_localID; }
- set { m_localID = value; }
- }
-
- protected string m_name;
-
- public virtual string Name
- {
- get { return m_name; }
- set { m_name = value; }
- }
-
- protected LLObject.ObjectFlags m_flags = 0;
-
- public uint ObjectFlags
- {
- get { return (uint) m_flags; }
- set { m_flags = (LLObject.ObjectFlags) value; }
- }
-
- protected LLObject.MaterialType m_material = 0;
-
- public byte Material
- {
- get { return (byte) m_material; }
- set { m_material = (LLObject.MaterialType) value; }
- }
-
- protected ulong m_regionHandle;
-
- public ulong RegionHandle
- {
- get { return m_regionHandle; }
- set { m_regionHandle = value; }
- }
-
- //unkown if this will be kept, added as a way of removing the group position from the group class
- protected LLVector3 m_groupPosition;
-
-
- public LLVector3 GroupPosition
- {
- get
- {
- if (PhysActor != null)
- {
- m_groupPosition.X = PhysActor.Position.X;
- m_groupPosition.Y = PhysActor.Position.Y;
- m_groupPosition.Z = PhysActor.Position.Z;
- }
- return m_groupPosition;
- }
- set
- {
- if (PhysActor != null)
- {
- try
- {
- //lock (m_parentGroup.Scene.SyncRoot)
- //{
- PhysActor.Position = new PhysicsVector(value.X, value.Y, value.Z);
- m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
- //}
- }
- catch (Exception e)
- {
- Console.WriteLine(e.Message);
- }
- }
- m_groupPosition = value;
- }
- }
-
- protected LLVector3 m_offsetPosition;
-
- public LLVector3 OffsetPosition
- {
- get { return m_offsetPosition; }
- set { m_offsetPosition = value; }
- }
-
- public LLVector3 AbsolutePosition
- {
- get { return m_offsetPosition + m_groupPosition; }
- }
-
- protected LLQuaternion m_rotationOffset;
-
- public LLQuaternion RotationOffset
- {
- get
- {
- if (PhysActor != null)
- {
- if (PhysActor.Orientation.x != 0 || PhysActor.Orientation.y != 0
- || PhysActor.Orientation.z != 0 || PhysActor.Orientation.w != 0)
- {
- m_rotationOffset.X = PhysActor.Orientation.x;
- m_rotationOffset.Y = PhysActor.Orientation.y;
- m_rotationOffset.Z = PhysActor.Orientation.z;
- m_rotationOffset.W = PhysActor.Orientation.w;
- }
- }
- return m_rotationOffset;
- }
- set
- {
- if (PhysActor != null)
- {
- try
- {
- //lock (Scene.SyncRoot)
- //{
- PhysActor.Orientation = new Quaternion(value.W, value.X, value.Y, value.Z);
- m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
- //}
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- }
- m_rotationOffset = value;
- }
- }
-
- protected LLVector3 m_velocity;
- protected LLVector3 m_rotationalvelocity;
-
- ///
- public LLVector3 Velocity
- {
- get
- {
- //if (PhysActor.Velocity.x != 0 || PhysActor.Velocity.y != 0
- //|| PhysActor.Velocity.z != 0)
- //{
- if (PhysActor != null)
- {
- if (PhysActor.IsPhysical)
- {
- m_velocity.X = PhysActor.Velocity.X;
- m_velocity.Y = PhysActor.Velocity.Y;
- m_velocity.Z = PhysActor.Velocity.Z;
- }
- }
-
- return m_velocity;
- }
- set { m_velocity = value; }
- }
-
- public LLVector3 RotationalVelocity
- {
- get
- {
- //if (PhysActor.Velocity.x != 0 || PhysActor.Velocity.y != 0
- //|| PhysActor.Velocity.z != 0)
- //{
- if (PhysActor != null)
- {
- if (PhysActor.IsPhysical)
- {
- m_rotationalvelocity.X = PhysActor.RotationalVelocity.X;
- m_rotationalvelocity.Y = PhysActor.RotationalVelocity.Y;
- m_rotationalvelocity.Z = PhysActor.RotationalVelocity.Z;
- }
- }
-
- return m_rotationalvelocity;
- }
- set { m_rotationalvelocity = value; }
- }
-
-
- protected LLVector3 m_angularVelocity;
-
- ///
- public LLVector3 AngularVelocity
- {
- get { return m_angularVelocity; }
- set { m_angularVelocity = value; }
- }
-
- protected LLVector3 m_acceleration;
-
- ///
- public LLVector3 Acceleration
- {
- get { return m_acceleration; }
- set { m_acceleration = value; }
- }
-
- private string m_description = "";
-
- public string Description
- {
- get { return m_description; }
- set { m_description = value; }
- }
-
- private Color m_color = Color.Black;
-
- public Color Color
- {
- get { return m_color; }
- set
- {
- m_color = value;
- /* ScheduleFullUpdate() need not be called b/c after
- * setting the color, the text will be set, so then
- * ScheduleFullUpdate() will be called. */
- //ScheduleFullUpdate();
- }
- }
-
- private string m_text = "";
-
- public Vector3 SitTargetPosition
- {
- get { return m_sitTargetPosition; }
- }
-
- public Quaternion SitTargetOrientation
- {
- get { return m_sitTargetOrientation; }
- }
-
- public string Text
- {
- get { return m_text; }
- set
- {
- m_text = value;
- ScheduleFullUpdate();
- }
- }
-
- private string m_sitName = "";
-
- public string SitName
- {
- get { return m_sitName; }
- set { m_sitName = value; }
- }
-
- private string m_touchName = "";
-
- //rex (hack)
- private LLUUID touchedBy = LLUUID.Zero;
-
- //rex (hack)
- public LLUUID TouchedBy
- {
- set
- {
- touchedBy = value;
- }
- get
- {
- return touchedBy;
- }
- }
-
- public string TouchName
- {
- get { return m_touchName; }
- set { m_touchName = value; }
- }
-
- private int m_linkNum = 0;
-
- public int LinkNum
- {
- get { return m_linkNum; }
- set { m_linkNum = value; }
- }
-
- private byte m_clickAction = 0;
-
- public byte ClickAction
- {
- get { return m_clickAction; }
- set
- {
- m_clickAction = value;
- ScheduleFullUpdate();
- }
- }
-
- protected PrimitiveBaseShape m_shape;
-
- public PrimitiveBaseShape Shape
- {
- get { return m_shape; }
- set { m_shape = value; }
- }
-
- public LLVector3 Scale
- {
- set { m_shape.Scale = value; }
- get { return m_shape.Scale; }
- }
-
- public bool Stopped
- {
- get {
- double threshold = 0.02;
- return (Math.Abs(Velocity.X) < threshold &&
- Math.Abs(Velocity.Y) < threshold &&
- Math.Abs(Velocity.Z) < threshold &&
- Math.Abs(AngularVelocity.X) < threshold &&
- Math.Abs(AngularVelocity.Y) < threshold &&
- Math.Abs(AngularVelocity.Z) < threshold);
- }
- }
-
- #endregion
-
- public LLUUID ObjectOwner
- {
- get { return OwnerID; }
- }
-
- // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out.
- protected SceneObjectGroup m_parentGroup;
-
- public SceneObjectGroup ParentGroup
- {
- get { return m_parentGroup; }
- }
-
- public byte UpdateFlag
- {
- get { return m_updateFlag; }
- set { m_updateFlag = value; }
- }
-
- #region Constructors
-
- ///
- /// No arg constructor called by region restore db code
- ///
- public SceneObjectPart()
- {
- // It's not necessary to persist this
- m_inventoryFileName = "taskinventory" + LLUUID.Random().ToString();
- }
-
- public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID,
- PrimitiveBaseShape shape, LLVector3 groupPosition, LLVector3 offsetPosition)
- : this(regionHandle, parent, ownerID, localID, shape, groupPosition, LLQuaternion.Identity, offsetPosition)
- {
- }
-
- ///
- /// Create a completely new SceneObjectPart (prim)
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID,
- PrimitiveBaseShape shape, LLVector3 groupPosition, LLQuaternion rotationOffset,
- LLVector3 offsetPosition)
- {
- m_name = "Primitive";
- m_regionHandle = regionHandle;
- m_parentGroup = parent;
-
- CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
- OwnerID = ownerID;
- CreatorID = OwnerID;
- LastOwnerID = LLUUID.Zero;
- UUID = LLUUID.Random();
- LocalID = (uint) (localID);
- Shape = shape;
- // Todo: Add More Object Parameter from above!
- OwnershipCost = 0;
- ObjectSaleType = (byte) 0;
- SalePrice = 0;
- Category = (uint) 0;
- LastOwnerID = CreatorID;
- // End Todo: ///
- GroupPosition = groupPosition;
- OffsetPosition = offsetPosition;
- RotationOffset = rotationOffset;
- Velocity = new LLVector3(0, 0, 0);
- m_rotationalvelocity = new LLVector3(0, 0, 0);
- AngularVelocity = new LLVector3(0, 0, 0);
- Acceleration = new LLVector3(0, 0, 0);
-
- m_inventoryFileName = "taskinventory" + LLUUID.Random().ToString();
- m_folderID = LLUUID.Random();
-
- m_flags = 0;
- m_flags |= LLObject.ObjectFlags.Touch |
- LLObject.ObjectFlags.AllowInventoryDrop |
- LLObject.ObjectFlags.CreateSelected;
-
- ApplySanePermissions();
-
- ScheduleFullUpdate();
- }
-
- ///
- /// Re/create a SceneObjectPart (prim)
- /// currently not used, and maybe won't be
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, int creationDate, LLUUID ownerID,
- LLUUID creatorID, LLUUID lastOwnerID, uint localID, PrimitiveBaseShape shape,
- LLVector3 position, LLQuaternion rotation, uint flags)
- {
- m_regionHandle = regionHandle;
- m_parentGroup = parent;
- TimeStampTerse = (uint) Util.UnixTimeSinceEpoch();
- CreationDate = creationDate;
- OwnerID = ownerID;
- CreatorID = creatorID;
- LastOwnerID = lastOwnerID;
- UUID = LLUUID.Random();
- LocalID = (uint) (localID);
- Shape = shape;
- OwnershipCost = 0;
- ObjectSaleType = (byte) 0;
- SalePrice = 0;
- Category = (uint) 0;
- LastOwnerID = CreatorID;
- OffsetPosition = position;
- RotationOffset = rotation;
- ObjectFlags = flags;
-
- ApplySanePermissions();
- // ApplyPhysics();
-
- ScheduleFullUpdate();
- }
-
- #endregion
-
- ///
- ///
- ///
- ///
- ///
- public static SceneObjectPart FromXml(XmlReader xmlReader)
- {
- XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart));
- SceneObjectPart newobject = (SceneObjectPart) serializer.Deserialize(xmlReader);
- return newobject;
- }
-
- public void ApplyPhysics()
- {
- bool isPhysical = ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0);
- bool isPhantom = ((ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) != 0);
-
- bool usePhysics = isPhysical && !isPhantom;
-
- if (usePhysics)
- {
- PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
- Name,
- Shape,
- new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
- AbsolutePosition.Z),
- new PhysicsVector(Scale.X, Scale.Y, Scale.Z),
- new Quaternion(RotationOffset.W, RotationOffset.X,
- RotationOffset.Y, RotationOffset.Z), usePhysics,LocalID);
- }
-
- DoPhysicsPropertyUpdate(usePhysics, true);
- }
-
- public void ApplyNextOwnerPermissions()
- {
- BaseMask = NextOwnerMask;
- OwnerMask = NextOwnerMask;
- }
-
- public void ApplySanePermissions()
- {
- // These are some flags that The OwnerMask should never have
- OwnerMask &= ~(uint) LLObject.ObjectFlags.ObjectGroupOwned;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.Physics;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.Phantom;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.Scripted;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.Touch;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.Temporary;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.TemporaryOnRez;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.ZlibCompressed;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.AllowInventoryDrop;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.AnimSource;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.Money;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.CastShadows;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.InventoryEmpty;
- OwnerMask &= ~(uint) LLObject.ObjectFlags.CreateSelected;
-
-
- // These are some flags that the next owner mask should never have
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ObjectYouOwner;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ObjectTransfer;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ObjectOwnerModify;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ObjectGroupOwned;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Physics;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Phantom;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Scripted;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Touch;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Temporary;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.TemporaryOnRez;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ZlibCompressed;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.AllowInventoryDrop;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.AnimSource;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Money;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.CastShadows;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.InventoryEmpty;
- NextOwnerMask &= ~(uint) LLObject.ObjectFlags.CreateSelected;
-
-
- // These are some flags that the GroupMask should never have
- GroupMask &= ~(uint) LLObject.ObjectFlags.ObjectYouOwner;
- GroupMask &= ~(uint) LLObject.ObjectFlags.ObjectTransfer;
- GroupMask &= ~(uint) LLObject.ObjectFlags.ObjectOwnerModify;
- GroupMask &= ~(uint) LLObject.ObjectFlags.ObjectGroupOwned;
- GroupMask &= ~(uint) LLObject.ObjectFlags.Physics;
- GroupMask &= ~(uint) LLObject.ObjectFlags.Phantom;
- GroupMask &= ~(uint) LLObject.ObjectFlags.Scripted;
- GroupMask &= ~(uint) LLObject.ObjectFlags.Touch;
- GroupMask &= ~(uint) LLObject.ObjectFlags.Temporary;
- GroupMask &= ~(uint) LLObject.ObjectFlags.TemporaryOnRez;
- GroupMask &= ~(uint) LLObject.ObjectFlags.ZlibCompressed;
- GroupMask &= ~(uint) LLObject.ObjectFlags.AllowInventoryDrop;
- GroupMask &= ~(uint) LLObject.ObjectFlags.AnimSource;
- GroupMask &= ~(uint) LLObject.ObjectFlags.Money;
- GroupMask &= ~(uint) LLObject.ObjectFlags.CastShadows;
- GroupMask &= ~(uint) LLObject.ObjectFlags.InventoryEmpty;
- GroupMask &= ~(uint) LLObject.ObjectFlags.CreateSelected;
-
-
- // These are some flags that EveryoneMask should never have
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.ObjectYouOwner;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.ObjectTransfer;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.ObjectOwnerModify;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.ObjectGroupOwned;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.Physics;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.Phantom;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.Scripted;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.Touch;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.Temporary;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.TemporaryOnRez;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.ZlibCompressed;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.AllowInventoryDrop;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.AnimSource;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.Money;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.CastShadows;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.InventoryEmpty;
- EveryoneMask &= ~(uint) LLObject.ObjectFlags.CreateSelected;
- EveryoneMask &= ~(uint)LLObject.ObjectFlags.ObjectYouOfficer;
- EveryoneMask &= ~(uint)LLObject.ObjectFlags.ObjectModify;
-
-
- // These are some flags that ObjectFlags (m_flags) should never have
- ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectYouOwner;
- ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectTransfer;
- ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectOwnerModify;
- ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectYouOfficer;
- ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectCopy;
- ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectModify;
- ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectMove;
- }
-
- ///
- ///
- ///
- ///
- public void ToXml(XmlWriter xmlWriter)
- {
- XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart));
- serializer.Serialize(xmlWriter, this);
- }
-
- public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot)
- {
- // In this case we're using a sphere with a radius of the largest dimention of the prim
- // TODO: Change to take shape into account
-
-
- EntityIntersection returnresult = new EntityIntersection();
- Vector3 vAbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
-
- Vector3 vScale = new Vector3(Scale.X, Scale.Y, Scale.Z);
- Quaternion qRotation =
- new Quaternion(RotationOffset.W, RotationOffset.X, RotationOffset.Y, RotationOffset.Z);
-
-
- //Quaternion worldRotation = (qRotation*parentrot);
- //Matrix3 worldRotM = worldRotation.ToRotationMatrix();
-
-
- Vector3 rOrigin = iray.Origin;
- Vector3 rDirection = iray.Direction;
-
-
-
- //rDirection = rDirection.Normalize();
- // Buidling the first part of the Quadratic equation
- Vector3 r2ndDirection = rDirection*rDirection;
- float itestPart1 = r2ndDirection.x + r2ndDirection.y + r2ndDirection.z;
-
- // Buidling the second part of the Quadratic equation
- Vector3 tmVal2 = rOrigin - vAbsolutePosition;
- Vector3 r2Direction = rDirection*2.0f;
- Vector3 tmVal3 = r2Direction*tmVal2;
-
- float itestPart2 = tmVal3.x + tmVal3.y + tmVal3.z;
-
- // Buidling the third part of the Quadratic equation
- Vector3 tmVal4 = rOrigin*rOrigin;
- Vector3 tmVal5 = vAbsolutePosition*vAbsolutePosition;
-
- Vector3 tmVal6 = vAbsolutePosition*rOrigin;
-
-
- // Set Radius to the largest dimention of the prim
- float radius = 0f;
- if (vScale.x > radius)
- radius = vScale.x;
- if (vScale.y > radius)
- radius = vScale.y;
- if (vScale.z > radius)
- radius = vScale.z;
-
- //radius = radius;
-
- float itestPart3 = tmVal4.x + tmVal4.y + tmVal4.z + tmVal5.x + tmVal5.y + tmVal5.z -
- (2.0f*(tmVal6.x + tmVal6.y + tmVal6.z + (radius*radius)));
-
- // Yuk Quadradrics.. Solve first
- float rootsqr = (itestPart2*itestPart2) - (4.0f*itestPart1*itestPart3);
- if (rootsqr < 0.0f)
- {
- // No intersection
- return returnresult;
- }
- float root = ((-itestPart2) - (float) Math.Sqrt((double) rootsqr))/(itestPart1*2.0f);
-
- if (root < 0.0f)
- {
- // perform second quadratic root solution
- root = ((-itestPart2) + (float) Math.Sqrt((double) rootsqr))/(itestPart1*2.0f);
-
- // is there any intersection?
- if (root < 0.0f)
- {
- // nope, no intersection
- return returnresult;
- }
- }
-
- // We got an intersection. putting together an EntityIntersection object with the
- // intersection information
- Vector3 ipoint =
- new Vector3(iray.Origin.x + (iray.Direction.x*root), iray.Origin.y + (iray.Direction.y*root),
- iray.Origin.z + (iray.Direction.z*root));
-
- returnresult.HitTF = true;
- returnresult.ipoint = ipoint;
-
- // Normal is calculated by the difference and then normalizing the result
- Vector3 normalpart = ipoint - vAbsolutePosition;
- returnresult.normal = normalpart.Normalize();
-
- // It's funny how the LLVector3 object has a Distance function, but the Axiom.Math object doesnt.
- // I can write a function to do it.. but I like the fact that this one is Static.
-
- LLVector3 distanceConvert1 = new LLVector3(iray.Origin.x, iray.Origin.y, iray.Origin.z);
- LLVector3 distanceConvert2 = new LLVector3(ipoint.x, ipoint.y, ipoint.z);
- float distance = (float) Util.GetDistanceTo(distanceConvert1, distanceConvert2);
-
- returnresult.distance = distance;
-
- return returnresult;
- }
-
-
- ///
- ///
- ///
- public void SetParent(SceneObjectGroup parent)
- {
- m_parentGroup = parent;
- }
-
- public void SetSitTarget(Vector3 offset, Quaternion orientation)
- {
- m_sitTargetPosition = offset;
- m_sitTargetOrientation = orientation;
- }
-
- public LLVector3 GetSitTargetPositionLL()
- {
- return new LLVector3(m_sitTargetPosition.x, m_sitTargetPosition.y, m_sitTargetPosition.z);
- }
-
- public LLQuaternion GetSitTargetOrientationLL()
- {
- return
- new LLQuaternion(m_sitTargetOrientation.x, m_sitTargetOrientation.y, m_sitTargetOrientation.z,
- m_sitTargetOrientation.w);
- }
-
- // Utility function so the databases don't have to reference axiom.math
- public void SetSitTargetLL(LLVector3 offset, LLQuaternion orientation)
- {
- if (
- !(offset.X == 0 && offset.Y == 0 && offset.Z == 0 && (orientation.W == 0 || orientation.W == 1) &&
- orientation.X == 0 && orientation.Y == 0 && orientation.Z == 0))
- {
- m_sitTargetPosition = new Vector3(offset.X, offset.Y, offset.Z);
- m_sitTargetOrientation = new Quaternion(orientation.W, orientation.X, orientation.Y, orientation.Z);
- }
- }
-
- public Vector3 GetSitTargetPosition()
- {
- return m_sitTargetPosition;
- }
-
- public Quaternion GetSitTargetOrientation()
- {
- return m_sitTargetOrientation;
- }
-
- public void SetAvatarOnSitTarget(LLUUID avatarID)
- {
- m_SitTargetAvatar = avatarID;
- }
-
- public LLUUID GetAvatarOnSitTarget()
- {
- return m_SitTargetAvatar;
- }
-
-
- public LLUUID GetRootPartUUID()
- {
- if (m_parentGroup != null)
- {
- return m_parentGroup.UUID;
- }
- return LLUUID.Zero;
- }
-
- public static SceneObjectPart Create()
- {
- SceneObjectPart part = new SceneObjectPart();
- part.UUID = LLUUID.Random();
-
- PrimitiveBaseShape shape = PrimitiveBaseShape.Create();
- part.Shape = shape;
-
- part.Name = "Primitive";
- part.OwnerID = LLUUID.Random();
-
- return part;
- }
-
- #region Copying
-
- ///
- ///
- ///
- ///
- public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID)
- {
- SceneObjectPart dupe = (SceneObjectPart) MemberwiseClone();
- dupe.m_shape = m_shape.Copy();
- dupe.m_regionHandle = m_regionHandle;
- dupe.UUID = LLUUID.Random();
- dupe.LocalID = localID;
- dupe.OwnerID = AgentID;
- dupe.GroupID = GroupID;
- dupe.GroupPosition = new LLVector3(GroupPosition.X, GroupPosition.Y, GroupPosition.Z);
- dupe.OffsetPosition = new LLVector3(OffsetPosition.X, OffsetPosition.Y, OffsetPosition.Z);
- dupe.RotationOffset =
- new LLQuaternion(RotationOffset.X, RotationOffset.Y, RotationOffset.Z, RotationOffset.W);
- dupe.Velocity = new LLVector3(0, 0, 0);
- dupe.Acceleration = new LLVector3(0, 0, 0);
- dupe.AngularVelocity = new LLVector3(0, 0, 0);
- dupe.ObjectFlags = ObjectFlags;
-
- dupe.OwnershipCost = OwnershipCost;
- dupe.ObjectSaleType = ObjectSaleType;
- dupe.SalePrice = SalePrice;
- dupe.Category = Category;
-
- // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
- dupe.LastOwnerID = ObjectOwner;
-
- byte[] extraP = new byte[Shape.ExtraParams.Length];
- Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
- dupe.Shape.ExtraParams = extraP;
- bool UsePhysics = ((dupe.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0);
- dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
-
- return dupe;
- }
-
- #endregion
-
- #region Update Scheduling
-
- ///
- ///
- ///
- private void ClearUpdateSchedule()
- {
- m_updateFlag = 0;
- }
-
- ///
- ///
- ///
- public void ScheduleFullUpdate()
- {
- if (m_parentGroup != null)
- {
- m_parentGroup.HasChanged = true;
- }
- TimeStampFull = (uint) Util.UnixTimeSinceEpoch();
- m_updateFlag = 2;
- }
-
- public void AddFlag(LLObject.ObjectFlags flag)
- {
- LLObject.ObjectFlags prevflag = m_flags;
- //uint objflags = m_flags;
- if ((ObjectFlags & (uint) flag) == 0)
- {
- //Console.WriteLine("Adding flag: " + ((LLObject.ObjectFlags) flag).ToString());
- m_flags |= flag;
- }
- //uint currflag = (uint)m_flags;
- //System.Console.WriteLine("Aprev: " + prevflag.ToString() + " curr: " + m_flags.ToString());
- //ScheduleFullUpdate();
- }
-
- public void RemFlag(LLObject.ObjectFlags flag)
- {
- LLObject.ObjectFlags prevflag = m_flags;
- if ((ObjectFlags & (uint) flag) != 0)
- {
- //Console.WriteLine("Removing flag: " + ((LLObject.ObjectFlags)flag).ToString());
- m_flags &= ~flag;
- }
- //System.Console.WriteLine("prev: " + prevflag.ToString() + " curr: " + m_flags.ToString());
- //ScheduleFullUpdate();
- }
-
- ///
- ///
- ///
- public void ScheduleTerseUpdate()
- {
- if (m_updateFlag < 1)
- {
- if (m_parentGroup != null)
- {
- m_parentGroup.HasChanged = true;
- }
- TimeStampTerse = (uint) Util.UnixTimeSinceEpoch();
- m_updateFlag = 1;
- }
- }
-
- ///
- ///
- ///
- public void SendScheduledUpdates()
- {
- if (m_updateFlag == 1) //some change has been made so update the clients
- {
- AddTerseUpdateToAllAvatars();
- ClearUpdateSchedule();
-
- // This causes the Scene to 'poll' physical objects every couple of frames
- // bad, so it's been replaced by an event driven method.
- //if ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0)
- //{
- // Only send the constant terse updates on physical objects!
- //ScheduleTerseUpdate();
- //}
- }
- else
- {
- if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
- {
- AddFullUpdateToAllAvatars();
- ClearUpdateSchedule();
- }
- }
- }
-
- #endregion
-
- #region Shape
-
- ///
- ///
- ///
- ///
- public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock)
- {
- m_shape.PathBegin = shapeBlock.PathBegin;
- m_shape.PathEnd = shapeBlock.PathEnd;
- m_shape.PathScaleX = shapeBlock.PathScaleX;
- m_shape.PathScaleY = shapeBlock.PathScaleY;
- m_shape.PathShearX = shapeBlock.PathShearX;
- m_shape.PathShearY = shapeBlock.PathShearY;
- m_shape.PathSkew = shapeBlock.PathSkew;
- m_shape.ProfileBegin = shapeBlock.ProfileBegin;
- m_shape.ProfileEnd = shapeBlock.ProfileEnd;
- m_shape.PathCurve = shapeBlock.PathCurve;
- m_shape.ProfileCurve = shapeBlock.ProfileCurve;
- m_shape.ProfileHollow = shapeBlock.ProfileHollow;
- m_shape.PathRadiusOffset = shapeBlock.PathRadiusOffset;
- m_shape.PathRevolutions = shapeBlock.PathRevolutions;
- m_shape.PathTaperX = shapeBlock.PathTaperX;
- m_shape.PathTaperY = shapeBlock.PathTaperY;
- m_shape.PathTwist = shapeBlock.PathTwist;
- m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
- ScheduleFullUpdate();
- }
-
- #endregion
-
- #region ExtraParams
-
- public void UpdatePrimFlags(ushort type, bool inUse, byte[] data)
- {
- bool usePhysics = false;
- bool IsTemporary = false;
- bool IsPhantom = false;
- bool castsShadows = false;
- bool wasUsingPhysics = ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0);
- //bool IsLocked = false;
- int i = 0;
- //rex
- LLUUID AgentID = LLUUID.Zero, SessionID = LLUUID.Zero;
- uint ObjectLocalID;
-
- try
- {
- //rex
- i += 10;
- AgentID = new LLUUID(data, i); i += 16;
- SessionID = new LLUUID(data, i); i += 16;
- ObjectLocalID = (uint)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24));
- //IsLocked = (data[i++] != 0) ? true : false;
- usePhysics = ((data[i++] != 0) && m_parentGroup.Scene.m_physicalPrim) ? true : false;
- //System.Console.WriteLine("U" + packet.ToBytes().Length.ToString());
- IsTemporary = (data[i++] != 0) ? true : false;
- IsPhantom = (data[i++] != 0) ? true : false;
- castsShadows = (data[i++] != 0) ? true : false;
- }
- catch (Exception)
- {
- Console.WriteLine("Ignoring invalid Packet:");
- //Silently ignore it - TODO: FIXME Quick
- }
-
- #region rex added flags
- if (AgentID == this.OwnerID)
- {
- AddFlag(LLObject.ObjectFlags.ObjectYouOwner);
- }
- else
- {
- RemFlag(LLObject.ObjectFlags.ObjectYouOwner);
- }
- #endregion
-
- if (usePhysics)
- {
- AddFlag(LLObject.ObjectFlags.Physics);
- if (!wasUsingPhysics)
- {
- DoPhysicsPropertyUpdate(usePhysics, false);
- }
- }
- else
- {
- RemFlag(LLObject.ObjectFlags.Physics);
- if (wasUsingPhysics)
- {
- DoPhysicsPropertyUpdate(usePhysics, false);
- }
- }
-
-
- if (IsPhantom)
- {
- AddFlag(LLObject.ObjectFlags.Phantom);
- if (PhysActor != null)
- {
- m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
- /// that's not wholesome. Had to make Scene public
- PhysActor = null;
- }
- }
- else
- {
- RemFlag(LLObject.ObjectFlags.Phantom);
- if (PhysActor == null)
- {
- PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
- Name,
- Shape,
- new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
- AbsolutePosition.Z),
- new PhysicsVector(Scale.X, Scale.Y, Scale.Z),
- new Quaternion(RotationOffset.W, RotationOffset.X,
- RotationOffset.Y, RotationOffset.Z), usePhysics, LocalID);
- DoPhysicsPropertyUpdate(usePhysics, true);
- }
- else
- {
- PhysActor.IsPhysical = usePhysics;
- DoPhysicsPropertyUpdate(usePhysics, false);
- }
- }
-
- if (IsTemporary)
- {
- AddFlag(LLObject.ObjectFlags.TemporaryOnRez);
- }
- else
- {
- RemFlag(LLObject.ObjectFlags.TemporaryOnRez);
- }
- // System.Console.WriteLine("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
- ScheduleFullUpdate();
- }
-
- public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
- {
- if (PhysActor != null)
- {
- if (UsePhysics != PhysActor.IsPhysical || isNew)
- {
- if (PhysActor.IsPhysical)
- {
- if (!isNew)
- ParentGroup.Scene.RemovePhysicalPrim(1);
-
- PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
- PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
- }
-
- PhysActor.IsPhysical = UsePhysics;
- // If we're not what we're supposed to be in the physics scene, recreate ourselves.
- //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
- /// that's not wholesome. Had to make Scene public
- //PhysActor = null;
-
-
- if ((ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) == 0)
- {
- //PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
- //Name,
- //Shape,
- //new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
- //AbsolutePosition.Z),
- //new PhysicsVector(Scale.X, Scale.Y, Scale.Z),
- //new Quaternion(RotationOffset.W, RotationOffset.X,
- //RotationOffset.Y, RotationOffset.Z), UsePhysics);
- if (UsePhysics)
- {
- ParentGroup.Scene.AddPhysicalPrim(1);
-
- PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
- PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
- }
- }
- }
- m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
- }
- }
-
- public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
- {
- // rex, function fixed for handling multiple parameter blocks and disabling them
-
- //m_shape.ExtraParams = new byte[data.Length + 7];
- //int i = 0;
- //uint length = (uint) data.Length;
- //m_shape.ExtraParams[i++] = 1;
- //m_shape.ExtraParams[i++] = (byte) (type%256);
- //m_shape.ExtraParams[i++] = (byte) ((type >> 8)%256);
-
- //m_shape.ExtraParams[i++] = (byte) (length%256);
- //m_shape.ExtraParams[i++] = (byte) ((length >> 8)%256);
- //m_shape.ExtraParams[i++] = (byte) ((length >> 16)%256);
- //m_shape.ExtraParams[i++] = (byte) ((length >> 24)%256);
- //Array.Copy(data, 0, m_shape.ExtraParams, i, data.Length);
-
- // Amount of param blocks in new & old extra params
- int numOld = 0;
- int numNew = 0;
-
- // If old param block exists, take its length & amount of param blocks in it
- int totalSizeOld = 0;
- int idxOld = 0;
- if (m_shape.ExtraParams != null)
- {
- numOld = m_shape.ExtraParams[idxOld++];
- totalSizeOld = m_shape.ExtraParams.Length;
- }
-
- // New extra params: maximum size = old extra params + size of new data + possible new param block header + num of blocks
- byte[] newExtraParams = new byte[totalSizeOld + data.Length + 6 + 1];
-
- int idxNew = 1; // Don't know the amount of new param blocks yet, fill it later
- bool isNewBlock = true;
-
- // Go through each of the old params, and see if this new update disables or changes it
- for (int i = 0; i < numOld; i++)
- {
- int typeOld = m_shape.ExtraParams[idxOld++] | (m_shape.ExtraParams[idxOld++] << 8);
- int lengthOld = m_shape.ExtraParams[idxOld++] | (m_shape.ExtraParams[idxOld++] << 8) |
- (m_shape.ExtraParams[idxOld++] << 16) | (m_shape.ExtraParams[idxOld++] << 24);
-
- // Not changed, copy verbatim
- if (typeOld != type)
- {
- newExtraParams[idxNew++] = (byte)(typeOld % 256);
- newExtraParams[idxNew++] = (byte)((typeOld >> 8) % 256);
- newExtraParams[idxNew++] = (byte)(lengthOld % 256);
- newExtraParams[idxNew++] = (byte)((lengthOld >> 8) % 256);
- newExtraParams[idxNew++] = (byte)((lengthOld >> 16) % 256);
- newExtraParams[idxNew++] = (byte)((lengthOld >> 24) % 256);
- Array.Copy(m_shape.ExtraParams, idxOld, newExtraParams, idxNew, lengthOld);
-
- idxNew += lengthOld;
- numNew++;
- }
- else
- {
- isNewBlock = false;
-
- // Old parameter updated, check if still in use, or if should remove
- if (inUse)
- {
- newExtraParams[idxNew++] = (byte)(type % 256);
- newExtraParams[idxNew++] = (byte)((type >> 8) % 256);
- newExtraParams[idxNew++] = (byte)(data.Length % 256);
- newExtraParams[idxNew++] = (byte)((data.Length >> 8) % 256);
- newExtraParams[idxNew++] = (byte)((data.Length >> 16) % 256);
- newExtraParams[idxNew++] = (byte)((data.Length >> 24) % 256);
- Array.Copy(data, 0, newExtraParams, idxNew, data.Length);
-
- idxNew += data.Length;
- numNew++;
- }
- }
- idxOld += lengthOld;
- }
- // If type was not listed, create new block
- if ((isNewBlock) && (inUse))
- {
- newExtraParams[idxNew++] = (byte)(type % 256);
- newExtraParams[idxNew++] = (byte)((type >> 8) % 256);
- newExtraParams[idxNew++] = (byte)(data.Length % 256);
- newExtraParams[idxNew++] = (byte)((data.Length >> 8) % 256);
- newExtraParams[idxNew++] = (byte)((data.Length >> 16) % 256);
- newExtraParams[idxNew++] = (byte)((data.Length >> 24) % 256);
- Array.Copy(data, 0, newExtraParams, idxNew, data.Length);
-
- idxNew += data.Length;
- numNew++;
- }
-
- // Now we know final size and number of param blocks
- newExtraParams[0] = (byte)numNew;
- m_shape.ExtraParams = new byte[idxNew];
- Array.Copy(newExtraParams, m_shape.ExtraParams, idxNew);
-
- string OldPythonClass = m_RexClassName;
- LLUUID OldColMesh = m_RexCollisionMeshUUID;
- bool OldMeshScaling = ((m_RexFlags & REXFLAGS_SCALEMESH) != 0);
-
- GetRexParameters();
-
- if (m_RexClassName != OldPythonClass)
- m_parentGroup.Scene.EventManager.TriggerOnChangePythonClass(LocalID);
-
- if (GlobalSettings.Instance.m_3d_collision_models)
- {
- if (m_RexCollisionMeshUUID != OldColMesh && PhysActor != null)
- {
- if (m_RexCollisionMeshUUID != LLUUID.Zero)
- RexUpdateCollisionMesh();
- else
- PhysActor.SetCollisionMesh(null, "", false);
- }
-
- bool NewMeshScaling = ((m_RexFlags & REXFLAGS_SCALEMESH) != 0);
- if (NewMeshScaling != OldMeshScaling && PhysActor != null)
- {
- PhysActor.SetBoundsScaling(NewMeshScaling);
- m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
- }
- }
- // rexend
-
- ScheduleFullUpdate();
- }
-
- // rex, new function, compiles / sends rex parameters after serverside modification
- public void UpdateRexParameters()
- {
- // Compile reX member variables into an extraparam-block
- int size = m_RexClassName.Length + 1 // Name + endzero
- + 1 + 1 + 4 + 4 // Flags, collisiontype, drawdistance, lod
- + 16 + 16 // Mesh UUID & collisionmesh UUID
- + 2 + m_RexMaterialUUID.Count * 16 // Material count and UUID's
- + 1 // Fixed material
- + 16; // Particle script UUID
-
- byte[] buffer = new byte[size];
- int idx = 0;
-
- for (int i = 0; i < m_RexClassName.Length; i++)
- {
- buffer[idx++] = (byte)m_RexClassName[i];
- }
- buffer[idx++] = 0;
-
- buffer[idx++] = m_RexFlags;
-
- buffer[idx++] = m_RexCollisionType;
-
- System.BitConverter.GetBytes(m_RexDrawDistance).CopyTo(buffer, idx);
- idx += 4;
-
- System.BitConverter.GetBytes(m_RexLOD).CopyTo(buffer, idx);
- idx += 4;
-
- m_RexMeshUUID.GetBytes().CopyTo(buffer, idx);
- idx += 16;
-
- m_RexCollisionMeshUUID.GetBytes().CopyTo(buffer, idx);
- idx += 16;
-
- System.BitConverter.GetBytes((short)m_RexMaterialUUID.Count).CopyTo(buffer, idx);
- idx += 2;
- for (int i = 0; i < m_RexMaterialUUID.Count; i++)
- {
- m_RexMaterialUUID[i].GetBytes().CopyTo(buffer, idx);
- idx += 16;
- }
-
- buffer[idx++] = m_RexFixedMaterial;
-
- m_RexParticleScriptUUID.GetBytes().CopyTo(buffer, idx);
- idx += 16;
-
- UpdateExtraParam(PARAMS_REX, true, buffer);
- }
-
- // rex, new function, extract reX parameters from the parameter block
- public void GetRexParameters()
- {
- if (m_shape.ExtraParams == null) return;
-
- int idx = 0;
- int numParams = m_shape.ExtraParams[idx++];
-
- for (int i = 0; i < numParams; i++)
- {
- // Is this the reX parameter block?
- int type = m_shape.ExtraParams[idx++] | (m_shape.ExtraParams[idx++] << 8);
- int length = m_shape.ExtraParams[idx++] | (m_shape.ExtraParams[idx++] << 8) |
- (m_shape.ExtraParams[idx++] << 16) | (m_shape.ExtraParams[idx++] << 24);
- int start = idx;
-
- if (type == PARAMS_REX)
- {
- // Class name
- StringBuilder buffer = new StringBuilder();
- while ((idx < (length + start)) && (m_shape.ExtraParams[idx] != 0))
- {
- char c = (char)m_shape.ExtraParams[idx++];
- buffer.Append(c);
- }
- m_RexClassName = buffer.ToString();
- idx++;
-
- // Rex flags
- if (idx < (length + start))
- {
- m_RexFlags = m_shape.ExtraParams[idx++];
- }
-
- // Collision type
- if (idx < (length + start))
- {
- m_RexCollisionType = m_shape.ExtraParams[idx++];
- }
-
- // Draw distance
- if (idx < (length + start - 3))
- {
- m_RexDrawDistance = System.BitConverter.ToSingle(m_shape.ExtraParams, idx);
- idx += 4;
- }
-
- // Mesh LOD
- if (idx < (length + start - 3))
- {
- m_RexLOD = System.BitConverter.ToSingle(m_shape.ExtraParams, idx);
- idx += 4;
- }
-
- // Mesh UUID
- if (idx < (length + start - 15))
- {
- m_RexMeshUUID = new LLUUID(m_shape.ExtraParams, idx);
- idx += 16;
- }
-
- // Collision mesh UUID
- if (idx < (length + start - 15))
- {
- m_RexCollisionMeshUUID = new LLUUID(m_shape.ExtraParams, idx);
- idx += 16;
- }
-
- // Number of materials
- if (idx < (length + start - 1))
- {
- short rexMaterials = System.BitConverter.ToInt16(m_shape.ExtraParams, idx);
- idx += 2;
- m_RexMaterialUUID = new List();
-
- for (short j = 0; j < rexMaterials; j++)
- {
- if (idx < (length + start - 15))
- {
- m_RexMaterialUUID.Add(new LLUUID(m_shape.ExtraParams, idx));
- idx += 16;
- }
- else break;
- }
- }
- // Fixed material
- if (idx < (length + start))
- {
- m_RexFixedMaterial = m_shape.ExtraParams[idx++];
- }
- // Particle script UUID
- if (idx < (length + start - 15))
- {
- m_RexParticleScriptUUID = new LLUUID(m_shape.ExtraParams, idx);
- idx += 16;
- }
-
- //System.Console.WriteLine("Rex parameters of an object updated");
- //System.Console.WriteLine("Rex class name: " + m_RexClassName);
- //System.Console.WriteLine("Rex flags: " + (short)m_RexFlags);
- //System.Console.WriteLine("Rex collision type: " + (short)m_RexCollisionType);
- //System.Console.WriteLine("Rex draw distance: " + m_RexDrawDistance);
- //System.Console.WriteLine("Rex LOD: " + m_RexLOD);
- //System.Console.WriteLine("Rex mesh UUID: " + m_RexMeshUUID);
- //System.Console.WriteLine("Rex collisionmesh UUID: " + m_RexCollisionMeshUUID);
- //System.Console.WriteLine("Rex material count: " + m_RexMaterialUUID.Count);
- //for (int j = 0; j < m_RexMaterialUUID.Count; j++)
- //{
- // System.Console.WriteLine("Rex material UUID " + j + ": " + m_RexMaterialUUID[j]);
- //}
- break;
- }
- else idx += length;
- }
- }
-
- #endregion
-
- #region Physics
-
- public float GetMass()
- {
- if (PhysActor != null)
- {
- return PhysActor.Mass;
- }
- else
- {
- return 0;
- }
- }
-
- // rex, added
- public void SetMass(float vValue)
- {
- if (PhysActor != null)
- {
- // PhysActor.Mass = vValue;
- }
- }
-
- // rex, added
- public bool GetUsePrimVolumeCollision()
- {
- if (PhysActor != null)
- return (PhysActor.PhysicsActorType == 4);
- else
- return false;
- }
-
- // rex, added
- public void SetUsePrimVolumeCollision(bool vUseVolumeCollision)
- {
- if (PhysActor != null)
- {
- if (vUseVolumeCollision)
- {
- if (PhysActor.PhysicsActorType != 4)
- PhysActor.OnCollisionUpdate += PhysicsCollisionUpdate;
- PhysActor.PhysicsActorType = 4;
- }
- else
- {
- if (PhysActor.PhysicsActorType == 4)
- PhysActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
-
- PhysActor.PhysicsActorType = 2;
- }
- }
- }
-
- // rex, added
- private void PhysicsCollisionUpdate(EventArgs e)
- {
- if (PhysActor != null && PhysActor.PhysicsActorType == 4)
- m_parentGroup.Scene.EventManager.TriggerOnPrimVolumeCollision(LocalID, (e as CollisionEventUpdate).m_LocalID);
- }
-
-
-
- // rex, added
- public void RexUpdateCollisionMesh()
- {
- if (!GlobalSettings.Instance.m_3d_collision_models)
- return;
-
- if (m_RexCollisionMeshUUID != LLUUID.Zero && PhysActor != null)
- {
- bool ScaleMesh = ((m_RexFlags & REXFLAGS_SCALEMESH) != 0);
- AssetBase tempmodel = m_parentGroup.Scene.AssetCache.FetchAsset(m_RexCollisionMeshUUID);
- if (tempmodel != null)
- PhysActor.SetCollisionMesh(tempmodel.Data, tempmodel.Name, ScaleMesh);
- }
- }
-
-
-
- public LLVector3 GetGeometricCenter()
- {
- if (PhysActor != null)
- {
- return new LLVector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z);
- }
- else
- {
- return new LLVector3(0, 0, 0);
- }
- }
-
- #endregion
-
- #region Texture
-
- ///
- ///
- ///
- ///
- public void UpdateTextureEntry(byte[] textureEntry)
- {
- m_shape.TextureEntry = textureEntry;
- ScheduleFullUpdate();
- }
-
- // Added to handle bug in libsecondlife's TextureEntry.ToBytes()
- // not handling RGBA properly. Cycles through, and "fixes" the color
- // info
- public void UpdateTexture(LLObject.TextureEntry tex)
- {
- //LLColor tmpcolor;
- //for (uint i = 0; i < 32; i++)
- //{
- // if (tex.FaceTextures[i] != null)
- // {
- // tmpcolor = tex.GetFace((uint) i).RGBA;
- // tmpcolor.A = tmpcolor.A*255;
- // tmpcolor.R = tmpcolor.R*255;
- // tmpcolor.G = tmpcolor.G*255;
- // tmpcolor.B = tmpcolor.B*255;
- // tex.FaceTextures[i].RGBA = tmpcolor;
- // }
- //}
- //tmpcolor = tex.DefaultTexture.RGBA;
- //tmpcolor.A = tmpcolor.A*255;
- //tmpcolor.R = tmpcolor.R*255;
- //tmpcolor.G = tmpcolor.G*255;
- //tmpcolor.B = tmpcolor.B*255;
- //tex.DefaultTexture.RGBA = tmpcolor;
- UpdateTextureEntry(tex.ToBytes());
- }
-
- #endregion
-
- #region ParticleSystem
-
- public void AddNewParticleSystem(Primitive.ParticleSystem pSystem)
- {
- m_particleSystem = pSystem.GetBytes();
- }
-
- #endregion
-
- #region Position
-
- public void AttachToAvatar(LLUUID agentId, ScenePresence presence, byte attachPt, LLQuaternion rotation, RegionInfo regionInfo)
- {
- m_attachAgentId = agentId;
- m_attachPresence = presence;
- m_attachPt = attachPt;
- m_attachRot = rotation;
- m_attachRegInfo = regionInfo;
-
- RotationOffset = new LLQuaternion(0, 0, 0, 1);
-
- ScheduleFullUpdate();
- }
-
- public void Detach()
- {
- m_attachPresence = null;
- ScheduleFullUpdate();
- }
-
- ///
- ///
- ///
- ///
- public void UpdateOffSet(LLVector3 pos)
- {
- LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z);
- OffsetPosition = newPos;
- ScheduleTerseUpdate();
- }
-
- public void UpdateGroupPosition(LLVector3 pos)
- {
- LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z);
- GroupPosition = newPos;
- ScheduleTerseUpdate();
- }
-
- #endregion
-
- #region rotation
-
- public void UpdateRotation(LLQuaternion rot)
- {
- RotationOffset = new LLQuaternion(rot.X, rot.Y, rot.Z, rot.W);
- ScheduleTerseUpdate();
- }
-
- #endregion
-
- #region Resizing/Scale
-
- ///
- ///
- ///
- ///
- public void Resize(LLVector3 scale)
- {
- m_shape.Scale = scale;
- ScheduleFullUpdate();
- }
-
- #endregion
-
- public void UpdatePermissions(LLUUID AgentID, byte field, uint localID, uint mask, byte addRemTF)
- {
- // Are we the owner?
- if (AgentID == OwnerID)
- {
- MainLog.Instance.Verbose("PERMISSIONS",
- "field: " + field.ToString() + ", mask: " + mask.ToString() + " addRemTF: " +
- addRemTF.ToString());
-
- //Field 8 = EveryoneMask
- if (field == (byte) 8)
- {
- MainLog.Instance.Verbose("PERMISSIONS", "Left over: " + (OwnerMask - EveryoneMask));
- if (addRemTF == (byte) 0)
- {
- //EveryoneMask = (uint)0;
- EveryoneMask &= ~mask;
- //EveryoneMask &= ~(uint)57344;
- }
- else
- {
- //EveryoneMask = (uint)0;
- EveryoneMask |= mask;
- //EveryoneMask |= (uint)57344;
- }
- //ScheduleFullUpdate();
- SendFullUpdateToAllClients();
- }
- //Field 16 = NextownerMask
- if (field == (byte) 16)
- {
- if (addRemTF == (byte) 0)
- {
- NextOwnerMask &= ~mask;
- }
- else
- {
- NextOwnerMask |= mask;
- }
- SendFullUpdateToAllClients();
- }
- }
- }
-
- #region Client Update Methods
-
- public void AddFullUpdateToAllAvatars()
- {
- List avatars = m_parentGroup.GetScenePresences();
- for (int i = 0; i < avatars.Count; i++)
- {
- avatars[i].QueuePartForUpdate(this);
- }
- }
-
- public void AddFullUpdateToAvatar(ScenePresence presence)
- {
- presence.QueuePartForUpdate(this);
- }
-
- ///
- ///
- ///
- public void SendFullUpdateToAllClients()
- {
- List avatars = m_parentGroup.GetScenePresences();
- for (int i = 0; i < avatars.Count; i++)
- {
- // Ugly reference :(
- m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this,
- avatars[i].GenerateClientFlags(UUID));
- }
- }
-
- ///
- ///
- ///
- ///
- public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
- {
- m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags);
- }
-
- ///
- ///
- ///
- ///
- public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientflags)
- {
- LLVector3 lPos;
- lPos = OffsetPosition;
- SendFullUpdateToClient(remoteClient, lPos, clientflags);
- }
-
- public void SendAttachedUpdateToClient(IClientAPI remoteClient, LLVector3 lPos, uint clientFlags)
- {
- MainLog.Instance.Verbose("OBJECTPART", "Sending as attached object to " + remoteClient.FirstName + " " + remoteClient.LastName);
- ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
- objupdate.RegionData.RegionHandle = m_attachRegInfo.RegionHandle;
- objupdate.RegionData.TimeDilation = 64096;
- objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[2];
-
- // avatar stuff - horrible group copypaste
- objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock();
- objupdate.ObjectData[0].PSBlock = new byte[0];
- objupdate.ObjectData[0].ExtraParams = new byte[1];
- objupdate.ObjectData[0].MediaURL = new byte[0];
- objupdate.ObjectData[0].NameValue = new byte[0];
- objupdate.ObjectData[0].Text = new byte[0];
- objupdate.ObjectData[0].TextColor = new byte[4];
- objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0);
- objupdate.ObjectData[0].JointPivot = new LLVector3(0, 0, 0);
- objupdate.ObjectData[0].Material = 4;
- objupdate.ObjectData[0].TextureAnim = new byte[0];
- objupdate.ObjectData[0].Sound = LLUUID.Zero;
-
- objupdate.ObjectData[0].State = 0;
- objupdate.ObjectData[0].Data = new byte[0];
-
- objupdate.ObjectData[0].ObjectData = new byte[76];
- objupdate.ObjectData[0].ObjectData[15] = 128;
- objupdate.ObjectData[0].ObjectData[16] = 63;
- objupdate.ObjectData[0].ObjectData[56] = 128;
- objupdate.ObjectData[0].ObjectData[61] = 102;
- objupdate.ObjectData[0].ObjectData[62] = 40;
- objupdate.ObjectData[0].ObjectData[63] = 61;
- objupdate.ObjectData[0].ObjectData[64] = 189;
-
-
- objupdate.ObjectData[0].UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
- objupdate.ObjectData[0].PathCurve = 16;
- objupdate.ObjectData[0].ProfileCurve = 1;
- objupdate.ObjectData[0].PathScaleX = 100;
- objupdate.ObjectData[0].PathScaleY = 100;
- objupdate.ObjectData[0].ParentID = 0;
- objupdate.ObjectData[0].OwnerID = LLUUID.Zero;
- objupdate.ObjectData[0].Scale = new LLVector3(1, 1, 1);
- objupdate.ObjectData[0].PCode = 47;
- objupdate.ObjectData[0].TextureEntry = ScenePresence.DefaultTexture;
-
- objupdate.ObjectData[0].ID = m_attachPresence.LocalId;
- objupdate.ObjectData[0].FullID = m_attachAgentId;
- objupdate.ObjectData[0].ParentID = 0;
- objupdate.ObjectData[0].NameValue =
- Helpers.StringToField("FirstName STRING RW SV " + m_attachPresence.Firstname + "\nLastName STRING RW SV " + m_attachPresence.Lastname);
- LLVector3 pos2 = m_attachPresence.AbsolutePosition;
- // new LLVector3((float) Pos.X, (float) Pos.Y, (float) Pos.Z);
- byte[] pb = pos2.GetBytes();
- Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
-
-
- // primitive part
- objupdate.ObjectData[1] = new ObjectUpdatePacket.ObjectDataBlock();
- // SetDefaultPrimPacketValues
- objupdate.ObjectData[1].PSBlock = new byte[0];
- objupdate.ObjectData[1].ExtraParams = new byte[1];
- objupdate.ObjectData[1].MediaURL = new byte[0];
- objupdate.ObjectData[1].NameValue = new byte[0];
- objupdate.ObjectData[1].Text = new byte[0];
- objupdate.ObjectData[1].TextColor = new byte[4];
- objupdate.ObjectData[1].JointAxisOrAnchor = new LLVector3(0, 0, 0);
- objupdate.ObjectData[1].JointPivot = new LLVector3(0, 0, 0);
- objupdate.ObjectData[1].Material = 3;
- objupdate.ObjectData[1].TextureAnim = new byte[0];
- objupdate.ObjectData[1].Sound = LLUUID.Zero;
- objupdate.ObjectData[1].State = 0;
- objupdate.ObjectData[1].Data = new byte[0];
-
- objupdate.ObjectData[1].ObjectData = new byte[60];
- objupdate.ObjectData[1].ObjectData[46] = 128;
- objupdate.ObjectData[1].ObjectData[47] = 63;
-
- // SetPrimPacketShapeData
- PrimitiveBaseShape primData = Shape;
-
- objupdate.ObjectData[1].TextureEntry = primData.TextureEntry;
- objupdate.ObjectData[1].PCode = primData.PCode;
- objupdate.ObjectData[1].State = (byte)(((byte)m_attachPt) << 4);
- objupdate.ObjectData[1].PathBegin = primData.PathBegin;
- objupdate.ObjectData[1].PathEnd = primData.PathEnd;
- objupdate.ObjectData[1].PathScaleX = primData.PathScaleX;
- objupdate.ObjectData[1].PathScaleY = primData.PathScaleY;
- objupdate.ObjectData[1].PathShearX = primData.PathShearX;
- objupdate.ObjectData[1].PathShearY = primData.PathShearY;
- objupdate.ObjectData[1].PathSkew = primData.PathSkew;
- objupdate.ObjectData[1].ProfileBegin = primData.ProfileBegin;
- objupdate.ObjectData[1].ProfileEnd = primData.ProfileEnd;
- objupdate.ObjectData[1].Scale = primData.Scale;
- objupdate.ObjectData[1].PathCurve = primData.PathCurve;
- objupdate.ObjectData[1].ProfileCurve = primData.ProfileCurve;
- objupdate.ObjectData[1].ProfileHollow = primData.ProfileHollow;
- objupdate.ObjectData[1].PathRadiusOffset = primData.PathRadiusOffset;
- objupdate.ObjectData[1].PathRevolutions = primData.PathRevolutions;
- objupdate.ObjectData[1].PathTaperX = primData.PathTaperX;
- objupdate.ObjectData[1].PathTaperY = primData.PathTaperY;
- objupdate.ObjectData[1].PathTwist = primData.PathTwist;
- objupdate.ObjectData[1].PathTwistBegin = primData.PathTwistBegin;
- objupdate.ObjectData[1].ExtraParams = primData.ExtraParams;
-
- objupdate.ObjectData[1].UpdateFlags = 276957500; // flags; // ??
- objupdate.ObjectData[1].ID = LocalID;
- objupdate.ObjectData[1].FullID = UUID;
- objupdate.ObjectData[1].OwnerID = OwnerID;
- objupdate.ObjectData[1].Text = Helpers.StringToField(Text);
- objupdate.ObjectData[1].TextColor[0] = 255;
- objupdate.ObjectData[1].TextColor[1] = 255;
- objupdate.ObjectData[1].TextColor[2] = 255;
- objupdate.ObjectData[1].TextColor[3] = 128;
- objupdate.ObjectData[1].ParentID = objupdate.ObjectData[0].ID;
- //objupdate.ObjectData[1].PSBlock = particleSystem;
- //objupdate.ObjectData[1].ClickAction = clickAction;
- objupdate.ObjectData[1].Radius = 20;
- objupdate.ObjectData[1].NameValue =
- Helpers.StringToField("AttachItemID STRING RW SV " + UUID);
- LLVector3 pos = new LLVector3((float)0.0, (float)0.0, (float)0.0);
-
- pb = pos.GetBytes();
- Array.Copy(pb, 0, objupdate.ObjectData[1].ObjectData, 0, pb.Length);
-
- byte[] brot = m_attachRot.GetBytes();
- Array.Copy(brot, 0, objupdate.ObjectData[1].ObjectData, 36, brot.Length);
-
- remoteClient.OutPacket(objupdate, ThrottleOutPacketType.Task);
- }
-
- ///
- ///
- ///
- ///
- ///
- public void SendFullUpdateToClient(IClientAPI remoteClient, LLVector3 lPos, uint clientFlags)
- {
- if (m_attachPresence != null)
- {
- SendAttachedUpdateToClient(remoteClient, lPos, clientFlags);
- return;
- }
-
- LLQuaternion lRot;
- lRot = RotationOffset;
- clientFlags &= ~(uint) LLObject.ObjectFlags.CreateSelected;
-
- if (remoteClient.AgentId == OwnerID)
- {
- if ((uint) (m_flags & LLObject.ObjectFlags.CreateSelected) != 0)
- {
- clientFlags |= (uint) LLObject.ObjectFlags.CreateSelected;
- m_flags &= ~LLObject.ObjectFlags.CreateSelected;
- }
- }
-
-
- byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A};
- remoteClient.SendPrimitiveToClient(m_regionHandle, 64096, LocalID, m_shape, lPos, clientFlags, m_uuid,
- OwnerID,
- m_text, color, ParentID, m_particleSystem, lRot, m_clickAction);
- }
-
- /// Terse updates
- public void AddTerseUpdateToAllAvatars()
- {
- List avatars = m_parentGroup.GetScenePresences();
- for (int i = 0; i < avatars.Count; i++)
- {
- avatars[i].QueuePartForUpdate(this);
- }
- }
-
- public void AddTerseUpdateToAvatar(ScenePresence presence)
- {
- presence.QueuePartForUpdate(this);
- }
-
- ///
- ///
- ///
- public void SendTerseUpdateToAllClients()
- {
- List avatars = m_parentGroup.GetScenePresences();
- for (int i = 0; i < avatars.Count; i++)
- {
- m_parentGroup.SendPartTerseUpdate(avatars[i].ControllingClient, this);
- }
- }
-
- ///
- ///
- ///
- ///
- public void SendTerseUpdate(IClientAPI remoteClient)
- {
- m_parentGroup.SendPartTerseUpdate(remoteClient, this);
- }
-
- public void SendTerseUpdateToClient(IClientAPI remoteClient)
- {
- LLVector3 lPos;
- lPos = OffsetPosition;
- LLQuaternion mRot = RotationOffset;
- if ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0)
- {
- remoteClient.SendPrimTerseUpdate(m_regionHandle, 64096, LocalID, lPos, mRot);
- }
- else
- {
- remoteClient.SendPrimTerseUpdate(m_regionHandle, 64096, LocalID, lPos, mRot, Velocity,
- RotationalVelocity);
- }
- }
-
- public void SendTerseUpdateToClient(IClientAPI remoteClient, LLVector3 lPos)
- {
- LLQuaternion mRot = RotationOffset;
- if ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0)
- {
- remoteClient.SendPrimTerseUpdate(m_regionHandle, 64096, LocalID, lPos, mRot);
- }
- else
- {
- remoteClient.SendPrimTerseUpdate(m_regionHandle, 64096, LocalID, lPos, mRot, Velocity,
- RotationalVelocity);
- //System.Console.WriteLine("RVel:" + RotationalVelocity);
- }
- }
-
- #endregion
-
- public virtual void UpdateMovement()
- {
- }
-
- #region Events
-
- public void PhysicsRequestingTerseUpdate()
- {
- ScheduleTerseUpdate();
-
- //SendTerseUpdateToAllClients();
- }
-
- #endregion
-
- public void PhysicsOutOfBounds(PhysicsVector pos)
- {
- MainLog.Instance.Verbose("PHYSICS", "Physical Object went out of bounds.");
- RemFlag(LLObject.ObjectFlags.Physics);
- DoPhysicsPropertyUpdate(false, true);
- m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
- }
-
- public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient)
- {
- }
-
- public void SetText(string text, Vector3 color, double alpha)
- {
- Color = Color.FromArgb(0xff - (int) (alpha*0xff),
- (int) (color.x*0xff),
- (int) (color.y*0xff),
- (int) (color.z*0xff));
- Text = text;
- }
- }
-}
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the OpenSim Project nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+using System;
+using System.Text; // rex, StringBuilder needed
+using System.Collections.Generic;
+using System.Drawing;
+using System.Xml;
+using System.Xml.Serialization;
+using Axiom.Math;
+using libsecondlife;
+using libsecondlife.Packets;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+using OpenSim.Region.Environment.Interfaces;
+using OpenSim.Region.Environment.Scenes.Scripting;
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Environment.Scenes
+{
+ // I don't really know where to put this except here.
+ // Can't access the OpenSim.Region.ScriptEngine.Common.LSL_BaseClass.Changed constants
+ [Flags]
+ public enum ExtraParamType
+ {
+ Something1 = 1,
+ Something2 = 2,
+ Something3 = 4,
+ Something4 = 8,
+ Flexible = 16,
+ Light = 32,
+ Sculpt = 48,
+ Something5 = 64,
+ Something6 = 128
+ }
+ [Flags]
+ public enum Changed : uint
+ {
+ INVENTORY = 1,
+ COLOR = 2,
+ SHAPE = 4,
+ SCALE = 8,
+ TEXTURE = 16,
+ LINK = 32,
+ ALLOWED_DROP = 64,
+ OWNER = 128
+ }
+ [Flags]
+ public enum TextureAnimFlags : byte
+ {
+ NONE = 0x00,
+ ANIM_ON = 0x01,
+ LOOP = 0x02,
+ REVERSE = 0x04,
+ PING_PONG = 0x08,
+ SMOOTH = 0x10,
+ ROTATE = 0x20,
+ SCALE = 0x40
+ }
+
+ public partial class SceneObjectPart : IScriptHost
+ {
+
+ [XmlIgnore] public PhysicsActor PhysActor = null;
+
+ public LLUUID LastOwnerID;
+ public LLUUID OwnerID;
+ public LLUUID GroupID;
+ public int OwnershipCost;
+ public byte ObjectSaleType;
+ public int SalePrice;
+ public uint Category;
+
+
+ public Int32 CreationDate;
+ public uint ParentID = 0;
+
+ private PhysicsVector m_lastRotationalVelocity = PhysicsVector.Zero;
+ private Vector3 m_sitTargetPosition = new Vector3(0, 0, 0);
+ private Quaternion m_sitTargetOrientation = new Quaternion(0, 0, 0, 1);
+ private LLUUID m_sitTargetAvatar = LLUUID.Zero;
+
+ #region Permissions
+
+ public uint BaseMask = (uint)PermissionMask.All;
+ public uint OwnerMask = (uint)PermissionMask.All;
+ public uint GroupMask = (uint)PermissionMask.None;
+ public uint EveryoneMask = (uint)PermissionMask.None;
+ public uint NextOwnerMask = (uint)PermissionMask.All;
+
+ public LLObject.ObjectFlags Flags = LLObject.ObjectFlags.None;
+
+ public uint ObjectFlags
+ {
+ get { return (uint)Flags; }
+ set { Flags = (LLObject.ObjectFlags)value; }
+ }
+
+ #endregion
+
+ protected byte[] m_particleSystem = new byte[0];
+
+ [XmlIgnore] public uint TimeStampFull = 0;
+ [XmlIgnore] public uint TimeStampTerse = 0;
+ [XmlIgnore] public uint TimeStampLastActivity = 0; // Will be used for AutoReturn
+
+ ///
+ /// Only used internally to schedule client updates
+ ///
+ private byte m_updateFlag;
+
+ // rex, extra parameters & their definitions
+
+ // reX extra block parameters in easily readable format
+ public string m_RexClassName = "";
+ public byte m_RexFlags = 0;
+ public byte m_RexCollisionType = 0;
+ public float m_RexDrawDistance = 0.0F;
+ public float m_RexLOD = 0.0F;
+ public LLUUID m_RexMeshUUID = LLUUID.Zero;
+ public LLUUID m_RexCollisionMeshUUID = LLUUID.Zero;
+ public List m_RexMaterialUUID = new List();
+ public byte m_RexFixedMaterial = 0;
+ public LLUUID m_RexParticleScriptUUID = LLUUID.Zero;
+
+ // reX extra parameter block defines
+ public const int PARAMS_REX = 0x0100;
+
+ // Bit values for flags
+ public const int REXFLAGS_ISMESH = 0x01;
+ public const int REXFLAGS_ISVISIBLE = 0x02;
+ public const int REXFLAGS_CASTSHADOWS = 0x04;
+ public const int REXFLAGS_SHOWTEXT = 0x08;
+ public const int REXFLAGS_SCALEMESH = 0x10;
+ public const int REXFLAGS_SOLIDALPHA = 0x20;
+ public const int REXFLAGS_ISBILLBOARD = 0x40;
+ public const int REXFLAGS_USEPARTICLESCRIPT = 0x80;
+
+ // Collision type enumeration (still unused :))
+ public const int REXCOLLISION_VOLUME = 0x01;
+ public const int REXCOLLISION_TRIMESH = 0x02;
+
+ // Attachment parameters
+ private ScenePresence m_attachPresence = null;
+ private byte m_attachPt;
+ private LLQuaternion m_attachRot;
+ private RegionInfo m_attachRegInfo;
+ private LLUUID m_attachAgentId;
+
+ // rexend
+
+ #region Properties
+
+ public LLUUID CreatorID;
+
+ public LLUUID ObjectCreator
+ {
+ get { return CreatorID; }
+ }
+
+ protected LLUUID m_uuid;
+
+ public LLUUID UUID
+ {
+ get { return m_uuid; }
+ set { m_uuid = value; }
+ }
+
+ protected uint m_localID;
+
+ public uint LocalID
+ {
+ get { return m_localID; }
+ set { m_localID = value; }
+ }
+
+ protected string m_name;
+
+ public virtual string Name
+ {
+ get { return m_name; }
+ set { m_name = value; }
+ }
+
+
+
+ protected LLObject.MaterialType m_material = 0;
+
+ public byte Material
+ {
+ get { return (byte) m_material; }
+ set { m_material = (LLObject.MaterialType) value; }
+ }
+
+ protected ulong m_regionHandle;
+
+ public ulong RegionHandle
+ {
+ get { return m_regionHandle; }
+ set { m_regionHandle = value; }
+ }
+
+ //unkown if this will be kept, added as a way of removing the group position from the group class
+ protected LLVector3 m_groupPosition;
+
+ ///
+ /// Method for a prim to get it's world position from the group.
+ /// Remember, the Group Position simply gives the position of the group itself
+ ///
+ /// A Linked Child Prim objects position in world
+ public LLVector3 GetWorldPosition()
+ {
+
+ Quaternion parentRot = new Quaternion(
+ ParentGroup.RootPart.RotationOffset.W,
+ ParentGroup.RootPart.RotationOffset.X,
+ ParentGroup.RootPart.RotationOffset.Y,
+ ParentGroup.RootPart.RotationOffset.Z);
+
+ Vector3 axPos
+ = new Vector3(
+ OffsetPosition.X,
+ OffsetPosition.Y,
+ OffsetPosition.Z);
+
+ axPos = parentRot * axPos;
+ LLVector3 translationOffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
+ return GroupPosition + translationOffsetPosition;
+
+ //return (new LLVector3(axiomPos.x, axiomPos.y, axiomPos.z) + AbsolutePosition);
+ }
+
+ ///
+ /// Gets the rotation of this prim offset by the group rotation
+ ///
+ ///
+ public LLQuaternion GetWorldRotation()
+ {
+
+ Quaternion newRot;
+
+ if (this.LinkNum == 0)
+ {
+ newRot = new Quaternion(RotationOffset.W,RotationOffset.X,RotationOffset.Y,RotationOffset.Z);
+
+ }
+ else
+ {
+ Quaternion parentRot = new Quaternion(
+ ParentGroup.RootPart.RotationOffset.W,
+ ParentGroup.RootPart.RotationOffset.X,
+ ParentGroup.RootPart.RotationOffset.Y,
+ ParentGroup.RootPart.RotationOffset.Z);
+
+ Quaternion oldRot
+ = new Quaternion(
+ RotationOffset.W,
+ RotationOffset.X,
+ RotationOffset.Y,
+ RotationOffset.Z);
+
+ newRot = parentRot * oldRot;
+ }
+ return new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
+
+ //return new LLQuaternion(axiomPartRotation.x, axiomPartRotation.y, axiomPartRotation.z, axiomPartRotation.w);
+
+ }
+
+ public LLVector3 GroupPosition
+ {
+ get
+ {
+ // If this is a linkset, we don't want the physics engine mucking up our group position here.
+ if (PhysActor != null && ParentID == 0)
+ {
+ m_groupPosition.X = PhysActor.Position.X;
+ m_groupPosition.Y = PhysActor.Position.Y;
+ m_groupPosition.Z = PhysActor.Position.Z;
+ }
+ return m_groupPosition;
+ }
+ set
+ {
+ m_groupPosition = value;
+
+ if (PhysActor != null)
+ {
+ try
+ {
+
+ // Root prim actually goes at Position
+ if (ParentID == 0)
+ {
+ PhysActor.Position = new PhysicsVector(value.X, value.Y, value.Z);
+
+ }
+ else
+ {
+
+ // To move the child prim in respect to the group position and rotation we have to calculate
+
+ LLVector3 resultingposition = GetWorldPosition();
+ PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z);
+ LLQuaternion resultingrot = GetWorldRotation();
+ PhysActor.Orientation = new Quaternion(resultingrot.W, resultingrot.X, resultingrot.Y, resultingrot.Z);
+ }
+
+ // Tell the physics engines that this prim changed.
+ m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ }
+
+ }
+ }
+
+ private byte[] m_TextureAnimation;
+
+ protected LLVector3 m_offsetPosition;
+
+ public LLVector3 OffsetPosition
+ {
+ get { return m_offsetPosition; }
+ set { m_offsetPosition = value;
+ try
+ {
+ // Hack to get the child prim to update world positions in the physics engine
+ ParentGroup.ResetChildPrimPhysicsPositions();
+
+ }
+ catch (System.NullReferenceException)
+ {
+ // Ignore, and skip over.
+ }
+ //m_log.Info("[PART]: OFFSET:" + m_offsetPosition.ToString());
+ }
+ }
+
+ public LLVector3 AbsolutePosition
+ {
+ get { return m_offsetPosition + m_groupPosition; }
+ }
+
+ protected LLQuaternion m_rotationOffset;
+
+ public LLQuaternion RotationOffset
+ {
+ get
+ {
+ // We don't want the physics engine mucking up the rotations in a linkset
+ if (PhysActor != null && ParentID == 0)
+ {
+ if (PhysActor.Orientation.x != 0 || PhysActor.Orientation.y != 0
+ || PhysActor.Orientation.z != 0 || PhysActor.Orientation.w != 0)
+ {
+ m_rotationOffset.X = PhysActor.Orientation.x;
+ m_rotationOffset.Y = PhysActor.Orientation.y;
+ m_rotationOffset.Z = PhysActor.Orientation.z;
+ m_rotationOffset.W = PhysActor.Orientation.w;
+ }
+ }
+ return m_rotationOffset;
+ }
+ set
+ {
+ m_rotationOffset = value;
+
+ if (PhysActor != null)
+ {
+ try
+ {
+ // Root prim gets value directly
+ if (ParentID == 0)
+ {
+ PhysActor.Orientation = new Quaternion(value.W, value.X, value.Y, value.Z);
+ //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString());
+ }
+ else
+ {
+ // Child prim we have to calculate it's world rotationwel
+ LLQuaternion resultingrotation = GetWorldRotation();
+ PhysActor.Orientation = new Quaternion(resultingrotation.W, resultingrotation.X, resultingrotation.Y, resultingrotation.Z);
+ //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString());
+ }
+ m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
+ //}
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+
+ }
+ }
+
+ protected LLVector3 m_velocity;
+ protected LLVector3 m_rotationalvelocity;
+
+ ///
+ public LLVector3 Velocity
+ {
+ get
+ {
+ //if (PhysActor.Velocity.x != 0 || PhysActor.Velocity.y != 0
+ //|| PhysActor.Velocity.z != 0)
+ //{
+ if (PhysActor != null)
+ {
+ if (PhysActor.IsPhysical)
+ {
+ m_velocity.X = PhysActor.Velocity.X;
+ m_velocity.Y = PhysActor.Velocity.Y;
+ m_velocity.Z = PhysActor.Velocity.Z;
+ }
+ }
+
+ return m_velocity;
+ }
+ set {
+
+ m_velocity = value;
+ if (PhysActor != null)
+ {
+ if (PhysActor.IsPhysical)
+ {
+ PhysActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z);
+ m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
+ }
+ }
+
+ }
+ }
+
+ public LLVector3 RotationalVelocity
+ {
+ get
+ {
+ //if (PhysActor.Velocity.x != 0 || PhysActor.Velocity.y != 0
+ //|| PhysActor.Velocity.z != 0)
+ //{
+ if (PhysActor != null)
+ {
+ if (PhysActor.IsPhysical)
+ {
+ m_rotationalvelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(),0);
+ }
+ }
+
+ return m_rotationalvelocity;
+ }
+ set { m_rotationalvelocity = value; }
+ }
+
+
+ protected LLVector3 m_angularVelocity;
+
+ ///
+ public LLVector3 AngularVelocity
+ {
+ get { return m_angularVelocity; }
+ set { m_angularVelocity = value; }
+ }
+
+ protected LLVector3 m_acceleration;
+
+ ///
+ public LLVector3 Acceleration
+ {
+ get { return m_acceleration; }
+ set { m_acceleration = value; }
+ }
+
+ private string m_description = String.Empty;
+
+ public string Description
+ {
+ get { return m_description; }
+ set { m_description = value; }
+ }
+
+ private Color m_color = Color.Black;
+
+ public Color Color
+ {
+ get { return m_color; }
+ set
+ {
+ m_color = value;
+ TriggerScriptChangedEvent(Changed.COLOR);
+
+ /* ScheduleFullUpdate() need not be called b/c after
+ * setting the color, the text will be set, so then
+ * ScheduleFullUpdate() will be called. */
+ //ScheduleFullUpdate();
+ }
+ }
+
+ private string m_text = String.Empty;
+
+ public Vector3 SitTargetPosition
+ {
+ get { return m_sitTargetPosition; }
+ }
+
+ public Quaternion SitTargetOrientation
+ {
+ get { return m_sitTargetOrientation; }
+ }
+
+ public string Text
+ {
+ get { return m_text; }
+ set
+ {
+ m_text = value;
+ ScheduleFullUpdate();
+ }
+ }
+
+ private string m_sitName = String.Empty;
+
+ public string SitName
+ {
+ get { return m_sitName; }
+ set { m_sitName = value; }
+ }
+
+ private string m_touchName = String.Empty;
+
+ //rex (hack)
+ private LLUUID touchedBy = LLUUID.Zero;
+
+ //rex (hack)
+ public LLUUID TouchedBy
+ {
+ set
+ {
+ touchedBy = value;
+ }
+ get
+ {
+ return touchedBy;
+ }
+ }
+
+ public string TouchName
+ {
+ get { return m_touchName; }
+ set { m_touchName = value; }
+ }
+
+ private int m_linkNum = 0;
+
+ public int LinkNum
+ {
+ get { return m_linkNum; }
+ set
+ {
+ m_linkNum = value;
+ TriggerScriptChangedEvent(Changed.LINK);
+
+ }
+ }
+
+ private byte m_clickAction = 0;
+
+ public byte ClickAction
+ {
+ get { return m_clickAction; }
+ set
+ {
+ m_clickAction = value;
+ }
+ }
+
+ protected PrimitiveBaseShape m_shape;
+
+ ///
+ /// hook to the physics scene to apply impulse
+ /// This is sent up to the group, which then finds the root prim
+ /// and applies the force on the root prim of the group
+ ///
+ /// Vector force
+ public void ApplyImpulse(LLVector3 impulsei)
+ {
+ PhysicsVector impulse = new PhysicsVector(impulsei.X, impulsei.Y, impulsei.Z);
+ if (m_parentGroup != null)
+ {
+ m_parentGroup.applyImpulse(impulse);
+ }
+ }
+
+ public void TriggerScriptChangedEvent(Changed val)
+ {
+ if (m_parentGroup != null)
+ {
+ if (m_parentGroup.Scene != null)
+ m_parentGroup.Scene.TriggerObjectChanged(LocalID, (uint)val);
+ }
+
+ }
+
+ public PrimitiveBaseShape Shape
+ {
+ get { return m_shape; }
+ set
+ {
+
+ m_shape = value;
+ TriggerScriptChangedEvent(Changed.SHAPE);
+ }
+ }
+
+ public LLVector3 Scale
+ {
+ get { return m_shape.Scale; }
+ set
+ {
+ m_shape.Scale = value;
+ TriggerScriptChangedEvent(Changed.SCALE);
+ }
+ }
+
+ public bool Stopped
+ {
+ get {
+ double threshold = 0.02;
+ return (Math.Abs(Velocity.X) < threshold &&
+ Math.Abs(Velocity.Y) < threshold &&
+ Math.Abs(Velocity.Z) < threshold &&
+ Math.Abs(AngularVelocity.X) < threshold &&
+ Math.Abs(AngularVelocity.Y) < threshold &&
+ Math.Abs(AngularVelocity.Z) < threshold);
+ }
+ }
+
+ #endregion
+
+ public LLUUID ObjectOwner
+ {
+ get { return OwnerID; }
+ }
+
+ // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out.
+ protected SceneObjectGroup m_parentGroup;
+
+ public SceneObjectGroup ParentGroup
+ {
+ get { return m_parentGroup; }
+ }
+
+ public byte UpdateFlag
+ {
+ get { return m_updateFlag; }
+ set { m_updateFlag = value; }
+ }
+
+ #region Constructors
+
+ ///
+ /// No arg constructor called by region restore db code
+ ///
+ public SceneObjectPart()
+ {
+ // It's not necessary to persist this
+ m_inventoryFileName = "taskinventory" + LLUUID.Random().ToString();
+ m_TextureAnimation = new byte[0];
+ }
+
+ public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID,
+ PrimitiveBaseShape shape, LLVector3 groupPosition, LLVector3 offsetPosition)
+ : this(regionHandle, parent, ownerID, localID, shape, groupPosition, LLQuaternion.Identity, offsetPosition)
+ {
+ }
+
+ ///
+ /// Create a completely new SceneObjectPart (prim)
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID,
+ PrimitiveBaseShape shape, LLVector3 groupPosition, LLQuaternion rotationOffset,
+ LLVector3 offsetPosition)
+ {
+ m_name = "Primitive";
+ m_regionHandle = regionHandle;
+ m_parentGroup = parent;
+
+ CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
+ OwnerID = ownerID;
+ CreatorID = OwnerID;
+ LastOwnerID = LLUUID.Zero;
+ UUID = LLUUID.Random();
+ LocalID = (uint) (localID);
+ Shape = shape;
+ // Todo: Add More Object Parameter from above!
+ OwnershipCost = 0;
+ ObjectSaleType = (byte) 0;
+ SalePrice = 0;
+ Category = (uint) 0;
+ LastOwnerID = CreatorID;
+ // End Todo: ///
+ GroupPosition = groupPosition;
+ OffsetPosition = offsetPosition;
+ RotationOffset = rotationOffset;
+ Velocity = new LLVector3(0, 0, 0);
+ m_rotationalvelocity = new LLVector3(0, 0, 0);
+ AngularVelocity = new LLVector3(0, 0, 0);
+ Acceleration = new LLVector3(0, 0, 0);
+ m_TextureAnimation = new byte[0];
+ m_inventoryFileName = "taskinventory" + LLUUID.Random().ToString();
+ m_folderID = LLUUID.Random();
+
+ Flags = 0;
+ Flags |= LLObject.ObjectFlags.Touch |
+ LLObject.ObjectFlags.AllowInventoryDrop |
+ LLObject.ObjectFlags.CreateSelected;
+
+
+ TrimPermissions();
+
+ ScheduleFullUpdate();
+ }
+
+ ///
+ /// Re/create a SceneObjectPart (prim)
+ /// currently not used, and maybe won't be
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, int creationDate, LLUUID ownerID,
+ LLUUID creatorID, LLUUID lastOwnerID, uint localID, PrimitiveBaseShape shape,
+ LLVector3 position, LLQuaternion rotation, uint flags)
+ {
+ m_regionHandle = regionHandle;
+ m_parentGroup = parent;
+ TimeStampTerse = (uint) Util.UnixTimeSinceEpoch();
+ CreationDate = creationDate;
+ OwnerID = ownerID;
+ CreatorID = creatorID;
+ LastOwnerID = lastOwnerID;
+ UUID = LLUUID.Random();
+ LocalID = (uint) (localID);
+ Shape = shape;
+ OwnershipCost = 0;
+ ObjectSaleType = (byte) 0;
+ SalePrice = 0;
+ Category = (uint) 0;
+ LastOwnerID = CreatorID;
+ OffsetPosition = position;
+ RotationOffset = rotation;
+ ObjectFlags = flags;
+
+ // Since we don't store script state, this is only a 'temporary' objectflag now
+ // If the object is scripted, the script will get loaded and this will be set again
+ ObjectFlags &= ~(uint)LLObject.ObjectFlags.Scripted;
+
+ TrimPermissions();
+ // ApplyPhysics();
+
+ ScheduleFullUpdate();
+ }
+
+ #endregion
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static SceneObjectPart FromXml(XmlReader xmlReader)
+ {
+ XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart));
+ SceneObjectPart newobject = (SceneObjectPart) serializer.Deserialize(xmlReader);
+
+ return newobject;
+ }
+
+ public void ApplyPhysics(uint rootObjectFlags, bool m_physicalPrim)
+ {
+
+ bool isPhysical = (((rootObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0) && m_physicalPrim);
+ bool isPhantom = ((rootObjectFlags & (uint) LLObject.ObjectFlags.Phantom) != 0);
+
+ // Added clarification.. since A rigid body is an object that you can kick around, etc.
+ bool RigidBody = isPhysical && !isPhantom;
+
+ // The only time the physics scene shouldn't know about the prim is if it's phantom
+ if (!isPhantom)
+ {
+ PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
+ Name,
+ Shape,
+ new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
+ AbsolutePosition.Z),
+ new PhysicsVector(Scale.X, Scale.Y, Scale.Z),
+ new Quaternion(RotationOffset.W, RotationOffset.X,
+ RotationOffset.Y, RotationOffset.Z), RigidBody);
+
+
+ DoPhysicsPropertyUpdate(RigidBody, true);
+ }
+ }
+
+ public void ApplyNextOwnerPermissions()
+ {
+ BaseMask = NextOwnerMask;
+ OwnerMask = NextOwnerMask;
+
+ TriggerScriptChangedEvent(Changed.OWNER);
+
+ }
+
+ public void TrimPermissions()
+ {
+
+ BaseMask &= (uint)PermissionMask.All;
+ OwnerMask &= (uint)PermissionMask.All;
+ GroupMask &= (uint)PermissionMask.All;
+ EveryoneMask &= (uint)PermissionMask.All;
+ NextOwnerMask &= (uint)PermissionMask.All;
+
+ // These are some flags that the next owner mask should never have
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ObjectYouOwner;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ObjectTransfer;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ObjectOwnerModify;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ObjectGroupOwned;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Physics;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Phantom;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Scripted;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Touch;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Temporary;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.TemporaryOnRez;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.ZlibCompressed;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.AllowInventoryDrop;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.AnimSource;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.Money;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.CastShadows;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.InventoryEmpty;
+ NextOwnerMask &= ~(uint) LLObject.ObjectFlags.CreateSelected;
+
+
+ // These are some flags that the GroupMask should never have
+ GroupMask &= ~(uint) LLObject.ObjectFlags.ObjectYouOwner;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.ObjectTransfer;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.ObjectOwnerModify;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.ObjectGroupOwned;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.Physics;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.Phantom;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.Scripted;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.Touch;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.Temporary;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.TemporaryOnRez;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.ZlibCompressed;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.AllowInventoryDrop;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.AnimSource;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.Money;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.CastShadows;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.InventoryEmpty;
+ GroupMask &= ~(uint) LLObject.ObjectFlags.CreateSelected;
+
+
+ // These are some flags that EveryoneMask should never have
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.ObjectYouOwner;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.ObjectTransfer;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.ObjectOwnerModify;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.ObjectGroupOwned;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.Physics;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.Phantom;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.Scripted;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.Touch;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.Temporary;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.TemporaryOnRez;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.ZlibCompressed;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.AllowInventoryDrop;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.AnimSource;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.Money;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.CastShadows;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.InventoryEmpty;
+ EveryoneMask &= ~(uint) LLObject.ObjectFlags.CreateSelected;
+ EveryoneMask &= ~(uint)LLObject.ObjectFlags.ObjectYouOfficer;
+ EveryoneMask &= ~(uint)LLObject.ObjectFlags.ObjectModify;
+
+
+ // These are some flags that ObjectFlags (m_flags) should never have
+ ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectYouOwner;
+ ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectTransfer;
+ ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectOwnerModify;
+ ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectYouOfficer;
+ ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectCopy;
+ ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectModify;
+ ObjectFlags &= ~(uint) LLObject.ObjectFlags.ObjectMove;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void ToXml(XmlWriter xmlWriter)
+ {
+ XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart));
+ serializer.Serialize(xmlWriter, this);
+ }
+
+ public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot)
+ {
+ // In this case we're using a sphere with a radius of the largest dimention of the prim
+ // TODO: Change to take shape into account
+
+
+ EntityIntersection returnresult = new EntityIntersection();
+ Vector3 vAbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
+
+ Vector3 vScale = new Vector3(Scale.X, Scale.Y, Scale.Z);
+ Quaternion qRotation =
+ new Quaternion(RotationOffset.W, RotationOffset.X, RotationOffset.Y, RotationOffset.Z);
+
+
+ //Quaternion worldRotation = (qRotation*parentrot);
+ //Matrix3 worldRotM = worldRotation.ToRotationMatrix();
+
+
+ Vector3 rOrigin = iray.Origin;
+ Vector3 rDirection = iray.Direction;
+
+
+
+ //rDirection = rDirection.Normalize();
+ // Buidling the first part of the Quadratic equation
+ Vector3 r2ndDirection = rDirection*rDirection;
+ float itestPart1 = r2ndDirection.x + r2ndDirection.y + r2ndDirection.z;
+
+ // Buidling the second part of the Quadratic equation
+ Vector3 tmVal2 = rOrigin - vAbsolutePosition;
+ Vector3 r2Direction = rDirection*2.0f;
+ Vector3 tmVal3 = r2Direction*tmVal2;
+
+ float itestPart2 = tmVal3.x + tmVal3.y + tmVal3.z;
+
+ // Buidling the third part of the Quadratic equation
+ Vector3 tmVal4 = rOrigin*rOrigin;
+ Vector3 tmVal5 = vAbsolutePosition*vAbsolutePosition;
+
+ Vector3 tmVal6 = vAbsolutePosition*rOrigin;
+
+
+ // Set Radius to the largest dimention of the prim
+ float radius = 0f;
+ if (vScale.x > radius)
+ radius = vScale.x;
+ if (vScale.y > radius)
+ radius = vScale.y;
+ if (vScale.z > radius)
+ radius = vScale.z;
+
+ //radius = radius;
+
+ float itestPart3 = tmVal4.x + tmVal4.y + tmVal4.z + tmVal5.x + tmVal5.y + tmVal5.z -
+ (2.0f*(tmVal6.x + tmVal6.y + tmVal6.z + (radius*radius)));
+
+ // Yuk Quadradrics.. Solve first
+ float rootsqr = (itestPart2*itestPart2) - (4.0f*itestPart1*itestPart3);
+ if (rootsqr < 0.0f)
+ {
+ // No intersection
+ return returnresult;
+ }
+ float root = ((-itestPart2) - (float) Math.Sqrt((double) rootsqr))/(itestPart1*2.0f);
+
+ if (root < 0.0f)
+ {
+ // perform second quadratic root solution
+ root = ((-itestPart2) + (float) Math.Sqrt((double) rootsqr))/(itestPart1*2.0f);
+
+ // is there any intersection?
+ if (root < 0.0f)
+ {
+ // nope, no intersection
+ return returnresult;
+ }
+ }
+
+ // We got an intersection. putting together an EntityIntersection object with the
+ // intersection information
+ Vector3 ipoint =
+ new Vector3(iray.Origin.x + (iray.Direction.x*root), iray.Origin.y + (iray.Direction.y*root),
+ iray.Origin.z + (iray.Direction.z*root));
+
+ returnresult.HitTF = true;
+ returnresult.ipoint = ipoint;
+
+ // Normal is calculated by the difference and then normalizing the result
+ Vector3 normalpart = ipoint - vAbsolutePosition;
+ returnresult.normal = normalpart.Normalize();
+
+ // It's funny how the LLVector3 object has a Distance function, but the Axiom.Math object doesnt.
+ // I can write a function to do it.. but I like the fact that this one is Static.
+
+ LLVector3 distanceConvert1 = new LLVector3(iray.Origin.x, iray.Origin.y, iray.Origin.z);
+ LLVector3 distanceConvert2 = new LLVector3(ipoint.x, ipoint.y, ipoint.z);
+ float distance = (float) Util.GetDistanceTo(distanceConvert1, distanceConvert2);
+
+ returnresult.distance = distance;
+
+ return returnresult;
+ }
+
+
+ ///
+ ///
+ ///
+ public void SetParent(SceneObjectGroup parent)
+ {
+ m_parentGroup = parent;
+ }
+
+ public void SetSitTarget(Vector3 offset, Quaternion orientation)
+ {
+ m_sitTargetPosition = offset;
+ m_sitTargetOrientation = orientation;
+ }
+
+ public LLVector3 GetSitTargetPositionLL()
+ {
+ return new LLVector3(m_sitTargetPosition.x, m_sitTargetPosition.y, m_sitTargetPosition.z);
+ }
+
+ public LLQuaternion GetSitTargetOrientationLL()
+ {
+ return
+ new LLQuaternion(m_sitTargetOrientation.x, m_sitTargetOrientation.y, m_sitTargetOrientation.z,
+ m_sitTargetOrientation.w);
+ }
+
+ // Utility function so the databases don't have to reference axiom.math
+ public void SetSitTargetLL(LLVector3 offset, LLQuaternion orientation)
+ {
+ if (
+ !(offset.X == 0 && offset.Y == 0 && offset.Z == 0 && (orientation.W == 0 || orientation.W == 1) &&
+ orientation.X == 0 && orientation.Y == 0 && orientation.Z == 0))
+ {
+ m_sitTargetPosition = new Vector3(offset.X, offset.Y, offset.Z);
+ m_sitTargetOrientation = new Quaternion(orientation.W, orientation.X, orientation.Y, orientation.Z);
+ }
+ }
+
+ public Vector3 GetSitTargetPosition()
+ {
+ return m_sitTargetPosition;
+ }
+
+ public Quaternion GetSitTargetOrientation()
+ {
+ return m_sitTargetOrientation;
+ }
+
+ public void SetAvatarOnSitTarget(LLUUID avatarID)
+ {
+ m_sitTargetAvatar = avatarID;
+ TriggerScriptChangedEvent(Changed.LINK);
+ }
+
+ public LLUUID GetAvatarOnSitTarget()
+ {
+ return m_sitTargetAvatar;
+ }
+
+
+ public LLUUID GetRootPartUUID()
+ {
+ if (m_parentGroup != null)
+ {
+ return m_parentGroup.UUID;
+ }
+ return LLUUID.Zero;
+ }
+
+ public static SceneObjectPart Create()
+ {
+ SceneObjectPart part = new SceneObjectPart();
+ part.UUID = LLUUID.Random();
+
+ PrimitiveBaseShape shape = PrimitiveBaseShape.Create();
+ part.Shape = shape;
+
+ part.Name = "Primitive";
+ part.OwnerID = LLUUID.Random();
+
+ return part;
+ }
+
+ #region Copying
+
+ ///
+ /// Duplicates this part.
+ ///
+ ///
+ public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID, int linkNum)
+ {
+ SceneObjectPart dupe = (SceneObjectPart) MemberwiseClone();
+ dupe.m_shape = m_shape.Copy();
+ dupe.m_regionHandle = m_regionHandle;
+ dupe.UUID = LLUUID.Random();
+ dupe.LocalID = localID;
+ dupe.OwnerID = AgentID;
+ dupe.GroupID = GroupID;
+ dupe.GroupPosition = new LLVector3(GroupPosition.X, GroupPosition.Y, GroupPosition.Z);
+ dupe.OffsetPosition = new LLVector3(OffsetPosition.X, OffsetPosition.Y, OffsetPosition.Z);
+ dupe.RotationOffset =
+ new LLQuaternion(RotationOffset.X, RotationOffset.Y, RotationOffset.Z, RotationOffset.W);
+ dupe.Velocity = new LLVector3(0, 0, 0);
+ dupe.Acceleration = new LLVector3(0, 0, 0);
+ dupe.AngularVelocity = new LLVector3(0, 0, 0);
+ dupe.ObjectFlags = ObjectFlags;
+
+ dupe.OwnershipCost = OwnershipCost;
+ dupe.ObjectSaleType = ObjectSaleType;
+ dupe.SalePrice = SalePrice;
+ dupe.Category = Category;
+
+ dupe.TaskInventory = (TaskInventoryDictionary)dupe.TaskInventory.Clone();
+
+ dupe.ResetIDs(linkNum);
+
+ // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
+ dupe.LastOwnerID = ObjectOwner;
+
+ byte[] extraP = new byte[Shape.ExtraParams.Length];
+ Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
+ dupe.Shape.ExtraParams = extraP;
+ bool UsePhysics = ((dupe.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0);
+ dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
+
+ return dupe;
+ }
+
+ #endregion
+
+ ///
+ /// Reset LLUUIDs for this part. This involves generate this part's own LLUUID and
+ /// generating new LLUUIDs for all the items in the inventory.
+ ///
+ ///
+ ///
+ ///
+ public void ScheduleTerseUpdate()
+ {
+ if (m_updateFlag < 1)
+ {
+ if (m_parentGroup != null)
+ {
+ m_parentGroup.HasGroupChanged = true;
+ m_parentGroup.QueueForUpdateCheck();
+ }
+ TimeStampTerse = (uint) Util.UnixTimeSinceEpoch();
+ m_updateFlag = 1;
+
+ }
+ }
+
+ ///
+ ///
+ ///
+ public void SendScheduledUpdates()
+ {
+ if (m_updateFlag == 1) //some change has been made so update the clients
+ {
+ AddTerseUpdateToAllAvatars();
+ ClearUpdateSchedule();
+
+ // This causes the Scene to 'poll' physical objects every couple of frames
+ // bad, so it's been replaced by an event driven method.
+ //if ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0)
+ //{
+ // Only send the constant terse updates on physical objects!
+ //ScheduleTerseUpdate();
+ //}
+ }
+ else
+ {
+ if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
+ {
+ AddFullUpdateToAllAvatars();
+ ClearUpdateSchedule();
+ }
+ }
+ }
+
+ #endregion
+
+ #region Shape
+
+ ///
+ ///
+ ///
+ ///
+ public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock)
+ {
+ m_shape.PathBegin = shapeBlock.PathBegin;
+ m_shape.PathEnd = shapeBlock.PathEnd;
+ m_shape.PathScaleX = shapeBlock.PathScaleX;
+ m_shape.PathScaleY = shapeBlock.PathScaleY;
+ m_shape.PathShearX = shapeBlock.PathShearX;
+ m_shape.PathShearY = shapeBlock.PathShearY;
+ m_shape.PathSkew = shapeBlock.PathSkew;
+ m_shape.ProfileBegin = shapeBlock.ProfileBegin;
+ m_shape.ProfileEnd = shapeBlock.ProfileEnd;
+ m_shape.PathCurve = shapeBlock.PathCurve;
+ m_shape.ProfileCurve = shapeBlock.ProfileCurve;
+ m_shape.ProfileHollow = shapeBlock.ProfileHollow;
+ m_shape.PathRadiusOffset = shapeBlock.PathRadiusOffset;
+ m_shape.PathRevolutions = shapeBlock.PathRevolutions;
+ m_shape.PathTaperX = shapeBlock.PathTaperX;
+ m_shape.PathTaperY = shapeBlock.PathTaperY;
+ m_shape.PathTwist = shapeBlock.PathTwist;
+ m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
+ if (PhysActor != null)
+ {
+ PhysActor.Shape = m_shape;
+ }
+ ScheduleFullUpdate();
+ }
+
+ #endregion
+
+ #region ExtraParams
+
+ public void UpdatePrimFlags(ushort type, bool inUse, byte[] data)
+ {
+
+
+ //m_log.Info("TSomething1:" + ((type & (ushort)ExtraParamType.Something1) == (ushort)ExtraParamType.Something1));
+ //m_log.Info("TSomething2:" + ((type & (ushort)ExtraParamType.Something2) == (ushort)ExtraParamType.Something2));
+ //m_log.Info("TSomething3:" + ((type & (ushort)ExtraParamType.Something3) == (ushort)ExtraParamType.Something3));
+ //m_log.Info("TSomething4:" + ((type & (ushort)ExtraParamType.Something4) == (ushort)ExtraParamType.Something4));
+ //m_log.Info("TSomething5:" + ((type & (ushort)ExtraParamType.Something5) == (ushort)ExtraParamType.Something5));
+ //m_log.Info("TSomething6:" + ((type & (ushort)ExtraParamType.Something6) == (ushort)ExtraParamType.Something6));
+
+ bool usePhysics = false;
+ bool IsTemporary = false;
+ bool IsPhantom = false;
+ bool castsShadows = false;
+ bool wasUsingPhysics = ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0);
+ //bool IsLocked = false;
+ int i = 0;
+ //rex
+ LLUUID AgentID = LLUUID.Zero, SessionID = LLUUID.Zero;
+ uint ObjectLocalID;
+
+ try
+ {
+ //rex
+ i += 10;
+ AgentID = new LLUUID(data, i); i += 16;
+ SessionID = new LLUUID(data, i); i += 16;
+ ObjectLocalID = (uint)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24));
+ //IsLocked = (data[i++] != 0) ? true : false;
+ usePhysics = ((data[i++] != 0) && m_parentGroup.Scene.m_physicalPrim) ? true : false;
+ //System.Console.WriteLine("U" + packet.ToBytes().Length.ToString());
+ IsTemporary = (data[i++] != 0) ? true : false;
+ IsPhantom = (data[i++] != 0) ? true : false;
+ castsShadows = (data[i++] != 0) ? true : false;
+ }
+ catch (Exception)
+ {
+ Console.WriteLine("Ignoring invalid Packet:");
+ //Silently ignore it - TODO: FIXME Quick
+ }
+
+ #region rex added flags
+ if (AgentID == this.OwnerID)
+ {
+ AddFlag(LLObject.ObjectFlags.ObjectYouOwner);
+ }
+ else
+ {
+ RemFlag(LLObject.ObjectFlags.ObjectYouOwner);
+ }
+ #endregion
+
+ if (usePhysics)
+ {
+ AddFlag(LLObject.ObjectFlags.Physics);
+ if (!wasUsingPhysics)
+ {
+ DoPhysicsPropertyUpdate(usePhysics, false);
+ }
+ }
+ else
+ {
+ RemFlag(LLObject.ObjectFlags.Physics);
+ if (wasUsingPhysics)
+ {
+ DoPhysicsPropertyUpdate(usePhysics, false);
+ }
+ }
+
+
+ if (IsPhantom)
+ {
+ AddFlag(LLObject.ObjectFlags.Phantom);
+ if (PhysActor != null)
+ {
+ m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
+ /// that's not wholesome. Had to make Scene public
+ PhysActor = null;
+ }
+ }
+ else
+ {
+ RemFlag(LLObject.ObjectFlags.Phantom);
+ if (PhysActor == null)
+ {
+ PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
+ Name,
+ Shape,
+ new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
+ AbsolutePosition.Z),
+ new PhysicsVector(Scale.X, Scale.Y, Scale.Z),
+ new Quaternion(RotationOffset.W, RotationOffset.X,
+ RotationOffset.Y, RotationOffset.Z), usePhysics, LocalID);
+ DoPhysicsPropertyUpdate(usePhysics, true);
+ }
+ else
+ {
+ PhysActor.IsPhysical = usePhysics;
+ DoPhysicsPropertyUpdate(usePhysics, false);
+ }
+ }
+
+ if (IsTemporary)
+ {
+ AddFlag(LLObject.ObjectFlags.TemporaryOnRez);
+ }
+ else
+ {
+ RemFlag(LLObject.ObjectFlags.TemporaryOnRez);
+ }
+ // System.Console.WriteLine("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
+ ScheduleFullUpdate();
+ }
+
+ public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
+ {
+ if (PhysActor != null)
+ {
+ if (UsePhysics != PhysActor.IsPhysical || isNew)
+ {
+ if (PhysActor.IsPhysical)
+ {
+ if (!isNew)
+ ParentGroup.Scene.RemovePhysicalPrim(1);
+
+ PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
+ PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
+ }
+
+ PhysActor.IsPhysical = UsePhysics;
+ // If we're not what we're supposed to be in the physics scene, recreate ourselves.
+ //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
+ /// that's not wholesome. Had to make Scene public
+ //PhysActor = null;
+
+
+ if ((ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) == 0)
+ {
+ //PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
+ //Name,
+ //Shape,
+ //new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
+ //AbsolutePosition.Z),
+ //new PhysicsVector(Scale.X, Scale.Y, Scale.Z),
+ //new Quaternion(RotationOffset.W, RotationOffset.X,
+ //RotationOffset.Y, RotationOffset.Z), UsePhysics);
+ if (UsePhysics)
+ {
+ ParentGroup.Scene.AddPhysicalPrim(1);
+
+ PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
+ PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
+ }
+ }
+ }
+ m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
+ }
+ }
+
+ public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
+ {
+ // rex, function fixed for handling multiple parameter blocks and disabling them
+
+ //m_shape.ExtraParams = new byte[data.Length + 7];
+ //int i = 0;
+ //uint length = (uint) data.Length;
+ //m_shape.ExtraParams[i++] = 1;
+ //m_shape.ExtraParams[i++] = (byte) (type%256);
+ //m_shape.ExtraParams[i++] = (byte) ((type >> 8)%256);
+
+ //m_shape.ExtraParams[i++] = (byte) (length%256);
+ //m_shape.ExtraParams[i++] = (byte) ((length >> 8)%256);
+ //m_shape.ExtraParams[i++] = (byte) ((length >> 16)%256);
+ //m_shape.ExtraParams[i++] = (byte) ((length >> 24)%256);
+ //Array.Copy(data, 0, m_shape.ExtraParams, i, data.Length);
+
+ // Amount of param blocks in new & old extra params
+ int numOld = 0;
+ int numNew = 0;
+
+ // If old param block exists, take its length & amount of param blocks in it
+ int totalSizeOld = 0;
+ int idxOld = 0;
+ if (m_shape.ExtraParams != null)
+ {
+ numOld = m_shape.ExtraParams[idxOld++];
+ totalSizeOld = m_shape.ExtraParams.Length;
+ }
+
+ // New extra params: maximum size = old extra params + size of new data + possible new param block header + num of blocks
+ byte[] newExtraParams = new byte[totalSizeOld + data.Length + 6 + 1];
+
+ int idxNew = 1; // Don't know the amount of new param blocks yet, fill it later
+ bool isNewBlock = true;
+
+ // Go through each of the old params, and see if this new update disables or changes it
+ for (int i = 0; i < numOld; i++)
+ {
+ int typeOld = m_shape.ExtraParams[idxOld++] | (m_shape.ExtraParams[idxOld++] << 8);
+ int lengthOld = m_shape.ExtraParams[idxOld++] | (m_shape.ExtraParams[idxOld++] << 8) |
+ (m_shape.ExtraParams[idxOld++] << 16) | (m_shape.ExtraParams[idxOld++] << 24);
+
+ // Not changed, copy verbatim
+ if (typeOld != type)
+ {
+ newExtraParams[idxNew++] = (byte)(typeOld % 256);
+ newExtraParams[idxNew++] = (byte)((typeOld >> 8) % 256);
+ newExtraParams[idxNew++] = (byte)(lengthOld % 256);
+ newExtraParams[idxNew++] = (byte)((lengthOld >> 8) % 256);
+ newExtraParams[idxNew++] = (byte)((lengthOld >> 16) % 256);
+ newExtraParams[idxNew++] = (byte)((lengthOld >> 24) % 256);
+ Array.Copy(m_shape.ExtraParams, idxOld, newExtraParams, idxNew, lengthOld);
+
+ idxNew += lengthOld;
+ numNew++;
+ }
+ else
+ {
+ isNewBlock = false;
+
+ // Old parameter updated, check if still in use, or if should remove
+ if (inUse)
+ {
+ newExtraParams[idxNew++] = (byte)(type % 256);
+ newExtraParams[idxNew++] = (byte)((type >> 8) % 256);
+ newExtraParams[idxNew++] = (byte)(data.Length % 256);
+ newExtraParams[idxNew++] = (byte)((data.Length >> 8) % 256);
+ newExtraParams[idxNew++] = (byte)((data.Length >> 16) % 256);
+ newExtraParams[idxNew++] = (byte)((data.Length >> 24) % 256);
+ Array.Copy(data, 0, newExtraParams, idxNew, data.Length);
+
+ idxNew += data.Length;
+ numNew++;
+ }
+ }
+ idxOld += lengthOld;
+ }
+ // If type was not listed, create new block
+ if ((isNewBlock) && (inUse))
+ {
+ newExtraParams[idxNew++] = (byte)(type % 256);
+ newExtraParams[idxNew++] = (byte)((type >> 8) % 256);
+ newExtraParams[idxNew++] = (byte)(data.Length % 256);
+ newExtraParams[idxNew++] = (byte)((data.Length >> 8) % 256);
+ newExtraParams[idxNew++] = (byte)((data.Length >> 16) % 256);
+ newExtraParams[idxNew++] = (byte)((data.Length >> 24) % 256);
+ Array.Copy(data, 0, newExtraParams, idxNew, data.Length);
+
+ idxNew += data.Length;
+ numNew++;
+ }
+
+ // Now we know final size and number of param blocks
+ newExtraParams[0] = (byte)numNew;
+ m_shape.ExtraParams = new byte[idxNew];
+ Array.Copy(newExtraParams, m_shape.ExtraParams, idxNew);
+
+ string OldPythonClass = m_RexClassName;
+ LLUUID OldColMesh = m_RexCollisionMeshUUID;
+ bool OldMeshScaling = ((m_RexFlags & REXFLAGS_SCALEMESH) != 0);
+
+ GetRexParameters();
+
+ if (m_RexClassName != OldPythonClass)
+ m_parentGroup.Scene.EventManager.TriggerOnChangePythonClass(LocalID);
+
+ if (GlobalSettings.Instance.m_3d_collision_models)
+ {
+ if (m_RexCollisionMeshUUID != OldColMesh && PhysActor != null)
+ {
+ if (m_RexCollisionMeshUUID != LLUUID.Zero)
+ RexUpdateCollisionMesh();
+ else
+ PhysActor.SetCollisionMesh(null, "", false);
+ }
+
+ bool NewMeshScaling = ((m_RexFlags & REXFLAGS_SCALEMESH) != 0);
+ if (NewMeshScaling != OldMeshScaling && PhysActor != null)
+ {
+ PhysActor.SetBoundsScaling(NewMeshScaling);
+ m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
+ }
+ }
+ // rexend
+
+ ScheduleFullUpdate();
+ }
+
+ // rex, new function, compiles / sends rex parameters after serverside modification
+ public void UpdateRexParameters()
+ {
+ // Compile reX member variables into an extraparam-block
+ int size = m_RexClassName.Length + 1 // Name + endzero
+ + 1 + 1 + 4 + 4 // Flags, collisiontype, drawdistance, lod
+ + 16 + 16 // Mesh UUID & collisionmesh UUID
+ + 2 + m_RexMaterialUUID.Count * 16 // Material count and UUID's
+ + 1 // Fixed material
+ + 16; // Particle script UUID
+
+ byte[] buffer = new byte[size];
+ int idx = 0;
+
+ for (int i = 0; i < m_RexClassName.Length; i++)
+ {
+ buffer[idx++] = (byte)m_RexClassName[i];
+ }
+ buffer[idx++] = 0;
+
+ buffer[idx++] = m_RexFlags;
+
+ buffer[idx++] = m_RexCollisionType;
+
+ System.BitConverter.GetBytes(m_RexDrawDistance).CopyTo(buffer, idx);
+ idx += 4;
+
+ System.BitConverter.GetBytes(m_RexLOD).CopyTo(buffer, idx);
+ idx += 4;
+
+ m_RexMeshUUID.GetBytes().CopyTo(buffer, idx);
+ idx += 16;
+
+ m_RexCollisionMeshUUID.GetBytes().CopyTo(buffer, idx);
+ idx += 16;
+
+ System.BitConverter.GetBytes((short)m_RexMaterialUUID.Count).CopyTo(buffer, idx);
+ idx += 2;
+ for (int i = 0; i < m_RexMaterialUUID.Count; i++)
+ {
+ m_RexMaterialUUID[i].GetBytes().CopyTo(buffer, idx);
+ idx += 16;
+ }
+
+ buffer[idx++] = m_RexFixedMaterial;
+
+ m_RexParticleScriptUUID.GetBytes().CopyTo(buffer, idx);
+ idx += 16;
+
+ UpdateExtraParam(PARAMS_REX, true, buffer);
+ }
+
+ // rex, new function, extract reX parameters from the parameter block
+ public void GetRexParameters()
+ {
+ if (m_shape.ExtraParams == null) return;
+
+ int idx = 0;
+ int numParams = m_shape.ExtraParams[idx++];
+
+ for (int i = 0; i < numParams; i++)
+ {
+ // Is this the reX parameter block?
+ int type = m_shape.ExtraParams[idx++] | (m_shape.ExtraParams[idx++] << 8);
+ int length = m_shape.ExtraParams[idx++] | (m_shape.ExtraParams[idx++] << 8) |
+ (m_shape.ExtraParams[idx++] << 16) | (m_shape.ExtraParams[idx++] << 24);
+ int start = idx;
+
+ if (type == PARAMS_REX)
+ {
+ // Class name
+ StringBuilder buffer = new StringBuilder();
+ while ((idx < (length + start)) && (m_shape.ExtraParams[idx] != 0))
+ {
+ char c = (char)m_shape.ExtraParams[idx++];
+ buffer.Append(c);
+ }
+ m_RexClassName = buffer.ToString();
+ idx++;
+
+ // Rex flags
+ if (idx < (length + start))
+ {
+ m_RexFlags = m_shape.ExtraParams[idx++];
+ }
+
+ // Collision type
+ if (idx < (length + start))
+ {
+ m_RexCollisionType = m_shape.ExtraParams[idx++];
+ }
+
+ // Draw distance
+ if (idx < (length + start - 3))
+ {
+ m_RexDrawDistance = System.BitConverter.ToSingle(m_shape.ExtraParams, idx);
+ idx += 4;
+ }
+
+ // Mesh LOD
+ if (idx < (length + start - 3))
+ {
+ m_RexLOD = System.BitConverter.ToSingle(m_shape.ExtraParams, idx);
+ idx += 4;
+ }
+
+ // Mesh UUID
+ if (idx < (length + start - 15))
+ {
+ m_RexMeshUUID = new LLUUID(m_shape.ExtraParams, idx);
+ idx += 16;
+ }
+
+ // Collision mesh UUID
+ if (idx < (length + start - 15))
+ {
+ m_RexCollisionMeshUUID = new LLUUID(m_shape.ExtraParams, idx);
+ idx += 16;
+ }
+
+ // Number of materials
+ if (idx < (length + start - 1))
+ {
+ short rexMaterials = System.BitConverter.ToInt16(m_shape.ExtraParams, idx);
+ idx += 2;
+ m_RexMaterialUUID = new List();
+
+ for (short j = 0; j < rexMaterials; j++)
+ {
+ if (idx < (length + start - 15))
+ {
+ m_RexMaterialUUID.Add(new LLUUID(m_shape.ExtraParams, idx));
+ idx += 16;
+ }
+ else break;
+ }
+ }
+ // Fixed material
+ if (idx < (length + start))
+ {
+ m_RexFixedMaterial = m_shape.ExtraParams[idx++];
+ }
+ // Particle script UUID
+ if (idx < (length + start - 15))
+ {
+ m_RexParticleScriptUUID = new LLUUID(m_shape.ExtraParams, idx);
+ idx += 16;
+ }
+
+ //System.Console.WriteLine("Rex parameters of an object updated");
+ //System.Console.WriteLine("Rex class name: " + m_RexClassName);
+ //System.Console.WriteLine("Rex flags: " + (short)m_RexFlags);
+ //System.Console.WriteLine("Rex collision type: " + (short)m_RexCollisionType);
+ //System.Console.WriteLine("Rex draw distance: " + m_RexDrawDistance);
+ //System.Console.WriteLine("Rex LOD: " + m_RexLOD);
+ //System.Console.WriteLine("Rex mesh UUID: " + m_RexMeshUUID);
+ //System.Console.WriteLine("Rex collisionmesh UUID: " + m_RexCollisionMeshUUID);
+ //System.Console.WriteLine("Rex material count: " + m_RexMaterialUUID.Count);
+ //for (int j = 0; j < m_RexMaterialUUID.Count; j++)
+ //{
+ // System.Console.WriteLine("Rex material UUID " + j + ": " + m_RexMaterialUUID[j]);
+ //}
+ break;
+ }
+ else idx += length;
+ }
+ }
+
+ #endregion
+
+ #region Physics
+
+ public float GetMass()
+ {
+ if (PhysActor != null)
+ {
+ return PhysActor.Mass;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ // rex, added
+ public void SetMass(float vValue)
+ {
+ if (PhysActor != null)
+ {
+ // PhysActor.Mass = vValue;
+ }
+ }
+
+ // rex, added
+ public bool GetUsePrimVolumeCollision()
+ {
+ if (PhysActor != null)
+ return (PhysActor.PhysicsActorType == 4);
+ else
+ return false;
+ }
+
+ // rex, added
+ public void SetUsePrimVolumeCollision(bool vUseVolumeCollision)
+ {
+ if (PhysActor != null)
+ {
+ if (vUseVolumeCollision)
+ {
+ if (PhysActor.PhysicsActorType != 4)
+ PhysActor.OnCollisionUpdate += PhysicsCollisionUpdate;
+ PhysActor.PhysicsActorType = 4;
+ }
+ else
+ {
+ if (PhysActor.PhysicsActorType == 4)
+ PhysActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
+
+ PhysActor.PhysicsActorType = 2;
+ }
+ }
+ }
+
+ // rex, added
+ private void PhysicsCollisionUpdate(EventArgs e)
+ {
+ if (PhysActor != null && PhysActor.PhysicsActorType == 4)
+ m_parentGroup.Scene.EventManager.TriggerOnPrimVolumeCollision(LocalID, (e as CollisionEventUpdate).m_LocalID);
+ }
+
+
+
+ // rex, added
+ public void RexUpdateCollisionMesh()
+ {
+ if (!GlobalSettings.Instance.m_3d_collision_models)
+ return;
+
+ if (m_RexCollisionMeshUUID != LLUUID.Zero && PhysActor != null)
+ {
+ bool ScaleMesh = ((m_RexFlags & REXFLAGS_SCALEMESH) != 0);
+ AssetBase tempmodel = m_parentGroup.Scene.AssetCache.FetchAsset(m_RexCollisionMeshUUID);
+ if (tempmodel != null)
+ PhysActor.SetCollisionMesh(tempmodel.Data, tempmodel.Name, ScaleMesh);
+ }
+ }
+
+
+
+ public LLVector3 GetGeometricCenter()
+ {
+ if (PhysActor != null)
+ {
+ return new LLVector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z);
+ }
+ else
+ {
+ return new LLVector3(0, 0, 0);
+ }
+ }
+
+ #endregion
+
+ #region Texture
+
+ ///
+ ///
+ ///
+ ///
+ public void UpdateTextureEntry(byte[] textureEntry)
+ {
+ m_shape.TextureEntry = textureEntry;
+ TriggerScriptChangedEvent(Changed.TEXTURE);
+ ScheduleFullUpdate();
+ }
+
+ // Added to handle bug in libsecondlife's TextureEntry.ToBytes()
+ // not handling RGBA properly. Cycles through, and "fixes" the color
+ // info
+ public void UpdateTexture(LLObject.TextureEntry tex)
+ {
+ //LLColor tmpcolor;
+ //for (uint i = 0; i < 32; i++)
+ //{
+ // if (tex.FaceTextures[i] != null)
+ // {
+ // tmpcolor = tex.GetFace((uint) i).RGBA;
+ // tmpcolor.A = tmpcolor.A*255;
+ // tmpcolor.R = tmpcolor.R*255;
+ // tmpcolor.G = tmpcolor.G*255;
+ // tmpcolor.B = tmpcolor.B*255;
+ // tex.FaceTextures[i].RGBA = tmpcolor;
+ // }
+ //}
+ //tmpcolor = tex.DefaultTexture.RGBA;
+ //tmpcolor.A = tmpcolor.A*255;
+ //tmpcolor.R = tmpcolor.R*255;
+ //tmpcolor.G = tmpcolor.G*255;
+ //tmpcolor.B = tmpcolor.B*255;
+ //tex.DefaultTexture.RGBA = tmpcolor;
+ UpdateTextureEntry(tex.ToBytes());
+ }
+
+ public byte ConvertScriptUintToByte(uint indata)
+ {
+ byte outdata = (byte)TextureAnimFlags.NONE;
+ if ((indata & 1) != 0) outdata |= (byte)TextureAnimFlags.ANIM_ON;
+ if ((indata & 2) != 0) outdata |= (byte)TextureAnimFlags.LOOP;
+ if ((indata & 4) != 0) outdata |= (byte)TextureAnimFlags.REVERSE;
+ if ((indata & 8) != 0) outdata |= (byte)TextureAnimFlags.PING_PONG;
+ if ((indata & 16) != 0) outdata |= (byte)TextureAnimFlags.SMOOTH;
+ if ((indata & 32) != 0) outdata |= (byte)TextureAnimFlags.ROTATE;
+ if ((indata & 64) != 0) outdata |= (byte)TextureAnimFlags.SCALE;
+ return outdata;
+ }
+
+ public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim)
+ {
+ byte[] data = new byte[16];
+ int pos = 0;
+
+ // The flags don't like conversion from uint to byte, so we have to do
+ // it the crappy way. See the above function :(
+
+ data[pos] = ConvertScriptUintToByte(pTexAnim.Flags); pos++;
+ data[pos] = (byte)pTexAnim.Face; pos++;
+ data[pos] = (byte)pTexAnim.SizeX; pos++;
+ data[pos] = (byte)pTexAnim.SizeX; pos++;
+
+ Helpers.FloatToBytes(pTexAnim.Start).CopyTo(data, pos);
+ Helpers.FloatToBytes(pTexAnim.Length ).CopyTo(data, pos + 4);
+ Helpers.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8);
+
+ m_TextureAnimation = data;
+ }
+
+ #endregion
+
+ #region ParticleSystem
+
+ public void AddNewParticleSystem(Primitive.ParticleSystem pSystem)
+ {
+ m_particleSystem = pSystem.GetBytes();
+ }
+
+ #endregion
+
+ #region Position
+
+ public void AttachToAvatar(LLUUID agentId, ScenePresence presence, byte attachPt, LLQuaternion rotation, RegionInfo regionInfo)
+ {
+ m_attachAgentId = agentId;
+ m_attachPresence = presence;
+ m_attachPt = attachPt;
+ m_attachRot = rotation;
+ m_attachRegInfo = regionInfo;
+
+ RotationOffset = new LLQuaternion(0, 0, 0, 1);
+
+ ScheduleFullUpdate();
+ }
+
+ public void Detach()
+ {
+ m_attachPresence = null;
+ ScheduleFullUpdate();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void UpdateOffSet(LLVector3 pos)
+ {
+ LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z);
+ OffsetPosition = newPos;
+ ScheduleTerseUpdate();
+ }
+
+ public void UpdateGroupPosition(LLVector3 pos)
+ {
+ LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z);
+ GroupPosition = newPos;
+ ScheduleTerseUpdate();
+ }
+
+ #endregion
+
+ #region rotation
+
+ public void UpdateRotation(LLQuaternion rot)
+ {
+ RotationOffset = new LLQuaternion(rot.X, rot.Y, rot.Z, rot.W);
+ ScheduleTerseUpdate();
+ }
+
+ #endregion
+
+ #region Sound
+ public void PreloadSound(string sound)
+ {
+ LLUUID ownerID = OwnerID;
+ LLUUID objectID = UUID;
+ LLUUID soundID = LLUUID.Zero;
+
+ if (!LLUUID.TryParse(sound, out soundID))
+ {
+ //Trys to fetch sound id from prim's inventory.
+ //Prim's inventory doesn't support non script items yet
+ SceneObjectPart op = this;
+ foreach (KeyValuePair item in op.TaskInventory)
+ {
+ if (item.Value.Name == sound)
+ {
+ soundID = item.Value.ItemID;
+ break;
+ }
+ }
+ }
+
+ List avatarts = m_parentGroup.Scene.GetAvatars();
+ foreach (ScenePresence p in avatarts)
+ {
+ // TODO: some filtering by distance of avatar
+
+ p.ControllingClient.SendPreLoadSound(objectID, objectID, soundID);
+ }
+ }
+
+ public void SendSound(string sound, double volume, bool triggered)
+ {
+ if (volume > 1)
+ volume = 1;
+ if (volume < 0)
+ volume = 0;
+
+ LLUUID ownerID = OwnerID;
+ LLUUID objectID = UUID;
+ LLUUID parentID = GetRootPartUUID();
+ LLUUID soundID = LLUUID.Zero;
+ LLVector3 position = AbsolutePosition; // region local
+ ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle;
+
+ byte flags = 0;
+
+ if (!LLUUID.TryParse(sound, out soundID))
+ {
+ // search sound file from inventory
+ SceneObjectPart op = this;
+ foreach (KeyValuePair item in op.TaskInventory)
+ {
+ if (item.Value.Name == sound)
+ {
+ soundID = item.Value.ItemID;
+ break;
+ }
+ }
+ }
+
+ List avatarts = m_parentGroup.Scene.GetAvatars();
+ foreach (ScenePresence p in avatarts)
+ {
+ // TODO: some filtering by distance of avatar
+ if (triggered)
+ {
+ p.ControllingClient.SendTriggeredSound(soundID, ownerID, objectID, parentID, regionHandle, position, (float)volume);
+ }
+ else
+ {
+ p.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)volume, flags);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Resizing/Scale
+
+ ///
+ ///
+ ///
+ ///
+ public void Resize(LLVector3 scale)
+ {
+ m_shape.Scale = scale;
+
+ ScheduleFullUpdate();
+ }
+
+ #endregion
+
+ public void UpdatePermissions(LLUUID AgentID, byte field, uint localID, uint mask, byte addRemTF)
+ {
+ bool set = addRemTF == 1;
+
+ // Are we the owner?
+ if (AgentID == OwnerID)
+ {
+ switch (field)
+ {
+ case 2:
+ OwnerMask = ApplyMask(OwnerMask, set, mask);
+ break;
+ case 4:
+ GroupMask = ApplyMask(GroupMask, set, mask);
+ break;
+ case 8:
+ EveryoneMask = ApplyMask(EveryoneMask, set, mask);
+ break;
+ case 16:
+ NextOwnerMask = ApplyMask(NextOwnerMask, set, mask);
+ break;
+ }
+ SendFullUpdateToAllClients();
+
+ SendObjectPropertiesToClient(AgentID);
+
+ }
+ }
+
+ private void SendObjectPropertiesToClient(LLUUID AgentID)
+ {
+ List avatars = m_parentGroup.GetScenePresences();
+ for (int i = 0; i < avatars.Count; i++)
+ {
+ // Ugly reference :(
+ if (avatars[i].UUID == AgentID)
+ {
+ m_parentGroup.GetProperties(avatars[i].ControllingClient);
+ }
+ }
+ }
+
+ private uint ApplyMask(uint val, bool set, uint mask)
+ {
+ if (set)
+ {
+ return val |= mask;
+ }
+ else
+ {
+ return val &= ~mask;
+ }
+ }
+
+ #region Client Update Methods
+
+ public void AddFullUpdateToAllAvatars()
+ {
+ List avatars = m_parentGroup.GetScenePresences();
+ for (int i = 0; i < avatars.Count; i++)
+ {
+ avatars[i].QueuePartForUpdate(this);
+ }
+ }
+ public void SendFullUpdateToAllClientsExcept(LLUUID agentID)
+ {
+ List avatars = m_parentGroup.GetScenePresences();
+ for (int i = 0; i < avatars.Count; i++)
+ {
+ // Ugly reference :(
+ if (avatars[i].UUID != agentID)
+ {
+ m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this,
+ avatars[i].GenerateClientFlags(UUID));
+ }
+ }
+ }
+ public void AddFullUpdateToAvatar(ScenePresence presence)
+ {
+ presence.QueuePartForUpdate(this);
+ }
+
+ ///
+ ///
+ ///
+ public void SendFullUpdateToAllClients()
+ {
+ List avatars = m_parentGroup.GetScenePresences();
+ for (int i = 0; i < avatars.Count; i++)
+ {
+ // Ugly reference :(
+ m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this,
+ avatars[i].GenerateClientFlags(UUID));
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
+ {
+ m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientflags)
+ {
+ LLVector3 lPos;
+ lPos = OffsetPosition;
+ SendFullUpdateToClient(remoteClient, lPos, clientflags);
+ }
+
+ public void SendAttachedUpdateToClient(IClientAPI remoteClient, LLVector3 lPos, uint clientFlags)
+ {
+ MainLog.Instance.Verbose("OBJECTPART", "Sending as attached object to " + remoteClient.FirstName + " " + remoteClient.LastName);
+ ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
+ objupdate.RegionData.RegionHandle = m_attachRegInfo.RegionHandle;
+ objupdate.RegionData.TimeDilation = 64096;
+ objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[2];
+
+ // avatar stuff - horrible group copypaste
+ objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock();
+ objupdate.ObjectData[0].PSBlock = new byte[0];
+ objupdate.ObjectData[0].ExtraParams = new byte[1];
+ objupdate.ObjectData[0].MediaURL = new byte[0];
+ objupdate.ObjectData[0].NameValue = new byte[0];
+ objupdate.ObjectData[0].Text = new byte[0];
+ objupdate.ObjectData[0].TextColor = new byte[4];
+ objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0);
+ objupdate.ObjectData[0].JointPivot = new LLVector3(0, 0, 0);
+ objupdate.ObjectData[0].Material = 4;
+ objupdate.ObjectData[0].TextureAnim = new byte[0];
+ objupdate.ObjectData[0].Sound = LLUUID.Zero;
+
+ objupdate.ObjectData[0].State = 0;
+ objupdate.ObjectData[0].Data = new byte[0];
+
+ objupdate.ObjectData[0].ObjectData = new byte[76];
+ objupdate.ObjectData[0].ObjectData[15] = 128;
+ objupdate.ObjectData[0].ObjectData[16] = 63;
+ objupdate.ObjectData[0].ObjectData[56] = 128;
+ objupdate.ObjectData[0].ObjectData[61] = 102;
+ objupdate.ObjectData[0].ObjectData[62] = 40;
+ objupdate.ObjectData[0].ObjectData[63] = 61;
+ objupdate.ObjectData[0].ObjectData[64] = 189;
+
+
+ objupdate.ObjectData[0].UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
+ objupdate.ObjectData[0].PathCurve = 16;
+ objupdate.ObjectData[0].ProfileCurve = 1;
+ objupdate.ObjectData[0].PathScaleX = 100;
+ objupdate.ObjectData[0].PathScaleY = 100;
+ objupdate.ObjectData[0].ParentID = 0;
+ objupdate.ObjectData[0].OwnerID = LLUUID.Zero;
+ objupdate.ObjectData[0].Scale = new LLVector3(1, 1, 1);
+ objupdate.ObjectData[0].PCode = 47;
+ objupdate.ObjectData[0].TextureEntry = ScenePresence.DefaultTexture;
+
+ objupdate.ObjectData[0].ID = m_attachPresence.LocalId;
+ objupdate.ObjectData[0].FullID = m_attachAgentId;
+ objupdate.ObjectData[0].ParentID = 0;
+ objupdate.ObjectData[0].NameValue =
+ Helpers.StringToField("FirstName STRING RW SV " + m_attachPresence.Firstname + "\nLastName STRING RW SV " + m_attachPresence.Lastname);
+ LLVector3 pos2 = m_attachPresence.AbsolutePosition;
+ // new LLVector3((float) Pos.X, (float) Pos.Y, (float) Pos.Z);
+ byte[] pb = pos2.GetBytes();
+ Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
+
+
+ // primitive part
+ objupdate.ObjectData[1] = new ObjectUpdatePacket.ObjectDataBlock();
+ // SetDefaultPrimPacketValues
+ objupdate.ObjectData[1].PSBlock = new byte[0];
+ objupdate.ObjectData[1].ExtraParams = new byte[1];
+ objupdate.ObjectData[1].MediaURL = new byte[0];
+ objupdate.ObjectData[1].NameValue = new byte[0];
+ objupdate.ObjectData[1].Text = new byte[0];
+ objupdate.ObjectData[1].TextColor = new byte[4];
+ objupdate.ObjectData[1].JointAxisOrAnchor = new LLVector3(0, 0, 0);
+ objupdate.ObjectData[1].JointPivot = new LLVector3(0, 0, 0);
+ objupdate.ObjectData[1].Material = 3;
+ objupdate.ObjectData[1].TextureAnim = new byte[0];
+ objupdate.ObjectData[1].Sound = LLUUID.Zero;
+ objupdate.ObjectData[1].State = 0;
+ objupdate.ObjectData[1].Data = new byte[0];
+
+ objupdate.ObjectData[1].ObjectData = new byte[60];
+ objupdate.ObjectData[1].ObjectData[46] = 128;
+ objupdate.ObjectData[1].ObjectData[47] = 63;
+
+ // SetPrimPacketShapeData
+ PrimitiveBaseShape primData = Shape;
+
+ objupdate.ObjectData[1].TextureEntry = primData.TextureEntry;
+ objupdate.ObjectData[1].PCode = primData.PCode;
+ objupdate.ObjectData[1].State = (byte)(((byte)m_attachPt) << 4);
+ objupdate.ObjectData[1].PathBegin = primData.PathBegin;
+ objupdate.ObjectData[1].PathEnd = primData.PathEnd;
+ objupdate.ObjectData[1].PathScaleX = primData.PathScaleX;
+ objupdate.ObjectData[1].PathScaleY = primData.PathScaleY;
+ objupdate.ObjectData[1].PathShearX = primData.PathShearX;
+ objupdate.ObjectData[1].PathShearY = primData.PathShearY;
+ objupdate.ObjectData[1].PathSkew = primData.PathSkew;
+ objupdate.ObjectData[1].ProfileBegin = primData.ProfileBegin;
+ objupdate.ObjectData[1].ProfileEnd = primData.ProfileEnd;
+ objupdate.ObjectData[1].Scale = primData.Scale;
+ objupdate.ObjectData[1].PathCurve = primData.PathCurve;
+ objupdate.ObjectData[1].ProfileCurve = primData.ProfileCurve;
+ objupdate.ObjectData[1].ProfileHollow = primData.ProfileHollow;
+ objupdate.ObjectData[1].PathRadiusOffset = primData.PathRadiusOffset;
+ objupdate.ObjectData[1].PathRevolutions = primData.PathRevolutions;
+ objupdate.ObjectData[1].PathTaperX = primData.PathTaperX;
+ objupdate.ObjectData[1].PathTaperY = primData.PathTaperY;
+ objupdate.ObjectData[1].PathTwist = primData.PathTwist;
+ objupdate.ObjectData[1].PathTwistBegin = primData.PathTwistBegin;
+ objupdate.ObjectData[1].ExtraParams = primData.ExtraParams;
+
+ objupdate.ObjectData[1].UpdateFlags = 276957500; // flags; // ??
+ objupdate.ObjectData[1].ID = LocalID;
+ objupdate.ObjectData[1].FullID = UUID;
+ objupdate.ObjectData[1].OwnerID = OwnerID;
+ objupdate.ObjectData[1].Text = Helpers.StringToField(Text);
+ objupdate.ObjectData[1].TextColor[0] = 255;
+ objupdate.ObjectData[1].TextColor[1] = 255;
+ objupdate.ObjectData[1].TextColor[2] = 255;
+ objupdate.ObjectData[1].TextColor[3] = 128;
+ objupdate.ObjectData[1].ParentID = objupdate.ObjectData[0].ID;
+ //objupdate.ObjectData[1].PSBlock = particleSystem;
+ //objupdate.ObjectData[1].ClickAction = clickAction;
+ objupdate.ObjectData[1].Radius = 20;
+ objupdate.ObjectData[1].NameValue =
+ Helpers.StringToField("AttachItemID STRING RW SV " + UUID);
+ LLVector3 pos = new LLVector3((float)0.0, (float)0.0, (float)0.0);
+
+ pb = pos.GetBytes();
+ Array.Copy(pb, 0, objupdate.ObjectData[1].ObjectData, 0, pb.Length);
+
+ byte[] brot = m_attachRot.GetBytes();
+ Array.Copy(brot, 0, objupdate.ObjectData[1].ObjectData, 36, brot.Length);
+
+ remoteClient.OutPacket(objupdate, ThrottleOutPacketType.Task);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SendFullUpdateToClient(IClientAPI remoteClient, LLVector3 lPos, uint clientFlags)
+ {
+ if (m_attachPresence != null)
+ {
+ SendAttachedUpdateToClient(remoteClient, lPos, clientFlags);
+ return;
+ }
+
+ LLQuaternion lRot;
+ lRot = RotationOffset;
+ clientFlags &= ~(uint) LLObject.ObjectFlags.CreateSelected;
+
+ if (remoteClient.AgentId == OwnerID)
+ {
+ if ((uint) (Flags & LLObject.ObjectFlags.CreateSelected) != 0)
+ {
+ clientFlags |= (uint) LLObject.ObjectFlags.CreateSelected;
+ Flags &= ~LLObject.ObjectFlags.CreateSelected;
+ }
+ }
+
+
+ byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A};
+ remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalID, m_shape, lPos, clientFlags, m_uuid,
+ OwnerID,
+ m_text, color, ParentID, m_particleSystem, lRot, m_clickAction, m_TextureAnimation);
+ }
+
+ /// Terse updates
+ public void AddTerseUpdateToAllAvatars()
+ {
+ List avatars = m_parentGroup.GetScenePresences();
+ for (int i = 0; i < avatars.Count; i++)
+ {
+ avatars[i].QueuePartForUpdate(this);
+ }
+ }
+
+ public void AddTerseUpdateToAvatar(ScenePresence presence)
+ {
+ presence.QueuePartForUpdate(this);
+ }
+
+ ///
+ ///
+ ///
+ public void SendTerseUpdateToAllClients()
+ {
+ List avatars = m_parentGroup.GetScenePresences();
+ for (int i = 0; i < avatars.Count; i++)
+ {
+ m_parentGroup.SendPartTerseUpdate(avatars[i].ControllingClient, this);
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void SendTerseUpdate(IClientAPI remoteClient)
+ {
+ m_parentGroup.SendPartTerseUpdate(remoteClient, this);
+ }
+
+ public void SendTerseUpdateToClient(IClientAPI remoteClient)
+ {
+ LLVector3 lPos;
+ lPos = OffsetPosition;
+ LLQuaternion mRot = RotationOffset;
+ if ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0)
+ {
+ remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalID, lPos, mRot);
+ }
+ else
+ {
+ remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalID, lPos, mRot, Velocity,
+ RotationalVelocity);
+ //System.Console.WriteLine("LID: " + LocalID + " RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString());
+ }
+ }
+
+ public void SendTerseUpdateToClient(IClientAPI remoteClient, LLVector3 lPos)
+ {
+ LLQuaternion mRot = RotationOffset;
+ if ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0)
+ {
+ remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalID, lPos, mRot);
+ }
+ else
+ {
+ remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalID, lPos, mRot, Velocity,
+ RotationalVelocity);
+ //System.Console.WriteLine("LID: " + LocalID + "RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString());
+ }
+ }
+
+ #endregion
+
+ public virtual void UpdateMovement()
+ {
+ }
+
+ #region Events
+
+ public void PhysicsRequestingTerseUpdate()
+ {
+ if (PhysActor != null)
+ {
+ LLVector3 newpos = new LLVector3(PhysActor.Position.GetBytes(), 0);
+ if (newpos.X > 257f || newpos.X < -1f || newpos.Y > 257f || newpos.Y < -1f)
+ {
+ m_parentGroup.AbsolutePosition = newpos;
+ return;
+ }
+
+ }
+ ScheduleTerseUpdate();
+
+ //SendTerseUpdateToAllClients();
+ }
+
+ #endregion
+
+ public void PhysicsOutOfBounds(PhysicsVector pos)
+ {
+ m_log.Info("[PHYSICS]: Physical Object went out of bounds.");
+ RemFlag(LLObject.ObjectFlags.Physics);
+ DoPhysicsPropertyUpdate(false, true);
+ m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
+ }
+
+ public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient)
+ {
+ }
+
+ public void SetText(string text, Vector3 color, double alpha)
+ {
+ Color = Color.FromArgb(0xff - (int) (alpha*0xff),
+ (int) (color.x*0xff),
+ (int) (color.y*0xff),
+ (int) (color.z*0xff));
+ Text = text;
+ }
+ }
+}