123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Collections.Generic;
- using System.Security;
- using OpenMetaverse;
- using OpenMetaverse.Packets;
- using OpenSim.Framework;
- using OpenSim.Region.Framework.Interfaces;
- using OpenSim.Region.Framework.Scenes;
- using OpenSim.Region.OptionalModules.Scripting.Minimodule.Object;
- using OpenSim.Region.PhysicsModules.SharedBase;
- using PrimType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.PrimType;
- using SculptType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType;
- namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
- {
- class SOPObject : MarshalByRefObject, IObject, IObjectPhysics, IObjectShape, IObjectSound
- {
- private readonly Scene m_rootScene;
- private readonly uint m_localID;
- private readonly ISecurityCredential m_security;
- [Obsolete("Replace with 'credential' constructor [security]")]
- public SOPObject(Scene rootScene, uint localID)
- {
- m_rootScene = rootScene;
- m_localID = localID;
- }
- public SOPObject(Scene rootScene, uint localID, ISecurityCredential credential)
- {
- m_rootScene = rootScene;
- m_localID = localID;
- m_security = credential;
- }
- /// <summary>
- /// This needs to run very, very quickly.
- /// It is utilized in nearly every property and method.
- /// </summary>
- /// <returns></returns>
- private SceneObjectPart GetSOP()
- {
- return m_rootScene.GetSceneObjectPart(m_localID);
- }
- private bool CanEdit()
- {
- if (!m_security.CanEditObject(this))
- {
- throw new SecurityException("Insufficient Permission to edit object with UUID [" + GetSOP().UUID + "]");
- }
- return true;
- }
- #region OnTouch
- private event OnTouchDelegate _OnTouch;
- private bool _OnTouchActive = false;
- public event OnTouchDelegate OnTouch
- {
- add
- {
- if (CanEdit())
- {
- if (!_OnTouchActive)
- {
- GetSOP().Flags |= PrimFlags.Touch;
- _OnTouchActive = true;
- m_rootScene.EventManager.OnObjectGrab += EventManager_OnObjectGrab;
- }
- _OnTouch += value;
- }
- }
- remove
- {
- _OnTouch -= value;
- if (_OnTouch == null)
- {
- GetSOP().Flags &= ~PrimFlags.Touch;
- _OnTouchActive = false;
- m_rootScene.EventManager.OnObjectGrab -= EventManager_OnObjectGrab;
- }
- }
- }
- void EventManager_OnObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
- {
- if (_OnTouchActive && m_localID == localID)
- {
- TouchEventArgs e = new TouchEventArgs();
- e.Avatar = new SPAvatar(m_rootScene, remoteClient.AgentId, m_security);
- e.TouchBiNormal = surfaceArgs.Binormal;
- e.TouchMaterialIndex = surfaceArgs.FaceIndex;
- e.TouchNormal = surfaceArgs.Normal;
- e.TouchPosition = surfaceArgs.Position;
- e.TouchST = new Vector2(surfaceArgs.STCoord.X, surfaceArgs.STCoord.Y);
- e.TouchUV = new Vector2(surfaceArgs.UVCoord.X, surfaceArgs.UVCoord.Y);
- IObject sender = this;
- if (_OnTouch != null)
- _OnTouch(sender, e);
- }
- }
- #endregion
- public bool Exists
- {
- get { return GetSOP() != null; }
- }
- public uint LocalID
- {
- get { return m_localID; }
- }
- public UUID GlobalID
- {
- get { return GetSOP().UUID; }
- }
- public string Name
- {
- get { return GetSOP().Name; }
- set
- {
- if (CanEdit())
- GetSOP().Name = value;
- }
- }
- public string Description
- {
- get { return GetSOP().Description; }
- set
- {
- if (CanEdit())
- GetSOP().Description = value;
- }
- }
- public UUID OwnerId
- {
- get { return GetSOP().OwnerID;}
- }
- public UUID CreatorId
- {
- get { return GetSOP().CreatorID;}
- }
- public IObject[] Children
- {
- get
- {
- SceneObjectPart my = GetSOP();
- IObject[] rets = null;
- int total = my.ParentGroup.PrimCount;
- rets = new IObject[total];
- int i = 0;
- foreach (SceneObjectPart part in my.ParentGroup.Parts)
- {
- rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security);
- }
- return rets;
- }
- }
- public IObject Root
- {
- get { return new SOPObject(m_rootScene, GetSOP().ParentGroup.RootPart.LocalId, m_security); }
- }
- public IObjectMaterial[] Materials
- {
- get
- {
- SceneObjectPart sop = GetSOP();
- IObjectMaterial[] rets = new IObjectMaterial[getNumberOfSides(sop)];
- for (int i = 0; i < rets.Length; i++)
- {
- rets[i] = new SOPObjectMaterial(i, sop);
- }
- return rets;
- }
- }
- public Vector3 Scale
- {
- get { return GetSOP().Scale; }
- set
- {
- if (CanEdit())
- GetSOP().Scale = value;
- }
- }
- public Quaternion WorldRotation
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public Quaternion OffsetRotation
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public Vector3 WorldPosition
- {
- get { return GetSOP().AbsolutePosition; }
- set
- {
- if (CanEdit())
- {
- SceneObjectPart pos = GetSOP();
- pos.UpdateOffSet(value - pos.AbsolutePosition);
- }
- }
- }
- public Vector3 OffsetPosition
- {
- get { return GetSOP().OffsetPosition; }
- set
- {
- if (CanEdit())
- {
- GetSOP().OffsetPosition = value;
- }
- }
- }
- public Vector3 SitTarget
- {
- get { return GetSOP().SitTargetPosition; }
- set
- {
- if (CanEdit())
- {
- GetSOP().SitTargetPosition = value;
- }
- }
- }
- public string SitTargetText
- {
- get { return GetSOP().SitName; }
- set
- {
- if (CanEdit())
- {
- GetSOP().SitName = value;
- }
- }
- }
- public string TouchText
- {
- get { return GetSOP().TouchName; }
- set
- {
- if (CanEdit())
- {
- GetSOP().TouchName = value;
- }
- }
- }
- public string Text
- {
- get { return GetSOP().Text; }
- set
- {
- if (CanEdit())
- {
- GetSOP().SetText(value,new Vector3(1.0f,1.0f,1.0f),1.0f);
- }
- }
- }
- public bool IsRotationLockedX
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public bool IsRotationLockedY
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public bool IsRotationLockedZ
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public bool IsSandboxed
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public bool IsImmotile
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public bool IsAlwaysReturned
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public bool IsTemporary
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public bool IsFlexible
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public PhysicsMaterial PhysicsMaterial
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public IObjectPhysics Physics
- {
- get { return this; }
- }
- public IObjectShape Shape
- {
- get { return this; }
- }
- public IObjectInventory Inventory
- {
- get { return new SOPObjectInventory(m_rootScene, GetSOP().TaskInventory); }
- }
- #region Public Functions
- public void Say(string msg)
- {
- if (!CanEdit())
- return;
- SceneObjectPart sop = GetSOP();
- m_rootScene.SimChat(msg, ChatTypeEnum.Say, sop.AbsolutePosition, sop.Name, sop.UUID, false);
- }
- public void Say(string msg,int channel)
- {
- if (!CanEdit())
- return;
- SceneObjectPart sop = GetSOP();
- m_rootScene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,channel, sop.AbsolutePosition, sop.Name, sop.UUID, false);
- }
- public void Dialog(UUID avatar, string message, string[] buttons, int chat_channel)
- {
- if (!CanEdit())
- return;
- IDialogModule dm = m_rootScene.RequestModuleInterface<IDialogModule>();
- if (dm == null)
- return;
- if (buttons.Length < 1)
- {
- Say("ERROR: No less than 1 button can be shown",2147483647);
- return;
- }
- if (buttons.Length > 12)
- {
- Say("ERROR: No more than 12 buttons can be shown",2147483647);
- return;
- }
- foreach (string button in buttons)
- {
- if (button == String.Empty)
- {
- Say("ERROR: button label cannot be blank",2147483647);
- return;
- }
- if (button.Length > 24)
- {
- Say("ERROR: button label cannot be longer than 24 characters",2147483647);
- return;
- }
- }
- dm.SendDialogToUser(
- avatar, GetSOP().Name, GetSOP().UUID, GetSOP().OwnerID,
- message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buttons);
- }
- #endregion
- #region Supporting Functions
- // Helper functions to understand if object has cut, hollow, dimple, and other affecting number of faces
- private static void hasCutHollowDimpleProfileCut(int primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
- out bool hasDimple, out bool hasProfileCut)
- {
- if (primType == (int)PrimType.Box
- ||
- primType == (int)PrimType.Cylinder
- ||
- primType == (int)PrimType.Prism)
- hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
- else
- hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
- hasHollow = shape.ProfileHollow > 0;
- hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
- hasProfileCut = hasDimple; // is it the same thing?
- }
- private static int getScriptPrimType(PrimitiveBaseShape primShape)
- {
- if (primShape.SculptEntry)
- return (int) PrimType.Sculpt;
- if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Square)
- {
- if (primShape.PathCurve == (byte) Extrusion.Straight)
- return (int) PrimType.Box;
- if (primShape.PathCurve == (byte) Extrusion.Curve1)
- return (int) PrimType.Tube;
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Circle)
- {
- if (primShape.PathCurve == (byte) Extrusion.Straight)
- return (int) PrimType.Cylinder;
- if (primShape.PathCurve == (byte) Extrusion.Curve1)
- return (int) PrimType.Torus;
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.HalfCircle)
- {
- if (primShape.PathCurve == (byte) Extrusion.Curve1 || primShape.PathCurve == (byte) Extrusion.Curve2)
- return (int) PrimType.Sphere;
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.EquilateralTriangle)
- {
- if (primShape.PathCurve == (byte) Extrusion.Straight)
- return (int) PrimType.Prism;
- if (primShape.PathCurve == (byte) Extrusion.Curve1)
- return (int) PrimType.Ring;
- }
- return (int) PrimType.NotPrimitive;
- }
- private static int getNumberOfSides(SceneObjectPart part)
- {
- int ret;
- bool hasCut;
- bool hasHollow;
- bool hasDimple;
- bool hasProfileCut;
- int primType = getScriptPrimType(part.Shape);
- hasCutHollowDimpleProfileCut(primType, part.Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
- switch (primType)
- {
- default:
- case (int) PrimType.Box:
- ret = 6;
- if (hasCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case (int) PrimType.Cylinder:
- ret = 3;
- if (hasCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case (int) PrimType.Prism:
- ret = 5;
- if (hasCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case (int) PrimType.Sphere:
- ret = 1;
- if (hasCut) ret += 2;
- if (hasDimple) ret += 2;
- if (hasHollow)
- ret += 1; // GOTCHA: LSL shows 2 additional sides here.
- // This has been fixed, but may cause porting issues.
- break;
- case (int) PrimType.Torus:
- ret = 1;
- if (hasCut) ret += 2;
- if (hasProfileCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case (int) PrimType.Tube:
- ret = 4;
- if (hasCut) ret += 2;
- if (hasProfileCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case (int) PrimType.Ring:
- ret = 3;
- if (hasCut) ret += 2;
- if (hasProfileCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case (int) PrimType.Sculpt:
- ret = 1;
- break;
- }
- return ret;
- }
- #endregion
- #region IObjectPhysics
- public bool Enabled
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public bool Phantom
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public bool PhantomCollisions
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public double Density
- {
- get { return (GetSOP().PhysActor.Mass/Scale.X*Scale.Y/Scale.Z); }
- set { throw new NotImplementedException(); }
- }
- public double Mass
- {
- get { return GetSOP().PhysActor.Mass; }
- set { throw new NotImplementedException(); }
- }
- public double Buoyancy
- {
- get { return GetSOP().PhysActor.Buoyancy; }
- set { GetSOP().PhysActor.Buoyancy = (float)value; }
- }
- public Vector3 GeometricCenter
- {
- get
- {
- Vector3 tmp = GetSOP().PhysActor.GeometricCenter;
- return tmp;
- }
- }
- public Vector3 CenterOfMass
- {
- get
- {
- Vector3 tmp = GetSOP().PhysActor.CenterOfMass;
- return tmp;
- }
- }
- public Vector3 RotationalVelocity
- {
- get
- {
- Vector3 tmp = GetSOP().PhysActor.RotationalVelocity;
- return tmp;
- }
- set
- {
- if (!CanEdit())
- return;
- GetSOP().PhysActor.RotationalVelocity = value;
- }
- }
- public Vector3 Velocity
- {
- get
- {
- Vector3 tmp = GetSOP().PhysActor.Velocity;
- return tmp;
- }
- set
- {
- if (!CanEdit())
- return;
- GetSOP().PhysActor.Velocity = value;
- }
- }
- public Vector3 Torque
- {
- get
- {
- Vector3 tmp = GetSOP().PhysActor.Torque;
- return tmp;
- }
- set
- {
- if (!CanEdit())
- return;
- GetSOP().PhysActor.Torque = value;
- }
- }
- public Vector3 Acceleration
- {
- get
- {
- Vector3 tmp = GetSOP().PhysActor.Acceleration;
- return tmp;
- }
- }
- public Vector3 Force
- {
- get
- {
- Vector3 tmp = GetSOP().PhysActor.Force;
- return tmp;
- }
- set
- {
- if (!CanEdit())
- return;
- GetSOP().PhysActor.Force = value;
- }
- }
- public bool FloatOnWater
- {
- set
- {
- if (!CanEdit())
- return;
- GetSOP().PhysActor.FloatOnWater = value;
- }
- }
- public void AddForce(Vector3 force, bool pushforce)
- {
- if (!CanEdit())
- return;
- GetSOP().PhysActor.AddForce(force, pushforce);
- }
- public void AddAngularForce(Vector3 force, bool pushforce)
- {
- if (!CanEdit())
- return;
- GetSOP().PhysActor.AddAngularForce(force, pushforce);
- }
- public void SetMomentum(Vector3 momentum)
- {
- if (!CanEdit())
- return;
- GetSOP().PhysActor.SetMomentum(momentum);
- }
- #endregion
- #region Implementation of IObjectShape
- private UUID m_sculptMap = UUID.Zero;
- public UUID SculptMap
- {
- get { return m_sculptMap; }
- set
- {
- if (!CanEdit())
- return;
- m_sculptMap = value;
- SetPrimitiveSculpted(SculptMap, (byte) SculptType);
- }
- }
- private SculptType m_sculptType = Object.SculptType.Default;
- public SculptType SculptType
- {
- get { return m_sculptType; }
- set
- {
- if (!CanEdit())
- return;
- m_sculptType = value;
- SetPrimitiveSculpted(SculptMap, (byte) SculptType);
- }
- }
- public HoleShape HoleType
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public double HoleSize
- {
- get { throw new System.NotImplementedException(); }
- set { throw new System.NotImplementedException(); }
- }
- public PrimType PrimType
- {
- get { return (PrimType)getScriptPrimType(GetSOP().Shape); }
- set { throw new System.NotImplementedException(); }
- }
- private void SetPrimitiveSculpted(UUID map, byte type)
- {
- ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
- SceneObjectPart part = GetSOP();
- UUID sculptId = map;
- shapeBlock.ObjectLocalID = part.LocalId;
- shapeBlock.PathScaleX = 100;
- shapeBlock.PathScaleY = 150;
- // retain pathcurve
- shapeBlock.PathCurve = part.Shape.PathCurve;
- part.Shape.SetSculptProperties((byte)type, sculptId);
- part.Shape.SculptEntry = true;
- part.UpdateShape(shapeBlock);
- }
- #endregion
- #region Implementation of IObjectSound
- public IObjectSound Sound
- {
- get { return this; }
- }
- public void Play(UUID asset, double volume)
- {
- if (!CanEdit())
- return;
- ISoundModule module = m_rootScene.RequestModuleInterface<ISoundModule>();
- if (module != null)
- {
- module.SendSound(GetSOP().UUID, asset, volume, true, 0, 0, false, false);
- }
- }
- #endregion
- }
- }
|