| 260 | } |
| 261 | |
| 262 | bool Model::LoadHeader(ReadStream& stream, byte& headerVersion) |
| 263 | { |
| 264 | PROFILE_MEM(GraphicsMeshes); |
| 265 | if (ModelBase::LoadHeader(stream, headerVersion)) |
| 266 | return true; |
| 267 | |
| 268 | // LODs |
| 269 | byte lods = stream.ReadByte(); |
| 270 | if (lods == 0 || lods > MODEL_MAX_LODS) |
| 271 | return true; |
| 272 | LODs.Resize(lods); |
| 273 | _initialized = true; |
| 274 | for (int32 lodIndex = 0; lodIndex < lods; lodIndex++) |
| 275 | { |
| 276 | auto& lod = LODs[lodIndex]; |
| 277 | lod._model = this; |
| 278 | lod._lodIndex = lodIndex; |
| 279 | stream.ReadFloat(&lod.ScreenSize); |
| 280 | |
| 281 | // Meshes |
| 282 | uint16 meshesCount; |
| 283 | stream.ReadUint16(&meshesCount); |
| 284 | if (meshesCount > MODEL_MAX_MESHES) |
| 285 | return true; |
| 286 | ASSERT(lodIndex == 0 || LODs[0].Meshes.Count() >= meshesCount); |
| 287 | lod.Meshes.Resize(meshesCount, false); |
| 288 | for (uint16 meshIndex = 0; meshIndex < meshesCount; meshIndex++) |
| 289 | { |
| 290 | Mesh& mesh = lod.Meshes[meshIndex]; |
| 291 | mesh.Link(this, lodIndex, meshIndex); |
| 292 | |
| 293 | // Material Slot index |
| 294 | int32 materialSlotIndex; |
| 295 | stream.ReadInt32(&materialSlotIndex); |
| 296 | if (materialSlotIndex < 0 || materialSlotIndex >= MaterialSlots.Count()) |
| 297 | { |
| 298 | LOG(Warning, "Invalid material slot index {0} for mesh {1}. Slots count: {2}.", materialSlotIndex, meshIndex, MaterialSlots.Count()); |
| 299 | return true; |
| 300 | } |
| 301 | mesh.SetMaterialSlotIndex(materialSlotIndex); |
| 302 | |
| 303 | // Bounds |
| 304 | BoundingBox box; |
| 305 | stream.Read(box); |
| 306 | BoundingSphere sphere; |
| 307 | stream.Read(sphere); |
| 308 | mesh.SetBounds(box, sphere); |
| 309 | |
| 310 | // Lightmap UVs channel |
| 311 | int8 lightmapUVs; |
| 312 | stream.ReadInt8(&lightmapUVs); |
| 313 | mesh.LightmapUVsIndex = (int32)lightmapUVs; |
| 314 | } |
| 315 | } |
| 316 | |
| 317 | return stream.HasError(); |
| 318 | } |
| 319 | |