void CModel::UpdateMatrices() { // Rotation D3DXMATRIX translation; D3DXMATRIX scale; D3DXMATRIX matrixRotationX; D3DXMATRIX matrixRotationY; D3DXMATRIX matrixRotationZ; // Calculate the rotation of the model. float rotX = (GetRotationX() * PrioEngine::kPi) / 180.0f; float rotY = (GetRotationY() * PrioEngine::kPi) / 180.0f; float rotZ = (GetRotationZ() * PrioEngine::kPi) / 180.0f; D3DXMatrixRotationX(&matrixRotationX, rotX); D3DXMatrixRotationY(&matrixRotationY, rotY); D3DXMatrixRotationZ(&matrixRotationZ, rotZ); // Calculate scaling. D3DXMatrixScaling(&scale, GetScaleX(), GetScaleY(), GetScaleZ()); // Calculate the translation of the model. D3DXMatrixTranslation(&translation, GetPosX(), GetPosY(), GetPosZ()); // Calculate the world matrix mWorldMatrix = scale * matrixRotationX * matrixRotationY * matrixRotationZ * translation; }
bool Map::CompileS3D( std::vector<EQEmu::S3D::WLDFragment> &zone_frags, std::vector<EQEmu::S3D::WLDFragment> &zone_object_frags, std::vector<EQEmu::S3D::WLDFragment> &object_frags ) { collide_verts.clear(); collide_indices.clear(); non_collide_verts.clear(); non_collide_indices.clear(); current_collide_index = 0; current_non_collide_index = 0; collide_vert_to_index.clear(); non_collide_vert_to_index.clear(); map_models.clear(); map_eqg_models.clear(); map_placeables.clear(); eqLogMessage(LogTrace, "Processing s3d zone geometry fragments."); for(uint32_t i = 0; i < zone_frags.size(); ++i) { if(zone_frags[i].type == 0x36) { EQEmu::S3D::WLDFragment36 &frag = reinterpret_cast<EQEmu::S3D::WLDFragment36&>(zone_frags[i]); auto model = frag.GetData(); auto &mod_polys = model->GetPolygons(); auto &mod_verts = model->GetVertices(); for (uint32_t j = 0; j < mod_polys.size(); ++j) { auto ¤t_poly = mod_polys[j]; auto v1 = mod_verts[current_poly.verts[0]]; auto v2 = mod_verts[current_poly.verts[1]]; auto v3 = mod_verts[current_poly.verts[2]]; float t = v1.pos.x; v1.pos.x = v1.pos.y; v1.pos.y = t; t = v2.pos.x; v2.pos.x = v2.pos.y; v2.pos.y = t; t = v3.pos.x; v3.pos.x = v3.pos.y; v3.pos.y = t; if(current_poly.flags == 0x10) AddFace(v1.pos, v2.pos, v3.pos, false); else AddFace(v1.pos, v2.pos, v3.pos, true); } } } eqLogMessage(LogTrace, "Processing zone placeable fragments."); std::vector<std::pair<std::shared_ptr<EQEmu::Placeable>, std::shared_ptr<EQEmu::S3D::Geometry>>> placables; std::vector<std::pair<std::shared_ptr<EQEmu::Placeable>, std::shared_ptr<EQEmu::S3D::SkeletonTrack>>> placables_skeleton; for (uint32_t i = 0; i < zone_object_frags.size(); ++i) { if (zone_object_frags[i].type == 0x15) { EQEmu::S3D::WLDFragment15 &frag = reinterpret_cast<EQEmu::S3D::WLDFragment15&>(zone_object_frags[i]); auto plac = frag.GetData(); if(!plac) { eqLogMessage(LogWarn, "Placeable entry was not found."); continue; } bool found = false; for (uint32_t o = 0; o < object_frags.size(); ++o) { if (object_frags[o].type == 0x14) { EQEmu::S3D::WLDFragment14 &obj_frag = reinterpret_cast<EQEmu::S3D::WLDFragment14&>(object_frags[o]); auto mod_ref = obj_frag.GetData(); if(mod_ref->GetName().compare(plac->GetName()) == 0) { found = true; auto &frag_refs = mod_ref->GetFrags(); for (uint32_t m = 0; m < frag_refs.size(); ++m) { if (object_frags[frag_refs[m] - 1].type == 0x2D) { EQEmu::S3D::WLDFragment2D &r_frag = reinterpret_cast<EQEmu::S3D::WLDFragment2D&>(object_frags[frag_refs[m] - 1]); auto m_ref = r_frag.GetData(); EQEmu::S3D::WLDFragment36 &mod_frag = reinterpret_cast<EQEmu::S3D::WLDFragment36&>(object_frags[m_ref]); auto mod = mod_frag.GetData(); placables.push_back(std::make_pair(plac, mod)); } else if (object_frags[frag_refs[m] - 1].type == 0x11) { EQEmu::S3D::WLDFragment11 &r_frag = reinterpret_cast<EQEmu::S3D::WLDFragment11&>(object_frags[frag_refs[m] - 1]); auto s_ref = r_frag.GetData(); EQEmu::S3D::WLDFragment10 &skeleton_frag = reinterpret_cast<EQEmu::S3D::WLDFragment10&>(object_frags[s_ref]); auto skele = skeleton_frag.GetData(); placables_skeleton.push_back(std::make_pair(plac, skele)); } } break; } } } if(!found) { eqLogMessage(LogWarn, "Could not find model for placeable %s", plac->GetName().c_str()); } } } eqLogMessage(LogTrace, "Processing s3d placeables."); size_t pl_sz = placables.size(); for(size_t i = 0; i < pl_sz; ++i) { auto plac = placables[i].first; auto model = placables[i].second; auto &mod_polys = model->GetPolygons(); auto &mod_verts = model->GetVertices(); float offset_x = plac->GetX(); float offset_y = plac->GetY(); float offset_z = plac->GetZ(); float rot_x = plac->GetRotateX() * 3.14159f / 180.0f; float rot_y = plac->GetRotateY() * 3.14159f / 180.0f; float rot_z = plac->GetRotateZ() * 3.14159f / 180.0f; float scale_x = plac->GetScaleX(); float scale_y = plac->GetScaleY(); float scale_z = plac->GetScaleZ(); if (map_models.count(model->GetName()) == 0) { map_models[model->GetName()] = model; } std::shared_ptr<EQEmu::Placeable> gen_plac(new EQEmu::Placeable()); gen_plac->SetFileName(model->GetName()); gen_plac->SetLocation(offset_x, offset_y, offset_z); //y rotation seems backwards on s3ds, probably cause of the weird coord system they used back then //x rotation might be too but there are literally 0 x rotated placeables in all the s3ds so who knows gen_plac->SetRotation(rot_x, -rot_y, rot_z); gen_plac->SetScale(scale_x, scale_y, scale_z); map_placeables.push_back(gen_plac); eqLogMessage(LogTrace, "Adding placeable %s at (%f, %f, %f)", model->GetName().c_str(), offset_x, offset_y, offset_z); } eqLogMessage(LogTrace, "Processing s3d animated placeables."); pl_sz = placables_skeleton.size(); for (size_t i = 0; i < pl_sz; ++i) { auto &plac = placables_skeleton[i].first; auto &bones = placables_skeleton[i].second->GetBones(); if(bones.size() > 0) { float offset_x = plac->GetX(); float offset_y = plac->GetY(); float offset_z = plac->GetZ(); float rot_x = plac->GetRotateX() * 3.14159f / 180.0f; float rot_y = plac->GetRotateY() * 3.14159f / 180.0f; float rot_z = plac->GetRotateZ() * 3.14159f / 180.0f; float scale_x = plac->GetScaleX(); float scale_y = plac->GetScaleY(); float scale_z = plac->GetScaleZ(); TraverseBone(bones[0], glm::vec3(offset_x, offset_y, offset_z), glm::vec3(rot_x, rot_y, rot_z), glm::vec3(scale_x, scale_y, scale_z)); } } return true; }