示例#1
0
        // ================================================================= //
        // Public Methods
        // ================================================================= //

        public void HandleAsset(string xmlPath)
        {
            // load atlas
            MeshAnimationAtlas atlas = this.FindAtlas(Path.GetDirectoryName(xmlPath), Path.GetFileNameWithoutExtension(xmlPath));

            if (atlas == null)
            {
                // throw new System.Exception(string.Format("Could not load atlas: {0}", Path.GetFileNameWithoutExtension(xmlPath)));
                return;
            }

            // load text
            TextAsset text = AssetDatabase.LoadAssetAtPath(xmlPath, typeof(TextAsset)) as TextAsset;

            if (text == null)
            {
                // throw new System.Exception(string.Format("Could not load xml: {0}", Path.GetFileNameWithoutExtension(xmlPath)));
                return;
            }

            // load xml
            XmlDocument xml = new XmlDocument();

            try {
                xml.LoadXml(text.text);
            } catch {
                // } catch (System.Exception e) {
                // throw new System.Exception(string.Format("Could not parse xml: {0}", Path.GetFileNameWithoutExtension(xmlPath)), e);
                return;
            }

            // validate xml
            if (xml.SelectSingleNode("/timeline") == null)
            {
                return;
            }

            // read anchor point
            Vector2 anchorPoint;

            anchorPoint = xml.SelectSingleNode("timeline").Attributes["anchorPoint"].Value.ToVector2();

            // read content size
            Vector2 contentSize;

            contentSize  = xml.SelectSingleNode("timeline").Attributes["contentSize"].Value.ToVector2();
            contentSize *= EditorSettings.Instance.MetersPerPixel;

            // read frames per second
            int framesPerSecond;

            framesPerSecond = System.Convert.ToInt32(xml.SelectSingleNode("timeline").Attributes["framesPerSecond"].Value);

            // read markers
            foreach (XmlNode markerIdentifierNode in xml.SelectNodes("/timeline/marker"))
            {
                string id;
                id = markerIdentifierNode.Attributes["id"].Value;

                foreach (XmlNode labelNode in xml.SelectNodes("/timeline/label"))
                {
                    // create frames
                    List <MarkerAnimationFrame> frames = new List <MarkerAnimationFrame>();
                    foreach (XmlNode markerDataNode in labelNode.SelectNodes(string.Format("frame/marker[@id='{0}']", id)))
                    {
                        MarkerAnimationFrame frame = new MarkerAnimationFrame();
                        frame.Active   = System.Convert.ToBoolean(markerDataNode.Attributes["active"].Value);
                        frame.Position = markerDataNode.Attributes["position"].Value.ToVector2() * EditorSettings.Instance.MetersPerPixel;
                        frame.Rotation = System.Convert.ToSingle(markerDataNode.Attributes["rotation"].Value);
                        frame.Scale    = markerDataNode.Attributes["scale"].Value.ToVector2();
                        frame.Skew     = (
                            markerDataNode.Attributes.GetNamedItem("skew") != null ?
                            markerDataNode.Attributes["skew"].Value.ToVector2() :
                            Vector2.zero
                            );
                        frames.Add(frame);
                    }

                    // set path
                    string directoryPath = Path.GetDirectoryName(xmlPath);
                    string animationId   = xml.SelectSingleNode("timeline").Attributes["id"].Value;
                    string labelId       = Regex.Replace(labelNode.Attributes["id"].Value, string.Format("^{0}_", animationId), "");
                    string markerId      = markerIdentifierNode.Attributes["name"].Value;

                    string path;
                    path = MarkerAnimationAssetPathUtil.GetMarkerAnimationAssetPath(directoryPath, animationId, labelId, markerId);

                    // find or create marker
                    MarkerAnimation marker;
                    marker = AssetDatabase.LoadAssetAtPath(path, typeof(MarkerAnimation)) as MarkerAnimation;

                    if (marker == null)
                    {
                        marker = ScriptableObject.CreateInstance <MarkerAnimation>();
                        AssetDatabase.CreateAsset(marker, path);
                    }

                    // update marker
                    marker.hideFlags       = HideFlags.None;
                    marker.Frames          = frames.ToArray();
                    marker.FramesPerSecond = framesPerSecond;
                    marker.PixelsPerMeter  = EditorSettings.Instance.PixelsPerMeter;
                    marker.ResetVersion();

                    // mark marker dirty to make sure it gets saved
                    EditorUtility.SetDirty(marker);
                }
            }

            //
            Dictionary <string, Mesh> atlasDictionary = new Dictionary <string, Mesh>();

            foreach (Object atlasAsset in AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(atlas)))
            {
                if (atlasAsset is Mesh)
                {
                    atlasDictionary.Add(atlasAsset.name, atlasAsset as Mesh);
                }
            }

            // read labels
            foreach (XmlNode labelNode in xml.SelectNodes("/timeline/label"))
            {
                // read frames
                List <MeshAnimationFrame> frames = new List <MeshAnimationFrame>();
                foreach (XmlNode frameNode in labelNode.SelectNodes("frame"))
                {
                    // read audio clips
                    List <AudioClip> audioClips = new List <AudioClip>();
                    foreach (XmlNode audioClipNode in frameNode.SelectNodes("sound"))
                    {
                        string name;
                        name = audioClipNode.Attributes["id"].Value;

                        string directory;
                        directory = Path.GetDirectoryName(xmlPath);

                        AudioClip audioClip;
                        audioClip = this.FindAudioClip(directory, name);

                        if (audioClip)
                        {
                            audioClips.Add(audioClip);
                        }
                        else
                        {
                            throw new System.Exception(string.Format("Could not find audio clip: {0}", name));
                        }
                    }

                    // read meshes
                    List <Mesh> meshes = new List <Mesh>();
                    foreach (XmlNode meshNode in frameNode.SelectNodes("mesh"))
                    {
                        string name;
                        name = meshNode.Attributes["id"].Value;

                        Mesh mesh;
                        mesh = atlasDictionary.ContainsKey(name) ? atlasDictionary[name] : null;

                        if (mesh)
                        {
                            meshes.Add(mesh);
                        }
                        else
                        {
                            throw new System.Exception(string.Format("Could not find mesh: {0}", name));
                        }
                    }

                    // create frame
                    MeshAnimationFrame frame;
                    frame            = new MeshAnimationFrame();
                    frame.AudioClips = audioClips.ToArray();
                    frame.Meshes     = meshes.ToArray();
                    frames.Add(frame);
                }

                // read layers
                List <MeshAnimationLayer> layers = new List <MeshAnimationLayer>();
                for (int layerIndex = 0; frames.Count != 0 && layerIndex < frames[0].Meshes.Length; layerIndex++)
                {
                    List <Mesh> meshes = new List <Mesh>();
                    for (int frameIndex = 0; frameIndex < frames.Count; frameIndex++)
                    {
                        meshes.Add(frames[frameIndex].Meshes[layerIndex]);
                    }

                    MeshAnimationLayer layer;
                    layer        = new MeshAnimationLayer();
                    layer.Meshes = meshes.ToArray();
                    layers.Add(layer);
                }

                // create animation path
                string animationPath;
                animationPath = string.Format("{0}/{1}.asset", Path.GetDirectoryName(xmlPath), labelNode.Attributes["id"].Value);

                // find or create animation
                MeshAnimation animation;
                animation = AssetDatabase.LoadAssetAtPath(animationPath, typeof(MeshAnimation)) as MeshAnimation;

                if (animation == null)
                {
                    animation = ScriptableObject.CreateInstance <MeshAnimation>();
                    AssetDatabase.CreateAsset(animation, animationPath);
                }

                // update animation
                animation.AnchorPoint     = anchorPoint;
                animation.ContentSize     = contentSize;
                animation.Frames          = frames.ToArray();
                animation.FramesPerSecond = framesPerSecond;
                animation.Layers          = layers.ToArray();
                animation.PixelsPerMeter  = EditorSettings.Instance.PixelsPerMeter;
                animation.ResetVersion();

                // mark animation dirty to make sure it gets saved
                EditorUtility.SetDirty(animation);
            }

            // delete xml
            if (EditorSettings.Instance.DeleteIntermediateFiles)
            {
                AssetDatabase.DeleteAsset(xmlPath);
            }
        }
示例#2
0
        public ActResource(string name, System.IO.Stream stream)
            : base(name, true)
        {
            int currentStreamPosition = (int)stream.Position;

            System.IO.BinaryReader reader = new System.IO.BinaryReader(stream, Encoding.ASCII);

            ActHeader header;

            header.Magic = reader.ReadUInt32();

            if (header.Magic != 0x41435448)
            {
                throw new Resource.InvalidResourceFileFormat("Invalid ACT file header");
            }

            header.Version1  = reader.ReadUInt16();
            header.Version2  = reader.ReadUInt16();
            header.NumFrames = reader.ReadUInt32();
            header.NumMeshes = reader.ReadUInt32();
            header.DataSize  = reader.ReadUInt32();
            header.ModelName = Gk3Main.Utils.ConvertAsciiToString(reader.ReadBytes(32));

            _modelName = header.ModelName;
            _numMeshes = header.NumMeshes;
            _numFrames = header.NumFrames;
            _frames    = new ActFrame[header.NumFrames * _numMeshes];

            // read the offsets
            uint[] offsets = new uint[header.NumFrames];
            for (int i = 0; i < header.NumFrames; i++)
            {
                offsets[i] = reader.ReadUInt32();
            }

            for (uint i = 0; i < header.NumFrames; i++)
            {
                stream.Seek(currentStreamPosition + offsets[i], System.IO.SeekOrigin.Begin);
                uint frameSize;
                if (i == header.NumFrames - 1)
                {
                    frameSize = header.DataSize - offsets[i];
                }
                else
                {
                    frameSize = offsets[i + 1] - offsets[i];
                }

                readFrame(reader, i, frameSize);
            }

            // now we have all the frames loaded from the ACT file,
            // so now it's time to convert the frame data into a more
            // usable layout
            _animationFrames = new MeshAnimationFrame[_numMeshes][];
            for (uint i = 0; i < _numMeshes; i++)
            {
                // count the active frames
                uint numActiveFramesThisMesh = 0;
                for (uint j = 0; j < _numFrames; j++)
                {
                    if (_frames[j * _numMeshes + i].Active)
                    {
                        numActiveFramesThisMesh++;
                    }
                }

                // create the frames
                _animationFrames[i] = new MeshAnimationFrame[numActiveFramesThisMesh];
                uint currentFrame = 0;
                for (uint j = 0; j < _numFrames; j++)
                {
                    if (_frames[j * _numMeshes + i].Active)
                    {
                        _animationFrames[i][currentFrame].Time      = _millisecondsPerFrame * j;
                        _animationFrames[i][currentFrame].Transform = _frames[j * _numMeshes + i].Transform;
                        if (_frames[j * _numMeshes + i].Vertices != null)
                        {
                            _animationFrames[i][currentFrame].Vertices = _frames[j * _numMeshes + i].Vertices.ToArray();
                        }
                        if (_frames[j * _numMeshes + i].BoundingBox != null)
                        {
                            _animationFrames[i][currentFrame].BoundingBox = _frames[j * _numMeshes + i].BoundingBox;
                        }
                        currentFrame++;
                    }
                }
            }
        }