// Get the animation matrix for each bone
        public Matrix4[] GetAnimationMatrices(float time, Skeleton skeleton)
        {
            // Create output array
            var matrices = new Matrix4[skeleton.Bones.Length];

            // Get bone transformations
            var transforms = GetTransformsAtTime(time);

            foreach (var root in skeleton.Roots)
            {
                GetAnimationMatrixRecursive(root, Matrix4.Identity, Matrix4.Identity, transforms, ref matrices);
            }

            return matrices;
        }
        public Renderer(TabControl mainTabs, string fileName, Package currentPackage)
        {
            MeshesToRender = new List<MeshObject>();
            Animations = new List<Animation.Animation>();
            cameras = new List<Tuple<string, Matrix4>>();

            CurrentPackage = currentPackage;
            CurrentFileName = fileName;
            tabs = mainTabs;

            Debug = new DebugUtil();

            Skeleton = new Skeleton(); // Default empty skeleton

            MaterialLoader = new MaterialLoader(CurrentFileName, CurrentPackage);
        }
        private void LoadAnimationGroup(string path, Skeleton skeleton)
        {
            // Get the list of animation files
            var animArray = (NTROArray)data.Output["m_localHAnimArray"];
            // Get the key to decode the animations
            var decodeKey = ((NTROValue<NTROStruct>)data.Output["m_decodeKey"]).Value;

            AnimationList = new List<Animation>();
            for (var i = 0; i < animArray.Count; i++)
            {
                // Load animation files
                var refAnim = ((NTROValue<ResourceExtRefList.ResourceReferenceInfo>)animArray[i]).Value;
                var animResource = FileExtensions.LoadFileByAnyMeansNecessary(refAnim.Name + "_c", path, null);
            #if DEBUG
                Console.WriteLine("Animation found: " + refAnim.Name);
            #endif

                // Build animation classes
                AnimationList.Add(new Animation(animResource, decodeKey, skeleton));
            }
        }
        // Build animation from resource
        public Animation(Resource resource, NTROStruct decodeKey, Skeleton skeleton)
        {
            Name = string.Empty;
            Fps = 0;
            Frames = new Frame[0];

            Skeleton = skeleton;

            var animationData = (NTRO)resource.Blocks[BlockType.DATA];
            var animArray = (NTROArray)animationData.Output["m_animArray"];

            if (animArray.Count == 0)
            {
                Console.WriteLine("Empty animation file found.");
                return;
            }

            var decoderArray = MakeDecoderArray((NTROArray)animationData.Output["m_decoderArray"]);
            var segmentArray = (NTROArray)animationData.Output["m_segmentArray"];

            // Get the first animation description
            ConstructFromDesc(animArray.Get<NTROStruct>(0), decodeKey, decoderArray, segmentArray);
        }
 public AnimationGroupLoader(Resource resource, string filename, Skeleton skeleton)
 {
     data = (NTRO)resource.Blocks[BlockType.DATA];
     LoadAnimationGroup(filename, skeleton);
 }
 public float[] GetAnimationMatricesAsArray(float time, Skeleton skeleton)
 {
     var matrices = GetAnimationMatrices(time, skeleton);
     return Flatten(matrices);
 }
 public void SetSkeleton(Skeleton skeleton)
 {
     Skeleton = skeleton;
 }