Пример #1
0
        protected int GetNumberOfSides (ISceneChildEntity part)
        {
            int sides = part.GetNumberOfSides();

            if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0)
            {
                // Make up for a bug where LSL shows 4 sides rather than 2
                sides += 2;
            }

            return sides;
        }
Пример #2
0
        public LSL_List GetLinkPrimitiveParams (ISceneChildEntity part, LSL_List rules)
        {
            LSL_List res = new LSL_List();
            int idx = 0;
            while (idx < rules.Length)
            {
                int code = (int)rules.GetLSLIntegerItem(idx++);
                int remain = rules.Length - idx;
                Primitive.TextureEntry tex = part.Shape.Textures;
                int face = 0;
                //if (idx < rules.Length)
                //    face = (int)rules.GetLSLIntegerItem(idx++);

                if (code == (int)ScriptBaseClass.PRIM_NAME)
                {
                    res.Add(new LSL_String(part.Name));
                }

                if (code == (int)ScriptBaseClass.PRIM_DESC)
                {
                    res.Add (new LSL_String (part.Description));
                }

                if (code == (int)ScriptBaseClass.PRIM_MATERIAL)
                {
                    res.Add(new LSL_Integer(part.Material));
                }

                if (code == (int)ScriptBaseClass.PRIM_PHYSICS)
                {
                    if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) != 0)
                        res.Add(new LSL_Integer(1));
                    else
                        res.Add(new LSL_Integer(0));
                }

                if (code == (int)ScriptBaseClass.PRIM_TEMP_ON_REZ)
                {
                    if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) != 0)
                        res.Add(new LSL_Integer(1));
                    else
                        res.Add(new LSL_Integer(0));
                }

                if (code == (int)ScriptBaseClass.PRIM_PHANTOM)
                {
                    if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
                        res.Add(new LSL_Integer(1));
                    else
                        res.Add(new LSL_Integer(0));
                }

                if (code == (int)ScriptBaseClass.PRIM_POSITION)
                {
                    Vector3 tmp = part.AbsolutePosition;
                    LSL_Vector v = new LSL_Vector(tmp.X,
                                                  tmp.Y,
                                                  tmp.Z);
                    // For some reason, the part.AbsolutePosition.* values do not change if the
                    // linkset is rotated; they always reflect the child prim's world position
                    // as though the linkset is unrotated. This is incompatible behavior with SL's
                    // implementation, so will break scripts imported from there (not to mention it
                    // makes it more difficult to determine a child prim's actual inworld position).
                    if (part.ParentID != 0)
                        {
                        LSL_Rotation rtmp = llGetRootRotation();
                        LSL_Vector rpos = llGetRootPosition();
                        v = ((v - rpos) * rtmp) + rpos;
                        }
                    res.Add(v);
                }

                if (code == (int)ScriptBaseClass.PRIM_SIZE)
                {
                    Vector3 tmp = part.Scale;
                    res.Add(new LSL_Vector(tmp.X,
                                                  tmp.Y,
                                                  tmp.Z));
                }

                if (code == (int)ScriptBaseClass.PRIM_ROTATION)
                {
                    res.Add(GetPartRot(part));
                }

                if (code == (int)ScriptBaseClass.PRIM_TYPE)
                {
                    // implementing box
                    PrimitiveBaseShape Shape = part.Shape;
                    int primType = (int)part.GetPrimType();
                    res.Add(new LSL_Integer(primType));
                    double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX
                    double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY.
                    if (primType == ScriptBaseClass.PRIM_TYPE_BOX ||
                         ScriptBaseClass.PRIM_TYPE_CYLINDER ||
                         ScriptBaseClass.PRIM_TYPE_PRISM)
                    {
                        res.Add(new LSL_Integer(Shape.ProfileCurve));
                        res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
                        res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
                        res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
                        res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));
                        res.Add(new LSL_Vector(topshearx, topsheary, 0));
                    }

                    if (primType == ScriptBaseClass.PRIM_TYPE_SPHERE)
                    {
                        res.Add(new LSL_Integer(Shape.ProfileCurve));
                        res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
                        res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
                        res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
                        res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
                    }

                    if (primType == ScriptBaseClass.PRIM_TYPE_SCULPT)
                    {
                        res.Add(Shape.SculptTexture.ToString());
                        res.Add(new LSL_Integer(Shape.SculptType));
                    }
                    if (primType == ScriptBaseClass.PRIM_TYPE_RING ||
                     ScriptBaseClass.PRIM_TYPE_TUBE ||
                     ScriptBaseClass.PRIM_TYPE_TORUS)
                    {
                        // holeshape
                        res.Add(new LSL_Integer(Shape.ProfileCurve));

                        // cut
                        res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));

                        // hollow
                        res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));

                        // twist
                        res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));

                        // vector holesize
                        res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));

                        // vector topshear
                        res.Add(new LSL_Vector(topshearx, topsheary, 0));

                        // vector profilecut
                        res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));

                        // vector tapera
                        res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));

                        // float revolutions
                        res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned
                        // byte is being used to represent the entire
                        // range of floating-point values from 1.0
                        // through 4.0 (which is how SL does it). 

                        // float radiusoffset
                        res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));

                        // float skew
                        res.Add(new LSL_Float(Shape.PathSkew / 100.0));
                    }
                }

                if (code == (int)ScriptBaseClass.PRIM_TEXTURE)
                {
                    if (remain < 1)
                        return res;

                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint)face);

                            res.Add(new LSL_String(texface.TextureID.ToString()));
                            res.Add(new LSL_Vector(texface.RepeatU,
                                                   texface.RepeatV,
                                                   0));
                            res.Add(new LSL_Vector(texface.OffsetU,
                                                   texface.OffsetV,
                                                   0));
                            res.Add(new LSL_Float(texface.Rotation));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint)face);

                            res.Add(new LSL_String(texface.TextureID.ToString()));
                            res.Add(new LSL_Vector(texface.RepeatU,
                                                   texface.RepeatV,
                                                   0));
                            res.Add(new LSL_Vector(texface.OffsetU,
                                                   texface.OffsetV,
                                                   0));
                            res.Add(new LSL_Float(texface.Rotation));
                        }
                    }
                }

                if (code == (int)ScriptBaseClass.PRIM_COLOR)
                {
                    if (remain < 1)
                        return res;

                    tex = part.Shape.Textures;
                    Color4 texcolor;
                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            texcolor = tex.GetFace((uint)face).RGBA;
                            res.Add(new LSL_Vector(texcolor.R,
                                                   texcolor.G,
                                                   texcolor.B));
                            res.Add(new LSL_Float(texcolor.A));
                        }
                    }
                    else
                    {
                        texcolor = tex.GetFace((uint)face).RGBA;
                        res.Add(new LSL_Vector(texcolor.R,
                                               texcolor.G,
                                               texcolor.B));
                        res.Add(new LSL_Float(texcolor.A));
                    }
                }

                if (code == (int)ScriptBaseClass.PRIM_BUMP_SHINY)
                {
                    if (remain < 1)
                        return res;

                    face = (int)rules.GetLSLIntegerItem(idx++);

                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
                            // Convert Shininess to PRIM_SHINY_*
                            res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
                            // PRIM_BUMP_*
                            res.Add(new LSL_Integer((int)texface.Bump));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
                            // Convert Shininess to PRIM_SHINY_*
                            res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
                            // PRIM_BUMP_*
                            res.Add(new LSL_Integer((int)texface.Bump));
                        }
                    }
                }

                if (code == (int)ScriptBaseClass.PRIM_FULLBRIGHT)
                {
                    if (remain < 1)
                        return res;

                    face = (int)rules.GetLSLIntegerItem(idx++);
                    tex = part.Shape.Textures;
                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
                            res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
                            res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
                        }
                    }
                }

                if (code == (int)ScriptBaseClass.PRIM_FLEXIBLE)
                {
                    PrimitiveBaseShape shape = part.Shape;

                    if (shape.FlexiEntry)
                        res.Add(new LSL_Integer(1));              // active
                    else
                        res.Add(new LSL_Integer(0));
                    res.Add(new LSL_Integer(shape.FlexiSoftness));// softness
                    res.Add(new LSL_Float(shape.FlexiGravity));   // gravity
                    res.Add(new LSL_Float(shape.FlexiDrag));      // friction
                    res.Add(new LSL_Float(shape.FlexiWind));      // wind
                    res.Add(new LSL_Float(shape.FlexiTension));   // tension
                    res.Add(new LSL_Vector(shape.FlexiForceX,       // force
                                           shape.FlexiForceY,
                                           shape.FlexiForceZ));
                }

                if (code == (int)ScriptBaseClass.PRIM_TEXGEN)
                {
                    if (remain < 1)
                        return res;

                    face = (int)rules.GetLSLIntegerItem(idx++);
                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            MappingType texgen = tex.GetFace((uint)face).TexMapType;
                            // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc.
                            res.Add(new LSL_Integer((uint)texgen >> 1));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            MappingType texgen = tex.GetFace((uint)face).TexMapType;
                            res.Add(new LSL_Integer((uint)texgen >> 1));
                        }
                    }
                }

                if (code == (int)ScriptBaseClass.PRIM_POINT_LIGHT)
                {
                    PrimitiveBaseShape shape = part.Shape;

                    if (shape.LightEntry)
                        res.Add(new LSL_Integer(1));              // active
                    else
                        res.Add(new LSL_Integer(0));
                    res.Add(new LSL_Vector(shape.LightColorR,       // color
                                           shape.LightColorG,
                                           shape.LightColorB));
                    res.Add(new LSL_Float(shape.LightIntensity)); // intensity
                    res.Add(new LSL_Float(shape.LightRadius));    // radius
                    res.Add(new LSL_Float(shape.LightFalloff));   // falloff
                }

                if (code == (int)ScriptBaseClass.PRIM_GLOW)
                {
                    if (remain < 1)
                        return res;

                    face = (int)rules.GetLSLIntegerItem(idx++);
                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
                            res.Add(new LSL_Float(texface.Glow));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
                            res.Add(new LSL_Float(texface.Glow));
                        }
                    }
                }

                if (code == (int)ScriptBaseClass.PRIM_TEXT)
                {
                    Color4 textColor = part.GetTextColor();
                    res.Add(part.Text);
                    res.Add(new LSL_Vector(textColor.R,
                                           textColor.G,
                                           textColor.B));
                    res.Add(new LSL_Float(textColor.A));
                }
                if (code == (int)ScriptBaseClass.PRIM_ROT_LOCAL)
                {
                    Quaternion rtmp = part.RotationOffset;
                    res.Add(new LSL_Rotation(rtmp.X, rtmp.Y, rtmp.Z, rtmp.W));
                }
            }
            return res;
        }
Пример #3
0
        public LSL_List GetLinkPrimitiveParams(ISceneChildEntity part, LSL_List rules)
        {
            LSL_List res = new LSL_List();
            int idx = 0;
            while (idx < rules.Length)
            {
                int code = rules.GetLSLIntegerItem(idx++);
                int remain = rules.Length - idx;
                Primitive.TextureEntry tex = part.Shape.Textures;
                int face = 0;

                if (code == (int) ScriptBaseClass.PRIM_NAME)
                {
                    res.Add(new LSL_String(part.Name));
                }

                else if (code == (int) ScriptBaseClass.PRIM_DESC)
                {
                    res.Add(new LSL_String(part.Description));
                }

                else if (code == (int) ScriptBaseClass.PRIM_MATERIAL)
                {
                    res.Add(new LSL_Integer(part.Material));
                }

                else if (code == (int) ScriptBaseClass.PRIM_PHYSICS)
                {
                    res.Add((part.GetEffectiveObjectFlags() & (uint) PrimFlags.Physics) != 0
                                ? new LSL_Integer(1)
                                : new LSL_Integer(0));
                }

                else if (code == (int) ScriptBaseClass.PRIM_TEMP_ON_REZ)
                {
                    res.Add((part.GetEffectiveObjectFlags() & (uint) PrimFlags.TemporaryOnRez) != 0
                                ? new LSL_Integer(1)
                                : new LSL_Integer(0));
                }

                else if (code == (int) ScriptBaseClass.PRIM_PHANTOM)
                {
                    res.Add((part.GetEffectiveObjectFlags() & (uint) PrimFlags.Phantom) != 0
                                ? new LSL_Integer(1)
                                : new LSL_Integer(0));
                }

                else if (code == (int) ScriptBaseClass.PRIM_POSITION)
                {
                    Vector3 tmp = part.AbsolutePosition;
                    LSL_Vector v = new LSL_Vector(tmp.X,
                                                  tmp.Y,
                                                  tmp.Z);
                    // For some reason, the part.AbsolutePosition.* values do not change if the
                    // linkset is rotated; they always reflect the child prim's world position
                    // as though the linkset is unrotated. This is incompatible behavior with SL's
                    // implementation, so will break scripts imported from there (not to mention it
                    // makes it more difficult to determine a child prim's actual inworld position).
                    if (part.ParentID != 0)
                    {
                        LSL_Rotation rtmp = llGetRootRotation();
                        LSL_Vector rpos = llGetRootPosition();
                        v = ((v - rpos)*rtmp) + rpos;
                    }
                    res.Add(v);
                }
                else if (code == (int) ScriptBaseClass.PRIM_POS_LOCAL)
                {
                    res.Add(GetLocalPos(part));
                }
                else if (code == (int) ScriptBaseClass.PRIM_SIZE)
                {
                    Vector3 tmp = part.Scale;
                    res.Add(new LSL_Vector(tmp.X,
                                           tmp.Y,
                                           tmp.Z));
                }

                else if (code == (int) ScriptBaseClass.PRIM_ROTATION)
                {
                    res.Add(GetPartRot(part));
                }

                else if (code == (int) ScriptBaseClass.PRIM_TYPE)
                {
                    // implementing box
                    PrimitiveBaseShape Shape = part.Shape;
                    int primType = (int) part.GetPrimType();
                    res.Add(new LSL_Integer(primType));
                    double topshearx = (sbyte) Shape.PathShearX/100.0; // Fix negative values for PathShearX
                    double topsheary = (sbyte) Shape.PathShearY/100.0; // and PathShearY.
                    if (primType == ScriptBaseClass.PRIM_TYPE_BOX ||
                        primType == ScriptBaseClass.PRIM_TYPE_CYLINDER ||
                        primType == ScriptBaseClass.PRIM_TYPE_PRISM)
                    {
                        res.Add(new LSL_Integer(Shape.ProfileCurve));
                        res.Add(new LSL_Vector(Shape.ProfileBegin/50000.0, 1 - Shape.ProfileEnd/50000.0, 0));
                        res.Add(new LSL_Float(Shape.ProfileHollow/50000.0));
                        res.Add(new LSL_Vector(Shape.PathTwistBegin/100.0, Shape.PathTwist/100.0, 0));
                        res.Add(new LSL_Vector(1 - (Shape.PathScaleX/100.0 - 1), 1 - (Shape.PathScaleY/100.0 - 1), 0));
                        res.Add(new LSL_Vector(topshearx, topsheary, 0));
                    }

                    if (primType == ScriptBaseClass.PRIM_TYPE_SPHERE)
                    {
                        res.Add(new LSL_Integer(Shape.ProfileCurve));
                        res.Add(new LSL_Vector(Shape.PathBegin/50000.0, 1 - Shape.PathEnd/50000.0, 0));
                        res.Add(new LSL_Float(Shape.ProfileHollow/50000.0));
                        res.Add(new LSL_Vector(Shape.PathTwistBegin/100.0, Shape.PathTwist/100.0, 0));
                        res.Add(new LSL_Vector(Shape.ProfileBegin/50000.0, 1 - Shape.ProfileEnd/50000.0, 0));
                    }

                    if (primType == ScriptBaseClass.PRIM_TYPE_SCULPT)
                    {
                        res.Add(Shape.SculptTexture.ToString());
                        res.Add(new LSL_Integer(Shape.SculptType));
                    }
                    if (primType == ScriptBaseClass.PRIM_TYPE_RING ||
                        primType == ScriptBaseClass.PRIM_TYPE_TUBE ||
                        primType == ScriptBaseClass.PRIM_TYPE_TORUS)
                    {
                        // holeshape
                        res.Add(new LSL_Integer(Shape.ProfileCurve));

                        // cut
                        res.Add(new LSL_Vector(Shape.PathBegin/50000.0, 1 - Shape.PathEnd/50000.0, 0));

                        // hollow
                        res.Add(new LSL_Float(Shape.ProfileHollow/50000.0));

                        // twist
                        res.Add(new LSL_Vector(Shape.PathTwistBegin/100.0, Shape.PathTwist/100.0, 0));

                        // vector holesize
                        res.Add(new LSL_Vector(1 - (Shape.PathScaleX/100.0 - 1), 1 - (Shape.PathScaleY/100.0 - 1), 0));

                        // vector topshear
                        res.Add(new LSL_Vector(topshearx, topsheary, 0));

                        // vector profilecut
                        res.Add(new LSL_Vector(Shape.ProfileBegin/50000.0, 1 - Shape.ProfileEnd/50000.0, 0));

                        // vector tapera
                        res.Add(new LSL_Vector(Shape.PathTaperX/100.0, Shape.PathTaperY/100.0, 0));

                        // float revolutions
                        res.Add(
                            new LSL_Float(Math.Round(Shape.PathRevolutions*0.015d, 2, MidpointRounding.AwayFromZero)) +
                            1.0d);
                        // Slightly inaccurate, because an unsigned byte is being used to represent
                        // the entire range of floating-point values from 1.0 through 4.0 (which is how
                        // SL does it).
                        //
                        // Using these formulas to store and retrieve PathRevolutions, it is not
                        // possible to use all values between 1.00 and 4.00. For instance, you can't
                        // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
                        // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
                        // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
                        // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
                        // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
                        // such as 1.10. So, SL must store and retreive the actual user input rather
                        // than only storing the encoded value.

                        // float radiusoffset
                        res.Add(new LSL_Float(Shape.PathRadiusOffset/100.0));

                        // float skew
                        res.Add(new LSL_Float(Shape.PathSkew/100.0));
                    }
                }

                else if (code == (int) ScriptBaseClass.PRIM_TEXTURE)
                {
                    if (remain < 1)
                        return res;
                    face = rules.GetLSLIntegerItem(idx++);
                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint) face);

                            res.Add(new LSL_String(texface.TextureID.ToString()));
                            res.Add(new LSL_Vector(texface.RepeatU,
                                                   texface.RepeatV,
                                                   0));
                            res.Add(new LSL_Vector(texface.OffsetU,
                                                   texface.OffsetV,
                                                   0));
                            res.Add(new LSL_Float(texface.Rotation));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint) face);

                            res.Add(new LSL_String(texface.TextureID.ToString()));
                            res.Add(new LSL_Vector(texface.RepeatU,
                                                   texface.RepeatV,
                                                   0));
                            res.Add(new LSL_Vector(texface.OffsetU,
                                                   texface.OffsetV,
                                                   0));
                            res.Add(new LSL_Float(texface.Rotation));
                        }
                    }
                }

                else if (code == (int) ScriptBaseClass.PRIM_COLOR)
                {
                    if (remain < 1)
                        return res;
                    face = rules.GetLSLIntegerItem(idx++);
                    tex = part.Shape.Textures;
                    Color4 texcolor;
                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            texcolor = tex.GetFace((uint) face).RGBA;
                            res.Add(new LSL_Vector(texcolor.R,
                                                   texcolor.G,
                                                   texcolor.B));
                            res.Add(new LSL_Float(texcolor.A));
                        }
                    }
                    else
                    {
                        texcolor = tex.GetFace((uint) face).RGBA;
                        res.Add(new LSL_Vector(texcolor.R,
                                               texcolor.G,
                                               texcolor.B));
                        res.Add(new LSL_Float(texcolor.A));
                    }
                }

                else if (code == (int) ScriptBaseClass.PRIM_BUMP_SHINY)
                {
                    if (remain < 1)
                        return res;

                    face = rules.GetLSLIntegerItem(idx++);

                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint) face);
                            // Convert Shininess to PRIM_SHINY_*
                            res.Add(new LSL_Integer((uint) texface.Shiny >> 6));
                            // PRIM_BUMP_*
                            res.Add(new LSL_Integer((int) texface.Bump));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint) face);
                            // Convert Shininess to PRIM_SHINY_*
                            res.Add(new LSL_Integer((uint) texface.Shiny >> 6));
                            // PRIM_BUMP_*
                            res.Add(new LSL_Integer((int) texface.Bump));
                        }
                    }
                }

                else if (code == (int) ScriptBaseClass.PRIM_FULLBRIGHT)
                {
                    if (remain < 1)
                        return res;

                    face = rules.GetLSLIntegerItem(idx++);
                    tex = part.Shape.Textures;
                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint) face);
                            res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint) face);
                            res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
                        }
                    }
                }

                else if (code == (int) ScriptBaseClass.PRIM_FLEXIBLE)
                {
                    PrimitiveBaseShape shape = part.Shape;

                    res.Add(shape.FlexiEntry ? new LSL_Integer(1) : new LSL_Integer(0));
                    res.Add(new LSL_Integer(shape.FlexiSoftness)); // softness
                    res.Add(new LSL_Float(shape.FlexiGravity)); // gravity
                    res.Add(new LSL_Float(shape.FlexiDrag)); // friction
                    res.Add(new LSL_Float(shape.FlexiWind)); // wind
                    res.Add(new LSL_Float(shape.FlexiTension)); // tension
                    res.Add(new LSL_Vector(shape.FlexiForceX, // force
                                           shape.FlexiForceY,
                                           shape.FlexiForceZ));
                }

                else if (code == (int) ScriptBaseClass.PRIM_TEXGEN)
                {
                    if (remain < 1)
                        return res;

                    face = rules.GetLSLIntegerItem(idx++);
                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            MappingType texgen = tex.GetFace((uint) face).TexMapType;
                            // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc.
                            res.Add(new LSL_Integer((uint) texgen >> 1));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            MappingType texgen = tex.GetFace((uint) face).TexMapType;
                            res.Add(new LSL_Integer((uint) texgen >> 1));
                        }
                    }
                }

                else if (code == (int) ScriptBaseClass.PRIM_POINT_LIGHT)
                {
                    PrimitiveBaseShape shape = part.Shape;

                    res.Add(shape.LightEntry ? new LSL_Integer(1) : new LSL_Integer(0));
                    res.Add(new LSL_Vector(shape.LightColorR, // color
                                           shape.LightColorG,
                                           shape.LightColorB));
                    res.Add(new LSL_Float(shape.LightIntensity)); // intensity
                    res.Add(new LSL_Float(shape.LightRadius)); // radius
                    res.Add(new LSL_Float(shape.LightFalloff)); // falloff
                }

                else if (code == (int) ScriptBaseClass.PRIM_GLOW)
                {
                    if (remain < 1)
                        return res;

                    face = rules.GetLSLIntegerItem(idx++);
                    if (face == ScriptBaseClass.ALL_SIDES)
                    {
                        for (face = 0; face < GetNumberOfSides(part); face++)
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint) face);
                            res.Add(new LSL_Float(texface.Glow));
                        }
                    }
                    else
                    {
                        if (face >= 0 && face < GetNumberOfSides(part))
                        {
                            Primitive.TextureEntryFace texface = tex.GetFace((uint) face);
                            res.Add(new LSL_Float(texface.Glow));
                        }
                    }
                }

                else if (code == (int) ScriptBaseClass.PRIM_TEXT)
                {
                    Color4 textColor = part.GetTextColor();
                    res.Add(new LSL_String(part.Text));
                    res.Add(new LSL_Vector(textColor.R,
                                           textColor.G,
                                           textColor.B));
                    res.Add(new LSL_Float(textColor.A));
                }
                else if (code == (int) ScriptBaseClass.PRIM_ROT_LOCAL)
                {
                    Quaternion rtmp = part.GetRotationOffset();
                    res.Add(new LSL_Rotation(rtmp.X, rtmp.Y, rtmp.Z, rtmp.W));
                }
                else if (code == (int) ScriptBaseClass.PRIM_OMEGA)
                {
                    Vector3 axis = part.OmegaAxis;
                    LSL_Float spinRate = part.OmegaSpinRate;
                    LSL_Float gain = part.OmegaGain;
                    res.Add(axis);
                    res.Add(spinRate);
                    res.Add(gain);
                }
                else if (code == (int) ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE)
                {
                    res.Add(new LSL_Integer(part.PhysicsType));
                }
                else if (code == (int) ScriptBaseClass.PRIM_LINK_TARGET)
                {
                    if (remain < 1)
                        continue;
                    LSL_Integer nextLink = rules.GetLSLIntegerItem(idx++);
                    List<ISceneChildEntity> entities = GetLinkParts(nextLink);
                    if (entities.Count > 0)
                        part = entities[0];
                }
            }
            return res;
        }