Event() public method

Logs an event
public Event ( String message ) : void
message String The message to explain the event
return void
        public static bool Read(int skin, IFileEntry file,
            ref Dictionary<String, String> animations, Logger logger)
        {
            bool result = true;

            logger.Event("Parsing animation list: " + file.FileName );

            try
            {
                // Get the data from the archive
                MemoryStream myInput = new MemoryStream( file.GetContent() );
                StreamReader reader = new StreamReader(myInput);

                ParseAnimations(skin, reader, ref animations);

                reader.Close();
                myInput.Close();
            }
            catch
            {
                logger.Error("Failed to parse animation list: " + file.FileName);

                result = false;
                animations.Clear();
            }

            return result;
        }
        public static bool Read(RAFFileListEntry file, ref InibinFile data, Logger logger)
        {
            bool result = true;

            logger.Event("Reading inibin: " + file.FileName);

            try
            {
                // Get the data from the archive
                MemoryStream myInput = new MemoryStream( file.GetContent() );
                result = ReadCharacterInibin(myInput, ref data, logger);

                int end = file.FileName.LastIndexOf("/");
                String directory = file.FileName.Substring(0, end);
                String archive = file.RAFArchive.RAFFilePath;
                archive = archive.Replace("\\", "/");
                end = archive.LastIndexOf("/");
                archive = archive.Substring(0, end);

                data.directory = new DirectoryInfo(archive + "/" + directory);
                myInput.Close();
            }
            catch(Exception e)
            {
                logger.Error("Unable to open memory stream: " + file.FileName);
                logger.Error(e.Message);
                result = false;
            }

            return result;
        }
Beispiel #3
0
        /// <summary>
        /// Read in binary .dds file from RAF.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="data">The contents of the file are stored in here.</param>
        /// <returns></returns>
        public static bool Read(RAFFileListEntry file, ref Bitmap bitmap, Logger logger)
        {
            bool result = true;

            logger.Event("Reading dds: " + file.FileName);

            try
            {
                // Create image.
                int[] images = new int[1];
                Il.ilGenImages(1, images);

                // Bind image.
                Il.ilBindImage(images[0]);

                // Load the image data into DevIL.
                byte[] data = file.GetContent();
                result = Il.ilLoadL(Il.IL_DDS, data, data.Length);
                if (result == true)
                {
                    int width = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
                    int height = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT); ;

                    // Create the bitmap.
                    bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    Rectangle rect = new Rectangle(0, 0, width, height);

                    // Store the DevIL image data into the bitmap.
                    BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

                    Il.ilConvertImage(Il.IL_BGRA, Il.IL_UNSIGNED_BYTE);
                    Il.ilCopyPixels(0, 0, 0, width, height, 1, Il.IL_BGRA, Il.IL_UNSIGNED_BYTE, bitmapData.Scan0);

                    bitmap.UnlockBits(bitmapData);
                }

                // Free image.
                Il.ilDeleteImages(1, images);

                if (result == false)
                {
                    throw new System.Exception("Unable to load image data.");
                }
            }
            catch(Exception e)
            {
                logger.Error("Unable to open dds file: " + file.FileName);
                logger.Error(e.Message);
                result = false;
            }

            return result;
        }
Beispiel #4
0
        /// <summary>
        /// Read in binary .anm file from RAF.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="data">The contents of the file are stored in here.</param>
        /// <returns></returns>
        public static bool Read(RAFFileListEntry file, ref ANMFile data, Logger logger)
        {
            bool result = true;

            logger.Event("Reading anm: " + file.FileName);

            try
            {
                // Get the data from the archive
                MemoryStream myInput = new MemoryStream( file.GetContent() );
                result = ReadBinary(myInput, ref data, logger);
                myInput.Close();
            }
            catch(Exception e)
            {
                logger.Error("Unable to open memory stream: " + file.FileName);
                logger.Error(e.Message);
                result = false;
            }

            return result;
        }
        //
        // Helper creation function.
        //
        private bool Create(List<float> vertexPositions, List<float> vertexNormals,
            List<float> vertexTextureCoordinates, List<uint> indices, Logger logger)
        {
            bool result = true;

            logger.Event("Creating OpenGL static model.");

            numIndices = indices.Count;

            // Create Vertex Array Object
            if (result == true)
            {
                GL.GenVertexArrays(1, out vao);
            }

            ErrorCode error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Bind VAO
            if (result == true)
            {
                GL.BindVertexArray(vao);
            }

            // Create the VBOs
            int[] buffers = new int[4];
            if (result == true)
            {
                GL.GenBuffers(4, buffers);
            }

            // Check for errors
            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Store data and bind vertex buffer.
            if (result == true)
            {
                vertexPositionBuffer = buffers[0];
                vertexNormalBuffer = buffers[1];
                vertexTextureCoordinateBuffer = buffers[2];
                indexBuffer = buffers[3];

                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexPositionBuffer);
            }

            //
            //
            // Set vertex data.
            //
            //
            if (result == true)
            {
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexPositions.Count * sizeof(float)),
                    vertexPositions.ToArray(), BufferUsageHint.StaticDraw);
            }

            // Check for errors.
            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Put vertices into attribute slot 0.
            if (result == true)
            {
                GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float,
                    false, 0, 0);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Enable the attribute index.
            if (result == true)
            {
                GL.EnableVertexAttribArray(0);
            }

            //
            //
            // Bind normal buffer.
            //
            //
            if (result == true)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexNormalBuffer);
            }

            // Set normal data.
            if (result == true)
            {
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexNormals.Count * sizeof(float)),
                    vertexNormals.ToArray(), BufferUsageHint.StaticDraw);
            }

            // Check for errors.
            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Put normals into attribute slot 1.
            if (result == true)
            {
                GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float,
                    false, 0, 0);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Enable the attribute index.
            if (result == true)
            {
                GL.EnableVertexAttribArray(1);
            }

            //
            //
            // Bind texture cordinates buffer.
            //
            //
            if (result == true)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexTextureCoordinateBuffer);
            }

            // Set Texture Coordinate Data
            if (result == true)
            {
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexTextureCoordinates.Count * sizeof(float)),
                    vertexTextureCoordinates.ToArray(), BufferUsageHint.StaticDraw);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Put texture coords into attribute slot 2.
            if (result == true)
            {
                GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float,
                    false, 0, 0);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Enable the attribute index.
            if (result == true)
            {
                GL.EnableVertexAttribArray(2);
            }

            // Bind index buffer.
            if (result == true)
            {
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer);
            }

            // Set index data.
            if (result == true)
            {
                GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Count * sizeof(uint)),
                    indices.ToArray(), BufferUsageHint.StaticDraw);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Unbind VAO from pipeline.
            if (result == true)
            {
                GL.BindVertexArray(0);
            }
            else
            {
                logger.Error("Failed to create OpenGL static model.");
            }

            return result;
        }
Beispiel #6
0
        public MainWindow()
        {
            logger = new Logger(DEFAULT_LOG_FILE); // Not checking result.
            logger.Event("Program Start.");

            isGLLoaded = false;
            timer = new Stopwatch();

            camera = new GLCamera();
            camera.SetViewParameters(new Vector3(0.0f, 0.0f, 2.0f), Vector3.Zero);
            renderer = new GLRenderer();

            // Set up the reader and initialize its root to the value in 'lolviewer.dat' if
            // the file exists.
            {
                reader = new LOLDirectoryReader();

                bool isFileOpen = false;
                FileStream file = null;
                try
                {
                    FileInfo fileInfo = new FileInfo(DEFAULT_DATA_FILE);
                    if (fileInfo.Exists == true)
                    {
                        file = new FileStream(fileInfo.FullName, FileMode.Open);
                        isFileOpen = true;
                    }
                    else
                    {
                        logger.Warning("Failed to locate " + DEFAULT_DATA_FILE + ".");
                    }
                }
                catch
                {
                    logger.Warning("Failed to open " + DEFAULT_DATA_FILE + ".");
                }

                if (isFileOpen == true)
                {
                    BinaryReader fileReader = null;
                    if (file != null)
                    {
                        try
                        {
                            logger.Event("Reading " + DEFAULT_DATA_FILE + ".");

                            fileReader = new BinaryReader(file);
                            reader.Root = fileReader.ReadString();
                            fileReader.Close();
                        }
                        catch
                        {
                            logger.Warning("Failed to read " + DEFAULT_DATA_FILE + ".");
                            file.Close();
                        }
                    }
                }
            }

            InitializeComponent();

            mainWindowProgressBar.Style = ProgressBarStyle.Marquee;
            mainWindowProgressBar.Value = 100;

            lastSearch = String.Empty;
            currentSearchSubset = new List<String>();

            // Main window Callbacks
            this.Shown += new EventHandler(OnMainWindowShown);

            // GLControl Callbacks
            glControlMain.Load += new EventHandler(GLControlMainOnLoad);
            glControlMain.Resize += new EventHandler(GLControlMainOnResize);
            glControlMain.Paint += new PaintEventHandler(GLControlMainOnPaint);
            glControlMain.Disposed += new EventHandler(GLControlMainOnDispose);

            // Set mouse events
            glControlMain.MouseDown += new MouseEventHandler(GLControlOnMouseDown);
            glControlMain.MouseUp += new MouseEventHandler(GLControlOnMouseUp);
            glControlMain.MouseWheel += new MouseEventHandler(GLControlOnMouseWheel);
            glControlMain.MouseMove += new MouseEventHandler(GLControlOnMouseMove);

            // Set keyboard events
            glControlMain.KeyDown += new KeyEventHandler(GLControlMainOnKeyDown);
            glControlMain.KeyUp += new KeyEventHandler(GLControlMainOnKeyUp);

            // Menu Callbacks
            exitToolStripMenuItem.Click += new EventHandler(OnExit);
            aboutToolStripMenuItem.Click += new EventHandler(OnAbout);
            readDirectoryMainMenuStripItem.Click += new EventHandler(OnReadModels);
            readMainMenuStripItem.Click += new EventHandler(OnSetDirectory);

            // Model View Callbacks
            modelListBox.DoubleClick += new EventHandler(OnModelListDoubleClick);
            modelListBox.KeyPress += new KeyPressEventHandler(OnModelListKeyPress);

            // Buttons
            resetCameraButton.Click += new EventHandler(OnResetCameraButtonClick);
            backgroundColorButton.Click += new EventHandler(OnBackgroundColorButtonClick);
            fullscreenButton.Click += new EventHandler(OnFullscreenButtonClick);

            //
            // Animation Controller
            //

            // TODO: Pass the references and callbacks into constructor instead of doing them out here.
            // Kind of ugly code. :(
            animationController = new AnimationController();

            // Set references
            animationController.enableAnimationButton = enableAnimationButton;
            animationController.currentAnimationComboBox = currentAnimationComboBox;
            animationController.playAnimationButton = playAnimationButton;
            animationController.glControlMain = glControlMain;
            animationController.timelineTrackBar = timelineTrackBar;
            animationController.mainWindowStatusLabel = mainWindowStatusLabel;

            animationController.renderer = renderer;

            // Set callbacks.
            enableAnimationButton.Click += new EventHandler(animationController.OnEnableAnimationButtonClick);
            playAnimationButton.Click += new EventHandler(animationController.OnPlayAnimationButtonClick);
            currentAnimationComboBox.SelectedIndexChanged += new EventHandler(animationController.OnCurrentAnimationComboBoxSelectedIndexChanged);
            timelineTrackBar.Scroll += new EventHandler(animationController.OnTimelineTrackBar);

            animationController.DisableAnimation();

            //
            // End Animation Controller
            //

            // Search Box
            modelSearchBox.TextChanged += new EventHandler(OnModelSearchBoxTextChanged);
            modelSearchBox.KeyPress += new KeyPressEventHandler(OnModelSearchBoxKeyPress);
            modelSearchBox.KeyDown += new KeyEventHandler(OnModelSearchBoxKeyDown);
        }
Beispiel #7
0
        private static bool ReadData(BinaryReader file, ref ANMFile data, Logger logger)
        {
            bool result = true;

            try
            {
                // File Header Information.
                data.id = new String(file.ReadChars(ANMFile.ID_SIZE));
                data.version = file.ReadUInt32();

                // Version 0, 1, 2, 3 Code
                if (data.version == 0 ||
                    data.version == 1 ||
                    data.version == 2 ||
                    data.version == 3)
                {
                    //
                    // Header information specific to these versions.
                    //

                    data.magic = file.ReadUInt32();
                    data.numberOfBones = file.ReadUInt32();
                    data.numberOfFrames = file.ReadUInt32();
                    data.playbackFPS = file.ReadUInt32();

                    // Read in all the bones
                    for (UInt32 i = 0; i < data.numberOfBones; ++i)
                    {
                        ANMBone bone = new ANMBone();
                        bone.name = new String(file.ReadChars(ANMBone.BONE_NAME_LENGTH));
                        bone.name = RemoveAnimationNamePadding(bone.name);
                        bone.name = bone.name.ToLower();

                        // Unknown
                        file.ReadUInt32();

                        // For each bone, read in its value at each frame in the animation.
                        for (UInt32 j = 0; j < data.numberOfFrames; ++j)
                        {
                            ANMFrame frame = new ANMFrame();

                            // Read in the frame's quaternion.
                            frame.orientation[0] = file.ReadSingle(); // x
                            frame.orientation[1] = file.ReadSingle(); // y
                            frame.orientation[2] = file.ReadSingle(); // z
                            frame.orientation[3] = file.ReadSingle(); // w

                            // Read in the frame's position.
                            frame.position[0] = file.ReadSingle(); // x
                            frame.position[1] = file.ReadSingle(); // y
                            frame.position[2] = file.ReadSingle(); // z

                            bone.frames.Add(frame);
                        }

                        data.bones.Add(bone);
                    }
                }
                // Version 4 Code
                else if (data.version == 4)
                {
                    //
                    // Based on the reverse engineering work of Hossein Ahmadi.
                    //
                    // In this version, position vectors and orientation quaternions are
                    // stored separately in sorted, keyed blocks.  The assumption is Riot
                    // is removing duplicate vectors and quaternions by using an indexing scheme
                    // to look up values.
                    //
                    // So, after the header, there are three data sections: a vector section, a quaternion
                    // section, and a look up section.  The number of vectors and quaternions
                    // may not match the expected value based on the number of frames and bones.  However,
                    // the number of look ups should match this value and can be used to create the animation.

                    //
                    // Header information specific to version 4.
                    //

                    data.magic = file.ReadUInt32();

                    // Not sure what any of these mean.
                    float unknown = file.ReadSingle();
                    unknown = file.ReadSingle();
                    unknown = file.ReadSingle();

                    data.numberOfBones = file.ReadUInt32();
                    data.numberOfFrames = file.ReadUInt32();

                    // Time per frame is stored in this file type.  Need to invert it into FPS.
                    data.playbackFPS = (UInt32) Math.Round(1.0f / file.ReadSingle());

                    // These are offsets to specific data sections in the file.
                    UInt32 unknownOffset = file.ReadUInt32();
                    unknownOffset = file.ReadUInt32();
                    unknownOffset = file.ReadUInt32();

                    UInt32 positionOffset = file.ReadUInt32();
                    UInt32 orientationOffset = file.ReadUInt32();
                    UInt32 indexOffset = file.ReadUInt32();

                    // These last three values are confusing.
                    // They aren't a vector and they throw off the offset values
                    // by 12 bytes. Just ignore them and keep reading.
                    unknownOffset = file.ReadUInt32();
                    unknownOffset = file.ReadUInt32();
                    unknownOffset = file.ReadUInt32();

                    //
                    // Vector section.
                    //

                    List<float> positions = new List<float>();
                    UInt32 numberOfPositions = (orientationOffset - positionOffset) / sizeof(float);
                    for (UInt32 i = 0; i < numberOfPositions; ++i)
                    {
                        positions.Add(file.ReadSingle());
                    }

                    //
                    // Quaternion section.
                    //

                    List<float> orientations = new List<float>();
                    UInt32 numberOfOrientations = (indexOffset - orientationOffset) / sizeof(float);
                    for (UInt32 i = 0; i < numberOfOrientations; ++i)
                    {
                        orientations.Add(file.ReadSingle());
                    }

                    //
                    // Offset section.
                    //
                    // Note: Unlike versions 0-3, data in this version is
                    // Frame 1:
                    //      Bone 1:
                    //      Bone 2:
                    // ...
                    // Frame 2:
                    //      Bone 1:
                    // ...
                    //

                    Dictionary<UInt32, ANMBone> boneMap = new Dictionary<UInt32, ANMBone>();
                    for (Int32 i = 0; i < data.numberOfBones; ++i)
                    {
                        //
                        // The first frame is a special case since we are allocating bones
                        // as we read them in.
                        //

                        // Read in the offset data.
                        UInt32 boneID = file.ReadUInt32();
                        UInt16 positionID = file.ReadUInt16();
                        UInt16 unknownIndex = file.ReadUInt16(); // Unknown.
                        UInt16 orientationID = file.ReadUInt16();
                        unknownIndex = file.ReadUInt16(); // Unknown. Seems to always be zero.

                        // Allocate the bone.
                        ANMBone bone = new ANMBone();
                        bone.id = boneID;

                        // Allocate all the frames for the bone.
                        for (int j = 0; j < data.numberOfFrames; ++j)
                        {
                            bone.frames.Add(new ANMFrame());
                        }

                        // Retrieve the data for the first frame.
                        ANMFrame frame = bone.frames[0];
                        frame.position = LookUpVector(positionID, positions);
                        frame.orientation = LookUpQuaternion(orientationID, orientations);

                        // Store the bone in the dictionary by bone ID.
                        boneMap[boneID] = bone;
                    }

                    Int32 currentFrame = 1;
                    Int32 currentBone = 0;

                    UInt32 numberOfLookUps = (data.numberOfFrames - 1) * data.numberOfBones;
                    for (UInt32 i = 0; i < numberOfLookUps; ++i)
                    {
                        //
                        // Normal case for all frames after the first.
                        //

                        // Read in the offset data.

                        UInt32 boneID = file.ReadUInt32();
                        UInt16 positionID = file.ReadUInt16();
                        UInt16 unknownIndex = file.ReadUInt16(); // Unknown.
                        UInt16 orientationID = file.ReadUInt16();
                        unknownIndex = file.ReadUInt16(); // Unknown. Seems to always be zero.

                        // Retrieve the bone from the dictionary.
                        // Note: The bones appear to be in the same order in every frame.  So, a dictionary
                        // isn't exactly needed and you could probably get away with a list.  However, this way
                        // feels safer just in case something ends up being out of order.
                        ANMBone bone = boneMap[boneID];
                        ANMFrame frame = bone.frames[currentFrame];
                        frame.position = LookUpVector(positionID, positions);
                        frame.orientation = LookUpQuaternion(orientationID, orientations);

                        // This loop is slightly ambiguous.
                        //
                        // The problem is previous .anm versions contain data like:
                        // foreach bone
                        //      foreach frame
                        //
                        // However, this version contains data like:
                        // foreach frame
                        //      foreach bone
                        //
                        // So, reading one version is going to be a little goofy.
                        currentBone++;
                        if (currentBone >= data.numberOfBones)
                        {
                            currentBone = 0;
                            currentFrame++;
                        }
                    }

                    // Finally, we need to move all the data from the dictionary into the ANMFile.
                    foreach(var bone in boneMap)
                    {
                        data.bones.Add(bone.Value);
                    }

                    // Currently returning false for this version.  We can not render this version correctly yet.
                    // So, we need to tell the viewer not to try and load it.
                    result = false;
                }
                // Unknown version
                else
                {
                    logger.Error("Unknown anm version: " + data.version);
                    result = false;
                }
            }
            catch(Exception e)
            {
                logger.Error("Anm reading error.");
                logger.Error(e.Message);
                result = false;
            }

            logger.Event("File ID: " + data.id);
            logger.Event("Magic: " + data.magic);
            logger.Event("Version: " + data.version);
            logger.Event("Number of Bones: " + data.numberOfBones);
            logger.Event("Number of Frames: " + data.numberOfFrames);
            logger.Event("Playback FPS: " + data.playbackFPS);

            return result;
        }
        private static bool ReadCharacterInibin(MemoryStream stream, ref InibinFile file, Logger logger)
        {
            bool result = true;

            file = new InibinFile();

            stream.Seek( 0, SeekOrigin.Begin );

            // Header Info
            int version = stream.ReadByte();

            #if VERBOSE
            DebugOut("version", version);
            #endif

            int fileLen = (int) stream.Length;
            #if VERBOSE
            DebugOut("file length", fileLen);
            #endif

            int oldLen = (int)ReadShort(ref stream);
            #if VERBOSE
            DebugOut("old style length", oldLen);
            #endif

            int oldStyleOffset = fileLen - oldLen;
            #if VERBOSE
            DebugOut("old style offset", oldStyleOffset);
            #endif

            int format = (int) ReadShort(ref stream);
            #if VERBOSE
            DebugOut("format", format);
            #endif

            if ((format & 0x0001) == 0)
            {
            #if VERBOSE
                DebugOut("No U32 segment", "skipping");
            #endif
            }
            else
            {
                // Reads values based on the hash keys.
            #if VERBOSE
                DebugOut("U32 properties start position", stream.Position);
            #endif
                long[] keys = ReadSegmentKeys( ref stream );
                if (keys != null)
                {
                    foreach (long key in keys)
                    {
                        long val = (long)ReadInt32(ref stream);
            #if VERBOSE
                        DebugOut("U32 prop(" + key + ")", val);
            #endif

                        file.AddProperty(key, val);
                    }
                }
            }

            // float values
            if ((format & 0x0002) == 0)
            {
            #if VERBOSE
                DebugOut("No float segment", "skipping");
            #endif
            }
            else
            {
            #if VERBOSE
                DebugOut("Float properties start position", stream.Position);
            #endif
                long[] keys = ReadSegmentKeys( ref stream );
                if (keys != null)
                {
                    foreach (long key in keys)
                    {
                        float val = ReadFloat(ref stream);
            #if VERBOSE
                        DebugOut("float prop(" + key + ")", val);
            #endif

                        file.AddProperty(key, val);
                    }
                }
            }

            // U8 values
            if ((format & 0x0004) == 0)
            {
            #if VERBOSE
                DebugOut("No U8/10 segment", "skipping");
            #endif
            }
            else
            {
            #if VERBOSE
                DebugOut("U8/10 properties start position", stream.Position);
            #endif
                long[] keys = ReadSegmentKeys( ref stream );
                if (keys != null)
                {
                    foreach (long key in keys)
                    {
                        float val = stream.ReadByte() * 0.1F;
            #if VERBOSE
                        DebugOut("U8/10 prop(" + key + ")", val);
            #endif

                        file.AddProperty(key, val);
                    }
                }
            }

            // U16 values
            if ((format & 0x0008) == 0)
            {
            #if VERBOSE
                DebugOut("No U16 segment", "skipping");
            #endif
            }
            else
            {
            #if VERBOSE
                DebugOut("U16 properties start position", stream.Position);
            #endif
                long[] keys = ReadSegmentKeys( ref stream );
                if (keys != null)
                {
                    foreach (long key in keys)
                    {
                        int val = (int)ReadShort(ref stream);
            #if VERBOSE
                        DebugOut("U16 prop(" + key + ")", val);
            #endif

                        file.AddProperty(key, val);
                    }
                }
            }

            // U8 values
            if ((format & 0x0010) == 0)
            {
            #if VERBOSE
                DebugOut("No U8 segment", "skipping");
            #endif
            }
            else
            {
            #if VERBOSE
                DebugOut("U8 properties start position", stream.Position);
            #endif
                long[] keys = ReadSegmentKeys( ref stream );
                if (keys != null)
                {
                    foreach (long key in keys)
                    {
                        int val = 0xff & stream.ReadByte();
            #if VERBOSE
                        DebugOut("U8 prop(" + key + ")", val);
            #endif

                        file.AddProperty(key, val);
                    }
                }
            }

            // Boolean flags - single bit, ignoring
            if ((format & 0x0020) == 0)
            {
            #if VERBOSE
                DebugOut("No boolean segment", "skipping");
            #endif
            }
            else
            {
            #if VERBOSE
                DebugOut("Boolean flags start position", stream.Position);
            #endif
                long[] booleanKeys = ReadSegmentKeys(ref stream);
                if (booleanKeys != null)
                {
            #if VERBOSE
                    DebugOut("Boolean keys found", booleanKeys.Length);
            #endif
                    int index = 0;
                    for (int i = 0; i < 1 + ((booleanKeys.Length - 1) / 8); ++i)
                    {
                        int bits = stream.ReadByte();
                        for (int b = 0; b < 8; ++b)
                        {
                            long key = booleanKeys[index];
                            int val = 0x1 & bits;
            #if VERBOSE
                            DebugOut("Boolean prop(" + key + ")", val);
            #endif

                            file.AddProperty(key, val);

                            bits = bits >> 1;
                            if (++index == booleanKeys.Length)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            // 4-byte color values or something?
            if ((format & 0x0400) == 0)
            {
            #if VERBOSE
                DebugOut("No 4-byte color segment", "skipping");
            #endif
            }
            else
            {
            #if VERBOSE
                DebugOut("Color? properties start position", stream.Position);
            #endif
                long[] keys = ReadSegmentKeys( ref stream );
                if (keys != null)
                {
                    foreach (long key in keys)
                    {
                        long val = (long)ReadInt32(ref stream);
            #if VERBOSE
                        DebugOut("U32 color prop(" + key + ")", val);
            #endif

                        file.AddProperty(key, val);
                    }
                }
            }

            // Newer section.
            // I don't know what exactly these values represent.
            // I think it's related to champions with the new rage mechanic.
            // I'm just using it to increment the stream.
            // So, when I get to the part to read in strings, the pointer is at the
            // correct location.
            if ((format & 0x0080) == 0)
            {
            #if VERBOSE
                DebugOut("No offsets segment", "skipping");
            #endif
            }
            else
            {
            #if VERBOSE
                DebugOut("Rage values start position", stream.Position);
            #endif
                long[] rageKeys = ReadSegmentKeys(ref stream);
                if (rageKeys != null)
                {
            #if VERBOSE
                    DebugOut("Rage keys found", rageKeys.Length);
            #endif
                    foreach (long key in rageKeys)
                    {
                        float val1 = ReadFloat(ref stream);
                        float val2 = ReadFloat(ref stream);
                        float val3 = ReadFloat(ref stream);
            #if VERBOSE
                        DebugOut("Rage prop 1(" + key + ")", val1);
                        DebugOut("Rage prop 2(" + key + ")", val2);
                        DebugOut("Rage prop 3(" + key + ")", val3);
            #endif
                        // If you actually need these values, figure out what 12 byte
                        // structure they represent and add that property.
                        // It's probably a Vector3.
                        // file.AddProperty(key, MyRageKeyStructure);
                    }
                }
            }

            // Old-style offsets to strings
            if ((format & 0x1000) == 0)
            {
            #if VERBOSE
                DebugOut("No offsets segment", "skipping");
            #endif
            }
            else
            {
            #if VERBOSE
                DebugOut("Old style data position", stream.Position);
            #endif
                int lastOffset = -1;
                long[] keys = ReadSegmentKeys( ref stream );

                //
                // New method to read the newer .inibins.
                // Why determine the offset by reading in data from the file header
                // when we can just compute it here?  This seems to fix the problem
                // with newer .inibins.  I'm not sure what the value in the header
                // is used for though.
                //

                if (keys != null)
                {
                    oldStyleOffset = (int)stream.Position + keys.Length * 2;

                    foreach (long key in keys)
                    {
                        int offset = (int)ReadShort(ref stream);
            #if VERBOSE
                        DebugOut("String offset(" + key + ")", offset);
            #endif
                        String val = ReadNullTerminatedString(ref stream,
                            oldStyleOffset + offset);
            #if VERBOSE
                        DebugOut("String prop(" + key + ")", val);
            #endif

                        file.AddProperty(key, val);

                        lastOffset = offset;
                    }
                }
            }

            #if VERBOSE
            // Debuging Code
            //Debug.WriteLine("Skin #1 Name: " + file.properties[(long) InibinHashID.SKIN_ONE_NAME]);
            Debug.WriteLine("Skin #1 SKN: " + file.properties[(long) InibinHashID.SKIN_ONE_SKN]);
            Debug.WriteLine("Skin #1 SKL: " + file.properties[(long) InibinHashID.SKIN_ONE_SKL]);
            Debug.WriteLine("Skin #1 DDS: " + file.properties[(long) InibinHashID.SKIN_ONE_TEXTURE]);

            Debug.WriteLine("Skin #2 Name: " + file.properties[(long) InibinHashID.SKIN_TWO_NAME]);
            Debug.WriteLine("Skin #2 SKN: " + file.properties[(long) InibinHashID.SKIN_TWO_SKN]);
            Debug.WriteLine("Skin #2 SKL: " + file.properties[(long) InibinHashID.SKIN_TWO_SKL]);
            Debug.WriteLine("Skin #2 DDS: " + file.properties[(long) InibinHashID.SKIN_TWO_TEXTURE]);

            Debug.WriteLine("Skin #3 Name: " + file.properties[(long) InibinHashID.SKIN_THREE_NAME]);
            Debug.WriteLine("Skin #3 SKN: " + file.properties[(long) InibinHashID.SKIN_THREE_SKN]);
            Debug.WriteLine("Skin #3 SKL: " + file.properties[(long) InibinHashID.SKIN_THREE_SKL]);
            Debug.WriteLine("Skin #3 DDS: " + file.properties[(long) InibinHashID.SKIN_THREE_TEXTURE]);

            Debug.WriteLine("Skin #4 Name: " + file.properties[(long) InibinHashID.SKIN_FOUR_NAME]);
            Debug.WriteLine("Skin #4 SKN: " + file.properties[(long) InibinHashID.SKIN_FOUR_SKN]);
            Debug.WriteLine("Skin #4 SKL: " + file.properties[(long) InibinHashID.SKIN_FOUR_SKL]);
            Debug.WriteLine("Skin #4 DDS: " + file.properties[(long) InibinHashID.SKIN_FOUR_TEXTURE]);

            Debug.WriteLine("Skin #5 Name: " + file.properties[(long) InibinHashID.SKIN_FIVE_NAME]);
            Debug.WriteLine("Skin #5 SKN: " + file.properties[(long) InibinHashID.SKIN_FIVE_SKN]);
            Debug.WriteLine("Skin #5 SKL: " + file.properties[(long) InibinHashID.SKIN_FIVE_SKL]);
            Debug.WriteLine("Skin #5 DDS: " + file.properties[(long) InibinHashID.SKIN_FIVE_TEXTURE]);

            Debug.WriteLine("Skin #6 Name: " + file.properties[(long) InibinHashID.SKIN_SIX_NAME]);
            Debug.WriteLine("Skin #6 SKN: " + file.properties[(long) InibinHashID.SKIN_SIX_SKN]);
            Debug.WriteLine("Skin #6 SKL: " + file.properties[(long) InibinHashID.SKIN_SIX_SKL]);
            Debug.WriteLine("Skin #6 DDS: " + file.properties[(long) InibinHashID.SKIN_SIX_TEXTURE]);

            Debug.WriteLine("Skin #7 Name: " + file.properties[(long)InibinHashID.SKIN_SEVEN_NAME]);
            Debug.WriteLine("Skin #7 SKN: " + file.properties[(long)InibinHashID.SKIN_SEVEN_SKN]);
            Debug.WriteLine("Skin #7 SKL: " + file.properties[(long)InibinHashID.SKIN_SEVEN_SKL]);
            Debug.WriteLine("Skin #7 DDS: " + file.properties[(long)InibinHashID.SKIN_SEVEN_TEXTURE]);

            Debug.WriteLine("Skin #8 Name: " + file.properties[(long)InibinHashID.SKIN_EIGHT_NAME]);
            Debug.WriteLine("Skin #8 SKN: " + file.properties[(long)InibinHashID.SKIN_EIGHT_SKN]);
            Debug.WriteLine("Skin #8 SKL: " + file.properties[(long)InibinHashID.SKIN_EIGHT_SKL]);
            Debug.WriteLine("Skin #8 DDS: " + file.properties[(long)InibinHashID.SKIN_EIGHT_TEXTURE]);
            #endif

            logger.Event("Version: " + version);

            //if (file.properties.ContainsKey((long)InibinHashID.SKIN_ONE_NAME))
                //logger.LogEvent("Skin #1 Name: " + file.properties[(long) InibinHashID.SKIN_ONE_NAME]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_ONE_SKN))
                logger.Event("Skin #1 SKN: " + file.properties[(long)InibinHashID.SKIN_ONE_SKN]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_ONE_SKL))
                logger.Event("Skin #1 SKL: " + file.properties[(long)InibinHashID.SKIN_ONE_SKL]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_ONE_TEXTURE))
                logger.Event("Skin #1 DDS: " + file.properties[(long)InibinHashID.SKIN_ONE_TEXTURE]);

            if (file.properties.ContainsKey((long)InibinHashID.SKIN_TWO_NAME))
                logger.Event("Skin #2 Name: " + file.properties[(long)InibinHashID.SKIN_TWO_NAME]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_TWO_SKN))
                logger.Event("Skin #2 SKN: " + file.properties[(long)InibinHashID.SKIN_TWO_SKN]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_TWO_SKL))
                logger.Event("Skin #2 SKL: " + file.properties[(long)InibinHashID.SKIN_TWO_SKL]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_TWO_TEXTURE))
                logger.Event("Skin #2 DDS: " + file.properties[(long)InibinHashID.SKIN_TWO_TEXTURE]);

            if (file.properties.ContainsKey((long)InibinHashID.SKIN_THREE_NAME))
                logger.Event("Skin #3 Name: " + file.properties[(long)InibinHashID.SKIN_THREE_NAME]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_THREE_SKN))
                logger.Event("Skin #3 SKN: " + file.properties[(long)InibinHashID.SKIN_THREE_SKN]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_THREE_SKL))
                logger.Event("Skin #3 SKL: " + file.properties[(long)InibinHashID.SKIN_THREE_SKL]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_THREE_TEXTURE))
                logger.Event("Skin #3 DDS: " + file.properties[(long)InibinHashID.SKIN_THREE_TEXTURE]);

            if (file.properties.ContainsKey((long)InibinHashID.SKIN_FOUR_NAME))
                logger.Event("Skin #4 Name: " + file.properties[(long)InibinHashID.SKIN_FOUR_NAME]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_FOUR_SKN))
                logger.Event("Skin #4 SKN: " + file.properties[(long)InibinHashID.SKIN_FOUR_SKN]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_FOUR_SKL))
                logger.Event("Skin #4 SKL: " + file.properties[(long)InibinHashID.SKIN_FOUR_SKL]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_FOUR_TEXTURE))
                logger.Event("Skin #4 DDS: " + file.properties[(long)InibinHashID.SKIN_FOUR_TEXTURE]);

            if (file.properties.ContainsKey((long)InibinHashID.SKIN_FIVE_NAME))
                logger.Event("Skin #5 Name: " + file.properties[(long)InibinHashID.SKIN_FIVE_NAME]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_FIVE_SKN))
                logger.Event("Skin #5 SKN: " + file.properties[(long)InibinHashID.SKIN_FIVE_SKN]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_FIVE_SKL))
                logger.Event("Skin #5 SKL: " + file.properties[(long)InibinHashID.SKIN_FIVE_SKL]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_FIVE_TEXTURE))
                logger.Event("Skin #5 DDS: " + file.properties[(long)InibinHashID.SKIN_FIVE_TEXTURE]);

            if (file.properties.ContainsKey((long)InibinHashID.SKIN_SIX_NAME))
                logger.Event("Skin #6 Name: " + file.properties[(long)InibinHashID.SKIN_SIX_NAME]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_SIX_SKN))
                logger.Event("Skin #6 SKN: " + file.properties[(long)InibinHashID.SKIN_SIX_SKN]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_SIX_SKL))
                logger.Event("Skin #6 SKL: " + file.properties[(long)InibinHashID.SKIN_SIX_SKL]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_SIX_TEXTURE))
                logger.Event("Skin #6 DDS: " + file.properties[(long)InibinHashID.SKIN_SIX_TEXTURE]);

            if (file.properties.ContainsKey((long)InibinHashID.SKIN_SEVEN_NAME))
                logger.Event("Skin #7 Name: " + file.properties[(long)InibinHashID.SKIN_SEVEN_NAME]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_SEVEN_SKN))
                logger.Event("Skin #7 SKN: " + file.properties[(long)InibinHashID.SKIN_SEVEN_SKN]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_SEVEN_SKL))
                logger.Event("Skin #7 SKL: " + file.properties[(long)InibinHashID.SKIN_SEVEN_SKL]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_SEVEN_TEXTURE))
                logger.Event("Skin #7 DDS: " + file.properties[(long)InibinHashID.SKIN_SEVEN_TEXTURE]);

            if (file.properties.ContainsKey((long)InibinHashID.SKIN_EIGHT_NAME))
                logger.Event("Skin #8 Name: " + file.properties[(long)InibinHashID.SKIN_EIGHT_NAME]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_EIGHT_SKN))
                logger.Event("Skin #8 SKN: " + file.properties[(long)InibinHashID.SKIN_EIGHT_SKN]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_EIGHT_SKL))
                logger.Event("Skin #8 SKL: " + file.properties[(long)InibinHashID.SKIN_EIGHT_SKL]);
            if (file.properties.ContainsKey((long)InibinHashID.SKIN_EIGHT_TEXTURE))
                logger.Event("Skin #8 DDS: " + file.properties[(long)InibinHashID.SKIN_EIGHT_TEXTURE]);

            return result;
        }
Beispiel #9
0
        private static bool ReadData(BinaryReader file, ref SKNFile data, Logger logger)
        {
            bool result = true;

            try
            {
                // File Header Information.
                data.magic       = file.ReadInt32();
                data.version     = file.ReadInt16();
                data.numObjects  = file.ReadInt16();

                if (data.version == 1 || data.version == 2)
                {
                    // Contains material headers.
                    data.numMaterialHeaders = file.ReadInt32();
                    for (int i = 0; i < data.numMaterialHeaders; ++i)
                    {
                        // Read in the headers.
                        SKNMaterial header = new SKNMaterial();

                        header.name = new String(file.ReadChars(SKNMaterial.MATERIAL_NAME_SIZE));
                        header.startVertex = file.ReadInt32();
                        header.numVertices = file.ReadInt32();
                        header.startIndex = file.ReadInt32();
                        header.numIndices = file.ReadInt32();

                        data.materialHeaders.Add(header);
                    }

                    // Read in model data.
                    data.numIndices = file.ReadInt32();
                    data.numVertices = file.ReadInt32();

                    for (int i = 0; i < data.numIndices; ++i)
                    {
                        data.indices.Add(file.ReadInt16());
                    }

                    for (int i = 0; i < data.numVertices; ++i)
                    {
                        SKNVertex vertex = new SKNVertex();

                        vertex.position[0] = file.ReadSingle(); // x
                        vertex.position[1] = file.ReadSingle(); // y
                        vertex.position[2] = file.ReadSingle(); // z

                        for (int j = 0; j < SKNVertex.BONE_INDEX_SIZE; ++j)
                        {
                            int bone = (int)file.ReadByte();
                            vertex.boneIndex[j] = bone;
                        }

                        vertex.weights[0] = file.ReadSingle();
                        vertex.weights[1] = file.ReadSingle();
                        vertex.weights[2] = file.ReadSingle();
                        vertex.weights[3] = file.ReadSingle();

                        vertex.normal[0] = file.ReadSingle(); // x
                        vertex.normal[1] = file.ReadSingle(); // y
                        vertex.normal[2] = file.ReadSingle(); // z

                        vertex.texCoords[0] = file.ReadSingle(); // u
                        vertex.texCoords[1] = file.ReadSingle(); // v

                        data.vertices.Add(vertex);
                    }

                    // Data exclusive to version two.
                    if (data.version == 2)
                    {
                        data.endTab.Add(file.ReadInt32());
                        data.endTab.Add(file.ReadInt32());
                        data.endTab.Add(file.ReadInt32());
                    }
                }
                // Unknown Version
                else
                {
                    logger.Error("Unknown skn version: " + data.version);
                    result = false;
                }
            }
            catch(Exception e)
            {
                logger.Error("Skn reading error.");
                logger.Error(e.Message);
                result = false;
            }

            logger.Event("Magic: " + data.magic);
            logger.Event("Version: " + data.version);
            logger.Event("Number of Objects: " + data.numObjects);
            logger.Event("Number of Material Headers: " + data.numMaterialHeaders);
            logger.Event("Number of Vertices: " + data.numVertices);
            logger.Event("Number of Indices: " + data.numIndices);

            return result;
        }
Beispiel #10
0
        private static bool ReadData(BinaryReader file, ref SKLFile data, Logger logger)
        {
            bool result = true;

            try
            {
                // File Header Information.
                data.id = new String(file.ReadChars(SKLFile.ID_SIZE));
                data.version = file.ReadUInt32();

                if (data.version == 1 || data.version == 2)
                {
                    data.designerID = file.ReadUInt32();

                    // Read in the bones.
                    data.numBones = file.ReadUInt32();
                    for (int i = 0; i < data.numBones; ++i)
                    {
                        SKLBone bone = new SKLBone();

                        bone.name = new String(
                            file.ReadChars(SKLBone.BONE_NAME_SIZE));
                        bone.name = RemoveBoneNamePadding(bone.name);
                        bone.name = bone.name.ToLower();

                        bone.ID = i;
                        bone.parentID = file.ReadInt32();
                        bone.scale = file.ReadSingle();

                        // Read in transform matrix.
                        float[] orientation = new float[SKLBone.ORIENTATION_SIZE];
                        for (int j = 0; j < SKLBone.ORIENTATION_SIZE; ++j)
                        {
                            orientation[j] = file.ReadSingle();
                        }

                        bone.orientation = orientation;

                        // Position from matrix.
                        bone.position[0] = orientation[3];
                        bone.position[1] = orientation[7];
                        bone.position[2] = orientation[11];

                        data.bones.Add(bone);
                    }

                    // Version two contains bone IDs.
                    if (data.version == 2)
                    {
                        data.numBoneIDs = file.ReadUInt32();
                        for (uint i = 0; i < data.numBoneIDs; ++i)
                        {
                            data.boneIDs.Add(file.ReadUInt32());
                        }
                    }
                }
                // Newest version so far.
                else if (data.version == 0)
                {
                    // Header
                    Int16 zero = file.ReadInt16(); // ?

                    data.numBones = (uint)file.ReadInt16();

                    data.numBoneIDs = file.ReadUInt32();
                    Int16 offsetToVertexData = file.ReadInt16(); // Should be 64.

                    int unknown = file.ReadInt16(); // ?

                    int offset1 = file.ReadInt32();
                    int offsetToAnimationIndices = file.ReadInt32();
                    int offset2 = file.ReadInt32();
                    int offset3 = file.ReadInt32();
                    int offsetToStrings = file.ReadInt32();

                    // Not sure what this data represents.
                    // I think it's padding incase more header data is required later.
                    file.BaseStream.Position += 20;

                    file.BaseStream.Position = offsetToVertexData;
                    for (int i = 0; i < data.numBones; ++i)
                    {
                        SKLBone bone = new SKLBone();
                        // The old scale was always 0.1.
                        // For now, just go with it.
                        bone.scale = 0.1f;

                        zero = file.ReadInt16(); // ?
                        bone.ID = file.ReadInt16();
                        bone.parentID = file.ReadInt16();
                        unknown = file.ReadInt16(); // ?

                        int namehash = file.ReadInt32();

                        float twoPointOne = file.ReadSingle();

                        bone.position[0] = file.ReadSingle();
                        bone.position[1] = file.ReadSingle();
                        bone.position[2] = file.ReadSingle();

                        float one = file.ReadSingle(); // ? Maybe scales for X, Y, and Z
                        one = file.ReadSingle();
                        one = file.ReadSingle();

                        bone.orientation[0] = file.ReadSingle();
                        bone.orientation[1] = file.ReadSingle();
                        bone.orientation[2] = file.ReadSingle();
                        bone.orientation[3] = file.ReadSingle();

                        float ctx = file.ReadSingle(); // ctx
                        float cty = file.ReadSingle(); // cty
                        float ctz = file.ReadSingle(); // ctz

                        data.bones.Add(bone);

                        // The rest of the bone data is unknown. Maybe padding?
                        file.BaseStream.Position += 32;
                    }

                    file.BaseStream.Position = offset1;
                    for (int i = 0; i < data.numBones; ++i) // Inds for version 4 animation.
                    {
                        // 8 bytes
                        uint sklID = file.ReadUInt32();
                        uint anmID = file.ReadUInt32();

                        data.boneIDMap[anmID] = sklID;
                    }

                    file.BaseStream.Position = offsetToAnimationIndices;
                    for (int i = 0; i < data.numBoneIDs; ++i) // Inds for animation
                    {
                        // 2 bytes
                        UInt16 boneID = file.ReadUInt16();
                        data.boneIDs.Add(boneID);
                    }

                    file.BaseStream.Position = offsetToStrings;
                    for (int i = 0; i < data.numBones; ++i)
                    {
                        // bone names
                        string name = "";
                        while (name.Contains('\0') == false)
                        {
                            name += new string(file.ReadChars(4));
                        }
                        name = RemoveBoneNamePadding(name);
                        name = name.ToLower();

                        data.bones[i].name = name;
                    }
                }
                // Unknown Version
                else
                {
                    logger.Error("Unknown skl version: " + data.version);
                    result = false;
                }
            }
            catch (Exception e)
            {
                logger.Error("Skl reading error.");
                logger.Error(e.Message);
                result = false;
            }

            logger.Event("File ID: " + data.id);
            logger.Event("Version: " + data.version);
            logger.Event("Designer ID: " + data.designerID);
            logger.Event("Number of Bones: " + data.numBones);
            logger.Event("Number of Bone IDs: " + data.numBoneIDs);

            return result;
        }
        // Replacement for individual raf reading and individual filetype searching
        // Provide the directory of RADS\projects\lol_game_client\filearchives or the equivalent
        private bool ReadRAFs(DirectoryInfo dir, Logger logger)
        {
            try
            {
                RAFMasterFileList rafFiles = new RAFMasterFileList(dir.FullName);
                logger.Event("Opening the 'filearchives' directory: " + dir.FullName);
                foreach (RAFMasterFileList.RAFSearchResult result in rafFiles.SearchFileEntries(new string[] { ".dds", ".skn", ".skl", ".inibin", "animations.list", ".anm" }, RAFMasterFileList.RAFSearchType.All))
                {
                    RAFFileListEntry e = result.value;

                    // Split off the actual file name from the full path
                    String name = e.FileName.Substring(e.FileName.LastIndexOf('/') + 1).ToLower();

                    switch (result.searchPhrase)
                    {
                        case ".dds":
                            // Try to parse out unwanted textures.
                            if (!e.FileName.ToLower().Contains("loadscreen") &&
                                !e.FileName.ToLower().Contains("circle") &&
                                !e.FileName.ToLower().Contains("square") &&
                                e.FileName.ToLower().Contains("data") &&
                                e.FileName.ToLower().Contains("characters"))
                            {
                                // Check that the file isn't already in the dictionary
                                if (!textures.ContainsKey(name))
                                {
                                    textures.Add(name, e);
                                }
                                else
                                {
                                    logger.Warning("Duplicate texture " + name + ": " + e.FileName);
                                }
                            }
                            break;

                        case ".skn":
                            if (!skns.ContainsKey(name))
                            {
                                skns.Add(name, e);
                            }
                            else
                            {
                                logger.Warning("Duplicate skn " + name + ": " + e.FileName);
                            }
                            break;

                        case ".skl":
                            if (!skls.ContainsKey(name))
                            {
                                skls.Add(name, e);
                            }
                            else
                            {
                                logger.Warning("Duplicate skn " + name + ": " + e.FileName);
                            }
                            break;

                        case ".inibin":
                            // Try to only read champion inibins
                            if (e.FileName.ToLower().Contains("data") &&
                                e.FileName.ToLower().Contains("characters"))
                            {
                                inibins.Add(e);
                            }
                            else
                            {
                                logger.Warning("Excluding inibin " + name + ": " + e.FileName);
                            }
                            break;

                        case "animations.list":
                            // Riot changed their directory structure for some skins.
                            // Originally, champion Animation.list files were stored in a directory structure like
                            // "*/ChampionName/Animation.list".  Now, some are stored like
                            // "*/ChampionName/Skins/Skin01/Animation.list".

                            if (e.FileName.ToLower().Contains("skin") == false &&
                                e.FileName.ToLower().Contains("base") == false)
                            {
                                // Original Case.

                                // Remove the file name.
                                name = e.FileName.Remove(e.FileName.LastIndexOf('/'));

                                // Remove proceeding directories to get the parent directory
                                name = name.Substring(name.LastIndexOf('/') + 1).ToLower();
                            }
                            else
                            {
                                // Newer Case.
                                string path = e.FileName.ToString();
                                string[] splitPath = path.Split('/');

                                // Sanity
                                if (splitPath.Length > 3)
                                {
                                    name = splitPath[splitPath.Length - 4].ToLower();
                                }
                            }

                            // Store.
                            if (!animationLists.ContainsKey(name))
                            {
                                animationLists.Add(name, e);
                            }
                            else
                            {
                                logger.Warning("Duplicate animation list " + name + ": " + e.FileName);
                            }
                            break;

                        case ".anm":
                            // Remove the .anm extension.
                            name = name.Remove(name.Length - 4);

                            if (!animations.ContainsKey(name))
                            {
                                animations.Add(name, e);
                            }
                            else
                            {
                                logger.Warning("Duplicate anm " + name + ": " + e.FileName);
                            }
                            break;
                    }
                }

            }
            catch (Exception e)
            {
                // Something went wrong. Most likely the RAF read failed due to a bad directory.
                logger.Error("Failed to open RAFs");
                logger.Error(e.Message);
                return false;
            }

            return true;
        }
        private void GenerateModelDefinitions(Logger logger)
        {
            foreach (RAFFileListEntry f in inibins)
            {
                InibinFile iniFile = new InibinFile();
                bool readResult = InibinReader.Read(f, ref iniFile, logger);

                if (readResult == true)
                {
                    // Add the models from this .inibin file
                    List<ModelDefinition> modelDefs = iniFile.GetModelStrings();
                    for (int j = 0; j < modelDefs.Count; ++j)
                    {
                        // Name the model after the parent directory
                        // of the .inibin plus the name from the .inibin.
                        // Some things overlap without both.

                        string path = f.FileName;
                        string[] splitPath = path.Split('/');

                        string directoryName = splitPath[splitPath.Length - 2];
                        if (directoryName.Contains("Base") == true ||
                            directoryName.Contains("Skin") == true)
                        {
                            // The directory structure for this case will be something like
                            // "*/ChampionName/Skins/Base/".
                            // We just want the "ChampionName".
                            directoryName = splitPath[splitPath.Length - 4];
                        }

                        // Sometimes the name from the .inibin file is "".
                        // So, just name it after the directory
                        String name = modelDefs[j].name;
                        if (name == "")
                        {
                            name = directoryName + "/" + directoryName;
                        }
                        else
                        {
                            name = directoryName + "/" + name;
                        }

                        try
                        {
                            LOLModel model;
                            bool storeResult = StoreModel(modelDefs[j], out model, logger);

                            if (storeResult == true)
                            {
                                // Try to store animations for model as well
                                storeResult = StoreAnimations(ref model, logger);
                            }

                            if (storeResult == true)
                            {
                                if (models.ContainsKey(name) == false)
                                {
                                    logger.Event("Adding model definition: " + name);
                                    models.Add(name, model);
                                }
                                else
                                {
                                    logger.Warning("Duplicate model definition: " + name);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            logger.Error("Unable to store model definition: " + name);
                            logger.Error(e.Message);
                        }
                    }
                }
            }
        }
        public bool Read(Logger logger)
        {
            bool result = true;

            // Clear old data.

            models.Clear();

            skls.Clear();
            skns.Clear();
            textures.Clear();

            inibins.Clear();
            animationLists.Clear();
            animations.Clear();

            DirectoryInfo rootDir = null;
            try
            {
                logger.Event("Reading models from: " + Root);
                rootDir = new DirectoryInfo(Root);
            }
            catch
            {
                logger.Error("Unable to get the directory information: " + Root);
                result = false;
            }

            //
            // Try to find the raf files and read them.
            //

            if (result == true)
            {
                try
                {
                    result = GetRAFFiles(rootDir, logger);

                    // If the finding or reading fails, bail.
                    if (!result)
                    {
                        logger.Error("Unable to find the 'filearchives' directory: " + Root);
                    }
                }
                catch (Exception e)
                {
                    logger.Error("Unable to open directory: " + Root);
                    logger.Error(e.Message);
                    result = false;
                }
            }

            // Sanity
            if (result == true)
            {
                GenerateModelDefinitions(logger);
            }

            return result;
        }