Example #1
0
 static public SsKeyAttrDesc GetById(SsKeyAttr attr)
 {
     foreach (SsKeyAttrDesc e in _list.Values)
     {
         if (e.Attr == attr)
         {
             return(e);
         }
     }
     // not found, fatal error!! must add element to the list
     return(null);
 }
Example #2
0
    GetAttrValues(SsKeyAttr attr)
    {
        switch (attr)
        {
        case SsKeyAttr.PosX:                    return(PosXValues);

        case SsKeyAttr.PosY:                    return(PosYValues);

        case SsKeyAttr.Angle:                   return(AngleValues);

        case SsKeyAttr.ScaleX:                  return(ScaleXValues);

        case SsKeyAttr.ScaleY:                  return(ScaleYValues);

        case SsKeyAttr.Trans:                   return(TransValues);

        case SsKeyAttr.Prio:                    return(PrioValues);

        case SsKeyAttr.FlipH:                   return(FlipHValues);

        case SsKeyAttr.FlipV:                   return(FlipVValues);

        case SsKeyAttr.Hide:                    return(HideValues);

        case SsKeyAttr.PartsCol:                return(PartsColValues);

        case SsKeyAttr.PartsPal:                return(PartsPalValues);

        case SsKeyAttr.Vertex:                  return(VertexValues);

        case SsKeyAttr.User:                    return(UserValues);

        case SsKeyAttr.Sound:                   return(SoundValues);

        case SsKeyAttr.ImageOffsetX:    return(ImageOffsetXValues);

        case SsKeyAttr.ImageOffsetY:    return(ImageOffsetYValues);

        case SsKeyAttr.ImageOffsetW:    return(ImageOffsetWValues);

        case SsKeyAttr.ImageOffsetH:    return(ImageOffsetHValues);

        case SsKeyAttr.OriginOffsetX:   return(OriginOffsetXValues);

        case SsKeyAttr.OriginOffsetY:   return(OriginOffsetYValues);
        }
        Debug.LogError("Unknown attribute: " + attr);
        return(null);
    }
Example #3
0
    GetKeyNumOf(SsKeyAttr attr)
    {
        switch (attr)
        {
        case SsKeyAttr.PosX:                    return(PosXKeys.Count);

        case SsKeyAttr.PosY:                    return(PosYKeys.Count);

        case SsKeyAttr.Angle:                   return(AngleKeys.Count);

        case SsKeyAttr.ScaleX:                  return(ScaleXKeys.Count);

        case SsKeyAttr.ScaleY:                  return(ScaleYKeys.Count);

        case SsKeyAttr.Trans:                   return(TransKeys.Count);

        case SsKeyAttr.Prio:                    return(PrioKeys.Count);

        case SsKeyAttr.FlipH:                   return(FlipHKeys.Count);

        case SsKeyAttr.FlipV:                   return(FlipVKeys.Count);

        case SsKeyAttr.Hide:                    return(HideKeys.Count);

        case SsKeyAttr.PartsCol:                return(PartsColKeys.Count);

        case SsKeyAttr.PartsPal:                return(PartsPalKeys.Count);

        case SsKeyAttr.Vertex:                  return(VertexKeys.Count);

        case SsKeyAttr.User:                    return(UserKeys.Count);

        case SsKeyAttr.Sound:                   return(SoundKeys.Count);

        case SsKeyAttr.ImageOffsetX:    return(ImageOffsetXKeys.Count);

        case SsKeyAttr.ImageOffsetY:    return(ImageOffsetYKeys.Count);

        case SsKeyAttr.ImageOffsetW:    return(ImageOffsetWKeys.Count);

        case SsKeyAttr.ImageOffsetH:    return(ImageOffsetHKeys.Count);

        case SsKeyAttr.OriginOffsetX:   return(OriginOffsetXKeys.Count);

        case SsKeyAttr.OriginOffsetY:   return(OriginOffsetYKeys.Count);
        }
        Debug.LogError("Unknown attribute: " + attr);
        return(0);
    }
Example #4
0
    AddKeyFrame(SsKeyAttr attr, SsKeyFrameInterface key)
    {
        switch (attr)
        {
        case SsKeyAttr.PosX:                    PosXKeys.Add((SsIntKeyFrame)key); return;

        case SsKeyAttr.PosY:                    PosYKeys.Add((SsIntKeyFrame)key); return;

        case SsKeyAttr.Angle:                   AngleKeys.Add((SsFloatKeyFrame)key); return;

        case SsKeyAttr.ScaleX:                  ScaleXKeys.Add((SsFloatKeyFrame)key); return;

        case SsKeyAttr.ScaleY:                  ScaleYKeys.Add((SsFloatKeyFrame)key); return;

        case SsKeyAttr.Trans:                   TransKeys.Add((SsFloatKeyFrame)key); return;

        case SsKeyAttr.Prio:                    PrioKeys.Add((SsIntKeyFrame)key); return;

        case SsKeyAttr.FlipH:                   FlipHKeys.Add((SsBoolKeyFrame)key); return;

        case SsKeyAttr.FlipV:                   FlipVKeys.Add((SsBoolKeyFrame)key); return;

        case SsKeyAttr.Hide:                    HideKeys.Add((SsBoolKeyFrame)key); return;

        case SsKeyAttr.PartsCol:                PartsColKeys.Add((SsColorBlendKeyFrame)key); return;

        case SsKeyAttr.PartsPal:                PartsPalKeys.Add((SsPaletteKeyFrame)key); return;

        case SsKeyAttr.Vertex:                  VertexKeys.Add((SsVertexKeyFrame)key); return;

        case SsKeyAttr.User:                    UserKeys.Add((SsUserDataKeyFrame)key); return;

        case SsKeyAttr.Sound:                   SoundKeys.Add((SsSoundKeyFrame)key); return;

        case SsKeyAttr.ImageOffsetX:    ImageOffsetXKeys.Add((SsIntKeyFrame)key); return;

        case SsKeyAttr.ImageOffsetY:    ImageOffsetYKeys.Add((SsIntKeyFrame)key); return;

        case SsKeyAttr.ImageOffsetW:    ImageOffsetWKeys.Add((SsIntKeyFrame)key); return;

        case SsKeyAttr.ImageOffsetH:    ImageOffsetHKeys.Add((SsIntKeyFrame)key); return;

        case SsKeyAttr.OriginOffsetX:   OriginOffsetXKeys.Add((SsIntKeyFrame)key); return;

        case SsKeyAttr.OriginOffsetY:   OriginOffsetYKeys.Add((SsIntKeyFrame)key); return;
        }
        Debug.LogError("Unknown attribute: " + attr);
    }
Example #5
0
    public float                                   InheritRate(SsKeyAttr attr)
    {
#if false
        // actual values are already inherited at import statically
        if (InheritState.Type == SsInheritanceType.Parent)
        {
            //... some code to get parent's value recursively.
        }
#endif
        SsInheritanceParam p = InheritParam(attr);
        if (!p.Use)
        {
            return(0f);
        }
        return(p.Rate);
    }
Example #6
0
    AttrValue <T, AttrType, KeyType>(SsKeyAttr attr, int frame, List <KeyType> keyList)
        where AttrType : SsAttrValueBase <T, KeyType>
        where KeyType : SsKeyFrameBase <T>
    {
        SsAttrValue[] values = GetAttrValues(attr);
        if (values.Length == 1)
        {
            // always use the value at frame 0 because this attribute has only one constant value.
            frame = 0;
        }
        SsAttrValue v = values[frame];

        if (v.HasValue)
        {
            // has direct value
#if _DEBUG
            AttrType derivedAttr;
            try{
                derivedAttr = (AttrType)v;
                return(derivedAttr.Value);
            }catch {
                Debug.LogError("derived VALUE can't be casted!!");
            }
            derivedAttr = (AttrType)v;
            return(derivedAttr.Value);
#else
            return(((AttrType)v).Value);
#endif
        }
        else
        {
            // use raw value of the key
            KeyType key = keyList[v.RefKeyIndex];
            return(key.Value);
        }
    }
Example #7
0
 public SsKeyAttrDesc(SsKeyAttr a, SsKeyValueType v, SsKeyCastType c)
 {
     Attr      = a;
     ValueType = v;
     CastType  = c;
 }
Example #8
0
	public SsKeyAttrDesc(SsKeyAttr a, SsKeyValueType v, SsKeyCastType c)
	{
		Attr = a;
		ValueType = v;
		CastType = c;
	}
Example #9
0
	static public SsKeyAttrDesc GetById(SsKeyAttr attr)
	{
		foreach (SsKeyAttrDesc e in _list.Values)
			if (e.Attr == attr)
				return e;
		// not found, fatal error!! must add element to the list
		return null;
	}
Example #10
0
    Parse(bool isAnime)    // = true)
    {
        if (_text == null)
        {
            return(false);
        }

        XmlDocument doc = new XmlDocument(); // doc is the new xml document.

        doc.LoadXml(_text);                  // load the file.

        string rootTagStr, rootNSStr;

        if (isAnime)
        {
            // this is .ssax
            rootTagStr = "SpriteStudioMotion";
            rootNSStr  = "http://www.webtech.co.jp/SpriteStudio/XML/Motion";
        }
        else
        {
            // this is .sssx
            rootTagStr = "SpriteStudioScene";
            rootNSStr  = "http://www.webtech.co.jp/SpriteStudio/XML/Scene";
        }

        // check the root tag name validity
        // root is ?xml, so skip to the next
        XmlNode rootNode = doc.FirstChild;

        rootNode = rootNode.NextSibling;
        if (rootNode.Name != rootTagStr)
        {
            Debug.LogError("Invalid root tag name: " + rootNode.Name);
            return(false);
        }

        // check the root tag namespace validity
        XmlAttributeCollection rootNodeAttrs = rootNode.Attributes;
        XmlNode nodeXMLNS = rootNodeAttrs["xmlns"];

        if (nodeXMLNS.Value != rootNSStr)
        {
            Debug.LogError("\"xmlns\" doesn't match: " + rootNode.Name);
            return(false);
        }

        // check file format version validity
        XmlNode versionNode = rootNodeAttrs["version"];
        int     readVersion = SsVersion.ToInt(versionNode.Value);

        if (readVersion < RequiredVersion)
        {
            Debug.LogError("Version under " + SsVersion.ToString(RequiredVersion) + " is not supported -> " + SsVersion.ToString(readVersion));
            return(false);
        }
        if (readVersion > CurrentVersion)
        {
            Debug.LogError("This version " + SsVersion.ToString(readVersion) + " is not supported yet. supports up to " + SsVersion.ToString(CurrentVersion));
            return(false);
        }

#if false
        // made sure the rootNode has Header, ImageList, Parts
        XmlNodeList children = rootNode.ChildNodes;
        foreach (XmlNode n in children)
        {
            Debug.Log(n.Name);
        }
#endif
        // Create an XmlNamespaceManager to resolve namespaces.
        NameTable nt = new NameTable();
        _nsMgr = new XmlNamespaceManager(nt);
        _nsMgr.AddNamespace("cur", nodeXMLNS.Value);

        // read header
        XmlNode headerNode = _SelectSingleNode(rootNode, "cur:Header");
        if (headerNode == null)
        {
            Debug.LogError("Header node is not found");
            return(false);
        }
        XmlNode endFrameNode = _SelectSingleNode(headerNode, "cur:EndFrame");
        if (endFrameNode == null)
        {
            Debug.LogError("EndFrame node is not found");
            return(false);
        }
        _anmRes.EndFrame = _ToInt(endFrameNode.InnerText);
#if NEED_EDIT_MODE
        _editMode = _ToInt(_SelectSingleNode(headerNode, "cur:EditMode").InnerText);
#endif
        _anmRes.FPS = _ToInt(_SelectSingleNode(headerNode, "cur:BaseTickTime").InnerText);

        // read option settings
        XmlNode optionNode = _SelectSingleNode(headerNode, "cur:OptionState");
        if (optionNode != null)
        {
            XmlNode n = _SelectSingleNode(optionNode, "cur:hvFlipForImageOnly");
            if (n == null)
            {
                _anmRes.hvFlipForImageOnly = true;
            }
            else
            {
                _anmRes.hvFlipForImageOnly = _ToBool(n.InnerText);
            }
        }

        // create image manager singleton
        //var imgMgr = SsImageManager.Singleton;

        // enumerate image paths
        // it is possible to be nothing in .ssax
        XmlNodeList imageNodeList = _SelectNodes(rootNode, "./cur:ImageList/cur:Image");
        if (imageNodeList == null)
        {
            Debug.LogError("ImageList node is not found");
            return(false);
        }
        if (imageNodeList.Count <= 0)
        {
            Debug.LogError("ImageList has no contents");
            return(false);
        }
        _anmRes.ImageList = new SsImageFile[imageNodeList.Count];

        //Debug.Log("imageNodeList.Count: " + imageNodeList.Count);
        foreach (XmlNode e in imageNodeList)
        {
            string idStr = e.Attributes["Id"].Value;
            int    index = _ToInt(idStr) - 1;           // because it starts from 1.
            string path  = e.Attributes["Path"].Value;
            // remove the useless string "./cur:" on head
            //Debug.Log("Id=" + idStr + " Path=" + path);
            if (path.StartsWith(@".\"))
            {
                path = path.Remove(0, 2);
            }
            path = path.Replace(@"\", "/");             // for Mac
            //path = _relPath + "/" + path; // doesn't care about ../
            string baseFullPath = Path.GetFullPath("./");
            path = Path.GetFullPath(Path.Combine(_relPath, path)); // combine path considering ../
            path = path.Substring(baseFullPath.Length);
            path = path.Replace(@"\", "/");                        // just in case
            //Debug.Log("Id=" + index + " Path=" + path);

            // get image file info which contains a Texture Asset.
            SsImageFile imgFile = GetImage(path);
            if (imgFile == null)
            {
                return(false);
            }

            XmlNode widthNode = e.Attributes["Width"];
            if (widthNode != null)
            {
                imgFile.width = _ToInt(widthNode.Value);
                if (!_IsPowerOfTwo(imgFile.width))
                {
                    Debug.LogWarning("Image width is not power of 2, it will be scaled.");
                }
            }
            else
            {
                imgFile.width = imgFile.texture.width;
            }

            XmlNode heightNode = e.Attributes["Height"];
            if (heightNode != null)
            {
                imgFile.height = _ToInt(heightNode.Value);
                if (!_IsPowerOfTwo(imgFile.height))
                {
                    Debug.LogWarning("Image height is not power of 2, it will be scaled.");
                }
            }
            else
            {
                imgFile.height = imgFile.texture.height;
            }

            // For now, bpp is not used anywhere.
            XmlNode bppNode = e.Attributes["Bpp"];
            if (bppNode != null)
            {
                imgFile.bpp = _ToInt(bppNode.Value);
                if (imgFile.bpp <= 8)
                {
                    Debug.LogWarning(path + " seems index color image, so it has to be converted to direct color or compressed type");
                }
            }
            else
            {
                switch (imgFile.texture.format)
                {
                default:
                    imgFile.bpp = 0;                            // Zero means something compressed type
                    break;

                case TextureFormat.ARGB4444:
                case TextureFormat.RGB565:
                    imgFile.bpp = 16;
                    break;

                case TextureFormat.RGB24:
                    imgFile.bpp = 24;
                    break;

                case TextureFormat.ARGB32:
                case TextureFormat.RGBA32:
                    imgFile.bpp = 32;
                    break;
                }
            }

            // register image info into the list
            _anmRes.ImageList[index] = imgFile;
        }

        // enumerate parts
        XmlNodeList partList = _SelectNodes(rootNode, "./cur:Parts/cur:Part");
        if (partList == null)
        {
            Debug.LogError("Parts node is not found");
            return(false);
        }
        //Debug.Log("Parts Num: " + partList.Count);
        if (partList.Count <= 0)
        {
            Debug.LogError("No existence of Parts");
            return(false);
        }

        _anmRes.PartList = new SsPartRes[partList.Count];

        foreach (XmlNode part in partList)
        {
            // create a part
            var partBase = new SsPartRes();
            partBase.AnimeRes = _anmRes;

            XmlAttribute rootAttr = part.Attributes["Root"];

            partBase.InheritState.Initialize(4, _anmRes.hvFlipForImageOnly);
            string partName = _GetNodeValue(part, "./cur:Name");
            partBase.Name = System.String.Copy(partName);
            if (rootAttr != null)
            {
                // this is root parts
                partBase.Type     = SsPartType.Root;
                partBase.MyId     = 0;
                partBase.ParentId = -1;
            }
            else
            {
                // general parts
                partBase.Type              = (SsPartType)_ToInt(_GetNodeValue(part, "./cur:Type"));
                partBase.PicArea.Top       = _ToInt(_GetNodeValue(part, "./cur:PictArea/cur:Top"));
                partBase.PicArea.Left      = _ToInt(_GetNodeValue(part, "./cur:PictArea/cur:Left"));
                partBase.PicArea.Bottom    = _ToInt(_GetNodeValue(part, "./cur:PictArea/cur:Bottom"));
                partBase.PicArea.Right     = _ToInt(_GetNodeValue(part, "./cur:PictArea/cur:Right"));
                partBase.OriginX           = _ToInt(_GetNodeValue(part, "./cur:OriginX"));
                partBase.OriginY           = _ToInt(_GetNodeValue(part, "./cur:OriginY"));
                partBase.MyId              = 1 + _ToInt(_GetNodeValue(part, "./cur:ID"));
                partBase.ParentId          = 1 + _ToInt(_GetNodeValue(part, "./cur:ParentID"));
                partBase.SrcObjId          = _ToInt(_GetNodeValue(part, "./cur:PicID"));
                partBase.AlphaBlendType    = (SsAlphaBlendOperation)(1 + _ToInt(_GetNodeValue(part, "./cur:TransBlendType")));
                partBase.InheritState.Type = (SsInheritanceType)_ToInt(_GetNodeValue(part, "./cur:InheritType"));

                if (partBase.SrcObjId >= _anmRes.ImageList.Length)
                {
                    /*
                     * // supply lack of image
                     * int count = 1 + partBase.SrcObjId - _anmRes.ImageList.Length;
                     * _anmRes.ImageList.
                     * for (int i = 0; i < count; ++i)
                     * {
                     *      _anmRes.ImageList[partBase.SrcObjId + i] = SsImageFile.invalidInstance;
                     * }
                     */
                    // clamp id
                    Debug.LogWarning("Picture ID is out of image list. Part: " + partName + " PicId: " + partBase.SrcObjId);
                    partBase.SrcObjId = 0;
                }

                partBase.imageFile = _anmRes.ImageList[partBase.SrcObjId];
                if (partBase.imageFile != SsImageFile.invalidInstance)
                {
                    // precalc UV coordinates
                    partBase.CalcUVs(0, 0, 0, 0);

                    // add basic material with basic shader
                    AddMaterials(partBase, SsColorBlendOperation.Non);
                }

                if (partBase.InheritState.Type == SsInheritanceType.Parent)
                {
                    // copy parent's value and rate statically. dynamic reference is certain implement but it costs much more.
                    for (int i = 0; i < (int)SsKeyAttr.Num; ++i)
                    {
                        SsKeyAttr attr  = (SsKeyAttr)i;
                        var       param = _anmRes.PartList[partBase.ParentId].InheritParam(attr);
                        partBase.InheritState.Values[i] = param;
                        //Debug.Log(partBase.Name +" inherits parent's attr: " + attr + " use: " + param.Use + " rate:" + param.Rate);
                    }
                }
            }

            // make original 4 vertices will be not modified. it consists of OriginX/Y and PicArea.WH.
            partBase.OrgVertices = partBase.GetVertices(partBase.PicArea.WH());

#if false
            // parent part
            SsPartRes parentPart = null;
            if (partBase.ParentId >= 0)
            {
                parentPart = _anmRes.PartList[partBase.ParentId];
            }
#endif

            if (!isAnime)
            {
                // scene only has this element
                partBase.SrcObjType = (SsSourceObjectType)_ToInt(_GetNodeValue(part, "./cur:ObjectType"));
            }

            // parse attributes
            XmlNodeList attrList = _SelectNodes(part, "./cur:Attributes/cur:Attribute");
            string      attrName;
            foreach (XmlNode attrNode in attrList)
            {
                // recognize the tag
                attrName = attrNode.Attributes["Tag"].Value;
                if (attrName.Length != 4)
                {
                    Debug.LogWarning("invalid attribute tag!!: " + attrName);
                    continue;
                }
                SsKeyAttrDesc attrDesc = SsKeyAttrDescManager.Get(attrName);
                if (attrDesc == null)
                {
                    Debug.LogWarning("Unknown or Unsupported attribute: " + attrName);
                    continue;
                }

                switch (attrDesc.Attr)
                {
                case SsKeyAttr.PartsPal:
                    if (attrNode.HasChildNodes)
                    {
                        Debug.LogWarning("Unsupported attribute: " + attrName);
                    }
                    continue;
                }

                // set inheritance parameter to part instance.
                if (partBase.Type != SsPartType.Root)
                {
                    if (partBase.InheritState.Type == SsInheritanceType.Self)
                    {
                        // has its own value.
                        var     InheritParam = new SsInheritanceParam();
                        XmlNode InheritNode  = attrNode.Attributes.GetNamedItem("Inherit");
                        if (InheritNode != null)
                        {
                            // mix my value and parent's value, but actually user 100% parent's...
                            InheritParam.Use  = true;
                            InheritParam.Rate = (100 * _ToInt(InheritNode.Value)) / SSIO_SUCCEED_DENOMINATOR;
                        }
                        else
                        {
                            // absolutely not refer the parent's value.
                            InheritParam.Use  = false;
                            InheritParam.Rate = 0;
                        }
                        // apply to part
                        partBase.InheritState.Values[(int)attrDesc.Attr] = InheritParam;
                        //Debug.LogError(partBase.Name +" has own value! attr:" + attrDesc.Attr + " use:" + InheritParam.Use);
                    }
                }

                // enumerate keys
                XmlNodeList keyList = _SelectNodes(attrNode, "./cur:Key");
                if (keyList == null ||
                    keyList.Count < 1)
                {
                    //Debug.Log(attrName + " has no keys");
                }
                else
                {
                    foreach (XmlNode key in keyList)
                    {
                        //dynamic keyBase;	cannot use dynamic at this time
                        SsKeyFrameInterface keyBase;
                        bool bNeedCurve = true;
                        switch (attrDesc.ValueType)
                        {
                        case SsKeyValueType.Data:
                        {
                            // if value type is Data, string format of node "Value" depends on attribute type.
                            string strValue = _GetNodeValue(key, "./cur:Value");
                            switch (attrDesc.CastType)
                            {
                            default:
                            case SsKeyCastType.Bool:                                            // not supported currently
                            case SsKeyCastType.Other:                                           // not supported currently
                            case SsKeyCastType.Int:
                            case SsKeyCastType.Hex:
                                // these types are used as integer.
                                var intKey = new SsIntKeyFrame();                                               // to make intellisence working, really??
                                if (attrDesc.CastType == SsKeyCastType.Hex)
                                {
                                    intKey.Value = _HexToInt(strValue);
                                }
                                else
                                {
                                    intKey.Value = _ToInt(strValue);
                                }

                                switch (attrDesc.Attr)
                                {
                                case SsKeyAttr.PosX:
                                case SsKeyAttr.PosY:
                                    // apply scale factor
                                    intKey.Value = (int)((float)intKey.Value * _anmRes.ScaleFactor);
                                    break;

#if _FORCE_BOUND_PART_TO_MOST_TOP
                                // force bound part to most top to draw surely if wanted
                                case SsKeyAttr.Prio:
                                    if (partBase.Type == SsPartType.Bound)
                                    {
                                        intKey.Value = short.MaxValue;                                                  // int.MaxValue is failed to unbox
                                    }
                                    break;
#endif
                                }
#if _DEBUG
                                Debug.LogWarning("Is it OK? -> " + strValue + " = " + intKey.Value);
#endif
                                keyBase = intKey;
                                break;

                            case SsKeyCastType.Float:
                            case SsKeyCastType.Degree:
                                var floatKey = new SsFloatKeyFrame();                                                   // to make intellisence working, really??
#if _FORCE_BOUND_PART_TO_BE_TRANSPARENT
                                // force bound part to transparent to draw if wanted
                                if (attrDesc.Attr == SsKeyAttr.Trans &&
                                    partBase.Type == SsPartType.Bound)
                                {
                                    floatKey.Value = 0.5f;
                                }
                                else
#endif
                                floatKey.Value = (float)_ToDouble(strValue);
                                // unnecessary to convert to radian. because Unity requires degree unit.
                                //if (attrDesc.CastType == SsKeyCastType.Degree)
                                //floatKey.Value = (float)_DegToRad( _ToDouble(strValue) );
                                keyBase = floatKey;
                                break;
                            }
                        }
                        break;

                        case SsKeyValueType.Param:
                        {
                            var boolKey = new SsBoolKeyFrame();
                            keyBase       = boolKey;
                            boolKey.Value = _ToUInt(_GetNodeValue(key, "./cur:Value")) != 0 ? true : false;
                            bNeedCurve    = false;
                        }
                        break;

                        case SsKeyValueType.Palette:
                        {
                            var paletteKey = new SsPaletteKeyFrame();
                            keyBase = paletteKey;
                            var v = new SsPaletteKeyValue();
                            v.Use            = _ToUInt(_GetNodeValue(key, "./cur:Use")) != 0 ? true : false;
                            v.Page           = _ToInt(_GetNodeValue(key, "./cur:Page"));
                            v.Block          = (byte)_ToInt(_GetNodeValue(key, "./cur:Block"));
                            paletteKey.Value = v;
                        }
                        break;

                        case SsKeyValueType.Color:
                        {
                            var colorBlendKey = new SsColorBlendKeyFrame();
                            keyBase = colorBlendKey;
                            var v = new SsColorBlendKeyValue(4);
                            v.Target    = (SsColorBlendTarget)_ToUInt(_GetNodeValue(key, "./cur:Type"));
                            v.Operation = (SsColorBlendOperation)(1 + _ToUInt(_GetNodeValue(key, "./cur:Blend")));
                            AddMaterials(partBase, v.Operation);
                            switch (v.Target)
                            {
                            case SsColorBlendTarget.None:
                                // no color, but do care about interpolation to/from 4 vertex colors
                                for (int i = 0; i < 4; ++i)
                                {
                                    v.Colors[i].R = v.Colors[i].G = v.Colors[i].B = 255;
                                    // 0 alpha value means no effect.
                                    v.Colors[i].A = 0;
                                }
                                break;

                            case SsColorBlendTarget.Overall:
                                // one color, but do care about interpolation to/from 4 vertex colors
                                _GetColorRef(v.Colors[0], key, "./cur:Value");
                                for (int i = 1; i < 4; ++i)
                                {
                                    v.Colors[i] = v.Colors[0];
                                }
                                break;

                            case SsColorBlendTarget.Vertex:
                                // 4 vertex colors. the order is clockwise.
                                _GetColorRef(v.Colors[0], key, "./cur:TopLeft");
                                _GetColorRef(v.Colors[1], key, "./cur:TopRight");
                                _GetColorRef(v.Colors[2], key, "./cur:BottomRight");
                                _GetColorRef(v.Colors[3], key, "./cur:BottomLeft");
                                break;
                            }
                            colorBlendKey.Value = v;
                        }
                        break;

                        case SsKeyValueType.Vertex:
                        {
                            var vertexKey = new SsVertexKeyFrame();
                            keyBase = vertexKey;
                            var v = new SsVertexKeyValue(4);
                            _GetPoint(v.Vertices[0], key, "./cur:TopLeft");
                            _GetPoint(v.Vertices[1], key, "./cur:TopRight");

                            if (readVersion <= (uint)SsAnimeFormatVersion.V320)
                            {                                    // for obsolete version
                                _GetPoint(v.Vertices[2], key, "./cur:BottomLeft");
                                _GetPoint(v.Vertices[3], key, "./cur:BottomRight");
                            }
                            else
                            {
                                _GetPoint(v.Vertices[3], key, "./cur:BottomLeft");
                                _GetPoint(v.Vertices[2], key, "./cur:BottomRight");
                            }
                            // apply scale factor
                            for (int i = 0; i < v.Vertices.Length; ++i)
                            {
                                v.Vertices[i].Scale(_anmRes.ScaleFactor);
                            }
                            vertexKey.Value = v;
                        }
                        break;

                        case SsKeyValueType.User:
                        {
                            var userKey = new SsUserDataKeyFrame();
                            keyBase = userKey;
                            var     v          = new SsUserDataKeyValue();
                            XmlNode numberNode = _SelectSingleNode(key, "./cur:Number");
                            if (numberNode != null)
                            {
                                v.IsNum = true;
                                v.Num   = _ToInt(numberNode.InnerText);
                            }
                            XmlNode rectNode = _SelectSingleNode(key, "./cur:Rect");
                            if (rectNode != null)
                            {
                                v.IsRect = true;
                                v.Rect   = new SsRect();
                                _GetRect(v.Rect, rectNode);
                            }
                            XmlNode pointNode = _SelectSingleNode(key, "./cur:Point");
                            if (pointNode != null)
                            {
                                v.IsPoint = true;
                                v.Point   = new SsPoint();
                                _GetPoint(v.Point, pointNode);
                            }
                            XmlNode stringNode = _SelectSingleNode(key, "./cur:String");
                            if (stringNode != null)
                            {
                                v.IsString = true;
                                v.String   = System.String.Copy(stringNode.InnerText);
                            }
                            // writeback
                            userKey.Value = v;

                            bNeedCurve = false;
                        }                                 // case KEYTYPE_USERDATA
                        break;

                        case SsKeyValueType.Sound:
                        {
                            var soundKey = new SsSoundKeyFrame();
                            keyBase = soundKey;
                            var v = new SsSoundKeyValue();
                            v.Flags    = (SsSoundKeyFlags)_ToUInt(_SelectSingleNode(key, "./cur:Use").InnerText);
                            v.NoteOn   = _ToByte(_SelectSingleNode(key, "./cur:Note").InnerText);
                            v.SoundId  = _ToByte(_SelectSingleNode(key, "./cur:ID").InnerText);
                            v.LoopNum  = _ToByte(_SelectSingleNode(key, "./cur:Loop").InnerText);
                            v.Volume   = _ToByte(_SelectSingleNode(key, "./cur:Volume").InnerText);
                            v.UserData = _ToUInt(_SelectSingleNode(key, "./cur:Data").InnerText);
                            // writeback
                            soundKey.Value = v;

                            bNeedCurve = false;
                        }
                        break;

                        default:
                            Debug.LogError("Fatal error!! not implemented cast type: " + _ToInt(attrNode.Value));
                            continue;
                        }                         // switch

                        //keyBase = InitKeyFrameData();
                        keyBase.ValueType = attrDesc.ValueType;
                        keyBase.Time      = _ToInt(key.Attributes["Time"].Value);

                        if (bNeedCurve)
                        {
                            // make values to interpolate
                            var v = new SsCurveParams();

                            XmlNode curveTypeNode = key.Attributes["CurveType"];
                            if (curveTypeNode == null)
                            {
                                v.Type = SsInterpolationType.None;
                            }
                            else
                            {
                                v.Type = (SsInterpolationType)_ToUInt(curveTypeNode.Value);
                                if (v.Type == SsInterpolationType.Hermite ||
                                    v.Type == SsInterpolationType.Bezier)
                                {
                                    // must exist
                                    if (key.Attributes["CurveStartT"] == null)
                                    {
                                        Debug.LogError("CurveStartT param not found!!");
                                        return(false);
                                    }

                                    v.StartT = _ToFloat(key.Attributes["CurveStartT"].Value);
                                    v.StartV = _ToFloat(key.Attributes["CurveStartV"].Value);
                                    v.EndT   = _ToFloat(key.Attributes["CurveEndT"].Value);
                                    v.EndV   = _ToFloat(key.Attributes["CurveEndV"].Value);

                                    switch (attrDesc.Attr)
                                    {
                                    case SsKeyAttr.PosX:
                                    case SsKeyAttr.PosY:
                                    case SsKeyAttr.Vertex:
                                        // apply scale factor
                                        v.StartV *= _anmRes.ScaleFactor;
                                        v.EndV   *= _anmRes.ScaleFactor;
                                        break;

                                    case SsKeyAttr.Angle:
                                        if (_database.AngleCurveParamAsRadian)
                                        {
                                            // degree to radian
                                            v.StartV = (float)(v.StartV * 180 / System.Math.PI);
                                            v.EndV   = (float)(v.EndV * 180 / System.Math.PI);
                                        }
                                        break;
                                    }
                                }
                            }
                            keyBase.Curve = v;
                        }

#if false//_DEBUG
                        // dump debug info
                        SsDebugLog.Print("Attr: " + attrDesc.Attr + " " + keyBase.ToString());
#endif

                        // add keyFrame info to part instance.
                        partBase.AddKeyFrame(attrDesc.Attr, keyBase);
                    }
                }
            }
#if _DEBUG
            // dump debug info
            SsDebugLog.Print(partBase.ToString());
#endif
            if (_precalcAttrValues)
            {
                // precalculate attribute values each frame
                partBase.CreateAttrValues(_anmRes.EndFrame + 1);
            }

            // add to list
            // if the container is Dictionary, allow non-sequential ID order of the stored parts, but it occurs to search by ID.
            _anmRes.PartList[partBase.MyId] = partBase;
            //_anmRes.PartList.Add(partBase);
        }
//		Debug.Log("_anmRes.PartList.Count: " + _anmRes.PartList.Count);

#if false
        // precalculate values to inherit parent's one.
        if (PrecalcAttrValues)
        {
            //foreach (var e in _anmRes.PartList.Values) // for Dictionary version
            foreach (var e in _anmRes.PartList)
            {
                if (!e.IsRoot && e.HasParent)
                {
                    e.CalcInheritedValues(_anmRes.PartList[e.ParentId]);
                }
            }
        }
#endif

        return(true);
    }
Example #11
0
    _OnEvent(SsKeyAttr attr)
    {
        // take value at just key frame.
        SsAttrValue[] values = _res.GetAttrValues(attr);
        if (values.Length == 0)
        {
            return;
        }

        // ignore within previous frame
        if ((int)_mgr._animeFrame == (int)_mgr._prevFrame)
        {
            return;
        }

        // trace each frame from previous frame to current frame.
        int destFrame = (int)_mgr._animeFrame;
        int frame     = (int)_mgr._prevFrame;

        for (int i = 0; i < _mgr._playFrameLength; ++i)
        {
            frame = _mgr._StepFrameFromPrev(frame);

            SsAttrValue v;
            if (frame < values.Length)
            {
                // get value at this frame
                v = values[frame];
            }
            else
            {
                // refer to the single value consolidated from multiple keyframes
                v = values[0];
            }

            // is this a generated value from interpolation?
            if (!v.HasValue)
            {
                // is time just at key?
                SsKeyFrameInterface key = _res.GetKey(attr, v.RefKeyIndex);
                if (key.Time == frame)
                {
                    // OK
                    switch (attr)
                    {
                    case SsKeyAttr.User:
                        SsUserDataKeyFrame userKey = (SsUserDataKeyFrame)key;
                        OnUserDataKey(this, userKey.Value);
                        break;

                    case SsKeyAttr.Sound:
                        SsSoundKeyFrame soundKey = (SsSoundKeyFrame)key;
                        OnSoundKey(this, soundKey.Value);
                        break;

                    default:
                        Debug.LogWarning("Not implemented event: " + attr);
                        break;
                    }
                }
            }
            if (frame == destFrame)
            {
                break;
            }
        }
    }
Example #12
0
    // initialize value depending on file format version
    public void Initialize(int iVersion, bool imageFlip)
    {
        Type = SsInheritanceType.Parent;                // first, set parent's value as intial value.
        for (int i = 0; i < Values.Length; i++)
        {
            Values[i] = new SsInheritanceParam();
            SsKeyAttr attr = (SsKeyAttr)i;
#if false
            // obsolete
            if (iVersion == 0)
            {
                // just to get info?
                Values[i].Use = true;
            }
            else if (iVersion == 1)
            {
                // compatible with Ver.1
                Type = SsInheritanceType.Self;                 // use myself value
                //			if( i <= KEYFRAME_PRIO )
                if ((attr == SsKeyAttr.FlipV) || (attr == SsKeyAttr.FlipH) || (attr == SsKeyAttr.Hide))
                {
                    Values[i].Use = false;
                }
                else
                {
                    Values[i].Use = true;
                }
            }
            else
            {
                // compatible with Ver.2
                if (!imageFlip)
                {
                    Values[i].Use = true;
                }
                else
                {
                    if ((attr == SsKeyAttr.FlipV) || (attr == SsKeyAttr.FlipH) || (attr == SsKeyAttr.Hide))
                    {
                        Values[i].Use = false;
                    }
                    else
                    {
                        Values[i].Use = true;
                    }
                }
            }
#else
            if (attr == SsKeyAttr.FlipV ||
                attr == SsKeyAttr.FlipH ||
                attr == SsKeyAttr.Hide)
            {
                Values[i].Use  = false;
                Values[i].Rate = 0f;
            }
            else
            {
                Values[i].Use  = true;
                Values[i].Rate = 1f;
            }
#endif
        }
    }
Example #13
0
    CreateAttrValues(int frameNum)
    {
        if (frameNum <= 0)
        {
            Debug.LogWarning("No keys to precalculate.");
            return;
        }
        FrameNum = frameNum;
//		if (keyFrameLists == null)
//		{
//			Debug.LogError("Key frame list must be prepared.");
//			return;
//		}
#if _DEBUG
        SsDebugLog.PrintLn("CreateAttrValues()");
        SsDebugLog.PrintLn("Name: " + Name);
#endif

        // create temporary key frame list
//		keyFrameLists = new List<SsKeyFrameInterface>[(int)SsKeyAttr.Num];
//		keyFrameLists[(int)SsKeyAttr.PosX] = PosXKeys;

        // create attribute value lists
        for (int attrIdx = 0; attrIdx < (int)SsKeyAttr.Num; ++attrIdx)
        {
            SsKeyAttr attr   = (SsKeyAttr)attrIdx;
            int       keyNum = GetKeyNumOf(attr);

            // skip non-key attribute
            if (keyNum <= 0)
            {
                continue;
            }

            int curKeyIndex             = 0;
            SsKeyFrameInterface curKey  = GetKey(attr, 0);
            int nextKeyIndex            = 0;
            SsKeyFrameInterface nextKey = null;
            int valuesNum = 1;
            if (keyNum > 1)
            {
                nextKey      = GetKey(attr, 1);
                nextKeyIndex = 1;
                // consolidate identical values if possible
                for (int i = 1; i < keyNum; ++i)
                {
                    SsKeyFrameInterface key = GetKey(attr, i);
                    if (!key.EqualsValue(curKey))
                    {
                        // give up consolidating
                        valuesNum = frameNum;
                        break;
                    }
                }
            }
            else if (keyNum == 1)
            {
                if (attr == SsKeyAttr.Hide)
                {
                    SsBoolKeyFrame hideKey = (SsBoolKeyFrame)curKey;
                    if (hideKey.Value == false)
                    {
                        valuesNum = frameNum;
                    }
                }
            }

            SsKeyAttrDesc attrDesc = SsKeyAttrDescManager.GetById(attr);
            switch (attr)
            {
            case SsKeyAttr.PosX:    PosXValues = new SsIntAttrValue[valuesNum];             break;

            case SsKeyAttr.PosY:    PosYValues = new SsIntAttrValue[valuesNum];             break;

            case SsKeyAttr.Angle:   AngleValues = new SsFloatAttrValue[valuesNum];  break;

            case SsKeyAttr.ScaleX:  ScaleXValues = new SsFloatAttrValue[valuesNum]; break;

            case SsKeyAttr.ScaleY:  ScaleYValues = new SsFloatAttrValue[valuesNum]; break;

            case SsKeyAttr.Trans:   TransValues = new SsFloatAttrValue[valuesNum];  break;

            case SsKeyAttr.Prio:    PrioValues = new SsIntAttrValue[valuesNum];             break;

            case SsKeyAttr.FlipH:   FlipHValues = new SsBoolAttrValue[valuesNum];   break;

            case SsKeyAttr.FlipV:   FlipVValues = new SsBoolAttrValue[valuesNum];   break;

            case SsKeyAttr.Hide:    HideValues = new SsBoolAttrValue[valuesNum];            break;

            case SsKeyAttr.PartsCol: PartsColValues = new SsColorBlendAttrValue[valuesNum]; break;

            case SsKeyAttr.PartsPal: PartsPalValues = new SsPaletteAttrValue[valuesNum]; break;

            case SsKeyAttr.Vertex:  VertexValues = new SsVertexAttrValue[valuesNum];        break;

            case SsKeyAttr.User:    UserValues = new SsUserDataAttrValue[valuesNum];        break;

            case SsKeyAttr.Sound:   SoundValues = new SsSoundAttrValue[valuesNum];  break;

            case SsKeyAttr.ImageOffsetX:    ImageOffsetXValues = new SsIntAttrValue[valuesNum];     break;

            case SsKeyAttr.ImageOffsetY:    ImageOffsetYValues = new SsIntAttrValue[valuesNum];     break;

            case SsKeyAttr.ImageOffsetW:    ImageOffsetWValues = new SsIntAttrValue[valuesNum];     break;

            case SsKeyAttr.ImageOffsetH:    ImageOffsetHValues = new SsIntAttrValue[valuesNum];     break;

            case SsKeyAttr.OriginOffsetX:   OriginOffsetXValues = new SsIntAttrValue[valuesNum];    break;

            case SsKeyAttr.OriginOffsetY:   OriginOffsetYValues = new SsIntAttrValue[valuesNum];    break;
            }
            // mark that this attribute is used.
            _hasAttrFlags |= (SsKeyAttrFlags)(1 << attrIdx);
#if _DEBUG
            SsDebugLog.Print(string.Format("\tAttr[{0}]: {1}\n", attrIdx, attrDesc.Attr));
#endif
            for (int frame = 0; frame < valuesNum; ++frame)
            {
                if (nextKey != null &&
                    frame >= nextKey.Time)
                {
                    // advance to next keyed frame
                    curKeyIndex = nextKeyIndex;
                    curKey      = nextKey;
                    ++nextKeyIndex;
                    nextKey = nextKeyIndex < keyNum?GetKey(attr, nextKeyIndex) : null;
                }

                // base typed value
                SsAttrValue v = null;
                // create new value to add
                SsBoolAttrValue  boolValue  = null;
                SsIntAttrValue   intValue   = null;
                SsFloatAttrValue floatValue = null;
//				SsPointAttrValue		pointValue = null;
                SsPaletteAttrValue    paletteValue    = null;
                SsColorBlendAttrValue colorBlendValue = null;
                SsVertexAttrValue     vertexValue     = null;
                SsUserDataAttrValue   userValue       = null;
                SsSoundAttrValue      soundValue      = null;
                switch (attrDesc.ValueType)
                {
                case SsKeyValueType.Data:                               ///< actually decimal or integer
                    switch (attrDesc.CastType)
                    {
                    default:
                        v = intValue = new SsIntAttrValue();
                        break;

                    case SsKeyCastType.Float:
                    case SsKeyCastType.Degree:
                        v = floatValue = new SsFloatAttrValue();
                        break;
                    }
                    break;

                case SsKeyValueType.Param:                              ///< actually boolean
                    v = boolValue = new SsBoolAttrValue();
                    break;

//				case SsKeyValueType.Point:		///< x,y
//					v = pointValue = new SsPointAttrValue();
//					break;
                case SsKeyValueType.Palette:                    ///< left,top,right,bottom
                    v = paletteValue = new SsPaletteAttrValue();
                    break;

                case SsKeyValueType.Color:                              ///< single or vertex colors
                    v = colorBlendValue = new SsColorBlendAttrValue();
                    break;

                case SsKeyValueType.Vertex:                             ///< vertex positions relative to origin
                    v = vertexValue = new SsVertexAttrValue();
                    break;

                case SsKeyValueType.User:                               ///< user defined data(numeric|point|rect|string...)
                    v = userValue = new SsUserDataAttrValue();
                    break;

                case SsKeyValueType.Sound:                              ///< sound id, volume, note on...
                    v = soundValue = new SsSoundAttrValue();
                    break;
                }

#if false       // move this care to runtime
                if (attrDesc.Attr == SsKeyAttr.Hide &&
                    frame < curKey.Time)
                {
                    // "hide" needs special care, it will be true before first key.
                    boolValue.Value = true;
                }
                else
#endif
                if (attrDesc.NeedsInterpolatable && nextKey != null && frame >= curKey.Time)
                {
                    bool doInterpolate = true;

                    if (attrDesc.Attr == SsKeyAttr.PartsCol)
                    {
                        var curCbk  = (SsColorBlendKeyValue)curKey.ObjectValue;
                        var nextCbk = (SsColorBlendKeyValue)nextKey.ObjectValue;
                        // if current and next key has no target, new value simply refers current key.
                        if (curCbk.Target == SsColorBlendTarget.None &&
                            nextCbk.Target == SsColorBlendTarget.None)
                        {
                            v.RefKeyIndex = curKeyIndex;
                            doInterpolate = false;
                        }
                    }

                    if (doInterpolate)
                    {
                        // needs interpolation
                        object res;
                        if (frame == curKey.Time)
                        {
                            // use start key value as is.
                            res = curKey.ObjectValue;
                        }
                        else
                        {
                            // interpolate curKey~nextKey
                            res = SsInterpolation.InterpolateKeyValue(curKey, nextKey, frame);
                        }
                        try{
                            // can't restore primitive type from the boxed through casting.
                            if (boolValue)
                            {
                                boolValue.Value = System.Convert.ToBoolean(res);
                            }
                            else if (intValue)
                            {
                                intValue.Value = System.Convert.ToInt32(res);
                            }
                            else if (floatValue)
                            {
                                floatValue.Value = System.Convert.ToSingle(res);
                            }
                            else
                            {
                                v.SetValue(res);
                            }
                        }catch {
                            Debug.LogError("[INTERNAL] failed to unbox: " + res);
                        }

                        if (attrDesc.Attr == SsKeyAttr.PartsCol)
                        {
                            var curCbk  = (SsColorBlendKeyValue)curKey.ObjectValue;
                            var nextCbk = (SsColorBlendKeyValue)nextKey.ObjectValue;
                            // if current or next key has vertex colors, key between them should have vertex colors.
                            if (curCbk.Target == SsColorBlendTarget.Vertex ||
                                nextCbk.Target == SsColorBlendTarget.Vertex)
                            {
                                var newCbk = colorBlendValue.Value;
                                newCbk.Target = SsColorBlendTarget.Vertex;
                                // use next key operation.
                                newCbk.Operation = nextCbk.Operation;
                            }
                        }
                    }
                }
                else
                {
                    // just use the value at last referred key frame.
                    v.RefKeyIndex = curKeyIndex;
                }
#if _DEBUG
                if (v.Value != null)
                {
                    SsDebugLog.Print(string.Format("\t\tframe[{0}]: {1}\n", frame, v.Value));
                }
#endif
                // add value to the relative array
                switch (attr)
                {
                case SsKeyAttr.PosX:                    PosXValues[frame] = intValue;           break;

                case SsKeyAttr.PosY:                    PosYValues[frame] = intValue;           break;

                case SsKeyAttr.Angle:                   AngleValues[frame] = floatValue;        break;

                case SsKeyAttr.ScaleX:                  ScaleXValues[frame] = floatValue;       break;

                case SsKeyAttr.ScaleY:                  ScaleYValues[frame] = floatValue;       break;

                case SsKeyAttr.Trans:                   TransValues[frame] = floatValue;        break;

                case SsKeyAttr.Prio:                    PrioValues[frame] = intValue;           break;

                case SsKeyAttr.FlipH:                   FlipHValues[frame] = boolValue;         break;

                case SsKeyAttr.FlipV:                   FlipVValues[frame] = boolValue;         break;

                case SsKeyAttr.Hide:                    HideValues[frame] = boolValue;          break;

                case SsKeyAttr.PartsCol:                PartsColValues[frame] = colorBlendValue; break;

                case SsKeyAttr.PartsPal:                PartsPalValues[frame] = paletteValue;   break;

                case SsKeyAttr.Vertex:                  VertexValues[frame] = vertexValue;      break;

                case SsKeyAttr.User:                    UserValues[frame] = userValue;          break;

                case SsKeyAttr.Sound:                   SoundValues[frame] = soundValue;        break;

                case SsKeyAttr.ImageOffsetX:    ImageOffsetXValues[frame] = intValue;   break;

                case SsKeyAttr.ImageOffsetY:    ImageOffsetYValues[frame] = intValue;   break;

                case SsKeyAttr.ImageOffsetW:    ImageOffsetWValues[frame] = intValue;   break;

                case SsKeyAttr.ImageOffsetH:    ImageOffsetHValues[frame] = intValue;   break;

                case SsKeyAttr.OriginOffsetX:   OriginOffsetXValues[frame] = intValue;  break;

                case SsKeyAttr.OriginOffsetY:   OriginOffsetYValues[frame] = intValue;  break;
                }
            }
        }

        // set having transparency flag
        HasTrancparency = false;
        if (HasAttrFlags(SsKeyAttrFlags.Trans))
        {
            // if opacity value under 1 exists in some keys, we recognize this will be transparent at some frames
            foreach (SsFloatKeyFrame e in TransKeys)
            {
                if (e.Value < 1f)
                {
                    HasTrancparency = true;
                    break;
                }
            }
        }
    }
Example #14
0
 public bool                                    Inherits(SsKeyAttr attr)
 {
     return(InheritParam(attr).Use);
 }
Example #15
0
 public SsInheritanceParam              InheritParam(SsKeyAttr attr)
 {
     return(InheritState.Values[(int)attr]);
 }