asset browser: implement render toggles, particle and box rendering
This commit is contained in:
@@ -63,6 +63,8 @@ void ModelViewer::resizeGL(int w, int h)
|
||||
|
||||
void ModelViewer::tick(float dt)
|
||||
{
|
||||
PreviewRenderer::tick(dt);
|
||||
|
||||
if (turn)
|
||||
{
|
||||
_camera.add_to_yaw(math::degrees(turn));
|
||||
@@ -84,8 +86,6 @@ void ModelViewer::tick(float dt)
|
||||
_camera.move_vertical(updown, dt);
|
||||
}
|
||||
|
||||
_animtime += dt * 1000.0f;
|
||||
|
||||
}
|
||||
|
||||
void ModelViewer::setModel(std::string const& filename)
|
||||
|
||||
@@ -32,10 +32,10 @@ namespace noggit
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ModelViewer(QWidget* parent = nullptr);
|
||||
void setModel(std::string const& filename) override;
|
||||
void setMoveSensitivity(float s) { _move_sensitivity = s / 30.0f; }
|
||||
float getMoveSensitivity() { return _move_sensitivity; }
|
||||
explicit ModelViewer(QWidget* parent = nullptr);
|
||||
void setModel(std::string const& filename) override;
|
||||
void setMoveSensitivity(float s) { _move_sensitivity = s / 30.0f; }
|
||||
float getMoveSensitivity() { return _move_sensitivity; }
|
||||
|
||||
signals:
|
||||
void resized();
|
||||
@@ -52,7 +52,7 @@ namespace noggit
|
||||
qreal _last_update = 0.f;
|
||||
float _move_sensitivity = 0.5f;
|
||||
|
||||
void tick(float dt);
|
||||
void tick(float dt) override;
|
||||
float aspect_ratio() const override;
|
||||
|
||||
void initializeGL() override;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <noggit/Log.h>
|
||||
#include <noggit/ContextObject.hpp>
|
||||
#include <noggit/ui/FramelessWindow.hpp>
|
||||
#include <noggit/ui/font_noggit.hpp>
|
||||
|
||||
#include <QStandardItemModel>
|
||||
#include <QItemSelectionModel>
|
||||
@@ -15,6 +16,7 @@
|
||||
#include <QSlider>
|
||||
|
||||
using namespace noggit::Red::AssetBrowser::Ui;
|
||||
using namespace noggit::ui;
|
||||
|
||||
AssetBrowserWidget::AssetBrowserWidget(QWidget *parent)
|
||||
: QMainWindow(parent, Qt::Window)
|
||||
@@ -53,6 +55,12 @@ AssetBrowserWidget::AssetBrowserWidget(QWidget *parent)
|
||||
}
|
||||
);
|
||||
|
||||
viewport_overlay_ui->toggleAnimationButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_ANIMATION));
|
||||
viewport_overlay_ui->toggleModelsButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_DOODADS));
|
||||
viewport_overlay_ui->toggleParticlesButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_UNUSED));
|
||||
viewport_overlay_ui->toggleBoundingBoxButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_WITH_BOX));
|
||||
viewport_overlay_ui->toggleWMOButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_WMO));
|
||||
|
||||
ui->viewport->installEventFilter(overlay);
|
||||
overlay->show();
|
||||
|
||||
@@ -173,6 +181,29 @@ AssetBrowserWidget::AssetBrowserWidget(QWidget *parent)
|
||||
}
|
||||
);
|
||||
|
||||
// Render toggles
|
||||
connect(viewport_overlay_ui->toggleWMOButton, &QPushButton::clicked,
|
||||
[this]() {ui->viewport->_draw_wmo.toggle();});
|
||||
connect(viewport_overlay_ui->toggleBoundingBoxButton, &QPushButton::clicked,
|
||||
[this]() {ui->viewport->_draw_boxes.toggle();});
|
||||
connect(viewport_overlay_ui->toggleParticlesButton, &QPushButton::clicked,
|
||||
[this]() {ui->viewport->_draw_particles.toggle();});
|
||||
connect(viewport_overlay_ui->toggleModelsButton, &QPushButton::clicked,
|
||||
[this]() {ui->viewport->_draw_models.toggle();});
|
||||
connect(viewport_overlay_ui->toggleAnimationButton, &QPushButton::clicked,
|
||||
[this]() {ui->viewport->_draw_animated.toggle();});
|
||||
|
||||
connect(&ui->viewport->_draw_wmo, &bool_toggle_property::changed,
|
||||
[this](bool state) {ui->viewport->_draw_wmo.set(state);});
|
||||
connect(&ui->viewport->_draw_boxes, &bool_toggle_property::changed,
|
||||
[this](bool state) {ui->viewport->_draw_boxes.set(state);});
|
||||
connect(&ui->viewport->_draw_particles, &bool_toggle_property::changed,
|
||||
[this](bool state) {ui->viewport->_draw_particles.set(state);});
|
||||
connect(&ui->viewport->_draw_models, &bool_toggle_property::changed,
|
||||
[this](bool state) {ui->viewport->_draw_models.set(state);});
|
||||
connect(&ui->viewport->_draw_animated, &bool_toggle_property::changed,
|
||||
[this](bool state) {ui->viewport->_draw_animated.set(state);});
|
||||
|
||||
_wmo_group_and_lod_regex = QRegularExpression(".+_\\d{3}(_lod.+)*.wmo");
|
||||
|
||||
updateModelData();
|
||||
|
||||
@@ -31,7 +31,6 @@ namespace noggit
|
||||
PreviewRenderer* _preview_renderer;
|
||||
QRegularExpression _wmo_group_and_lod_regex;
|
||||
|
||||
|
||||
void updateModelData();
|
||||
void recurseDirectory(Model::TreeManager& tree_mgr, const QString& s_dir, const QString& project_dir);
|
||||
|
||||
|
||||
@@ -30,67 +30,17 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<property name="spacing">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toggleAnimationButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toggleParticlesButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toggleModelsButton">
|
||||
<property name="sizePolicy">
|
||||
@@ -101,8 +51,8 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
@@ -111,6 +61,9 @@
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Draw models</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@@ -132,8 +85,8 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
@@ -142,6 +95,77 @@
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Draw WMOs</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toggleParticlesButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Draw particles</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toggleAnimationButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Draw animation</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@@ -161,12 +185,21 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Draw bounding boxes</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@@ -187,7 +220,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<width>550</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
|
||||
@@ -126,7 +126,6 @@ void PreviewRenderer::draw()
|
||||
{
|
||||
|
||||
float culldistance = 10000000;
|
||||
bool draw_doodads_wmo = true;
|
||||
|
||||
math::matrix_4x4 const mvp(model_view().transposed() * projection().transposed());
|
||||
math::frustum const frustum (mvp);
|
||||
@@ -151,6 +150,16 @@ void PreviewRenderer::draw()
|
||||
);
|
||||
}
|
||||
|
||||
if (!_m2_box_program)
|
||||
{
|
||||
_m2_box_program.reset
|
||||
( new opengl::program
|
||||
{ { GL_VERTEX_SHADER, opengl::shader::src_from_qrc("m2_box_vs") }
|
||||
, { GL_FRAGMENT_SHADER, opengl::shader::src_from_qrc("m2_box_fs") }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (!_m2_ribbons_program)
|
||||
{
|
||||
_m2_ribbons_program.reset
|
||||
@@ -180,6 +189,8 @@ void PreviewRenderer::draw()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!_liquid_render)
|
||||
{
|
||||
_liquid_render.emplace();
|
||||
@@ -193,7 +204,7 @@ void PreviewRenderer::draw()
|
||||
// draw WMOs
|
||||
std::unordered_map<std::string, std::vector<ModelInstance*>> _wmo_doodads;
|
||||
|
||||
if (!_wmo_instances.empty())
|
||||
if (_draw_wmo.get() && !_wmo_instances.empty())
|
||||
{
|
||||
// set anim time only once per frame
|
||||
{
|
||||
@@ -233,7 +244,7 @@ void PreviewRenderer::draw()
|
||||
{
|
||||
wmo_instance.draw(
|
||||
wmo_program, model_view().transposed(), projection().transposed(), frustum, culldistance,
|
||||
math::vector_3d(0.0f, 0.0f, 0.0f), false, false // doodads
|
||||
math::vector_3d(0.0f, 0.0f, 0.0f), _draw_boxes.get(), _draw_models.get() // doodads
|
||||
, false, _liquid_render.get(), std::vector<selection_type>(), 0, false, display_mode::in_3D
|
||||
);
|
||||
|
||||
@@ -241,13 +252,10 @@ void PreviewRenderer::draw()
|
||||
gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl.enable(GL_CULL_FACE);
|
||||
|
||||
if (draw_doodads_wmo)
|
||||
for (auto& doodad : wmo_instance.get_visible_doodads(frustum, culldistance, _camera.position,
|
||||
false,display_mode::in_3D))
|
||||
{
|
||||
for (auto& doodad : wmo_instance.get_visible_doodads(frustum, culldistance, _camera.position, false,
|
||||
display_mode::in_3D))
|
||||
{
|
||||
_wmo_doodads[doodad->model->filename].push_back(doodad);
|
||||
}
|
||||
_wmo_doodads[doodad->model->filename].push_back(doodad);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,8 +267,10 @@ void PreviewRenderer::draw()
|
||||
std::unordered_map<Model*, std::size_t> model_with_particles;
|
||||
std::unordered_map<Model*, std::size_t> model_boxes_to_draw;
|
||||
|
||||
if (_draw_models.get() && !(_model_instances.empty() && _wmo_doodads.empty()))
|
||||
{
|
||||
ModelManager::resetAnim();
|
||||
if (_draw_animated.get())
|
||||
ModelManager::resetAnim();
|
||||
|
||||
opengl::scoped::use_program m2_shader {*_m2_instanced_program.get()};
|
||||
|
||||
@@ -285,33 +295,55 @@ void PreviewRenderer::draw()
|
||||
, _camera.position
|
||||
, false
|
||||
, _animtime
|
||||
, false
|
||||
, false
|
||||
, _draw_particles.get()
|
||||
, _draw_boxes.get()
|
||||
, model_with_particles
|
||||
, model_boxes_to_draw
|
||||
, display_mode::in_3D
|
||||
);
|
||||
}
|
||||
|
||||
if (draw_doodads_wmo)
|
||||
for (auto& it : _wmo_doodads)
|
||||
{
|
||||
for (auto& it : _wmo_doodads)
|
||||
it.second[0]->model->draw(
|
||||
model_view().transposed()
|
||||
, it.second
|
||||
, m2_shader
|
||||
, frustum
|
||||
, culldistance
|
||||
, _camera.position
|
||||
, false
|
||||
, _animtime
|
||||
, _draw_particles.get()
|
||||
, _draw_boxes.get()
|
||||
, model_with_particles
|
||||
, model_boxes_to_draw
|
||||
, display_mode::in_3D
|
||||
);
|
||||
}
|
||||
|
||||
if(_draw_boxes.get() && !model_boxes_to_draw.empty())
|
||||
{
|
||||
opengl::scoped::use_program m2_box_shader{ *_m2_box_program.get() };
|
||||
|
||||
m2_box_shader.uniform ("model_view", model_view().transposed());
|
||||
m2_box_shader.uniform ("projection", projection().transposed());
|
||||
|
||||
opengl::scoped::bool_setter<GL_LINE_SMOOTH, GL_TRUE> const line_smooth;
|
||||
gl.hint (GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
|
||||
for (auto& it : model_boxes_to_draw)
|
||||
{
|
||||
it.second[0]->model->draw(
|
||||
model_view().transposed()
|
||||
, it.second
|
||||
, m2_shader
|
||||
, frustum
|
||||
, culldistance
|
||||
, _camera.position
|
||||
, false
|
||||
, _animtime
|
||||
, false
|
||||
, false
|
||||
, model_with_particles
|
||||
, model_boxes_to_draw
|
||||
, display_mode::in_3D
|
||||
);
|
||||
math::vector_4d color = it.first->is_hidden()
|
||||
? math::vector_4d(0.f, 0.f, 1.f, 1.f)
|
||||
: ( it.first->use_fake_geometry()
|
||||
? math::vector_4d(1.f, 0.f, 0.f, 1.f)
|
||||
: math::vector_4d(0.75f, 0.75f, 0.75f, 1.f)
|
||||
)
|
||||
;
|
||||
|
||||
m2_box_shader.uniform("color", color);
|
||||
it.first->draw_box(m2_box_shader, it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,6 +351,45 @@ void PreviewRenderer::draw()
|
||||
gl.bindVertexArray(0);
|
||||
gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
// model particles
|
||||
if (_draw_animated.get() && !model_with_particles.empty())
|
||||
{
|
||||
opengl::scoped::bool_setter<GL_CULL_FACE, GL_FALSE> const cull;
|
||||
opengl::scoped::depth_mask_setter<GL_FALSE> const depth_mask;
|
||||
|
||||
opengl::scoped::use_program particles_shader {*_m2_particles_program.get()};
|
||||
|
||||
particles_shader.uniform("model_view_projection", mvp);
|
||||
particles_shader.uniform("tex", 0);
|
||||
opengl::texture::set_active_texture(0);
|
||||
|
||||
for (auto& it : model_with_particles)
|
||||
{
|
||||
it.first->draw_particles(model_view().transposed(), particles_shader, it.second);
|
||||
}
|
||||
}
|
||||
|
||||
if (_draw_animated.get() && !model_with_particles.empty())
|
||||
{
|
||||
opengl::scoped::bool_setter<GL_CULL_FACE, GL_FALSE> const cull;
|
||||
opengl::scoped::depth_mask_setter<GL_FALSE> const depth_mask;
|
||||
|
||||
opengl::scoped::use_program ribbon_shader {*_m2_ribbons_program.get()};
|
||||
|
||||
ribbon_shader.uniform("model_view_projection", mvp);
|
||||
ribbon_shader.uniform("tex", 0);
|
||||
|
||||
gl.blendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
for (auto& it : model_with_particles)
|
||||
{
|
||||
it.first->draw_ribbons(ribbon_shader, it.second);
|
||||
}
|
||||
}
|
||||
|
||||
gl.enable(GL_BLEND);
|
||||
gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
}
|
||||
|
||||
math::matrix_4x4 PreviewRenderer::model_view() const
|
||||
@@ -436,3 +507,24 @@ void PreviewRenderer::setLightDirection(float y, float z)
|
||||
}
|
||||
|
||||
|
||||
void PreviewRenderer::update_emitters(float dt)
|
||||
{
|
||||
while (dt > 0.1f)
|
||||
{
|
||||
ModelManager::updateEmitters(0.1f);
|
||||
dt -= 0.1f;
|
||||
}
|
||||
ModelManager::updateEmitters(dt);
|
||||
}
|
||||
|
||||
void PreviewRenderer::tick(float dt)
|
||||
{
|
||||
_animtime += dt * 1000.0f;
|
||||
|
||||
if (_draw_animated.get())
|
||||
{
|
||||
update_emitters(dt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <noggit/WMO.h>
|
||||
#include <noggit/Model.h>
|
||||
#include <noggit/ContextObject.hpp>
|
||||
#include <noggit/bool_toggle_property.hpp>
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
#include <QSettings>
|
||||
@@ -39,6 +40,12 @@ namespace noggit::Red
|
||||
|
||||
void setLightDirection(float y, float z);
|
||||
|
||||
bool_toggle_property _draw_models = {true};
|
||||
bool_toggle_property _draw_wmo = {true};
|
||||
bool_toggle_property _draw_particles = {true};
|
||||
bool_toggle_property _draw_animated = {true};
|
||||
bool_toggle_property _draw_boxes = {false};
|
||||
|
||||
protected:
|
||||
|
||||
noggit::camera _camera;
|
||||
@@ -61,10 +68,13 @@ namespace noggit::Red
|
||||
|
||||
std::vector<math::vector_3d> calcSceneExtents();
|
||||
virtual void draw();
|
||||
virtual void tick(float dt);
|
||||
virtual math::matrix_4x4 model_view() const;
|
||||
virtual math::matrix_4x4 projection() const;
|
||||
virtual float aspect_ratio() const;
|
||||
|
||||
void update_emitters(float dt);
|
||||
|
||||
private:
|
||||
int _width;
|
||||
int _height;
|
||||
|
||||
Reference in New Issue
Block a user