lightpreview: add "show bmodels" checkbox
This commit is contained in:
parent
248ed7c614
commit
a109dfca28
|
|
@ -350,6 +350,30 @@ void main() {
|
|||
}
|
||||
)";
|
||||
|
||||
GLView::face_visibility_key_t GLView::desiredFaceVisibility() const
|
||||
{
|
||||
face_visibility_key_t result;
|
||||
result.show_bmodels = m_showBmodels;
|
||||
|
||||
if (m_visCulling) {
|
||||
const mbsp_t &bsp = *m_bsp;
|
||||
const auto &world = bsp.dmodels.at(0);
|
||||
|
||||
auto *leaf =
|
||||
BSP_FindLeafAtPoint(&bsp, &world, qvec3d{m_cameraOrigin.x(), m_cameraOrigin.y(), m_cameraOrigin.z()});
|
||||
|
||||
int leafnum = leaf - bsp.dleafs.data();
|
||||
int clusternum = leaf->cluster;
|
||||
|
||||
result.leafnum = leafnum;
|
||||
result.clusternum = clusternum;
|
||||
} else {
|
||||
result.leafnum = -1;
|
||||
result.clusternum = -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void GLView::updateFaceVisibility()
|
||||
{
|
||||
if (!m_bsp)
|
||||
|
|
@ -358,72 +382,65 @@ void GLView::updateFaceVisibility()
|
|||
const mbsp_t &bsp = *m_bsp;
|
||||
const auto &world = bsp.dmodels.at(0);
|
||||
|
||||
auto *leaf = BSP_FindLeafAtPoint(&bsp, &world, qvec3d{m_cameraOrigin.x(), m_cameraOrigin.y(), m_cameraOrigin.z()});
|
||||
const face_visibility_key_t desired = desiredFaceVisibility();
|
||||
|
||||
int leafnum = leaf - bsp.dleafs.data();
|
||||
int clusternum = leaf->cluster;
|
||||
|
||||
if (!m_visCulling) {
|
||||
clusternum = -1;
|
||||
}
|
||||
|
||||
if (m_lastLeaf == clusternum) {
|
||||
qDebug() << "reusing last frame visdata for leaf " << leafnum << " cluster " << clusternum;
|
||||
if (m_uploaded_face_visibility &&
|
||||
*m_uploaded_face_visibility == desired) {
|
||||
qDebug() << "reusing last frame visdata";
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "looking up pvs for clusternum " << clusternum;
|
||||
|
||||
auto it = m_decompressedVis.find(clusternum);
|
||||
if (it == m_decompressedVis.end()) {
|
||||
qDebug() << "no visdata, must be in void";
|
||||
|
||||
m_lastLeaf = -1;
|
||||
setFaceVisibilityToAllVisible();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Q_assert(it != m_decompressedVis.end());
|
||||
|
||||
const auto &pvs = it->second;
|
||||
qDebug() << "found bitvec of size " << pvs.size();
|
||||
|
||||
// check leaf visibility
|
||||
|
||||
auto leaf_sees = [&](const mleaf_t *b) -> bool {
|
||||
if (b->cluster < 0)
|
||||
return true;
|
||||
|
||||
return !!(pvs[b->cluster >> 3] & (1 << (b->cluster & 7)));
|
||||
};
|
||||
qDebug() << "looking up pvs for clusternum " << desired.clusternum;
|
||||
|
||||
const int face_visibility_width = m_bsp->dfaces.size();
|
||||
|
||||
std::vector<uint8_t> face_flags;
|
||||
face_flags.resize(face_visibility_width, 0);
|
||||
|
||||
// visit all world leafs: if they're visible, mark the appropriate faces
|
||||
BSP_VisitAllLeafs(bsp, bsp.dmodels[0], [&](const mleaf_t &leaf) {
|
||||
if (leaf_sees(&leaf)) {
|
||||
for (int ms = 0; ms < leaf.nummarksurfaces; ++ms) {
|
||||
int fnum = bsp.dleaffaces[leaf.firstmarksurface + ms];
|
||||
face_flags[fnum] = 16;
|
||||
if (auto it = m_decompressedVis.find(desired.clusternum);
|
||||
desired.leafnum != -1 && it != m_decompressedVis.end()) {
|
||||
|
||||
const auto &pvs = it->second;
|
||||
qDebug() << "found bitvec of size " << pvs.size();
|
||||
|
||||
// check leaf visibility
|
||||
|
||||
auto leaf_sees = [&](const mleaf_t *b) -> bool {
|
||||
if (b->cluster < 0)
|
||||
return true;
|
||||
|
||||
return !!(pvs[b->cluster >> 3] & (1 << (b->cluster & 7)));
|
||||
};
|
||||
|
||||
// visit all world leafs: if they're visible, mark the appropriate faces
|
||||
BSP_VisitAllLeafs(bsp, bsp.dmodels[0], [&](const mleaf_t &leaf) {
|
||||
if (leaf_sees(&leaf)) {
|
||||
for (int ms = 0; ms < leaf.nummarksurfaces; ++ms) {
|
||||
int fnum = bsp.dleaffaces[leaf.firstmarksurface + ms];
|
||||
face_flags[fnum] = 16;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// mark all world faces
|
||||
for (int fi = world.firstface; fi < (world.firstface + world.numfaces); ++fi) {
|
||||
face_flags[fi] = 16;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// set all bmodel faces to visible
|
||||
for (int mi = 1; mi < bsp.dmodels.size(); ++mi) {
|
||||
auto &model = bsp.dmodels[mi];
|
||||
for (int fi = model.firstface; fi < (model.firstface + model.numfaces); ++fi) {
|
||||
face_flags[fi] = 16;
|
||||
if (m_showBmodels) {
|
||||
for (int mi = 1; mi < bsp.dmodels.size(); ++mi) {
|
||||
auto &model = bsp.dmodels[mi];
|
||||
for (int fi = model.firstface; fi < (model.firstface + model.numfaces); ++fi) {
|
||||
face_flags[fi] = 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setFaceVisibilityArray(face_flags.data());
|
||||
|
||||
m_lastLeaf = clusternum;
|
||||
m_uploaded_face_visibility = desired;
|
||||
}
|
||||
|
||||
bool GLView::shouldLiveUpdate() const
|
||||
|
|
@ -812,11 +829,13 @@ void GLView::setKeepOrigin(bool keeporigin)
|
|||
void GLView::setDrawPortals(bool drawportals)
|
||||
{
|
||||
m_drawPortals = drawportals;
|
||||
update();
|
||||
}
|
||||
|
||||
void GLView::setDrawLeak(bool drawleak)
|
||||
{
|
||||
m_drawLeak = drawleak;
|
||||
update();
|
||||
}
|
||||
|
||||
void GLView::setLightStyleIntensity(int style_id, int intensity)
|
||||
|
|
@ -850,6 +869,14 @@ void GLView::setDrawTranslucencyAsOpaque(bool drawopaque)
|
|||
update();
|
||||
}
|
||||
|
||||
void GLView::setShowBmodels(bool bmodels)
|
||||
{
|
||||
// force re-upload of face visibility
|
||||
m_uploaded_face_visibility = std::nullopt;
|
||||
m_showBmodels = bmodels;
|
||||
update();
|
||||
}
|
||||
|
||||
void GLView::takeScreenshot(QString destPath, int w, int h)
|
||||
{
|
||||
// update aspect ratio
|
||||
|
|
@ -900,21 +927,6 @@ void GLView::setFaceVisibilityArray(uint8_t *data)
|
|||
logging::print("uploaded {} bytes face visibility texture", face_visibility_width);
|
||||
}
|
||||
|
||||
void GLView::setFaceVisibilityToAllVisible()
|
||||
{
|
||||
// one byte per face
|
||||
int face_visibility_width = m_bsp->dfaces.size();
|
||||
|
||||
uint8_t *data = new uint8_t[face_visibility_width];
|
||||
for (int x = 0; x < face_visibility_width; ++x) {
|
||||
data[x] = 16;
|
||||
}
|
||||
|
||||
setFaceVisibilityArray(data);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries_t &bspx,
|
||||
const std::vector<entdict_t> &entities, const full_atlas_t &lightmap, const settings::common_settings &settings,
|
||||
bool use_bspx_normals)
|
||||
|
|
@ -957,7 +969,7 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries
|
|||
m_portalIndexBuffer.allocate(0);
|
||||
num_leak_points = 0;
|
||||
num_portal_indices = 0;
|
||||
m_lastLeaf = -1;
|
||||
m_uploaded_face_visibility = std::nullopt;
|
||||
|
||||
int32_t highest_depth = 0;
|
||||
|
||||
|
|
@ -1018,11 +1030,6 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries
|
|||
delete[] data;
|
||||
}
|
||||
|
||||
// upload face visibility
|
||||
if (!bsp.dfaces.empty()) {
|
||||
setFaceVisibilityToAllVisible();
|
||||
}
|
||||
|
||||
struct face_payload
|
||||
{
|
||||
const mface_t *face;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ See file, 'COPYING', for details.
|
|||
#include <QVector3D>
|
||||
#include <QMatrix4x4>
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <common/qvec.hh>
|
||||
|
|
@ -68,10 +69,21 @@ private:
|
|||
float m_moveSpeed;
|
||||
|
||||
// vis culling stuff
|
||||
/**
|
||||
* -1 indicates solid leaf or no visdata (render all)
|
||||
*/
|
||||
int m_lastLeaf = -1;
|
||||
struct face_visibility_key_t
|
||||
{
|
||||
bool show_bmodels;
|
||||
// -1 indicates solid leaf or no visdata (render all world faces)
|
||||
int leafnum;
|
||||
int clusternum;
|
||||
|
||||
bool operator==(const face_visibility_key_t &other) const
|
||||
{
|
||||
return show_bmodels == other.show_bmodels && leafnum == other.leafnum && clusternum == other.clusternum;
|
||||
}
|
||||
};
|
||||
face_visibility_key_t desiredFaceVisibility() const;
|
||||
|
||||
std::optional<face_visibility_key_t> m_uploaded_face_visibility;
|
||||
bool m_visCulling = true;
|
||||
|
||||
// camera stuff
|
||||
|
|
@ -97,6 +109,7 @@ private:
|
|||
bool m_drawLeak = false;
|
||||
QOpenGLTexture::Filter m_filter = QOpenGLTexture::Linear;
|
||||
bool m_drawTranslucencyAsOpaque = false;
|
||||
bool m_showBmodels = true;
|
||||
|
||||
QOpenGLVertexArrayObject m_vao;
|
||||
QOpenGLBuffer m_vbo;
|
||||
|
|
@ -187,7 +200,6 @@ public:
|
|||
|
||||
private:
|
||||
void setFaceVisibilityArray(uint8_t *data);
|
||||
void setFaceVisibilityToAllVisible();
|
||||
|
||||
public:
|
||||
void renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries_t &bspx,
|
||||
|
|
@ -209,6 +221,7 @@ public:
|
|||
void setMagFilter(QOpenGLTexture::Filter filter);
|
||||
const bool &getKeepOrigin() const { return m_keepOrigin; }
|
||||
void setDrawTranslucencyAsOpaque(bool drawopaque);
|
||||
void setShowBmodels(bool bmodels);
|
||||
|
||||
void takeScreenshot(QString destPath, int w, int h);
|
||||
|
||||
|
|
|
|||
|
|
@ -200,6 +200,8 @@ void MainWindow::createPropertiesSidebar()
|
|||
bspx_normals->setChecked(true);
|
||||
|
||||
auto *draw_opaque = new QCheckBox(tr("Draw Translucency as Opaque"));
|
||||
auto *show_bmodels = new QCheckBox(tr("Show Bmodels"));
|
||||
show_bmodels->setChecked(true);
|
||||
|
||||
formLayout->addRow(tr("common"), common_options);
|
||||
formLayout->addRow(tr("qbsp"), qbsp_options);
|
||||
|
|
@ -217,6 +219,7 @@ void MainWindow::createPropertiesSidebar()
|
|||
formLayout->addRow(bspx_decoupled_lm);
|
||||
formLayout->addRow(bspx_normals);
|
||||
formLayout->addRow(draw_opaque);
|
||||
formLayout->addRow(show_bmodels);
|
||||
|
||||
lightstyles = new QVBoxLayout();
|
||||
|
||||
|
|
@ -271,6 +274,8 @@ void MainWindow::createPropertiesSidebar()
|
|||
connect(draw_opaque, &QAbstractButton::toggled, this,
|
||||
[=](bool checked) { glView->setDrawTranslucencyAsOpaque(checked); });
|
||||
connect(glView, &GLView::cameraMoved, this, &MainWindow::displayCameraPositionInfo);
|
||||
connect(show_bmodels, &QAbstractButton::toggled, this,
|
||||
[=](bool checked) { glView->setShowBmodels(checked); });
|
||||
|
||||
// set up load timer
|
||||
m_fileReloadTimer = std::make_unique<QTimer>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue