// Decompiled by DJ v3.11.11.95 Copyright 2009 Atanas Neshkov  Date: 06.11.2010 20:17:33
// Home Page: http://members.fortunecity.com/neshkov/dj.html  http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   MDLFile.java

package mdl2smd;

import java.util.LinkedList;
import java.util.List;
import stackvis.StackVis;

// Referenced classes of package mdl2smd:
//            ReadFile, Bone, Pose, Attachment, 
//            HitBox, Animation, Sequence, FlexController, 
//            Blend, Vertex, Quaternion2Euler

public class MDLFile extends ReadFile
{

    public MDLFile(String filePath)
    {
        super(filePath);
        modelNameOffset = 12;
        nOBOffset = 240;
        bonesOffsetOffset = 244;
        boneSize = 160;
        parentBonePosition = 4;
        animPSize = 4;
        paramPos = 32;
        animPPos = 60;
        numberOfAnimsOffset = 264;
        animDescOffsetOffset = 268;
        animDescLength = 72;
        fpsPos = 4;
        framesPos = 12;
        nodePosePos = 48;
        nodePoseLength = 32;
        numOfSeqParameters = 7;
        parameterLength = 4;
        parameterPos = 4;
        nOFramesPos = 1;
        frameDataDescLength = 2;
        frameDataLength = 2;
        numberOfSequencesOffset = 272;
        sequencesOffset = 276;
        sequencesLength = 764;
        animationPos = 56;
        maxStringLength = 136;
        numberOfMaterialsOffset = 292;
        materialDescOffsetOffset = 296;
        materialDescLength = 20;
        numberOfCDMaterialsOffset = 300;
        cdMaterialsOffsetOffset = 304;
        numberOfAttachmentsOffset = 328;
        attachmentsOffsetOffset = 332;
        attachmentSize = 60;
        numberOfEyesOffsetDelay = 192;
        eyesOffsetOffsetDelay = 196;
        eyesSize = 140;
        numberOfModelsOffset = 320;
        modelsOffsetOffset = 324;
        modelSize = 224;
        numberOfFlexNamesOffset = 344;
        flexNamesOffsetOffset = 348;
        flexNamesSize = 4;
        numberOfFlexControllerOffset = 352;
        flexControllerOffsetOffset = 356;
        flexControllerLength = 20;
        numberOfFlexEqOffset = 360;
        flexEqOffsetOffset = 364;
        flexEqLength = 12;
        flexExpLength = 8;
        numberOfPartsSize = 4;
        partsDescOffsetSize = 4;
        nOVOffsetSize = 4;
        nOVToFileType = 12;
        partDescSize = 60;
        partOffsetDelay = 12;
        vertexSize0 = 44;
        vertexSize1 = 12;
        vertexSize2 = 8;
        hitBoxDescNumOffset = 256;
        hitBoxDescOffsetOffset = 260;
        hitBoxDescLength = 12;
        hitBoxNumPos = 4;
        hitBoxOffsetPos = 8;
        hitBoxLength = 32;
        blendsNumberOffset = 384;
        blendsOffsetOffset = 388;
        blendSize = 20;
        surfacePropOffset = 392;
        numberOfIncludeModelsOffset = 404;
        includeModelsOffsetOffset = 408;
        vertexTypeOffset = 228;
        modelName = readString(modelNameOffset);
        numberOfBones = bytesToInt(file, nOBOffset);
        bonesOffset = bytesToInt(file, bonesOffsetOffset);
        int modelOffsetDelay = bytesToInt(file, bytesToInt(file, modelsOffsetOffset) + 12);
        int refFileOffset = bytesToInt(file, modelsOffsetOffset) + modelOffsetDelay;
        partsDescOffsetOffset = numberOfPartsOffset + numberOfPartsSize;
        partsDescOffset = refFileOffset + bytesToInt(file, partsDescOffsetOffset);
        nOVOffset = partsDescOffsetOffset + partsDescOffsetSize;
        refPrefaceOffset = nOVOffset + nOVOffsetSize;
        refPrefaceSize = bytesToInt(file, refPrefaceOffset);
        vertexType = unsignedByteToInt(file[vertexTypeOffset]);
        numberOfPartsOffset = refFileOffset + maxStringLength;
        readBones();
        readModel();
        numberOfMaterials = bytesToInt(file, numberOfMaterialsOffset);
        materialDescOffset = bytesToInt(file, materialDescOffsetOffset);
        materials = new String[numberOfMaterials];
        for(int i = 0; i < numberOfMaterials; i++)
        {
            int cStrDescOffset = materialDescOffset + materialDescLength * i;
            int cStrOffset = cStrDescOffset + bytesToInt(file, cStrDescOffset);
            materials[i] = readString(cStrOffset);
        }

        readPose();
        readCDMaterials();
        readAttachments();
        readIncludeModels();
        readHitBoxes();
        readAnimations();
        readSequences();
        readFlexEquations();
        readBlends();
        readSurfaceProp();
    }

    public boolean isValid()
    {
        return "IDST".compareTo(new String(bytes(0, 4))) == 0 && bytesToShort(4) == 2531;
    }

    public void readModel()
    {
        numberOfModels = bytesToInt(file, numberOfModelsOffset);
        modelsOffset = bytesToInt(file, modelsOffsetOffset);
        model = readString(modelsOffset + bytesToInt(file, modelsOffset));
        int cOffset = modelsOffset + bytesToInt(file, modelsOffset + 12);
        refFilenames = new String[numberOfModels];
        partStart = new int[numberOfModels][];
        vAnimDesc = new int[numberOfModels][][];
        allVertices = new Vertex[numberOfModels][];
        for(int i = 0; i < numberOfModels; i++)
        {
            refFilenames[i] = readString(cOffset);
            int cNumberOfParts = bytesToInt(file, cOffset + 136);
            int cPartOffset = cOffset + bytesToInt(file, cOffset + 140);
            partStart[i] = new int[cNumberOfParts];
            vAnimDesc[i] = new int[cNumberOfParts][];
            for(int j = 0; j < cNumberOfParts; j++)
            {
                partStart[i][j] = bytesToInt(file, cPartOffset + partOffsetDelay);
                vAnimDesc[i][j] = new int[2];
                vAnimDesc[i][j][0] = bytesToInt(file, cPartOffset + 16);
                vAnimDesc[i][j][1] = bytesToInt(file, cPartOffset + 20) + cPartOffset;
                cPartOffset += partDescSize;
            }

            int cNumberOfVertices = bytesToInt(file, cOffset + 144);
            int cVerticesOffset = cOffset + bytesToInt(file, cOffset + 148);
            int cFiletypeOffset = cOffset + 156;
            int cFiletype = bytesToInt(file, cFiletypeOffset);
            switch(cFiletype)
            {
            case 0: // '\0'
            {
                allVertices[i] = readVerticesType0(cNumberOfVertices, cVerticesOffset);
                break;
            }

            case 1: // '\001'
            {
                float cPosX = bytesToFloat(file, 180);
                float cPosY = bytesToFloat(file, 184);
                float cPosZ = bytesToFloat(file, 176);
                float cRotX = bytesToFloat(file, 188);
                float cRotY = bytesToFloat(file, 192);
                float cRotZ = bytesToFloat(file, 196);
                allVertices[i] = readVerticesType1(cNumberOfVertices, cVerticesOffset, cPosX, cPosY, cPosZ, cRotX, cRotY, cRotZ);
                break;
            }

            case 2: // '\002'
            {
                float cPosX = bytesToFloat(file, 180);
                float cPosY = bytesToFloat(file, 184);
                float cPosZ = bytesToFloat(file, 176);
                float cRotX = bytesToFloat(file, 188);
                float cRotY = bytesToFloat(file, 192);
                float cRotZ = bytesToFloat(file, 196);
                allVertices[i] = readVerticesType2(cNumberOfVertices, cVerticesOffset, cPosX, cPosY, cPosZ, cRotX, cRotY, cRotZ);
                break;
            }
            }
            if(refFilenames[i].equals(""))
                i--;
            cOffset += modelSize;
        }

    }

    public void readBones()
    {
        bones = new LinkedList();
        for(int i = 0; i < numberOfBones; i++)
        {
            int cBoneOffset = bonesOffset + i * boneSize;
            int cParent = bytesToInt(file, cBoneOffset + parentBonePosition);
            int cBoneNameOffset = cBoneOffset + bytesToInt(file, cBoneOffset);
            bones.add(new Bone(i, readString(cBoneNameOffset), cParent));
        }

    }

    public void readPose()
    {
        LinkedList frame = new LinkedList();
        boneParams = new float[numberOfBones][];
        animStepSize = new float[numberOfBones][];
        orientation = new boolean[numberOfBones];
        for(int i = 0; i < numberOfBones; i++)
        {
            int cBoneOffset = bonesOffset + boneSize * i;
            Bone cBone = (Bone)bones.get(i);
            float cPosX = bytesToFloat(file, cBoneOffset + 32);
            float cPosY = bytesToFloat(file, cBoneOffset + 36);
            float cPosZ = bytesToFloat(file, cBoneOffset + 40);
            float cI = bytesToFloat(file, cBoneOffset + 44);
            float cJ = bytesToFloat(file, cBoneOffset + 48);
            float cK = bytesToFloat(file, cBoneOffset + 52);
            float cReal = bytesToFloat(file, cBoneOffset + 56);
            List cRots = Quaternion2Euler.quat2Euler(cReal, cI, cJ, cK);
            boneParams[i] = new float[numOfSeqParameters];
            animStepSize[i] = new float[numOfSeqParameters];
            for(int j = 0; j < numOfSeqParameters; j++)
            {
                boneParams[i][j] = bytesToFloat(file, cBoneOffset + paramPos + j * animPSize);
                animStepSize[i][j] = bytesToFloat(file, cBoneOffset + animPPos + j * animPSize);
            }

            int vector = unsignedShortToInt(bytesToShort(file, cBoneOffset + 136));
            orientation[i] = (vector & 2) >> 1 == 1;
            frame.add(new Pose(cBone, cPosX, cPosY, cPosZ, ((Float)cRots.get(0)).floatValue(), ((Float)cRots.get(1)).floatValue(), ((Float)cRots.get(2)).floatValue()));
        }

        this.frame = frame;
    }

    public void readCDMaterials()
    {
        numberOfCDMaterials = bytesToInt(file, numberOfCDMaterialsOffset);
        cdMaterialsOffset = bytesToInt(file, cdMaterialsOffsetOffset);
        cdMaterials = new String[numberOfCDMaterials];
        for(int i = 0; i < numberOfCDMaterials; i++)
            cdMaterials[i] = readString(bytesToInt(file, cdMaterialsOffset + 4 * i));

    }

    public void readAttachments()
    {
        numberOfAttachments = bytesToInt(file, numberOfAttachmentsOffset);
        attachmentsOffset = bytesToInt(file, attachmentsOffsetOffset);
        int cOffset = attachmentsOffset;
        attachments = new Attachment[numberOfAttachments];
        for(int i = 0; i < numberOfAttachments; i++)
        {
            String cName = readString(cOffset + bytesToInt(file, cOffset));
            Bone cParent = (Bone)bones.get(bytesToInt(file, cOffset + 8));
            float cX = bytesToFloat(file, cOffset + 24);
            float cY = bytesToFloat(file, cOffset + 40);
            float cZ = bytesToFloat(file, cOffset + 56);
            float cXX = bytesToFloat(file, cOffset + 12);
            float cYX = bytesToFloat(file, cOffset + 28);
            float cZX = bytesToFloat(file, cOffset + 44);
            float cZY = bytesToFloat(file, cOffset + 48);
            float cZZ = bytesToFloat(file, cOffset + 52);
            attachments[i] = new Attachment(cName, cParent, cX, cY, cZ, cXX, cYX, cZX, cZY, cZZ);
            cOffset += attachmentSize;
        }

    }

    public void readIncludeModels()
    {
        numberOfIncludeModels = bytesToInt(file, numberOfIncludeModelsOffset);
        includeModelsOffset = bytesToInt(file, includeModelsOffsetOffset);
        int cOffset = includeModelsOffset;
        includeModels = new String[numberOfIncludeModels];
        for(int i = 0; i < numberOfIncludeModels; i++)
        {
            includeModels[i] = readString(cOffset + bytesToInt(file, cOffset));
            cOffset += 116;
        }

    }

    public void readHitBoxes()
    {
        hitBoxDescNum = bytesToInt(file, hitBoxDescNumOffset);
        hitBoxDescOffset = bytesToInt(file, hitBoxDescOffsetOffset);
        hitBoxSet = new String[hitBoxDescNum];
        hitBoxNum = new int[hitBoxDescNum];
        hitBoxOffset = new int[hitBoxDescNum];
        hitBoxes = new HitBox[hitBoxDescNum][];
        for(int i = 0; i < hitBoxDescNum; i++)
        {
            int cHitBoxDescOffset = hitBoxDescOffset + hitBoxDescLength * i;
            hitBoxSet[i] = readString(cHitBoxDescOffset + bytesToInt(file, cHitBoxDescOffset));
            hitBoxNum[i] = bytesToInt(file, cHitBoxDescOffset + hitBoxNumPos);
            hitBoxOffset[i] = bytesToInt(file, cHitBoxDescOffset + hitBoxOffsetPos);
            hitBoxes[i] = new HitBox[hitBoxNum[i]];
            int cHitBoxOffset = cHitBoxDescOffset + hitBoxOffset[i];
            for(int j = 0; j < hitBoxNum[i]; j++)
            {
                int cBone = bytesToInt(file, cHitBoxOffset);
                int cGroup = bytesToInt(file, cHitBoxOffset + 4);
                float cX1 = bytesToFloat(file, cHitBoxOffset + 8);
                float cY1 = bytesToFloat(file, cHitBoxOffset + 12);
                float cZ1 = bytesToFloat(file, cHitBoxOffset + 16);
                float cX2 = bytesToFloat(file, cHitBoxOffset + 20);
                float cY2 = bytesToFloat(file, cHitBoxOffset + 24);
                float cZ2 = bytesToFloat(file, cHitBoxOffset + 28);
                hitBoxes[i][j] = new HitBox((Bone)bones.get(cBone), cGroup, cX1, cY1, cZ1, cX2, cY2, cZ2);
                cHitBoxOffset += hitBoxLength;
            }

        }

    }

    public void readAnimations()
    {
        numberOfAnims = bytesToInt(file, numberOfAnimsOffset);
        animDescOffset = bytesToInt(file, animDescOffsetOffset);
        frames = new int[numberOfAnims];
        nodePoseOffset = new int[numberOfAnims][];
        animDataOffsets = new int[numberOfAnims][][];
        animations = new Animation[numberOfAnims];
        int cAnimDescOffset = animDescOffset;
        for(int i = 0; i < numberOfAnims; i++)
        {
            String cSeqName = readString(cAnimDescOffset + bytesToInt(file, cAnimDescOffset));
            float cFps = bytesToFloat(file, cAnimDescOffset + fpsPos);
            frames[i] = bytesToInt(file, cAnimDescOffset + framesPos);
            int cNodePoseOffset = cAnimDescOffset + bytesToInt(file, cAnimDescOffset + nodePosePos);
            nodePoseOffset[i] = new int[numberOfBones];
            animDataOffsets[i] = new int[numberOfBones][];
            animations[i] = new Animation(bones, orientation, frames[i], boneParams, cSeqName, cFps);
            for(int j = 0; j < numberOfBones; j++)
            {
                nodePoseOffset[i][j] = cNodePoseOffset + j * nodePoseLength;
                animDataOffsets[i][j] = new int[numOfSeqParameters];
                for(int k = 0; k < numOfSeqParameters; k++)
                {
                    int cParameter = bytesToInt(file, nodePoseOffset[i][j] + parameterLength * k + parameterPos);
                    if(cParameter != 0)
                        animDataOffsets[i][j][k] = nodePoseOffset[i][j] + cParameter;
                    else
                        animDataOffsets[i][j][k] = 0;
                    int cTNOFrames = 0;
                    int cSeqDataOffset = animDataOffsets[i][j][k];
                    while(cTNOFrames < frames[i]) 
                        if(cSeqDataOffset == 0)
                        {
                            animations[i].newSeqData(j, k, frames[i]);
                            animations[i].add(j, k, 0.0F);
                            cTNOFrames = frames[i];
                        } else
                        {
                            int cNOFrames = unsignedByteToInt(file[cSeqDataOffset]);
                            int cLength = unsignedByteToInt(file[cSeqDataOffset + nOFramesPos]);
                            animations[i].newSeqData(j, k, cLength);
                            cSeqDataOffset += frameDataDescLength;
                            for(int l = 0; l < cNOFrames; l++)
                            {
                                animations[i].add(j, k, animStepSize[j][k] * (float)bytesToShort(file, cSeqDataOffset));
                                cSeqDataOffset += frameDataLength;
                            }

                            cTNOFrames += cLength;
                        }
                }

            }

            cAnimDescOffset += animDescLength;
        }

        for(int i = 0; i < numberOfAnims; i++)
            animations[i].calcTimes();

    }

    private void readSequences()
    {
        numberOfSequences = bytesToInt(file, numberOfSequencesOffset);
        sequences = new Sequence[numberOfSequences];
        int cSeqOffset = bytesToInt(file, sequencesOffset);
        for(int i = 0; i < numberOfSequences; i++)
        {
            String cName = readString(cSeqOffset + bytesToInt(file, cSeqOffset));
            String cActivity = readString(cSeqOffset + bytesToInt(file, cSeqOffset + 4));
            int cAnimation = unsignedShortToInt(bytesToShort(file, cSeqOffset + animationPos));
            if(cAnimation >= animations.length)
                cAnimation = animations.length - 1;
            sequences[i] = new Sequence(cName, cActivity, animations[cAnimation]);
            cSeqOffset += sequencesLength;
        }

    }

    private void readFlexNames()
    {
        numberOfFlexNames = bytesToInt(file, numberOfFlexNamesOffset);
        flexNames = new String[numberOfFlexNames];
        flexNamesOffset = bytesToInt(file, flexNamesOffsetOffset);
        int cFlexOffsetOffset = flexNamesOffset;
        for(int i = 0; i < numberOfFlexNames; i++)
        {
            int cFlexOffset = bytesToInt(file, cFlexOffsetOffset) + cFlexOffsetOffset;
            flexNames[i] = readString(cFlexOffset);
            cFlexOffsetOffset += flexNamesSize;
        }

    }

    private void readFlexControllers()
    {
        numberOfFlexControllers = bytesToInt(file, numberOfFlexControllerOffset);
        flexControllerOffset = bytesToInt(file, flexControllerOffsetOffset);
        int cFlexOffset = flexControllerOffset;
        flexControllers = new FlexController[numberOfFlexControllers];
        for(int i = 0; i < numberOfFlexControllers; i++)
        {
            String cParent = readString(cFlexOffset + bytesToInt(file, cFlexOffset));
            String cController = readString(cFlexOffset + bytesToInt(file, cFlexOffset + 4));
            float cMin = bytesToFloat(file, cFlexOffset + 12);
            float cMax = bytesToFloat(file, cFlexOffset + 16);
            flexControllers[i] = new FlexController(cParent, cController, cMin, cMax);
            cFlexOffset += flexControllerLength;
        }

    }

    public void readFlexEquations()
    {
        readFlexNames();
        readFlexControllers();
        numberOfFlexEq = bytesToInt(file, numberOfFlexEqOffset);
        flexEqOffset = bytesToInt(file, flexEqOffsetOffset);
        int cFlexEqOffset = flexEqOffset;
        flexEq = new String[numberOfFlexEq];
        flexStacks = new StackVis[numberOfFlexEq];
        for(int i = 0; i < numberOfFlexEq; i++)
        {
            flexEq[i] = flexNames[bytesToInt(file, cFlexEqOffset)];
            int cLength = bytesToInt(file, cFlexEqOffset + 4);
            int cStackOffset = cFlexEqOffset + bytesToInt(file, cFlexEqOffset + 8);
            flexStacks[i] = new StackVis();
            for(int j = 0; j < cLength; j++)
            {
                switch(bytesToInt(file, cStackOffset))
                {
                case 1: // '\001'
                    flexStacks[i].push(bytesToFloat(file, cStackOffset + 4));
                    break;

                case 2: // '\002'
                    flexStacks[i].push(flexControllers[bytesToInt(file, cStackOffset + 4)].getController());
                    break;

                case 3: // '\003'
                    flexStacks[i].push(flexNames[bytesToInt(file, cStackOffset + 4)]);
                    break;

                case 4: // '\004'
                    flexStacks[i].push('+');
                    break;

                case 5: // '\005'
                    flexStacks[i].push('-');
                    break;

                case 6: // '\006'
                    flexStacks[i].push('*');
                    break;

                case 7: // '\007'
                    flexStacks[i].push(47F);
                    break;
                }
                cStackOffset += flexExpLength;
            }

            cFlexEqOffset += flexEqLength;
        }

    }

    public void readBlends()
    {
        blendsNumber = bytesToInt(file, blendsNumberOffset);
        blendsOffset = bytesToInt(file, blendsOffsetOffset);
        blends = new Blend[blendsNumber];
        int cOffset = blendsOffset;
        for(int i = 0; i < blendsNumber; i++)
        {
            String cName = readString(cOffset + bytesToInt(file, cOffset));
            int cCls = bytesToInt(file, cOffset + 4);
            float cMin = bytesToFloat(file, cOffset + 8);
            float cMax = bytesToFloat(file, cOffset + 12);
            float cLoop = bytesToFloat(file, cOffset + 16);
            blends[i] = new Blend(cName, cCls, cMin, cMax, cLoop);
            cOffset += blendSize;
        }

    }

    public void readSurfaceProp()
    {
        surfaceProp = readString(bytesToInt(file, surfacePropOffset));
    }

    public Vertex[] readVerticesType0(int numberOfVertices, int verticesOffset)
    {
        Vertex vertices[] = new Vertex[numberOfVertices];
        int cVertexOffset = verticesOffset;
        for(int i = 0; i < numberOfVertices; i++)
        {
            float weights[] = new float[3];
            int boneIndices[] = new int[3];
            weights[0] = byteToFraction(file, cVertexOffset);
            weights[1] = byteToFraction(file, cVertexOffset + 1);
            weights[2] = byteToFraction(file, cVertexOffset + 2);
            boneIndices[0] = unsignedShortToInt(bytesToShort(file, cVertexOffset + 4));
            boneIndices[1] = unsignedShortToInt(bytesToShort(file, cVertexOffset + 6));
            boneIndices[2] = unsignedShortToInt(bytesToShort(file, cVertexOffset + 8));
            Bone cParent = (Bone)bones.get(unsignedShortToInt(bytesToShort(file, cVertexOffset + 4)));
            float cPosX = bytesToFloat(file, cVertexOffset + 12);
            float cPosY = bytesToFloat(file, cVertexOffset + 16);
            float cPosZ = bytesToFloat(file, cVertexOffset + 20);
            float cNormX = bytesToFloat(file, cVertexOffset + 24);
            float cNormY = bytesToFloat(file, cVertexOffset + 28);
            float cNormZ = bytesToFloat(file, cVertexOffset + 32);
            float cTexU = bytesToFloat(file, cVertexOffset + 36);
            float cTexV = bytesToFloat(file, cVertexOffset + 40);
            vertices[i] = new Vertex(cParent, i, cPosX, cPosY, cPosZ, cNormX, cNormY, cNormZ, cTexU, cTexV, weights, boneIndices);
            cVertexOffset += vertexSize0;
        }

        return vertices;
    }

    public Vertex[] readVerticesType1(int numberOfVertices, int verticesOffset, float cPosX, float cPosY, float cPosZ, float cNormX, float cNormY, 
            float cNormZ)
    {
        Vertex vertices[] = new Vertex[numberOfVertices];
        for(int i = 0; i < numberOfVertices; i++)
        {
            int cVertexOffset = verticesOffset + i * vertexSize1;
            Bone cParent = (Bone)bones.get(0);
            float fracPosX = bytesToFraction(file, cVertexOffset);
            float fracPosY = bytesToFraction(file, cVertexOffset + 2);
            float fracPosZ = bytesToFraction(file, cVertexOffset + 4);
            float fracNormX = bytesToFraction(file, cVertexOffset + 6);
            float fracNormY = bytesToFraction(file, cVertexOffset + 8);
            float fracNormZ = bytesToFraction(file, cVertexOffset + 10);
            float cTexU = fracNormY;
            float cTexV = fracNormZ;
            vertices[i] = new Vertex(cParent, i, cPosX * fracPosX, cPosY * fracPosY, cPosZ * fracPosZ, cNormX * fracNormX, cNormY * fracNormY, cNormZ * fracNormZ, cTexU, cTexV, new float[0], new int[0]);
        }

        return vertices;
    }

    public Vertex[] readVerticesType2(int numberOfVertices, int verticesOffset, float cPosX, float cPosY, float cPosZ, float cNormX, float cNormY, 
            float cNormZ)
    {
        Vertex vertices[] = new Vertex[numberOfVertices];
        for(int i = 0; i < numberOfVertices; i++)
        {
            int cVertexOffset = verticesOffset + i * vertexSize2;
            Bone cParent = (Bone)bones.get(0);
            float fracPosX = byteToFraction(file, cVertexOffset + 0);
            float fracPosY = byteToFraction(file, cVertexOffset + 1);
            float fracPosZ = byteToFraction(file, cVertexOffset + 2);
            float fracNormX = byteToFraction(file, cVertexOffset + 3);
            float fracNormY = byteToFraction(file, cVertexOffset + 4);
            float fracNormZ = byteToFraction(file, cVertexOffset + 6);
            float cTexU = byteToFraction(file, cVertexOffset + 5);
            float cTexV = byteToFraction(file, cVertexOffset + 7);
            vertices[i] = new Vertex(cParent, i, cPosX * fracPosX, cPosY * fracPosY, cPosZ * fracPosZ, cNormX * fracNormX, cNormY * fracNormY, cNormZ * fracNormZ, cTexU, cTexV, new float[0], new int[0]);
        }

        return vertices;
    }

    public String getModelname()
    {
        return modelName;
    }

    public List getBones()
    {
        return bones;
    }

    public Vertex[][] getAllVertices()
    {
        return allVertices;
    }

    public List getPose()
    {
        return frame;
    }

    public String[] getHitBoxSets()
    {
        return hitBoxSet;
    }

    public HitBox[][] getHitBoxes()
    {
        return hitBoxes;
    }

    public String[] getMaterials()
    {
        return materials;
    }

    public int[][] getPartStart()
    {
        return partStart;
    }

    public float[] getFPS()
    {
        return fps;
    }

    public String getSurfaceProp()
    {
        return surfaceProp;
    }

    public String getModel()
    {
        return model;
    }

    public String[] getReferenceFilenames()
    {
        return refFilenames;
    }

    public Animation[] getAnimations()
    {
        return animations;
    }

    public Sequence[] getSequences()
    {
        return sequences;
    }

    public String[] getCDMaterials()
    {
        return cdMaterials;
    }

    public Attachment[] getAttachments()
    {
        return attachments;
    }

    public String[] getIncludeModels()
    {
        return includeModels;
    }

    public int getVertexType()
    {
        return vertexType;
    }

    public volatile int unsignedShortToInt(short x0)
    {
        return super.unsignedShortToInt(x0);
    }

    public volatile short bytesToShort(int x0)
    {
        return super.bytesToShort(x0);
    }

    public volatile int bytesToInt(int x0)
    {
        return super.bytesToInt(x0);
    }

    private int modelNameOffset;
    private String modelName;
    private int nOBOffset;
    private int numberOfBones;
    private int bonesOffsetOffset;
    private int bonesOffset;
    private int boneSize;
    private int parentBonePosition;
    private int animPSize;
    private int paramPos;
    private int animPPos;
    private int numberOfAnimsOffset;
    private int numberOfAnims;
    private int animDescOffsetOffset;
    private int animDescOffset;
    private int animDescLength;
    private float fps[];
    private int fpsPos;
    private int frames[];
    private int framesPos;
    private int nodePosePos;
    private int nodePoseOffset[][];
    private int nodePoseLength;
    private int animDataOffsets[][][];
    private int numOfSeqParameters;
    private int parameterLength;
    private int parameterPos;
    private Animation animations[];
    private int nOFramesPos;
    private int frameDataDescLength;
    private int frameDataLength;
    private int numberOfSequencesOffset;
    private int numberOfSequences;
    private int sequencesOffset;
    private int sequencesLength;
    private int animationPos;
    private Sequence sequences[];
    private String refFilenames[];
    private int maxStringLength;
    private int numberOfMaterialsOffset;
    private int numberOfMaterials;
    private int materialDescOffsetOffset;
    private int materialDescOffset;
    private int materialDescLength;
    private int numberOfCDMaterialsOffset;
    private int numberOfCDMaterials;
    private int cdMaterialsOffsetOffset;
    private int cdMaterialsOffset;
    private String cdMaterials[];
    private int numberOfAttachmentsOffset;
    private int numberOfAttachments;
    private int attachmentsOffsetOffset;
    private int attachmentsOffset;
    private int attachmentSize;
    private Attachment attachments[];
    private int numberOfEyesOffsetDelay;
    private int numberOfEyesOffset;
    private int numberOfEyes;
    private int eyesOffsetOffsetDelay;
    private int eyesOffsetOffset;
    private int eyesOffset;
    private int eyesSize;
    private int numberOfModelsOffset;
    private int numberOfModels;
    private int modelsOffsetOffset;
    private int modelsOffset;
    private int modelSize;
    private String model;
    private int numberOfFlexNamesOffset;
    private int numberOfFlexNames;
    private int flexNamesOffsetOffset;
    private int flexNamesOffset;
    private int flexNamesSize;
    private String flexNames[];
    private int numberOfFlexControllerOffset;
    private int numberOfFlexControllers;
    private int flexControllerOffsetOffset;
    private int flexControllerOffset;
    private int flexControllerLength;
    private FlexController flexControllers[];
    private int numberOfFlexEqOffset;
    private int numberOfFlexEq;
    private int flexEqOffsetOffset;
    private int flexEqOffset;
    private int flexEqLength;
    private int flexExpLength;
    private String flexEq[];
    private StackVis flexStacks[];
    private int numberOfPartsOffset;
    private int numberOfParts;
    private int numberOfPartsSize;
    private int partsDescOffsetOffset;
    private int partsDescOffset;
    private int partsDescOffsetSize;
    private int nOVOffset;
    private int nOVOffsetSize;
    private int nOVToFileType;
    private int refPrefaceOffset;
    private int refPrefaceSize;
    private int partDescSize;
    private int partOffsetDelay;
    private int vertexSize0;
    private int vertexSize1;
    private int vertexSize2;
    private int hitBoxDescNumOffset;
    private int hitBoxDescNum;
    private int hitBoxDescOffsetOffset;
    private int hitBoxDescOffset;
    private int hitBoxDescLength;
    private String hitBoxSet[];
    private int hitBoxNum[];
    private int hitBoxNumPos;
    private int hitBoxOffset[];
    private int hitBoxOffsetPos;
    private int hitBoxLength;
    private int blendsNumberOffset;
    private int blendsNumber;
    private int blendsOffsetOffset;
    private int blendsOffset;
    private int blendSize;
    private Blend blends[];
    private int surfacePropOffset;
    private String surfaceProp;
    private int numberOfIncludeModelsOffset;
    private int numberOfIncludeModels;
    private int includeModelsOffsetOffset;
    private int includeModelsOffset;
    private String includeModels[];
    private List bones;
    private List frame;
    private boolean orientation[];
    private float boneParams[][];
    private float animStepSize[][];
    private Vertex allVertices[][];
    private HitBox hitBoxes[][];
    private String materials[];
    private int partStart[][];
    private int vAnimDesc[][][];
    private int vertexTypeOffset;
    private int vertexType;
}
