diff options
Diffstat (limited to 'OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs')
-rw-r--r-- | OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs | 833 |
1 files changed, 833 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs new file mode 100644 index 0000000..5ed1514 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs | |||
@@ -0,0 +1,833 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Security; | ||
31 | using OpenMetaverse; | ||
32 | using OpenMetaverse.Packets; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Region.Framework.Interfaces; | ||
35 | using OpenSim.Region.Framework.Scenes; | ||
36 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Object; | ||
37 | using OpenSim.Region.Physics.Manager; | ||
38 | using PrimType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.PrimType; | ||
39 | using SculptType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType; | ||
40 | |||
41 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
42 | { | ||
43 | class SOPObject : MarshalByRefObject, IObject, IObjectPhysics, IObjectShape, IObjectSound | ||
44 | { | ||
45 | private readonly Scene m_rootScene; | ||
46 | private readonly uint m_localID; | ||
47 | private readonly ISecurityCredential m_security; | ||
48 | |||
49 | [Obsolete("Replace with 'credential' constructor [security]")] | ||
50 | public SOPObject(Scene rootScene, uint localID) | ||
51 | { | ||
52 | m_rootScene = rootScene; | ||
53 | m_localID = localID; | ||
54 | } | ||
55 | |||
56 | public SOPObject(Scene rootScene, uint localID, ISecurityCredential credential) | ||
57 | { | ||
58 | m_rootScene = rootScene; | ||
59 | m_localID = localID; | ||
60 | m_security = credential; | ||
61 | } | ||
62 | |||
63 | /// <summary> | ||
64 | /// This needs to run very, very quickly. | ||
65 | /// It is utilized in nearly every property and method. | ||
66 | /// </summary> | ||
67 | /// <returns></returns> | ||
68 | private SceneObjectPart GetSOP() | ||
69 | { | ||
70 | return m_rootScene.GetSceneObjectPart(m_localID); | ||
71 | } | ||
72 | |||
73 | private bool CanEdit() | ||
74 | { | ||
75 | if (!m_security.CanEditObject(this)) | ||
76 | { | ||
77 | throw new SecurityException("Insufficient Permission to edit object with UUID [" + GetSOP().UUID + "]"); | ||
78 | } | ||
79 | return true; | ||
80 | } | ||
81 | |||
82 | #region OnTouch | ||
83 | |||
84 | private event OnTouchDelegate _OnTouch; | ||
85 | private bool _OnTouchActive = false; | ||
86 | |||
87 | public event OnTouchDelegate OnTouch | ||
88 | { | ||
89 | add | ||
90 | { | ||
91 | if (CanEdit()) | ||
92 | { | ||
93 | if (!_OnTouchActive) | ||
94 | { | ||
95 | GetSOP().Flags |= PrimFlags.Touch; | ||
96 | _OnTouchActive = true; | ||
97 | m_rootScene.EventManager.OnObjectGrab += EventManager_OnObjectGrab; | ||
98 | } | ||
99 | |||
100 | _OnTouch += value; | ||
101 | } | ||
102 | } | ||
103 | remove | ||
104 | { | ||
105 | _OnTouch -= value; | ||
106 | |||
107 | if (_OnTouch == null) | ||
108 | { | ||
109 | GetSOP().Flags &= ~PrimFlags.Touch; | ||
110 | _OnTouchActive = false; | ||
111 | m_rootScene.EventManager.OnObjectGrab -= EventManager_OnObjectGrab; | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | void EventManager_OnObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) | ||
117 | { | ||
118 | if (_OnTouchActive && m_localID == localID) | ||
119 | { | ||
120 | TouchEventArgs e = new TouchEventArgs(); | ||
121 | e.Avatar = new SPAvatar(m_rootScene, remoteClient.AgentId, m_security); | ||
122 | e.TouchBiNormal = surfaceArgs.Binormal; | ||
123 | e.TouchMaterialIndex = surfaceArgs.FaceIndex; | ||
124 | e.TouchNormal = surfaceArgs.Normal; | ||
125 | e.TouchPosition = surfaceArgs.Position; | ||
126 | e.TouchST = new Vector2(surfaceArgs.STCoord.X, surfaceArgs.STCoord.Y); | ||
127 | e.TouchUV = new Vector2(surfaceArgs.UVCoord.X, surfaceArgs.UVCoord.Y); | ||
128 | |||
129 | IObject sender = this; | ||
130 | |||
131 | if (_OnTouch != null) | ||
132 | _OnTouch(sender, e); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | #endregion | ||
137 | |||
138 | public bool Exists | ||
139 | { | ||
140 | get { return GetSOP() != null; } | ||
141 | } | ||
142 | |||
143 | public uint LocalID | ||
144 | { | ||
145 | get { return m_localID; } | ||
146 | } | ||
147 | |||
148 | public UUID GlobalID | ||
149 | { | ||
150 | get { return GetSOP().UUID; } | ||
151 | } | ||
152 | |||
153 | public string Name | ||
154 | { | ||
155 | get { return GetSOP().Name; } | ||
156 | set | ||
157 | { | ||
158 | if (CanEdit()) | ||
159 | GetSOP().Name = value; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | public string Description | ||
164 | { | ||
165 | get { return GetSOP().Description; } | ||
166 | set | ||
167 | { | ||
168 | if (CanEdit()) | ||
169 | GetSOP().Description = value; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | public UUID OwnerId | ||
174 | { | ||
175 | get { return GetSOP().OwnerID;} | ||
176 | } | ||
177 | |||
178 | public UUID CreatorId | ||
179 | { | ||
180 | get { return GetSOP().CreatorID;} | ||
181 | } | ||
182 | |||
183 | public IObject[] Children | ||
184 | { | ||
185 | get | ||
186 | { | ||
187 | SceneObjectPart my = GetSOP(); | ||
188 | IObject[] rets = null; | ||
189 | |||
190 | int total = my.ParentGroup.PrimCount; | ||
191 | |||
192 | rets = new IObject[total]; | ||
193 | |||
194 | int i = 0; | ||
195 | |||
196 | foreach (SceneObjectPart part in my.ParentGroup.Parts) | ||
197 | { | ||
198 | rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security); | ||
199 | } | ||
200 | |||
201 | return rets; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | public IObject Root | ||
206 | { | ||
207 | get { return new SOPObject(m_rootScene, GetSOP().ParentGroup.RootPart.LocalId, m_security); } | ||
208 | } | ||
209 | |||
210 | public IObjectMaterial[] Materials | ||
211 | { | ||
212 | get | ||
213 | { | ||
214 | SceneObjectPart sop = GetSOP(); | ||
215 | IObjectMaterial[] rets = new IObjectMaterial[getNumberOfSides(sop)]; | ||
216 | |||
217 | for (int i = 0; i < rets.Length; i++) | ||
218 | { | ||
219 | rets[i] = new SOPObjectMaterial(i, sop); | ||
220 | } | ||
221 | |||
222 | return rets; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | public Vector3 Scale | ||
227 | { | ||
228 | get { return GetSOP().Scale; } | ||
229 | set | ||
230 | { | ||
231 | if (CanEdit()) | ||
232 | GetSOP().Scale = value; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | public Quaternion WorldRotation | ||
237 | { | ||
238 | get { throw new System.NotImplementedException(); } | ||
239 | set { throw new System.NotImplementedException(); } | ||
240 | } | ||
241 | |||
242 | public Quaternion OffsetRotation | ||
243 | { | ||
244 | get { throw new System.NotImplementedException(); } | ||
245 | set { throw new System.NotImplementedException(); } | ||
246 | } | ||
247 | |||
248 | public Vector3 WorldPosition | ||
249 | { | ||
250 | get { return GetSOP().AbsolutePosition; } | ||
251 | set | ||
252 | { | ||
253 | if (CanEdit()) | ||
254 | { | ||
255 | SceneObjectPart pos = GetSOP(); | ||
256 | pos.UpdateOffSet(value - pos.AbsolutePosition); | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | |||
261 | public Vector3 OffsetPosition | ||
262 | { | ||
263 | get { return GetSOP().OffsetPosition; } | ||
264 | set | ||
265 | { | ||
266 | if (CanEdit()) | ||
267 | { | ||
268 | GetSOP().OffsetPosition = value; | ||
269 | } | ||
270 | } | ||
271 | } | ||
272 | |||
273 | public Vector3 SitTarget | ||
274 | { | ||
275 | get { return GetSOP().SitTargetPosition; } | ||
276 | set | ||
277 | { | ||
278 | if (CanEdit()) | ||
279 | { | ||
280 | GetSOP().SitTargetPosition = value; | ||
281 | } | ||
282 | } | ||
283 | } | ||
284 | |||
285 | public string SitTargetText | ||
286 | { | ||
287 | get { return GetSOP().SitName; } | ||
288 | set | ||
289 | { | ||
290 | if (CanEdit()) | ||
291 | { | ||
292 | GetSOP().SitName = value; | ||
293 | } | ||
294 | } | ||
295 | } | ||
296 | |||
297 | public string TouchText | ||
298 | { | ||
299 | get { return GetSOP().TouchName; } | ||
300 | set | ||
301 | { | ||
302 | if (CanEdit()) | ||
303 | { | ||
304 | GetSOP().TouchName = value; | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | |||
309 | public string Text | ||
310 | { | ||
311 | get { return GetSOP().Text; } | ||
312 | set | ||
313 | { | ||
314 | if (CanEdit()) | ||
315 | { | ||
316 | GetSOP().SetText(value,new Vector3(1.0f,1.0f,1.0f),1.0f); | ||
317 | } | ||
318 | } | ||
319 | } | ||
320 | |||
321 | public bool IsRotationLockedX | ||
322 | { | ||
323 | get { throw new System.NotImplementedException(); } | ||
324 | set { throw new System.NotImplementedException(); } | ||
325 | } | ||
326 | |||
327 | public bool IsRotationLockedY | ||
328 | { | ||
329 | get { throw new System.NotImplementedException(); } | ||
330 | set { throw new System.NotImplementedException(); } | ||
331 | } | ||
332 | |||
333 | public bool IsRotationLockedZ | ||
334 | { | ||
335 | get { throw new System.NotImplementedException(); } | ||
336 | set { throw new System.NotImplementedException(); } | ||
337 | } | ||
338 | |||
339 | public bool IsSandboxed | ||
340 | { | ||
341 | get { throw new System.NotImplementedException(); } | ||
342 | set { throw new System.NotImplementedException(); } | ||
343 | } | ||
344 | |||
345 | public bool IsImmotile | ||
346 | { | ||
347 | get { throw new System.NotImplementedException(); } | ||
348 | set { throw new System.NotImplementedException(); } | ||
349 | } | ||
350 | |||
351 | public bool IsAlwaysReturned | ||
352 | { | ||
353 | get { throw new System.NotImplementedException(); } | ||
354 | set { throw new System.NotImplementedException(); } | ||
355 | } | ||
356 | |||
357 | public bool IsTemporary | ||
358 | { | ||
359 | get { throw new System.NotImplementedException(); } | ||
360 | set { throw new System.NotImplementedException(); } | ||
361 | } | ||
362 | |||
363 | public bool IsFlexible | ||
364 | { | ||
365 | get { throw new System.NotImplementedException(); } | ||
366 | set { throw new System.NotImplementedException(); } | ||
367 | } | ||
368 | |||
369 | public PhysicsMaterial PhysicsMaterial | ||
370 | { | ||
371 | get { throw new System.NotImplementedException(); } | ||
372 | set { throw new System.NotImplementedException(); } | ||
373 | } | ||
374 | |||
375 | public IObjectPhysics Physics | ||
376 | { | ||
377 | get { return this; } | ||
378 | } | ||
379 | |||
380 | public IObjectShape Shape | ||
381 | { | ||
382 | get { return this; } | ||
383 | } | ||
384 | |||
385 | public IObjectInventory Inventory | ||
386 | { | ||
387 | get { return new SOPObjectInventory(m_rootScene, GetSOP().TaskInventory); } | ||
388 | } | ||
389 | |||
390 | #region Public Functions | ||
391 | |||
392 | public void Say(string msg) | ||
393 | { | ||
394 | if (!CanEdit()) | ||
395 | return; | ||
396 | |||
397 | SceneObjectPart sop = GetSOP(); | ||
398 | m_rootScene.SimChat(msg, ChatTypeEnum.Say, sop.AbsolutePosition, sop.Name, sop.UUID, false); | ||
399 | } | ||
400 | |||
401 | public void Say(string msg,int channel) | ||
402 | { | ||
403 | if (!CanEdit()) | ||
404 | return; | ||
405 | |||
406 | SceneObjectPart sop = GetSOP(); | ||
407 | m_rootScene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,channel, sop.AbsolutePosition, sop.Name, sop.UUID, false); | ||
408 | } | ||
409 | |||
410 | public void Dialog(UUID avatar, string message, string[] buttons, int chat_channel) | ||
411 | { | ||
412 | if (!CanEdit()) | ||
413 | return; | ||
414 | |||
415 | IDialogModule dm = m_rootScene.RequestModuleInterface<IDialogModule>(); | ||
416 | |||
417 | if (dm == null) | ||
418 | return; | ||
419 | |||
420 | if (buttons.Length < 1) | ||
421 | { | ||
422 | Say("ERROR: No less than 1 button can be shown",2147483647); | ||
423 | return; | ||
424 | } | ||
425 | if (buttons.Length > 12) | ||
426 | { | ||
427 | Say("ERROR: No more than 12 buttons can be shown",2147483647); | ||
428 | return; | ||
429 | } | ||
430 | |||
431 | foreach (string button in buttons) | ||
432 | { | ||
433 | if (button == String.Empty) | ||
434 | { | ||
435 | Say("ERROR: button label cannot be blank",2147483647); | ||
436 | return; | ||
437 | } | ||
438 | if (button.Length > 24) | ||
439 | { | ||
440 | Say("ERROR: button label cannot be longer than 24 characters",2147483647); | ||
441 | return; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | dm.SendDialogToUser( | ||
446 | avatar, GetSOP().Name, GetSOP().UUID, GetSOP().OwnerID, | ||
447 | message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buttons); | ||
448 | |||
449 | } | ||
450 | |||
451 | #endregion | ||
452 | |||
453 | |||
454 | #region Supporting Functions | ||
455 | |||
456 | // Helper functions to understand if object has cut, hollow, dimple, and other affecting number of faces | ||
457 | private static void hasCutHollowDimpleProfileCut(int primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow, | ||
458 | out bool hasDimple, out bool hasProfileCut) | ||
459 | { | ||
460 | if (primType == (int)PrimType.Box | ||
461 | || | ||
462 | primType == (int)PrimType.Cylinder | ||
463 | || | ||
464 | primType == (int)PrimType.Prism) | ||
465 | |||
466 | hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); | ||
467 | else | ||
468 | hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0); | ||
469 | |||
470 | hasHollow = shape.ProfileHollow > 0; | ||
471 | hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms | ||
472 | hasProfileCut = hasDimple; // is it the same thing? | ||
473 | |||
474 | } | ||
475 | |||
476 | private static int getScriptPrimType(PrimitiveBaseShape primShape) | ||
477 | { | ||
478 | if (primShape.SculptEntry) | ||
479 | return (int) PrimType.Sculpt; | ||
480 | if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Square) | ||
481 | { | ||
482 | if (primShape.PathCurve == (byte) Extrusion.Straight) | ||
483 | return (int) PrimType.Box; | ||
484 | if (primShape.PathCurve == (byte) Extrusion.Curve1) | ||
485 | return (int) PrimType.Tube; | ||
486 | } | ||
487 | else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Circle) | ||
488 | { | ||
489 | if (primShape.PathCurve == (byte) Extrusion.Straight) | ||
490 | return (int) PrimType.Cylinder; | ||
491 | if (primShape.PathCurve == (byte) Extrusion.Curve1) | ||
492 | return (int) PrimType.Torus; | ||
493 | } | ||
494 | else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.HalfCircle) | ||
495 | { | ||
496 | if (primShape.PathCurve == (byte) Extrusion.Curve1 || primShape.PathCurve == (byte) Extrusion.Curve2) | ||
497 | return (int) PrimType.Sphere; | ||
498 | } | ||
499 | else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.EquilateralTriangle) | ||
500 | { | ||
501 | if (primShape.PathCurve == (byte) Extrusion.Straight) | ||
502 | return (int) PrimType.Prism; | ||
503 | if (primShape.PathCurve == (byte) Extrusion.Curve1) | ||
504 | return (int) PrimType.Ring; | ||
505 | } | ||
506 | return (int) PrimType.NotPrimitive; | ||
507 | } | ||
508 | |||
509 | private static int getNumberOfSides(SceneObjectPart part) | ||
510 | { | ||
511 | int ret; | ||
512 | bool hasCut; | ||
513 | bool hasHollow; | ||
514 | bool hasDimple; | ||
515 | bool hasProfileCut; | ||
516 | |||
517 | int primType = getScriptPrimType(part.Shape); | ||
518 | hasCutHollowDimpleProfileCut(primType, part.Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut); | ||
519 | |||
520 | switch (primType) | ||
521 | { | ||
522 | default: | ||
523 | case (int) PrimType.Box: | ||
524 | ret = 6; | ||
525 | if (hasCut) ret += 2; | ||
526 | if (hasHollow) ret += 1; | ||
527 | break; | ||
528 | case (int) PrimType.Cylinder: | ||
529 | ret = 3; | ||
530 | if (hasCut) ret += 2; | ||
531 | if (hasHollow) ret += 1; | ||
532 | break; | ||
533 | case (int) PrimType.Prism: | ||
534 | ret = 5; | ||
535 | if (hasCut) ret += 2; | ||
536 | if (hasHollow) ret += 1; | ||
537 | break; | ||
538 | case (int) PrimType.Sphere: | ||
539 | ret = 1; | ||
540 | if (hasCut) ret += 2; | ||
541 | if (hasDimple) ret += 2; | ||
542 | if (hasHollow) | ||
543 | ret += 1; // GOTCHA: LSL shows 2 additional sides here. | ||
544 | // This has been fixed, but may cause porting issues. | ||
545 | break; | ||
546 | case (int) PrimType.Torus: | ||
547 | ret = 1; | ||
548 | if (hasCut) ret += 2; | ||
549 | if (hasProfileCut) ret += 2; | ||
550 | if (hasHollow) ret += 1; | ||
551 | break; | ||
552 | case (int) PrimType.Tube: | ||
553 | ret = 4; | ||
554 | if (hasCut) ret += 2; | ||
555 | if (hasProfileCut) ret += 2; | ||
556 | if (hasHollow) ret += 1; | ||
557 | break; | ||
558 | case (int) PrimType.Ring: | ||
559 | ret = 3; | ||
560 | if (hasCut) ret += 2; | ||
561 | if (hasProfileCut) ret += 2; | ||
562 | if (hasHollow) ret += 1; | ||
563 | break; | ||
564 | case (int) PrimType.Sculpt: | ||
565 | ret = 1; | ||
566 | break; | ||
567 | } | ||
568 | return ret; | ||
569 | } | ||
570 | |||
571 | |||
572 | #endregion | ||
573 | |||
574 | #region IObjectPhysics | ||
575 | |||
576 | public bool Enabled | ||
577 | { | ||
578 | get { throw new System.NotImplementedException(); } | ||
579 | set { throw new System.NotImplementedException(); } | ||
580 | } | ||
581 | |||
582 | public bool Phantom | ||
583 | { | ||
584 | get { throw new System.NotImplementedException(); } | ||
585 | set { throw new System.NotImplementedException(); } | ||
586 | } | ||
587 | |||
588 | public bool PhantomCollisions | ||
589 | { | ||
590 | get { throw new System.NotImplementedException(); } | ||
591 | set { throw new System.NotImplementedException(); } | ||
592 | } | ||
593 | |||
594 | public double Density | ||
595 | { | ||
596 | get { return (GetSOP().PhysActor.Mass/Scale.X*Scale.Y/Scale.Z); } | ||
597 | set { throw new NotImplementedException(); } | ||
598 | } | ||
599 | |||
600 | public double Mass | ||
601 | { | ||
602 | get { return GetSOP().PhysActor.Mass; } | ||
603 | set { throw new NotImplementedException(); } | ||
604 | } | ||
605 | |||
606 | public double Buoyancy | ||
607 | { | ||
608 | get { return GetSOP().PhysActor.Buoyancy; } | ||
609 | set { GetSOP().PhysActor.Buoyancy = (float)value; } | ||
610 | } | ||
611 | |||
612 | public Vector3 GeometricCenter | ||
613 | { | ||
614 | get | ||
615 | { | ||
616 | Vector3 tmp = GetSOP().PhysActor.GeometricCenter; | ||
617 | return tmp; | ||
618 | } | ||
619 | } | ||
620 | |||
621 | public Vector3 CenterOfMass | ||
622 | { | ||
623 | get | ||
624 | { | ||
625 | Vector3 tmp = GetSOP().PhysActor.CenterOfMass; | ||
626 | return tmp; | ||
627 | } | ||
628 | } | ||
629 | |||
630 | public Vector3 RotationalVelocity | ||
631 | { | ||
632 | get | ||
633 | { | ||
634 | Vector3 tmp = GetSOP().PhysActor.RotationalVelocity; | ||
635 | return tmp; | ||
636 | } | ||
637 | set | ||
638 | { | ||
639 | if (!CanEdit()) | ||
640 | return; | ||
641 | |||
642 | GetSOP().PhysActor.RotationalVelocity = value; | ||
643 | } | ||
644 | } | ||
645 | |||
646 | public Vector3 Velocity | ||
647 | { | ||
648 | get | ||
649 | { | ||
650 | Vector3 tmp = GetSOP().PhysActor.Velocity; | ||
651 | return tmp; | ||
652 | } | ||
653 | set | ||
654 | { | ||
655 | if (!CanEdit()) | ||
656 | return; | ||
657 | |||
658 | GetSOP().PhysActor.Velocity = value; | ||
659 | } | ||
660 | } | ||
661 | |||
662 | public Vector3 Torque | ||
663 | { | ||
664 | get | ||
665 | { | ||
666 | Vector3 tmp = GetSOP().PhysActor.Torque; | ||
667 | return tmp; | ||
668 | } | ||
669 | set | ||
670 | { | ||
671 | if (!CanEdit()) | ||
672 | return; | ||
673 | |||
674 | GetSOP().PhysActor.Torque = value; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | public Vector3 Acceleration | ||
679 | { | ||
680 | get | ||
681 | { | ||
682 | Vector3 tmp = GetSOP().PhysActor.Acceleration; | ||
683 | return tmp; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | public Vector3 Force | ||
688 | { | ||
689 | get | ||
690 | { | ||
691 | Vector3 tmp = GetSOP().PhysActor.Force; | ||
692 | return tmp; | ||
693 | } | ||
694 | set | ||
695 | { | ||
696 | if (!CanEdit()) | ||
697 | return; | ||
698 | |||
699 | GetSOP().PhysActor.Force = value; | ||
700 | } | ||
701 | } | ||
702 | |||
703 | public bool FloatOnWater | ||
704 | { | ||
705 | set | ||
706 | { | ||
707 | if (!CanEdit()) | ||
708 | return; | ||
709 | GetSOP().PhysActor.FloatOnWater = value; | ||
710 | } | ||
711 | } | ||
712 | |||
713 | public void AddForce(Vector3 force, bool pushforce) | ||
714 | { | ||
715 | if (!CanEdit()) | ||
716 | return; | ||
717 | |||
718 | GetSOP().PhysActor.AddForce(force, pushforce); | ||
719 | } | ||
720 | |||
721 | public void AddAngularForce(Vector3 force, bool pushforce) | ||
722 | { | ||
723 | if (!CanEdit()) | ||
724 | return; | ||
725 | |||
726 | GetSOP().PhysActor.AddAngularForce(force, pushforce); | ||
727 | } | ||
728 | |||
729 | public void SetMomentum(Vector3 momentum) | ||
730 | { | ||
731 | if (!CanEdit()) | ||
732 | return; | ||
733 | |||
734 | GetSOP().PhysActor.SetMomentum(momentum); | ||
735 | } | ||
736 | |||
737 | #endregion | ||
738 | |||
739 | #region Implementation of IObjectShape | ||
740 | |||
741 | private UUID m_sculptMap = UUID.Zero; | ||
742 | |||
743 | public UUID SculptMap | ||
744 | { | ||
745 | get { return m_sculptMap; } | ||
746 | set | ||
747 | { | ||
748 | if (!CanEdit()) | ||
749 | return; | ||
750 | |||
751 | m_sculptMap = value; | ||
752 | SetPrimitiveSculpted(SculptMap, (byte) SculptType); | ||
753 | } | ||
754 | } | ||
755 | |||
756 | private SculptType m_sculptType = Object.SculptType.Default; | ||
757 | |||
758 | public SculptType SculptType | ||
759 | { | ||
760 | get { return m_sculptType; } | ||
761 | set | ||
762 | { | ||
763 | if (!CanEdit()) | ||
764 | return; | ||
765 | |||
766 | m_sculptType = value; | ||
767 | SetPrimitiveSculpted(SculptMap, (byte) SculptType); | ||
768 | } | ||
769 | } | ||
770 | |||
771 | public HoleShape HoleType | ||
772 | { | ||
773 | get { throw new System.NotImplementedException(); } | ||
774 | set { throw new System.NotImplementedException(); } | ||
775 | } | ||
776 | |||
777 | public double HoleSize | ||
778 | { | ||
779 | get { throw new System.NotImplementedException(); } | ||
780 | set { throw new System.NotImplementedException(); } | ||
781 | } | ||
782 | |||
783 | public PrimType PrimType | ||
784 | { | ||
785 | get { return (PrimType)getScriptPrimType(GetSOP().Shape); } | ||
786 | set { throw new System.NotImplementedException(); } | ||
787 | } | ||
788 | |||
789 | private void SetPrimitiveSculpted(UUID map, byte type) | ||
790 | { | ||
791 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); | ||
792 | |||
793 | SceneObjectPart part = GetSOP(); | ||
794 | |||
795 | UUID sculptId = map; | ||
796 | |||
797 | shapeBlock.ObjectLocalID = part.LocalId; | ||
798 | shapeBlock.PathScaleX = 100; | ||
799 | shapeBlock.PathScaleY = 150; | ||
800 | |||
801 | // retain pathcurve | ||
802 | shapeBlock.PathCurve = part.Shape.PathCurve; | ||
803 | |||
804 | part.Shape.SetSculptProperties((byte)type, sculptId); | ||
805 | part.Shape.SculptEntry = true; | ||
806 | part.UpdateShape(shapeBlock); | ||
807 | } | ||
808 | |||
809 | |||
810 | #endregion | ||
811 | |||
812 | |||
813 | #region Implementation of IObjectSound | ||
814 | |||
815 | public IObjectSound Sound | ||
816 | { | ||
817 | get { return this; } | ||
818 | } | ||
819 | |||
820 | public void Play(UUID asset, double volume) | ||
821 | { | ||
822 | if (!CanEdit()) | ||
823 | return; | ||
824 | ISoundModule module = m_rootScene.RequestModuleInterface<ISoundModule>(); | ||
825 | if (module != null) | ||
826 | { | ||
827 | module.SendSound(GetSOP().UUID, asset, volume, true, 0, 0, false, false); | ||
828 | } | ||
829 | } | ||
830 | |||
831 | #endregion | ||
832 | } | ||
833 | } | ||