aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/Primitive.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/Primitive.cs')
-rw-r--r--OpenSim/Region/Environment/Scenes/Primitive.cs594
1 files changed, 594 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Primitive.cs b/OpenSim/Region/Environment/Scenes/Primitive.cs
new file mode 100644
index 0000000..d23a569
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Primitive.cs
@@ -0,0 +1,594 @@
1using System;
2using System.Collections.Generic;
3using Axiom.Math;
4using libsecondlife;
5using libsecondlife.Packets;
6using OpenSim.Framework.Interfaces;
7using OpenSim.Framework.Inventory;
8using OpenSim.Framework.Types;
9
10namespace OpenSim.Region.Environment.Scenes
11{
12 public class Primitive : EntityBase
13 {
14 private const uint FULL_MASK_PERMISSIONS = 2147483647;
15
16 private LLVector3 positionLastFrame = new LLVector3(0, 0, 0);
17 private ulong m_regionHandle;
18 private byte updateFlag = 0;
19 private uint m_flags = 32 + 65536 + 131072 + 256 + 4 + 8 + 2048 + 524288 + 268435456 + 128;
20
21 private Dictionary<LLUUID, InventoryItem> inventoryItems;
22
23 private string m_description = "";
24
25 public string SitName = "";
26 public string TouchName = "";
27 public string Text = "";
28
29 public LLUUID CreatorID;
30 public LLUUID OwnerID;
31 public LLUUID LastOwnerID;
32 public Int32 CreationDate;
33
34 public uint ParentID = 0;
35
36 public uint OwnerMask = FULL_MASK_PERMISSIONS;
37 public uint NextOwnerMask = FULL_MASK_PERMISSIONS;
38 public uint GroupMask = FULL_MASK_PERMISSIONS;
39 public uint EveryoneMask = FULL_MASK_PERMISSIONS;
40 public uint BaseMask = FULL_MASK_PERMISSIONS;
41
42 private PrimitiveBaseShape m_Shape;
43
44 public SceneObject m_RootParent;
45 public bool m_isRootPrim;
46 public EntityBase m_Parent;
47
48 #region Properties
49 /// <summary>
50 /// If rootprim, will return world position
51 /// otherwise will return local offset from rootprim
52 /// </summary>
53 public override LLVector3 Pos
54 {
55 get
56 {
57 if (m_isRootPrim)
58 {
59 //if we are rootprim then our offset should be zero
60 return this.m_pos + m_Parent.Pos;
61 }
62 else
63 {
64 return this.m_pos;
65 }
66 }
67 set
68 {
69 if (m_isRootPrim)
70 {
71 m_Parent.Pos = value;
72 }
73 this.m_pos = value - m_Parent.Pos;
74 }
75
76 }
77
78 public LLVector3 WorldPos
79 {
80 get
81 {
82 if (!this.m_isRootPrim)
83 {
84 Primitive parentPrim = (Primitive)this.m_Parent;
85 Axiom.Math.Vector3 offsetPos = new Vector3(this.m_pos.X, this.m_pos.Y, this.m_pos.Z);
86 offsetPos = parentPrim.Rotation * offsetPos;
87 return parentPrim.WorldPos + new LLVector3(offsetPos.x, offsetPos.y, offsetPos.z);
88 }
89 else
90 {
91 return this.Pos;
92 }
93 }
94 }
95
96 public string Description
97 {
98 get
99 {
100 return this.m_description;
101 }
102 set
103 {
104 this.m_description = value;
105 }
106 }
107
108 public LLVector3 Scale
109 {
110 set
111 {
112 this.m_Shape.Scale = value;
113 }
114 get
115 {
116 return this.m_Shape.Scale;
117 }
118 }
119 #endregion
120
121 #region Constructors
122 /// <summary>
123 ///
124 /// </summary>
125 /// <param name="regionHandle"></param>
126 /// <param name="world"></param>
127 /// <param name="addPacket"></param>
128 /// <param name="ownerID"></param>
129 /// <param name="localID"></param>
130 /// <param name="isRoot"></param>
131 /// <param name="parent"></param>
132 /// <param name="rootObject"></param>
133 public Primitive(ulong regionHandle, Scene world, ObjectAddPacket addPacket, LLUUID ownerID, uint localID, bool isRoot, EntityBase parent, SceneObject rootObject)
134 {
135 m_regionHandle = regionHandle;
136 m_world = world;
137 inventoryItems = new Dictionary<LLUUID, InventoryItem>();
138 this.m_Parent = parent;
139 this.m_isRootPrim = isRoot;
140 this.m_RootParent = rootObject;
141 this.CreateFromPacket(addPacket, ownerID, localID);
142 this.Rotation = Axiom.Math.Quaternion.Identity;
143 }
144
145 /// <summary>
146 ///
147 /// </summary>
148 /// <remarks>Empty constructor for duplication</remarks>
149 public Primitive()
150 {
151
152 }
153
154 #endregion
155
156 #region Duplication
157
158 public Primitive Copy(EntityBase parent, SceneObject rootParent)
159 {
160 Primitive dupe = (Primitive)this.MemberwiseClone();
161 // TODO: Copy this properly.
162 dupe.inventoryItems = this.inventoryItems;
163 dupe.m_Parent = parent;
164 dupe.m_RootParent = rootParent;
165 // TODO: Copy this properly.
166 dupe.m_Shape = this.m_Shape;
167
168 uint newLocalID = this.m_world.PrimIDAllocate();
169 dupe.LocalId = newLocalID;
170
171 dupe.Scale = new LLVector3(this.Scale.X, this.Scale.Y, this.Scale.Z);
172 dupe.Rotation = new Quaternion(this.Rotation.w, this.Rotation.x, this.Rotation.y, this.Rotation.z);
173 dupe.Pos = new LLVector3(this.Pos.X, this.Pos.Y, this.Pos.Z);
174
175 return dupe;
176 }
177
178 #endregion
179
180
181 #region Override from EntityBase
182 /// <summary>
183 ///
184 /// </summary>
185 public override void update()
186 {
187 if (this.updateFlag == 1) // is a new prim just been created/reloaded or has major changes
188 {
189 this.SendFullUpdateToAllClients();
190 this.updateFlag = 0;
191 }
192 if (this.updateFlag == 2) //some change has been made so update the clients
193 {
194 this.SendTerseUpdateToALLClients();
195 this.updateFlag = 0;
196 }
197
198 foreach (EntityBase child in children)
199 {
200 child.update();
201 }
202 }
203 #endregion
204
205 #region Setup
206 /// <summary>
207 ///
208 /// </summary>
209 /// <param name="addPacket"></param>
210 /// <param name="ownerID"></param>
211 /// <param name="localID"></param>
212 public void CreateFromPacket(ObjectAddPacket addPacket, LLUUID ownerID, uint localID)
213 {
214 this.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
215 this.OwnerID = ownerID;
216 this.CreatorID = this.OwnerID;
217 this.LastOwnerID = LLUUID.Zero;
218 this.Pos = addPacket.ObjectData.RayEnd;
219 this.uuid = LLUUID.Random();
220 this.m_localId = (uint)(localID);
221
222 PrimitiveBaseShape pShape = new PrimitiveBaseShape();
223 this.m_Shape = pShape;
224
225 pShape.PCode = addPacket.ObjectData.PCode;
226 pShape.PathBegin = addPacket.ObjectData.PathBegin;
227 pShape.PathEnd = addPacket.ObjectData.PathEnd;
228 pShape.PathScaleX = addPacket.ObjectData.PathScaleX;
229 pShape.PathScaleY = addPacket.ObjectData.PathScaleY;
230 pShape.PathShearX = addPacket.ObjectData.PathShearX;
231 pShape.PathShearY = addPacket.ObjectData.PathShearY;
232 pShape.PathSkew = addPacket.ObjectData.PathSkew;
233 pShape.ProfileBegin = addPacket.ObjectData.ProfileBegin;
234 pShape.ProfileEnd = addPacket.ObjectData.ProfileEnd;
235 pShape.Scale = addPacket.ObjectData.Scale;
236 pShape.PathCurve = addPacket.ObjectData.PathCurve;
237 pShape.ProfileCurve = addPacket.ObjectData.ProfileCurve;
238 pShape.ProfileHollow = addPacket.ObjectData.ProfileHollow;
239 pShape.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
240 pShape.PathRevolutions = addPacket.ObjectData.PathRevolutions;
241 pShape.PathTaperX = addPacket.ObjectData.PathTaperX;
242 pShape.PathTaperY = addPacket.ObjectData.PathTaperY;
243 pShape.PathTwist = addPacket.ObjectData.PathTwist;
244 pShape.PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
245
246 this.updateFlag = 1;
247 }
248 #endregion
249
250 #region Linking / unlinking
251 /// <summary>
252 ///
253 /// </summary>
254 /// <param name="linkObject"></param>
255 public void AddNewChildren(SceneObject linkObject)
256 {
257 // Console.WriteLine("linking new prims " + linkObject.rootLocalID + " to me (" + this.LocalId + ")");
258 //TODO check permissions
259 this.children.Add(linkObject.rootPrimitive);
260 linkObject.rootPrimitive.SetNewParent(this, this.m_RootParent);
261
262 this.m_world.DeleteEntity(linkObject.rootUUID);
263 linkObject.DeleteAllChildren();
264 }
265
266 /// <summary>
267 ///
268 /// </summary>
269 /// <param name="newParent"></param>
270 /// <param name="rootParent"></param>
271 public void SetNewParent(Primitive newParent, SceneObject rootParent)
272 {
273 LLVector3 oldPos = new LLVector3(this.Pos.X, this.Pos.Y, this.Pos.Z);
274 this.m_isRootPrim = false;
275 this.m_Parent = newParent;
276 this.ParentID = newParent.LocalId;
277 this.m_RootParent = rootParent;
278 this.m_RootParent.AddChildToList(this);
279 this.Pos = oldPos;
280 Axiom.Math.Vector3 axPos = new Axiom.Math.Vector3(this.m_pos.X, m_pos.Y, m_pos.Z);
281 axPos = this.m_Parent.Rotation.Inverse() * axPos;
282 this.m_pos = new LLVector3(axPos.x, axPos.y, axPos.z);
283 Axiom.Math.Quaternion oldRot = new Quaternion(this.Rotation.w, this.Rotation.x, this.Rotation.y, this.Rotation.z);
284 this.Rotation = this.m_Parent.Rotation.Inverse() * this.Rotation;
285 this.updateFlag = 1;
286
287 foreach (Primitive child in children)
288 {
289 child.SetRootParent(rootParent, newParent, oldPos, oldRot);
290 }
291 children.Clear();
292
293
294 }
295
296 /// <summary>
297 ///
298 /// </summary>
299 /// <param name="newRoot"></param>
300 public void SetRootParent(SceneObject newRoot , Primitive newParent, LLVector3 oldParentPosition, Axiom.Math.Quaternion oldParentRotation)
301 {
302 LLVector3 oldPos = new LLVector3(this.Pos.X, this.Pos.Y, this.Pos.Z);
303 Axiom.Math.Vector3 axOldPos = new Vector3(oldPos.X, oldPos.Y, oldPos.Z);
304 axOldPos = oldParentRotation * axOldPos;
305 oldPos = new LLVector3(axOldPos.x, axOldPos.y, axOldPos.z);
306 oldPos += oldParentPosition;
307 Axiom.Math.Quaternion oldRot = new Quaternion(this.Rotation.w, this.Rotation.x, this.Rotation.y, this.Rotation.z);
308 this.m_isRootPrim = false;
309 this.m_Parent = newParent;
310 this.ParentID = newParent.LocalId;
311 newParent.AddToChildrenList(this);
312 this.m_RootParent = newRoot;
313 this.m_RootParent.AddChildToList(this);
314 this.Pos = oldPos;
315 Axiom.Math.Vector3 axPos = new Axiom.Math.Vector3(this.m_pos.X, m_pos.Y, m_pos.Z);
316 axPos = this.m_Parent.Rotation.Inverse() * axPos;
317 this.m_pos = new LLVector3(axPos.x, axPos.y, axPos.z);
318 this.Rotation = oldParentRotation * this.Rotation;
319 this.Rotation = this.m_Parent.Rotation.Inverse()* this.Rotation ;
320 this.updateFlag = 1;
321 foreach (Primitive child in children)
322 {
323 child.SetRootParent(newRoot, newParent, oldPos, oldRot);
324 }
325 children.Clear();
326 }
327
328 /// <summary>
329 ///
330 /// </summary>
331 /// <param name="offset"></param>
332 public void AddOffsetToChildren(LLVector3 offset)
333 {
334 foreach (Primitive prim in this.children)
335 {
336 prim.m_pos += offset;
337 prim.updateFlag = 2;
338 }
339 }
340
341 /// <summary>
342 ///
343 /// </summary>
344 /// <param name="prim"></param>
345 public void AddToChildrenList(Primitive prim)
346 {
347 this.children.Add(prim);
348 }
349 #endregion
350
351 #region Resizing/Scale
352 /// <summary>
353 ///
354 /// </summary>
355 /// <param name="scale"></param>
356 public void ResizeGoup(LLVector3 scale)
357 {
358 LLVector3 offset = (scale - this.m_Shape.Scale);
359 offset.X /= 2;
360 offset.Y /= 2;
361 offset.Z /= 2;
362 if (this.m_isRootPrim)
363 {
364 this.m_Parent.Pos += offset;
365 }
366 else
367 {
368 this.m_pos += offset;
369 }
370
371 this.AddOffsetToChildren(new LLVector3(-offset.X, -offset.Y, -offset.Z));
372 this.m_Shape.Scale = scale;
373
374 this.updateFlag = 1;
375 }
376 #endregion
377
378 #region Position
379 /// <summary>
380 ///
381 /// </summary>
382 /// <param name="pos"></param>
383 public void UpdateGroupPosition(LLVector3 pos)
384 {
385 LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z);
386
387 this.Pos = newPos;
388 this.updateFlag = 2;
389 }
390
391 /// <summary>
392 ///
393 /// </summary>
394 /// <param name="pos"></param>
395 public void UpdateSinglePosition(LLVector3 pos)
396 {
397 // Console.WriteLine("updating single prim position");
398 if (this.m_isRootPrim)
399 {
400 LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z);
401 LLVector3 oldPos = new LLVector3(Pos.X, Pos.Y, Pos.Z);
402 LLVector3 diff = oldPos - newPos;
403 Axiom.Math.Vector3 axDiff = new Vector3(diff.X, diff.Y, diff.Z);
404 axDiff = this.Rotation.Inverse() * axDiff;
405 diff.X = axDiff.x;
406 diff.Y = axDiff.y;
407 diff.Z = axDiff.z;
408 this.Pos = newPos;
409
410 foreach (Primitive prim in this.children)
411 {
412 prim.m_pos += diff;
413 prim.updateFlag = 2;
414 }
415 this.updateFlag = 2;
416 }
417 else
418 {
419 LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z);
420 this.m_pos = newPos;
421 this.updateFlag = 2;
422 }
423 }
424
425 #endregion
426
427 #region Rotation
428 /// <summary>
429 ///
430 /// </summary>
431 /// <param name="rot"></param>
432 public void UpdateGroupRotation(LLQuaternion rot)
433 {
434 this.Rotation = new Axiom.Math.Quaternion(rot.W, rot.X, rot.Y, rot.Z);
435 this.updateFlag = 2;
436
437 }
438
439 /// <summary>
440 ///
441 /// </summary>
442 /// <param name="pos"></param>
443 /// <param name="rot"></param>
444 public void UpdateGroupMouseRotation(LLVector3 pos, LLQuaternion rot)
445 {
446 this.Rotation = new Axiom.Math.Quaternion(rot.W, rot.X, rot.Y, rot.Z);
447 this.Pos = pos;
448 this.updateFlag = 2;
449 }
450
451 /// <summary>
452 ///
453 /// </summary>
454 /// <param name="rot"></param>
455 public void UpdateSingleRotation(LLQuaternion rot)
456 {
457 //Console.WriteLine("updating single prim rotation");
458 Axiom.Math.Quaternion axRot = new Axiom.Math.Quaternion(rot.W, rot.X, rot.Y, rot.Z);
459 Axiom.Math.Quaternion oldParentRot = new Quaternion(this.Rotation.w, this.Rotation.x, this.Rotation.y, this.Rotation.z);
460 this.Rotation = axRot;
461 foreach (Primitive prim in this.children)
462 {
463 Axiom.Math.Vector3 axPos = new Vector3(prim.m_pos.X, prim.m_pos.Y, prim.m_pos.Z);
464 axPos = oldParentRot * axPos;
465 axPos = axRot.Inverse() * axPos;
466 prim.m_pos = new LLVector3(axPos.x, axPos.y, axPos.z);
467 prim.Rotation = oldParentRot * prim.Rotation ;
468 prim.Rotation = axRot.Inverse()* prim.Rotation;
469 prim.updateFlag = 2;
470 }
471 this.updateFlag = 2;
472 }
473 #endregion
474
475 #region Shape
476 /// <summary>
477 ///
478 /// </summary>
479 /// <param name="shapeBlock"></param>
480 public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock)
481 {
482 this.m_Shape.PathBegin = shapeBlock.PathBegin;
483 this.m_Shape.PathEnd = shapeBlock.PathEnd;
484 this.m_Shape.PathScaleX = shapeBlock.PathScaleX;
485 this.m_Shape.PathScaleY = shapeBlock.PathScaleY;
486 this.m_Shape.PathShearX = shapeBlock.PathShearX;
487 this.m_Shape.PathShearY = shapeBlock.PathShearY;
488 this.m_Shape.PathSkew = shapeBlock.PathSkew;
489 this.m_Shape.ProfileBegin = shapeBlock.ProfileBegin;
490 this.m_Shape.ProfileEnd = shapeBlock.ProfileEnd;
491 this.m_Shape.PathCurve = shapeBlock.PathCurve;
492 this.m_Shape.ProfileCurve = shapeBlock.ProfileCurve;
493 this.m_Shape.ProfileHollow = shapeBlock.ProfileHollow;
494 this.m_Shape.PathRadiusOffset = shapeBlock.PathRadiusOffset;
495 this.m_Shape.PathRevolutions = shapeBlock.PathRevolutions;
496 this.m_Shape.PathTaperX = shapeBlock.PathTaperX;
497 this.m_Shape.PathTaperY = shapeBlock.PathTaperY;
498 this.m_Shape.PathTwist = shapeBlock.PathTwist;
499 this.m_Shape.PathTwistBegin = shapeBlock.PathTwistBegin;
500 this.updateFlag = 1;
501 }
502 #endregion
503
504 #region Client Update Methods
505
506 /// <summary>
507 ///
508 /// </summary>
509 /// <param name="remoteClient"></param>
510 public void SendFullUpdateForAllChildren(IClientAPI remoteClient)
511 {
512 this.SendFullUpdateToClient(remoteClient);
513 for (int i = 0; i < this.children.Count; i++)
514 {
515 if (this.children[i] is Primitive)
516 {
517 ((Primitive)this.children[i]).SendFullUpdateForAllChildren(remoteClient);
518 }
519 }
520 }
521
522 /// <summary>
523 ///
524 /// </summary>
525 /// <param name="remoteClient"></param>
526 public void SendFullUpdateToClient(IClientAPI remoteClient)
527 {
528 LLVector3 lPos;
529 lPos = this.Pos;
530 LLQuaternion lRot;
531 lRot = new LLQuaternion(this.Rotation.x, this.Rotation.y, this.Rotation.z, this.Rotation.w);
532
533 remoteClient.SendPrimitiveToClient(this.m_regionHandle, 64096, this.LocalId, this.m_Shape, lPos, lRot, new LLUUID("00000000-0000-0000-9999-000000000005"), this.m_flags, this.uuid, this.OwnerID, this.Text, this.ParentID);
534 }
535
536 /// <summary>
537 ///
538 /// </summary>
539 public void SendFullUpdateToAllClients()
540 {
541 List<ScenePresence> avatars = this.m_world.RequestAvatarList();
542 for (int i = 0; i < avatars.Count; i++)
543 {
544 this.SendFullUpdateToClient(avatars[i].ControllingClient);
545 }
546 }
547
548 /// <summary>
549 ///
550 /// </summary>
551 /// <param name="remoteClient"></param>
552 public void SendTerseUpdateForAllChildren(IClientAPI remoteClient)
553 {
554 this.SendTerseUpdateToClient(remoteClient);
555 for (int i = 0; i < this.children.Count; i++)
556 {
557 if (this.children[i] is Primitive)
558 {
559 ((Primitive)this.children[i]).SendTerseUpdateForAllChildren(remoteClient);
560 }
561 }
562 }
563
564 /// <summary>
565 ///
566 /// </summary>
567 /// <param name="RemoteClient"></param>
568 public void SendTerseUpdateToClient(IClientAPI RemoteClient)
569 {
570 LLVector3 lPos;
571 Quaternion lRot;
572
573 lPos = this.Pos;
574 lRot = this.Rotation;
575
576 LLQuaternion mRot = new LLQuaternion(lRot.x, lRot.y, lRot.z, lRot.w);
577 RemoteClient.SendPrimTerseUpdate(this.m_regionHandle, 64096, this.LocalId, lPos, mRot);
578 }
579
580 /// <summary>
581 ///
582 /// </summary>
583 public void SendTerseUpdateToALLClients()
584 {
585 List<ScenePresence> avatars = this.m_world.RequestAvatarList();
586 for (int i = 0; i < avatars.Count; i++)
587 {
588 this.SendTerseUpdateToClient(avatars[i].ControllingClient);
589 }
590 }
591
592 #endregion
593 }
594}