Ejemplo n.º 1
0
        protected override bool OnLoad(Model model, File stream)
        {
            String fileID = stream.ReadFileID();

            if (fileID != "UMDL" && fileID != "UMD2")
            {
                Log.Error("Invalid model file");
                return(false);
            }

            bool hasVertexDeclarations = (fileID == "UMD2");

            int memoryUse = Unsafe.SizeOf <Model>();

            List <Buffer>     vertexBuffers_;
            List <Buffer>     indexBuffers_;
            List <Geometry[]> geometries_ = new List <Geometry[]>();

            VertexBufferDesc[]    loadVBData_;
            IndexBufferDesc[]     loadIBData_;
            List <GeometryDesc[]> loadGeometries_;

            // Read vertex buffers
            int numVertexBuffers = (int)stream.Read <uint>();

            vertexBuffers_ = new List <Buffer>();//[numVertexBuffers];
            vertexBuffers_.Resize(numVertexBuffers);
            var morphRangeStarts_ = new int[numVertexBuffers];
            var morphRangeCounts_ = new int[numVertexBuffers];

            loadVBData_ = new VertexBufferDesc[numVertexBuffers];
            var GeometryBoneMappings = new List <int[]>();
            var GeometryCenters      = new List <vec3>();

            for (int i = 0; i < numVertexBuffers; ++i)
            {
                loadVBData_[i].vertexCount_ = stream.Read <int>();
                uint vertexSize = 0;
                if (!hasVertexDeclarations)
                {
                    uint elementMask = stream.Read <uint>();
                    loadVBData_[i].layout = CreateVertexInputStateCreateInfo(elementMask, out vertexSize);
                }
                else
                {
                    /*
                     * enum VertexElementSemantic
                     * {
                     *  SEM_POSITION = 0,
                     *  SEM_NORMAL,
                     *  SEM_BINORMAL,
                     *  SEM_TANGENT,
                     *  SEM_TEXCOORD,
                     *  SEM_COLOR,
                     *  SEM_BLENDWEIGHTS,
                     *  SEM_BLENDINDICES,
                     *  SEM_OBJECTINDEX,
                     *  MAX_VERTEX_ELEMENT_SEMANTICS
                     * }*/

                    uint numElements = stream.Read <uint>();
                    FastList <VertexAttribute> attrs = new FastList <VertexAttribute>();
                    uint offset = 0;
                    for (uint j = 0; j < numElements; ++j)
                    {
                        uint elementDesc = stream.Read <uint>();
                        uint type        = (elementDesc & 0xff);
                        uint semantic    = ((elementDesc >> 8) & 0xff);
                        uint index       = ((elementDesc >> 16) & 0xff);

                        VertexAttribute attr = new VertexAttribute(0, j, semanticToFormat[semantic], offset);
                        offset += semanticSize[semantic];
                        attrs.Add(attr);
                    }

                    vertexSize = offset;
                    var layout = new VertexLayout(attrs.ToArray());
                    loadVBData_[i].layout = layout;
                    //layout.Print();
                }

                morphRangeStarts_[i]       = stream.Read <int>();
                morphRangeCounts_[i]       = stream.Read <int>();
                loadVBData_[i].vertexSize_ = (int)vertexSize;
                loadVBData_[i].dataSize_   = loadVBData_[i].vertexCount_ * (int)vertexSize;
                loadVBData_[i].data_       = stream.ReadArray <byte>(loadVBData_[i].dataSize_);
            }

            // Read index buffers
            int numIndexBuffers = (int)stream.Read <uint>();

            indexBuffers_ = new List <Buffer>();//[numIndexBuffers];
            indexBuffers_.Resize(numIndexBuffers);
            loadIBData_ = new IndexBufferDesc[numIndexBuffers];
            for (int i = 0; i < numIndexBuffers; ++i)
            {
                int indexCount = stream.Read <int>();
                int indexSize  = stream.Read <int>();

                loadIBData_[i].indexCount_ = indexCount;
                loadIBData_[i].indexSize_  = indexSize;
                loadIBData_[i].dataSize_   = indexCount * indexSize;
                loadIBData_[i].data_       = stream.ReadArray <byte>(loadIBData_[i].dataSize_);
            }

            // Read geometries
            int numGeometries = stream.Read <int>();

            loadGeometries_ = new List <GeometryDesc[]>(numGeometries);
            geometries_.Resize(numGeometries);

            for (int i = 0; i < numGeometries; ++i)
            {
                // Read bone mappings
                int   boneMappingCount = stream.Read <int>();
                int[] boneMapping      = new int[boneMappingCount];
                for (uint j = 0; j < boneMappingCount; ++j)
                {
                    boneMapping[j] = stream.Read <int>();
                }

                GeometryBoneMappings.Add(boneMapping);

                int            numLodLevels      = stream.Read <int>();
                Geometry[]     geometryLodLevels = new Geometry[numLodLevels];
                GeometryDesc[] deoDesc           = new GeometryDesc[numLodLevels];
                loadGeometries_.Add(deoDesc);
                for (int j = 0; j < numLodLevels; ++j)
                {
                    float distance = stream.Read <float>();

                    /*
                     *  public enum PrimitiveType : ushort
                     *  {
                     *      TRIANGLE_LIST = 0,
                     *      TRIANGLE_STRIP,
                     *      LINE_LIST,
                     *      LINE_STRIP,
                     *      POINT_LIST
                     *  }
                     */

                    VkPrimitiveTopology type = primitiveType2Topology[stream.Read <int>()];
                    int vbRef      = stream.Read <int>();
                    int ibRef      = stream.Read <int>();
                    int indexStart = stream.Read <int>();
                    int indexCount = stream.Read <int>();

                    if (vbRef >= vertexBuffers_.Count)
                    {
                        Log.Error("Vertex buffer index out of bounds");
                        loadVBData_ = null;
                        loadIBData_ = null;
                        loadGeometries_.Clear();
                        return(false);
                    }

                    if (ibRef >= indexBuffers_.Count)
                    {
                        Log.Error("Index buffer index out of bounds");
                        loadVBData_ = null;
                        loadIBData_ = null;
                        loadGeometries_.Clear();
                        return(false);
                    }

                    Geometry geometry = new Geometry();
                    geometry.LodDistance = distance;

                    // Prepare geometry to be defined during EndLoad()
                    deoDesc[j].primitiveTopology = type;
                    deoDesc[j].vbRef             = vbRef;
                    deoDesc[j].ibRef             = ibRef;
                    deoDesc[j].indexStart        = indexStart;
                    deoDesc[j].indexCount        = indexCount;

                    geometryLodLevels[j] = geometry;
                    memoryUse           += Unsafe.SizeOf <Geometry>();
                }

                geometries_[i] = geometryLodLevels;
            }

            // Read morphs
            uint numMorphs = stream.Read <uint>();
            var  morphs_   = new ModelMorph[(int)numMorphs];

            for (int i = 0; i < numMorphs; ++i)
            {
                morphs_[i].name_   = stream.ReadCString();
                morphs_[i].weight_ = 0.0f;
                uint numBuffers = stream.Read <uint>();

                for (int j = 0; j < numBuffers; ++j)
                {
                    VertexBufferMorph newBuffer;
                    int bufferIndex = stream.Read <int>();

                    newBuffer.elementMask_ = stream.Read <uint>();
                    newBuffer.vertexCount_ = stream.Read <int>();

                    // Base size: size of each vertex index
                    int vertexSize = sizeof(int);
                    // Add size of individual elements
                    unsafe
                    {
                        if ((newBuffer.elementMask_ & MASK_POSITION) != 0)
                        {
                            vertexSize += sizeof(vec3);
                        }
                        if ((newBuffer.elementMask_ & MASK_NORMAL) != 0)
                        {
                            vertexSize += sizeof(vec3);
                        }
                        if ((newBuffer.elementMask_ & MASK_TANGENT) != 0)
                        {
                            vertexSize += sizeof(vec3);
                        }
                    }

                    newBuffer.dataSize_              = newBuffer.vertexCount_ * (int)vertexSize;
                    newBuffer.morphData_             = stream.ReadArray <byte>((int)newBuffer.dataSize_);
                    morphs_[i].buffers_[bufferIndex] = newBuffer;
                    memoryUse += Unsafe.SizeOf <VertexBufferMorph>() + newBuffer.vertexCount_ * vertexSize;
                }

                memoryUse += Unsafe.SizeOf <ModelMorph>();
            }

            Skeleton skeleton_ = new Skeleton();

            // Read skeleton
            skeleton_.Load(stream);
            memoryUse += skeleton_.NumBones * Unsafe.SizeOf <Bone>();

            // Read bounding box
            var boundingBox_ = stream.Read <BoundingBox>();

            // Read geometry centers
            for (int i = 0; i < geometries_.Count && !stream.IsEof; ++i)
            {
                GeometryCenters.Add(stream.Read <vec3>());
            }
            while (GeometryCenters.Count < geometries_.Count)
            {
                GeometryCenters.Add(vec3.Zero);
            }

            model.VertexBuffers = vertexBuffers_;
            model.IndexBuffers  = indexBuffers_;

            model.Skeleton             = skeleton_;
            model.BoundingBox          = boundingBox_;
            model.Geometries           = geometries_;
            model.GeometryBoneMappings = GeometryBoneMappings;
            model.GeometryCenters      = GeometryCenters;
            //model.morphRangeStarts_ = morphRangeStarts_;
            //model.morphRangeCounts_ = morphRangeCounts_;
            model.MemoryUse = memoryUse;

            for (int i = 0; i < vertexBuffers_.Count; ++i)
            {
                ref VertexBufferDesc desc = ref loadVBData_[i];
                if (desc.data_ != null)
                {
                    vertexBuffers_[i] = Buffer.Create(VkBufferUsageFlags.VertexBuffer, false
                                                      , (uint)desc.vertexSize_, (uint)desc.vertexCount_, Utilities.AsPointer(ref desc.data_[0]));
                }
            }
Ejemplo n.º 2
0
 public override void Free(FastList <T> obj)
 {
     obj.Clear();
     Add(obj);
 }