diff options
author | Sean Dague | 2008-06-27 19:21:15 +0000 |
---|---|---|
committer | Sean Dague | 2008-06-27 19:21:15 +0000 |
commit | 333b741e30a494dfae5a22c2fd48d6a891d48847 (patch) | |
tree | 97f16c237df3225f359c58117ad293f316330131 /OpenSim/Region/Environment | |
parent | Mantis#1615. Thank you, Matth for a patch that: (diff) | |
download | opensim-SC_OLD-333b741e30a494dfae5a22c2fd48d6a891d48847.zip opensim-SC_OLD-333b741e30a494dfae5a22c2fd48d6a891d48847.tar.gz opensim-SC_OLD-333b741e30a494dfae5a22c2fd48d6a891d48847.tar.bz2 opensim-SC_OLD-333b741e30a494dfae5a22c2fd48d6a891d48847.tar.xz |
run NArrange on SOP to stack together the attributes,
properties, private methods, public methods, etc.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneObjectPart.cs | 3785 |
1 files changed, 1866 insertions, 1919 deletions
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index af535cc..d7aa962 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs | |||
@@ -1,3 +1,5 @@ | |||
1 | #region Header | ||
2 | |||
1 | /* | 3 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 4 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 5 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
@@ -25,6 +27,8 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 28 | */ |
27 | 29 | ||
30 | #endregion Header | ||
31 | |||
28 | using System; | 32 | using System; |
29 | using System.Collections.Generic; | 33 | using System.Collections.Generic; |
30 | using System.Drawing; | 34 | using System.Drawing; |
@@ -32,15 +36,33 @@ using System.Runtime.Serialization; | |||
32 | using System.Security.Permissions; | 36 | using System.Security.Permissions; |
33 | using System.Xml; | 37 | using System.Xml; |
34 | using System.Xml.Serialization; | 38 | using System.Xml.Serialization; |
39 | |||
35 | using Axiom.Math; | 40 | using Axiom.Math; |
41 | |||
36 | using libsecondlife; | 42 | using libsecondlife; |
37 | using libsecondlife.Packets; | 43 | using libsecondlife.Packets; |
44 | |||
38 | using OpenSim.Framework; | 45 | using OpenSim.Framework; |
39 | using OpenSim.Region.Environment.Scenes.Scripting; | 46 | using OpenSim.Region.Environment.Scenes.Scripting; |
40 | using OpenSim.Region.Physics.Manager; | 47 | using OpenSim.Region.Physics.Manager; |
41 | 48 | ||
42 | namespace OpenSim.Region.Environment.Scenes | 49 | namespace OpenSim.Region.Environment.Scenes |
43 | { | 50 | { |
51 | #region Enumerations | ||
52 | |||
53 | [Flags] | ||
54 | public enum Changed : uint | ||
55 | { | ||
56 | INVENTORY = 1, | ||
57 | COLOR = 2, | ||
58 | SHAPE = 4, | ||
59 | SCALE = 8, | ||
60 | TEXTURE = 16, | ||
61 | LINK = 32, | ||
62 | ALLOWED_DROP = 64, | ||
63 | OWNER = 128 | ||
64 | } | ||
65 | |||
44 | // I don't really know where to put this except here. | 66 | // I don't really know where to put this except here. |
45 | // Can't access the OpenSim.Region.ScriptEngine.Common.LSL_BaseClass.Changed constants | 67 | // Can't access the OpenSim.Region.ScriptEngine.Common.LSL_BaseClass.Changed constants |
46 | [Flags] | 68 | [Flags] |
@@ -56,18 +78,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
56 | Something5 = 64, | 78 | Something5 = 64, |
57 | Something6 = 128 | 79 | Something6 = 128 |
58 | } | 80 | } |
59 | [Flags] | 81 | |
60 | public enum Changed : uint | ||
61 | { | ||
62 | INVENTORY = 1, | ||
63 | COLOR = 2, | ||
64 | SHAPE = 4, | ||
65 | SCALE = 8, | ||
66 | TEXTURE = 16, | ||
67 | LINK = 32, | ||
68 | ALLOWED_DROP = 64, | ||
69 | OWNER = 128 | ||
70 | } | ||
71 | [Flags] | 82 | [Flags] |
72 | public enum TextureAnimFlags : byte | 83 | public enum TextureAnimFlags : byte |
73 | { | 84 | { |
@@ -81,74 +92,96 @@ namespace OpenSim.Region.Environment.Scenes | |||
81 | SCALE = 0x40 | 92 | SCALE = 0x40 |
82 | } | 93 | } |
83 | 94 | ||
95 | #endregion Enumerations | ||
84 | 96 | ||
85 | [Serializable] | 97 | [Serializable] |
86 | public partial class SceneObjectPart : IScriptHost, ISerializable | 98 | public partial class SceneObjectPart : IScriptHost, ISerializable |
87 | { | 99 | { |
88 | [XmlIgnore] public PhysicsActor PhysActor = null; | 100 | #region Fields |
89 | 101 | ||
102 | [XmlIgnore] | ||
103 | public bool AllowedDrop = false; | ||
104 | public uint BaseMask = (uint)PermissionMask.All; | ||
105 | public uint Category; | ||
106 | public Int32 CreationDate; | ||
107 | public LLUUID CreatorID; | ||
108 | [XmlIgnore] | ||
109 | public bool DIE_AT_EDGE = false; | ||
110 | public uint EveryoneMask = (uint)PermissionMask.None; | ||
111 | public LLObject.ObjectFlags Flags = LLObject.ObjectFlags.None; | ||
112 | public LLUUID GroupID; | ||
113 | public uint GroupMask = (uint)PermissionMask.None; | ||
90 | public LLUUID LastOwnerID; | 114 | public LLUUID LastOwnerID; |
115 | public uint NextOwnerMask = (uint)PermissionMask.All; | ||
116 | public byte ObjectSaleType; | ||
91 | public LLUUID OwnerID; | 117 | public LLUUID OwnerID; |
92 | public LLUUID GroupID; | 118 | public uint OwnerMask = (uint)PermissionMask.All; |
93 | public int OwnershipCost; | 119 | public int OwnershipCost; |
94 | public byte ObjectSaleType; | 120 | public uint ParentID = 0; |
95 | public int SalePrice; | ||
96 | public uint Category; | ||
97 | 121 | ||
98 | // TODO: This needs to be persisted in next XML version update! | 122 | // TODO: This needs to be persisted in next XML version update! |
99 | [XmlIgnore] public int[] PayPrice = {-2,-2,-2,-2,-2}; | 123 | [XmlIgnore] |
100 | [XmlIgnore] public bool AllowedDrop = false; | 124 | public int[] PayPrice = {-2,-2,-2,-2,-2}; |
101 | [XmlIgnore] private Dictionary<LLUUID, scriptEvents> m_scriptEvents = new Dictionary<LLUUID, scriptEvents>(); | 125 | [XmlIgnore] |
102 | [XmlIgnore] public scriptEvents m_aggregateScriptEvents=0; | 126 | public PhysicsActor PhysActor = null; |
103 | [XmlIgnore] private LLObject.ObjectFlags LocalFlags = LLObject.ObjectFlags.None; | 127 | public int SalePrice; |
104 | [XmlIgnore] public bool DIE_AT_EDGE = false; | ||
105 | [XmlIgnore] private int m_scriptAccessPin = 0; | ||
106 | |||
107 | [XmlIgnore] public bool m_IsAttachment = false; | ||
108 | [XmlIgnore] public uint m_attachmentPoint = (byte)0; | ||
109 | [XmlIgnore] public LLUUID m_attachedAvatar = LLUUID.Zero; | ||
110 | [XmlIgnore] public LLVector3 m_attachedPos = LLVector3.Zero; | ||
111 | [XmlIgnore] public LLUUID fromAssetID = LLUUID.Zero; | ||
112 | |||
113 | [XmlIgnore] public bool m_undoing = false; | ||
114 | 128 | ||
115 | public Int32 CreationDate; | 129 | //Xantor 20080528 Sound stuff: |
116 | public uint ParentID = 0; | 130 | // Note: This isn't persisted in the database right now, as the fields for that aren't just there yet. |
131 | // Not a big problem as long as the script that sets it remains in the prim on startup. | ||
132 | // for SL compatibility it should be persisted though (set sound / displaytext / particlesystem, kill script) | ||
133 | [XmlIgnore] | ||
134 | public LLUUID Sound; | ||
135 | [XmlIgnore] | ||
136 | public byte SoundFlags; | ||
137 | [XmlIgnore] | ||
138 | public double SoundGain; | ||
139 | [XmlIgnore] | ||
140 | public double SoundRadius; | ||
141 | [XmlIgnore] | ||
142 | public uint TimeStampFull = 0; | ||
143 | [XmlIgnore] | ||
144 | public uint TimeStampLastActivity = 0; // Will be used for AutoReturn | ||
145 | [XmlIgnore] | ||
146 | public uint TimeStampTerse = 0; | ||
147 | [XmlIgnore] | ||
148 | public LLUUID fromAssetID = LLUUID.Zero; | ||
149 | [XmlIgnore] | ||
150 | public bool m_IsAttachment = false; | ||
151 | [XmlIgnore] | ||
152 | public scriptEvents m_aggregateScriptEvents = 0; | ||
153 | [XmlIgnore] | ||
154 | public LLUUID m_attachedAvatar = LLUUID.Zero; | ||
155 | [XmlIgnore] | ||
156 | public LLVector3 m_attachedPos = LLVector3.Zero; | ||
157 | [XmlIgnore] | ||
158 | public uint m_attachmentPoint = (byte)0; | ||
159 | [XmlIgnore] | ||
160 | public PhysicsVector m_rotationAxis = new PhysicsVector(1f,1f,1f); | ||
161 | public LLUUID m_sitTargetAvatar = LLUUID.Zero; | ||
162 | [XmlIgnore] | ||
163 | public bool m_undoing = false; | ||
117 | 164 | ||
165 | [XmlIgnore] | ||
166 | private LLObject.ObjectFlags LocalFlags = LLObject.ObjectFlags.None; | ||
167 | private byte[] m_TextureAnimation; | ||
168 | private byte m_clickAction = 0; | ||
169 | private Color m_color = Color.Black; | ||
170 | private string m_description = String.Empty; | ||
118 | private List<uint> m_lastColliders = new List<uint>(); | 171 | private List<uint> m_lastColliders = new List<uint>(); |
119 | |||
120 | private PhysicsVector m_lastRotationalVelocity = PhysicsVector.Zero; | 172 | private PhysicsVector m_lastRotationalVelocity = PhysicsVector.Zero; |
121 | private Vector3 m_sitTargetPosition = new Vector3(0, 0, 0); | 173 | private int m_linkNum = 0; |
174 | [XmlIgnore] | ||
175 | private int m_scriptAccessPin = 0; | ||
176 | [XmlIgnore] | ||
177 | private Dictionary<LLUUID, scriptEvents> m_scriptEvents = new Dictionary<LLUUID, scriptEvents>(); | ||
178 | private string m_sitName = String.Empty; | ||
122 | private Quaternion m_sitTargetOrientation = new Quaternion(0, 0, 0, 1); | 179 | private Quaternion m_sitTargetOrientation = new Quaternion(0, 0, 0, 1); |
123 | public LLUUID m_sitTargetAvatar = LLUUID.Zero; | 180 | private Vector3 m_sitTargetPosition = new Vector3(0, 0, 0); |
124 | [XmlIgnore] public PhysicsVector m_rotationAxis = new PhysicsVector(1f,1f,1f); | 181 | private string m_text = String.Empty; |
125 | 182 | private string m_touchName = String.Empty; | |
126 | #region Permissions | ||
127 | |||
128 | public uint BaseMask = (uint)PermissionMask.All; | ||
129 | public uint OwnerMask = (uint)PermissionMask.All; | ||
130 | public uint GroupMask = (uint)PermissionMask.None; | ||
131 | public uint EveryoneMask = (uint)PermissionMask.None; | ||
132 | public uint NextOwnerMask = (uint)PermissionMask.All; | ||
133 | |||
134 | private UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); | 183 | private UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); |
135 | 184 | ||
136 | public LLObject.ObjectFlags Flags = LLObject.ObjectFlags.None; | ||
137 | |||
138 | public uint ObjectFlags | ||
139 | { | ||
140 | get { return (uint)Flags; } | ||
141 | set { Flags = (LLObject.ObjectFlags)value; } | ||
142 | } | ||
143 | |||
144 | #endregion | ||
145 | |||
146 | protected byte[] m_particleSystem = new byte[0]; | ||
147 | |||
148 | [XmlIgnore] public uint TimeStampFull = 0; | ||
149 | [XmlIgnore] public uint TimeStampTerse = 0; | ||
150 | [XmlIgnore] public uint TimeStampLastActivity = 0; // Will be used for AutoReturn | ||
151 | |||
152 | /// <summary> | 185 | /// <summary> |
153 | /// Only used internally to schedule client updates. | 186 | /// Only used internally to schedule client updates. |
154 | /// 0 - no update is scheduled | 187 | /// 0 - no update is scheduled |
@@ -159,174 +192,213 @@ namespace OpenSim.Region.Environment.Scenes | |||
159 | /// </summary> | 192 | /// </summary> |
160 | private byte m_updateFlag; | 193 | private byte m_updateFlag; |
161 | 194 | ||
162 | #region Properties | 195 | protected LLVector3 m_acceleration; |
163 | 196 | protected LLVector3 m_angularVelocity; | |
164 | public LLUUID CreatorID; | ||
165 | 197 | ||
166 | public LLUUID ObjectCreator | 198 | //unkown if this will be kept, added as a way of removing the group position from the group class |
167 | { | 199 | protected LLVector3 m_groupPosition; |
168 | get { return CreatorID; } | 200 | protected uint m_localId; |
169 | } | 201 | protected LLObject.MaterialType m_material = 0; |
202 | protected string m_name; | ||
203 | protected LLVector3 m_offsetPosition; | ||
170 | 204 | ||
205 | // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out. | ||
206 | protected SceneObjectGroup m_parentGroup; | ||
207 | protected byte[] m_particleSystem = new byte[0]; | ||
208 | protected ulong m_regionHandle; | ||
209 | protected LLQuaternion m_rotationOffset; | ||
210 | protected LLVector3 m_rotationalvelocity; | ||
211 | protected PrimitiveBaseShape m_shape; | ||
171 | protected LLUUID m_uuid; | 212 | protected LLUUID m_uuid; |
213 | protected LLVector3 m_velocity; | ||
172 | 214 | ||
173 | public LLUUID UUID | 215 | #endregion Fields |
174 | { | ||
175 | get { return m_uuid; } | ||
176 | set { m_uuid = value; } | ||
177 | } | ||
178 | 216 | ||
179 | protected uint m_localId; | 217 | #region Constructors |
180 | 218 | ||
181 | public uint LocalId | 219 | /// <summary> |
220 | /// No arg constructor called by region restore db code | ||
221 | /// </summary> | ||
222 | public SceneObjectPart() | ||
182 | { | 223 | { |
183 | get { return m_localId; } | 224 | // It's not necessary to persist this |
184 | set { m_localId = value; } | 225 | m_TextureAnimation = new byte[0]; |
185 | } | 226 | } |
186 | 227 | ||
187 | protected string m_name; | 228 | public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID, |
188 | 229 | PrimitiveBaseShape shape, LLVector3 groupPosition, LLVector3 offsetPosition) | |
189 | public virtual string Name | 230 | : this(regionHandle, parent, ownerID, localID, shape, groupPosition, LLQuaternion.Identity, offsetPosition) |
190 | { | 231 | { |
191 | get { return m_name; } | ||
192 | set { m_name = value; } | ||
193 | } | 232 | } |
194 | 233 | ||
195 | public scriptEvents ScriptEvents | 234 | /// <summary> |
235 | /// Create a completely new SceneObjectPart (prim) | ||
236 | /// </summary> | ||
237 | /// <param name="regionHandle"></param> | ||
238 | /// <param name="parent"></param> | ||
239 | /// <param name="ownerID"></param> | ||
240 | /// <param name="localID"></param> | ||
241 | /// <param name="shape"></param> | ||
242 | /// <param name="position"></param> | ||
243 | public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID, | ||
244 | PrimitiveBaseShape shape, LLVector3 groupPosition, LLQuaternion rotationOffset, | ||
245 | LLVector3 offsetPosition) | ||
196 | { | 246 | { |
197 | get { return m_aggregateScriptEvents; } | 247 | m_name = "Primitive"; |
198 | } | 248 | m_regionHandle = regionHandle; |
199 | 249 | m_parentGroup = parent; | |
200 | protected LLObject.MaterialType m_material = 0; | ||
201 | 250 | ||
202 | public byte Material | 251 | CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; |
203 | { | 252 | OwnerID = ownerID; |
204 | get { return (byte) m_material; } | 253 | CreatorID = OwnerID; |
205 | set { m_material = (LLObject.MaterialType) value; } | 254 | LastOwnerID = LLUUID.Zero; |
206 | } | 255 | UUID = LLUUID.Random(); |
256 | LocalId = (uint) (localID); | ||
257 | Shape = shape; | ||
258 | // Todo: Add More Object Parameter from above! | ||
259 | OwnershipCost = 0; | ||
260 | ObjectSaleType = (byte) 0; | ||
261 | SalePrice = 0; | ||
262 | Category = (uint) 0; | ||
263 | LastOwnerID = CreatorID; | ||
264 | // End Todo: /// | ||
265 | GroupPosition = groupPosition; | ||
266 | OffsetPosition = offsetPosition; | ||
267 | RotationOffset = rotationOffset; | ||
268 | Velocity = new LLVector3(0, 0, 0); | ||
269 | m_rotationalvelocity = new LLVector3(0, 0, 0); | ||
270 | AngularVelocity = new LLVector3(0, 0, 0); | ||
271 | Acceleration = new LLVector3(0, 0, 0); | ||
272 | m_TextureAnimation = new byte[0]; | ||
207 | 273 | ||
208 | protected ulong m_regionHandle; | 274 | // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, |
275 | // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from | ||
276 | // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log | ||
209 | 277 | ||
210 | public ulong RegionHandle | 278 | Flags = 0; |
211 | { | 279 | Flags |= LLObject.ObjectFlags.CreateSelected; |
212 | get { return m_regionHandle; } | ||
213 | set { m_regionHandle = value; } | ||
214 | } | ||
215 | |||
216 | public int ScriptAccessPin | ||
217 | { | ||
218 | get { return m_scriptAccessPin; } | ||
219 | set { m_scriptAccessPin = (int)value; } | ||
220 | } | ||
221 | 280 | ||
222 | public uint GetEffectiveObjectFlags() | 281 | TrimPermissions(); |
223 | { | 282 | //m_undo = new UndoStack<UndoState>(ParentGroup.GetSceneMaxUndo()); |
224 | LLObject.ObjectFlags f = Flags; | ||
225 | if (m_parentGroup == null || m_parentGroup.RootPart == this) | ||
226 | f &= ~(LLObject.ObjectFlags.Touch | LLObject.ObjectFlags.Money); | ||
227 | 283 | ||
228 | return (uint)Flags | (uint)LocalFlags; | 284 | ScheduleFullUpdate(); |
229 | } | 285 | } |
230 | 286 | ||
231 | //unkown if this will be kept, added as a way of removing the group position from the group class | ||
232 | protected LLVector3 m_groupPosition; | ||
233 | |||
234 | /// <summary> | 287 | /// <summary> |
235 | /// Method for a prim to get it's world position from the group. | 288 | /// Re/create a SceneObjectPart (prim) |
236 | /// Remember, the Group Position simply gives the position of the group itself | 289 | /// currently not used, and maybe won't be |
237 | /// </summary> | 290 | /// </summary> |
238 | /// <returns>A Linked Child Prim objects position in world</returns> | 291 | /// <param name="regionHandle"></param> |
239 | public LLVector3 GetWorldPosition() | 292 | /// <param name="parent"></param> |
293 | /// <param name="ownerID"></param> | ||
294 | /// <param name="localID"></param> | ||
295 | /// <param name="shape"></param> | ||
296 | /// <param name="position"></param> | ||
297 | public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, int creationDate, LLUUID ownerID, | ||
298 | LLUUID creatorID, LLUUID lastOwnerID, uint localID, PrimitiveBaseShape shape, | ||
299 | LLVector3 position, LLQuaternion rotation, uint flags) | ||
240 | { | 300 | { |
301 | m_regionHandle = regionHandle; | ||
302 | m_parentGroup = parent; | ||
303 | TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); | ||
304 | CreationDate = creationDate; | ||
305 | OwnerID = ownerID; | ||
306 | CreatorID = creatorID; | ||
307 | LastOwnerID = lastOwnerID; | ||
308 | UUID = LLUUID.Random(); | ||
309 | LocalId = (uint) (localID); | ||
310 | Shape = shape; | ||
311 | OwnershipCost = 0; | ||
312 | ObjectSaleType = (byte) 0; | ||
313 | SalePrice = 0; | ||
314 | Category = (uint) 0; | ||
315 | LastOwnerID = CreatorID; | ||
316 | OffsetPosition = position; | ||
317 | RotationOffset = rotation; | ||
318 | ObjectFlags = flags; | ||
241 | 319 | ||
242 | Quaternion parentRot = new Quaternion( | 320 | // Since we don't store script state, this is only a 'temporary' objectflag now |
243 | ParentGroup.RootPart.RotationOffset.W, | 321 | // If the object is scripted, the script will get loaded and this will be set again |
244 | ParentGroup.RootPart.RotationOffset.X, | 322 | ObjectFlags &= ~(uint)(LLObject.ObjectFlags.Scripted | LLObject.ObjectFlags.Touch); |
245 | ParentGroup.RootPart.RotationOffset.Y, | ||
246 | ParentGroup.RootPart.RotationOffset.Z); | ||
247 | |||
248 | Vector3 axPos | ||
249 | = new Vector3( | ||
250 | OffsetPosition.X, | ||
251 | OffsetPosition.Y, | ||
252 | OffsetPosition.Z); | ||
253 | 323 | ||
254 | axPos = parentRot * axPos; | 324 | TrimPermissions(); |
255 | LLVector3 translationOffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); | 325 | // ApplyPhysics(); |
256 | return GroupPosition + translationOffsetPosition; | ||
257 | 326 | ||
258 | //return (new LLVector3(axiomPos.x, axiomPos.y, axiomPos.z) + AbsolutePosition); | 327 | ScheduleFullUpdate(); |
259 | } | 328 | } |
260 | 329 | ||
261 | /// <summary> | 330 | protected SceneObjectPart(SerializationInfo info, StreamingContext context) |
262 | /// Gets the rotation of this prim offset by the group rotation | ||
263 | /// </summary> | ||
264 | /// <returns></returns> | ||
265 | public LLQuaternion GetWorldRotation() | ||
266 | { | 331 | { |
332 | //System.Console.WriteLine("SceneObjectPart Deserialize BGN"); | ||
267 | 333 | ||
268 | Quaternion newRot; | 334 | if (info == null) |
269 | |||
270 | if (this.LinkNum == 0) | ||
271 | { | 335 | { |
272 | newRot = new Quaternion(RotationOffset.W,RotationOffset.X,RotationOffset.Y,RotationOffset.Z); | 336 | throw new ArgumentNullException("info"); |
273 | |||
274 | } | 337 | } |
275 | else | ||
276 | { | ||
277 | Quaternion parentRot = new Quaternion( | ||
278 | ParentGroup.RootPart.RotationOffset.W, | ||
279 | ParentGroup.RootPart.RotationOffset.X, | ||
280 | ParentGroup.RootPart.RotationOffset.Y, | ||
281 | ParentGroup.RootPart.RotationOffset.Z); | ||
282 | 338 | ||
283 | Quaternion oldRot | 339 | /* |
284 | = new Quaternion( | 340 | m_queue = (Queue<SceneObjectPart>)info.GetValue("m_queue", typeof(Queue<SceneObjectPart>)); |
285 | RotationOffset.W, | 341 | m_ids = (List<LLUUID>)info.GetValue("m_ids", typeof(List<LLUUID>)); |
286 | RotationOffset.X, | 342 | */ |
287 | RotationOffset.Y, | ||
288 | RotationOffset.Z); | ||
289 | 343 | ||
290 | newRot = parentRot * oldRot; | 344 | //System.Console.WriteLine("SceneObjectPart Deserialize END"); |
291 | } | 345 | } |
292 | return new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w); | ||
293 | 346 | ||
294 | //return new LLQuaternion(axiomPartRotation.x, axiomPartRotation.y, axiomPartRotation.z, axiomPartRotation.w); | 347 | #endregion Constructors |
348 | |||
349 | #region Public Properties | ||
350 | |||
351 | public LLVector3 AbsolutePosition | ||
352 | { | ||
353 | get { | ||
354 | if (m_IsAttachment) | ||
355 | return GroupPosition; | ||
295 | 356 | ||
357 | return m_offsetPosition + m_groupPosition; } | ||
296 | } | 358 | } |
297 | 359 | ||
298 | public void StoreUndoState() | 360 | /// <summary></summary> |
361 | public LLVector3 Acceleration | ||
299 | { | 362 | { |
300 | if (!m_undoing) | 363 | get { return m_acceleration; } |
301 | { | 364 | set { m_acceleration = value; } |
302 | if (m_parentGroup != null) | 365 | } |
303 | { | ||
304 | if (m_undo.Count > 0) | ||
305 | { | ||
306 | UndoState last = m_undo.Peek(); | ||
307 | if (last != null) | ||
308 | { | ||
309 | if (last.Compare(this)) | ||
310 | return; | ||
311 | } | ||
312 | } | ||
313 | 366 | ||
367 | /// <summary></summary> | ||
368 | public LLVector3 AngularVelocity | ||
369 | { | ||
370 | get { return m_angularVelocity; } | ||
371 | set { m_angularVelocity = value; } | ||
372 | } | ||
314 | 373 | ||
315 | if (m_parentGroup.GetSceneMaxUndo() > 0) | 374 | public byte ClickAction |
316 | { | 375 | { |
317 | UndoState nUndo = new UndoState(this); | 376 | get { return m_clickAction; } |
377 | set | ||
378 | { | ||
379 | m_clickAction = value; | ||
380 | } | ||
381 | } | ||
318 | 382 | ||
319 | m_undo.Push(nUndo); | 383 | public Color Color |
384 | { | ||
385 | get { return m_color; } | ||
386 | set | ||
387 | { | ||
388 | m_color = value; | ||
389 | TriggerScriptChangedEvent(Changed.COLOR); | ||
320 | 390 | ||
321 | } | 391 | /* ScheduleFullUpdate() need not be called b/c after |
322 | } | 392 | * setting the color, the text will be set, so then |
393 | * ScheduleFullUpdate() will be called. */ | ||
394 | //ScheduleFullUpdate(); | ||
323 | } | 395 | } |
324 | } | 396 | } |
325 | 397 | ||
326 | public void ClearUndoState() | 398 | public string Description |
327 | { | 399 | { |
328 | m_undo.Clear(); | 400 | get { return m_description; } |
329 | StoreUndoState(); | 401 | set { m_description = value; } |
330 | } | 402 | } |
331 | 403 | ||
332 | public LLVector3 GroupPosition | 404 | public LLVector3 GroupPosition |
@@ -391,9 +463,50 @@ namespace OpenSim.Region.Environment.Scenes | |||
391 | } | 463 | } |
392 | } | 464 | } |
393 | 465 | ||
394 | private byte[] m_TextureAnimation; | 466 | public int LinkNum |
467 | { | ||
468 | get { return m_linkNum; } | ||
469 | set | ||
470 | { | ||
471 | m_linkNum = value; | ||
472 | TriggerScriptChangedEvent(Changed.LINK); | ||
395 | 473 | ||
396 | protected LLVector3 m_offsetPosition; | 474 | } |
475 | } | ||
476 | |||
477 | public uint LocalId | ||
478 | { | ||
479 | get { return m_localId; } | ||
480 | set { m_localId = value; } | ||
481 | } | ||
482 | |||
483 | public byte Material | ||
484 | { | ||
485 | get { return (byte) m_material; } | ||
486 | set { m_material = (LLObject.MaterialType) value; } | ||
487 | } | ||
488 | |||
489 | public virtual string Name | ||
490 | { | ||
491 | get { return m_name; } | ||
492 | set { m_name = value; } | ||
493 | } | ||
494 | |||
495 | public LLUUID ObjectCreator | ||
496 | { | ||
497 | get { return CreatorID; } | ||
498 | } | ||
499 | |||
500 | public uint ObjectFlags | ||
501 | { | ||
502 | get { return (uint)Flags; } | ||
503 | set { Flags = (LLObject.ObjectFlags)value; } | ||
504 | } | ||
505 | |||
506 | public LLUUID ObjectOwner | ||
507 | { | ||
508 | get { return OwnerID; } | ||
509 | } | ||
397 | 510 | ||
398 | public LLVector3 OffsetPosition | 511 | public LLVector3 OffsetPosition |
399 | { | 512 | { |
@@ -416,16 +529,16 @@ namespace OpenSim.Region.Environment.Scenes | |||
416 | } | 529 | } |
417 | } | 530 | } |
418 | 531 | ||
419 | public LLVector3 AbsolutePosition | 532 | public SceneObjectGroup ParentGroup |
420 | { | 533 | { |
421 | get { | 534 | get { return m_parentGroup; } |
422 | if (m_IsAttachment) | ||
423 | return GroupPosition; | ||
424 | |||
425 | return m_offsetPosition + m_groupPosition; } | ||
426 | } | 535 | } |
427 | 536 | ||
428 | protected LLQuaternion m_rotationOffset; | 537 | public ulong RegionHandle |
538 | { | ||
539 | get { return m_regionHandle; } | ||
540 | set { m_regionHandle = value; } | ||
541 | } | ||
429 | 542 | ||
430 | public LLQuaternion RotationOffset | 543 | public LLQuaternion RotationOffset |
431 | { | 544 | { |
@@ -479,11 +592,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
479 | } | 592 | } |
480 | } | 593 | } |
481 | 594 | ||
482 | protected LLVector3 m_velocity; | 595 | public LLVector3 RotationalVelocity |
483 | protected LLVector3 m_rotationalvelocity; | ||
484 | |||
485 | /// <summary></summary> | ||
486 | public LLVector3 Velocity | ||
487 | { | 596 | { |
488 | get | 597 | get |
489 | { | 598 | { |
@@ -494,103 +603,86 @@ namespace OpenSim.Region.Environment.Scenes | |||
494 | { | 603 | { |
495 | if (PhysActor.IsPhysical) | 604 | if (PhysActor.IsPhysical) |
496 | { | 605 | { |
497 | m_velocity.X = PhysActor.Velocity.X; | 606 | m_rotationalvelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(),0); |
498 | m_velocity.Y = PhysActor.Velocity.Y; | ||
499 | m_velocity.Z = PhysActor.Velocity.Z; | ||
500 | } | 607 | } |
501 | } | 608 | } |
502 | 609 | ||
503 | return m_velocity; | 610 | return m_rotationalvelocity; |
504 | } | ||
505 | |||
506 | set | ||
507 | { | ||
508 | m_velocity = value; | ||
509 | if (PhysActor != null) | ||
510 | { | ||
511 | if (PhysActor.IsPhysical) | ||
512 | { | ||
513 | PhysActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z); | ||
514 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
515 | } | ||
516 | } | ||
517 | } | 611 | } |
612 | set { m_rotationalvelocity = value; } | ||
518 | } | 613 | } |
519 | 614 | ||
520 | public LLVector3 RotationalVelocity | 615 | public LLVector3 Scale |
521 | { | 616 | { |
522 | get | 617 | get { return m_shape.Scale; } |
618 | set | ||
523 | { | 619 | { |
524 | //if (PhysActor.Velocity.x != 0 || PhysActor.Velocity.y != 0 | 620 | StoreUndoState(); |
525 | //|| PhysActor.Velocity.z != 0) | 621 | m_shape.Scale = value; |
526 | //{ | 622 | |
527 | if (PhysActor != null) | 623 | if (PhysActor != null && m_parentGroup != null) |
528 | { | 624 | { |
529 | if (PhysActor.IsPhysical) | 625 | if (m_parentGroup.Scene != null) |
530 | { | 626 | { |
531 | m_rotationalvelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(),0); | 627 | if (m_parentGroup.Scene.PhysicsScene != null) |
628 | { | ||
629 | PhysActor.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); | ||
630 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
631 | } | ||
532 | } | 632 | } |
533 | } | 633 | } |
534 | 634 | TriggerScriptChangedEvent(Changed.SCALE); | |
535 | return m_rotationalvelocity; | ||
536 | } | 635 | } |
537 | set { m_rotationalvelocity = value; } | ||
538 | } | ||
539 | |||
540 | |||
541 | protected LLVector3 m_angularVelocity; | ||
542 | |||
543 | /// <summary></summary> | ||
544 | public LLVector3 AngularVelocity | ||
545 | { | ||
546 | get { return m_angularVelocity; } | ||
547 | set { m_angularVelocity = value; } | ||
548 | } | 636 | } |
549 | 637 | ||
550 | protected LLVector3 m_acceleration; | 638 | public int ScriptAccessPin |
551 | |||
552 | /// <summary></summary> | ||
553 | public LLVector3 Acceleration | ||
554 | { | 639 | { |
555 | get { return m_acceleration; } | 640 | get { return m_scriptAccessPin; } |
556 | set { m_acceleration = value; } | 641 | set { m_scriptAccessPin = (int)value; } |
557 | } | 642 | } |
558 | 643 | ||
559 | private string m_description = String.Empty; | 644 | public scriptEvents ScriptEvents |
560 | |||
561 | public string Description | ||
562 | { | 645 | { |
563 | get { return m_description; } | 646 | get { return m_aggregateScriptEvents; } |
564 | set { m_description = value; } | ||
565 | } | 647 | } |
566 | 648 | ||
567 | private Color m_color = Color.Black; | 649 | public PrimitiveBaseShape Shape |
568 | |||
569 | public Color Color | ||
570 | { | 650 | { |
571 | get { return m_color; } | 651 | get { return m_shape; } |
572 | set | 652 | set |
573 | { | 653 | { |
574 | m_color = value; | 654 | m_shape = value; |
575 | TriggerScriptChangedEvent(Changed.COLOR); | 655 | TriggerScriptChangedEvent(Changed.SHAPE); |
576 | |||
577 | /* ScheduleFullUpdate() need not be called b/c after | ||
578 | * setting the color, the text will be set, so then | ||
579 | * ScheduleFullUpdate() will be called. */ | ||
580 | //ScheduleFullUpdate(); | ||
581 | } | 656 | } |
582 | } | 657 | } |
583 | 658 | ||
584 | private string m_text = String.Empty; | 659 | public string SitName |
660 | { | ||
661 | get { return m_sitName; } | ||
662 | set { m_sitName = value; } | ||
663 | } | ||
664 | |||
665 | public Quaternion SitTargetOrientation | ||
666 | { | ||
667 | get { return m_sitTargetOrientation; } | ||
668 | } | ||
585 | 669 | ||
586 | public Vector3 SitTargetPosition | 670 | public Vector3 SitTargetPosition |
587 | { | 671 | { |
588 | get { return m_sitTargetPosition; } | 672 | get { return m_sitTargetPosition; } |
589 | } | 673 | } |
590 | 674 | ||
591 | public Quaternion SitTargetOrientation | 675 | public bool Stopped |
592 | { | 676 | { |
593 | get { return m_sitTargetOrientation; } | 677 | get { |
678 | double threshold = 0.02; | ||
679 | return (Math.Abs(Velocity.X) < threshold && | ||
680 | Math.Abs(Velocity.Y) < threshold && | ||
681 | Math.Abs(Velocity.Z) < threshold && | ||
682 | Math.Abs(AngularVelocity.X) < threshold && | ||
683 | Math.Abs(AngularVelocity.Y) < threshold && | ||
684 | Math.Abs(AngularVelocity.Z) < threshold); | ||
685 | } | ||
594 | } | 686 | } |
595 | 687 | ||
596 | public string Text | 688 | public string Text |
@@ -610,61 +702,209 @@ namespace OpenSim.Region.Environment.Scenes | |||
610 | } | 702 | } |
611 | } | 703 | } |
612 | 704 | ||
613 | //Xantor 20080528 Sound stuff: | 705 | public string TouchName |
614 | // Note: This isn't persisted in the database right now, as the fields for that aren't just there yet. | 706 | { |
615 | // Not a big problem as long as the script that sets it remains in the prim on startup. | 707 | get { return m_touchName; } |
616 | // for SL compatibility it should be persisted though (set sound / displaytext / particlesystem, kill script) | 708 | set { m_touchName = value; } |
617 | [XmlIgnore] | 709 | } |
618 | public LLUUID Sound; | ||
619 | [XmlIgnore] | ||
620 | public byte SoundFlags; | ||
621 | [XmlIgnore] | ||
622 | public double SoundGain; | ||
623 | [XmlIgnore] | ||
624 | public double SoundRadius; | ||
625 | 710 | ||
711 | public LLUUID UUID | ||
712 | { | ||
713 | get { return m_uuid; } | ||
714 | set { m_uuid = value; } | ||
715 | } | ||
626 | 716 | ||
627 | private string m_sitName = String.Empty; | 717 | public byte UpdateFlag |
718 | { | ||
719 | get { return m_updateFlag; } | ||
720 | set { m_updateFlag = value; } | ||
721 | } | ||
628 | 722 | ||
629 | public string SitName | 723 | /// <summary></summary> |
724 | public LLVector3 Velocity | ||
630 | { | 725 | { |
631 | get { return m_sitName; } | 726 | get |
632 | set { m_sitName = value; } | 727 | { |
728 | //if (PhysActor.Velocity.x != 0 || PhysActor.Velocity.y != 0 | ||
729 | //|| PhysActor.Velocity.z != 0) | ||
730 | //{ | ||
731 | if (PhysActor != null) | ||
732 | { | ||
733 | if (PhysActor.IsPhysical) | ||
734 | { | ||
735 | m_velocity.X = PhysActor.Velocity.X; | ||
736 | m_velocity.Y = PhysActor.Velocity.Y; | ||
737 | m_velocity.Z = PhysActor.Velocity.Z; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | return m_velocity; | ||
742 | } | ||
743 | |||
744 | set | ||
745 | { | ||
746 | m_velocity = value; | ||
747 | if (PhysActor != null) | ||
748 | { | ||
749 | if (PhysActor.IsPhysical) | ||
750 | { | ||
751 | PhysActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z); | ||
752 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
753 | } | ||
754 | } | ||
755 | } | ||
633 | } | 756 | } |
634 | 757 | ||
635 | private string m_touchName = String.Empty; | 758 | #endregion Public Properties |
636 | 759 | ||
637 | public string TouchName | 760 | #region Private Methods |
761 | |||
762 | private uint ApplyMask(uint val, bool set, uint mask) | ||
638 | { | 763 | { |
639 | get { return m_touchName; } | 764 | if (set) |
640 | set { m_touchName = value; } | 765 | { |
766 | return val |= mask; | ||
767 | } | ||
768 | else | ||
769 | { | ||
770 | return val &= ~mask; | ||
771 | } | ||
641 | } | 772 | } |
642 | 773 | ||
643 | private int m_linkNum = 0; | 774 | /// <summary> |
775 | /// Clear all pending updates | ||
776 | /// </summary> | ||
777 | private void ClearUpdateSchedule() | ||
778 | { | ||
779 | m_updateFlag = 0; | ||
780 | } | ||
644 | 781 | ||
645 | public int LinkNum | 782 | private void SendObjectPropertiesToClient(LLUUID AgentID) |
646 | { | 783 | { |
647 | get { return m_linkNum; } | 784 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); |
648 | set | 785 | for (int i = 0; i < avatars.Count; i++) |
649 | { | 786 | { |
650 | m_linkNum = value; | 787 | // Ugly reference :( |
651 | TriggerScriptChangedEvent(Changed.LINK); | 788 | if (avatars[i].UUID == AgentID) |
789 | { | ||
790 | m_parentGroup.GetProperties(avatars[i].ControllingClient); | ||
791 | } | ||
792 | } | ||
793 | } | ||
794 | |||
795 | private void handleTimerAccounting(uint localID, double interval) | ||
796 | { | ||
797 | if (localID == LocalId) | ||
798 | { | ||
799 | |||
800 | float sec = (float)interval; | ||
801 | if (m_parentGroup != null) | ||
802 | { | ||
803 | if (sec == 0) | ||
804 | { | ||
805 | if (m_parentGroup.scriptScore + 0.001f >= float.MaxValue - 0.001) | ||
806 | m_parentGroup.scriptScore = 0; | ||
807 | |||
808 | m_parentGroup.scriptScore += 0.001f; | ||
809 | return; | ||
810 | } | ||
811 | |||
812 | if (m_parentGroup.scriptScore + (0.001f / sec) >= float.MaxValue - (0.001f / sec)) | ||
813 | m_parentGroup.scriptScore = 0; | ||
814 | m_parentGroup.scriptScore += (0.001f / sec); | ||
815 | } | ||
652 | 816 | ||
653 | } | 817 | } |
654 | } | 818 | } |
655 | 819 | ||
656 | private byte m_clickAction = 0; | 820 | #endregion Private Methods |
657 | 821 | ||
658 | public byte ClickAction | 822 | #region Public Methods |
823 | |||
824 | public void AddFlag(LLObject.ObjectFlags flag) | ||
659 | { | 825 | { |
660 | get { return m_clickAction; } | 826 | LLObject.ObjectFlags prevflag = Flags; |
661 | set | 827 | //uint objflags = Flags; |
828 | if ((ObjectFlags & (uint) flag) == 0) | ||
662 | { | 829 | { |
663 | m_clickAction = value; | 830 | //Console.WriteLine("Adding flag: " + ((LLObject.ObjectFlags) flag).ToString()); |
831 | Flags |= flag; | ||
664 | } | 832 | } |
833 | //uint currflag = (uint)Flags; | ||
834 | //System.Console.WriteLine("Aprev: " + prevflag.ToString() + " curr: " + Flags.ToString()); | ||
835 | //ScheduleFullUpdate(); | ||
665 | } | 836 | } |
666 | 837 | ||
667 | protected PrimitiveBaseShape m_shape; | 838 | /// <summary> |
839 | /// Tell all scene presences that they should send updates for this part to their clients | ||
840 | /// </summary> | ||
841 | public void AddFullUpdateToAllAvatars() | ||
842 | { | ||
843 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); | ||
844 | for (int i = 0; i < avatars.Count; i++) | ||
845 | { | ||
846 | avatars[i].QueuePartForUpdate(this); | ||
847 | } | ||
848 | } | ||
849 | |||
850 | public void AddFullUpdateToAvatar(ScenePresence presence) | ||
851 | { | ||
852 | presence.QueuePartForUpdate(this); | ||
853 | } | ||
854 | |||
855 | public void AddNewParticleSystem(Primitive.ParticleSystem pSystem) | ||
856 | { | ||
857 | m_particleSystem = pSystem.GetBytes(); | ||
858 | } | ||
859 | |||
860 | /// Terse updates | ||
861 | public void AddTerseUpdateToAllAvatars() | ||
862 | { | ||
863 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); | ||
864 | for (int i = 0; i < avatars.Count; i++) | ||
865 | { | ||
866 | avatars[i].QueuePartForUpdate(this); | ||
867 | } | ||
868 | } | ||
869 | |||
870 | public void AddTerseUpdateToAvatar(ScenePresence presence) | ||
871 | { | ||
872 | presence.QueuePartForUpdate(this); | ||
873 | } | ||
874 | |||
875 | public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) | ||
876 | { | ||
877 | byte[] data = new byte[16]; | ||
878 | int pos = 0; | ||
879 | |||
880 | // The flags don't like conversion from uint to byte, so we have to do | ||
881 | // it the crappy way. See the above function :( | ||
882 | |||
883 | data[pos] = ConvertScriptUintToByte(pTexAnim.Flags); pos++; | ||
884 | data[pos] = (byte)pTexAnim.Face; pos++; | ||
885 | data[pos] = (byte)pTexAnim.SizeX; pos++; | ||
886 | data[pos] = (byte)pTexAnim.SizeY; pos++; | ||
887 | |||
888 | Helpers.FloatToBytes(pTexAnim.Start).CopyTo(data, pos); | ||
889 | Helpers.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4); | ||
890 | Helpers.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8); | ||
891 | |||
892 | m_TextureAnimation = data; | ||
893 | } | ||
894 | |||
895 | public void AdjustSoundGain(double volume) | ||
896 | { | ||
897 | if (volume > 1) | ||
898 | volume = 1; | ||
899 | if (volume < 0) | ||
900 | volume = 0; | ||
901 | |||
902 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); | ||
903 | foreach (ScenePresence p in avatarts) | ||
904 | { | ||
905 | p.ControllingClient.SendAttachedSoundGainChange(UUID, (float)volume); | ||
906 | } | ||
907 | } | ||
668 | 908 | ||
669 | /// <summary> | 909 | /// <summary> |
670 | /// hook to the physics scene to apply impulse | 910 | /// hook to the physics scene to apply impulse |
@@ -697,283 +937,1316 @@ namespace OpenSim.Region.Environment.Scenes | |||
697 | } | 937 | } |
698 | } | 938 | } |
699 | 939 | ||
700 | public void MoveToTarget(LLVector3 target, float tau) | 940 | /// <summary> |
941 | /// Apply physics to this part. | ||
942 | /// </summary> | ||
943 | /// <param name="rootObjectFlags"></param> | ||
944 | /// <param name="m_physicalPrim"></param> | ||
945 | public void ApplyPhysics(uint rootObjectFlags, bool m_physicalPrim) | ||
701 | { | 946 | { |
702 | if (tau > 0) | 947 | bool isPhysical = (((rootObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0) && m_physicalPrim); |
948 | bool isPhantom = ((rootObjectFlags & (uint) LLObject.ObjectFlags.Phantom) != 0); | ||
949 | |||
950 | // Added clarification.. since A rigid body is an object that you can kick around, etc. | ||
951 | bool RigidBody = isPhysical && !isPhantom; | ||
952 | |||
953 | // The only time the physics scene shouldn't know about the prim is if it's phantom | ||
954 | if (!isPhantom) | ||
703 | { | 955 | { |
704 | m_parentGroup.moveToTarget(target, tau); | 956 | PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( |
957 | Name, | ||
958 | Shape, | ||
959 | new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y, | ||
960 | AbsolutePosition.Z), | ||
961 | new PhysicsVector(Scale.X, Scale.Y, Scale.Z), | ||
962 | new Quaternion(RotationOffset.W, RotationOffset.X, | ||
963 | RotationOffset.Y, RotationOffset.Z), RigidBody); | ||
964 | |||
965 | // Basic Physics returns null.. joy joy joy. | ||
966 | if (PhysActor != null) | ||
967 | { | ||
968 | PhysActor.LocalID = LocalId; | ||
969 | DoPhysicsPropertyUpdate(RigidBody, true); | ||
970 | } | ||
971 | } | ||
972 | } | ||
973 | |||
974 | public void ClearUndoState() | ||
975 | { | ||
976 | m_undo.Clear(); | ||
977 | StoreUndoState(); | ||
978 | } | ||
979 | |||
980 | public byte ConvertScriptUintToByte(uint indata) | ||
981 | { | ||
982 | byte outdata = (byte)TextureAnimFlags.NONE; | ||
983 | if ((indata & 1) != 0) outdata |= (byte)TextureAnimFlags.ANIM_ON; | ||
984 | if ((indata & 2) != 0) outdata |= (byte)TextureAnimFlags.LOOP; | ||
985 | if ((indata & 4) != 0) outdata |= (byte)TextureAnimFlags.REVERSE; | ||
986 | if ((indata & 8) != 0) outdata |= (byte)TextureAnimFlags.PING_PONG; | ||
987 | if ((indata & 16) != 0) outdata |= (byte)TextureAnimFlags.SMOOTH; | ||
988 | if ((indata & 32) != 0) outdata |= (byte)TextureAnimFlags.ROTATE; | ||
989 | if ((indata & 64) != 0) outdata |= (byte)TextureAnimFlags.SCALE; | ||
990 | return outdata; | ||
991 | } | ||
992 | |||
993 | /// <summary> | ||
994 | /// Duplicates this part. | ||
995 | /// </summary> | ||
996 | /// <returns></returns> | ||
997 | public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID, int linkNum, bool userExposed) | ||
998 | { | ||
999 | SceneObjectPart dupe = (SceneObjectPart) MemberwiseClone(); | ||
1000 | dupe.m_shape = m_shape.Copy(); | ||
1001 | dupe.m_regionHandle = m_regionHandle; | ||
1002 | if (userExposed) | ||
1003 | dupe.UUID = LLUUID.Random(); | ||
1004 | |||
1005 | dupe.LocalId = localID; | ||
1006 | dupe.OwnerID = AgentID; | ||
1007 | dupe.GroupID = GroupID; | ||
1008 | dupe.GroupPosition = new LLVector3(GroupPosition.X, GroupPosition.Y, GroupPosition.Z); | ||
1009 | dupe.OffsetPosition = new LLVector3(OffsetPosition.X, OffsetPosition.Y, OffsetPosition.Z); | ||
1010 | dupe.RotationOffset = | ||
1011 | new LLQuaternion(RotationOffset.X, RotationOffset.Y, RotationOffset.Z, RotationOffset.W); | ||
1012 | dupe.Velocity = new LLVector3(0, 0, 0); | ||
1013 | dupe.Acceleration = new LLVector3(0, 0, 0); | ||
1014 | dupe.AngularVelocity = new LLVector3(0, 0, 0); | ||
1015 | dupe.ObjectFlags = ObjectFlags; | ||
1016 | |||
1017 | dupe.OwnershipCost = OwnershipCost; | ||
1018 | dupe.ObjectSaleType = ObjectSaleType; | ||
1019 | dupe.SalePrice = SalePrice; | ||
1020 | dupe.Category = Category; | ||
1021 | |||
1022 | dupe.TaskInventory = (TaskInventoryDictionary)dupe.TaskInventory.Clone(); | ||
1023 | |||
1024 | if (userExposed) | ||
1025 | dupe.ResetIDs(linkNum); | ||
1026 | |||
1027 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. | ||
1028 | dupe.LastOwnerID = ObjectOwner; | ||
1029 | |||
1030 | byte[] extraP = new byte[Shape.ExtraParams.Length]; | ||
1031 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); | ||
1032 | dupe.Shape.ExtraParams = extraP; | ||
1033 | |||
1034 | if (userExposed) | ||
1035 | { | ||
1036 | if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != LLUUID.Zero) | ||
1037 | { | ||
1038 | m_parentGroup.Scene.AssetCache.GetAsset(dupe.m_shape.SculptTexture, dupe.SculptTextureCallback, true); | ||
1039 | } | ||
1040 | bool UsePhysics = ((dupe.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0); | ||
1041 | dupe.DoPhysicsPropertyUpdate(UsePhysics, true); | ||
1042 | } | ||
1043 | return dupe; | ||
1044 | } | ||
1045 | |||
1046 | public static SceneObjectPart Create() | ||
1047 | { | ||
1048 | SceneObjectPart part = new SceneObjectPart(); | ||
1049 | part.UUID = LLUUID.Random(); | ||
1050 | |||
1051 | PrimitiveBaseShape shape = PrimitiveBaseShape.Create(); | ||
1052 | part.Shape = shape; | ||
1053 | |||
1054 | part.Name = "Primitive"; | ||
1055 | part.OwnerID = LLUUID.Random(); | ||
1056 | |||
1057 | return part; | ||
1058 | } | ||
1059 | |||
1060 | public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) | ||
1061 | { | ||
1062 | if (PhysActor != null) | ||
1063 | { | ||
1064 | if (UsePhysics != PhysActor.IsPhysical || isNew) | ||
1065 | { | ||
1066 | if (PhysActor.IsPhysical) | ||
1067 | { | ||
1068 | if (!isNew) | ||
1069 | ParentGroup.Scene.RemovePhysicalPrim(1); | ||
1070 | |||
1071 | PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; | ||
1072 | PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; | ||
1073 | PhysActor.delink(); | ||
1074 | } | ||
1075 | |||
1076 | PhysActor.IsPhysical = UsePhysics; | ||
1077 | |||
1078 | |||
1079 | // If we're not what we're supposed to be in the physics scene, recreate ourselves. | ||
1080 | //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); | ||
1081 | /// that's not wholesome. Had to make Scene public | ||
1082 | //PhysActor = null; | ||
1083 | |||
1084 | if ((ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) == 0) | ||
1085 | { | ||
1086 | //PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( | ||
1087 | //Name, | ||
1088 | //Shape, | ||
1089 | //new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y, | ||
1090 | //AbsolutePosition.Z), | ||
1091 | //new PhysicsVector(Scale.X, Scale.Y, Scale.Z), | ||
1092 | //new Quaternion(RotationOffset.W, RotationOffset.X, | ||
1093 | //RotationOffset.Y, RotationOffset.Z), UsePhysics); | ||
1094 | if (UsePhysics) | ||
1095 | { | ||
1096 | ParentGroup.Scene.AddPhysicalPrim(1); | ||
1097 | |||
1098 | PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; | ||
1099 | PhysActor.OnOutOfBounds += PhysicsOutOfBounds; | ||
1100 | if (ParentID != 0 && ParentID != LocalId) | ||
1101 | { | ||
1102 | if (ParentGroup.RootPart.PhysActor != null) | ||
1103 | { | ||
1104 | PhysActor.link(ParentGroup.RootPart.PhysActor); | ||
1105 | } | ||
1106 | } | ||
1107 | } | ||
1108 | } | ||
1109 | } | ||
1110 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | /// <summary> | ||
1115 | /// Restore this part from the serialized xml representation. | ||
1116 | /// </summary> | ||
1117 | /// <param name="xmlreader"></param> | ||
1118 | /// <returns></returns> | ||
1119 | public static SceneObjectPart FromXml(XmlReader xmlReader) | ||
1120 | { | ||
1121 | // It's not necessary to persist this | ||
1122 | |||
1123 | XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart)); | ||
1124 | SceneObjectPart newobject = (SceneObjectPart) serializer.Deserialize(xmlReader); | ||
1125 | return newobject; | ||
1126 | } | ||
1127 | |||
1128 | public LLUUID GetAvatarOnSitTarget() | ||
1129 | { | ||
1130 | return m_sitTargetAvatar; | ||
1131 | } | ||
1132 | |||
1133 | public bool GetDieAtEdge() | ||
1134 | { | ||
1135 | if (m_parentGroup == null) | ||
1136 | return false; | ||
1137 | if (m_parentGroup.RootPart == null) | ||
1138 | return false; | ||
1139 | |||
1140 | return m_parentGroup.RootPart.DIE_AT_EDGE; | ||
1141 | } | ||
1142 | |||
1143 | public double GetDistanceTo(Vector3 a, Vector3 b) | ||
1144 | { | ||
1145 | float dx = a.x - b.x; | ||
1146 | float dy = a.y - b.y; | ||
1147 | float dz = a.z - b.z; | ||
1148 | return Math.Sqrt(dx * dx + dy * dy + dz * dz); | ||
1149 | } | ||
1150 | |||
1151 | public uint GetEffectiveObjectFlags() | ||
1152 | { | ||
1153 | LLObject.ObjectFlags f = Flags; | ||
1154 | if (m_parentGroup == null || m_parentGroup.RootPart == this) | ||
1155 | f &= ~(LLObject.ObjectFlags.Touch | LLObject.ObjectFlags.Money); | ||
1156 | |||
1157 | return (uint)Flags | (uint)LocalFlags; | ||
1158 | } | ||
1159 | |||
1160 | public LLVector3 GetGeometricCenter() | ||
1161 | { | ||
1162 | if (PhysActor != null) | ||
1163 | { | ||
1164 | return new LLVector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); | ||
705 | } | 1165 | } |
706 | else | 1166 | else |
707 | { | 1167 | { |
708 | StopMoveToTarget(); | 1168 | return new LLVector3(0, 0, 0); |
709 | } | 1169 | } |
1170 | } | ||
710 | 1171 | ||
1172 | public float GetMass() | ||
1173 | { | ||
1174 | if (PhysActor != null) | ||
1175 | { | ||
1176 | return PhysActor.Mass; | ||
1177 | } | ||
1178 | else | ||
1179 | { | ||
1180 | return 0; | ||
1181 | } | ||
711 | } | 1182 | } |
712 | 1183 | ||
713 | public void StopMoveToTarget() | 1184 | [SecurityPermission(SecurityAction.LinkDemand, |
1185 | Flags = SecurityPermissionFlag.SerializationFormatter)] | ||
1186 | public virtual void GetObjectData( | ||
1187 | SerializationInfo info, StreamingContext context) | ||
714 | { | 1188 | { |
715 | m_parentGroup.stopMoveToTarget(); | 1189 | if (info == null) |
1190 | { | ||
1191 | throw new ArgumentNullException("info"); | ||
1192 | } | ||
1193 | |||
1194 | info.AddValue("m_inventoryFileName", GetInventoryFileName()); | ||
1195 | info.AddValue("m_folderID", UUID); | ||
1196 | info.AddValue("PhysActor", PhysActor); | ||
1197 | |||
1198 | Dictionary<Guid, TaskInventoryItem> TaskInventory_work = new Dictionary<Guid, TaskInventoryItem>(); | ||
1199 | |||
1200 | foreach (LLUUID id in TaskInventory.Keys) | ||
1201 | { | ||
1202 | TaskInventory_work.Add(id.UUID, TaskInventory[id]); | ||
1203 | } | ||
1204 | |||
1205 | info.AddValue("TaskInventory", TaskInventory_work); | ||
1206 | |||
1207 | info.AddValue("LastOwnerID", LastOwnerID.UUID); | ||
1208 | info.AddValue("OwnerID", OwnerID.UUID); | ||
1209 | info.AddValue("GroupID", GroupID.UUID); | ||
1210 | |||
1211 | info.AddValue("OwnershipCost", OwnershipCost); | ||
1212 | info.AddValue("ObjectSaleType", ObjectSaleType); | ||
1213 | info.AddValue("SalePrice", SalePrice); | ||
1214 | info.AddValue("Category", Category); | ||
1215 | |||
1216 | info.AddValue("CreationDate", CreationDate); | ||
1217 | info.AddValue("ParentID", ParentID); | ||
1218 | |||
1219 | info.AddValue("OwnerMask", OwnerMask); | ||
1220 | info.AddValue("NextOwnerMask", NextOwnerMask); | ||
1221 | info.AddValue("GroupMask", GroupMask); | ||
1222 | info.AddValue("EveryoneMask", EveryoneMask); | ||
1223 | info.AddValue("BaseMask", BaseMask); | ||
1224 | |||
1225 | info.AddValue("m_particleSystem", m_particleSystem); | ||
1226 | |||
1227 | info.AddValue("TimeStampFull", TimeStampFull); | ||
1228 | info.AddValue("TimeStampTerse", TimeStampTerse); | ||
1229 | info.AddValue("TimeStampLastActivity", TimeStampLastActivity); | ||
1230 | |||
1231 | info.AddValue("m_updateFlag", m_updateFlag); | ||
1232 | info.AddValue("CreatorID", CreatorID.UUID); | ||
1233 | |||
1234 | info.AddValue("m_inventorySerial", m_inventorySerial); | ||
1235 | info.AddValue("m_uuid", m_uuid.UUID); | ||
1236 | info.AddValue("m_localID", m_localId); | ||
1237 | info.AddValue("m_name", m_name); | ||
1238 | info.AddValue("m_flags", Flags); | ||
1239 | info.AddValue("m_material", m_material); | ||
1240 | info.AddValue("m_regionHandle", m_regionHandle); | ||
1241 | |||
1242 | info.AddValue("m_groupPosition.X", m_groupPosition.X); | ||
1243 | info.AddValue("m_groupPosition.Y", m_groupPosition.Y); | ||
1244 | info.AddValue("m_groupPosition.Z", m_groupPosition.Z); | ||
1245 | |||
1246 | info.AddValue("m_offsetPosition.X", m_offsetPosition.X); | ||
1247 | info.AddValue("m_offsetPosition.Y", m_offsetPosition.Y); | ||
1248 | info.AddValue("m_offsetPosition.Z", m_offsetPosition.Z); | ||
1249 | |||
1250 | info.AddValue("m_rotationOffset.W", m_rotationOffset.W); | ||
1251 | info.AddValue("m_rotationOffset.X", m_rotationOffset.X); | ||
1252 | info.AddValue("m_rotationOffset.Y", m_rotationOffset.Y); | ||
1253 | info.AddValue("m_rotationOffset.Z", m_rotationOffset.Z); | ||
1254 | |||
1255 | info.AddValue("m_velocity.X", m_velocity.X); | ||
1256 | info.AddValue("m_velocity.Y", m_velocity.Y); | ||
1257 | info.AddValue("m_velocity.Z", m_velocity.Z); | ||
1258 | |||
1259 | info.AddValue("m_rotationalvelocity.X", m_rotationalvelocity.X); | ||
1260 | info.AddValue("m_rotationalvelocity.Y", m_rotationalvelocity.Y); | ||
1261 | info.AddValue("m_rotationalvelocity.Z", m_rotationalvelocity.Z); | ||
1262 | |||
1263 | info.AddValue("m_angularVelocity.X", m_angularVelocity.X); | ||
1264 | info.AddValue("m_angularVelocity.Y", m_angularVelocity.Y); | ||
1265 | info.AddValue("m_angularVelocity.Z", m_angularVelocity.Z); | ||
1266 | |||
1267 | info.AddValue("m_acceleration.X", m_acceleration.X); | ||
1268 | info.AddValue("m_acceleration.Y", m_acceleration.Y); | ||
1269 | info.AddValue("m_acceleration.Z", m_acceleration.Z); | ||
1270 | |||
1271 | info.AddValue("m_description", m_description); | ||
1272 | info.AddValue("m_color", m_color); | ||
1273 | info.AddValue("m_text", m_text); | ||
1274 | info.AddValue("m_sitName", m_sitName); | ||
1275 | info.AddValue("m_touchName", m_touchName); | ||
1276 | info.AddValue("m_clickAction", m_clickAction); | ||
1277 | info.AddValue("m_shape", m_shape); | ||
1278 | info.AddValue("m_parentGroup", m_parentGroup); | ||
1279 | info.AddValue("PayPrice", PayPrice); | ||
716 | } | 1280 | } |
717 | 1281 | ||
718 | public void TriggerScriptChangedEvent(Changed val) | 1282 | public void GetProperties(IClientAPI client) |
1283 | { | ||
1284 | client.SendObjectPropertiesReply(LLUUID.Zero, (ulong)CreationDate, CreatorID, LLUUID.Zero, LLUUID.Zero, | ||
1285 | GroupID, (short)InventorySerial, LastOwnerID, UUID, OwnerID, | ||
1286 | ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description, | ||
1287 | ParentGroup.RootPart.OwnerMask, ParentGroup.RootPart.NextOwnerMask, ParentGroup.RootPart.GroupMask, ParentGroup.RootPart.EveryoneMask, | ||
1288 | ParentGroup.RootPart.BaseMask); | ||
1289 | } | ||
1290 | |||
1291 | public LLUUID GetRootPartUUID() | ||
719 | { | 1292 | { |
720 | if (m_parentGroup != null) | 1293 | if (m_parentGroup != null) |
721 | { | 1294 | { |
722 | if (m_parentGroup.Scene != null) | 1295 | return m_parentGroup.UUID; |
723 | m_parentGroup.Scene.TriggerObjectChanged(LocalId, (uint)val); | ||
724 | } | 1296 | } |
1297 | return LLUUID.Zero; | ||
1298 | } | ||
725 | 1299 | ||
1300 | public Quaternion GetSitTargetOrientation() | ||
1301 | { | ||
1302 | return m_sitTargetOrientation; | ||
726 | } | 1303 | } |
727 | 1304 | ||
728 | public PrimitiveBaseShape Shape | 1305 | public LLQuaternion GetSitTargetOrientationLL() |
729 | { | 1306 | { |
730 | get { return m_shape; } | 1307 | return |
731 | set | 1308 | new LLQuaternion(m_sitTargetOrientation.x, m_sitTargetOrientation.y, m_sitTargetOrientation.z, |
1309 | m_sitTargetOrientation.w); | ||
1310 | } | ||
1311 | |||
1312 | public Vector3 GetSitTargetPosition() | ||
1313 | { | ||
1314 | return m_sitTargetPosition; | ||
1315 | } | ||
1316 | |||
1317 | public LLVector3 GetSitTargetPositionLL() | ||
1318 | { | ||
1319 | return new LLVector3(m_sitTargetPosition.x, m_sitTargetPosition.y, m_sitTargetPosition.z); | ||
1320 | } | ||
1321 | |||
1322 | /// <summary> | ||
1323 | /// Method for a prim to get it's world position from the group. | ||
1324 | /// Remember, the Group Position simply gives the position of the group itself | ||
1325 | /// </summary> | ||
1326 | /// <returns>A Linked Child Prim objects position in world</returns> | ||
1327 | public LLVector3 GetWorldPosition() | ||
1328 | { | ||
1329 | Quaternion parentRot = new Quaternion( | ||
1330 | ParentGroup.RootPart.RotationOffset.W, | ||
1331 | ParentGroup.RootPart.RotationOffset.X, | ||
1332 | ParentGroup.RootPart.RotationOffset.Y, | ||
1333 | ParentGroup.RootPart.RotationOffset.Z); | ||
1334 | |||
1335 | Vector3 axPos | ||
1336 | = new Vector3( | ||
1337 | OffsetPosition.X, | ||
1338 | OffsetPosition.Y, | ||
1339 | OffsetPosition.Z); | ||
1340 | |||
1341 | axPos = parentRot * axPos; | ||
1342 | LLVector3 translationOffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); | ||
1343 | return GroupPosition + translationOffsetPosition; | ||
1344 | |||
1345 | //return (new LLVector3(axiomPos.x, axiomPos.y, axiomPos.z) + AbsolutePosition); | ||
1346 | } | ||
1347 | |||
1348 | /// <summary> | ||
1349 | /// Gets the rotation of this prim offset by the group rotation | ||
1350 | /// </summary> | ||
1351 | /// <returns></returns> | ||
1352 | public LLQuaternion GetWorldRotation() | ||
1353 | { | ||
1354 | Quaternion newRot; | ||
1355 | |||
1356 | if (this.LinkNum == 0) | ||
732 | { | 1357 | { |
733 | m_shape = value; | 1358 | newRot = new Quaternion(RotationOffset.W,RotationOffset.X,RotationOffset.Y,RotationOffset.Z); |
734 | TriggerScriptChangedEvent(Changed.SHAPE); | 1359 | |
1360 | } | ||
1361 | else | ||
1362 | { | ||
1363 | Quaternion parentRot = new Quaternion( | ||
1364 | ParentGroup.RootPart.RotationOffset.W, | ||
1365 | ParentGroup.RootPart.RotationOffset.X, | ||
1366 | ParentGroup.RootPart.RotationOffset.Y, | ||
1367 | ParentGroup.RootPart.RotationOffset.Z); | ||
1368 | |||
1369 | Quaternion oldRot | ||
1370 | = new Quaternion( | ||
1371 | RotationOffset.W, | ||
1372 | RotationOffset.X, | ||
1373 | RotationOffset.Y, | ||
1374 | RotationOffset.Z); | ||
1375 | |||
1376 | newRot = parentRot * oldRot; | ||
735 | } | 1377 | } |
1378 | return new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w); | ||
1379 | |||
1380 | //return new LLQuaternion(axiomPartRotation.x, axiomPartRotation.y, axiomPartRotation.z, axiomPartRotation.w); | ||
736 | } | 1381 | } |
737 | 1382 | ||
738 | public LLVector3 Scale | 1383 | public void MoveToTarget(LLVector3 target, float tau) |
739 | { | 1384 | { |
740 | get { return m_shape.Scale; } | 1385 | if (tau > 0) |
741 | set | ||
742 | { | 1386 | { |
743 | StoreUndoState(); | 1387 | m_parentGroup.moveToTarget(target, tau); |
744 | m_shape.Scale = value; | 1388 | } |
1389 | else | ||
1390 | { | ||
1391 | StopMoveToTarget(); | ||
1392 | } | ||
1393 | } | ||
745 | 1394 | ||
746 | if (PhysActor != null && m_parentGroup != null) | 1395 | public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient) |
1396 | { | ||
1397 | } | ||
1398 | |||
1399 | public void PhysicsCollision(EventArgs e) | ||
1400 | { | ||
1401 | // single threaded here | ||
1402 | if (e == null) | ||
1403 | { | ||
1404 | return; | ||
1405 | } | ||
1406 | |||
1407 | CollisionEventUpdate a = (CollisionEventUpdate)e; | ||
1408 | Dictionary<uint, float> collissionswith = a.m_objCollisionList; | ||
1409 | List<uint> thisHitColliders = new List<uint>(); | ||
1410 | List<uint> endedColliders = new List<uint>(); | ||
1411 | List<uint> startedColliders = new List<uint>(); | ||
1412 | |||
1413 | // calculate things that started colliding this time | ||
1414 | // and build up list of colliders this time | ||
1415 | foreach (uint localid in collissionswith.Keys) | ||
1416 | { | ||
1417 | if (localid != 0) | ||
747 | { | 1418 | { |
748 | if (m_parentGroup.Scene != null) | 1419 | thisHitColliders.Add(localid); |
1420 | if (!m_lastColliders.Contains(localid)) | ||
749 | { | 1421 | { |
750 | if (m_parentGroup.Scene.PhysicsScene != null) | 1422 | startedColliders.Add(localid); |
1423 | } | ||
1424 | |||
1425 | //m_log.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); | ||
1426 | } | ||
1427 | } | ||
1428 | |||
1429 | // calculate things that ended colliding | ||
1430 | foreach (uint localID in m_lastColliders) | ||
1431 | { | ||
1432 | if (!thisHitColliders.Contains(localID)) | ||
1433 | { | ||
1434 | endedColliders.Add(localID); | ||
1435 | } | ||
1436 | } | ||
1437 | |||
1438 | //add the items that started colliding this time to the last colliders list. | ||
1439 | foreach (uint localID in startedColliders) | ||
1440 | { | ||
1441 | m_lastColliders.Add(localID); | ||
1442 | } | ||
1443 | // remove things that ended colliding from the last colliders list | ||
1444 | foreach (uint localID in endedColliders) | ||
1445 | { | ||
1446 | m_lastColliders.Remove(localID); | ||
1447 | } | ||
1448 | if (m_parentGroup == null) | ||
1449 | return; | ||
1450 | if (m_parentGroup.RootPart == null) | ||
1451 | return; | ||
1452 | |||
1453 | if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) | ||
1454 | { | ||
1455 | // do event notification | ||
1456 | if (startedColliders.Count > 0) | ||
1457 | { | ||
1458 | ColliderArgs StartCollidingMessage = new ColliderArgs(); | ||
1459 | List<DetectedObject> colliding = new List<DetectedObject>(); | ||
1460 | foreach (uint localId in startedColliders) | ||
1461 | { | ||
1462 | // always running this check because if the user deletes the object it would return a null reference. | ||
1463 | if (m_parentGroup == null) | ||
1464 | return; | ||
1465 | if (m_parentGroup.Scene == null) | ||
1466 | return; | ||
1467 | SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); | ||
1468 | if (obj != null) | ||
751 | { | 1469 | { |
752 | PhysActor.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); | 1470 | DetectedObject detobj = new DetectedObject(); |
753 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 1471 | detobj.keyUUID = obj.UUID; |
1472 | detobj.nameStr = obj.Name; | ||
1473 | detobj.ownerUUID = obj.OwnerID; | ||
1474 | detobj.posVector = obj.AbsolutePosition; | ||
1475 | detobj.rotQuat = obj.GetWorldRotation(); | ||
1476 | detobj.velVector = obj.Velocity; | ||
1477 | detobj.colliderType = 0; | ||
1478 | detobj.groupUUID = obj.GroupID; | ||
1479 | colliding.Add(detobj); | ||
754 | } | 1480 | } |
1481 | else | ||
1482 | { | ||
1483 | List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences(); | ||
1484 | if (avlist != null) | ||
1485 | { | ||
1486 | foreach (ScenePresence av in avlist) | ||
1487 | { | ||
1488 | if (av.LocalId == localId) | ||
1489 | { | ||
1490 | DetectedObject detobj = new DetectedObject(); | ||
1491 | detobj.keyUUID = av.UUID; | ||
1492 | detobj.nameStr = av.ControllingClient.Name; | ||
1493 | detobj.ownerUUID = av.UUID; | ||
1494 | detobj.posVector = av.AbsolutePosition; | ||
1495 | detobj.rotQuat = new LLQuaternion(av.Rotation.x, av.Rotation.y, av.Rotation.z, av.Rotation.w); | ||
1496 | detobj.velVector = av.Velocity; | ||
1497 | detobj.colliderType = 0; | ||
1498 | detobj.groupUUID = av.ControllingClient.ActiveGroupId; | ||
1499 | colliding.Add(detobj); | ||
1500 | } | ||
1501 | } | ||
1502 | } | ||
1503 | } | ||
1504 | } | ||
1505 | if (colliding.Count > 0) | ||
1506 | { | ||
1507 | StartCollidingMessage.Colliders = colliding; | ||
1508 | // always running this check because if the user deletes the object it would return a null reference. | ||
1509 | if (m_parentGroup == null) | ||
1510 | return; | ||
1511 | if (m_parentGroup.Scene == null) | ||
1512 | return; | ||
1513 | m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart(LocalId, StartCollidingMessage); | ||
755 | } | 1514 | } |
756 | } | 1515 | } |
757 | TriggerScriptChangedEvent(Changed.SCALE); | 1516 | } |
1517 | if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0) | ||
1518 | { | ||
1519 | if (m_lastColliders.Count > 0) | ||
1520 | { | ||
1521 | ColliderArgs CollidingMessage = new ColliderArgs(); | ||
1522 | List<DetectedObject> colliding = new List<DetectedObject>(); | ||
1523 | foreach (uint localId in m_lastColliders) | ||
1524 | { | ||
1525 | // always running this check because if the user deletes the object it would return a null reference. | ||
1526 | if (localId == 0) | ||
1527 | continue; | ||
1528 | |||
1529 | if (m_parentGroup == null) | ||
1530 | return; | ||
1531 | if (m_parentGroup.Scene == null) | ||
1532 | return; | ||
1533 | SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); | ||
1534 | if (obj != null) | ||
1535 | { | ||
1536 | DetectedObject detobj = new DetectedObject(); | ||
1537 | detobj.keyUUID = obj.UUID; | ||
1538 | detobj.nameStr = obj.Name; | ||
1539 | detobj.ownerUUID = obj.OwnerID; | ||
1540 | detobj.posVector = obj.AbsolutePosition; | ||
1541 | detobj.rotQuat = obj.GetWorldRotation(); | ||
1542 | detobj.velVector = obj.Velocity; | ||
1543 | detobj.colliderType = 0; | ||
1544 | detobj.groupUUID = obj.GroupID; | ||
1545 | colliding.Add(detobj); | ||
1546 | } | ||
1547 | else | ||
1548 | { | ||
1549 | List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences(); | ||
1550 | if (avlist != null) | ||
1551 | { | ||
1552 | foreach (ScenePresence av in avlist) | ||
1553 | { | ||
1554 | if (av.LocalId == localId) | ||
1555 | { | ||
1556 | DetectedObject detobj = new DetectedObject(); | ||
1557 | detobj.keyUUID = av.UUID; | ||
1558 | detobj.nameStr = av.Name; | ||
1559 | detobj.ownerUUID = av.UUID; | ||
1560 | detobj.posVector = av.AbsolutePosition; | ||
1561 | detobj.rotQuat = new LLQuaternion(av.Rotation.x, av.Rotation.y, av.Rotation.z, av.Rotation.w); | ||
1562 | detobj.velVector = av.Velocity; | ||
1563 | detobj.colliderType = 0; | ||
1564 | detobj.groupUUID = av.ControllingClient.ActiveGroupId; | ||
1565 | colliding.Add(detobj); | ||
1566 | } | ||
1567 | } | ||
1568 | |||
1569 | } | ||
1570 | } | ||
1571 | } | ||
1572 | if (colliding.Count > 0) | ||
1573 | { | ||
1574 | CollidingMessage.Colliders = colliding; | ||
1575 | // always running this check because if the user deletes the object it would return a null reference. | ||
1576 | if (m_parentGroup == null) | ||
1577 | return; | ||
1578 | if (m_parentGroup.Scene == null) | ||
1579 | return; | ||
1580 | m_parentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage); | ||
1581 | } | ||
1582 | |||
1583 | } | ||
1584 | } | ||
1585 | if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0) | ||
1586 | { | ||
1587 | if (endedColliders.Count > 0) | ||
1588 | { | ||
1589 | ColliderArgs EndCollidingMessage = new ColliderArgs(); | ||
1590 | List<DetectedObject> colliding = new List<DetectedObject>(); | ||
1591 | foreach (uint localId in endedColliders) | ||
1592 | { | ||
1593 | if (localId == 0) | ||
1594 | continue; | ||
1595 | |||
1596 | // always running this check because if the user deletes the object it would return a null reference. | ||
1597 | if (m_parentGroup == null) | ||
1598 | return; | ||
1599 | if (m_parentGroup.Scene == null) | ||
1600 | return; | ||
1601 | SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); | ||
1602 | if (obj != null) | ||
1603 | { | ||
1604 | DetectedObject detobj = new DetectedObject(); | ||
1605 | detobj.keyUUID = obj.UUID; | ||
1606 | detobj.nameStr = obj.Name; | ||
1607 | detobj.ownerUUID = obj.OwnerID; | ||
1608 | detobj.posVector = obj.AbsolutePosition; | ||
1609 | detobj.rotQuat = obj.GetWorldRotation(); | ||
1610 | detobj.velVector = obj.Velocity; | ||
1611 | detobj.colliderType = 0; | ||
1612 | detobj.groupUUID = obj.GroupID; | ||
1613 | colliding.Add(detobj); | ||
1614 | } | ||
1615 | else | ||
1616 | { | ||
1617 | List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences(); | ||
1618 | if (avlist != null) | ||
1619 | { | ||
1620 | foreach (ScenePresence av in avlist) | ||
1621 | { | ||
1622 | if (av.LocalId == localId) | ||
1623 | { | ||
1624 | DetectedObject detobj = new DetectedObject(); | ||
1625 | detobj.keyUUID = av.UUID; | ||
1626 | detobj.nameStr = av.Name; | ||
1627 | detobj.ownerUUID = av.UUID; | ||
1628 | detobj.posVector = av.AbsolutePosition; | ||
1629 | detobj.rotQuat = new LLQuaternion(av.Rotation.x, av.Rotation.y, av.Rotation.z, av.Rotation.w); | ||
1630 | detobj.velVector = av.Velocity; | ||
1631 | detobj.colliderType = 0; | ||
1632 | detobj.groupUUID = av.ControllingClient.ActiveGroupId; | ||
1633 | colliding.Add(detobj); | ||
1634 | } | ||
1635 | } | ||
1636 | |||
1637 | } | ||
1638 | } | ||
1639 | } | ||
1640 | if (colliding.Count > 0) | ||
1641 | { | ||
1642 | EndCollidingMessage.Colliders = colliding; | ||
1643 | // always running this check because if the user deletes the object it would return a null reference. | ||
1644 | if (m_parentGroup == null) | ||
1645 | return; | ||
1646 | if (m_parentGroup.Scene == null) | ||
1647 | return; | ||
1648 | m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd(LocalId, EndCollidingMessage); | ||
1649 | } | ||
1650 | |||
1651 | } | ||
758 | } | 1652 | } |
759 | } | 1653 | } |
760 | 1654 | ||
761 | public bool Stopped | 1655 | public void PhysicsOutOfBounds(PhysicsVector pos) |
762 | { | 1656 | { |
763 | get { | 1657 | m_log.Info("[PHYSICS]: Physical Object went out of bounds."); |
764 | double threshold = 0.02; | 1658 | RemFlag(LLObject.ObjectFlags.Physics); |
765 | return (Math.Abs(Velocity.X) < threshold && | 1659 | DoPhysicsPropertyUpdate(false, true); |
766 | Math.Abs(Velocity.Y) < threshold && | 1660 | //m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); |
767 | Math.Abs(Velocity.Z) < threshold && | 1661 | } |
768 | Math.Abs(AngularVelocity.X) < threshold && | 1662 | |
769 | Math.Abs(AngularVelocity.Y) < threshold && | 1663 | public void PhysicsRequestingTerseUpdate() |
770 | Math.Abs(AngularVelocity.Z) < threshold); | 1664 | { |
1665 | if (PhysActor != null) | ||
1666 | { | ||
1667 | LLVector3 newpos = new LLVector3(PhysActor.Position.GetBytes(), 0); | ||
1668 | if (newpos.X > 257f || newpos.X < -1f || newpos.Y > 257f || newpos.Y < -1f) | ||
1669 | { | ||
1670 | m_parentGroup.AbsolutePosition = newpos; | ||
1671 | return; | ||
1672 | } | ||
771 | } | 1673 | } |
1674 | ScheduleTerseUpdate(); | ||
1675 | |||
1676 | //SendTerseUpdateToAllClients(); | ||
772 | } | 1677 | } |
773 | 1678 | ||
774 | #endregion | 1679 | public void PreloadSound(string sound) |
1680 | { | ||
1681 | LLUUID ownerID = OwnerID; | ||
1682 | LLUUID objectID = UUID; | ||
1683 | LLUUID soundID = LLUUID.Zero; | ||
775 | 1684 | ||
776 | public LLUUID ObjectOwner | 1685 | if (!LLUUID.TryParse(sound, out soundID)) |
1686 | { | ||
1687 | //Trys to fetch sound id from prim's inventory. | ||
1688 | //Prim's inventory doesn't support non script items yet | ||
1689 | SceneObjectPart op = this; | ||
1690 | foreach (KeyValuePair<LLUUID, TaskInventoryItem> item in op.TaskInventory) | ||
1691 | { | ||
1692 | if (item.Value.Name == sound) | ||
1693 | { | ||
1694 | soundID = item.Value.ItemID; | ||
1695 | break; | ||
1696 | } | ||
1697 | } | ||
1698 | } | ||
1699 | |||
1700 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); | ||
1701 | foreach (ScenePresence p in avatarts) | ||
1702 | { | ||
1703 | // TODO: some filtering by distance of avatar | ||
1704 | |||
1705 | p.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); | ||
1706 | } | ||
1707 | } | ||
1708 | |||
1709 | public void RemFlag(LLObject.ObjectFlags flag) | ||
777 | { | 1710 | { |
778 | get { return OwnerID; } | 1711 | LLObject.ObjectFlags prevflag = Flags; |
1712 | if ((ObjectFlags & (uint) flag) != 0) | ||
1713 | { | ||
1714 | //Console.WriteLine("Removing flag: " + ((LLObject.ObjectFlags)flag).ToString()); | ||
1715 | Flags &= ~flag; | ||
1716 | } | ||
1717 | //System.Console.WriteLine("prev: " + prevflag.ToString() + " curr: " + Flags.ToString()); | ||
1718 | //ScheduleFullUpdate(); | ||
779 | } | 1719 | } |
780 | 1720 | ||
781 | // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out. | 1721 | public void RemoveScriptEvents(LLUUID scriptid) |
782 | protected SceneObjectGroup m_parentGroup; | 1722 | { |
1723 | lock (m_scriptEvents) | ||
1724 | { | ||
1725 | if (m_scriptEvents.ContainsKey(scriptid)) | ||
1726 | { | ||
1727 | scriptEvents oldparts = scriptEvents.None; | ||
1728 | oldparts = (scriptEvents) m_scriptEvents[scriptid]; | ||
783 | 1729 | ||
784 | public SceneObjectGroup ParentGroup | 1730 | // remove values from aggregated script events |
1731 | m_aggregateScriptEvents &= ~oldparts; | ||
1732 | m_scriptEvents.Remove(scriptid); | ||
1733 | } | ||
1734 | } | ||
1735 | aggregateScriptEvents(); | ||
1736 | } | ||
1737 | |||
1738 | /// <summary> | ||
1739 | /// Reset LLUUIDs for this part. This involves generate this part's own LLUUID and | ||
1740 | /// generating new LLUUIDs for all the items in the inventory. | ||
1741 | /// </summary> | ||
1742 | /// <param name="linkNum">Link number for the part</param> | ||
1743 | public void ResetIDs(int linkNum) | ||
785 | { | 1744 | { |
786 | get { return m_parentGroup; } | 1745 | UUID = LLUUID.Random(); |
1746 | LinkNum = linkNum; | ||
1747 | |||
1748 | ResetInventoryIDs(); | ||
787 | } | 1749 | } |
788 | 1750 | ||
789 | public byte UpdateFlag | 1751 | /// <summary> |
1752 | /// Resize this part. | ||
1753 | /// </summary> | ||
1754 | /// <param name="scale"></param> | ||
1755 | public void Resize(LLVector3 scale) | ||
790 | { | 1756 | { |
791 | get { return m_updateFlag; } | 1757 | StoreUndoState(); |
792 | set { m_updateFlag = value; } | 1758 | m_shape.Scale = scale; |
1759 | |||
1760 | ParentGroup.HasGroupChanged = true; | ||
1761 | ScheduleFullUpdate(); | ||
793 | } | 1762 | } |
794 | 1763 | ||
795 | #region Constructors | 1764 | /// <summary> |
1765 | /// Schedules this prim for a full update | ||
1766 | /// </summary> | ||
1767 | public void ScheduleFullUpdate() | ||
1768 | { | ||
1769 | if (m_parentGroup != null) | ||
1770 | { | ||
1771 | m_parentGroup.QueueForUpdateCheck(); | ||
1772 | } | ||
1773 | |||
1774 | int timeNow = Util.UnixTimeSinceEpoch(); | ||
1775 | |||
1776 | // If multiple updates are scheduled on the same second, we still need to perform all of them | ||
1777 | // So we'll force the issue by bumping up the timestamp so that later processing sees these need | ||
1778 | // to be performed. | ||
1779 | if (timeNow <= TimeStampFull) | ||
1780 | { | ||
1781 | TimeStampFull += 1; | ||
1782 | } | ||
1783 | else | ||
1784 | { | ||
1785 | TimeStampFull = (uint)timeNow; | ||
1786 | } | ||
1787 | |||
1788 | m_updateFlag = 2; | ||
1789 | |||
1790 | // m_log.DebugFormat( | ||
1791 | // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", | ||
1792 | // UUID, Name, TimeStampFull); | ||
1793 | } | ||
796 | 1794 | ||
797 | /// <summary> | 1795 | /// <summary> |
798 | /// No arg constructor called by region restore db code | 1796 | /// Schedule a terse update for this prim. Terse updates only send position, |
1797 | /// rotation, velocity, rotational velocity and shape information. | ||
799 | /// </summary> | 1798 | /// </summary> |
800 | public SceneObjectPart() | 1799 | public void ScheduleTerseUpdate() |
801 | { | 1800 | { |
802 | // It's not necessary to persist this | 1801 | if (m_updateFlag < 1) |
803 | m_TextureAnimation = new byte[0]; | 1802 | { |
1803 | if (m_parentGroup != null) | ||
1804 | { | ||
1805 | m_parentGroup.HasGroupChanged = true; | ||
1806 | m_parentGroup.QueueForUpdateCheck(); | ||
1807 | } | ||
1808 | TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); | ||
1809 | m_updateFlag = 1; | ||
1810 | |||
1811 | // m_log.DebugFormat( | ||
1812 | // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", | ||
1813 | // UUID, Name, TimeStampTerse); | ||
1814 | } | ||
804 | } | 1815 | } |
805 | 1816 | ||
806 | public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID, | 1817 | public void ScriptSetPhantomStatus(bool Phantom) |
807 | PrimitiveBaseShape shape, LLVector3 groupPosition, LLVector3 offsetPosition) | 1818 | { |
808 | : this(regionHandle, parent, ownerID, localID, shape, groupPosition, LLQuaternion.Identity, offsetPosition) | 1819 | if (m_parentGroup != null) |
1820 | { | ||
1821 | m_parentGroup.ScriptSetPhantomStatus(Phantom); | ||
1822 | } | ||
1823 | } | ||
1824 | |||
1825 | public void ScriptSetPhysicsStatus(bool UsePhysics) | ||
809 | { | 1826 | { |
1827 | if (m_parentGroup != null) | ||
1828 | { | ||
1829 | m_parentGroup.ScriptSetPhysicsStatus(UsePhysics); | ||
1830 | } | ||
1831 | } | ||
1832 | |||
1833 | public void SculptTextureCallback(LLUUID textureID, AssetBase texture) | ||
1834 | { | ||
1835 | if (m_shape.SculptEntry) | ||
1836 | { | ||
1837 | if (texture != null) | ||
1838 | { | ||
1839 | m_shape.SculptData = texture.Data; | ||
1840 | if (PhysActor != null) | ||
1841 | { | ||
1842 | // Tricks physics engine into thinking we've changed the part shape. | ||
1843 | PrimitiveBaseShape m_newshape = m_shape.Copy(); | ||
1844 | PhysActor.Shape = m_newshape; | ||
1845 | m_shape = m_newshape; | ||
1846 | } | ||
1847 | } | ||
1848 | } | ||
810 | } | 1849 | } |
811 | 1850 | ||
812 | /// <summary> | 1851 | /// <summary> |
813 | /// Create a completely new SceneObjectPart (prim) | 1852 | /// |
814 | /// </summary> | 1853 | /// </summary> |
815 | /// <param name="regionHandle"></param> | 1854 | /// <param name="remoteClient"></param> |
816 | /// <param name="parent"></param> | 1855 | public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) |
817 | /// <param name="ownerID"></param> | ||
818 | /// <param name="localID"></param> | ||
819 | /// <param name="shape"></param> | ||
820 | /// <param name="position"></param> | ||
821 | public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID, | ||
822 | PrimitiveBaseShape shape, LLVector3 groupPosition, LLQuaternion rotationOffset, | ||
823 | LLVector3 offsetPosition) | ||
824 | { | 1856 | { |
825 | m_name = "Primitive"; | 1857 | m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); |
826 | m_regionHandle = regionHandle; | 1858 | } |
827 | m_parentGroup = parent; | ||
828 | 1859 | ||
829 | CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; | 1860 | /// <summary> |
830 | OwnerID = ownerID; | 1861 | /// |
831 | CreatorID = OwnerID; | 1862 | /// </summary> |
832 | LastOwnerID = LLUUID.Zero; | 1863 | public void SendFullUpdateToAllClients() |
833 | UUID = LLUUID.Random(); | 1864 | { |
834 | LocalId = (uint) (localID); | 1865 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); |
835 | Shape = shape; | 1866 | for (int i = 0; i < avatars.Count; i++) |
836 | // Todo: Add More Object Parameter from above! | 1867 | { |
837 | OwnershipCost = 0; | 1868 | // Ugly reference :( |
838 | ObjectSaleType = (byte) 0; | 1869 | m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this, |
839 | SalePrice = 0; | 1870 | avatars[i].GenerateClientFlags(UUID)); |
840 | Category = (uint) 0; | 1871 | } |
841 | LastOwnerID = CreatorID; | 1872 | } |
842 | // End Todo: /// | ||
843 | GroupPosition = groupPosition; | ||
844 | OffsetPosition = offsetPosition; | ||
845 | RotationOffset = rotationOffset; | ||
846 | Velocity = new LLVector3(0, 0, 0); | ||
847 | m_rotationalvelocity = new LLVector3(0, 0, 0); | ||
848 | AngularVelocity = new LLVector3(0, 0, 0); | ||
849 | Acceleration = new LLVector3(0, 0, 0); | ||
850 | m_TextureAnimation = new byte[0]; | ||
851 | 1873 | ||
852 | // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, | 1874 | public void SendFullUpdateToAllClientsExcept(LLUUID agentID) |
853 | // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from | 1875 | { |
854 | // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log | 1876 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); |
1877 | for (int i = 0; i < avatars.Count; i++) | ||
1878 | { | ||
1879 | // Ugly reference :( | ||
1880 | if (avatars[i].UUID != agentID) | ||
1881 | { | ||
1882 | m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this, | ||
1883 | avatars[i].GenerateClientFlags(UUID)); | ||
1884 | } | ||
1885 | } | ||
1886 | } | ||
855 | 1887 | ||
856 | Flags = 0; | 1888 | /// <summary> |
857 | Flags |= LLObject.ObjectFlags.CreateSelected; | 1889 | /// Sends a full update to the client |
1890 | /// </summary> | ||
1891 | /// <param name="remoteClient"></param> | ||
1892 | /// <param name="clientFlags"></param> | ||
1893 | public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientflags) | ||
1894 | { | ||
1895 | LLVector3 lPos; | ||
1896 | lPos = OffsetPosition; | ||
1897 | SendFullUpdateToClient(remoteClient, lPos, clientflags); | ||
1898 | } | ||
858 | 1899 | ||
859 | TrimPermissions(); | 1900 | /// <summary> |
860 | //m_undo = new UndoStack<UndoState>(ParentGroup.GetSceneMaxUndo()); | 1901 | /// Sends a full update to the client |
1902 | /// </summary> | ||
1903 | /// <param name="remoteClient"></param> | ||
1904 | /// <param name="lPos"></param> | ||
1905 | /// <param name="clientFlags"></param> | ||
1906 | public void SendFullUpdateToClient(IClientAPI remoteClient, LLVector3 lPos, uint clientFlags) | ||
1907 | { | ||
1908 | clientFlags &= ~(uint) LLObject.ObjectFlags.CreateSelected; | ||
861 | 1909 | ||
862 | ScheduleFullUpdate(); | 1910 | if (remoteClient.AgentId == OwnerID) |
1911 | { | ||
1912 | if ((uint) (Flags & LLObject.ObjectFlags.CreateSelected) != 0) | ||
1913 | { | ||
1914 | clientFlags |= (uint) LLObject.ObjectFlags.CreateSelected; | ||
1915 | Flags &= ~LLObject.ObjectFlags.CreateSelected; | ||
1916 | } | ||
1917 | } | ||
1918 | |||
1919 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; | ||
1920 | remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, | ||
1921 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, OwnerID, | ||
1922 | m_text, color, ParentID, m_particleSystem, m_clickAction, m_TextureAnimation, m_IsAttachment, | ||
1923 | m_attachmentPoint,fromAssetID, Sound, SoundGain, SoundFlags, SoundRadius); | ||
863 | } | 1924 | } |
864 | 1925 | ||
865 | /// <summary> | 1926 | /// <summary> |
866 | /// Re/create a SceneObjectPart (prim) | 1927 | /// Tell all the prims which have had updates scheduled |
867 | /// currently not used, and maybe won't be | ||
868 | /// </summary> | 1928 | /// </summary> |
869 | /// <param name="regionHandle"></param> | 1929 | public void SendScheduledUpdates() |
870 | /// <param name="parent"></param> | ||
871 | /// <param name="ownerID"></param> | ||
872 | /// <param name="localID"></param> | ||
873 | /// <param name="shape"></param> | ||
874 | /// <param name="position"></param> | ||
875 | public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, int creationDate, LLUUID ownerID, | ||
876 | LLUUID creatorID, LLUUID lastOwnerID, uint localID, PrimitiveBaseShape shape, | ||
877 | LLVector3 position, LLQuaternion rotation, uint flags) | ||
878 | { | 1930 | { |
879 | m_regionHandle = regionHandle; | 1931 | if (m_updateFlag == 1) //some change has been made so update the clients |
880 | m_parentGroup = parent; | 1932 | { |
881 | TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); | 1933 | AddTerseUpdateToAllAvatars(); |
882 | CreationDate = creationDate; | 1934 | ClearUpdateSchedule(); |
883 | OwnerID = ownerID; | ||
884 | CreatorID = creatorID; | ||
885 | LastOwnerID = lastOwnerID; | ||
886 | UUID = LLUUID.Random(); | ||
887 | LocalId = (uint) (localID); | ||
888 | Shape = shape; | ||
889 | OwnershipCost = 0; | ||
890 | ObjectSaleType = (byte) 0; | ||
891 | SalePrice = 0; | ||
892 | Category = (uint) 0; | ||
893 | LastOwnerID = CreatorID; | ||
894 | OffsetPosition = position; | ||
895 | RotationOffset = rotation; | ||
896 | ObjectFlags = flags; | ||
897 | 1935 | ||
898 | // Since we don't store script state, this is only a 'temporary' objectflag now | 1936 | // This causes the Scene to 'poll' physical objects every couple of frames |
899 | // If the object is scripted, the script will get loaded and this will be set again | 1937 | // bad, so it's been replaced by an event driven method. |
900 | ObjectFlags &= ~(uint)(LLObject.ObjectFlags.Scripted | LLObject.ObjectFlags.Touch); | 1938 | //if ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0) |
1939 | //{ | ||
1940 | // Only send the constant terse updates on physical objects! | ||
1941 | //ScheduleTerseUpdate(); | ||
1942 | //} | ||
1943 | } | ||
1944 | else | ||
1945 | { | ||
1946 | if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes | ||
1947 | { | ||
1948 | AddFullUpdateToAllAvatars(); | ||
1949 | ClearUpdateSchedule(); | ||
1950 | } | ||
1951 | } | ||
1952 | } | ||
901 | 1953 | ||
902 | TrimPermissions(); | 1954 | public void SendSound(string sound, double volume, bool triggered, byte flags) |
903 | // ApplyPhysics(); | 1955 | { |
1956 | if (volume > 1) | ||
1957 | volume = 1; | ||
1958 | if (volume < 0) | ||
1959 | volume = 0; | ||
904 | 1960 | ||
905 | ScheduleFullUpdate(); | 1961 | LLUUID ownerID = OwnerID; |
1962 | LLUUID objectID = UUID; | ||
1963 | LLUUID parentID = GetRootPartUUID(); | ||
1964 | LLUUID soundID = LLUUID.Zero; | ||
1965 | LLVector3 position = AbsolutePosition; // region local | ||
1966 | ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle; | ||
1967 | |||
1968 | //byte flags = 0; | ||
1969 | |||
1970 | if (!LLUUID.TryParse(sound, out soundID)) | ||
1971 | { | ||
1972 | // search sound file from inventory | ||
1973 | SceneObjectPart op = this; | ||
1974 | foreach (KeyValuePair<LLUUID, TaskInventoryItem> item in op.TaskInventory) | ||
1975 | { | ||
1976 | if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) | ||
1977 | { | ||
1978 | soundID = item.Value.ItemID; | ||
1979 | break; | ||
1980 | } | ||
1981 | } | ||
1982 | } | ||
1983 | |||
1984 | if (soundID == LLUUID.Zero) | ||
1985 | return; | ||
1986 | |||
1987 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); | ||
1988 | foreach (ScenePresence p in avatarts) | ||
1989 | { | ||
1990 | double dis=Util.GetDistanceTo(p.AbsolutePosition, position); | ||
1991 | if (dis > 100.0) // Max audio distance | ||
1992 | continue; | ||
1993 | |||
1994 | // Scale by distance | ||
1995 | volume*=((100.0-dis)/100.0); | ||
1996 | |||
1997 | if (triggered) | ||
1998 | { | ||
1999 | p.ControllingClient.SendTriggeredSound(soundID, ownerID, objectID, parentID, regionHandle, position, (float)volume); | ||
2000 | } | ||
2001 | else | ||
2002 | { | ||
2003 | p.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)volume, flags); | ||
2004 | } | ||
2005 | } | ||
906 | } | 2006 | } |
907 | 2007 | ||
908 | #endregion | 2008 | /// <summary> |
2009 | /// Send a terse update to the client. | ||
2010 | /// </summary> | ||
2011 | /// <param name="remoteClient"></param> | ||
2012 | public void SendTerseUpdate(IClientAPI remoteClient) | ||
2013 | { | ||
2014 | m_parentGroup.SendPartTerseUpdate(remoteClient, this); | ||
2015 | } | ||
909 | 2016 | ||
910 | /// <summary> | 2017 | /// <summary> |
911 | /// Restore this part from the serialized xml representation. | 2018 | /// |
912 | /// </summary> | 2019 | /// </summary> |
913 | /// <param name="xmlreader"></param> | 2020 | public void SendTerseUpdateToAllClients() |
914 | /// <returns></returns> | ||
915 | public static SceneObjectPart FromXml(XmlReader xmlReader) | ||
916 | { | 2021 | { |
917 | // It's not necessary to persist this | 2022 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); |
2023 | for (int i = 0; i < avatars.Count; i++) | ||
2024 | { | ||
2025 | m_parentGroup.SendPartTerseUpdate(avatars[i].ControllingClient, this); | ||
2026 | } | ||
2027 | } | ||
918 | 2028 | ||
919 | XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart)); | 2029 | public void SendTerseUpdateToClient(IClientAPI remoteClient) |
920 | SceneObjectPart newobject = (SceneObjectPart) serializer.Deserialize(xmlReader); | 2030 | { |
921 | return newobject; | 2031 | LLVector3 lPos; |
2032 | lPos = OffsetPosition; | ||
2033 | LLQuaternion mRot = RotationOffset; | ||
2034 | // TODO: I have no idea why we are making this check. This should be sorted out | ||
2035 | if ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0) | ||
2036 | { | ||
2037 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, RotationalVelocity, Shape.State, fromAssetID); | ||
2038 | } | ||
2039 | else | ||
2040 | { | ||
2041 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, | ||
2042 | RotationalVelocity); | ||
2043 | //System.Console.WriteLine("LID: " + LocalID + " RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString()); | ||
2044 | } | ||
2045 | } | ||
2046 | |||
2047 | public void SendTerseUpdateToClient(IClientAPI remoteClient, LLVector3 lPos) | ||
2048 | { | ||
2049 | LLQuaternion mRot = RotationOffset; | ||
2050 | if (m_IsAttachment) | ||
2051 | { | ||
2052 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, RotationalVelocity, (byte)((m_attachmentPoint % 16) * 16 + (m_attachmentPoint / 16)),fromAssetID); | ||
2053 | } | ||
2054 | else | ||
2055 | { | ||
2056 | if ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) == 0) | ||
2057 | { | ||
2058 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, RotationalVelocity, Shape.State, fromAssetID); | ||
2059 | } | ||
2060 | else | ||
2061 | { | ||
2062 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, | ||
2063 | RotationalVelocity); | ||
2064 | //System.Console.WriteLine("LID: " + LocalID + "RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString()); | ||
2065 | } | ||
2066 | } | ||
2067 | } | ||
2068 | |||
2069 | public void SetAttachmentPoint(uint AttachmentPoint) | ||
2070 | { | ||
2071 | m_attachmentPoint = AttachmentPoint; | ||
2072 | |||
2073 | // save the attachment point. | ||
2074 | //if (AttachmentPoint != 0) | ||
2075 | //{ | ||
2076 | m_shape.State = (byte)AttachmentPoint; | ||
2077 | //} | ||
2078 | } | ||
2079 | |||
2080 | public void SetAvatarOnSitTarget(LLUUID avatarID) | ||
2081 | { | ||
2082 | m_sitTargetAvatar = avatarID; | ||
2083 | TriggerScriptChangedEvent(Changed.LINK); | ||
2084 | } | ||
2085 | |||
2086 | public void SetAxisRotation(int axis, int rotate) | ||
2087 | { | ||
2088 | if (m_parentGroup != null) | ||
2089 | { | ||
2090 | m_parentGroup.SetAxisRotation(axis, rotate); | ||
2091 | } | ||
2092 | } | ||
2093 | |||
2094 | public void SetBuoyancy(float fvalue) | ||
2095 | { | ||
2096 | if (PhysActor != null) | ||
2097 | { | ||
2098 | PhysActor.Buoyancy = fvalue; | ||
2099 | } | ||
2100 | } | ||
2101 | |||
2102 | public void SetDieAtEdge(bool p) | ||
2103 | { | ||
2104 | if (m_parentGroup == null) | ||
2105 | return; | ||
2106 | if (m_parentGroup.RootPart == null) | ||
2107 | return; | ||
2108 | |||
2109 | m_parentGroup.RootPart.DIE_AT_EDGE = p; | ||
2110 | } | ||
2111 | |||
2112 | public void SetFloatOnWater(int floatYN) | ||
2113 | { | ||
2114 | if (PhysActor != null) | ||
2115 | { | ||
2116 | if (floatYN == 1) | ||
2117 | { | ||
2118 | PhysActor.FloatOnWater = true; | ||
2119 | } | ||
2120 | else | ||
2121 | { | ||
2122 | PhysActor.FloatOnWater = false; | ||
2123 | } | ||
2124 | } | ||
2125 | } | ||
2126 | |||
2127 | public void SetGroup(LLUUID groupID, IClientAPI client) | ||
2128 | { | ||
2129 | GroupID = groupID; | ||
2130 | GetProperties(client); | ||
2131 | m_updateFlag = 2; | ||
922 | } | 2132 | } |
923 | 2133 | ||
924 | /// <summary> | 2134 | /// <summary> |
925 | /// Apply physics to this part. | 2135 | /// |
926 | /// </summary> | 2136 | /// </summary> |
927 | /// <param name="rootObjectFlags"></param> | 2137 | public void SetParent(SceneObjectGroup parent) |
928 | /// <param name="m_physicalPrim"></param> | ||
929 | public void ApplyPhysics(uint rootObjectFlags, bool m_physicalPrim) | ||
930 | { | 2138 | { |
931 | bool isPhysical = (((rootObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0) && m_physicalPrim); | 2139 | m_parentGroup = parent; |
932 | bool isPhantom = ((rootObjectFlags & (uint) LLObject.ObjectFlags.Phantom) != 0); | 2140 | } |
933 | 2141 | ||
934 | // Added clarification.. since A rigid body is an object that you can kick around, etc. | 2142 | // Use this for attachments! LocalID should be avatar's localid |
935 | bool RigidBody = isPhysical && !isPhantom; | 2143 | public void SetParentLocalId(uint localID) |
2144 | { | ||
2145 | ParentID = localID; | ||
2146 | } | ||
936 | 2147 | ||
937 | // The only time the physics scene shouldn't know about the prim is if it's phantom | 2148 | public void SetPhysicsAxisRotation() |
938 | if (!isPhantom) | 2149 | { |
2150 | PhysActor.LockAngularMotion(m_rotationAxis); | ||
2151 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
2152 | } | ||
2153 | |||
2154 | public void SetScriptEvents(LLUUID scriptid, int events) | ||
2155 | { | ||
2156 | scriptEvents oldparts; | ||
2157 | lock (m_scriptEvents) | ||
939 | { | 2158 | { |
940 | PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( | 2159 | if (m_scriptEvents.ContainsKey(scriptid)) |
941 | Name, | 2160 | { |
942 | Shape, | 2161 | oldparts = m_scriptEvents[scriptid]; |
943 | new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y, | ||
944 | AbsolutePosition.Z), | ||
945 | new PhysicsVector(Scale.X, Scale.Y, Scale.Z), | ||
946 | new Quaternion(RotationOffset.W, RotationOffset.X, | ||
947 | RotationOffset.Y, RotationOffset.Z), RigidBody); | ||
948 | 2162 | ||
949 | // Basic Physics returns null.. joy joy joy. | 2163 | // remove values from aggregated script events |
950 | if (PhysActor != null) | 2164 | m_scriptEvents[scriptid] = (scriptEvents) events; |
2165 | } | ||
2166 | else | ||
951 | { | 2167 | { |
952 | PhysActor.LocalID = LocalId; | 2168 | m_scriptEvents.Add(scriptid, (scriptEvents) events); |
953 | DoPhysicsPropertyUpdate(RigidBody, true); | ||
954 | } | 2169 | } |
955 | } | 2170 | } |
2171 | aggregateScriptEvents(); | ||
956 | } | 2172 | } |
957 | 2173 | ||
958 | public void TrimPermissions() | 2174 | public void SetSitTarget(Vector3 offset, Quaternion orientation) |
959 | { | 2175 | { |
2176 | m_sitTargetPosition = offset; | ||
2177 | m_sitTargetOrientation = orientation; | ||
2178 | } | ||
960 | 2179 | ||
961 | BaseMask &= (uint)PermissionMask.All; | 2180 | // Utility function so the databases don't have to reference axiom.math |
962 | OwnerMask &= (uint)PermissionMask.All; | 2181 | public void SetSitTargetLL(LLVector3 offset, LLQuaternion orientation) |
963 | GroupMask &= (uint)PermissionMask.All; | 2182 | { |
964 | EveryoneMask &= (uint)PermissionMask.All; | 2183 | if ( |
965 | NextOwnerMask &= (uint)PermissionMask.All; | 2184 | !(offset.X == 0 && offset.Y == 0 && offset.Z == 0 && (orientation.W == 0 || orientation.W == 1) && |
2185 | orientation.X == 0 && orientation.Y == 0 && orientation.Z == 0)) | ||
2186 | { | ||
2187 | m_sitTargetPosition = new Vector3(offset.X, offset.Y, offset.Z); | ||
2188 | m_sitTargetOrientation = new Quaternion(orientation.W, orientation.X, orientation.Y, orientation.Z); | ||
2189 | } | ||
2190 | } | ||
966 | 2191 | ||
2192 | /// <summary> | ||
2193 | /// Set the text displayed for this part. | ||
2194 | /// </summary> | ||
2195 | /// <param name="text"></param> | ||
2196 | public void SetText(string text) | ||
2197 | { | ||
2198 | Text = text; | ||
2199 | |||
2200 | ParentGroup.HasGroupChanged = true; | ||
2201 | ScheduleFullUpdate(); | ||
967 | } | 2202 | } |
968 | 2203 | ||
969 | /// <summary> | 2204 | /// <summary> |
970 | /// Serialize this part to xml. | 2205 | /// Set the text displayed for this part. |
971 | /// </summary> | 2206 | /// </summary> |
972 | /// <param name="xmlWriter"></param> | 2207 | /// <param name="text"></param> |
973 | public void ToXml(XmlWriter xmlWriter) | 2208 | /// <param name="color"></param> |
2209 | /// <param name="alpha"></param> | ||
2210 | public void SetText(string text, Vector3 color, double alpha) | ||
974 | { | 2211 | { |
975 | XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart)); | 2212 | Color = Color.FromArgb(0xff - (int) (alpha*0xff), |
976 | serializer.Serialize(xmlWriter, this); | 2213 | (int) (color.x*0xff), |
2214 | (int) (color.y*0xff), | ||
2215 | (int) (color.z*0xff)); | ||
2216 | SetText(text); | ||
2217 | } | ||
2218 | |||
2219 | public void StopMoveToTarget() | ||
2220 | { | ||
2221 | m_parentGroup.stopMoveToTarget(); | ||
2222 | } | ||
2223 | |||
2224 | public void StoreUndoState() | ||
2225 | { | ||
2226 | if (!m_undoing) | ||
2227 | { | ||
2228 | if (m_parentGroup != null) | ||
2229 | { | ||
2230 | if (m_undo.Count > 0) | ||
2231 | { | ||
2232 | UndoState last = m_undo.Peek(); | ||
2233 | if (last != null) | ||
2234 | { | ||
2235 | if (last.Compare(this)) | ||
2236 | return; | ||
2237 | } | ||
2238 | } | ||
2239 | |||
2240 | |||
2241 | if (m_parentGroup.GetSceneMaxUndo() > 0) | ||
2242 | { | ||
2243 | UndoState nUndo = new UndoState(this); | ||
2244 | |||
2245 | m_undo.Push(nUndo); | ||
2246 | |||
2247 | } | ||
2248 | } | ||
2249 | } | ||
977 | } | 2250 | } |
978 | 2251 | ||
979 | public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot) | 2252 | public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot) |
@@ -1086,14 +2359,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
1086 | return returnresult; | 2359 | return returnresult; |
1087 | } | 2360 | } |
1088 | 2361 | ||
1089 | public double GetDistanceTo(Vector3 a, Vector3 b) | ||
1090 | { | ||
1091 | float dx = a.x - b.x; | ||
1092 | float dy = a.y - b.y; | ||
1093 | float dz = a.z - b.z; | ||
1094 | return Math.Sqrt(dx * dx + dy * dy + dz * dz); | ||
1095 | } | ||
1096 | |||
1097 | public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot, bool frontFacesOnly, bool faceCenters) | 2362 | public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot, bool frontFacesOnly, bool faceCenters) |
1098 | { | 2363 | { |
1099 | // In this case we're using a rectangular prism, which has 6 faces and therefore 6 planes | 2364 | // In this case we're using a rectangular prism, which has 6 faces and therefore 6 planes |
@@ -1183,7 +2448,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1183 | tScale = new Vector3(AXscale.x, -AXscale.y, AXscale.z); | 2448 | tScale = new Vector3(AXscale.x, -AXscale.y, AXscale.z); |
1184 | rScale = ((AXrot * tScale)); | 2449 | rScale = ((AXrot * tScale)); |
1185 | vertexes[0] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); | 2450 | vertexes[0] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); |
1186 | // vertexes[0].x = pos.X + vertexes[0].x; | 2451 | // vertexes[0].x = pos.X + vertexes[0].x; |
1187 | //vertexes[0].y = pos.Y + vertexes[0].y; | 2452 | //vertexes[0].y = pos.Y + vertexes[0].y; |
1188 | //vertexes[0].z = pos.Z + vertexes[0].z; | 2453 | //vertexes[0].z = pos.Z + vertexes[0].z; |
1189 | 2454 | ||
@@ -1195,8 +2460,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
1195 | rScale = ((AXrot * tScale)); | 2460 | rScale = ((AXrot * tScale)); |
1196 | vertexes[1] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); | 2461 | vertexes[1] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); |
1197 | 2462 | ||
1198 | // vertexes[1].x = pos.X + vertexes[1].x; | 2463 | // vertexes[1].x = pos.X + vertexes[1].x; |
1199 | // vertexes[1].y = pos.Y + vertexes[1].y; | 2464 | // vertexes[1].y = pos.Y + vertexes[1].y; |
1200 | //vertexes[1].z = pos.Z + vertexes[1].z; | 2465 | //vertexes[1].z = pos.Z + vertexes[1].z; |
1201 | 2466 | ||
1202 | FaceB[0] = vertexes[1]; | 2467 | FaceB[0] = vertexes[1]; |
@@ -1221,8 +2486,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
1221 | vertexes[3] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); | 2486 | vertexes[3] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); |
1222 | 2487 | ||
1223 | //vertexes[3].x = pos.X + vertexes[3].x; | 2488 | //vertexes[3].x = pos.X + vertexes[3].x; |
1224 | // vertexes[3].y = pos.Y + vertexes[3].y; | 2489 | // vertexes[3].y = pos.Y + vertexes[3].y; |
1225 | // vertexes[3].z = pos.Z + vertexes[3].z; | 2490 | // vertexes[3].z = pos.Z + vertexes[3].z; |
1226 | 2491 | ||
1227 | FaceD[0] = vertexes[3]; | 2492 | FaceD[0] = vertexes[3]; |
1228 | FaceC[1] = vertexes[3]; | 2493 | FaceC[1] = vertexes[3]; |
@@ -1232,9 +2497,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
1232 | rScale = ((AXrot * tScale)); | 2497 | rScale = ((AXrot * tScale)); |
1233 | vertexes[4] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); | 2498 | vertexes[4] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); |
1234 | 2499 | ||
1235 | // vertexes[4].x = pos.X + vertexes[4].x; | 2500 | // vertexes[4].x = pos.X + vertexes[4].x; |
1236 | // vertexes[4].y = pos.Y + vertexes[4].y; | 2501 | // vertexes[4].y = pos.Y + vertexes[4].y; |
1237 | // vertexes[4].z = pos.Z + vertexes[4].z; | 2502 | // vertexes[4].z = pos.Z + vertexes[4].z; |
1238 | 2503 | ||
1239 | FaceB[1] = vertexes[4]; | 2504 | FaceB[1] = vertexes[4]; |
1240 | FaceA[2] = vertexes[4]; | 2505 | FaceA[2] = vertexes[4]; |
@@ -1244,9 +2509,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
1244 | rScale = ((AXrot * tScale)); | 2509 | rScale = ((AXrot * tScale)); |
1245 | vertexes[5] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); | 2510 | vertexes[5] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); |
1246 | 2511 | ||
1247 | // vertexes[5].x = pos.X + vertexes[5].x; | 2512 | // vertexes[5].x = pos.X + vertexes[5].x; |
1248 | // vertexes[5].y = pos.Y + vertexes[5].y; | 2513 | // vertexes[5].y = pos.Y + vertexes[5].y; |
1249 | // vertexes[5].z = pos.Z + vertexes[5].z; | 2514 | // vertexes[5].z = pos.Z + vertexes[5].z; |
1250 | 2515 | ||
1251 | FaceD[1] = vertexes[5]; | 2516 | FaceD[1] = vertexes[5]; |
1252 | FaceC[2] = vertexes[5]; | 2517 | FaceC[2] = vertexes[5]; |
@@ -1256,9 +2521,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
1256 | rScale = ((AXrot * tScale)); | 2521 | rScale = ((AXrot * tScale)); |
1257 | vertexes[6] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); | 2522 | vertexes[6] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); |
1258 | 2523 | ||
1259 | // vertexes[6].x = pos.X + vertexes[6].x; | 2524 | // vertexes[6].x = pos.X + vertexes[6].x; |
1260 | // vertexes[6].y = pos.Y + vertexes[6].y; | 2525 | // vertexes[6].y = pos.Y + vertexes[6].y; |
1261 | // vertexes[6].z = pos.Z + vertexes[6].z; | 2526 | // vertexes[6].z = pos.Z + vertexes[6].z; |
1262 | 2527 | ||
1263 | FaceB[2] = vertexes[6]; | 2528 | FaceB[2] = vertexes[6]; |
1264 | FaceA[3] = vertexes[6]; | 2529 | FaceA[3] = vertexes[6]; |
@@ -1268,9 +2533,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
1268 | rScale = ((AXrot * tScale)); | 2533 | rScale = ((AXrot * tScale)); |
1269 | vertexes[7] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); | 2534 | vertexes[7] = (new Vector3((pos.X + rScale.x), (pos.Y + rScale.y), (pos.Z + rScale.z))); |
1270 | 2535 | ||
1271 | // vertexes[7].x = pos.X + vertexes[7].x; | 2536 | // vertexes[7].x = pos.X + vertexes[7].x; |
1272 | // vertexes[7].y = pos.Y + vertexes[7].y; | 2537 | // vertexes[7].y = pos.Y + vertexes[7].y; |
1273 | // vertexes[7].z = pos.Z + vertexes[7].z; | 2538 | // vertexes[7].z = pos.Z + vertexes[7].z; |
1274 | 2539 | ||
1275 | FaceD[2] = vertexes[7]; | 2540 | FaceD[2] = vertexes[7]; |
1276 | FaceC[3] = vertexes[7]; | 2541 | FaceC[3] = vertexes[7]; |
@@ -1352,7 +2617,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1352 | //if (fmax > 0) | 2617 | //if (fmax > 0) |
1353 | // a= fmax; | 2618 | // a= fmax; |
1354 | //else | 2619 | //else |
1355 | // a=fmin; | 2620 | // a=fmin; |
1356 | 2621 | ||
1357 | //q = iray.Origin + a * iray.Direction; | 2622 | //q = iray.Origin + a * iray.Direction; |
1358 | #endregion | 2623 | #endregion |
@@ -1437,370 +2702,122 @@ namespace OpenSim.Region.Environment.Scenes | |||
1437 | return returnresult; | 2702 | return returnresult; |
1438 | } | 2703 | } |
1439 | 2704 | ||
1440 | // Use this for attachments! LocalID should be avatar's localid | ||
1441 | public void SetParentLocalId(uint localID) | ||
1442 | { | ||
1443 | ParentID = localID; | ||
1444 | } | ||
1445 | |||
1446 | public void SetAttachmentPoint(uint AttachmentPoint) | ||
1447 | { | ||
1448 | m_attachmentPoint = AttachmentPoint; | ||
1449 | |||
1450 | // save the attachment point. | ||
1451 | //if (AttachmentPoint != 0) | ||
1452 | //{ | ||
1453 | m_shape.State = (byte)AttachmentPoint; | ||
1454 | //} | ||
1455 | } | ||
1456 | |||
1457 | /// <summary> | 2705 | /// <summary> |
1458 | /// | 2706 | /// Serialize this part to xml. |
1459 | /// </summary> | 2707 | /// </summary> |
1460 | public void SetParent(SceneObjectGroup parent) | 2708 | /// <param name="xmlWriter"></param> |
1461 | { | 2709 | public void ToXml(XmlWriter xmlWriter) |
1462 | m_parentGroup = parent; | ||
1463 | } | ||
1464 | |||
1465 | public void SetSitTarget(Vector3 offset, Quaternion orientation) | ||
1466 | { | ||
1467 | m_sitTargetPosition = offset; | ||
1468 | m_sitTargetOrientation = orientation; | ||
1469 | } | ||
1470 | |||
1471 | public void SetBuoyancy(float fvalue) | ||
1472 | { | 2710 | { |
1473 | if (PhysActor != null) | 2711 | XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart)); |
1474 | { | 2712 | serializer.Serialize(xmlWriter, this); |
1475 | PhysActor.Buoyancy = fvalue; | ||
1476 | } | ||
1477 | } | 2713 | } |
1478 | 2714 | ||
1479 | public void SetAxisRotation(int axis, int rotate) | 2715 | public void TriggerScriptChangedEvent(Changed val) |
1480 | { | 2716 | { |
1481 | if (m_parentGroup != null) | 2717 | if (m_parentGroup != null) |
1482 | { | 2718 | { |
1483 | m_parentGroup.SetAxisRotation(axis, rotate); | 2719 | if (m_parentGroup.Scene != null) |
1484 | } | 2720 | m_parentGroup.Scene.TriggerObjectChanged(LocalId, (uint)val); |
1485 | } | ||
1486 | |||
1487 | public void SetPhysicsAxisRotation() | ||
1488 | { | ||
1489 | PhysActor.LockAngularMotion(m_rotationAxis); | ||
1490 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
1491 | } | ||
1492 | |||
1493 | public void SetFloatOnWater(int floatYN) | ||
1494 | { | ||
1495 | if (PhysActor != null) | ||
1496 | { | ||
1497 | if (floatYN == 1) | ||
1498 | { | ||
1499 | PhysActor.FloatOnWater = true; | ||
1500 | } | ||
1501 | else | ||
1502 | { | ||
1503 | PhysActor.FloatOnWater = false; | ||
1504 | } | ||
1505 | } | ||
1506 | } | ||
1507 | |||
1508 | public LLVector3 GetSitTargetPositionLL() | ||
1509 | { | ||
1510 | return new LLVector3(m_sitTargetPosition.x, m_sitTargetPosition.y, m_sitTargetPosition.z); | ||
1511 | } | ||
1512 | |||
1513 | public LLQuaternion GetSitTargetOrientationLL() | ||
1514 | { | ||
1515 | return | ||
1516 | new LLQuaternion(m_sitTargetOrientation.x, m_sitTargetOrientation.y, m_sitTargetOrientation.z, | ||
1517 | m_sitTargetOrientation.w); | ||
1518 | } | ||
1519 | |||
1520 | // Utility function so the databases don't have to reference axiom.math | ||
1521 | public void SetSitTargetLL(LLVector3 offset, LLQuaternion orientation) | ||
1522 | { | ||
1523 | if ( | ||
1524 | !(offset.X == 0 && offset.Y == 0 && offset.Z == 0 && (orientation.W == 0 || orientation.W == 1) && | ||
1525 | orientation.X == 0 && orientation.Y == 0 && orientation.Z == 0)) | ||
1526 | { | ||
1527 | m_sitTargetPosition = new Vector3(offset.X, offset.Y, offset.Z); | ||
1528 | m_sitTargetOrientation = new Quaternion(orientation.W, orientation.X, orientation.Y, orientation.Z); | ||
1529 | } | 2721 | } |
1530 | } | 2722 | } |
1531 | 2723 | ||
1532 | public Vector3 GetSitTargetPosition() | 2724 | public void TrimPermissions() |
1533 | { | ||
1534 | return m_sitTargetPosition; | ||
1535 | } | ||
1536 | |||
1537 | public Quaternion GetSitTargetOrientation() | ||
1538 | { | ||
1539 | return m_sitTargetOrientation; | ||
1540 | } | ||
1541 | |||
1542 | public void SetAvatarOnSitTarget(LLUUID avatarID) | ||
1543 | { | ||
1544 | m_sitTargetAvatar = avatarID; | ||
1545 | TriggerScriptChangedEvent(Changed.LINK); | ||
1546 | } | ||
1547 | |||
1548 | public LLUUID GetAvatarOnSitTarget() | ||
1549 | { | 2725 | { |
1550 | return m_sitTargetAvatar; | 2726 | BaseMask &= (uint)PermissionMask.All; |
2727 | OwnerMask &= (uint)PermissionMask.All; | ||
2728 | GroupMask &= (uint)PermissionMask.All; | ||
2729 | EveryoneMask &= (uint)PermissionMask.All; | ||
2730 | NextOwnerMask &= (uint)PermissionMask.All; | ||
1551 | } | 2731 | } |
1552 | 2732 | ||
1553 | public LLUUID GetRootPartUUID() | 2733 | public void Undo() |
1554 | { | 2734 | { |
1555 | if (m_parentGroup != null) | 2735 | if (m_undo.Count > 0) |
1556 | { | 2736 | { |
1557 | return m_parentGroup.UUID; | 2737 | UndoState goback = m_undo.Pop(); |
2738 | if (goback != null) | ||
2739 | goback.PlaybackState(this); | ||
1558 | } | 2740 | } |
1559 | return LLUUID.Zero; | ||
1560 | } | ||
1561 | |||
1562 | public static SceneObjectPart Create() | ||
1563 | { | ||
1564 | SceneObjectPart part = new SceneObjectPart(); | ||
1565 | part.UUID = LLUUID.Random(); | ||
1566 | |||
1567 | PrimitiveBaseShape shape = PrimitiveBaseShape.Create(); | ||
1568 | part.Shape = shape; | ||
1569 | |||
1570 | part.Name = "Primitive"; | ||
1571 | part.OwnerID = LLUUID.Random(); | ||
1572 | |||
1573 | return part; | ||
1574 | } | 2741 | } |
1575 | 2742 | ||
1576 | #region Copying | 2743 | public void UpdateExtraParam(ushort type, bool inUse, byte[] data) |
1577 | |||
1578 | /// <summary> | ||
1579 | /// Duplicates this part. | ||
1580 | /// </summary> | ||
1581 | /// <returns></returns> | ||
1582 | public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID, int linkNum, bool userExposed) | ||
1583 | { | 2744 | { |
1584 | SceneObjectPart dupe = (SceneObjectPart) MemberwiseClone(); | 2745 | m_shape.ReadInUpdateExtraParam(type, inUse, data); |
1585 | dupe.m_shape = m_shape.Copy(); | ||
1586 | dupe.m_regionHandle = m_regionHandle; | ||
1587 | if (userExposed) | ||
1588 | dupe.UUID = LLUUID.Random(); | ||
1589 | |||
1590 | dupe.LocalId = localID; | ||
1591 | dupe.OwnerID = AgentID; | ||
1592 | dupe.GroupID = GroupID; | ||
1593 | dupe.GroupPosition = new LLVector3(GroupPosition.X, GroupPosition.Y, GroupPosition.Z); | ||
1594 | dupe.OffsetPosition = new LLVector3(OffsetPosition.X, OffsetPosition.Y, OffsetPosition.Z); | ||
1595 | dupe.RotationOffset = | ||
1596 | new LLQuaternion(RotationOffset.X, RotationOffset.Y, RotationOffset.Z, RotationOffset.W); | ||
1597 | dupe.Velocity = new LLVector3(0, 0, 0); | ||
1598 | dupe.Acceleration = new LLVector3(0, 0, 0); | ||
1599 | dupe.AngularVelocity = new LLVector3(0, 0, 0); | ||
1600 | dupe.ObjectFlags = ObjectFlags; | ||
1601 | |||
1602 | dupe.OwnershipCost = OwnershipCost; | ||
1603 | dupe.ObjectSaleType = ObjectSaleType; | ||
1604 | dupe.SalePrice = SalePrice; | ||
1605 | dupe.Category = Category; | ||
1606 | |||
1607 | dupe.TaskInventory = (TaskInventoryDictionary)dupe.TaskInventory.Clone(); | ||
1608 | |||
1609 | if (userExposed) | ||
1610 | dupe.ResetIDs(linkNum); | ||
1611 | |||
1612 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. | ||
1613 | dupe.LastOwnerID = ObjectOwner; | ||
1614 | |||
1615 | byte[] extraP = new byte[Shape.ExtraParams.Length]; | ||
1616 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); | ||
1617 | dupe.Shape.ExtraParams = extraP; | ||
1618 | 2746 | ||
1619 | if (userExposed) | 2747 | if (type == 0x30) |
1620 | { | 2748 | { |
1621 | if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != LLUUID.Zero) | 2749 | if (m_shape.SculptEntry && m_shape.SculptTexture != LLUUID.Zero) |
1622 | { | 2750 | { |
1623 | m_parentGroup.Scene.AssetCache.GetAsset(dupe.m_shape.SculptTexture, dupe.SculptTextureCallback, true); | 2751 | //AssetBase tx = m_parentGroup.Scene.getase |
2752 | m_parentGroup.Scene.AssetCache.GetAsset(m_shape.SculptTexture, SculptTextureCallback, true); | ||
1624 | } | 2753 | } |
1625 | bool UsePhysics = ((dupe.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0); | ||
1626 | dupe.DoPhysicsPropertyUpdate(UsePhysics, true); | ||
1627 | } | 2754 | } |
1628 | return dupe; | ||
1629 | } | ||
1630 | 2755 | ||
1631 | #endregion | 2756 | ParentGroup.HasGroupChanged = true; |
1632 | 2757 | ScheduleFullUpdate(); | |
1633 | /// <summary> | ||
1634 | /// Reset LLUUIDs for this part. This involves generate this part's own LLUUID and | ||
1635 | /// generating new LLUUIDs for all the items in the inventory. | ||
1636 | /// </summary> | ||
1637 | /// <param name="linkNum">Link number for the part</param> | ||
1638 | public void ResetIDs(int linkNum) | ||
1639 | { | ||
1640 | UUID = LLUUID.Random(); | ||
1641 | LinkNum = linkNum; | ||
1642 | |||
1643 | ResetInventoryIDs(); | ||
1644 | } | ||
1645 | |||
1646 | #region Update Scheduling | ||
1647 | |||
1648 | /// <summary> | ||
1649 | /// Clear all pending updates | ||
1650 | /// </summary> | ||
1651 | private void ClearUpdateSchedule() | ||
1652 | { | ||
1653 | m_updateFlag = 0; | ||
1654 | } | ||
1655 | |||
1656 | /// <summary> | ||
1657 | /// Schedules this prim for a full update | ||
1658 | /// </summary> | ||
1659 | public void ScheduleFullUpdate() | ||
1660 | { | ||
1661 | if (m_parentGroup != null) | ||
1662 | { | ||
1663 | m_parentGroup.QueueForUpdateCheck(); | ||
1664 | } | ||
1665 | |||
1666 | int timeNow = Util.UnixTimeSinceEpoch(); | ||
1667 | |||
1668 | // If multiple updates are scheduled on the same second, we still need to perform all of them | ||
1669 | // So we'll force the issue by bumping up the timestamp so that later processing sees these need | ||
1670 | // to be performed. | ||
1671 | if (timeNow <= TimeStampFull) | ||
1672 | { | ||
1673 | TimeStampFull += 1; | ||
1674 | } | ||
1675 | else | ||
1676 | { | ||
1677 | TimeStampFull = (uint)timeNow; | ||
1678 | } | ||
1679 | |||
1680 | m_updateFlag = 2; | ||
1681 | |||
1682 | // m_log.DebugFormat( | ||
1683 | // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", | ||
1684 | // UUID, Name, TimeStampFull); | ||
1685 | } | 2758 | } |
1686 | 2759 | ||
1687 | public void AddFlag(LLObject.ObjectFlags flag) | 2760 | public void UpdateGroupPosition(LLVector3 pos) |
1688 | { | 2761 | { |
1689 | LLObject.ObjectFlags prevflag = Flags; | 2762 | if ((pos.X != GroupPosition.X) || |
1690 | //uint objflags = Flags; | 2763 | (pos.Y != GroupPosition.Y) || |
1691 | if ((ObjectFlags & (uint) flag) == 0) | 2764 | (pos.Z != GroupPosition.Z)) |
1692 | { | 2765 | { |
1693 | //Console.WriteLine("Adding flag: " + ((LLObject.ObjectFlags) flag).ToString()); | 2766 | LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z); |
1694 | Flags |= flag; | 2767 | GroupPosition = newPos; |
2768 | ScheduleTerseUpdate(); | ||
1695 | } | 2769 | } |
1696 | //uint currflag = (uint)Flags; | ||
1697 | //System.Console.WriteLine("Aprev: " + prevflag.ToString() + " curr: " + Flags.ToString()); | ||
1698 | //ScheduleFullUpdate(); | ||
1699 | } | 2770 | } |
1700 | 2771 | ||
1701 | public void RemFlag(LLObject.ObjectFlags flag) | 2772 | public virtual void UpdateMovement() |
1702 | { | 2773 | { |
1703 | LLObject.ObjectFlags prevflag = Flags; | ||
1704 | if ((ObjectFlags & (uint) flag) != 0) | ||
1705 | { | ||
1706 | //Console.WriteLine("Removing flag: " + ((LLObject.ObjectFlags)flag).ToString()); | ||
1707 | Flags &= ~flag; | ||
1708 | } | ||
1709 | //System.Console.WriteLine("prev: " + prevflag.ToString() + " curr: " + Flags.ToString()); | ||
1710 | //ScheduleFullUpdate(); | ||
1711 | } | 2774 | } |
1712 | 2775 | ||
1713 | /// <summary> | 2776 | /// <summary> |
1714 | /// Schedule a terse update for this prim. Terse updates only send position, | 2777 | /// |
1715 | /// rotation, velocity, rotational velocity and shape information. | ||
1716 | /// </summary> | 2778 | /// </summary> |
1717 | public void ScheduleTerseUpdate() | 2779 | /// <param name="pos"></param> |
2780 | public void UpdateOffSet(LLVector3 pos) | ||
1718 | { | 2781 | { |
1719 | if (m_updateFlag < 1) | 2782 | if ((pos.X != OffsetPosition.X) || |
2783 | (pos.Y != OffsetPosition.Y) || | ||
2784 | (pos.Z != OffsetPosition.Z)) | ||
1720 | { | 2785 | { |
1721 | if (m_parentGroup != null) | 2786 | LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z); |
1722 | { | 2787 | OffsetPosition = newPos; |
1723 | m_parentGroup.HasGroupChanged = true; | 2788 | ScheduleTerseUpdate(); |
1724 | m_parentGroup.QueueForUpdateCheck(); | ||
1725 | } | ||
1726 | TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); | ||
1727 | m_updateFlag = 1; | ||
1728 | |||
1729 | // m_log.DebugFormat( | ||
1730 | // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", | ||
1731 | // UUID, Name, TimeStampTerse); | ||
1732 | } | 2789 | } |
1733 | } | 2790 | } |
1734 | 2791 | ||
1735 | /// <summary> | 2792 | public void UpdatePermissions(LLUUID AgentID, byte field, uint localID, uint mask, byte addRemTF) |
1736 | /// Tell all the prims which have had updates scheduled | ||
1737 | /// </summary> | ||
1738 | public void SendScheduledUpdates() | ||
1739 | { | 2793 | { |
1740 | if (m_updateFlag == 1) //some change has been made so update the clients | 2794 | bool set = addRemTF == 1; |
1741 | { | ||
1742 | AddTerseUpdateToAllAvatars(); | ||
1743 | ClearUpdateSchedule(); | ||
1744 | 2795 | ||
1745 | // This causes the Scene to 'poll' physical objects every couple of frames | 2796 | // Are we the owner? |
1746 | // bad, so it's been replaced by an event driven method. | 2797 | if (AgentID == OwnerID) |
1747 | //if ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0) | ||
1748 | //{ | ||
1749 | // Only send the constant terse updates on physical objects! | ||
1750 | //ScheduleTerseUpdate(); | ||
1751 | //} | ||
1752 | } | ||
1753 | else | ||
1754 | { | 2798 | { |
1755 | if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes | 2799 | switch (field) |
1756 | { | 2800 | { |
1757 | AddFullUpdateToAllAvatars(); | 2801 | case 2: |
1758 | ClearUpdateSchedule(); | 2802 | OwnerMask = ApplyMask(OwnerMask, set, mask); |
2803 | break; | ||
2804 | case 4: | ||
2805 | GroupMask = ApplyMask(GroupMask, set, mask); | ||
2806 | break; | ||
2807 | case 8: | ||
2808 | EveryoneMask = ApplyMask(EveryoneMask, set, mask); | ||
2809 | break; | ||
2810 | case 16: | ||
2811 | NextOwnerMask = ApplyMask(NextOwnerMask, set, mask); | ||
2812 | break; | ||
1759 | } | 2813 | } |
1760 | } | 2814 | SendFullUpdateToAllClients(); |
1761 | } | ||
1762 | |||
1763 | #endregion | ||
1764 | 2815 | ||
1765 | #region Shape | 2816 | SendObjectPropertiesToClient(AgentID); |
1766 | 2817 | ||
1767 | /// <summary> | ||
1768 | /// Update the shape of this part. | ||
1769 | /// </summary> | ||
1770 | /// <param name="shapeBlock"></param> | ||
1771 | public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) | ||
1772 | { | ||
1773 | m_shape.PathBegin = shapeBlock.PathBegin; | ||
1774 | m_shape.PathEnd = shapeBlock.PathEnd; | ||
1775 | m_shape.PathScaleX = shapeBlock.PathScaleX; | ||
1776 | m_shape.PathScaleY = shapeBlock.PathScaleY; | ||
1777 | m_shape.PathShearX = shapeBlock.PathShearX; | ||
1778 | m_shape.PathShearY = shapeBlock.PathShearY; | ||
1779 | m_shape.PathSkew = shapeBlock.PathSkew; | ||
1780 | m_shape.ProfileBegin = shapeBlock.ProfileBegin; | ||
1781 | m_shape.ProfileEnd = shapeBlock.ProfileEnd; | ||
1782 | m_shape.PathCurve = shapeBlock.PathCurve; | ||
1783 | m_shape.ProfileCurve = shapeBlock.ProfileCurve; | ||
1784 | m_shape.ProfileHollow = shapeBlock.ProfileHollow; | ||
1785 | m_shape.PathRadiusOffset = shapeBlock.PathRadiusOffset; | ||
1786 | m_shape.PathRevolutions = shapeBlock.PathRevolutions; | ||
1787 | m_shape.PathTaperX = shapeBlock.PathTaperX; | ||
1788 | m_shape.PathTaperY = shapeBlock.PathTaperY; | ||
1789 | m_shape.PathTwist = shapeBlock.PathTwist; | ||
1790 | m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; | ||
1791 | if (PhysActor != null) | ||
1792 | { | ||
1793 | PhysActor.Shape = m_shape; | ||
1794 | } | 2818 | } |
1795 | |||
1796 | ParentGroup.HasGroupChanged = true; | ||
1797 | ScheduleFullUpdate(); | ||
1798 | } | 2819 | } |
1799 | 2820 | ||
1800 | #endregion | ||
1801 | |||
1802 | #region ExtraParams | ||
1803 | |||
1804 | public void UpdatePrimFlags(ushort type, bool inUse, byte[] data) | 2821 | public void UpdatePrimFlags(ushort type, bool inUse, byte[] data) |
1805 | { | 2822 | { |
1806 | //m_log.Info("TSomething1:" + ((type & (ushort)ExtraParamType.Something1) == (ushort)ExtraParamType.Something1)); | 2823 | //m_log.Info("TSomething1:" + ((type & (ushort)ExtraParamType.Something1) == (ushort)ExtraParamType.Something1)); |
@@ -1930,152 +2947,49 @@ namespace OpenSim.Region.Environment.Scenes | |||
1930 | ScheduleFullUpdate(); | 2947 | ScheduleFullUpdate(); |
1931 | } | 2948 | } |
1932 | 2949 | ||
1933 | public void ScriptSetPhysicsStatus(bool UsePhysics) | 2950 | public void UpdateRotation(LLQuaternion rot) |
1934 | { | ||
1935 | if (m_parentGroup != null) | ||
1936 | { | ||
1937 | m_parentGroup.ScriptSetPhysicsStatus(UsePhysics); | ||
1938 | } | ||
1939 | } | ||
1940 | |||
1941 | public void ScriptSetPhantomStatus(bool Phantom) | ||
1942 | { | ||
1943 | if (m_parentGroup != null) | ||
1944 | { | ||
1945 | m_parentGroup.ScriptSetPhantomStatus(Phantom); | ||
1946 | } | ||
1947 | } | ||
1948 | |||
1949 | public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) | ||
1950 | { | ||
1951 | if (PhysActor != null) | ||
1952 | { | ||
1953 | if (UsePhysics != PhysActor.IsPhysical || isNew) | ||
1954 | { | ||
1955 | if (PhysActor.IsPhysical) | ||
1956 | { | ||
1957 | if (!isNew) | ||
1958 | ParentGroup.Scene.RemovePhysicalPrim(1); | ||
1959 | |||
1960 | PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; | ||
1961 | PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; | ||
1962 | PhysActor.delink(); | ||
1963 | } | ||
1964 | |||
1965 | PhysActor.IsPhysical = UsePhysics; | ||
1966 | |||
1967 | |||
1968 | // If we're not what we're supposed to be in the physics scene, recreate ourselves. | ||
1969 | //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); | ||
1970 | /// that's not wholesome. Had to make Scene public | ||
1971 | //PhysActor = null; | ||
1972 | |||
1973 | if ((ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) == 0) | ||
1974 | { | ||
1975 | //PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( | ||
1976 | //Name, | ||
1977 | //Shape, | ||
1978 | //new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y, | ||
1979 | //AbsolutePosition.Z), | ||
1980 | //new PhysicsVector(Scale.X, Scale.Y, Scale.Z), | ||
1981 | //new Quaternion(RotationOffset.W, RotationOffset.X, | ||
1982 | //RotationOffset.Y, RotationOffset.Z), UsePhysics); | ||
1983 | if (UsePhysics) | ||
1984 | { | ||
1985 | ParentGroup.Scene.AddPhysicalPrim(1); | ||
1986 | |||
1987 | PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; | ||
1988 | PhysActor.OnOutOfBounds += PhysicsOutOfBounds; | ||
1989 | if (ParentID != 0 && ParentID != LocalId) | ||
1990 | { | ||
1991 | if (ParentGroup.RootPart.PhysActor != null) | ||
1992 | { | ||
1993 | PhysActor.link(ParentGroup.RootPart.PhysActor); | ||
1994 | } | ||
1995 | } | ||
1996 | } | ||
1997 | } | ||
1998 | } | ||
1999 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
2000 | } | ||
2001 | } | ||
2002 | |||
2003 | public void UpdateExtraParam(ushort type, bool inUse, byte[] data) | ||
2004 | { | ||
2005 | m_shape.ReadInUpdateExtraParam(type, inUse, data); | ||
2006 | |||
2007 | if (type == 0x30) | ||
2008 | { | ||
2009 | if (m_shape.SculptEntry && m_shape.SculptTexture != LLUUID.Zero) | ||
2010 | { | ||
2011 | //AssetBase tx = m_parentGroup.Scene.getase | ||
2012 | m_parentGroup.Scene.AssetCache.GetAsset(m_shape.SculptTexture, SculptTextureCallback, true); | ||
2013 | } | ||
2014 | } | ||
2015 | |||
2016 | ParentGroup.HasGroupChanged = true; | ||
2017 | ScheduleFullUpdate(); | ||
2018 | } | ||
2019 | |||
2020 | public void SculptTextureCallback(LLUUID textureID, AssetBase texture) | ||
2021 | { | ||
2022 | if (m_shape.SculptEntry) | ||
2023 | { | ||
2024 | if (texture != null) | ||
2025 | { | ||
2026 | m_shape.SculptData = texture.Data; | ||
2027 | if (PhysActor != null) | ||
2028 | { | ||
2029 | // Tricks physics engine into thinking we've changed the part shape. | ||
2030 | PrimitiveBaseShape m_newshape = m_shape.Copy(); | ||
2031 | PhysActor.Shape = m_newshape; | ||
2032 | m_shape = m_newshape; | ||
2033 | } | ||
2034 | } | ||
2035 | } | ||
2036 | } | ||
2037 | |||
2038 | #endregion | ||
2039 | |||
2040 | #region Physics | ||
2041 | |||
2042 | public float GetMass() | ||
2043 | { | 2951 | { |
2044 | if (PhysActor != null) | 2952 | if ((rot.X != RotationOffset.X) || |
2045 | { | 2953 | (rot.Y != RotationOffset.Y) || |
2046 | return PhysActor.Mass; | 2954 | (rot.Z != RotationOffset.Z) || |
2047 | } | 2955 | (rot.W != RotationOffset.W)) |
2048 | else | ||
2049 | { | 2956 | { |
2050 | return 0; | 2957 | //StoreUndoState(); |
2958 | RotationOffset = new LLQuaternion(rot.X, rot.Y, rot.Z, rot.W); | ||
2959 | ParentGroup.HasGroupChanged = true; | ||
2960 | ScheduleTerseUpdate(); | ||
2051 | } | 2961 | } |
2052 | } | 2962 | } |
2053 | 2963 | ||
2054 | public LLVector3 GetGeometricCenter() | 2964 | /// <summary> |
2965 | /// Update the shape of this part. | ||
2966 | /// </summary> | ||
2967 | /// <param name="shapeBlock"></param> | ||
2968 | public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) | ||
2055 | { | 2969 | { |
2970 | m_shape.PathBegin = shapeBlock.PathBegin; | ||
2971 | m_shape.PathEnd = shapeBlock.PathEnd; | ||
2972 | m_shape.PathScaleX = shapeBlock.PathScaleX; | ||
2973 | m_shape.PathScaleY = shapeBlock.PathScaleY; | ||
2974 | m_shape.PathShearX = shapeBlock.PathShearX; | ||
2975 | m_shape.PathShearY = shapeBlock.PathShearY; | ||
2976 | m_shape.PathSkew = shapeBlock.PathSkew; | ||
2977 | m_shape.ProfileBegin = shapeBlock.ProfileBegin; | ||
2978 | m_shape.ProfileEnd = shapeBlock.ProfileEnd; | ||
2979 | m_shape.PathCurve = shapeBlock.PathCurve; | ||
2980 | m_shape.ProfileCurve = shapeBlock.ProfileCurve; | ||
2981 | m_shape.ProfileHollow = shapeBlock.ProfileHollow; | ||
2982 | m_shape.PathRadiusOffset = shapeBlock.PathRadiusOffset; | ||
2983 | m_shape.PathRevolutions = shapeBlock.PathRevolutions; | ||
2984 | m_shape.PathTaperX = shapeBlock.PathTaperX; | ||
2985 | m_shape.PathTaperY = shapeBlock.PathTaperY; | ||
2986 | m_shape.PathTwist = shapeBlock.PathTwist; | ||
2987 | m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; | ||
2056 | if (PhysActor != null) | 2988 | if (PhysActor != null) |
2057 | { | 2989 | { |
2058 | return new LLVector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); | 2990 | PhysActor.Shape = m_shape; |
2059 | } | ||
2060 | else | ||
2061 | { | ||
2062 | return new LLVector3(0, 0, 0); | ||
2063 | } | 2991 | } |
2064 | } | ||
2065 | |||
2066 | #endregion | ||
2067 | 2992 | ||
2068 | #region Texture | ||
2069 | |||
2070 | /// <summary> | ||
2071 | /// Update the texture entry for this part. | ||
2072 | /// </summary> | ||
2073 | /// <param name="textureEntry"></param> | ||
2074 | public void UpdateTextureEntry(byte[] textureEntry) | ||
2075 | { | ||
2076 | m_shape.TextureEntry = textureEntry; | ||
2077 | TriggerScriptChangedEvent(Changed.TEXTURE); | ||
2078 | |||
2079 | ParentGroup.HasGroupChanged = true; | 2993 | ParentGroup.HasGroupChanged = true; |
2080 | ScheduleFullUpdate(); | 2994 | ScheduleFullUpdate(); |
2081 | } | 2995 | } |
@@ -2107,684 +3021,19 @@ namespace OpenSim.Region.Environment.Scenes | |||
2107 | UpdateTextureEntry(tex.ToBytes()); | 3021 | UpdateTextureEntry(tex.ToBytes()); |
2108 | } | 3022 | } |
2109 | 3023 | ||
2110 | public byte ConvertScriptUintToByte(uint indata) | ||
2111 | { | ||
2112 | byte outdata = (byte)TextureAnimFlags.NONE; | ||
2113 | if ((indata & 1) != 0) outdata |= (byte)TextureAnimFlags.ANIM_ON; | ||
2114 | if ((indata & 2) != 0) outdata |= (byte)TextureAnimFlags.LOOP; | ||
2115 | if ((indata & 4) != 0) outdata |= (byte)TextureAnimFlags.REVERSE; | ||
2116 | if ((indata & 8) != 0) outdata |= (byte)TextureAnimFlags.PING_PONG; | ||
2117 | if ((indata & 16) != 0) outdata |= (byte)TextureAnimFlags.SMOOTH; | ||
2118 | if ((indata & 32) != 0) outdata |= (byte)TextureAnimFlags.ROTATE; | ||
2119 | if ((indata & 64) != 0) outdata |= (byte)TextureAnimFlags.SCALE; | ||
2120 | return outdata; | ||
2121 | } | ||
2122 | |||
2123 | public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) | ||
2124 | { | ||
2125 | byte[] data = new byte[16]; | ||
2126 | int pos = 0; | ||
2127 | |||
2128 | // The flags don't like conversion from uint to byte, so we have to do | ||
2129 | // it the crappy way. See the above function :( | ||
2130 | |||
2131 | data[pos] = ConvertScriptUintToByte(pTexAnim.Flags); pos++; | ||
2132 | data[pos] = (byte)pTexAnim.Face; pos++; | ||
2133 | data[pos] = (byte)pTexAnim.SizeX; pos++; | ||
2134 | data[pos] = (byte)pTexAnim.SizeY; pos++; | ||
2135 | |||
2136 | Helpers.FloatToBytes(pTexAnim.Start).CopyTo(data, pos); | ||
2137 | Helpers.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4); | ||
2138 | Helpers.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8); | ||
2139 | |||
2140 | m_TextureAnimation = data; | ||
2141 | } | ||
2142 | |||
2143 | #endregion | ||
2144 | |||
2145 | #region ParticleSystem | ||
2146 | |||
2147 | public void AddNewParticleSystem(Primitive.ParticleSystem pSystem) | ||
2148 | { | ||
2149 | m_particleSystem = pSystem.GetBytes(); | ||
2150 | } | ||
2151 | |||
2152 | #endregion | ||
2153 | |||
2154 | #region Position | ||
2155 | |||
2156 | /// <summary> | 3024 | /// <summary> |
2157 | /// | 3025 | /// Update the texture entry for this part. |
2158 | /// </summary> | ||
2159 | /// <param name="pos"></param> | ||
2160 | public void UpdateOffSet(LLVector3 pos) | ||
2161 | { | ||
2162 | if ((pos.X != OffsetPosition.X) || | ||
2163 | (pos.Y != OffsetPosition.Y) || | ||
2164 | (pos.Z != OffsetPosition.Z)) | ||
2165 | { | ||
2166 | LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z); | ||
2167 | OffsetPosition = newPos; | ||
2168 | ScheduleTerseUpdate(); | ||
2169 | } | ||
2170 | } | ||
2171 | |||
2172 | public void UpdateGroupPosition(LLVector3 pos) | ||
2173 | { | ||
2174 | if ((pos.X != GroupPosition.X) || | ||
2175 | (pos.Y != GroupPosition.Y) || | ||
2176 | (pos.Z != GroupPosition.Z)) | ||
2177 | { | ||
2178 | LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z); | ||
2179 | GroupPosition = newPos; | ||
2180 | ScheduleTerseUpdate(); | ||
2181 | } | ||
2182 | } | ||
2183 | |||
2184 | #endregion | ||
2185 | |||
2186 | #region rotation | ||
2187 | |||
2188 | public void UpdateRotation(LLQuaternion rot) | ||
2189 | { | ||
2190 | if ((rot.X != RotationOffset.X) || | ||
2191 | (rot.Y != RotationOffset.Y) || | ||
2192 | (rot.Z != RotationOffset.Z) || | ||
2193 | (rot.W != RotationOffset.W)) | ||
2194 | { | ||
2195 | //StoreUndoState(); | ||
2196 | RotationOffset = new LLQuaternion(rot.X, rot.Y, rot.Z, rot.W); | ||
2197 | ParentGroup.HasGroupChanged = true; | ||
2198 | ScheduleTerseUpdate(); | ||
2199 | } | ||
2200 | } | ||
2201 | |||
2202 | #endregion | ||
2203 | |||
2204 | #region Sound | ||
2205 | public void PreloadSound(string sound) | ||
2206 | { | ||
2207 | LLUUID ownerID = OwnerID; | ||
2208 | LLUUID objectID = UUID; | ||
2209 | LLUUID soundID = LLUUID.Zero; | ||
2210 | |||
2211 | if (!LLUUID.TryParse(sound, out soundID)) | ||
2212 | { | ||
2213 | //Trys to fetch sound id from prim's inventory. | ||
2214 | //Prim's inventory doesn't support non script items yet | ||
2215 | SceneObjectPart op = this; | ||
2216 | foreach (KeyValuePair<LLUUID, TaskInventoryItem> item in op.TaskInventory) | ||
2217 | { | ||
2218 | if (item.Value.Name == sound) | ||
2219 | { | ||
2220 | soundID = item.Value.ItemID; | ||
2221 | break; | ||
2222 | } | ||
2223 | } | ||
2224 | } | ||
2225 | |||
2226 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); | ||
2227 | foreach (ScenePresence p in avatarts) | ||
2228 | { | ||
2229 | // TODO: some filtering by distance of avatar | ||
2230 | |||
2231 | p.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); | ||
2232 | } | ||
2233 | } | ||
2234 | |||
2235 | public void AdjustSoundGain(double volume) | ||
2236 | { | ||
2237 | if (volume > 1) | ||
2238 | volume = 1; | ||
2239 | if (volume < 0) | ||
2240 | volume = 0; | ||
2241 | |||
2242 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); | ||
2243 | foreach (ScenePresence p in avatarts) | ||
2244 | { | ||
2245 | p.ControllingClient.SendAttachedSoundGainChange(UUID, (float)volume); | ||
2246 | } | ||
2247 | } | ||
2248 | |||
2249 | public void SendSound(string sound, double volume, bool triggered, byte flags) | ||
2250 | { | ||
2251 | if (volume > 1) | ||
2252 | volume = 1; | ||
2253 | if (volume < 0) | ||
2254 | volume = 0; | ||
2255 | |||
2256 | LLUUID ownerID = OwnerID; | ||
2257 | LLUUID objectID = UUID; | ||
2258 | LLUUID parentID = GetRootPartUUID(); | ||
2259 | LLUUID soundID = LLUUID.Zero; | ||
2260 | LLVector3 position = AbsolutePosition; // region local | ||
2261 | ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle; | ||
2262 | |||
2263 | //byte flags = 0; | ||
2264 | |||
2265 | if (!LLUUID.TryParse(sound, out soundID)) | ||
2266 | { | ||
2267 | // search sound file from inventory | ||
2268 | SceneObjectPart op = this; | ||
2269 | foreach (KeyValuePair<LLUUID, TaskInventoryItem> item in op.TaskInventory) | ||
2270 | { | ||
2271 | if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) | ||
2272 | { | ||
2273 | soundID = item.Value.ItemID; | ||
2274 | break; | ||
2275 | } | ||
2276 | } | ||
2277 | } | ||
2278 | |||
2279 | if (soundID == LLUUID.Zero) | ||
2280 | return; | ||
2281 | |||
2282 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); | ||
2283 | foreach (ScenePresence p in avatarts) | ||
2284 | { | ||
2285 | double dis=Util.GetDistanceTo(p.AbsolutePosition, position); | ||
2286 | if (dis > 100.0) // Max audio distance | ||
2287 | continue; | ||
2288 | |||
2289 | // Scale by distance | ||
2290 | volume*=((100.0-dis)/100.0); | ||
2291 | |||
2292 | if (triggered) | ||
2293 | { | ||
2294 | p.ControllingClient.SendTriggeredSound(soundID, ownerID, objectID, parentID, regionHandle, position, (float)volume); | ||
2295 | } | ||
2296 | else | ||
2297 | { | ||
2298 | p.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)volume, flags); | ||
2299 | } | ||
2300 | } | ||
2301 | } | ||
2302 | |||
2303 | #endregion | ||
2304 | |||
2305 | #region Resizing/Scale | ||
2306 | |||
2307 | /// <summary> | ||
2308 | /// Resize this part. | ||
2309 | /// </summary> | ||
2310 | /// <param name="scale"></param> | ||
2311 | public void Resize(LLVector3 scale) | ||
2312 | { | ||
2313 | StoreUndoState(); | ||
2314 | m_shape.Scale = scale; | ||
2315 | |||
2316 | ParentGroup.HasGroupChanged = true; | ||
2317 | ScheduleFullUpdate(); | ||
2318 | } | ||
2319 | |||
2320 | #endregion | ||
2321 | |||
2322 | public void UpdatePermissions(LLUUID AgentID, byte field, uint localID, uint mask, byte addRemTF) | ||
2323 | { | ||
2324 | bool set = addRemTF == 1; | ||
2325 | |||
2326 | // Are we the owner? | ||
2327 | if (AgentID == OwnerID) | ||
2328 | { | ||
2329 | switch (field) | ||
2330 | { | ||
2331 | case 2: | ||
2332 | OwnerMask = ApplyMask(OwnerMask, set, mask); | ||
2333 | break; | ||
2334 | case 4: | ||
2335 | GroupMask = ApplyMask(GroupMask, set, mask); | ||
2336 | break; | ||
2337 | case 8: | ||
2338 | EveryoneMask = ApplyMask(EveryoneMask, set, mask); | ||
2339 | break; | ||
2340 | case 16: | ||
2341 | NextOwnerMask = ApplyMask(NextOwnerMask, set, mask); | ||
2342 | break; | ||
2343 | } | ||
2344 | SendFullUpdateToAllClients(); | ||
2345 | |||
2346 | SendObjectPropertiesToClient(AgentID); | ||
2347 | |||
2348 | } | ||
2349 | } | ||
2350 | |||
2351 | private void SendObjectPropertiesToClient(LLUUID AgentID) | ||
2352 | { | ||
2353 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); | ||
2354 | for (int i = 0; i < avatars.Count; i++) | ||
2355 | { | ||
2356 | // Ugly reference :( | ||
2357 | if (avatars[i].UUID == AgentID) | ||
2358 | { | ||
2359 | m_parentGroup.GetProperties(avatars[i].ControllingClient); | ||
2360 | } | ||
2361 | } | ||
2362 | } | ||
2363 | |||
2364 | private uint ApplyMask(uint val, bool set, uint mask) | ||
2365 | { | ||
2366 | if (set) | ||
2367 | { | ||
2368 | return val |= mask; | ||
2369 | } | ||
2370 | else | ||
2371 | { | ||
2372 | return val &= ~mask; | ||
2373 | } | ||
2374 | } | ||
2375 | |||
2376 | #region Client Update Methods | ||
2377 | |||
2378 | /// <summary> | ||
2379 | /// Tell all scene presences that they should send updates for this part to their clients | ||
2380 | /// </summary> | ||
2381 | public void AddFullUpdateToAllAvatars() | ||
2382 | { | ||
2383 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); | ||
2384 | for (int i = 0; i < avatars.Count; i++) | ||
2385 | { | ||
2386 | avatars[i].QueuePartForUpdate(this); | ||
2387 | } | ||
2388 | } | ||
2389 | |||
2390 | public void SendFullUpdateToAllClientsExcept(LLUUID agentID) | ||
2391 | { | ||
2392 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); | ||
2393 | for (int i = 0; i < avatars.Count; i++) | ||
2394 | { | ||
2395 | // Ugly reference :( | ||
2396 | if (avatars[i].UUID != agentID) | ||
2397 | { | ||
2398 | m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this, | ||
2399 | avatars[i].GenerateClientFlags(UUID)); | ||
2400 | } | ||
2401 | } | ||
2402 | } | ||
2403 | |||
2404 | public void AddFullUpdateToAvatar(ScenePresence presence) | ||
2405 | { | ||
2406 | presence.QueuePartForUpdate(this); | ||
2407 | } | ||
2408 | |||
2409 | /// <summary> | ||
2410 | /// | ||
2411 | /// </summary> | ||
2412 | public void SendFullUpdateToAllClients() | ||
2413 | { | ||
2414 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); | ||
2415 | for (int i = 0; i < avatars.Count; i++) | ||
2416 | { | ||
2417 | // Ugly reference :( | ||
2418 | m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this, | ||
2419 | avatars[i].GenerateClientFlags(UUID)); | ||
2420 | } | ||
2421 | } | ||
2422 | |||
2423 | /// <summary> | ||
2424 | /// | ||
2425 | /// </summary> | ||
2426 | /// <param name="remoteClient"></param> | ||
2427 | public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) | ||
2428 | { | ||
2429 | m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); | ||
2430 | } | ||
2431 | |||
2432 | /// <summary> | ||
2433 | /// Sends a full update to the client | ||
2434 | /// </summary> | ||
2435 | /// <param name="remoteClient"></param> | ||
2436 | /// <param name="clientFlags"></param> | ||
2437 | public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientflags) | ||
2438 | { | ||
2439 | LLVector3 lPos; | ||
2440 | lPos = OffsetPosition; | ||
2441 | SendFullUpdateToClient(remoteClient, lPos, clientflags); | ||
2442 | } | ||
2443 | |||
2444 | /// <summary> | ||
2445 | /// Sends a full update to the client | ||
2446 | /// </summary> | ||
2447 | /// <param name="remoteClient"></param> | ||
2448 | /// <param name="lPos"></param> | ||
2449 | /// <param name="clientFlags"></param> | ||
2450 | public void SendFullUpdateToClient(IClientAPI remoteClient, LLVector3 lPos, uint clientFlags) | ||
2451 | { | ||
2452 | clientFlags &= ~(uint) LLObject.ObjectFlags.CreateSelected; | ||
2453 | |||
2454 | if (remoteClient.AgentId == OwnerID) | ||
2455 | { | ||
2456 | if ((uint) (Flags & LLObject.ObjectFlags.CreateSelected) != 0) | ||
2457 | { | ||
2458 | clientFlags |= (uint) LLObject.ObjectFlags.CreateSelected; | ||
2459 | Flags &= ~LLObject.ObjectFlags.CreateSelected; | ||
2460 | } | ||
2461 | } | ||
2462 | |||
2463 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; | ||
2464 | remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, | ||
2465 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, OwnerID, | ||
2466 | m_text, color, ParentID, m_particleSystem, m_clickAction, m_TextureAnimation, m_IsAttachment, | ||
2467 | m_attachmentPoint,fromAssetID, Sound, SoundGain, SoundFlags, SoundRadius); | ||
2468 | } | ||
2469 | |||
2470 | /// Terse updates | ||
2471 | public void AddTerseUpdateToAllAvatars() | ||
2472 | { | ||
2473 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); | ||
2474 | for (int i = 0; i < avatars.Count; i++) | ||
2475 | { | ||
2476 | avatars[i].QueuePartForUpdate(this); | ||
2477 | } | ||
2478 | } | ||
2479 | |||
2480 | public void AddTerseUpdateToAvatar(ScenePresence presence) | ||
2481 | { | ||
2482 | presence.QueuePartForUpdate(this); | ||
2483 | } | ||
2484 | |||
2485 | /// <summary> | ||
2486 | /// | ||
2487 | /// </summary> | ||
2488 | public void SendTerseUpdateToAllClients() | ||
2489 | { | ||
2490 | List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); | ||
2491 | for (int i = 0; i < avatars.Count; i++) | ||
2492 | { | ||
2493 | m_parentGroup.SendPartTerseUpdate(avatars[i].ControllingClient, this); | ||
2494 | } | ||
2495 | } | ||
2496 | |||
2497 | /// <summary> | ||
2498 | /// Send a terse update to the client. | ||
2499 | /// </summary> | 3026 | /// </summary> |
2500 | /// <param name="remoteClient"></param> | 3027 | /// <param name="textureEntry"></param> |
2501 | public void SendTerseUpdate(IClientAPI remoteClient) | 3028 | public void UpdateTextureEntry(byte[] textureEntry) |
2502 | { | ||
2503 | m_parentGroup.SendPartTerseUpdate(remoteClient, this); | ||
2504 | } | ||
2505 | |||
2506 | public void SendTerseUpdateToClient(IClientAPI remoteClient) | ||
2507 | { | ||
2508 | LLVector3 lPos; | ||
2509 | lPos = OffsetPosition; | ||
2510 | LLQuaternion mRot = RotationOffset; | ||
2511 | // TODO: I have no idea why we are making this check. This should be sorted out | ||
2512 | if ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0) | ||
2513 | { | ||
2514 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, RotationalVelocity, Shape.State, fromAssetID); | ||
2515 | } | ||
2516 | else | ||
2517 | { | ||
2518 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, | ||
2519 | RotationalVelocity); | ||
2520 | //System.Console.WriteLine("LID: " + LocalID + " RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString()); | ||
2521 | } | ||
2522 | } | ||
2523 | |||
2524 | public void SendTerseUpdateToClient(IClientAPI remoteClient, LLVector3 lPos) | ||
2525 | { | ||
2526 | LLQuaternion mRot = RotationOffset; | ||
2527 | if (m_IsAttachment) | ||
2528 | { | ||
2529 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, RotationalVelocity, (byte)((m_attachmentPoint % 16) * 16 + (m_attachmentPoint / 16)),fromAssetID); | ||
2530 | } | ||
2531 | else | ||
2532 | { | ||
2533 | if ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) == 0) | ||
2534 | { | ||
2535 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, RotationalVelocity, Shape.State, fromAssetID); | ||
2536 | } | ||
2537 | else | ||
2538 | { | ||
2539 | remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, | ||
2540 | RotationalVelocity); | ||
2541 | //System.Console.WriteLine("LID: " + LocalID + "RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString()); | ||
2542 | } | ||
2543 | } | ||
2544 | } | ||
2545 | |||
2546 | #endregion | ||
2547 | |||
2548 | public virtual void UpdateMovement() | ||
2549 | { | ||
2550 | } | ||
2551 | |||
2552 | #region Events | ||
2553 | |||
2554 | public void PhysicsRequestingTerseUpdate() | ||
2555 | { | ||
2556 | if (PhysActor != null) | ||
2557 | { | ||
2558 | LLVector3 newpos = new LLVector3(PhysActor.Position.GetBytes(), 0); | ||
2559 | if (newpos.X > 257f || newpos.X < -1f || newpos.Y > 257f || newpos.Y < -1f) | ||
2560 | { | ||
2561 | m_parentGroup.AbsolutePosition = newpos; | ||
2562 | return; | ||
2563 | } | ||
2564 | } | ||
2565 | ScheduleTerseUpdate(); | ||
2566 | |||
2567 | //SendTerseUpdateToAllClients(); | ||
2568 | } | ||
2569 | |||
2570 | #endregion | ||
2571 | |||
2572 | public void PhysicsOutOfBounds(PhysicsVector pos) | ||
2573 | { | ||
2574 | m_log.Info("[PHYSICS]: Physical Object went out of bounds."); | ||
2575 | RemFlag(LLObject.ObjectFlags.Physics); | ||
2576 | DoPhysicsPropertyUpdate(false, true); | ||
2577 | //m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
2578 | } | ||
2579 | |||
2580 | public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient) | ||
2581 | { | 3029 | { |
2582 | } | 3030 | m_shape.TextureEntry = textureEntry; |
3031 | TriggerScriptChangedEvent(Changed.TEXTURE); | ||
2583 | 3032 | ||
2584 | /// <summary> | ||
2585 | /// Set the text displayed for this part. | ||
2586 | /// </summary> | ||
2587 | /// <param name="text"></param> | ||
2588 | public void SetText(string text) | ||
2589 | { | ||
2590 | Text = text; | ||
2591 | |||
2592 | ParentGroup.HasGroupChanged = true; | 3033 | ParentGroup.HasGroupChanged = true; |
2593 | ScheduleFullUpdate(); | 3034 | ScheduleFullUpdate(); |
2594 | } | 3035 | } |
2595 | 3036 | ||
2596 | /// <summary> | ||
2597 | /// Set the text displayed for this part. | ||
2598 | /// </summary> | ||
2599 | /// <param name="text"></param> | ||
2600 | /// <param name="color"></param> | ||
2601 | /// <param name="alpha"></param> | ||
2602 | public void SetText(string text, Vector3 color, double alpha) | ||
2603 | { | ||
2604 | Color = Color.FromArgb(0xff - (int) (alpha*0xff), | ||
2605 | (int) (color.x*0xff), | ||
2606 | (int) (color.y*0xff), | ||
2607 | (int) (color.z*0xff)); | ||
2608 | SetText(text); | ||
2609 | } | ||
2610 | |||
2611 | public int registerTargetWaypoint(LLVector3 target, float tolerance) | ||
2612 | { | ||
2613 | if (m_parentGroup != null) | ||
2614 | { | ||
2615 | return m_parentGroup.registerTargetWaypoint(target, tolerance); | ||
2616 | } | ||
2617 | return 0; | ||
2618 | } | ||
2619 | public void unregisterTargetWaypoint(int handle) | ||
2620 | { | ||
2621 | if (m_parentGroup != null) | ||
2622 | { | ||
2623 | m_parentGroup.unregisterTargetWaypoint(handle); | ||
2624 | } | ||
2625 | } | ||
2626 | protected SceneObjectPart(SerializationInfo info, StreamingContext context) | ||
2627 | { | ||
2628 | //System.Console.WriteLine("SceneObjectPart Deserialize BGN"); | ||
2629 | |||
2630 | if (info == null) | ||
2631 | { | ||
2632 | throw new ArgumentNullException("info"); | ||
2633 | } | ||
2634 | |||
2635 | /* | ||
2636 | m_queue = (Queue<SceneObjectPart>)info.GetValue("m_queue", typeof(Queue<SceneObjectPart>)); | ||
2637 | m_ids = (List<LLUUID>)info.GetValue("m_ids", typeof(List<LLUUID>)); | ||
2638 | */ | ||
2639 | |||
2640 | //System.Console.WriteLine("SceneObjectPart Deserialize END"); | ||
2641 | } | ||
2642 | |||
2643 | [SecurityPermission(SecurityAction.LinkDemand, | ||
2644 | Flags = SecurityPermissionFlag.SerializationFormatter)] | ||
2645 | public virtual void GetObjectData( | ||
2646 | SerializationInfo info, StreamingContext context) | ||
2647 | { | ||
2648 | if (info == null) | ||
2649 | { | ||
2650 | throw new ArgumentNullException("info"); | ||
2651 | } | ||
2652 | |||
2653 | info.AddValue("m_inventoryFileName", GetInventoryFileName()); | ||
2654 | info.AddValue("m_folderID", UUID); | ||
2655 | info.AddValue("PhysActor", PhysActor); | ||
2656 | |||
2657 | Dictionary<Guid, TaskInventoryItem> TaskInventory_work = new Dictionary<Guid, TaskInventoryItem>(); | ||
2658 | |||
2659 | foreach (LLUUID id in TaskInventory.Keys) | ||
2660 | { | ||
2661 | TaskInventory_work.Add(id.UUID, TaskInventory[id]); | ||
2662 | } | ||
2663 | |||
2664 | info.AddValue("TaskInventory", TaskInventory_work); | ||
2665 | |||
2666 | info.AddValue("LastOwnerID", LastOwnerID.UUID); | ||
2667 | info.AddValue("OwnerID", OwnerID.UUID); | ||
2668 | info.AddValue("GroupID", GroupID.UUID); | ||
2669 | |||
2670 | info.AddValue("OwnershipCost", OwnershipCost); | ||
2671 | info.AddValue("ObjectSaleType", ObjectSaleType); | ||
2672 | info.AddValue("SalePrice", SalePrice); | ||
2673 | info.AddValue("Category", Category); | ||
2674 | |||
2675 | info.AddValue("CreationDate", CreationDate); | ||
2676 | info.AddValue("ParentID", ParentID); | ||
2677 | |||
2678 | info.AddValue("OwnerMask", OwnerMask); | ||
2679 | info.AddValue("NextOwnerMask", NextOwnerMask); | ||
2680 | info.AddValue("GroupMask", GroupMask); | ||
2681 | info.AddValue("EveryoneMask", EveryoneMask); | ||
2682 | info.AddValue("BaseMask", BaseMask); | ||
2683 | |||
2684 | info.AddValue("m_particleSystem", m_particleSystem); | ||
2685 | |||
2686 | info.AddValue("TimeStampFull", TimeStampFull); | ||
2687 | info.AddValue("TimeStampTerse", TimeStampTerse); | ||
2688 | info.AddValue("TimeStampLastActivity", TimeStampLastActivity); | ||
2689 | |||
2690 | info.AddValue("m_updateFlag", m_updateFlag); | ||
2691 | info.AddValue("CreatorID", CreatorID.UUID); | ||
2692 | |||
2693 | info.AddValue("m_inventorySerial", m_inventorySerial); | ||
2694 | info.AddValue("m_uuid", m_uuid.UUID); | ||
2695 | info.AddValue("m_localID", m_localId); | ||
2696 | info.AddValue("m_name", m_name); | ||
2697 | info.AddValue("m_flags", Flags); | ||
2698 | info.AddValue("m_material", m_material); | ||
2699 | info.AddValue("m_regionHandle", m_regionHandle); | ||
2700 | |||
2701 | info.AddValue("m_groupPosition.X", m_groupPosition.X); | ||
2702 | info.AddValue("m_groupPosition.Y", m_groupPosition.Y); | ||
2703 | info.AddValue("m_groupPosition.Z", m_groupPosition.Z); | ||
2704 | |||
2705 | info.AddValue("m_offsetPosition.X", m_offsetPosition.X); | ||
2706 | info.AddValue("m_offsetPosition.Y", m_offsetPosition.Y); | ||
2707 | info.AddValue("m_offsetPosition.Z", m_offsetPosition.Z); | ||
2708 | |||
2709 | info.AddValue("m_rotationOffset.W", m_rotationOffset.W); | ||
2710 | info.AddValue("m_rotationOffset.X", m_rotationOffset.X); | ||
2711 | info.AddValue("m_rotationOffset.Y", m_rotationOffset.Y); | ||
2712 | info.AddValue("m_rotationOffset.Z", m_rotationOffset.Z); | ||
2713 | |||
2714 | info.AddValue("m_velocity.X", m_velocity.X); | ||
2715 | info.AddValue("m_velocity.Y", m_velocity.Y); | ||
2716 | info.AddValue("m_velocity.Z", m_velocity.Z); | ||
2717 | |||
2718 | info.AddValue("m_rotationalvelocity.X", m_rotationalvelocity.X); | ||
2719 | info.AddValue("m_rotationalvelocity.Y", m_rotationalvelocity.Y); | ||
2720 | info.AddValue("m_rotationalvelocity.Z", m_rotationalvelocity.Z); | ||
2721 | |||
2722 | info.AddValue("m_angularVelocity.X", m_angularVelocity.X); | ||
2723 | info.AddValue("m_angularVelocity.Y", m_angularVelocity.Y); | ||
2724 | info.AddValue("m_angularVelocity.Z", m_angularVelocity.Z); | ||
2725 | |||
2726 | info.AddValue("m_acceleration.X", m_acceleration.X); | ||
2727 | info.AddValue("m_acceleration.Y", m_acceleration.Y); | ||
2728 | info.AddValue("m_acceleration.Z", m_acceleration.Z); | ||
2729 | |||
2730 | info.AddValue("m_description", m_description); | ||
2731 | info.AddValue("m_color", m_color); | ||
2732 | info.AddValue("m_text", m_text); | ||
2733 | info.AddValue("m_sitName", m_sitName); | ||
2734 | info.AddValue("m_touchName", m_touchName); | ||
2735 | info.AddValue("m_clickAction", m_clickAction); | ||
2736 | info.AddValue("m_shape", m_shape); | ||
2737 | info.AddValue("m_parentGroup", m_parentGroup); | ||
2738 | info.AddValue("PayPrice", PayPrice); | ||
2739 | } | ||
2740 | |||
2741 | public void Undo() | ||
2742 | { | ||
2743 | if (m_undo.Count > 0) | ||
2744 | { | ||
2745 | UndoState goback = m_undo.Pop(); | ||
2746 | if (goback != null) | ||
2747 | goback.PlaybackState(this); | ||
2748 | } | ||
2749 | } | ||
2750 | |||
2751 | public void SetScriptEvents(LLUUID scriptid, int events) | ||
2752 | { | ||
2753 | scriptEvents oldparts; | ||
2754 | lock (m_scriptEvents) | ||
2755 | { | ||
2756 | if (m_scriptEvents.ContainsKey(scriptid)) | ||
2757 | { | ||
2758 | oldparts = m_scriptEvents[scriptid]; | ||
2759 | |||
2760 | // remove values from aggregated script events | ||
2761 | m_scriptEvents[scriptid] = (scriptEvents) events; | ||
2762 | } | ||
2763 | else | ||
2764 | { | ||
2765 | m_scriptEvents.Add(scriptid, (scriptEvents) events); | ||
2766 | } | ||
2767 | } | ||
2768 | aggregateScriptEvents(); | ||
2769 | } | ||
2770 | |||
2771 | public void RemoveScriptEvents(LLUUID scriptid) | ||
2772 | { | ||
2773 | lock (m_scriptEvents) | ||
2774 | { | ||
2775 | if (m_scriptEvents.ContainsKey(scriptid)) | ||
2776 | { | ||
2777 | scriptEvents oldparts = scriptEvents.None; | ||
2778 | oldparts = (scriptEvents) m_scriptEvents[scriptid]; | ||
2779 | |||
2780 | // remove values from aggregated script events | ||
2781 | m_aggregateScriptEvents &= ~oldparts; | ||
2782 | m_scriptEvents.Remove(scriptid); | ||
2783 | } | ||
2784 | } | ||
2785 | aggregateScriptEvents(); | ||
2786 | } | ||
2787 | |||
2788 | public void aggregateScriptEvents() | 3037 | public void aggregateScriptEvents() |
2789 | { | 3038 | { |
2790 | // Aggregate script events | 3039 | // Aggregate script events |
@@ -2856,325 +3105,23 @@ namespace OpenSim.Region.Environment.Scenes | |||
2856 | ScheduleFullUpdate(); | 3105 | ScheduleFullUpdate(); |
2857 | } | 3106 | } |
2858 | 3107 | ||
2859 | public void PhysicsCollision(EventArgs e) | 3108 | public int registerTargetWaypoint(LLVector3 target, float tolerance) |
2860 | { | 3109 | { |
2861 | // single threaded here | 3110 | if (m_parentGroup != null) |
2862 | if (e == null) | ||
2863 | { | ||
2864 | return; | ||
2865 | } | ||
2866 | |||
2867 | CollisionEventUpdate a = (CollisionEventUpdate)e; | ||
2868 | Dictionary<uint, float> collissionswith = a.m_objCollisionList; | ||
2869 | List<uint> thisHitColliders = new List<uint>(); | ||
2870 | List<uint> endedColliders = new List<uint>(); | ||
2871 | List<uint> startedColliders = new List<uint>(); | ||
2872 | |||
2873 | // calculate things that started colliding this time | ||
2874 | // and build up list of colliders this time | ||
2875 | foreach (uint localid in collissionswith.Keys) | ||
2876 | { | ||
2877 | if (localid != 0) | ||
2878 | { | ||
2879 | thisHitColliders.Add(localid); | ||
2880 | if (!m_lastColliders.Contains(localid)) | ||
2881 | { | ||
2882 | startedColliders.Add(localid); | ||
2883 | } | ||
2884 | |||
2885 | //m_log.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); | ||
2886 | } | ||
2887 | } | ||
2888 | |||
2889 | // calculate things that ended colliding | ||
2890 | foreach (uint localID in m_lastColliders) | ||
2891 | { | ||
2892 | if (!thisHitColliders.Contains(localID)) | ||
2893 | { | ||
2894 | endedColliders.Add(localID); | ||
2895 | } | ||
2896 | } | ||
2897 | |||
2898 | //add the items that started colliding this time to the last colliders list. | ||
2899 | foreach (uint localID in startedColliders) | ||
2900 | { | ||
2901 | m_lastColliders.Add(localID); | ||
2902 | } | ||
2903 | // remove things that ended colliding from the last colliders list | ||
2904 | foreach (uint localID in endedColliders) | ||
2905 | { | ||
2906 | m_lastColliders.Remove(localID); | ||
2907 | } | ||
2908 | if (m_parentGroup == null) | ||
2909 | return; | ||
2910 | if (m_parentGroup.RootPart == null) | ||
2911 | return; | ||
2912 | |||
2913 | if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) | ||
2914 | { | ||
2915 | // do event notification | ||
2916 | if (startedColliders.Count > 0) | ||
2917 | { | ||
2918 | ColliderArgs StartCollidingMessage = new ColliderArgs(); | ||
2919 | List<DetectedObject> colliding = new List<DetectedObject>(); | ||
2920 | foreach (uint localId in startedColliders) | ||
2921 | { | ||
2922 | // always running this check because if the user deletes the object it would return a null reference. | ||
2923 | if (m_parentGroup == null) | ||
2924 | return; | ||
2925 | if (m_parentGroup.Scene == null) | ||
2926 | return; | ||
2927 | SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); | ||
2928 | if (obj != null) | ||
2929 | { | ||
2930 | DetectedObject detobj = new DetectedObject(); | ||
2931 | detobj.keyUUID = obj.UUID; | ||
2932 | detobj.nameStr = obj.Name; | ||
2933 | detobj.ownerUUID = obj.OwnerID; | ||
2934 | detobj.posVector = obj.AbsolutePosition; | ||
2935 | detobj.rotQuat = obj.GetWorldRotation(); | ||
2936 | detobj.velVector = obj.Velocity; | ||
2937 | detobj.colliderType = 0; | ||
2938 | detobj.groupUUID = obj.GroupID; | ||
2939 | colliding.Add(detobj); | ||
2940 | } | ||
2941 | else | ||
2942 | { | ||
2943 | List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences(); | ||
2944 | if (avlist != null) | ||
2945 | { | ||
2946 | foreach (ScenePresence av in avlist) | ||
2947 | { | ||
2948 | if (av.LocalId == localId) | ||
2949 | { | ||
2950 | DetectedObject detobj = new DetectedObject(); | ||
2951 | detobj.keyUUID = av.UUID; | ||
2952 | detobj.nameStr = av.ControllingClient.Name; | ||
2953 | detobj.ownerUUID = av.UUID; | ||
2954 | detobj.posVector = av.AbsolutePosition; | ||
2955 | detobj.rotQuat = new LLQuaternion(av.Rotation.x, av.Rotation.y, av.Rotation.z, av.Rotation.w); | ||
2956 | detobj.velVector = av.Velocity; | ||
2957 | detobj.colliderType = 0; | ||
2958 | detobj.groupUUID = av.ControllingClient.ActiveGroupId; | ||
2959 | colliding.Add(detobj); | ||
2960 | } | ||
2961 | } | ||
2962 | } | ||
2963 | } | ||
2964 | } | ||
2965 | if (colliding.Count > 0) | ||
2966 | { | ||
2967 | StartCollidingMessage.Colliders = colliding; | ||
2968 | // always running this check because if the user deletes the object it would return a null reference. | ||
2969 | if (m_parentGroup == null) | ||
2970 | return; | ||
2971 | if (m_parentGroup.Scene == null) | ||
2972 | return; | ||
2973 | m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart(LocalId, StartCollidingMessage); | ||
2974 | } | ||
2975 | } | ||
2976 | } | ||
2977 | if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0) | ||
2978 | { | ||
2979 | if (m_lastColliders.Count > 0) | ||
2980 | { | ||
2981 | ColliderArgs CollidingMessage = new ColliderArgs(); | ||
2982 | List<DetectedObject> colliding = new List<DetectedObject>(); | ||
2983 | foreach (uint localId in m_lastColliders) | ||
2984 | { | ||
2985 | // always running this check because if the user deletes the object it would return a null reference. | ||
2986 | if (localId == 0) | ||
2987 | continue; | ||
2988 | |||
2989 | if (m_parentGroup == null) | ||
2990 | return; | ||
2991 | if (m_parentGroup.Scene == null) | ||
2992 | return; | ||
2993 | SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); | ||
2994 | if (obj != null) | ||
2995 | { | ||
2996 | DetectedObject detobj = new DetectedObject(); | ||
2997 | detobj.keyUUID = obj.UUID; | ||
2998 | detobj.nameStr = obj.Name; | ||
2999 | detobj.ownerUUID = obj.OwnerID; | ||
3000 | detobj.posVector = obj.AbsolutePosition; | ||
3001 | detobj.rotQuat = obj.GetWorldRotation(); | ||
3002 | detobj.velVector = obj.Velocity; | ||
3003 | detobj.colliderType = 0; | ||
3004 | detobj.groupUUID = obj.GroupID; | ||
3005 | colliding.Add(detobj); | ||
3006 | } | ||
3007 | else | ||
3008 | { | ||
3009 | List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences(); | ||
3010 | if (avlist != null) | ||
3011 | { | ||
3012 | foreach (ScenePresence av in avlist) | ||
3013 | { | ||
3014 | if (av.LocalId == localId) | ||
3015 | { | ||
3016 | DetectedObject detobj = new DetectedObject(); | ||
3017 | detobj.keyUUID = av.UUID; | ||
3018 | detobj.nameStr = av.Name; | ||
3019 | detobj.ownerUUID = av.UUID; | ||
3020 | detobj.posVector = av.AbsolutePosition; | ||
3021 | detobj.rotQuat = new LLQuaternion(av.Rotation.x, av.Rotation.y, av.Rotation.z, av.Rotation.w); | ||
3022 | detobj.velVector = av.Velocity; | ||
3023 | detobj.colliderType = 0; | ||
3024 | detobj.groupUUID = av.ControllingClient.ActiveGroupId; | ||
3025 | colliding.Add(detobj); | ||
3026 | } | ||
3027 | } | ||
3028 | |||
3029 | } | ||
3030 | } | ||
3031 | } | ||
3032 | if (colliding.Count > 0) | ||
3033 | { | ||
3034 | CollidingMessage.Colliders = colliding; | ||
3035 | // always running this check because if the user deletes the object it would return a null reference. | ||
3036 | if (m_parentGroup == null) | ||
3037 | return; | ||
3038 | if (m_parentGroup.Scene == null) | ||
3039 | return; | ||
3040 | m_parentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage); | ||
3041 | } | ||
3042 | |||
3043 | } | ||
3044 | } | ||
3045 | if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0) | ||
3046 | { | 3111 | { |
3047 | if (endedColliders.Count > 0) | 3112 | return m_parentGroup.registerTargetWaypoint(target, tolerance); |
3048 | { | ||
3049 | ColliderArgs EndCollidingMessage = new ColliderArgs(); | ||
3050 | List<DetectedObject> colliding = new List<DetectedObject>(); | ||
3051 | foreach (uint localId in endedColliders) | ||
3052 | { | ||
3053 | if (localId == 0) | ||
3054 | continue; | ||
3055 | |||
3056 | // always running this check because if the user deletes the object it would return a null reference. | ||
3057 | if (m_parentGroup == null) | ||
3058 | return; | ||
3059 | if (m_parentGroup.Scene == null) | ||
3060 | return; | ||
3061 | SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); | ||
3062 | if (obj != null) | ||
3063 | { | ||
3064 | DetectedObject detobj = new DetectedObject(); | ||
3065 | detobj.keyUUID = obj.UUID; | ||
3066 | detobj.nameStr = obj.Name; | ||
3067 | detobj.ownerUUID = obj.OwnerID; | ||
3068 | detobj.posVector = obj.AbsolutePosition; | ||
3069 | detobj.rotQuat = obj.GetWorldRotation(); | ||
3070 | detobj.velVector = obj.Velocity; | ||
3071 | detobj.colliderType = 0; | ||
3072 | detobj.groupUUID = obj.GroupID; | ||
3073 | colliding.Add(detobj); | ||
3074 | } | ||
3075 | else | ||
3076 | { | ||
3077 | List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences(); | ||
3078 | if (avlist != null) | ||
3079 | { | ||
3080 | foreach (ScenePresence av in avlist) | ||
3081 | { | ||
3082 | if (av.LocalId == localId) | ||
3083 | { | ||
3084 | DetectedObject detobj = new DetectedObject(); | ||
3085 | detobj.keyUUID = av.UUID; | ||
3086 | detobj.nameStr = av.Name; | ||
3087 | detobj.ownerUUID = av.UUID; | ||
3088 | detobj.posVector = av.AbsolutePosition; | ||
3089 | detobj.rotQuat = new LLQuaternion(av.Rotation.x, av.Rotation.y, av.Rotation.z, av.Rotation.w); | ||
3090 | detobj.velVector = av.Velocity; | ||
3091 | detobj.colliderType = 0; | ||
3092 | detobj.groupUUID = av.ControllingClient.ActiveGroupId; | ||
3093 | colliding.Add(detobj); | ||
3094 | } | ||
3095 | } | ||
3096 | |||
3097 | } | ||
3098 | } | ||
3099 | } | ||
3100 | if (colliding.Count > 0) | ||
3101 | { | ||
3102 | EndCollidingMessage.Colliders = colliding; | ||
3103 | // always running this check because if the user deletes the object it would return a null reference. | ||
3104 | if (m_parentGroup == null) | ||
3105 | return; | ||
3106 | if (m_parentGroup.Scene == null) | ||
3107 | return; | ||
3108 | m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd(LocalId, EndCollidingMessage); | ||
3109 | } | ||
3110 | |||
3111 | } | ||
3112 | } | 3113 | } |
3114 | return 0; | ||
3113 | } | 3115 | } |
3114 | 3116 | ||
3115 | 3117 | public void unregisterTargetWaypoint(int handle) | |
3116 | |||
3117 | public void SetDieAtEdge(bool p) | ||
3118 | { | ||
3119 | if (m_parentGroup == null) | ||
3120 | return; | ||
3121 | if (m_parentGroup.RootPart == null) | ||
3122 | return; | ||
3123 | |||
3124 | m_parentGroup.RootPart.DIE_AT_EDGE = p; | ||
3125 | } | ||
3126 | public bool GetDieAtEdge() | ||
3127 | { | ||
3128 | if (m_parentGroup == null) | ||
3129 | return false; | ||
3130 | if (m_parentGroup.RootPart == null) | ||
3131 | return false; | ||
3132 | |||
3133 | return m_parentGroup.RootPart.DIE_AT_EDGE; | ||
3134 | } | ||
3135 | |||
3136 | public void GetProperties(IClientAPI client) | ||
3137 | { | ||
3138 | |||
3139 | client.SendObjectPropertiesReply(LLUUID.Zero, (ulong)CreationDate, CreatorID, LLUUID.Zero, LLUUID.Zero, | ||
3140 | GroupID, (short)InventorySerial, LastOwnerID, UUID, OwnerID, | ||
3141 | ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description, | ||
3142 | ParentGroup.RootPart.OwnerMask, ParentGroup.RootPart.NextOwnerMask, ParentGroup.RootPart.GroupMask, ParentGroup.RootPart.EveryoneMask, | ||
3143 | ParentGroup.RootPart.BaseMask); | ||
3144 | |||
3145 | } | ||
3146 | |||
3147 | public void SetGroup(LLUUID groupID, IClientAPI client) | ||
3148 | { | ||
3149 | GroupID = groupID; | ||
3150 | GetProperties(client); | ||
3151 | m_updateFlag = 2; | ||
3152 | } | ||
3153 | |||
3154 | private void handleTimerAccounting(uint localID, double interval) | ||
3155 | { | 3118 | { |
3156 | if (localID == LocalId) | 3119 | if (m_parentGroup != null) |
3157 | { | 3120 | { |
3158 | 3121 | m_parentGroup.unregisterTargetWaypoint(handle); | |
3159 | float sec = (float)interval; | ||
3160 | if (m_parentGroup != null) | ||
3161 | { | ||
3162 | if (sec == 0) | ||
3163 | { | ||
3164 | if (m_parentGroup.scriptScore + 0.001f >= float.MaxValue - 0.001) | ||
3165 | m_parentGroup.scriptScore = 0; | ||
3166 | |||
3167 | m_parentGroup.scriptScore += 0.001f; | ||
3168 | return; | ||
3169 | } | ||
3170 | |||
3171 | if (m_parentGroup.scriptScore + (0.001f / sec) >= float.MaxValue - (0.001f / sec)) | ||
3172 | m_parentGroup.scriptScore = 0; | ||
3173 | m_parentGroup.scriptScore += (0.001f / sec); | ||
3174 | } | ||
3175 | |||
3176 | } | 3122 | } |
3177 | } | 3123 | } |
3178 | 3124 | ||
3125 | #endregion Public Methods | ||
3179 | } | 3126 | } |
3180 | } | 3127 | } \ No newline at end of file |