//================================================================================================= // Wczytuje dane wierzcho³ków z modelu (na razie dzia³a tylko dla Vec3) //================================================================================================= void Mesh::LoadVertexData(VertexData* vd, StreamReader& stream) { // read and check header Header head; if(!stream.Read(head)) throw "Failed to read file header."; if(memcmp(head.format, "QMSH", 4) != 0) throw Format("Invalid file signature '%.4s'.", head.format); if(head.version != 20) throw Format("Invalid file version '%d'.", head.version); if(head.flags != F_PHYSICS) throw Format("Invalid mesh flags '%d'.", head.flags); vd->radius = head.radius; // read vertices uint size = sizeof(Vec3) * head.n_verts; if(!stream.Ensure(size)) throw "Failed to read vertex data."; vd->verts.resize(head.n_verts); stream.Read(vd->verts.data(), size); // read faces size = sizeof(Face) * head.n_tris; if(!stream.Ensure(size)) throw "Failed to read triangle data."; vd->faces.resize(head.n_tris); stream.Read(vd->faces.data(), size); }
void Mesh::LoadPoints(StreamReader& stream) { uint size = Point::MIN_SIZE * head.n_points; if(!stream.Ensure(size)) throw "Failed to read points."; attach_points.clear(); attach_points.resize(head.n_points); for(word i = 0; i < head.n_points; ++i) { Point& p = attach_points[i]; stream.Read(p.name); stream.Read(p.mat); stream.Read(p.bone); stream.Read(p.type); stream.Read(p.size); stream.Read(p.rot); p.rot.y = Clip(-p.rot.y); } }
//================================================================================================= // Wczytywanie modelu z pliku //================================================================================================= void Mesh::Load(StreamReader& stream, IDirect3DDevice9* device) { assert(device); LoadHeader(stream); SetVertexSizeDecl(); // ------ vertices // ensure size uint size = vertex_size * head.n_verts; if(!stream.Ensure(size)) throw "Failed to read vertex buffer."; // create vertex buffer HRESULT hr = device->CreateVertexBuffer(size, 0, 0, D3DPOOL_MANAGED, &vb, nullptr); if(FAILED(hr)) throw Format("Failed to create vertex buffer (%d).", hr); // read void* ptr; V(vb->Lock(0, size, &ptr, 0)); stream.Read(ptr, size); V(vb->Unlock()); // ----- triangles // ensure size size = sizeof(word) * head.n_tris * 3; if(!stream.Ensure(size)) throw "Failed to read index buffer."; // create index buffer hr = device->CreateIndexBuffer(size, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, nullptr); if(FAILED(hr)) throw Format("Failed to create index buffer (%d).", hr); // read V(ib->Lock(0, size, &ptr, 0)); stream.Read(ptr, size); V(ib->Unlock()); // ----- submeshes size = Submesh::MIN_SIZE * head.n_subs; if(!stream.Ensure(size)) throw "Failed to read submesh data."; subs.resize(head.n_subs); for(word i = 0; i < head.n_subs; ++i) { Submesh& sub = subs[i]; stream.Read(sub.first); stream.Read(sub.tris); stream.Read(sub.min_ind); stream.Read(sub.n_ind); stream.Read(sub.name); stream.ReadString1(); if(BUF[0]) sub.tex = ResourceManager::Get<Texture>().GetLoaded(BUF); else sub.tex = nullptr; // specular value stream.Read(sub.specular_color); stream.Read(sub.specular_intensity); stream.Read(sub.specular_hardness); // normalmap if(IS_SET(head.flags, F_TANGENTS)) { stream.ReadString1(); if(BUF[0]) { sub.tex_normal = ResourceManager::Get<Texture>().GetLoaded(BUF); stream.Read(sub.normal_factor); } else sub.tex_normal = nullptr; } else sub.tex_normal = nullptr; // specular map stream.ReadString1(); if(BUF[0]) { sub.tex_specular = ResourceManager::Get<Texture>().GetLoaded(BUF); stream.Read(sub.specular_factor); stream.Read(sub.specular_color_factor); } else sub.tex_specular = nullptr; if(!stream) throw Format("Failed to read submesh %u.", i); } // animation data if(IS_SET(head.flags, F_ANIMATED) && !IS_SET(head.flags, F_STATIC)) { // bones size = Bone::MIN_SIZE * head.n_bones; if(!stream.Ensure(size)) throw "Failed to read bones."; bones.resize(head.n_bones + 1); // zero bone Bone& zero_bone = bones[0]; zero_bone.parent = 0; zero_bone.name = "zero"; zero_bone.id = 0; zero_bone.mat = Matrix::IdentityMatrix; for(byte i = 1; i <= head.n_bones; ++i) { Bone& bone = bones[i]; bone.id = i; stream.Read(bone.parent); stream.Read(bone.mat._11); stream.Read(bone.mat._12); stream.Read(bone.mat._13); bone.mat._14 = 0; stream.Read(bone.mat._21); stream.Read(bone.mat._22); stream.Read(bone.mat._23); bone.mat._24 = 0; stream.Read(bone.mat._31); stream.Read(bone.mat._32); stream.Read(bone.mat._33); bone.mat._34 = 0; stream.Read(bone.mat._41); stream.Read(bone.mat._42); stream.Read(bone.mat._43); bone.mat._44 = 1; stream.Read(bone.name); bones[bone.parent].childs.push_back(i); } if(!stream) throw "Failed to read bones data."; // animations size = Animation::MIN_SIZE * head.n_anims; if(!stream.Ensure(size)) throw "Failed to read animations."; anims.resize(head.n_anims); for(byte i = 0; i < head.n_anims; ++i) { Animation& anim = anims[i]; stream.Read(anim.name); stream.Read(anim.length); stream.Read(anim.n_frames); size = anim.n_frames * (4 + sizeof(KeyframeBone) * head.n_bones); if(!stream.Ensure(size)) throw Format("Failed to read animation %u data.", i); anim.frames.resize(anim.n_frames); for(word j = 0; j < anim.n_frames; ++j) { stream.Read(anim.frames[j].time); anim.frames[j].bones.resize(head.n_bones); stream.Read(anim.frames[j].bones.data(), sizeof(KeyframeBone) * head.n_bones); } } // add zero bone to count ++head.n_bones; } LoadPoints(stream); // bone groups if(IS_SET(head.flags, F_ANIMATED) && !IS_SET(head.flags, F_STATIC)) { if(!stream.Ensure(BoneGroup::MIN_SIZE * head.n_groups)) throw "Failed to read bone groups."; groups.resize(head.n_groups); for(word i = 0; i < head.n_groups; ++i) { BoneGroup& gr = groups[i]; stream.Read(gr.name); // parent group stream.Read(gr.parent); assert(gr.parent < head.n_groups); assert(gr.parent != i || i == 0); // bone indexes byte count; stream.Read(count); gr.bones.resize(count); stream.Read(gr.bones.data(), gr.bones.size()); } if(!stream) throw "Failed to read bone groups data."; SetupBoneMatrices(); } // splits if(IS_SET(head.flags, F_SPLIT)) { size = sizeof(Split) * head.n_subs; if(!stream.Ensure(size)) throw "Failed to read mesh splits."; splits.resize(head.n_subs); stream.Read(splits.data(), size); } }