コード例 #1
0
        // split VBE by stream
        public VertexElementDescriptor[][] SplitVBE(VertexElementDescriptor[] input)
        {
            VertexElementDescriptor[][] elements = new VertexElementDescriptor[2][];

            // pass 1
            byte[] sizes = new byte[2] {
                0, 0
            };
            for (int i = 0; i < input.Length; ++i)
            {
                sizes[input[i].stream] += 1;
            }

            // pass 2
            elements[0] = new VertexElementDescriptor[sizes[0]];
            elements[1] = new VertexElementDescriptor[sizes[1]];
            sizes       = new byte[2] {
                0, 0
            };
            for (int i = 0; i < input.Length; ++i)
            {
                byte stream = input[i].stream;
                elements[stream][sizes[stream]] = input[i];
                sizes[stream] += 1;
            }
            return(elements);
        }
コード例 #2
0
 public VertexElementDescriptor[] ParseVBE(BinaryReader reader, VertexBufferDescriptor descriptor)
 {
     reader.BaseStream.Position = descriptor.vertexElementDescriptorPointer;
     VertexElementDescriptor[] elements = new VertexElementDescriptor[descriptor.vertexElementDescriptorCount];
     for (int i = 0; i < descriptor.vertexElementDescriptorCount; ++i)
     {
         elements[i] = reader.Read <VertexElementDescriptor>();
     }
     return(elements);
 }
コード例 #3
0
        public void GenerateMeshes(BinaryReader reader)
        {
            // TODO
            for (int i = 0; i < Submeshes.Length; ++i)
            {
                SubmeshDescriptor      submesh = Submeshes[i];
                VertexBufferDescriptor vbo     = VertexBuffers[submesh.vertexBuffer];
                IndexBufferDescriptor  ibo     = IndexBuffers[submesh.indexBuffer];
                byte uvCount = GetMaxIndex(VertexElements[submesh.vertexBuffer], SemanticType.UV);

                #region IBO
                ModelIndice[] indices = new ModelIndice[submesh.indicesToDraw / 3];

                reader.BaseStream.Position = ibo.dataStreamPointer + submesh.indexStart * 2;
                List <ushort> indexTracker = new List <ushort>(submesh.verticesToDraw);
                for (int j = 0; j < submesh.indicesToDraw / 3; ++j)
                {
                    ModelIndice index = reader.Read <ModelIndice>();
                    int         v1    = indexTracker.IndexOf(index.v1);
                    if (v1 == -1)
                    {
                        v1 = indexTracker.Count;
                        indexTracker.Add(index.v1);
                    }

                    int v2 = indexTracker.IndexOf(index.v2);
                    if (v2 == -1)
                    {
                        v2 = indexTracker.Count;
                        indexTracker.Add(index.v2);
                    }

                    int v3 = indexTracker.IndexOf(index.v3);
                    if (v3 == -1)
                    {
                        v3 = indexTracker.Count;
                        indexTracker.Add(index.v3);
                    }

                    indices[j] = new ModelIndice {
                        v1 = (ushort)v1, v2 = (ushort)v2, v3 = (ushort)v3
                    };
                }
                Indices[i] = indices;
                #endregion

                #region UV Pre.
                ModelUV[][] uv = new ModelUV[uvCount][];
                for (int j = 0; j < uvCount; ++j)
                {
                    uv[j] = new ModelUV[submesh.verticesToDraw];
                }
                #endregion

                #region VBO
                ModelVertex[]   vertex = new ModelVertex[submesh.verticesToDraw];
                ModelBoneData[] bone   = new ModelBoneData[submesh.verticesToDraw];
                ModelVertex[]   normal = new ModelVertex[submesh.verticesToDraw];

                VertexElementDescriptor[][] elements = SplitVBE(VertexElements[submesh.vertexBuffer]);
                for (int j = 0; j < Stride[submesh.vertexBuffer].Length; ++j)
                {
                    for (int k = 0; k < submesh.verticesToDraw; ++k)
                    {
                        long offset = submesh.vertexStart + indexTracker[k];
                        for (int l = 0; l < elements[j].Length; ++l)
                        {
                            VertexElementDescriptor element = elements[j][l];
                            if (element.format == SemanticFormat.NONE)
                            {
                                break;
                            }
                            object value = Stride[submesh.vertexBuffer][j][offset][l];
                            switch (element.type)
                            {
                            case SemanticType.POSITION:
                                if (element.index == 0)
                                {
                                    float[] t = (float[])value;
                                    vertex[k] = new ModelVertex {
                                        x = t[0], y = t[1], z = t[2]
                                    };
                                }
                                else
                                {
                                    if (unhandledSemanticTypes.Add(element.type) && System.Diagnostics.Debugger.IsAttached)
                                    {
                                        System.Diagnostics.Debugger.Log(2, "CHUNK_LDOMMNRM",
                                                                        $"Unhandled vertex layer {element.index:X} for type {Util.GetEnumName(typeof(SemanticType), element.type)}!\n");
                                    }
                                }
                                break;

                            case SemanticType.NORMAL:
                                if (element.index == 0)
                                {
                                    float[] t = (float[])value;
                                    normal[k] = new ModelVertex {
                                        x = t[0], y = t[1], z = t[2]
                                    };
                                }
                                else
                                {
                                    if (unhandledSemanticTypes.Add(element.type) && System.Diagnostics.Debugger.IsAttached)
                                    {
                                        System.Diagnostics.Debugger.Log(2, "CHUNK_LDOMMNRM",
                                                                        $"Unhandled vertex layer {element.index:X} for type {Util.GetEnumName(typeof(SemanticType), element.type)}!\n");
                                    }
                                }
                                break;

                            case SemanticType.UV: {
                                ushort[] t = (ushort[])value;
                                uv[element.index][k] = new ModelUV {
                                    u = Half.ToHalf(t[0]), v = Half.ToHalf(t[1])
                                };
                            }
                            break;

                            case SemanticType.BONE_INDEX:
                                if (element.index == 0)
                                {
                                    byte[] t = (byte[])value;
                                    bone[k].boneIndex = new ushort[t.Length];
                                    for (int m = 0; m < t.Length; ++m)
                                    {
                                        bone[k].boneIndex[m] = (ushort)(t[m] + submesh.boneIdOffset);
                                    }
                                }
                                else
                                {
                                    if (unhandledSemanticTypes.Add(element.type) && System.Diagnostics.Debugger.IsAttached)
                                    {
                                        System.Diagnostics.Debugger.Log(2, "CHUNK_LDOMMNRM",
                                                                        $"Unhandled vertex layer {element.index:X} for type {Util.GetEnumName(typeof(SemanticType), element.type)}!\n");
                                    }
                                }
                                break;

                            case SemanticType.BONE_WEIGHT:
                                if (element.index == 0)
                                {
                                    bone[k].boneWeight = (float[])value;
                                }
                                else
                                {
                                    if (unhandledSemanticTypes.Add(element.type) && System.Diagnostics.Debugger.IsAttached)
                                    {
                                        System.Diagnostics.Debugger.Log(2, "CHUNK_LDOMMNRM",
                                                                        $"Unhandled vertex layer {element.index:X} for type {Util.GetEnumName(typeof(SemanticType), element.type)}!\n");
                                    }
                                }
                                break;

                            default:
                                if (unhandledSemanticTypes.Add(element.type) && System.Diagnostics.Debugger.IsAttached)
                                {
                                    System.Diagnostics.Debugger.Log(2, "CHUNK_LDOMMNRM",
                                                                    $"Unhandled vertex type {Util.GetEnumName(typeof(SemanticType), element.type)}!\n");
                                }
                                break;
                            }
                        }
                    }
                }

                indexTracker.Clear();

                TextureCoordinates[i] = uv;
                Vertices[i]           = vertex;
                Bones[i]   = bone;
                Normals[i] = normal;
                #endregion
            }
        }