public uint GetOrCreate( Dictionary <FaceVertex, uint> vertexMap, FastList <VertexPosTexNorm> vertices, FaceVertex key, FaceVertex adjacent1, FaceVertex adjacent2) { uint index; if (!vertexMap.TryGetValue(key, out index)) { VertexPosTexNorm vertex = ConstructVertex(key, adjacent1, adjacent2); vertices.Add(vertex); index = checked ((uint)(vertices.Count - 1)); vertexMap.Add(key, index); } return(index); }
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])); } }