diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a5296eb1fd..8b5c348d18 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -90,10 +90,27 @@ namespace OpenSim.Region.Framework.Scenes SCALE = 0x40 } + public enum PrimType : int + { + BOX = 0, + CYLINDER = 1, + PRISM = 2, + SPHERE = 3, + TORUS = 4, + TUBE = 5, + RING = 6, + SCULPT = 7 + } + #endregion Enumerations public class SceneObjectPart : IScriptHost { + /// + /// Denote all sides of the prim + /// + public const int ALL_SIDES = -1; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // use only one serializer to give the runtime a chance to optimize it (it won't do that if you @@ -737,6 +754,9 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Text color. + /// public Color Color { get { return m_color; } @@ -2955,6 +2975,178 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Set the color of prim faces + /// + /// + /// + public void SetFaceColor(Vector3 color, int face) + { + Primitive.TextureEntry tex = Shape.Textures; + Color4 texcolor; + if (face >= 0 && face < GetNumberOfSides()) + { + texcolor = tex.CreateFace((uint)face).RGBA; + texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); + texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); + texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); + tex.FaceTextures[face].RGBA = texcolor; + UpdateTexture(tex); + return; + } + else if (face == ALL_SIDES) + { + for (uint i = 0; i < GetNumberOfSides(); i++) + { + if (tex.FaceTextures[i] != null) + { + texcolor = tex.FaceTextures[i].RGBA; + texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); + texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); + texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); + tex.FaceTextures[i].RGBA = texcolor; + } + texcolor = tex.DefaultTexture.RGBA; + texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); + texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); + texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); + tex.DefaultTexture.RGBA = texcolor; + } + UpdateTexture(tex); + return; + } + } + + /// + /// Get the number of sides that this part has. + /// + /// + public int GetNumberOfSides() + { + int ret = 0; + bool hasCut; + bool hasHollow; + bool hasDimple; + bool hasProfileCut; + + PrimType primType = getScriptPrimType(); + hasCutHollowDimpleProfileCut(primType, Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut); + + switch (primType) + { + case PrimType.BOX: + ret = 6; + if (hasCut) ret += 2; + if (hasHollow) ret += 1; + break; + case PrimType.CYLINDER: + ret = 3; + if (hasCut) ret += 2; + if (hasHollow) ret += 1; + break; + case PrimType.PRISM: + ret = 5; + if (hasCut) ret += 2; + if (hasHollow) ret += 1; + break; + case PrimType.SPHERE: + ret = 1; + if (hasCut) ret += 2; + if (hasDimple) ret += 2; + if (hasHollow) ret += 3; // Emulate lsl on secondlife (according to documentation it should have added only +1) + break; + case PrimType.TORUS: + ret = 1; + if (hasCut) ret += 2; + if (hasProfileCut) ret += 2; + if (hasHollow) ret += 1; + break; + case PrimType.TUBE: + ret = 4; + if (hasCut) ret += 2; + if (hasProfileCut) ret += 2; + if (hasHollow) ret += 1; + break; + case PrimType.RING: + ret = 3; + if (hasCut) ret += 2; + if (hasProfileCut) ret += 2; + if (hasHollow) ret += 1; + break; + case PrimType.SCULPT: + ret = 1; + break; + } + return ret; + } + + /// + /// Tell us what type this prim is + /// + /// + /// + public PrimType getScriptPrimType() + { + if (Shape.SculptEntry) + return PrimType.SCULPT; + if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Square) + { + if (Shape.PathCurve == (byte)Extrusion.Straight) + return PrimType.BOX; + else if (Shape.PathCurve == (byte)Extrusion.Curve1) + return PrimType.TUBE; + } + else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) + { + if (Shape.PathCurve == (byte)Extrusion.Straight) + return PrimType.CYLINDER; + // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits + else if (Shape.PathCurve == (byte)Extrusion.Curve1) + return PrimType.TORUS; + } + else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) + { + if (Shape.PathCurve == (byte)Extrusion.Curve1 || Shape.PathCurve == (byte)Extrusion.Curve2) + return PrimType.SPHERE; + } + else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) + { + if (Shape.PathCurve == (byte)Extrusion.Straight) + return PrimType.PRISM; + else if (Shape.PathCurve == (byte)Extrusion.Curve1) + return PrimType.RING; + } + + return PrimType.BOX; + } + + /// + /// Tell us if this object has cut, hollow, dimple, and other factors affecting the number of faces + /// + /// + /// + /// + /// + /// + /// + protected static void hasCutHollowDimpleProfileCut(PrimType primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow, + out bool hasDimple, out bool hasProfileCut) + { + if (primType == PrimType.BOX + || + primType == PrimType.CYLINDER + || + primType == 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? + } + public void SetGroup(UUID groupID, IClientAPI client) { _groupID = groupID; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c9998c0d86..2f00a1adf1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4394,7 +4394,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ret; } - /* The new / changed functions were tested with the following LSL script: default