Example #1
0
 static SsImageFile()
 {
     invalidInstance        = new SsImageFile();
     invalidInstance.path   = "INVALID";
     invalidInstance.width  = 8;
     invalidInstance.height = 8;
     invalidInstance.bpp    = 8;
 }
Example #2
0
    AddMaterials(SsPartRes part, SsColorBlendOperation colorBlendType)
    {
        SsImageFile  img        = part.imageFile;
        SsShaderType shaderType = SsShaderManager.EnumToType(colorBlendType, part.AlphaBlendType, SsMaterialColorBlendOperation.Non);
        Material     material   = img.GetMaterial(shaderType);

        if (material)
        {
            return;             // already added
        }
        // create material
#if _BUILD_UNIFIED_SHADERS
        img.useUnifiedShader = _anmRes.UseCgProgram;
        Shader shader = SsShaderManager.Get(shaderType, _anmRes.UseCgProgram);
#else
        Shader shader = SsShaderManager.Get(shaderType, false);
#endif
        // get material asset path
        string assetPath  = Path.GetDirectoryName(AssetDatabase.GetAssetPath(img.texture)) + "/assets/";
        string shaderName = shader.name;
        shaderName = shaderName.Replace("Ss/", "");
        string assetName = assetPath + img.texture.name + "_Mat_" + shaderName + ".asset";

        // try to load the exiting
        Material existedMat = (Material)AssetDatabase.LoadAssetAtPath(assetName, typeof(Material));
        Material mat        = (existedMat ?? new Material(shader));

        mat.SetTexture("_MainTex", img.texture);

        if (existedMat == null)
        {
            // if none, create material as asset file newly
//			Debug.Log("create material: " + img.path + " shader: " + shaderType);
            if (!Directory.Exists(assetPath))
            {
                string parentFolder = Path.GetDirectoryName(assetPath.TrimEnd('\\', '/'));
                AssetDatabase.CreateFolder(parentFolder, "assets");
            }
            AssetDatabase.CreateAsset(mat, assetName);
        }
        else
        {
            // update the existing content
            mat.shader = shader;
            EditorUtility.SetDirty(mat);
            AssetDatabase.SaveAssets();                 //same as EditorApplication.SaveAssets();
        }

        // add to material list
        img.materials[SsShaderManager.ToSerial(shaderType)] = mat;
    }
Example #3
0
    GetImage(string path)
    {
        //Debug.Log("Textures " + Resources.FindObjectsOfTypeAll(typeof(Texture)).Length);
        SsImageFile img;

        try
        {
            // try get the existing
            img = _imageFileList[path];
        }
        catch (KeyNotFoundException)
        {
            // not found, so create
            img           = new SsImageFile();
            img.path      = path;
            img.materials = new Material[(int)SsShaderType.Num];

#if false
            // reimport texture with settings for SpriteStudio
            SsAssetPostProcessor.HookTextureImport = true;
            AssetDatabase.ImportAsset(path, ImportAssetOptions.Default);
#endif

#if false
            // omit extension to load Texture Asset successfully
            //string pathExtOmitted = Path.ChangeExtension(path, null);

            // load image newly
            //Object obj = Resources.Load(pathExtOmitted, typeof(Texture2D));
#else
            Object obj = AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
#endif

            img.texture = obj as Texture2D;
            //Debug.Log(img.texture);
            if (img.texture == null)
            {
                Debug.LogError("can't load image: " + path);
                return(null);
            }

            // change default texture wrap and filtering medthod to avoid unexpected edge colors
            img.texture.wrapMode = TextureWrapMode.Clamp;
//			img.texture.filterMode = FilterMode.Point;	// unwanted... 2012.04.04

            // add to list
            _imageFileList[path] = img;
        }

        return(img);
    }
Example #4
0
	static SsImageFile()
	{
		invalidInstance = new SsImageFile();
		invalidInstance.path = "INVALID";
		invalidInstance.width = 8;
		invalidInstance.height = 8;
		invalidInstance.bpp = 8;
	}
Example #5
0
    Init()
    {
        // if don't do this, Transforms(GameObjects) are created every time as come into ExecuteInEditMode.
        DeleteTransformChildren();

        //Debug.Log("Init() " + gameObject.name);
        if (!_animation)
        {
            // clear variables
            //Debug.LogWarning("No anime resource attached-> " + gameObject.name);

            // works
            _partResList     = null;
            _imageList       = null;
            _partsNum        = 0;
            _parts           = null;
            _boundPartList   = null;
            _materials       = null;
            _vertices        = null;
            _uvs             = null;
            _colors          = null;
            _extras          = null;
            _mesh            = null;
            _meshFilter.mesh = null;
#if _USE_SHARED_MATERIAL
            _meshRenderer.sharedMaterials = new Material[1];
#else
            _meshRenderer.materials = new Material[1];
#endif

            // statuses
            _isPlaying         = _isFinished = false;
            PlayCount          = 0;
            Speed              = 1f;
            _prevPlayDirection = _playDirection = SsAnimePlayDirection.Forward;
            ResetAnimationStatus();
            _startAnimeFrame = _endAnimeFrame = _playFrameLength = 0;
            return;
        }

        EnsureMeshComponent();

        // initialize values
        ResetAnimationStatus();
        Pause();
        _isFinished = false;

        // get parts and images.
        _partResList = _animation.PartList;
        _imageList   = _animation.ImageList;
        _partsNum    = _partResList.Length;

        // create material array. actually root doesn't need material so can cut down.
        _materials = new Material[_partsNum - 1];

        // create vertices...
        int vertNum = (_partsNum - 1) * 4;
        _vertices = new Vector3[vertNum];
        _uvs      = new Vector2[vertNum];
        _colors   = new Color[vertNum];
        _extras   = new Vector2[vertNum];

        // now create mesh
        _mesh              = new Mesh();
        _mesh.vertices     = _vertices;         // to avoid "out of bounds" error when we set triangle indices.
        _mesh.subMeshCount = _partsNum - 1;
        _mesh.uv2          = _extras;

        // attach to MeshFilter
        _meshFilter.mesh = _mesh;
        // create sprite parts and pass to resource used
        _parts = new SsPart[_partsNum];
        for (int i = 0; i < _parts.Length; ++i)
        {
            SsPartRes   partRes = _partResList[i];
            SsImageFile image   = partRes.IsRoot ? null : _imageList[partRes.SrcObjId];
            _parts[i] = new SsPart(this, i, partRes, image);
            // set root sprite
            if (i == 0)
            {
                _rootPart = _parts[i];
            }
            else
            {
                // set individual material to buffer
                _materials[i - 1] = _parts[i]._material;
            }
            // register bound parts separately for fast access
            if (partRes.Type == SsPartType.Bound)
            {
                if (_boundPartList == null)
                {
                    _boundPartList = new List <SsPart>();
                }
                _boundPartList.Add(_parts[i]);
            }
        }

        // set materials to affect
#if _USE_SHARED_MATERIAL
        _meshRenderer.sharedMaterials = _materials;
#else
        _meshRenderer.materials = _materials;
#endif
        // attach values to the Mesh
        _mesh.vertices = _vertices;
        _mesh.uv       = _uvs;

        // at first time must invoke vertex update to display initial posed animation.
        _vertChanged = true;

        // reflect blend settings to shader
        _extraChanged = true;

#if false
        // use user data numeric value as PlayCount
        if (PartResList[0].UserKeys.Count > 0)
        {
            SsUserDataKeyFrame userKey = (SsUserDataKeyFrame)PartResList[0].GetKey(SsKeyAttr.User, 0);
            PlayCount = userKey.Value.Num;
        }
#endif
        // to fix the problem that h/vFlipped animation from initial time doesn't affects mesh
        UpdateAlways();
    }
Example #6
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 #7
0
    SsPart(
        SsSprite manager,
        int index,                              ///< index of parts
        SsPartRes partRes,                      ///< part resource
        SsImageFile imageFile)                  ///< source image path, texture and material.
    {
        _mgr          = manager;
        _index        = index;
        _vIndex       = (index - 1) * 4;
        _subMeshIndex = index - 1;
        _res          = partRes;
        _mesh         = _mgr._mesh;

        if (_res.HasParent)
        {
            _parent = _mgr.Sprite(_res.ParentId);
            if (_parent == null)
            {
                Debug.LogError("##### parent sprite must be created already!!");
                //throw ArgumentNullException;
                Debug.Break();
                return;
            }
        }

        // attach parent's transform to inherit its SRT.
        _pivotMatrix = Matrix4x4.identity;
        switch (_res.Type)
        {
        case SsPartType.Root:
            // root has only position, no vertices
#if _APPLY_ROOT_POS_AS_PIVOT
            _rootPivot = new Vector3(-_res.PosX(0), +_res.PosY(0), 0f);
#endif
            break;

        case SsPartType.Normal:
        case SsPartType.Bound:
            // each vertices are attached to pivot
            _vertPositions = new Vector3[4];
            _orgVertices   = new Vector3[4];
            for (int i = 0; i < _vertPositions.Length; ++i)
            {
                _orgVertices[i] = _vertPositions[i] = _res.OrgVertices[i];
#if _MOVE_BOUND_PART_TO_THE_FRONT
                if (_res.Type == SsPartType.Bound)
                {
                    _vertPositions[i].z = -0.1f;
                    _orgVertices[i].z   = -0.1f;
                }
#endif
            }
            break;

        default:
            // other types don't require vertices.
            break;
        }

        // set startup value
        _visible    = !_res.Hide(0);
        _flipH      = false;
        _flipV      = false;
        _pos        = Vector3.zero;
        _quaternion = Quaternion.identity;
        _scale      = Vector3.one;
#if _MAKE_ROOT_TO_LOCAL_TRANSFORM
        _rotChanged = false;
#endif
        // not any normal types don't require a material, colors, and vertices.
        if (_res.Type != SsPartType.Normal &&
            _res.Type != SsPartType.Bound)
        {
            return;
        }

        // shortcut
#if _USE_UNIFIED_SHADER
        _useUnifiedShader = _res.imageFile.useUnifiedShader;
#endif
        _useCgShader = (SystemInfo.graphicsShaderLevel >= 20);

        if (_res.Type == SsPartType.Bound)
        {
#if !_BOUND_PART_DRAW_AS_INVALID
            // set vertex color to transparent red.
            // this alpha value will be overwritten in AlphaValue property later.
            _vertexColor = new Color(1, 0, 0, 1);
            for (int i = 0; i < 4; ++i)
            {
                // set UVs to a point at left-top.
                _mgr._uvs[_vIndex + i] = Vector2.zero;

                // set vertex colors
                _mgr._colors[_vIndex + i] = _vertexColor;
            }
            // invisible is default.
            _visible = false;
#else
            _visible = _mgr.DrawBoundingParts;
#endif
        }
        else
        {
            // default vertex color
            _vertexColor = new Color(1, 1, 1, 1);
            for (int i = 0; i < 4; ++i)
            {
                // set UVs. use precalculated UVs, it is stored clockwise
                _mgr._uvs[_vIndex + i] = _res.UVs[i];

                // set vertex colors
                _mgr._colors[_vIndex + i] = _vertexColor;
            }
            // set blend type and _shaderType
            ColorBlendType = SsColorBlendOperation.Non;
        }

        // set boolean about having transparency
        if (_res.Type == SsPartType.Bound)
        {
#if _BOUND_PART_DRAW_AS_INVALID
            // become purple that mean invalid.
            _material = null;
#else
            // needs any appropriate material
            _hasTransparency = true;
            AlphaValue       = 0.5f;
#endif
        }
        else
        {
            _hasTransparency = _res.HasTrancparency ||
                               (_parent != null && _res.Inherits(SsKeyAttr.Trans));    // always inherits parent's alpha whether the immediate parent has transparency or not. 2012.12.19 bug fixed
            // set alpha value
            AlphaValue = _res.Trans(0);

            // set appropriate material. _shaderType was set inside ColorBlendType property.
            _material = imageFile.GetMaterial(_shaderType);
        }

        //--------- calculates various info...
        Update(true);

        // set triangle indices. never changed so far.
#if _USE_TRIANGLE_STRIP
        _triIndices = new int[] { _vIndex + 0, _vIndex + 1, _vIndex + 3, _vIndex + 2 };                           // order is LT->RT->LB->RB.
#else
        _triIndices = new int[] { _vIndex + 0, _vIndex + 1, _vIndex + 2, _vIndex + 2, _vIndex + 3, _vIndex + 0 }; // order is LT->RT->RB->RB->LB->LT
#endif

        SetToSubmeshArray(_index - 1);
    }