private void LoadModel(int EntryIndex)
    {
        if (EntryIndex < 0 || EntryIndex >= Result.ModelsPAK.Models.Count)
        {
            Debug.LogWarning("Asked to load model at index " + EntryIndex + ", which is out of bounds!");
            //return new GameObject();
            return;
        }

        alien_pak_model_entry ChunkArray = Result.ModelsPAK.Models[EntryIndex];

        for (int ChunkIndex = 0; ChunkIndex < ChunkArray.Header.ChunkCount; ++ChunkIndex)
        {
            int BINIndex = ChunkArray.ChunkInfos[ChunkIndex].BINIndex;
            alien_model_bin_model_info Model = Result.ModelsBIN.Models[BINIndex];
            //if (Model.BlockSize == 0) continue;

            alien_vertex_buffer_format VertexInput          = Result.ModelsBIN.VertexBufferFormats[Model.VertexFormatIndex];
            alien_vertex_buffer_format VertexInputLowDetail = Result.ModelsBIN.VertexBufferFormats[Model.VertexFormatIndexLowDetail];

            BinaryReader Stream = new BinaryReader(new MemoryStream(ChunkArray.Chunks[ChunkIndex]));

            List <List <alien_vertex_buffer_format_element> > Elements = new List <List <alien_vertex_buffer_format_element> >();
            alien_vertex_buffer_format_element ElementHeader           = new alien_vertex_buffer_format_element();
            foreach (alien_vertex_buffer_format_element Element in VertexInput.Elements)
            {
                if (Element.ArrayIndex == 0xFF)
                {
                    ElementHeader = Element;
                    continue;
                }

                while (Elements.Count - 1 < Element.ArrayIndex)
                {
                    Elements.Add(new List <alien_vertex_buffer_format_element>());
                }
                Elements[Element.ArrayIndex].Add(Element);
            }
            Elements.Add(new List <alien_vertex_buffer_format_element>()
            {
                ElementHeader
            });

            List <UInt16>  InIndices  = new List <UInt16>();
            List <Vector3> InVertices = new List <Vector3>();
            List <Vector3> InNormals  = new List <Vector3>();
            List <Vector4> InTangents = new List <Vector4>();
            List <Vector2> InUVs0     = new List <Vector2>();
            List <Vector2> InUVs1     = new List <Vector2>();
            List <Vector2> InUVs2     = new List <Vector2>();
            List <Vector2> InUVs3     = new List <Vector2>();
            List <Vector2> InUVs7     = new List <Vector2>();

            //TODO: implement skeleton lookup for the indexes
            List <Vector4> InBoneIndexes = new List <Vector4>(); //The indexes of 4 bones that affect each vertex
            List <Vector4> InBoneWeights = new List <Vector4>(); //The weights for each bone

            for (int VertexArrayIndex = 0; VertexArrayIndex < Elements.Count; ++VertexArrayIndex)
            {
                alien_vertex_buffer_format_element Inputs = Elements[VertexArrayIndex][0];
                if (Inputs.ArrayIndex == 0xFF)
                {
                    for (int i = 0; i < Model.IndexCount; i++)
                    {
                        InIndices.Add(Stream.ReadUInt16());
                    }
                }
                else
                {
                    for (int VertexIndex = 0; VertexIndex < Model.VertexCount; ++VertexIndex)
                    {
                        for (int ElementIndex = 0; ElementIndex < Elements[VertexArrayIndex].Count; ++ElementIndex)
                        {
                            alien_vertex_buffer_format_element Input = Elements[VertexArrayIndex][ElementIndex];
                            switch (Input.VariableType)
                            {
                            case alien_vertex_input_type.AlienVertexInputType_v3:
                            {
                                Vector3 Value = new Vector3(Stream.ReadSingle(), Stream.ReadSingle(), Stream.ReadSingle());
                                switch (Input.ShaderSlot)
                                {
                                case alien_vertex_input_slot.AlienVertexInputSlot_N:
                                    InNormals.Add(Value);
                                    break;

                                case alien_vertex_input_slot.AlienVertexInputSlot_T:
                                    InTangents.Add(new Vector4(Value.x, Value.y, Value.z, 0));
                                    break;

                                case alien_vertex_input_slot.AlienVertexInputSlot_UV:
                                    //TODO: 3D UVW
                                    break;
                                }
                                ;
                                break;
                            }

                            case alien_vertex_input_type.AlienVertexInputType_u32_C:
                            {
                                int Value = Stream.ReadInt32();
                                switch (Input.ShaderSlot)
                                {
                                case alien_vertex_input_slot.AlienVertexInputSlot_C:
                                    //??
                                    break;
                                }
                                break;
                            }

                            case alien_vertex_input_type.AlienVertexInputType_v4u8_i:
                            {
                                Vector4 Value = new Vector4(Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte());
                                switch (Input.ShaderSlot)
                                {
                                case alien_vertex_input_slot.AlienVertexInputSlot_BI:
                                    InBoneIndexes.Add(Value);
                                    break;
                                }
                                break;
                            }

                            case alien_vertex_input_type.AlienVertexInputType_v4u8_f:
                            {
                                Vector4 Value = new Vector4(Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte());
                                Value /= 255.0f;
                                switch (Input.ShaderSlot)
                                {
                                case alien_vertex_input_slot.AlienVertexInputSlot_BW:
                                    float Sum = Value.x + Value.y + Value.z + Value.w;
                                    InBoneWeights.Add(Value / Sum);
                                    break;

                                case alien_vertex_input_slot.AlienVertexInputSlot_UV:
                                    InUVs2.Add(new Vector2(Value.x, Value.y));
                                    InUVs3.Add(new Vector2(Value.z, Value.w));
                                    break;
                                }
                                break;
                            }

                            case alien_vertex_input_type.AlienVertexInputType_v2s16_UV:
                            {
                                Vector2 Value = new Vector2(Stream.ReadInt16(), Stream.ReadInt16());
                                Value /= 2048.0f;
                                switch (Input.ShaderSlot)
                                {
                                case alien_vertex_input_slot.AlienVertexInputSlot_UV:
                                    if (Input.VariantIndex == 0)
                                    {
                                        InUVs0.Add(Value);
                                    }
                                    else if (Input.VariantIndex == 1)
                                    {
                                        // TODO: We can figure this out based on alien_vertex_buffer_format_element.
                                        //Material->Material.Flags |= Material_HasTexCoord1;
                                        InUVs1.Add(Value);
                                    }
                                    else if (Input.VariantIndex == 2)
                                    {
                                        InUVs2.Add(Value);
                                    }
                                    else if (Input.VariantIndex == 3)
                                    {
                                        InUVs3.Add(Value);
                                    }
                                    else if (Input.VariantIndex == 7)
                                    {
                                        InUVs7.Add(Value);
                                    }
                                    break;
                                }
                                break;
                            }

                            case alien_vertex_input_type.AlienVertexInputType_v4s16_f:
                            {
                                Vector4 Value = new Vector4(Stream.ReadInt16(), Stream.ReadInt16(), Stream.ReadInt16(), Stream.ReadInt16());
                                Value /= (float)Int16.MaxValue;
                                switch (Input.ShaderSlot)
                                {
                                case alien_vertex_input_slot.AlienVertexInputSlot_P:
                                    InVertices.Add(Value);
                                    break;
                                }
                                break;
                            }

                            case alien_vertex_input_type.AlienVertexInputType_v4u8_NTB:
                            {
                                Vector4 Value = new Vector4(Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte());
                                Value /= (float)byte.MaxValue - 0.5f;
                                Value.Normalize();
                                switch (Input.ShaderSlot)
                                {
                                case alien_vertex_input_slot.AlienVertexInputSlot_N:
                                    InNormals.Add(Value);
                                    break;

                                case alien_vertex_input_slot.AlienVertexInputSlot_T:
                                    break;

                                case alien_vertex_input_slot.AlienVertexInputSlot_B:
                                    break;
                                }
                            }
                            break;
                            }
                        }
                    }
                }
                CATHODE.Utilities.Align(ref Stream, 16);
            }

            if (InVertices.Count == 0)
            {
                continue;
            }

            Mesh thisMesh = new Mesh();
            thisMesh.name = Result.ModelsBIN.ModelFilePaths[BINIndex] + ": " + Result.ModelsBIN.ModelLODPartNames[BINIndex];
            thisMesh.SetVertices(InVertices);
            thisMesh.SetNormals(InNormals);
            thisMesh.SetIndices(InIndices, MeshTopology.Triangles, 0); //0??
            thisMesh.SetTangents(InTangents);
            thisMesh.SetUVs(0, InUVs0);
            thisMesh.SetUVs(1, InUVs1);
            thisMesh.SetUVs(2, InUVs2);
            thisMesh.SetUVs(3, InUVs3);
            thisMesh.SetUVs(7, InUVs7);
            //thisMesh.SetBoneWeights(InBoneWeights.ToArray());
            thisMesh.RecalculateBounds();
            thisMesh.RecalculateNormals();
            thisMesh.RecalculateTangents();

            GameObjectHolder ThisModelPart = new GameObjectHolder();
            ThisModelPart.LocalScale      = new Vector3(Model.ScaleFactor, Model.ScaleFactor, Model.ScaleFactor);
            ThisModelPart.Name            = Result.ModelsBIN.ModelFilePaths[BINIndex] + ": " + Result.ModelsBIN.ModelLODPartNames[BINIndex] + " (" + Result.ModelsMTL.MaterialNames[Model.MaterialLibraryIndex] + ")";
            ThisModelPart.MainMesh        = thisMesh;
            ThisModelPart.DefaultMaterial = Model.MaterialLibraryIndex;
            LoadedModels[BINIndex]        = ThisModelPart;
        }
    }
Example #2
0
    private void LoadMeshAssets()
    {
        AssetDatabase.StartAssetEditing();
        for (int i = 0; i < levelData.ModelsPAK.Models.Count; i++)
        {
            alien_pak_model_entry ChunkArray = levelData.ModelsPAK.Models[i];
            for (int ChunkIndex = 0; ChunkIndex < ChunkArray.Header.ChunkCount; ++ChunkIndex)
            {
                int BINIndex = ChunkArray.ChunkInfos[ChunkIndex].BINIndex;
                alien_model_bin_model_info Model = levelData.ModelsBIN.Models[BINIndex];
                //if (Model.BlockSize == 0) continue;

                alien_vertex_buffer_format VertexInput          = levelData.ModelsBIN.VertexBufferFormats[Model.VertexFormatIndex];
                alien_vertex_buffer_format VertexInputLowDetail = levelData.ModelsBIN.VertexBufferFormats[Model.VertexFormatIndexLowDetail];

                BinaryReader Stream = new BinaryReader(new MemoryStream(ChunkArray.Chunks[ChunkIndex]));

                List <List <alien_vertex_buffer_format_element> > Elements = new List <List <alien_vertex_buffer_format_element> >();
                alien_vertex_buffer_format_element ElementHeader           = new alien_vertex_buffer_format_element();
                foreach (alien_vertex_buffer_format_element Element in VertexInput.Elements)
                {
                    if (Element.ArrayIndex == 0xFF)
                    {
                        ElementHeader = Element;
                        continue;
                    }

                    while (Elements.Count - 1 < Element.ArrayIndex)
                    {
                        Elements.Add(new List <alien_vertex_buffer_format_element>());
                    }
                    Elements[Element.ArrayIndex].Add(Element);
                }
                Elements.Add(new List <alien_vertex_buffer_format_element>()
                {
                    ElementHeader
                });

                List <UInt16>  InIndices  = new List <UInt16>();
                List <Vector3> InVertices = new List <Vector3>();
                List <Vector3> InNormals  = new List <Vector3>();
                List <Vector4> InTangents = new List <Vector4>();
                List <Vector2> InUVs0     = new List <Vector2>();
                List <Vector2> InUVs1     = new List <Vector2>();
                List <Vector2> InUVs2     = new List <Vector2>();
                List <Vector2> InUVs3     = new List <Vector2>();
                List <Vector2> InUVs7     = new List <Vector2>();

                //TODO: implement skeleton lookup for the indexes
                List <Vector4> InBoneIndexes = new List <Vector4>(); //The indexes of 4 bones that affect each vertex
                List <Vector4> InBoneWeights = new List <Vector4>(); //The weights for each bone

                for (int VertexArrayIndex = 0; VertexArrayIndex < Elements.Count; ++VertexArrayIndex)
                {
                    alien_vertex_buffer_format_element Inputs = Elements[VertexArrayIndex][0];
                    if (Inputs.ArrayIndex == 0xFF)
                    {
                        for (int x = 0; x < Model.IndexCount; x++)
                        {
                            InIndices.Add(Stream.ReadUInt16());
                        }
                    }
                    else
                    {
                        for (int VertexIndex = 0; VertexIndex < Model.VertexCount; ++VertexIndex)
                        {
                            for (int ElementIndex = 0; ElementIndex < Elements[VertexArrayIndex].Count; ++ElementIndex)
                            {
                                alien_vertex_buffer_format_element Input = Elements[VertexArrayIndex][ElementIndex];
                                switch (Input.VariableType)
                                {
                                case alien_vertex_input_type.AlienVertexInputType_v3:
                                {
                                    Vector3 Value = new Vector3(Stream.ReadSingle(), Stream.ReadSingle(), Stream.ReadSingle());
                                    switch (Input.ShaderSlot)
                                    {
                                    case alien_vertex_input_slot.AlienVertexInputSlot_N:
                                        InNormals.Add(Value);
                                        break;

                                    case alien_vertex_input_slot.AlienVertexInputSlot_T:
                                        InTangents.Add(new Vector4(Value.x, Value.y, Value.z, 0));
                                        break;

                                    case alien_vertex_input_slot.AlienVertexInputSlot_UV:
                                        //TODO: 3D UVW
                                        break;
                                    }
                                    ;
                                    break;
                                }

                                case alien_vertex_input_type.AlienVertexInputType_u32_C:
                                {
                                    int Value = Stream.ReadInt32();
                                    switch (Input.ShaderSlot)
                                    {
                                    case alien_vertex_input_slot.AlienVertexInputSlot_C:
                                        //??
                                        break;
                                    }
                                    break;
                                }

                                case alien_vertex_input_type.AlienVertexInputType_v4u8_i:
                                {
                                    Vector4 Value = new Vector4(Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte());
                                    switch (Input.ShaderSlot)
                                    {
                                    case alien_vertex_input_slot.AlienVertexInputSlot_BI:
                                        InBoneIndexes.Add(Value);
                                        break;
                                    }
                                    break;
                                }

                                case alien_vertex_input_type.AlienVertexInputType_v4u8_f:
                                {
                                    Vector4 Value = new Vector4(Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte());
                                    Value /= 255.0f;
                                    switch (Input.ShaderSlot)
                                    {
                                    case alien_vertex_input_slot.AlienVertexInputSlot_BW:
                                        float Sum = Value.x + Value.y + Value.z + Value.w;
                                        InBoneWeights.Add(Value / Sum);
                                        break;

                                    case alien_vertex_input_slot.AlienVertexInputSlot_UV:
                                        InUVs2.Add(new Vector2(Value.x, Value.y));
                                        InUVs3.Add(new Vector2(Value.z, Value.w));
                                        break;
                                    }
                                    break;
                                }

                                case alien_vertex_input_type.AlienVertexInputType_v2s16_UV:
                                {
                                    Vector2 Value = new Vector2(Stream.ReadInt16(), Stream.ReadInt16());
                                    Value /= 2048.0f;
                                    switch (Input.ShaderSlot)
                                    {
                                    case alien_vertex_input_slot.AlienVertexInputSlot_UV:
                                        if (Input.VariantIndex == 0)
                                        {
                                            InUVs0.Add(Value);
                                        }
                                        else if (Input.VariantIndex == 1)
                                        {
                                            // TODO: We can figure this out based on alien_vertex_buffer_format_element.
                                            //Material->Material.Flags |= Material_HasTexCoord1;
                                            InUVs1.Add(Value);
                                        }
                                        else if (Input.VariantIndex == 2)
                                        {
                                            InUVs2.Add(Value);
                                        }
                                        else if (Input.VariantIndex == 3)
                                        {
                                            InUVs3.Add(Value);
                                        }
                                        else if (Input.VariantIndex == 7)
                                        {
                                            InUVs7.Add(Value);
                                        }
                                        break;
                                    }
                                    break;
                                }

                                case alien_vertex_input_type.AlienVertexInputType_v4s16_f:
                                {
                                    Vector4 Value = new Vector4(Stream.ReadInt16(), Stream.ReadInt16(), Stream.ReadInt16(), Stream.ReadInt16());
                                    Value /= (float)Int16.MaxValue;
                                    switch (Input.ShaderSlot)
                                    {
                                    case alien_vertex_input_slot.AlienVertexInputSlot_P:
                                        InVertices.Add(Value);
                                        break;
                                    }
                                    break;
                                }

                                case alien_vertex_input_type.AlienVertexInputType_v4u8_NTB:
                                {
                                    Vector4 Value = new Vector4(Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte(), Stream.ReadByte());
                                    Value /= (float)byte.MaxValue - 0.5f;
                                    Value.Normalize();
                                    switch (Input.ShaderSlot)
                                    {
                                    case alien_vertex_input_slot.AlienVertexInputSlot_N:
                                        InNormals.Add(Value);
                                        break;

                                    case alien_vertex_input_slot.AlienVertexInputSlot_T:
                                        break;

                                    case alien_vertex_input_slot.AlienVertexInputSlot_B:
                                        break;
                                    }
                                }
                                break;
                                }
                            }
                        }
                    }
                    CATHODE.Utilities.Align(ref Stream, 16);
                }

                if (InVertices.Count == 0)
                {
                    continue;
                }

                Mesh thisMesh = new Mesh();
                thisMesh.name = levelData.ModelsBIN.ModelFilePaths[BINIndex] + ": " + levelData.ModelsBIN.ModelLODPartNames[BINIndex];
                thisMesh.SetVertices(InVertices);
                thisMesh.SetNormals(InNormals);
                thisMesh.SetIndices(InIndices, MeshTopology.Triangles, 0); //0??
                thisMesh.SetTangents(InTangents);
                thisMesh.SetUVs(0, InUVs0);
                thisMesh.SetUVs(1, InUVs1);
                thisMesh.SetUVs(2, InUVs2);
                thisMesh.SetUVs(3, InUVs3);
                thisMesh.SetUVs(7, InUVs7);
                //thisMesh.SetBoneWeights(InBoneWeights.ToArray());
                thisMesh.RecalculateBounds();
                thisMesh.RecalculateNormals();
                thisMesh.RecalculateTangents();

                //TODO: do this as proper submeshes
                string fullFilePath  = "Assets/Resources/" + SharedVals.instance.LevelName + "/Meshes/" + levelData.ModelsBIN.ModelFilePaths[BINIndex] + "_" + levelData.ModelsBIN.ModelLODPartNames[BINIndex] + "_" + ChunkIndex + ".asset";
                string fileDirectory = GetDirectory(fullFilePath);
                if (!Directory.Exists(fileDirectory))
                {
                    Directory.CreateDirectory(fileDirectory);
                }
                AssetDatabase.CreateAsset(thisMesh, fullFilePath);
            }
        }
        AssetDatabase.StopAssetEditing();
    }