// ================================================================= // // 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); } }
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++; } } } }