1 /* 2 * OpenClonk, http://www.openclonk.org 3 * 4 * Copyright (c) 2010-2016, The OpenClonk Team and contributors 5 * 6 * Distributed under the terms of the ISC license; see accompanying file 7 * "COPYING" for details. 8 * 9 * "Clonk" is a registered trademark of Matthes Bender, used with permission. 10 * See accompanying file "TRADEMARK" for details. 11 * 12 * To redistribute this file separately, substitute the full license texts 13 * for the above references. 14 */ 15 16 #ifndef INC_StdMeshLoaderChunks 17 #define INC_StdMeshLoaderChunks 18 19 #include "lib/StdMesh.h" 20 #include "lib/StdMeshLoaderDataStream.h" 21 22 // ==== Ogre file format ==== 23 // The Ogre file format is a chunked format similar to PNG. 24 // Each chunk except for the file header (type 0x1000) has the following format: 25 // uint32_t chunk_type, values dependent on file type (mesh or skeleton) 26 // uint32_t chunk_length, in bytes; includes the size of the header 27 // uint8_t data[] 28 // The file header omits the length field. 29 // Ogre files can be stored in either big-endian or little-endian byte order. The 30 // byte order is determined by the first two bytes in the file, which must always 31 // be the chunk type of the file header (0x1000). If the bytes are 0x00 0x10, the 32 // file is assumed to be little-endian, if they are 0x10 0x00, the file is big- 33 // endian. If any other bytes are encountered, the file is invalid. 34 // This implementation only reads files stored in the platform's native byte order. 35 // 36 // ==== Data types ==== 37 // Most of the numeric data is stored directly in binary as a memory representation. 38 // Strings are stored without a leading length field, and terminated by a 0x0A byte. 39 // Boolean fields are stored as a single byte, which is 0x00 for false or anything 40 // else for true. 41 // 42 // ==== Mesh chunks ==== 43 // Unless specified, this section will only describe the data part of each chunk. 44 // Any values that are in parentheses are not available in this implementation. 45 // 46 // Type 0x1000: File Header 47 // string version 48 // Depending on the version, different features are enabled or disabled while 49 // loading the file. 50 // This implementation does not support fallback to different versions of the 51 // file format. 52 // This chunk does not contain a length field; the type id is directly followed 53 // by the version string. 54 // The file header must be immediately followed by a 0x3000 Mesh Data chunk. 55 // ---------- 56 // Type 0x3000: Mesh Data 57 // bool skeletal_animation 58 // This field is only used by Ogre to optimize rendering. Set if the mesh has 59 // animation data associated with it. 60 // Allowed subchunks: 61 // 0x4000 Submesh Data 62 // 0x5000 Geometry Data (may occur at most once) 63 // 0x6000 Skeleton Link (may occur at most once) 64 // 0x7000 Mesh Bone Assignments 65 // (0x8000 Precomputed Level of Detail Data) 66 // 0x9000 Mesh Boundaries 67 // (0xA000 Submesh Name Table) 68 // (0xB000 Edge List) 69 // (0xC000 Animation Poses) 70 // (0xD000 Animation List) 71 // (0xE000 Table of Extremes) 72 // ---------- 73 // Type 0x4000: Submesh data 74 // string material 75 // The name of a material to be used for this submesh. Must be loaded externally. 76 // bool vertices_shared 77 // If set, the submesh uses the geometry data of its parent mesh. In this case, the 78 // submesh may not contain its own 0x5000 Geometry Data chunk. 79 // uint32_t index_count 80 // The number of vertex indices used by this submesh. 81 // bool indices_are_32_bit 82 // If set, each vertex index is 32 bits wide. If unset, each vertex index is 16 bits 83 // wide. 84 // uint16_t/uint32_t indices[index_count] 85 // A list of vertex indices used by this submesh. 86 // Allowed subchunks: 87 // 0x5000 Geometry Data (only if vertices_shared == false) 88 // 0x4010 Submesh Operation 89 // 0x4100 Submesh Bone Assignments 90 // (0x4200 Submesh Texture Replacement) 91 // If no 0x4010 Submesh Operation chunk is present, the submesh uses SO_TriList. 92 // ---------- 93 // Type 0x4010: Submesh Operation 94 // uint16_t operation 95 // This value specifies how the indices of a submesh are to be interpreted. 96 // Acceptable values: 97 // (0x01 SO_PointList) 98 // Each index defines a single point. 99 // (0x02 SO_LineList) 100 // Each pair (2k, 2k+1) of indices defines a line. 101 // (0x03 SO_LineStrip) 102 // Each pair (k, k+1) of indices defines a line. 103 // 0x04 SO_TriList 104 // Each triplet (3k, 3k+1, 3k+2) of indices defines a triangle. 105 // (0x05 SO_TriStrip) 106 // For odd k, (k, k+1, k+2) define a triangle. For even k, (k+1, k, k+2) define a triangle. 107 // (0x06 SO_TriFan) 108 // Indices (1, k+1, k+2) define a triangle. 109 // ---------- 110 // Type 0x4100: Submesh Bone Assignments 111 // Type 0x7000: Mesh Bone Assignments 112 // uint32_t vertex_index 113 // uint32_t bone_index 114 // float weight 115 // This defines the strength of the influence a bone has on a vertex. The sum of 116 // the weights on each vertex is not guaranteed to be 1.0. 117 // These values repeat until the size of the chunk is exhausted. 118 // ---------- 119 // Type 0x5000: Geometry Data 120 // uint32_t vertex_count 121 // The number of vertices stored in each contained 0x5020 Vertex Buffer chunk. 122 // Allowed subchunks: 123 // 0x5100 Vertex Declaration (required; must occur exactly once) 124 // 0x5200 Vertex Buffer (required; must occur at least once) 125 // ---------- 126 // Type 0x5100 Vertex Declaration 127 // This chunk does not store any values itself. It only acts as a container for 128 // 0x5110 Vertex Declaration Element chunks. 129 // Allowed subchunks: 130 // 0x5110 Vertex Declaration Element (required; repeats until the size of the chunk is exhausted) 131 // ---------- 132 // Type 0x5110 Vertex Declaration Element 133 // uint16_t source 134 // The index of the stream where this element is found. 135 // uint16_t type 136 // The type of data this element contains. 137 // Acceptable values: 138 // 0x00 VDET_Float1 139 // A single 32-bit float, expanded to (a, 0, 0, 1) 140 // 0x01 VDET_Float2 141 // Two 32-bit floats, expanded to (a, b, 0, 1) 142 // 0x02 VDET_Float3 143 // Three 32-bit floats, expanded to (a, b, c, 1) 144 // 0x03 VDET_Float4 145 // Four 32-bit floats 146 // (0x04 VDET_Reserved) 147 // (0x05 VDET_Short1) 148 // A single 16-bit integer 149 // (0x06 VDET_Short2) 150 // Two 16-bit integers 151 // (0x07 VDET_Short3) 152 // Three 16-bit integers 153 // (0x08 VDET_Short4) 154 // Four 16-bit integers 155 // (0x09 VDET_UByte4) 156 // Four 8-bit integers 157 // 0x0A VDET_Color_ARGB 158 // Four 8-bit integers, describing a color in the order Alpha, Red, Green, Blue. 159 // Acceptable values range from 0 to 255. 160 // 0x0B VDET_Color_ABGR 161 // Four 8-bit integers, describing a color in the order Alpha, Blue, Green, Red. 162 // Acceptable values range from 0 to 255. 163 // uint16_t semantic 164 // The semantic of the data this element contains. 165 // Acceptable values: 166 // 0x01 VDES_Position 167 // The element contains the vertex's position in world space. 168 // (0x02 VDES_Blend_Weights) 169 // (0x03 VDES_Blend_Indices) 170 // 0x04 VDES_Normals 171 // The element contains vertex normals. 172 // (0x05 VDES_Diffuse) 173 // The element contains the diffuse color of the vertex. 174 // (0x06 VDES_Specular) 175 // The element contains the specular color of the vertex. 176 // 0x07 VDES_Texcoords 177 // The element contains the texture coordinates of the vertex. 178 // uint16_t offset 179 // The element's offset in bytes from the beginning of the stream. 180 // uint16_t index 181 // Index of the element semantic. Used with colors and texture coordinates. 182 // ---------- 183 // 0x5200 Vertex Buffer 184 // uint16_t index 185 // The index of the stream this buffer will get bound to. 186 // uint16_t stride 187 // The distance in bytes between two elements inside the buffer. 188 // Allowed subchunks: 189 // 0x5210 Vertex Buffer Data (required; must occur exactly once) 190 // ---------- 191 // 0x5210 Vertex Buffer Data 192 // uint8_t data[] 193 // The buffered data. This field spans the whole extent of the chunk. 194 // ---------- 195 // 0x6000 Skeleton Link 196 // string file 197 // The name of the file that contains the skeleton of this mesh. 198 // ---------- 199 // 0x9000 Mesh Boundaries 200 // float min[3] 201 // The minimum extents of the axis-aligned bounding box of the mesh. 202 // float max[3] 203 // The maximum extents of the axis-aligned bounding box of the mesh. 204 // float radius 205 // The radius of the minimal enclosing sphere of the mesh. 206 // 207 // ==== Skeleton files ==== 208 // Each skeleton file must begin with a 0x1000 File Header chunk. Afterwards, 209 // any combination of the following chunks may appear: 210 // 0x2000 Bone Data 211 // 0x3000 Bone Hierarchy 212 // 0x4000 Animation 213 // (0x5000 Animation Link) 214 // 215 // Unless specified, this section will only describe the data part of each chunk. 216 // Any values that are in parentheses are not available in this implementation. 217 // 218 // Type 0x1000: File Header 219 // string version 220 // Depending on the version, different features are enabled or disabled while 221 // loading the file. 222 // This implementation does not support fallback to different versions of the 223 // file format. 224 // This chunk does not contain a length field; the type id is directly followed 225 // by the version string. 226 // ---------- 227 // Type 0x2000: Bone Data 228 // string name 229 // The name of the bone. This is only used to produce human-readable output. 230 // uint16_t handle 231 // The internal handle of the bone. All other chunks that refer to a bone reference 232 // this. 233 // float position[3] 234 // The position of the bone, relative to its parent. 235 // float orientation[4] 236 // The orientation of the bone, as a quaternion (x,y,z,w). Relative to the parent. 237 // float scale[3] 238 // The scale of the bone, relative to its parent. This element only appears if the 239 // chunk size is large enough; if it is omitted, it defaults to (1,1,1). 240 // ---------- 241 // Type 0x3000 Bone Hierarchy 242 // uint16_t child 243 // The handle of the parent bone. 244 // uint16_t parent 245 // The handle of the parent bone. 246 // ---------- 247 // Type 0x4000 Animation 248 // string name 249 // The name of this animation. 250 // float duration 251 // The length of this animation, in seconds. 252 // Allowed subchunks: 253 // 0x4100 Animation Track 254 // ---------- 255 // Type 0x4100 Animation Track 256 // uint16_t bone 257 // The handle of the bone this track belongs to. 258 // Allowed subchunks: 259 // 0x4110 Animation Track Keyframe 260 // ---------- 261 // Type 0x4110 Animation Track Keyframe 262 // float time 263 // The time this keyframe matches. 264 // float rotation[4] 265 // The rotation of the bone at the corresponding time, as a quaternion (x,y,z,w). 266 // float translation[3] 267 // The translation of the bone at the corresponding time. 268 // float scale[3] 269 // The scale of the bone at the time of the keyframe. This element only appears if the 270 // chunk size is large enough; if it is omitted, it defaults to (1,1,1). 271 272 // Most of the chunk classes below faithfully match the abovementioned file format. 273 namespace Ogre 274 { 275 // used to have boost::ptr_vector. Behaves reasonably similar 276 template<typename T> 277 using unique_ptr_vector = std::vector<std::unique_ptr<T>>; 278 279 class DataStream; 280 template<class _Type> 281 class ChunkBase 282 { 283 protected: ChunkBase()284 ChunkBase() : type(static_cast<Type>(0)) {} 285 virtual void ReadImpl(DataStream *stream) = 0; 286 typedef _Type Type; 287 Type type; 288 size_t size; 289 public: 290 virtual ~ChunkBase() = default; GetType()291 Type GetType() const { return type; } GetSize()292 size_t GetSize() const { return size; } 293 294 static const size_t ChunkHeaderLength = sizeof(uint16_t) /* chunk type */ + sizeof(uint32_t) /* chunk length */; Peek(const DataStream * stream)295 static Type Peek(const DataStream *stream) 296 { 297 return static_cast<Type>(stream->Peek<uint16_t>()); 298 } 299 }; 300 301 namespace Mesh 302 { 303 enum ChunkID 304 { 305 CID_Invalid = 0, 306 CID_Header = 0x1000, 307 CID_Mesh = 0x3000, 308 CID_Submesh = 0x4000, 309 CID_Submesh_Op = 0x4010, 310 CID_Submesh_Bone_Assignment = 0x4100, 311 CID_Submesh_Texture_Alias = 0x4200, 312 CID_Geometry = 0x5000, 313 CID_Geometry_Vertex_Decl = 0x5100, 314 CID_Geometry_Vertex_Decl_Element = 0x5110, 315 CID_Geometry_Vertex_Buffer = 0x5200, 316 CID_Geometry_Vertex_Data = 0x5210, 317 CID_Mesh_Skeleton_Link = 0x6000, 318 CID_Mesh_Bone_Assignment = 0x7000, 319 CID_Mesh_LOD = 0x8000, 320 CID_Mesh_LOD_Usage = 0x8100, 321 CID_Mesh_LOD_Manual = 0x8110, 322 CID_Mesh_LOD_Generated = 0x8120, 323 CID_Mesh_Bounds = 0x9000, 324 CID_Submesh_Name_Table = 0xA000, 325 CID_Submesh_Name_Table_Entry = 0xA100, 326 CID_Edge_List = 0xB000, 327 CID_Edge_List_LOD = 0xB100, 328 CID_Edge_Group = 0xB110, 329 CID_Pose_List = 0xC000, 330 CID_Pose = 0xC100, 331 CID_Pose_Vertex = 0xC111, 332 CID_Animation_List = 0xD000, 333 CID_Animation = 0xD100, 334 CID_Animation_Track = 0xD110, 335 CID_Animation_Morph_Keyframe = 0xD111, 336 CID_Animation_Pose_Keyframe = 0xD112, 337 CID_Animation_Pose_Ref = 0xD113, 338 CID_Table_Extremes = 0xE000 339 }; 340 341 struct BoneAssignment 342 { 343 uint32_t vertex; 344 uint32_t bone; 345 float weight; 346 }; 347 348 class Chunk : public ChunkBase<ChunkID> 349 { 350 public: 351 static std::unique_ptr<Chunk> Read(DataStream *stream); 352 }; 353 354 class ChunkUnknown; class 355 ChunkFileHeader; 356 class ChunkMesh; class ChunkMeshSkeletonLink; class ChunkMeshBoneAssignments; class ChunkMeshBounds; 357 class ChunkSubmesh; class ChunkSubmeshOp; 358 class ChunkGeometry; class ChunkGeometryVertexDecl; class ChunkGeometryVertexDeclElement; class ChunkGeometryVertexBuffer; class ChunkGeometryVertexData; 359 class ChunkPoseList; class ChunkPose; class ChunkPoseVertex; 360 class ChunkAnimationList; class ChunkAnimation; class ChunkAnimationTrack; 361 class ChunkAnimationMorphKF; class ChunkAnimationPoseKF; class ChunkAnimationPoseRef; 362 363 class ChunkUnknown : public Chunk 364 { 365 protected: 366 void ReadImpl(DataStream *stream) override; 367 }; 368 369 class ChunkFileHeader : public Chunk 370 { 371 typedef std::map<std::string, uint32_t> VersionTable_t; 372 static const VersionTable_t VersionTable; 373 static const uint32_t CurrentVersion; 374 public: 375 std::string version; 376 377 protected: 378 void ReadImpl(DataStream *stream) override; 379 }; 380 381 class ChunkMesh : public Chunk 382 { 383 public: 384 ChunkMesh() = default; 385 bool hasAnimatedSkeleton{false}; 386 std::string skeletonFile; 387 std::unique_ptr<ChunkGeometry> geometry; 388 unique_ptr_vector<ChunkSubmesh> submeshes; 389 std::vector<BoneAssignment> boneAssignments; 390 StdMeshBox bounds; 391 float radius{0.0f}; 392 393 protected: 394 void ReadImpl(DataStream *stream) override; 395 }; 396 397 class ChunkMeshSkeletonLink : public Chunk 398 { 399 public: 400 std::string skeleton; 401 protected: 402 void ReadImpl(DataStream *stream) override; 403 }; 404 405 class ChunkSubmesh : public Chunk 406 { 407 public: 408 ChunkSubmesh() = default; 409 std::string material; 410 bool hasSharedVertices; 411 std::vector<size_t> faceVertices; 412 std::unique_ptr<ChunkGeometry> geometry; 413 enum SubmeshOperation 414 { 415 SO_PointList = 1, 416 SO_LineList = 2, 417 SO_LineStrip = 3, 418 SO_TriList = 4, 419 SO_TriStrip = 5, 420 SO_TriFan = 6, 421 SO_MIN = SO_PointList, 422 SO_MAX = SO_TriFan 423 } operation{SO_TriList}; 424 std::vector<BoneAssignment> boneAssignments; 425 protected: 426 void ReadImpl(DataStream *stream) override; 427 }; 428 429 class ChunkSubmeshOp : public Chunk 430 { 431 public: 432 ChunkSubmesh::SubmeshOperation operation; 433 protected: 434 void ReadImpl(DataStream *stream) override; 435 }; 436 437 class ChunkMeshBoneAssignments : public Chunk 438 { 439 public: 440 std::vector<BoneAssignment> assignments; 441 protected: 442 void ReadImpl(DataStream *stream) override; 443 }; 444 445 class ChunkMeshBounds : public Chunk 446 { 447 public: 448 StdMeshBox bounds; 449 float radius; 450 protected: 451 void ReadImpl(DataStream *stream) override; 452 }; 453 454 class ChunkGeometry : public Chunk 455 { 456 public: 457 size_t vertexCount; 458 unique_ptr_vector<ChunkGeometryVertexDeclElement> vertexDeclaration; 459 unique_ptr_vector<ChunkGeometryVertexBuffer> vertexBuffers; 460 protected: 461 void ReadImpl(DataStream *stream) override; 462 }; 463 464 class ChunkGeometryVertexDecl : public Chunk 465 { 466 public: 467 unique_ptr_vector<ChunkGeometryVertexDeclElement> declaration; 468 protected: 469 void ReadImpl(DataStream *stream) override; 470 }; 471 472 class ChunkGeometryVertexDeclElement : public Chunk 473 { 474 public: 475 uint16_t source; 476 uint16_t offset; 477 enum Type 478 { 479 VDET_Float1 = 0, 480 VDET_Float2 = 1, 481 VDET_Float3 = 2, 482 VDET_Float4 = 3, 483 /* 4 omitted intentionally */ 484 VDET_Short1 = 5, 485 VDET_Short2 = 6, 486 VDET_Short3 = 7, 487 VDET_Short4 = 8, 488 VDET_UByte4 = 9, 489 VDET_Color_ARGB = 10, 490 VDET_Color_ABGR = 11, 491 VDET_MIN = VDET_Float1, 492 VDET_MAX = VDET_Color_ABGR 493 } type; 494 enum Semantic 495 { 496 VDES_Position = 1, 497 VDES_Blend_Weights = 2, 498 VDES_Blend_Indices = 3, 499 VDES_Normals = 4, 500 VDES_Diffuse = 5, 501 VDES_Specular = 6, 502 VDES_Texcoords = 7, 503 VDES_Binormal = 8, 504 VDES_Tangent = 9, 505 VDES_MIN = VDES_Position, 506 VDES_MAX = VDES_Tangent 507 } semantic; 508 uint16_t index; 509 protected: 510 void ReadImpl(DataStream *stream) override; 511 }; 512 513 class ChunkGeometryVertexBuffer : public Chunk 514 { 515 public: 516 uint16_t index; 517 uint16_t vertexSize; 518 std::unique_ptr<ChunkGeometryVertexData> data; 519 protected: 520 void ReadImpl(DataStream *stream) override; 521 }; 522 523 class ChunkGeometryVertexData : public Chunk 524 { 525 public: 526 ChunkGeometryVertexData() = default; ~ChunkGeometryVertexData()527 ~ChunkGeometryVertexData() override { delete[] static_cast<char*>(data); } 528 void *data{nullptr}; 529 protected: 530 void ReadImpl(DataStream *stream) override; 531 }; 532 } 533 534 namespace Skeleton 535 { 536 enum ChunkID 537 { 538 CID_Invalid = 0, 539 CID_Header = 0x1000, 540 CID_BlendMode= 0x1010, 541 CID_Bone = 0x2000, 542 CID_Bone_Parent = 0x3000, 543 CID_Animation = 0x4000, 544 CID_Animation_BaseInfo = 0x4010, 545 CID_Animation_Track = 0x4100, 546 CID_Animation_Track_KF = 0x4110, 547 CID_Animation_Link = 0x5000 548 }; 549 550 class Chunk : public ChunkBase<ChunkID> 551 { 552 public: 553 static std::unique_ptr<Chunk> Read(DataStream *stream); 554 }; 555 556 class ChunkUnknown; class ChunkFileHeader; 557 class ChunkBone; class ChunkBoneParent; 558 class ChunkAnimation; class ChunkAnimationTrack; class ChunkAnimationTrackKF; class ChunkAnimationLink; 559 560 class ChunkUnknown : public Chunk 561 { 562 protected: 563 void ReadImpl(DataStream *stream) override; 564 }; 565 566 class ChunkFileHeader : public Chunk 567 { 568 typedef std::map<std::string, uint32_t> VersionTable_t; 569 static const VersionTable_t VersionTable; 570 static const uint32_t CurrentVersion; 571 public: 572 std::string version; 573 574 protected: 575 void ReadImpl(DataStream *stream) override; 576 }; 577 578 class ChunkBlendMode : public Chunk 579 { 580 public: 581 uint16_t blend_mode; 582 protected: 583 void ReadImpl(DataStream* stream) override; 584 }; 585 586 class ChunkBone : public Chunk 587 { 588 public: 589 std::string name; 590 uint16_t handle; 591 592 StdMeshVector position; 593 StdMeshQuaternion orientation; 594 StdMeshVector scale; 595 protected: 596 void ReadImpl(DataStream *stream) override; 597 }; 598 599 class ChunkBoneParent : public Chunk 600 { 601 public: 602 uint16_t childHandle; 603 uint16_t parentHandle; 604 protected: 605 void ReadImpl(DataStream *stream) override; 606 }; 607 608 class ChunkAnimation : public Chunk 609 { 610 public: 611 std::string name; 612 float duration; 613 unique_ptr_vector<ChunkAnimationTrack> tracks; 614 protected: 615 void ReadImpl(DataStream *stream) override; 616 }; 617 618 class ChunkAnimationBaseInfo : public Chunk 619 { 620 public: 621 std::string base_animation_name; 622 float base_key_frame_time; 623 protected: 624 void ReadImpl(DataStream* stream) override; 625 }; 626 627 class ChunkAnimationTrack : public Chunk 628 { 629 public: 630 uint16_t bone; 631 unique_ptr_vector<ChunkAnimationTrackKF> keyframes; 632 protected: 633 void ReadImpl(DataStream *stream) override; 634 }; 635 636 class ChunkAnimationTrackKF : public Chunk 637 { 638 public: 639 float time; 640 StdMeshQuaternion rotation; 641 StdMeshVector translation; 642 StdMeshVector scale; 643 protected: 644 void ReadImpl(DataStream *stream) override; 645 }; 646 647 class ChunkAnimationLink : public Chunk 648 { 649 public: 650 std::string file; 651 StdMeshVector scale; 652 protected: 653 void ReadImpl(DataStream *stream) override; 654 }; 655 } 656 } 657 658 #endif 659