restore my error
This commit is contained in:
@@ -1,55 +1,55 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(qglengine)
|
||||
find_package(QAD REQUIRED)
|
||||
set(_DOMAIN "org.SHS")
|
||||
set(_COMPANY "SHS")
|
||||
find_qt(Qt5 Core Gui OpenGL Xml)
|
||||
if (NOT Qt5)
|
||||
message(WARNING "Building ${PROJECT_NAME} available only on Qt5!")
|
||||
else()
|
||||
find_package(OpenGL REQUIRED)
|
||||
set_version(qglengine
|
||||
MAJOR 1
|
||||
MINOR 0
|
||||
REVISION 0
|
||||
BUILD "${BUILD_NUMBER}"
|
||||
SUFFIX rc
|
||||
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/core/qglengine_version.h")
|
||||
|
||||
qt_sources(SRC)
|
||||
qt_sources(FSRC DIR "formats")
|
||||
list(APPEND SRC ${FSRC})
|
||||
qt_sources(FSRC DIR "core")
|
||||
list(APPEND SRC ${FSRC})
|
||||
qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM)
|
||||
file(GLOB PHS "*_p.h" "formats/*_p.h" "core/*_p.h")
|
||||
list(REMOVE_ITEM out_HDR "${PHS}")
|
||||
import_version(qglengine_core qglengine)
|
||||
set_deploy_property(qglengine_core SHARED
|
||||
LABEL "QGLEngine core library"
|
||||
FULLNAME "${_DOMAIN}.qglengine_core"
|
||||
COMPANY "${_COMPANY}"
|
||||
INFO "QGLEngine core library")
|
||||
make_rc(qglengine_core _RC)
|
||||
qt_add_library(qglengine_core SHARED out_CPP ${_RC})
|
||||
qt_generate_export_header(qglengine_core)
|
||||
list(APPEND out_HDR "${CMAKE_CURRENT_BINARY_DIR}/qglengine_core_export.h")
|
||||
qt_target_include_directories(qglengine_core PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/core")
|
||||
qt_target_link_libraries(qglengine_core qad_utils qad_widgets assimp ${OPENGL_LIBRARIES})
|
||||
message(STATUS "Building QGLEngine version ${qglengine_VERSION} (SHARED)")
|
||||
list(APPEND QT_MULTILIB_LIST qglengine_core)
|
||||
add_subdirectory(widgets)
|
||||
copy_to_parent("")
|
||||
sdk_install("qglengine" FALSE "qglengine_core" "${out_HDR}" "${out_QM}")
|
||||
if (NOT DEFINED ANDROID_PLATFORM)
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plugin")
|
||||
#add_subdirectory(plugin)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt_sources(test_SRC DIR "qglview_test")
|
||||
qt_wrap(${test_SRC} CPPS test_CPP)
|
||||
qt_add_executable(qglengine_test test_CPP)
|
||||
qt_target_link_libraries(qglengine_test qglengine_core qglengine_widgets)
|
||||
qt_target_include_directories(qglengine_test PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/core" "${CMAKE_CURRENT_SOURCE_DIR}/widgets")
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(qglengine)
|
||||
find_package(QAD REQUIRED)
|
||||
set(_DOMAIN "org.SHS")
|
||||
set(_COMPANY "SHS")
|
||||
find_qt(Qt5 Core Gui OpenGL Xml)
|
||||
if (NOT Qt5)
|
||||
message(WARNING "Building ${PROJECT_NAME} available only on Qt5!")
|
||||
else()
|
||||
find_package(OpenGL REQUIRED)
|
||||
set_version(qglengine
|
||||
MAJOR 1
|
||||
MINOR 0
|
||||
REVISION 0
|
||||
BUILD "${BUILD_NUMBER}"
|
||||
SUFFIX rc
|
||||
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/core/qglengine_version.h")
|
||||
|
||||
qt_sources(SRC)
|
||||
qt_sources(FSRC DIR "formats")
|
||||
list(APPEND SRC ${FSRC})
|
||||
qt_sources(FSRC DIR "core")
|
||||
list(APPEND SRC ${FSRC})
|
||||
qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM)
|
||||
file(GLOB PHS "*_p.h" "formats/*_p.h" "core/*_p.h")
|
||||
list(REMOVE_ITEM out_HDR "${PHS}")
|
||||
import_version(qglengine_core qglengine)
|
||||
set_deploy_property(qglengine_core SHARED
|
||||
LABEL "QGLEngine core library"
|
||||
FULLNAME "${_DOMAIN}.qglengine_core"
|
||||
COMPANY "${_COMPANY}"
|
||||
INFO "QGLEngine core library")
|
||||
make_rc(qglengine_core _RC)
|
||||
qt_add_library(qglengine_core SHARED out_CPP ${_RC})
|
||||
qt_generate_export_header(qglengine_core)
|
||||
list(APPEND out_HDR "${CMAKE_CURRENT_BINARY_DIR}/qglengine_core_export.h")
|
||||
qt_target_include_directories(qglengine_core PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/core")
|
||||
qt_target_link_libraries(qglengine_core qad_utils qad_widgets assimp ${OPENGL_LIBRARIES})
|
||||
message(STATUS "Building QGLEngine version ${qglengine_VERSION} (SHARED)")
|
||||
list(APPEND QT_MULTILIB_LIST qglengine_core)
|
||||
add_subdirectory(widgets)
|
||||
copy_to_parent("")
|
||||
sdk_install("qglengine" FALSE "qglengine_core" "${out_HDR}" "${out_QM}")
|
||||
if (NOT DEFINED ANDROID_PLATFORM)
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plugin")
|
||||
#add_subdirectory(plugin)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt_sources(test_SRC DIR "qglview_test")
|
||||
qt_wrap(${test_SRC} CPPS test_CPP)
|
||||
qt_add_executable(qglengine_test test_CPP)
|
||||
qt_target_link_libraries(qglengine_test qglengine_core qglengine_widgets)
|
||||
qt_target_include_directories(qglengine_test PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/core" "${CMAKE_CURRENT_SOURCE_DIR}/widgets")
|
||||
endif()
|
||||
|
||||
@@ -1,240 +1,240 @@
|
||||
/*
|
||||
QGL GLWidget
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "glwidget.h"
|
||||
#include "qglview.h"
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
||||
GLWidget::GLWidget(QWidget *parent) : QWidget(parent) {
|
||||
view_ = new QGLView();
|
||||
view_->setFlags(windowFlags() | Qt::FramelessWindowHint);
|
||||
container = QWidget::createWindowContainer(view_, this);
|
||||
lay = new QVBoxLayout(this);
|
||||
lay->addWidget(container);
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
lay->setSpacing(0);
|
||||
setMouseTracking(true);
|
||||
setWindowIcon(QIcon("://icons/qglview.png"));
|
||||
connect(view_, &QGLView::doubleClick, this, &GLWidget::viewDoubleClicked);
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::backColor() const {
|
||||
return view_->backColor();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::lineWidth() const {
|
||||
return view_->lineWidth();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::FOV() const {
|
||||
return view_->FOV();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::depthStart() const {
|
||||
return view_->depthStart();
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::ambientColor() const {
|
||||
return view_->ambientColor();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isLightEnabled() const {
|
||||
return view_->isLightEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isGrabMouseEnabled() const {
|
||||
return view_->isGrabMouseEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isMouseRotateEnabled() const {
|
||||
return view_->isMouseRotateEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isMouseSelectionEnabled() const {
|
||||
return view_->isMouseSelectionEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isCameraOrbit() const
|
||||
{
|
||||
return view_->isCameraOrbit();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isHoverHaloEnabled() const {
|
||||
return view_->isHoverHaloEnabled();
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::hoverHaloColor() const {
|
||||
return view_->hoverHaloColor();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::hoverHaloFillAlpha() const {
|
||||
return view_->hoverHaloFillAlpha();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isSelectionHaloEnabled() const {
|
||||
return view_->isSelectionHaloEnabled();
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::selectionHaloColor() const {
|
||||
return view_->selectionHaloColor();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::selectionHaloFillAlpha() const {
|
||||
return view_->selectionHaloFillAlpha();
|
||||
}
|
||||
|
||||
|
||||
Scene * GLWidget::scene() {
|
||||
return view_->scene();
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::addObject(ObjectBase * o) {
|
||||
view_->scene()->addObject(o);
|
||||
}
|
||||
|
||||
|
||||
QByteArray GLWidget::saveCamera() {
|
||||
return view_->saveCamera();
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::restoreCamera(const QByteArray &ba) {
|
||||
view_->restoreCamera(ba);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::stop() {
|
||||
view_->stop();
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::start(float freq) {
|
||||
view_->start(freq);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setBackColor(const QColor & c) {
|
||||
view_->setBackColor(c);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setLineWidth(const qreal & arg) {
|
||||
view_->setLineWidth(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setFOV(const qreal & arg) {
|
||||
view_->setFOV(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setDepthStart(const qreal & arg) {
|
||||
view_->setDepthStart(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setAmbientColor(const QColor & arg) {
|
||||
view_->setAmbientColor(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setLightEnabled(const bool & arg) {
|
||||
view_->setLightEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setGrabMouseEnabled(const bool & arg) {
|
||||
view_->setGrabMouseEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setMouseRotateEnabled(const bool & arg) {
|
||||
view_->setMouseRotateEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setMouseSelectionEnabled(const bool & arg) {
|
||||
view_->setMouseSelectionEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setCameraOrbit(const bool & arg) {
|
||||
view_->setCameraOrbit(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setHoverHaloEnabled(const bool & arg) {
|
||||
view_->setHoverHaloEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setHoverHaloColor(const QColor & arg) {
|
||||
view_->setHoverHaloColor(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setHoverHaloFillAlpha(const qreal & arg) {
|
||||
view_->setHoverHaloFillAlpha(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setSelectionHaloEnabled(const bool & arg) {
|
||||
view_->setSelectionHaloEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setSelectionHaloColor(const QColor & arg) {
|
||||
view_->setSelectionHaloColor(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setSelectionHaloFillAlpha(const qreal & arg) {
|
||||
view_->setSelectionHaloFillAlpha(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::viewDoubleClicked() {
|
||||
if (view_->windowState() == Qt::WindowFullScreen) {
|
||||
view_->showNormal();
|
||||
container = QWidget::createWindowContainer(view_, this);
|
||||
lay->addWidget(container);
|
||||
container->show();
|
||||
} else {
|
||||
view_->setParent(nullptr);
|
||||
view_->showFullScreen();
|
||||
lay->removeWidget(container);
|
||||
}
|
||||
}
|
||||
/*
|
||||
QGL GLWidget
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "glwidget.h"
|
||||
#include "qglview.h"
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
||||
GLWidget::GLWidget(QWidget *parent) : QWidget(parent) {
|
||||
view_ = new QGLView();
|
||||
view_->setFlags(windowFlags() | Qt::FramelessWindowHint);
|
||||
container = QWidget::createWindowContainer(view_, this);
|
||||
lay = new QVBoxLayout(this);
|
||||
lay->addWidget(container);
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
lay->setSpacing(0);
|
||||
setMouseTracking(true);
|
||||
setWindowIcon(QIcon("://icons/qglview.png"));
|
||||
connect(view_, &QGLView::doubleClick, this, &GLWidget::viewDoubleClicked);
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::backColor() const {
|
||||
return view_->backColor();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::lineWidth() const {
|
||||
return view_->lineWidth();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::FOV() const {
|
||||
return view_->FOV();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::depthStart() const {
|
||||
return view_->depthStart();
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::ambientColor() const {
|
||||
return view_->ambientColor();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isLightEnabled() const {
|
||||
return view_->isLightEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isGrabMouseEnabled() const {
|
||||
return view_->isGrabMouseEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isMouseRotateEnabled() const {
|
||||
return view_->isMouseRotateEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isMouseSelectionEnabled() const {
|
||||
return view_->isMouseSelectionEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isCameraOrbit() const
|
||||
{
|
||||
return view_->isCameraOrbit();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isHoverHaloEnabled() const {
|
||||
return view_->isHoverHaloEnabled();
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::hoverHaloColor() const {
|
||||
return view_->hoverHaloColor();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::hoverHaloFillAlpha() const {
|
||||
return view_->hoverHaloFillAlpha();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isSelectionHaloEnabled() const {
|
||||
return view_->isSelectionHaloEnabled();
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::selectionHaloColor() const {
|
||||
return view_->selectionHaloColor();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::selectionHaloFillAlpha() const {
|
||||
return view_->selectionHaloFillAlpha();
|
||||
}
|
||||
|
||||
|
||||
Scene * GLWidget::scene() {
|
||||
return view_->scene();
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::addObject(ObjectBase * o) {
|
||||
view_->scene()->addObject(o);
|
||||
}
|
||||
|
||||
|
||||
QByteArray GLWidget::saveCamera() {
|
||||
return view_->saveCamera();
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::restoreCamera(const QByteArray &ba) {
|
||||
view_->restoreCamera(ba);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::stop() {
|
||||
view_->stop();
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::start(float freq) {
|
||||
view_->start(freq);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setBackColor(const QColor & c) {
|
||||
view_->setBackColor(c);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setLineWidth(const qreal & arg) {
|
||||
view_->setLineWidth(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setFOV(const qreal & arg) {
|
||||
view_->setFOV(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setDepthStart(const qreal & arg) {
|
||||
view_->setDepthStart(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setAmbientColor(const QColor & arg) {
|
||||
view_->setAmbientColor(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setLightEnabled(const bool & arg) {
|
||||
view_->setLightEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setGrabMouseEnabled(const bool & arg) {
|
||||
view_->setGrabMouseEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setMouseRotateEnabled(const bool & arg) {
|
||||
view_->setMouseRotateEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setMouseSelectionEnabled(const bool & arg) {
|
||||
view_->setMouseSelectionEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setCameraOrbit(const bool & arg) {
|
||||
view_->setCameraOrbit(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setHoverHaloEnabled(const bool & arg) {
|
||||
view_->setHoverHaloEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setHoverHaloColor(const QColor & arg) {
|
||||
view_->setHoverHaloColor(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setHoverHaloFillAlpha(const qreal & arg) {
|
||||
view_->setHoverHaloFillAlpha(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setSelectionHaloEnabled(const bool & arg) {
|
||||
view_->setSelectionHaloEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setSelectionHaloColor(const QColor & arg) {
|
||||
view_->setSelectionHaloColor(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setSelectionHaloFillAlpha(const qreal & arg) {
|
||||
view_->setSelectionHaloFillAlpha(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::viewDoubleClicked() {
|
||||
if (view_->windowState() == Qt::WindowFullScreen) {
|
||||
view_->showNormal();
|
||||
container = QWidget::createWindowContainer(view_, this);
|
||||
lay->addWidget(container);
|
||||
container->show();
|
||||
} else {
|
||||
view_->setParent(nullptr);
|
||||
view_->showFullScreen();
|
||||
lay->removeWidget(container);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,104 +1,104 @@
|
||||
/*
|
||||
QGL GLWidget
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLWIDGET_H
|
||||
#define GLWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
class QGLView;
|
||||
class ObjectBase;
|
||||
class Scene;
|
||||
|
||||
class GLWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor)
|
||||
Q_PROPERTY (qreal lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY (qreal FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY (qreal depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor)
|
||||
Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY (qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY (qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
public:
|
||||
explicit GLWidget(QWidget *parent = nullptr);
|
||||
QGLView * view() {return view_;}
|
||||
|
||||
QColor backColor() const;
|
||||
qreal lineWidth() const;
|
||||
qreal FOV() const;
|
||||
qreal depthStart() const;
|
||||
QColor ambientColor() const;
|
||||
bool isLightEnabled() const;
|
||||
bool isGrabMouseEnabled() const;
|
||||
bool isMouseRotateEnabled() const;
|
||||
bool isMouseSelectionEnabled() const;
|
||||
bool isCameraOrbit() const;
|
||||
bool isHoverHaloEnabled() const;
|
||||
QColor hoverHaloColor() const;
|
||||
qreal hoverHaloFillAlpha() const;
|
||||
bool isSelectionHaloEnabled() const;
|
||||
QColor selectionHaloColor() const;
|
||||
qreal selectionHaloFillAlpha() const;
|
||||
Scene * scene();
|
||||
|
||||
void addObject(ObjectBase * o);
|
||||
QByteArray saveCamera();
|
||||
void restoreCamera(const QByteArray & ba);
|
||||
|
||||
public slots:
|
||||
void stop();
|
||||
void start(float freq = 60.0);
|
||||
void setBackColor(const QColor & c);
|
||||
void setLineWidth(const qreal & arg);
|
||||
void setFOV(const qreal & arg);
|
||||
void setDepthStart(const qreal & arg);
|
||||
void setAmbientColor(const QColor & arg);
|
||||
void setLightEnabled(const bool & arg);
|
||||
void setGrabMouseEnabled(const bool & arg);
|
||||
void setMouseRotateEnabled(const bool & arg);
|
||||
void setMouseSelectionEnabled(const bool & arg);
|
||||
void setCameraOrbit(const bool & arg);
|
||||
void setHoverHaloEnabled(const bool & arg);
|
||||
void setHoverHaloColor(const QColor & arg);
|
||||
void setHoverHaloFillAlpha(const qreal & arg);
|
||||
void setSelectionHaloEnabled(const bool & arg);
|
||||
void setSelectionHaloColor(const QColor & arg);
|
||||
void setSelectionHaloFillAlpha(const qreal & arg);
|
||||
|
||||
private slots:
|
||||
void viewDoubleClicked();
|
||||
|
||||
private:
|
||||
QWidget * container;
|
||||
QGLView * view_;
|
||||
QLayout * lay;
|
||||
|
||||
signals:
|
||||
};
|
||||
|
||||
#endif // GLWIDGET_H
|
||||
/*
|
||||
QGL GLWidget
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLWIDGET_H
|
||||
#define GLWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
class QGLView;
|
||||
class ObjectBase;
|
||||
class Scene;
|
||||
|
||||
class GLWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor)
|
||||
Q_PROPERTY (qreal lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY (qreal FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY (qreal depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor)
|
||||
Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY (qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY (qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
public:
|
||||
explicit GLWidget(QWidget *parent = nullptr);
|
||||
QGLView * view() {return view_;}
|
||||
|
||||
QColor backColor() const;
|
||||
qreal lineWidth() const;
|
||||
qreal FOV() const;
|
||||
qreal depthStart() const;
|
||||
QColor ambientColor() const;
|
||||
bool isLightEnabled() const;
|
||||
bool isGrabMouseEnabled() const;
|
||||
bool isMouseRotateEnabled() const;
|
||||
bool isMouseSelectionEnabled() const;
|
||||
bool isCameraOrbit() const;
|
||||
bool isHoverHaloEnabled() const;
|
||||
QColor hoverHaloColor() const;
|
||||
qreal hoverHaloFillAlpha() const;
|
||||
bool isSelectionHaloEnabled() const;
|
||||
QColor selectionHaloColor() const;
|
||||
qreal selectionHaloFillAlpha() const;
|
||||
Scene * scene();
|
||||
|
||||
void addObject(ObjectBase * o);
|
||||
QByteArray saveCamera();
|
||||
void restoreCamera(const QByteArray & ba);
|
||||
|
||||
public slots:
|
||||
void stop();
|
||||
void start(float freq = 60.0);
|
||||
void setBackColor(const QColor & c);
|
||||
void setLineWidth(const qreal & arg);
|
||||
void setFOV(const qreal & arg);
|
||||
void setDepthStart(const qreal & arg);
|
||||
void setAmbientColor(const QColor & arg);
|
||||
void setLightEnabled(const bool & arg);
|
||||
void setGrabMouseEnabled(const bool & arg);
|
||||
void setMouseRotateEnabled(const bool & arg);
|
||||
void setMouseSelectionEnabled(const bool & arg);
|
||||
void setCameraOrbit(const bool & arg);
|
||||
void setHoverHaloEnabled(const bool & arg);
|
||||
void setHoverHaloColor(const QColor & arg);
|
||||
void setHoverHaloFillAlpha(const qreal & arg);
|
||||
void setSelectionHaloEnabled(const bool & arg);
|
||||
void setSelectionHaloColor(const QColor & arg);
|
||||
void setSelectionHaloFillAlpha(const qreal & arg);
|
||||
|
||||
private slots:
|
||||
void viewDoubleClicked();
|
||||
|
||||
private:
|
||||
QWidget * container;
|
||||
QGLView * view_;
|
||||
QLayout * lay;
|
||||
|
||||
signals:
|
||||
};
|
||||
|
||||
#endif // GLWIDGET_H
|
||||
|
||||
@@ -1,289 +1,289 @@
|
||||
/*
|
||||
QGL MouseController
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "mouse_controller.h"
|
||||
#include "glmesh.h"
|
||||
#include "qglview.h"
|
||||
#include <qad_types.h>
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
|
||||
using namespace QGLEngineShaders;
|
||||
|
||||
|
||||
MouseController::MouseController(QGLView * view_): view(view_) {
|
||||
app_scale = 1;
|
||||
lastPos = QPoint(-1, -1);
|
||||
cur_action = RendererService::haNoAction;
|
||||
sel_button = Qt::LeftButton;
|
||||
sel_mod = Qt::ControlModifier;
|
||||
mouse_first = mouseSelect_ = mouseRotate_ = cameraOrbit_ = canSelect_ = true;
|
||||
grabMouse_ = mouse_sec = selecting_ = customMouseMove_ = false;
|
||||
}
|
||||
|
||||
|
||||
MouseController::~MouseController() {
|
||||
}
|
||||
|
||||
|
||||
void MouseController::resize() {
|
||||
mouse_first = true;
|
||||
app_scale = appScale();
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mouseReleaseEvent(QMouseEvent * e) {
|
||||
if (cur_action != RendererService::haNoAction) {
|
||||
mouseMoveEvent(e);
|
||||
return;
|
||||
}
|
||||
bool add_ts = e->modifiers().testFlag(sel_mod);
|
||||
if (selecting_) {
|
||||
selecting_ = false;
|
||||
canSelect_ = true;
|
||||
view->renderer_.mouse_rect = QRect();
|
||||
view->scene_->selectObjects(hov_objects.toList(), add_ts);
|
||||
return;
|
||||
}
|
||||
if (canSelect_ && mouseSelect_) {
|
||||
if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance()) {
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
//qDebug() << hov_objects << hov_aims;
|
||||
if (hov_objects.isEmpty() && hov_aims.isEmpty()) {
|
||||
view->scene()->clearSelection();
|
||||
} else {
|
||||
if (!hov_objects.isEmpty())
|
||||
view->scene_->selectObject(hov_objects[0], add_ts);
|
||||
if (!hov_aims.isEmpty()) {
|
||||
view->scene_->selectObject(hov_aims[0], add_ts);
|
||||
hov_aims[0]->selected_aim = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e->button() == Qt::RightButton) {
|
||||
if (view->renderer_.edit_mode && !view->scene()->selectedObjects().isEmpty())
|
||||
view->context_menu.popup(e->globalPos());
|
||||
}
|
||||
}
|
||||
}
|
||||
canSelect_ = e->buttons() == 0;
|
||||
emit view->glMouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mousePressEvent(QMouseEvent * e) {
|
||||
downPos = e->pos();
|
||||
if (cur_action != RendererService::haNoAction && e->buttons() == Qt::LeftButton) {
|
||||
return;
|
||||
}
|
||||
if (selecting_) {
|
||||
selecting_ = false;
|
||||
view->renderer_.mouse_rect = QRect();
|
||||
return;
|
||||
}
|
||||
if (!QRect(QPoint(), view->size()).contains(e->pos())) return;
|
||||
lastPos = e->pos();
|
||||
downPos = e->pos();
|
||||
emit view->glMousePressEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mouseMoveEvent(QMouseEvent * e) {
|
||||
QPoint cpos = e->pos();
|
||||
if (cur_action != RendererService::haNoAction && (e->buttons() == Qt::LeftButton)) {
|
||||
RendererService & rs(view->renderer_.rend_service);
|
||||
ObjectBaseList objects = view->scene_->selectedObjects(true);
|
||||
QVector<int> axis;
|
||||
switch (cur_action) {
|
||||
case RendererService::haMove:
|
||||
if (cur_handle.testFlag(RendererService::hmMoveX)) axis << 0;
|
||||
if (cur_handle.testFlag(RendererService::hmMoveY)) axis << 1;
|
||||
if (cur_handle.testFlag(RendererService::hmMoveZ)) axis << 2;
|
||||
break;
|
||||
case RendererService::haRotate:
|
||||
if (cur_handle.testFlag(RendererService::hmRotateX)) axis << 0;
|
||||
if (cur_handle.testFlag(RendererService::hmRotateY)) axis << 1;
|
||||
if (cur_handle.testFlag(RendererService::hmRotateZ)) axis << 2;
|
||||
break;
|
||||
case RendererService::haScale:
|
||||
if (cur_handle.testFlag(RendererService::hmScaleX)) axis << 0;
|
||||
if (cur_handle.testFlag(RendererService::hmScaleY)) axis << 1;
|
||||
if (cur_handle.testFlag(RendererService::hmScaleZ)) axis << 2;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
QVector<QVector3D> scales;
|
||||
foreach (int a, axis) {
|
||||
QVector3D axe_vector; axe_vector[a] = 1.;
|
||||
QMatrix4x4 axis_mat = view->camera()->fullViewMatrix() * rs.axis_mat;
|
||||
QVector3D center_screen = axis_mat * rs.selection_center;
|
||||
QVector3D axe_screen = ((axis_mat * (rs.selection_center + axe_vector)) - center_screen).normalized();
|
||||
QVector3D mouse_vector(cpos - lastPos);
|
||||
mouse_vector[1] *= -1.;
|
||||
if (cur_action == RendererService::haMove) {
|
||||
double len_scl = 1. / QVector3D(axe_screen.x(), axe_screen.y(), 1.E-6).length();
|
||||
mouse_vector /= QVector3D(view->width(), view->height(), 1);
|
||||
mouse_vector *= -center_screen.z() * len_scl;
|
||||
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
||||
QMatrix4x4 pmat;
|
||||
foreach (ObjectBase * o, objects) {
|
||||
pmat.setToIdentity();
|
||||
if (o->parent())
|
||||
pmat = o->parent()->worldTransform().inverted();
|
||||
QVector3D dv = pmat.mapVector(axe_vector);
|
||||
if (o->selected_aim) {
|
||||
AimedObject * ao = (AimedObject*)o;
|
||||
ao->setAim(ao->aim() + dv);
|
||||
} else
|
||||
o->move(dv);
|
||||
}
|
||||
}
|
||||
if (cur_action == RendererService::haRotate) {
|
||||
axe_screen.setZ(0.);
|
||||
axe_screen.normalize();
|
||||
QVector3D norm = QVector3D(axe_screen.y(), -axe_screen.x(), 0.);
|
||||
axe_vector *= QVector3D::dotProduct(mouse_vector, norm) / 2. / app_scale;
|
||||
foreach (ObjectBase * o, objects)
|
||||
o->setRotation(o->rotation() + axe_vector);
|
||||
}
|
||||
if (cur_action == RendererService::haScale) {
|
||||
mouse_vector /= QVector3D(view->width(), view->height(), 1);
|
||||
mouse_vector *= 3. / app_scale;
|
||||
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
||||
scales << axe_vector;
|
||||
}
|
||||
}
|
||||
//if (cur_handle >= RendererService::htScaleX && cur_handle <= RendererService::htScaleZ ) cs = Qt::SplitHCursor;
|
||||
if (cur_action == RendererService::haScale) {
|
||||
double sc = 0., max = 0.;
|
||||
foreach (const QVector3D & s, scales) {
|
||||
double v = QVector3D::dotProduct(s, QVector3D(1,1,1));
|
||||
sc += v;
|
||||
max = qMax(max, qAbs(v));
|
||||
}
|
||||
sc = max * (sc > 0. ? 1. : -1);
|
||||
QVector3D axe_vector;
|
||||
foreach (int a, axis)
|
||||
axe_vector[a] = 1.;
|
||||
foreach (ObjectBase * o, objects)
|
||||
o->scale(QVector3D(1,1,1) + (axe_vector * sc));
|
||||
QCursor::setPos(view->mapToGlobal(downPos));
|
||||
} else
|
||||
lastPos = e->pos();
|
||||
emit view->objectsPositionChanged();
|
||||
return;
|
||||
}
|
||||
if (selecting_) {
|
||||
view->renderer_.mouse_rect = QRect(downPos, cpos).normalized();
|
||||
return;
|
||||
}
|
||||
if (e->buttons().testFlag(Qt::LeftButton)) {
|
||||
if ((cpos - downPos).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
selecting_ = true;
|
||||
canSelect_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
QRect g_rect(QPoint(), view->size());
|
||||
if (mouseRotate_) {
|
||||
float dx = e->x() - lastPos.x();
|
||||
float dy = e->y() - lastPos.y();
|
||||
if (e->buttons().testFlag(Qt::MidButton)) {
|
||||
if (cameraOrbit_) {
|
||||
view->camera()->orbitZ (dx / 4.f);
|
||||
view->camera()->orbitXY(dy / 4.f);
|
||||
} else {
|
||||
view->camera()->rotateZ(-dx / 4.f);
|
||||
view->camera()->rotateX(-dy / 4.f);
|
||||
}
|
||||
emit view->cameraPosChanged(view->camera()->pos());
|
||||
} else if (e->buttons().testFlag(Qt::RightButton)) {
|
||||
float ad = view->camera()->distance();
|
||||
view->camera()->moveLeft(dx / 1000.f * ad);
|
||||
view->camera()->moveUp (dy / 1000.f * ad);
|
||||
emit view->cameraPosChanged(view->camera()->pos());
|
||||
}
|
||||
}
|
||||
if (customMouseMove_) emit view->customMouseMoveEvent(e->pos(), lastPos, e->buttons());
|
||||
lastPos = e->pos();
|
||||
if (e->buttons() == 0) {
|
||||
cur_handle = 0;
|
||||
cur_action = RendererService::haNoAction;
|
||||
Qt::CursorShape cs = Qt::CrossCursor;
|
||||
if (view->renderer_.edit_mode) {
|
||||
uint hid = view->renderer_.rend_selection.id_hover;
|
||||
cur_handle = (RendererService::HandleMesh)hid;
|
||||
if (hid >= RendererService::hmMoveX && hid <= RendererService::hmMaxMove ) {
|
||||
cur_action = RendererService::haMove;
|
||||
cs = Qt::SizeAllCursor;
|
||||
}
|
||||
if (hid >= RendererService::hmRotateX && hid <= RendererService::hmMaxRotate) {
|
||||
cur_action = RendererService::haRotate;
|
||||
cs = Qt::PointingHandCursor;
|
||||
}
|
||||
if (hid >= RendererService::hmScaleX && hid <= RendererService::hmMaxScale ) {
|
||||
cur_action = RendererService::haScale;
|
||||
cs = Qt::SplitHCursor;
|
||||
}
|
||||
}
|
||||
if (cur_action == RendererService::haNoAction)
|
||||
cur_handle = 0;
|
||||
view->setCursor(cs);
|
||||
view->renderer_.rend_service.current_handle = cur_handle;
|
||||
}
|
||||
if (grabMouse_) {
|
||||
QCursor::setPos(view->mapToGlobal(QRect(QPoint(), view->size()).center()));
|
||||
if (mouse_sec) {
|
||||
mouse_sec = false;
|
||||
return;
|
||||
}
|
||||
if (mouse_first) {
|
||||
mouse_first = false;
|
||||
mouse_sec = true;
|
||||
return;
|
||||
}
|
||||
lastPos = g_rect.center();
|
||||
int dx = e->x() - lastPos.x();
|
||||
int dy = e->y() - lastPos.y();
|
||||
emit view->glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers()));
|
||||
return;
|
||||
}
|
||||
emit view->glMouseMoveEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::wheelEvent(QWheelEvent * e) {
|
||||
if (mouseRotate_) {
|
||||
if (e->delta() > 0) view->camera()->flyCloser(0.1f);
|
||||
if (e->delta() < 0) view->camera()->flyFarer(0.1f);
|
||||
emit view->cameraPosChanged(view->camera()->pos());
|
||||
}
|
||||
emit view->glWheelEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::leaveEvent(QEvent * ) {
|
||||
lastPos = QPoint(-1, -1);
|
||||
//qDebug() << lastPos;
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mouseDoubleClickEvent(QMouseEvent * e) {
|
||||
if (e->buttons().testFlag(Qt::MidButton))
|
||||
emit view->doubleClick();
|
||||
}
|
||||
/*
|
||||
QGL MouseController
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "mouse_controller.h"
|
||||
#include "glmesh.h"
|
||||
#include "qglview.h"
|
||||
#include <qad_types.h>
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
|
||||
using namespace QGLEngineShaders;
|
||||
|
||||
|
||||
MouseController::MouseController(QGLView * view_): view(view_) {
|
||||
app_scale = 1;
|
||||
lastPos = QPoint(-1, -1);
|
||||
cur_action = RendererService::haNoAction;
|
||||
sel_button = Qt::LeftButton;
|
||||
sel_mod = Qt::ControlModifier;
|
||||
mouse_first = mouseSelect_ = mouseRotate_ = cameraOrbit_ = canSelect_ = true;
|
||||
grabMouse_ = mouse_sec = selecting_ = customMouseMove_ = false;
|
||||
}
|
||||
|
||||
|
||||
MouseController::~MouseController() {
|
||||
}
|
||||
|
||||
|
||||
void MouseController::resize() {
|
||||
mouse_first = true;
|
||||
app_scale = appScale();
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mouseReleaseEvent(QMouseEvent * e) {
|
||||
if (cur_action != RendererService::haNoAction) {
|
||||
mouseMoveEvent(e);
|
||||
return;
|
||||
}
|
||||
bool add_ts = e->modifiers().testFlag(sel_mod);
|
||||
if (selecting_) {
|
||||
selecting_ = false;
|
||||
canSelect_ = true;
|
||||
view->renderer_.mouse_rect = QRect();
|
||||
view->scene_->selectObjects(hov_objects.toList(), add_ts);
|
||||
return;
|
||||
}
|
||||
if (canSelect_ && mouseSelect_) {
|
||||
if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance()) {
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
//qDebug() << hov_objects << hov_aims;
|
||||
if (hov_objects.isEmpty() && hov_aims.isEmpty()) {
|
||||
view->scene()->clearSelection();
|
||||
} else {
|
||||
if (!hov_objects.isEmpty())
|
||||
view->scene_->selectObject(hov_objects[0], add_ts);
|
||||
if (!hov_aims.isEmpty()) {
|
||||
view->scene_->selectObject(hov_aims[0], add_ts);
|
||||
hov_aims[0]->selected_aim = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e->button() == Qt::RightButton) {
|
||||
if (view->renderer_.edit_mode && !view->scene()->selectedObjects().isEmpty())
|
||||
view->context_menu.popup(e->globalPos());
|
||||
}
|
||||
}
|
||||
}
|
||||
canSelect_ = e->buttons() == 0;
|
||||
emit view->glMouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mousePressEvent(QMouseEvent * e) {
|
||||
downPos = e->pos();
|
||||
if (cur_action != RendererService::haNoAction && e->buttons() == Qt::LeftButton) {
|
||||
return;
|
||||
}
|
||||
if (selecting_) {
|
||||
selecting_ = false;
|
||||
view->renderer_.mouse_rect = QRect();
|
||||
return;
|
||||
}
|
||||
if (!QRect(QPoint(), view->size()).contains(e->pos())) return;
|
||||
lastPos = e->pos();
|
||||
downPos = e->pos();
|
||||
emit view->glMousePressEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mouseMoveEvent(QMouseEvent * e) {
|
||||
QPoint cpos = e->pos();
|
||||
if (cur_action != RendererService::haNoAction && (e->buttons() == Qt::LeftButton)) {
|
||||
RendererService & rs(view->renderer_.rend_service);
|
||||
ObjectBaseList objects = view->scene_->selectedObjects(true);
|
||||
QVector<int> axis;
|
||||
switch (cur_action) {
|
||||
case RendererService::haMove:
|
||||
if (cur_handle.testFlag(RendererService::hmMoveX)) axis << 0;
|
||||
if (cur_handle.testFlag(RendererService::hmMoveY)) axis << 1;
|
||||
if (cur_handle.testFlag(RendererService::hmMoveZ)) axis << 2;
|
||||
break;
|
||||
case RendererService::haRotate:
|
||||
if (cur_handle.testFlag(RendererService::hmRotateX)) axis << 0;
|
||||
if (cur_handle.testFlag(RendererService::hmRotateY)) axis << 1;
|
||||
if (cur_handle.testFlag(RendererService::hmRotateZ)) axis << 2;
|
||||
break;
|
||||
case RendererService::haScale:
|
||||
if (cur_handle.testFlag(RendererService::hmScaleX)) axis << 0;
|
||||
if (cur_handle.testFlag(RendererService::hmScaleY)) axis << 1;
|
||||
if (cur_handle.testFlag(RendererService::hmScaleZ)) axis << 2;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
QVector<QVector3D> scales;
|
||||
foreach (int a, axis) {
|
||||
QVector3D axe_vector; axe_vector[a] = 1.;
|
||||
QMatrix4x4 axis_mat = view->camera()->fullViewMatrix() * rs.axis_mat;
|
||||
QVector3D center_screen = axis_mat * rs.selection_center;
|
||||
QVector3D axe_screen = ((axis_mat * (rs.selection_center + axe_vector)) - center_screen).normalized();
|
||||
QVector3D mouse_vector(cpos - lastPos);
|
||||
mouse_vector[1] *= -1.;
|
||||
if (cur_action == RendererService::haMove) {
|
||||
double len_scl = 1. / QVector3D(axe_screen.x(), axe_screen.y(), 1.E-6).length();
|
||||
mouse_vector /= QVector3D(view->width(), view->height(), 1);
|
||||
mouse_vector *= -center_screen.z() * len_scl;
|
||||
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
||||
QMatrix4x4 pmat;
|
||||
foreach (ObjectBase * o, objects) {
|
||||
pmat.setToIdentity();
|
||||
if (o->parent())
|
||||
pmat = o->parent()->worldTransform().inverted();
|
||||
QVector3D dv = pmat.mapVector(axe_vector);
|
||||
if (o->selected_aim) {
|
||||
AimedObject * ao = (AimedObject*)o;
|
||||
ao->setAim(ao->aim() + dv);
|
||||
} else
|
||||
o->move(dv);
|
||||
}
|
||||
}
|
||||
if (cur_action == RendererService::haRotate) {
|
||||
axe_screen.setZ(0.);
|
||||
axe_screen.normalize();
|
||||
QVector3D norm = QVector3D(axe_screen.y(), -axe_screen.x(), 0.);
|
||||
axe_vector *= QVector3D::dotProduct(mouse_vector, norm) / 2. / app_scale;
|
||||
foreach (ObjectBase * o, objects)
|
||||
o->setRotation(o->rotation() + axe_vector);
|
||||
}
|
||||
if (cur_action == RendererService::haScale) {
|
||||
mouse_vector /= QVector3D(view->width(), view->height(), 1);
|
||||
mouse_vector *= 3. / app_scale;
|
||||
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
||||
scales << axe_vector;
|
||||
}
|
||||
}
|
||||
//if (cur_handle >= RendererService::htScaleX && cur_handle <= RendererService::htScaleZ ) cs = Qt::SplitHCursor;
|
||||
if (cur_action == RendererService::haScale) {
|
||||
double sc = 0., max = 0.;
|
||||
foreach (const QVector3D & s, scales) {
|
||||
double v = QVector3D::dotProduct(s, QVector3D(1,1,1));
|
||||
sc += v;
|
||||
max = qMax(max, qAbs(v));
|
||||
}
|
||||
sc = max * (sc > 0. ? 1. : -1);
|
||||
QVector3D axe_vector;
|
||||
foreach (int a, axis)
|
||||
axe_vector[a] = 1.;
|
||||
foreach (ObjectBase * o, objects)
|
||||
o->scale(QVector3D(1,1,1) + (axe_vector * sc));
|
||||
QCursor::setPos(view->mapToGlobal(downPos));
|
||||
} else
|
||||
lastPos = e->pos();
|
||||
emit view->objectsPositionChanged();
|
||||
return;
|
||||
}
|
||||
if (selecting_) {
|
||||
view->renderer_.mouse_rect = QRect(downPos, cpos).normalized();
|
||||
return;
|
||||
}
|
||||
if (e->buttons().testFlag(Qt::LeftButton)) {
|
||||
if ((cpos - downPos).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
selecting_ = true;
|
||||
canSelect_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
QRect g_rect(QPoint(), view->size());
|
||||
if (mouseRotate_) {
|
||||
float dx = e->x() - lastPos.x();
|
||||
float dy = e->y() - lastPos.y();
|
||||
if (e->buttons().testFlag(Qt::MidButton)) {
|
||||
if (cameraOrbit_) {
|
||||
view->camera()->orbitZ (dx / 4.f);
|
||||
view->camera()->orbitXY(dy / 4.f);
|
||||
} else {
|
||||
view->camera()->rotateZ(-dx / 4.f);
|
||||
view->camera()->rotateX(-dy / 4.f);
|
||||
}
|
||||
emit view->cameraPosChanged(view->camera()->pos());
|
||||
} else if (e->buttons().testFlag(Qt::RightButton)) {
|
||||
float ad = view->camera()->distance();
|
||||
view->camera()->moveLeft(dx / 1000.f * ad);
|
||||
view->camera()->moveUp (dy / 1000.f * ad);
|
||||
emit view->cameraPosChanged(view->camera()->pos());
|
||||
}
|
||||
}
|
||||
if (customMouseMove_) emit view->customMouseMoveEvent(e->pos(), lastPos, e->buttons());
|
||||
lastPos = e->pos();
|
||||
if (e->buttons() == 0) {
|
||||
cur_handle = 0;
|
||||
cur_action = RendererService::haNoAction;
|
||||
Qt::CursorShape cs = Qt::CrossCursor;
|
||||
if (view->renderer_.edit_mode) {
|
||||
uint hid = view->renderer_.rend_selection.id_hover;
|
||||
cur_handle = (RendererService::HandleMesh)hid;
|
||||
if (hid >= RendererService::hmMoveX && hid <= RendererService::hmMaxMove ) {
|
||||
cur_action = RendererService::haMove;
|
||||
cs = Qt::SizeAllCursor;
|
||||
}
|
||||
if (hid >= RendererService::hmRotateX && hid <= RendererService::hmMaxRotate) {
|
||||
cur_action = RendererService::haRotate;
|
||||
cs = Qt::PointingHandCursor;
|
||||
}
|
||||
if (hid >= RendererService::hmScaleX && hid <= RendererService::hmMaxScale ) {
|
||||
cur_action = RendererService::haScale;
|
||||
cs = Qt::SplitHCursor;
|
||||
}
|
||||
}
|
||||
if (cur_action == RendererService::haNoAction)
|
||||
cur_handle = 0;
|
||||
view->setCursor(cs);
|
||||
view->renderer_.rend_service.current_handle = cur_handle;
|
||||
}
|
||||
if (grabMouse_) {
|
||||
QCursor::setPos(view->mapToGlobal(QRect(QPoint(), view->size()).center()));
|
||||
if (mouse_sec) {
|
||||
mouse_sec = false;
|
||||
return;
|
||||
}
|
||||
if (mouse_first) {
|
||||
mouse_first = false;
|
||||
mouse_sec = true;
|
||||
return;
|
||||
}
|
||||
lastPos = g_rect.center();
|
||||
int dx = e->x() - lastPos.x();
|
||||
int dy = e->y() - lastPos.y();
|
||||
emit view->glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers()));
|
||||
return;
|
||||
}
|
||||
emit view->glMouseMoveEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::wheelEvent(QWheelEvent * e) {
|
||||
if (mouseRotate_) {
|
||||
if (e->delta() > 0) view->camera()->flyCloser(0.1f);
|
||||
if (e->delta() < 0) view->camera()->flyFarer(0.1f);
|
||||
emit view->cameraPosChanged(view->camera()->pos());
|
||||
}
|
||||
emit view->glWheelEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::leaveEvent(QEvent * ) {
|
||||
lastPos = QPoint(-1, -1);
|
||||
//qDebug() << lastPos;
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mouseDoubleClickEvent(QMouseEvent * e) {
|
||||
if (e->buttons().testFlag(Qt::MidButton))
|
||||
emit view->doubleClick();
|
||||
}
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
/*
|
||||
QGL MouseController
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MOUSE_CONTROLLER_H
|
||||
#define MOUSE_CONTROLLER_H
|
||||
|
||||
#include "glprimitives.h"
|
||||
#include "glcamera.h"
|
||||
#include "renderer_service.h"
|
||||
#include <QMouseEvent>
|
||||
#include <QTime>
|
||||
|
||||
|
||||
class MouseController: public QObject
|
||||
{
|
||||
friend class QGLView;
|
||||
friend class RendererSelection;
|
||||
Q_OBJECT
|
||||
public:
|
||||
MouseController(QGLView * view_);
|
||||
virtual ~MouseController();
|
||||
|
||||
bool isGrabMouseEnabled() const {return grabMouse_;}
|
||||
bool isMouseRotateEnabled() const {return mouseRotate_;}
|
||||
bool isMouseSelectionEnabled() const {return mouseSelect_;}
|
||||
bool isCameraOrbit() const {return cameraOrbit_;}
|
||||
|
||||
Qt::MouseButton selectionButton() const {return sel_button;}
|
||||
Qt::KeyboardModifier selectionModifier() const {return sel_mod;}
|
||||
|
||||
void setSelectionButton(Qt::MouseButton v) {sel_button = v;}
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;}
|
||||
|
||||
protected:
|
||||
void resize();
|
||||
void mousePressEvent(QMouseEvent * e);
|
||||
void mouseMoveEvent(QMouseEvent * e);
|
||||
void mouseReleaseEvent(QMouseEvent * e);
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void leaveEvent(QEvent * );
|
||||
void mouseDoubleClickEvent(QMouseEvent * e);
|
||||
|
||||
private:
|
||||
QGLView * view;
|
||||
QPoint lastPos, downPos;
|
||||
QSet<int> keys_;
|
||||
QVector<ObjectBase * > hov_objects, hov_aims;
|
||||
Qt::MouseButton sel_button;
|
||||
Qt::KeyboardModifier sel_mod;
|
||||
RendererService::HandleAction cur_action;
|
||||
QFlags<RendererService::HandleMesh> cur_handle;
|
||||
float app_scale;
|
||||
bool grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_, canSelect_;
|
||||
bool cameraOrbit_, selecting_, mouse_sec;
|
||||
|
||||
private slots:
|
||||
|
||||
public slots:
|
||||
void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;}
|
||||
void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;}
|
||||
void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;}
|
||||
void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;}
|
||||
void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;}
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // QGLVIEW_H
|
||||
/*
|
||||
QGL MouseController
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MOUSE_CONTROLLER_H
|
||||
#define MOUSE_CONTROLLER_H
|
||||
|
||||
#include "glprimitives.h"
|
||||
#include "glcamera.h"
|
||||
#include "renderer_service.h"
|
||||
#include <QMouseEvent>
|
||||
#include <QTime>
|
||||
|
||||
|
||||
class MouseController: public QObject
|
||||
{
|
||||
friend class QGLView;
|
||||
friend class RendererSelection;
|
||||
Q_OBJECT
|
||||
public:
|
||||
MouseController(QGLView * view_);
|
||||
virtual ~MouseController();
|
||||
|
||||
bool isGrabMouseEnabled() const {return grabMouse_;}
|
||||
bool isMouseRotateEnabled() const {return mouseRotate_;}
|
||||
bool isMouseSelectionEnabled() const {return mouseSelect_;}
|
||||
bool isCameraOrbit() const {return cameraOrbit_;}
|
||||
|
||||
Qt::MouseButton selectionButton() const {return sel_button;}
|
||||
Qt::KeyboardModifier selectionModifier() const {return sel_mod;}
|
||||
|
||||
void setSelectionButton(Qt::MouseButton v) {sel_button = v;}
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;}
|
||||
|
||||
protected:
|
||||
void resize();
|
||||
void mousePressEvent(QMouseEvent * e);
|
||||
void mouseMoveEvent(QMouseEvent * e);
|
||||
void mouseReleaseEvent(QMouseEvent * e);
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void leaveEvent(QEvent * );
|
||||
void mouseDoubleClickEvent(QMouseEvent * e);
|
||||
|
||||
private:
|
||||
QGLView * view;
|
||||
QPoint lastPos, downPos;
|
||||
QSet<int> keys_;
|
||||
QVector<ObjectBase * > hov_objects, hov_aims;
|
||||
Qt::MouseButton sel_button;
|
||||
Qt::KeyboardModifier sel_mod;
|
||||
RendererService::HandleAction cur_action;
|
||||
QFlags<RendererService::HandleMesh> cur_handle;
|
||||
float app_scale;
|
||||
bool grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_, canSelect_;
|
||||
bool cameraOrbit_, selecting_, mouse_sec;
|
||||
|
||||
private slots:
|
||||
|
||||
public slots:
|
||||
void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;}
|
||||
void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;}
|
||||
void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;}
|
||||
void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;}
|
||||
void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;}
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // QGLVIEW_H
|
||||
|
||||
@@ -1,113 +1,113 @@
|
||||
/*
|
||||
QGL OpenGLWindow
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "openglwindow.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLPaintDevice>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
OpenGLWindow::OpenGLWindow(QWindow *parent)
|
||||
: QWindow(parent)
|
||||
, m_context(nullptr)
|
||||
, m_device(nullptr)
|
||||
{
|
||||
setFlags(flags() | Qt::FramelessWindowHint);
|
||||
setSurfaceType(QWindow::OpenGLSurface);
|
||||
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
|
||||
// qDebug() << format;
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
format.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||
#else
|
||||
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
|
||||
format.setVersion(4, 0);
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
}
|
||||
#endif
|
||||
format.setDepthBufferSize(24);
|
||||
format.setSamples(8);
|
||||
// format.setStencilBufferSize(8);
|
||||
setFormat(format);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
}
|
||||
|
||||
|
||||
OpenGLWindow::~OpenGLWindow() {
|
||||
delete m_device;
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::render(QPainter *painter) {
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::initialize() {
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::render() {
|
||||
// if (!m_device) m_device = new QOpenGLPaintDevice;
|
||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
// m_device->setSize(size() * devicePixelRatio());
|
||||
// m_device->setDevicePixelRatio(devicePixelRatio());
|
||||
// QPainter painter(m_device);
|
||||
// render(&painter);
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::renderLater() {
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
|
||||
bool OpenGLWindow::event(QEvent *event) {
|
||||
switch (event->type()) {
|
||||
case QEvent::UpdateRequest:
|
||||
renderNow();
|
||||
return true;
|
||||
default:
|
||||
return QWindow::event(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::exposeEvent(QExposeEvent *event) {
|
||||
if (isExposed()) renderNow();
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::renderNow() {
|
||||
if (!isExposed())
|
||||
return;
|
||||
bool needsInitialize = false;
|
||||
if (!m_context) {
|
||||
m_context = new QOpenGLContext(this);
|
||||
m_context->setFormat(requestedFormat());
|
||||
m_context->create();
|
||||
needsInitialize = true;
|
||||
}
|
||||
m_context->makeCurrent(this);
|
||||
if (needsInitialize) {
|
||||
initializeOpenGLFunctions();
|
||||
initialize();
|
||||
}
|
||||
render();
|
||||
m_context->swapBuffers(this);
|
||||
}
|
||||
|
||||
/*
|
||||
QGL OpenGLWindow
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "openglwindow.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLPaintDevice>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
OpenGLWindow::OpenGLWindow(QWindow *parent)
|
||||
: QWindow(parent)
|
||||
, m_context(nullptr)
|
||||
, m_device(nullptr)
|
||||
{
|
||||
setFlags(flags() | Qt::FramelessWindowHint);
|
||||
setSurfaceType(QWindow::OpenGLSurface);
|
||||
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
|
||||
// qDebug() << format;
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
format.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||
#else
|
||||
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
|
||||
format.setVersion(4, 0);
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
}
|
||||
#endif
|
||||
format.setDepthBufferSize(24);
|
||||
format.setSamples(8);
|
||||
// format.setStencilBufferSize(8);
|
||||
setFormat(format);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
}
|
||||
|
||||
|
||||
OpenGLWindow::~OpenGLWindow() {
|
||||
delete m_device;
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::render(QPainter *painter) {
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::initialize() {
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::render() {
|
||||
// if (!m_device) m_device = new QOpenGLPaintDevice;
|
||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
// m_device->setSize(size() * devicePixelRatio());
|
||||
// m_device->setDevicePixelRatio(devicePixelRatio());
|
||||
// QPainter painter(m_device);
|
||||
// render(&painter);
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::renderLater() {
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
|
||||
bool OpenGLWindow::event(QEvent *event) {
|
||||
switch (event->type()) {
|
||||
case QEvent::UpdateRequest:
|
||||
renderNow();
|
||||
return true;
|
||||
default:
|
||||
return QWindow::event(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::exposeEvent(QExposeEvent *event) {
|
||||
if (isExposed()) renderNow();
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::renderNow() {
|
||||
if (!isExposed())
|
||||
return;
|
||||
bool needsInitialize = false;
|
||||
if (!m_context) {
|
||||
m_context = new QOpenGLContext(this);
|
||||
m_context->setFormat(requestedFormat());
|
||||
m_context->create();
|
||||
needsInitialize = true;
|
||||
}
|
||||
m_context->makeCurrent(this);
|
||||
if (needsInitialize) {
|
||||
initializeOpenGLFunctions();
|
||||
initialize();
|
||||
}
|
||||
render();
|
||||
m_context->swapBuffers(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
/*
|
||||
QGL OpenGLWindow
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QWindow>
|
||||
#include <QOpenGLExtraFunctions>
|
||||
|
||||
class QPainter;
|
||||
class QOpenGLContext;
|
||||
class QOpenGLPaintDevice;
|
||||
|
||||
|
||||
class OpenGLWindow: public QWindow, protected QOpenGLExtraFunctions
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OpenGLWindow(QWindow *parent = nullptr);
|
||||
~OpenGLWindow();
|
||||
|
||||
virtual void render(QPainter *painter);
|
||||
virtual void render();
|
||||
|
||||
virtual void initialize();
|
||||
|
||||
QOpenGLContext * context() {return m_context;}
|
||||
|
||||
public slots:
|
||||
void renderLater();
|
||||
void renderNow();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
void exposeEvent(QExposeEvent *event) override;
|
||||
|
||||
private:
|
||||
QOpenGLContext *m_context;
|
||||
QOpenGLPaintDevice *m_device;
|
||||
};
|
||||
|
||||
/*
|
||||
QGL OpenGLWindow
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QWindow>
|
||||
#include <QOpenGLExtraFunctions>
|
||||
|
||||
class QPainter;
|
||||
class QOpenGLContext;
|
||||
class QOpenGLPaintDevice;
|
||||
|
||||
|
||||
class OpenGLWindow: public QWindow, protected QOpenGLExtraFunctions
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OpenGLWindow(QWindow *parent = nullptr);
|
||||
~OpenGLWindow();
|
||||
|
||||
virtual void render(QPainter *painter);
|
||||
virtual void render();
|
||||
|
||||
virtual void initialize();
|
||||
|
||||
QOpenGLContext * context() {return m_context;}
|
||||
|
||||
public slots:
|
||||
void renderLater();
|
||||
void renderNow();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
void exposeEvent(QExposeEvent *event) override;
|
||||
|
||||
private:
|
||||
QOpenGLContext *m_context;
|
||||
QOpenGLPaintDevice *m_device;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
if (DESIGNER_PLUGINS)
|
||||
if (NOT Qt5)
|
||||
message(WARNING "Building ${PROJECT_NAME} available only on Qt5!")
|
||||
else()
|
||||
project(qglengine_plugin)
|
||||
include_directories("..")
|
||||
add_definitions(-DQT_PLUGIN)
|
||||
add_definitions(-DQT_NO_DEBUG)
|
||||
add_definitions(-DQT_SHARED)
|
||||
add_definitions(-DQDESIGNER_EXPORT_WIDGETS)
|
||||
find_qt(Qt5 Core Designer Gui Widgets OpenGL)
|
||||
qt_sources(SRC)
|
||||
qt_wrap(${SRC} CPPS out_CPP QMS out_QM)
|
||||
qt_add_library(${PROJECT_NAME} SHARED out_CPP)
|
||||
qt_target_link_libraries(${PROJECT_NAME} qglengine)
|
||||
qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION QtPlugins/designer)
|
||||
endif()
|
||||
endif()
|
||||
if (DESIGNER_PLUGINS)
|
||||
if (NOT Qt5)
|
||||
message(WARNING "Building ${PROJECT_NAME} available only on Qt5!")
|
||||
else()
|
||||
project(qglengine_plugin)
|
||||
include_directories("..")
|
||||
add_definitions(-DQT_PLUGIN)
|
||||
add_definitions(-DQT_NO_DEBUG)
|
||||
add_definitions(-DQT_SHARED)
|
||||
add_definitions(-DQDESIGNER_EXPORT_WIDGETS)
|
||||
find_qt(Qt5 Core Designer Gui Widgets OpenGL)
|
||||
qt_sources(SRC)
|
||||
qt_wrap(${SRC} CPPS out_CPP QMS out_QM)
|
||||
qt_add_library(${PROJECT_NAME} SHARED out_CPP)
|
||||
qt_target_link_libraries(${PROJECT_NAME} qglengine)
|
||||
qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION QtPlugins/designer)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,299 +1,299 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qglview.h"
|
||||
#include "glmesh.h"
|
||||
#include "gltexture_manager.h"
|
||||
#include <chunkstream.h>
|
||||
#include <qad_types.h>
|
||||
#include <QApplication>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QKeyEvent>
|
||||
|
||||
using namespace QGLEngineShaders;
|
||||
|
||||
|
||||
QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
|
||||
setIcon(QIcon(":/icons/qglview.png"));
|
||||
deleting_ = false;
|
||||
timer = 0;
|
||||
need_init_ = is_first_draw = true;
|
||||
backColor_ = Qt::darkGray;
|
||||
hoverHaloColor_ = QColor(195, 140, 255);
|
||||
selectionHaloColor_ = QColor(175, 255, 140);
|
||||
ambientColor_ = QColor(10, 10, 10);
|
||||
lineWidth_ = 1.;
|
||||
max_anisotropic = 1;
|
||||
max_texture_chanels = 8;
|
||||
lightEnabled_ = true;
|
||||
shaders_supported = false;
|
||||
fps_cnt = 0;
|
||||
fps_tm = fps_ = 0.;
|
||||
fogColor_ = Qt::darkGray;
|
||||
fogDensity_ = 0.;
|
||||
fogDecay_ = 10.;
|
||||
hoverHaloFill_ = selectionHaloFill_ = 0.15f;
|
||||
//lmode = Simple;
|
||||
setFeature(qglFXAA, false);
|
||||
setFeature(qglAnisotropicLevel, 8);
|
||||
setFeature(qglEyeAccomodationEnabled, false);
|
||||
setFeature(qglEyeAccomodationTime, 16.);
|
||||
setFeature(qglEyeAccomodationMaxSpeed, 0.2);
|
||||
setFeature(qglBloomEnabled, false);
|
||||
setFeature(qglBloomThreshold, 0.9);
|
||||
setFeature(qglBloomFactor, 1.);
|
||||
setFeature(qglBloomRadius, 8);
|
||||
setFeature(qglMotionBlurEnabled, false);
|
||||
setFeature(qglMotionBlurFactor, 1.);
|
||||
setFeature(qglMotionBlurSteps, 8);
|
||||
setFeature(qglShadowsEnabled, false);
|
||||
setFeature(qglShadowsMapSize, 512);
|
||||
setFeature(qglShadowsSoftEnabled, true);
|
||||
setFeature(qglReflectionsEnabled, false);
|
||||
setFeature(qglReflectionsBlur, true);
|
||||
setFeature(qglSSAOEnabled, false);
|
||||
setFeature(qglSSAORadius, 5);
|
||||
setFeature(qglDepthOfFieldEnabled, false);
|
||||
setFeature(qglDepthOfFieldAutoFocusEnabled, true);
|
||||
setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1);
|
||||
setFeature(qglDepthOfFieldFocus, 1.);
|
||||
setFeature(qglDepthOfFieldDiaphragm, 8.);
|
||||
hoverHalo_ = selectionHalo_ = true;
|
||||
fogEnabled_ = is_init = shaders_bind = changed_ = false;
|
||||
rmode = ObjectBase::Fill;
|
||||
// sel_pen = QPen(Qt::black, 1, Qt::DashLine);
|
||||
// sel_brush = QBrush(QColor(170, 100, 255, 120));
|
||||
scene_ = new Scene();
|
||||
connect(scene_, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
|
||||
connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed()));
|
||||
connect(scene_, SIGNAL(__objectDeleted(ObjectBase*)), this, SLOT(__objectDeleted(ObjectBase*)));
|
||||
default_camera = new Camera();
|
||||
default_camera->setPos(QVector3D(2, 2, 2));
|
||||
default_camera->setAim(QVector3D());
|
||||
camera_ = default_camera;
|
||||
// qDebug() << camera_->aim();
|
||||
default_camera->setName("Camera");
|
||||
emit cameraPosChanged(default_camera->pos());
|
||||
//camera().aim_ = camera().pos_;
|
||||
ktm_.restart();
|
||||
|
||||
//Mesh * m = Primitive::torus(100, 40, 1., 0.4, 360);
|
||||
Mesh * m = Primitive::cube(10, 10, 10);
|
||||
m->flipNormals();
|
||||
//QMatrix4x4 mat;
|
||||
//mat.rotate(90, 0,1,0);
|
||||
//mat.translate(0, 0, 2);
|
||||
//mat.rotate(180, 1,0,0);
|
||||
//m->transformPoints(mat);
|
||||
ObjectBase * o = new ObjectBase(m);
|
||||
o->setColor(Qt::cyan);
|
||||
scene()->addObject(o);
|
||||
delete m;
|
||||
|
||||
}
|
||||
|
||||
|
||||
QGLView::~QGLView() {
|
||||
deleting_ = true;
|
||||
stop();
|
||||
scene_->clear();
|
||||
delete scene_;
|
||||
delete default_camera;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::stop() {
|
||||
if (timer) killTimer(timer);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::start(float freq) {
|
||||
timer = startTimer(freq <= 0.f ? 0 : int(1000.f / freq));
|
||||
}
|
||||
|
||||
|
||||
QList<Light * > QGLView::selectedLights() const {
|
||||
QList<Light * > ret;
|
||||
ObjectBaseList sol = scene_->selectedObjects();
|
||||
foreach (ObjectBase * o, sol)
|
||||
if (o->type() == ObjectBase::glLight)
|
||||
ret << (Light*)o;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<Camera * > QGLView::selectedCameras() const {
|
||||
QList<Camera * > ret;
|
||||
ObjectBaseList sol = scene_->selectedObjects();
|
||||
foreach (ObjectBase * o, sol)
|
||||
if (o->type() == ObjectBase::glCamera)
|
||||
ret << (Camera*)o;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void QGLView::resizeEvent(QResizeEvent * e) {
|
||||
renderLater();
|
||||
mouse.resize();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::timerEvent(QTimerEvent *) {
|
||||
renderNow();
|
||||
//if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return;
|
||||
Qt::KeyboardModifiers km = QApplication::keyboardModifiers();
|
||||
foreach (int i, keys_)
|
||||
emit keyEvent((Qt::Key)i, km);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::render() {
|
||||
resizeGL(width(), height());
|
||||
emit glBeginPaint();
|
||||
renderer_.mouse_pos = mapFromGlobal(QCursor::pos());
|
||||
renderer_.renderScene();
|
||||
emit glEndPaint();
|
||||
fps_tm += time.elapsed();
|
||||
time.restart();
|
||||
fps_cnt++;
|
||||
if (fps_tm < 1000.) return;
|
||||
fps_ = fps_cnt / fps_tm * 1000.;
|
||||
fps_tm = 0.;
|
||||
fps_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::initialize() {
|
||||
checkCaps();
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP);
|
||||
glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
glCullFace(GL_BACK);
|
||||
renderer_.reloadShaders();
|
||||
renderer_.init(width(), height());
|
||||
is_init = true;
|
||||
need_init_ = false;
|
||||
emit glInitializeDone();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::checkCaps() {
|
||||
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropic);
|
||||
shaders_supported = QOpenGLShaderProgram::hasOpenGLShaderPrograms();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::__destroyed() {
|
||||
renderer_.rend_mat.mat_thumbnails.clear();
|
||||
mouse.hov_objects.clear();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::__objectDeleted(ObjectBase * o) {
|
||||
if (o == camera_)
|
||||
setDefaultCamera();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::resizeGL(int width, int height) {
|
||||
if (!is_init) return;
|
||||
if (width <= 0 || height <= 0) return;
|
||||
if (prev_size == QSize(width, height)) return;
|
||||
prev_size = QSize(width, height);
|
||||
aspect = float(width) / float(height);
|
||||
renderer_.resize(width, height);
|
||||
//qDebug() << "resize" << width << height;
|
||||
iaspect = (aspect == 0.f) ? 0. : 1 / aspect;
|
||||
glViewport(0, 0, width, height);
|
||||
emit glResize(width, height);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::keyPressEvent(QKeyEvent * e) {
|
||||
emit glKeyPressEvent(e);
|
||||
if (e->key() > 0) keys_.insert(e->key());
|
||||
if (e->key() == Qt::Key_F11) {
|
||||
emit doubleClick();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QGLView::keyReleaseEvent(QKeyEvent * e) {
|
||||
emit glKeyReleaseEvent(e);
|
||||
keys_.remove(e->key());
|
||||
}
|
||||
|
||||
|
||||
void QGLView::focusOutEvent(QFocusEvent *) {
|
||||
keys_.clear();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::focusOn(const Box3D & bb) {
|
||||
if (bb.isEmpty() || !camera()) return;
|
||||
double size = qMax(qMax(bb.width, bb.length), bb.height);
|
||||
camera()->setAim(bb.center());
|
||||
camera()->flyToDistance(size * 1.25);
|
||||
}
|
||||
|
||||
|
||||
QByteArray QGLView::saveCamera() {
|
||||
ChunkStream cs;
|
||||
const Camera * c = camera();
|
||||
cs.add(1, c->pos()).add(2, c->aim()).add(3, c->rotation()).add(4, c->FOV());
|
||||
return cs.data();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::restoreCamera(const QByteArray & ba) {
|
||||
if (ba.isEmpty()) return;
|
||||
Camera * c = camera();
|
||||
QVector3D pos(c->pos()), aim(c->aim()), ang(c->rotation());
|
||||
float fov(c->FOV());
|
||||
ChunkStream cs(ba);
|
||||
cs.readAll();
|
||||
cs.get(1, pos).get(2, aim).get(3, ang).get(4, fov);
|
||||
camera()->setPos(pos);
|
||||
camera()->setAim(aim);
|
||||
camera()->setAngles(ang);
|
||||
camera()->setFOV(fov);
|
||||
}
|
||||
|
||||
|
||||
QByteArray QGLView::saveFeatures() {
|
||||
QByteArray ba;
|
||||
QDataStream ds(&ba, QIODevice::WriteOnly);
|
||||
ds << features_;
|
||||
return ba;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::restoreFeatures(const QByteArray & ba) {
|
||||
QHash<int, QVariant> f;
|
||||
QDataStream ds(ba);
|
||||
ds >> f;
|
||||
features_ = f;
|
||||
}
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qglview.h"
|
||||
#include "glmesh.h"
|
||||
#include "gltexture_manager.h"
|
||||
#include <chunkstream.h>
|
||||
#include <qad_types.h>
|
||||
#include <QApplication>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QKeyEvent>
|
||||
|
||||
using namespace QGLEngineShaders;
|
||||
|
||||
|
||||
QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
|
||||
setIcon(QIcon(":/icons/qglview.png"));
|
||||
deleting_ = false;
|
||||
timer = 0;
|
||||
need_init_ = is_first_draw = true;
|
||||
backColor_ = Qt::darkGray;
|
||||
hoverHaloColor_ = QColor(195, 140, 255);
|
||||
selectionHaloColor_ = QColor(175, 255, 140);
|
||||
ambientColor_ = QColor(10, 10, 10);
|
||||
lineWidth_ = 1.;
|
||||
max_anisotropic = 1;
|
||||
max_texture_chanels = 8;
|
||||
lightEnabled_ = true;
|
||||
shaders_supported = false;
|
||||
fps_cnt = 0;
|
||||
fps_tm = fps_ = 0.;
|
||||
fogColor_ = Qt::darkGray;
|
||||
fogDensity_ = 0.;
|
||||
fogDecay_ = 10.;
|
||||
hoverHaloFill_ = selectionHaloFill_ = 0.15f;
|
||||
//lmode = Simple;
|
||||
setFeature(qglFXAA, false);
|
||||
setFeature(qglAnisotropicLevel, 8);
|
||||
setFeature(qglEyeAccomodationEnabled, false);
|
||||
setFeature(qglEyeAccomodationTime, 16.);
|
||||
setFeature(qglEyeAccomodationMaxSpeed, 0.2);
|
||||
setFeature(qglBloomEnabled, false);
|
||||
setFeature(qglBloomThreshold, 0.9);
|
||||
setFeature(qglBloomFactor, 1.);
|
||||
setFeature(qglBloomRadius, 8);
|
||||
setFeature(qglMotionBlurEnabled, false);
|
||||
setFeature(qglMotionBlurFactor, 1.);
|
||||
setFeature(qglMotionBlurSteps, 8);
|
||||
setFeature(qglShadowsEnabled, false);
|
||||
setFeature(qglShadowsMapSize, 512);
|
||||
setFeature(qglShadowsSoftEnabled, true);
|
||||
setFeature(qglReflectionsEnabled, false);
|
||||
setFeature(qglReflectionsBlur, true);
|
||||
setFeature(qglSSAOEnabled, false);
|
||||
setFeature(qglSSAORadius, 5);
|
||||
setFeature(qglDepthOfFieldEnabled, false);
|
||||
setFeature(qglDepthOfFieldAutoFocusEnabled, true);
|
||||
setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1);
|
||||
setFeature(qglDepthOfFieldFocus, 1.);
|
||||
setFeature(qglDepthOfFieldDiaphragm, 8.);
|
||||
hoverHalo_ = selectionHalo_ = true;
|
||||
fogEnabled_ = is_init = shaders_bind = changed_ = false;
|
||||
rmode = ObjectBase::Fill;
|
||||
// sel_pen = QPen(Qt::black, 1, Qt::DashLine);
|
||||
// sel_brush = QBrush(QColor(170, 100, 255, 120));
|
||||
scene_ = new Scene();
|
||||
connect(scene_, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
|
||||
connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed()));
|
||||
connect(scene_, SIGNAL(__objectDeleted(ObjectBase*)), this, SLOT(__objectDeleted(ObjectBase*)));
|
||||
default_camera = new Camera();
|
||||
default_camera->setPos(QVector3D(2, 2, 2));
|
||||
default_camera->setAim(QVector3D());
|
||||
camera_ = default_camera;
|
||||
// qDebug() << camera_->aim();
|
||||
default_camera->setName("Camera");
|
||||
emit cameraPosChanged(default_camera->pos());
|
||||
//camera().aim_ = camera().pos_;
|
||||
ktm_.restart();
|
||||
|
||||
//Mesh * m = Primitive::torus(100, 40, 1., 0.4, 360);
|
||||
Mesh * m = Primitive::cube(10, 10, 10);
|
||||
m->flipNormals();
|
||||
//QMatrix4x4 mat;
|
||||
//mat.rotate(90, 0,1,0);
|
||||
//mat.translate(0, 0, 2);
|
||||
//mat.rotate(180, 1,0,0);
|
||||
//m->transformPoints(mat);
|
||||
ObjectBase * o = new ObjectBase(m);
|
||||
o->setColor(Qt::cyan);
|
||||
scene()->addObject(o);
|
||||
delete m;
|
||||
|
||||
}
|
||||
|
||||
|
||||
QGLView::~QGLView() {
|
||||
deleting_ = true;
|
||||
stop();
|
||||
scene_->clear();
|
||||
delete scene_;
|
||||
delete default_camera;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::stop() {
|
||||
if (timer) killTimer(timer);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::start(float freq) {
|
||||
timer = startTimer(freq <= 0.f ? 0 : int(1000.f / freq));
|
||||
}
|
||||
|
||||
|
||||
QList<Light * > QGLView::selectedLights() const {
|
||||
QList<Light * > ret;
|
||||
ObjectBaseList sol = scene_->selectedObjects();
|
||||
foreach (ObjectBase * o, sol)
|
||||
if (o->type() == ObjectBase::glLight)
|
||||
ret << (Light*)o;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<Camera * > QGLView::selectedCameras() const {
|
||||
QList<Camera * > ret;
|
||||
ObjectBaseList sol = scene_->selectedObjects();
|
||||
foreach (ObjectBase * o, sol)
|
||||
if (o->type() == ObjectBase::glCamera)
|
||||
ret << (Camera*)o;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void QGLView::resizeEvent(QResizeEvent * e) {
|
||||
renderLater();
|
||||
mouse.resize();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::timerEvent(QTimerEvent *) {
|
||||
renderNow();
|
||||
//if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return;
|
||||
Qt::KeyboardModifiers km = QApplication::keyboardModifiers();
|
||||
foreach (int i, keys_)
|
||||
emit keyEvent((Qt::Key)i, km);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::render() {
|
||||
resizeGL(width(), height());
|
||||
emit glBeginPaint();
|
||||
renderer_.mouse_pos = mapFromGlobal(QCursor::pos());
|
||||
renderer_.renderScene();
|
||||
emit glEndPaint();
|
||||
fps_tm += time.elapsed();
|
||||
time.restart();
|
||||
fps_cnt++;
|
||||
if (fps_tm < 1000.) return;
|
||||
fps_ = fps_cnt / fps_tm * 1000.;
|
||||
fps_tm = 0.;
|
||||
fps_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::initialize() {
|
||||
checkCaps();
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP);
|
||||
glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
glCullFace(GL_BACK);
|
||||
renderer_.reloadShaders();
|
||||
renderer_.init(width(), height());
|
||||
is_init = true;
|
||||
need_init_ = false;
|
||||
emit glInitializeDone();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::checkCaps() {
|
||||
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropic);
|
||||
shaders_supported = QOpenGLShaderProgram::hasOpenGLShaderPrograms();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::__destroyed() {
|
||||
renderer_.rend_mat.mat_thumbnails.clear();
|
||||
mouse.hov_objects.clear();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::__objectDeleted(ObjectBase * o) {
|
||||
if (o == camera_)
|
||||
setDefaultCamera();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::resizeGL(int width, int height) {
|
||||
if (!is_init) return;
|
||||
if (width <= 0 || height <= 0) return;
|
||||
if (prev_size == QSize(width, height)) return;
|
||||
prev_size = QSize(width, height);
|
||||
aspect = float(width) / float(height);
|
||||
renderer_.resize(width, height);
|
||||
//qDebug() << "resize" << width << height;
|
||||
iaspect = (aspect == 0.f) ? 0. : 1 / aspect;
|
||||
glViewport(0, 0, width, height);
|
||||
emit glResize(width, height);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::keyPressEvent(QKeyEvent * e) {
|
||||
emit glKeyPressEvent(e);
|
||||
if (e->key() > 0) keys_.insert(e->key());
|
||||
if (e->key() == Qt::Key_F11) {
|
||||
emit doubleClick();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QGLView::keyReleaseEvent(QKeyEvent * e) {
|
||||
emit glKeyReleaseEvent(e);
|
||||
keys_.remove(e->key());
|
||||
}
|
||||
|
||||
|
||||
void QGLView::focusOutEvent(QFocusEvent *) {
|
||||
keys_.clear();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::focusOn(const Box3D & bb) {
|
||||
if (bb.isEmpty() || !camera()) return;
|
||||
double size = qMax(qMax(bb.width, bb.length), bb.height);
|
||||
camera()->setAim(bb.center());
|
||||
camera()->flyToDistance(size * 1.25);
|
||||
}
|
||||
|
||||
|
||||
QByteArray QGLView::saveCamera() {
|
||||
ChunkStream cs;
|
||||
const Camera * c = camera();
|
||||
cs.add(1, c->pos()).add(2, c->aim()).add(3, c->rotation()).add(4, c->FOV());
|
||||
return cs.data();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::restoreCamera(const QByteArray & ba) {
|
||||
if (ba.isEmpty()) return;
|
||||
Camera * c = camera();
|
||||
QVector3D pos(c->pos()), aim(c->aim()), ang(c->rotation());
|
||||
float fov(c->FOV());
|
||||
ChunkStream cs(ba);
|
||||
cs.readAll();
|
||||
cs.get(1, pos).get(2, aim).get(3, ang).get(4, fov);
|
||||
camera()->setPos(pos);
|
||||
camera()->setAim(aim);
|
||||
camera()->setAngles(ang);
|
||||
camera()->setFOV(fov);
|
||||
}
|
||||
|
||||
|
||||
QByteArray QGLView::saveFeatures() {
|
||||
QByteArray ba;
|
||||
QDataStream ds(&ba, QIODevice::WriteOnly);
|
||||
ds << features_;
|
||||
return ba;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::restoreFeatures(const QByteArray & ba) {
|
||||
QHash<int, QVariant> f;
|
||||
QDataStream ds(ba);
|
||||
ds >> f;
|
||||
features_ = f;
|
||||
}
|
||||
|
||||
@@ -1,293 +1,293 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QGLVIEW_H
|
||||
#define QGLVIEW_H
|
||||
|
||||
#include "openglwindow.h"
|
||||
#include "glframebuffer.h"
|
||||
#include "glprimitives.h"
|
||||
#include "glcamera.h"
|
||||
#include "glrendererbase.h"
|
||||
#include "glscene.h"
|
||||
#include "renderer.h"
|
||||
#include "mouse_controller.h"
|
||||
#include <QTime>
|
||||
#include <QMenu>
|
||||
|
||||
|
||||
class QGLView: public OpenGLWindow
|
||||
{
|
||||
friend class MouseController;
|
||||
friend class GLRendererBase;
|
||||
friend class TextureManager;
|
||||
friend class ObjectBase;
|
||||
friend class Scene;
|
||||
friend class RendererBase;
|
||||
friend class Renderer;
|
||||
friend class RendererMaterial;
|
||||
friend class RendererService;
|
||||
friend class RendererSelection;
|
||||
friend class TonemappingProc;
|
||||
Q_OBJECT
|
||||
Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor)
|
||||
Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY (float FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY (float depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY (float gamma READ gamma WRITE setGamma)
|
||||
Q_PROPERTY (bool autoExposure READ autoExposure WRITE setAutoExposure)
|
||||
Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor)
|
||||
Q_PROPERTY (QColor fogColor READ fogColor WRITE setFogColor)
|
||||
Q_PROPERTY (bool fogEnabled READ isFogEnabled WRITE setFogEnabled)
|
||||
Q_PROPERTY (float fogDensity READ fogDensity WRITE setFogDensity)
|
||||
Q_PROPERTY (float fogDecay READ fogDecay WRITE setFogDecay)
|
||||
Q_PROPERTY (int renderMode READ renderMode WRITE setRenderMode)
|
||||
Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY (float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY (float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
Q_PROPERTY (Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton)
|
||||
Q_PROPERTY (Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier)
|
||||
Q_PROPERTY (Scene::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
|
||||
|
||||
public:
|
||||
QGLView();
|
||||
virtual ~QGLView();
|
||||
|
||||
enum CameraLightMode {
|
||||
clmOff,
|
||||
clmAuto,
|
||||
clmOn,
|
||||
};
|
||||
|
||||
enum Feature {
|
||||
qglFXAA,
|
||||
qglAnisotropicLevel,
|
||||
qglEyeAccomodationEnabled,
|
||||
qglEyeAccomodationTime,
|
||||
qglEyeAccomodationMaxSpeed,
|
||||
qglBloomEnabled,
|
||||
qglBloomThreshold,
|
||||
qglBloomFactor,
|
||||
qglBloomRadius,
|
||||
qglMotionBlurEnabled,
|
||||
qglMotionBlurFactor,
|
||||
qglMotionBlurSteps,
|
||||
qglShadowsEnabled,
|
||||
qglShadowsMapSize,
|
||||
qglShadowsSoftEnabled,
|
||||
qglReflectionsEnabled,
|
||||
qglReflectionsBlur,
|
||||
qglSSAOEnabled,
|
||||
qglSSAORadius,
|
||||
qglDepthOfFieldEnabled,
|
||||
qglDepthOfFieldAutoFocusEnabled,
|
||||
qglDepthOfFieldAutoFocusSpeed,
|
||||
qglDepthOfFieldFocus,
|
||||
qglDepthOfFieldDiaphragm
|
||||
};
|
||||
|
||||
Q_ENUM(CameraLightMode)
|
||||
|
||||
void stop();
|
||||
void start(float freq = 60.);
|
||||
|
||||
QColor backColor() const {return backColor_;}
|
||||
float lineWidth() const {return lineWidth_;}
|
||||
float FOV() const {return camera()->fov_;}
|
||||
float depthStart() const {return camera()->depth_start;}
|
||||
float currentFPS() const {return fps_;}
|
||||
float gamma() const {return renderer_.gamma_;}
|
||||
bool autoExposure() const {return renderer_.tone_proc.enabled;}
|
||||
int maxAnisotropicLevel() const {return max_anisotropic;}
|
||||
QString environmentMapFile() const {return renderer_.tex_env.fileHDR();}
|
||||
|
||||
QColor ambientColor() const {return ambientColor_;}
|
||||
QColor fogColor() const {return fogColor_;}
|
||||
float fogDensity() const {return fogDensity_;}
|
||||
float fogDecay() const {return fogDecay_;}
|
||||
bool isFogEnabled() const {return fogEnabled_;}
|
||||
bool isLightEnabled() const {return lightEnabled_;}
|
||||
bool isGrabMouseEnabled() const {return mouse.isGrabMouseEnabled();}
|
||||
bool isMouseRotateEnabled() const {return mouse.isMouseRotateEnabled();}
|
||||
bool isMouseSelectionEnabled() const {return mouse.isMouseSelectionEnabled();}
|
||||
bool isCameraOrbit() const {return mouse.isCameraOrbit();}
|
||||
bool isHoverHaloEnabled() const {return hoverHalo_;}
|
||||
QColor hoverHaloColor() const {return hoverHaloColor_;}
|
||||
float hoverHaloFillAlpha() const {return hoverHaloFill_;}
|
||||
bool isSelectionHaloEnabled() const {return selectionHalo_;}
|
||||
QColor selectionHaloColor() const {return selectionHaloColor_;}
|
||||
float selectionHaloFillAlpha() const {return selectionHaloFill_;}
|
||||
|
||||
QVariant feature(Feature f) const {return features_.value(int(f));}
|
||||
QVariant setFeature(Feature f, const QVariant & value) {QVariant ret = features_.value(int(f)); features_[int(f)] = value; return ret;}
|
||||
bool isFeatureEnabled(Feature f) const {return features_[int(f)].toBool();}
|
||||
|
||||
int renderMode() const {return (int)rmode;}
|
||||
void setRenderMode(int mode) {rmode = (ObjectBase::RenderMode)mode;}
|
||||
|
||||
bool isServiceMode() const {return renderer_.edit_mode;}
|
||||
void setServiceMode(bool yes) {renderer_.edit_mode = yes;}
|
||||
|
||||
|
||||
Scene::SelectionMode selectionMode() const {return scene_->selectionMode();}
|
||||
Qt::MouseButton selectionButton() const {return mouse.selectionButton();}
|
||||
Qt::KeyboardModifier selectionModifier() const {return mouse.selectionModifier();}
|
||||
|
||||
void setSelectionMode(Scene::SelectionMode m) {scene_->setSelectionMode(m);}
|
||||
void setSelectionButton(Qt::MouseButton v) {mouse.setSelectionButton(v);}
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) {mouse.setSelectionModifier(v);}
|
||||
|
||||
void selectObject(ObjectBase * o, bool add_to_selection = false) {scene_->selectObject(o, add_to_selection);}
|
||||
void clearSelection() {scene_->clearSelection();}
|
||||
ObjectBaseList selectedObjects(bool top_only = false) const {return scene_->selectedObjects(top_only);}
|
||||
QList<Light * > selectedLights() const;
|
||||
QList<Camera * > selectedCameras() const;
|
||||
ObjectBase * selectedObject() const {return scene_->selectedObject();}
|
||||
|
||||
TextureManager * textureManager() {return renderer_.textures_manager;}
|
||||
void reloadTextures() {renderer_.markReloadTextures();}
|
||||
|
||||
Scene * scene() {return scene_;}
|
||||
void focusOn(const Box3D & bb);
|
||||
void setCameraLightMode(CameraLightMode m) {renderer_.setCameraLightMode(m);}
|
||||
CameraLightMode cameraLightMode() const {return (CameraLightMode)renderer_.cameraLightMode();}
|
||||
|
||||
Camera * camera() {return camera_;}
|
||||
const Camera * camera() const {return camera_;}
|
||||
void setCamera(Camera * camera) {camera_ = camera;}
|
||||
void setDefaultCamera() {camera_ = default_camera;}
|
||||
QByteArray saveCamera();
|
||||
void restoreCamera(const QByteArray & ba);
|
||||
QByteArray saveFeatures();
|
||||
void restoreFeatures(const QByteArray & ba);
|
||||
|
||||
QImage materialThumbnail(Material * m) {return renderer_.materialThumbnail(m);}
|
||||
void setCurrentAction(RendererService::HandleAction ha) {renderer_.rend_service.setCurrentAction(ha);}
|
||||
void setContextActions(QList<QAction*> al) {context_menu.clear(); context_menu.addActions(al);}
|
||||
|
||||
GLfloat aspect, iaspect;
|
||||
Renderer renderer_;
|
||||
|
||||
protected:
|
||||
void render();
|
||||
void resizeEvent(QResizeEvent * e);
|
||||
|
||||
void timerEvent(QTimerEvent * );
|
||||
void initialize();
|
||||
void resizeGL(int width, int height);
|
||||
void mousePressEvent(QMouseEvent * e) {mouse.mousePressEvent(e);}
|
||||
void mouseMoveEvent(QMouseEvent * e) {mouse.mouseMoveEvent(e);}
|
||||
void mouseReleaseEvent(QMouseEvent * e) {mouse.mouseReleaseEvent(e);}
|
||||
void wheelEvent(QWheelEvent * e) {mouse.wheelEvent(e);}
|
||||
void mouseDoubleClickEvent(QMouseEvent * e) {mouse.mouseDoubleClickEvent(e);}
|
||||
void leaveEvent(QEvent * );
|
||||
|
||||
void keyPressEvent(QKeyEvent * e);
|
||||
void keyReleaseEvent(QKeyEvent * e);
|
||||
void focusOutEvent(QFocusEvent *);
|
||||
|
||||
void checkCaps();
|
||||
|
||||
private:
|
||||
void processKeys();
|
||||
bool setupViewport();
|
||||
|
||||
Scene * scene_;
|
||||
Camera * camera_, * default_camera;
|
||||
MouseController mouse;
|
||||
QMenu context_menu;
|
||||
QSet<int> keys_;
|
||||
QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_;
|
||||
QTime time, ktm_;
|
||||
GLint max_anisotropic, max_texture_chanels;
|
||||
ObjectBase::RenderMode rmode;
|
||||
GLRendererBase::RenderingParameters start_rp;
|
||||
QHash<int, QVariant> features_;
|
||||
QSize prev_size;
|
||||
float lineWidth_;
|
||||
float fps_, fps_tm, fogDensity_, fogDecay_;
|
||||
float hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor;
|
||||
int timer, fps_cnt, sh_id_loc, deleting_;
|
||||
bool is_first_draw, is_init, fogEnabled_, lightEnabled_;
|
||||
bool shaders_supported, changed_, need_init_;
|
||||
bool hoverHalo_, selectionHalo_, shaders_bind;
|
||||
|
||||
private slots:
|
||||
void __destroyed();
|
||||
void __objectDeleted(ObjectBase * o);
|
||||
|
||||
public slots:
|
||||
void setBackColor(const QColor & arg) {backColor_ = arg;}
|
||||
void setLineWidth(const float & arg) {lineWidth_ = arg;}
|
||||
void setFOV(const float & arg) {camera()->fov_ = arg;}
|
||||
void setDepthStart(const float & arg) {camera()->depth_start = arg;}
|
||||
void setGamma(const float & arg) {renderer_.gamma_ = arg;}
|
||||
void setAutoExposure(bool arg) {renderer_.tone_proc.enabled = arg;}
|
||||
void setAmbientColor(const QColor & arg) {ambientColor_ = arg;}
|
||||
void setEnvironmentMapFile(QString file) {renderer_.tex_env.setFileHDR(file); renderer_.recreateMaterialThumbnails(true);}
|
||||
void setFogColor(const QColor & arg) {fogColor_ = arg;}
|
||||
void setFogDensity(const float & arg) {fogDensity_ = arg;}
|
||||
void setFogDecay(const float & arg) {fogDecay_ = arg;}
|
||||
void setFogEnabled(const bool & arg) {fogEnabled_ = arg;}
|
||||
void setLightEnabled(const bool & arg) {lightEnabled_ = arg;}
|
||||
void setGrabMouseEnabled(const bool & arg) {mouse.setGrabMouseEnabled(arg);}
|
||||
void setMouseRotateEnabled(const bool & arg) {mouse.setMouseRotateEnabled(arg);}
|
||||
void setMouseSelectionEnabled(const bool & arg) {mouse.setMouseSelectionEnabled(arg);}
|
||||
void setCustomMouseMove(const bool & arg) {mouse.setCustomMouseMove(arg);}
|
||||
void setCameraOrbit(const bool & arg) {mouse.setCameraOrbit(arg);}
|
||||
void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;}
|
||||
void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;}
|
||||
void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;}
|
||||
void setSelectionHaloEnabled(const bool & arg) {selectionHalo_ = arg;}
|
||||
void setSelectionHaloColor(const QColor & arg) {selectionHaloColor_ = arg;}
|
||||
void setSelectionHaloFillAlpha(const float & arg) {selectionHaloFill_ = arg;}
|
||||
|
||||
void reloadShaders() {renderer_.reloadShaders();}
|
||||
|
||||
signals:
|
||||
void glBeginPaint();
|
||||
void glEndPaint();
|
||||
void glKeyPressEvent(QKeyEvent * e);
|
||||
void glKeyReleaseEvent(QKeyEvent * e);
|
||||
void glMousePressEvent(QMouseEvent * e);
|
||||
void glMouseMoveEvent(QMouseEvent * e);
|
||||
void glMouseReleaseEvent(QMouseEvent * e);
|
||||
void glWheelEvent(QWheelEvent * e);
|
||||
void glResize(int, int);
|
||||
void glInitializeDone();
|
||||
void cameraPosChanged(QVector3D pos);
|
||||
void keyEvent(Qt::Key key, Qt::KeyboardModifiers mod);
|
||||
void customMouseMoveEvent(QPoint curpos, QPoint lastpos, Qt::MouseButtons buttons);
|
||||
|
||||
void hoverChanged(ObjectBase * cur, ObjectBase * prev);
|
||||
void selectionChanged();
|
||||
void objectsPositionChanged();
|
||||
void materialsChanged();
|
||||
void materialThumbnailCreated(Material*);
|
||||
void doubleClick();
|
||||
|
||||
};
|
||||
|
||||
#endif // QGLVIEW_H
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QGLVIEW_H
|
||||
#define QGLVIEW_H
|
||||
|
||||
#include "openglwindow.h"
|
||||
#include "glframebuffer.h"
|
||||
#include "glprimitives.h"
|
||||
#include "glcamera.h"
|
||||
#include "glrendererbase.h"
|
||||
#include "glscene.h"
|
||||
#include "renderer.h"
|
||||
#include "mouse_controller.h"
|
||||
#include <QTime>
|
||||
#include <QMenu>
|
||||
|
||||
|
||||
class QGLView: public OpenGLWindow
|
||||
{
|
||||
friend class MouseController;
|
||||
friend class GLRendererBase;
|
||||
friend class TextureManager;
|
||||
friend class ObjectBase;
|
||||
friend class Scene;
|
||||
friend class RendererBase;
|
||||
friend class Renderer;
|
||||
friend class RendererMaterial;
|
||||
friend class RendererService;
|
||||
friend class RendererSelection;
|
||||
friend class TonemappingProc;
|
||||
Q_OBJECT
|
||||
Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor)
|
||||
Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY (float FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY (float depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY (float gamma READ gamma WRITE setGamma)
|
||||
Q_PROPERTY (bool autoExposure READ autoExposure WRITE setAutoExposure)
|
||||
Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor)
|
||||
Q_PROPERTY (QColor fogColor READ fogColor WRITE setFogColor)
|
||||
Q_PROPERTY (bool fogEnabled READ isFogEnabled WRITE setFogEnabled)
|
||||
Q_PROPERTY (float fogDensity READ fogDensity WRITE setFogDensity)
|
||||
Q_PROPERTY (float fogDecay READ fogDecay WRITE setFogDecay)
|
||||
Q_PROPERTY (int renderMode READ renderMode WRITE setRenderMode)
|
||||
Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY (float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY (float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
Q_PROPERTY (Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton)
|
||||
Q_PROPERTY (Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier)
|
||||
Q_PROPERTY (Scene::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
|
||||
|
||||
public:
|
||||
QGLView();
|
||||
virtual ~QGLView();
|
||||
|
||||
enum CameraLightMode {
|
||||
clmOff,
|
||||
clmAuto,
|
||||
clmOn,
|
||||
};
|
||||
|
||||
enum Feature {
|
||||
qglFXAA,
|
||||
qglAnisotropicLevel,
|
||||
qglEyeAccomodationEnabled,
|
||||
qglEyeAccomodationTime,
|
||||
qglEyeAccomodationMaxSpeed,
|
||||
qglBloomEnabled,
|
||||
qglBloomThreshold,
|
||||
qglBloomFactor,
|
||||
qglBloomRadius,
|
||||
qglMotionBlurEnabled,
|
||||
qglMotionBlurFactor,
|
||||
qglMotionBlurSteps,
|
||||
qglShadowsEnabled,
|
||||
qglShadowsMapSize,
|
||||
qglShadowsSoftEnabled,
|
||||
qglReflectionsEnabled,
|
||||
qglReflectionsBlur,
|
||||
qglSSAOEnabled,
|
||||
qglSSAORadius,
|
||||
qglDepthOfFieldEnabled,
|
||||
qglDepthOfFieldAutoFocusEnabled,
|
||||
qglDepthOfFieldAutoFocusSpeed,
|
||||
qglDepthOfFieldFocus,
|
||||
qglDepthOfFieldDiaphragm
|
||||
};
|
||||
|
||||
Q_ENUM(CameraLightMode)
|
||||
|
||||
void stop();
|
||||
void start(float freq = 60.);
|
||||
|
||||
QColor backColor() const {return backColor_;}
|
||||
float lineWidth() const {return lineWidth_;}
|
||||
float FOV() const {return camera()->fov_;}
|
||||
float depthStart() const {return camera()->depth_start;}
|
||||
float currentFPS() const {return fps_;}
|
||||
float gamma() const {return renderer_.gamma_;}
|
||||
bool autoExposure() const {return renderer_.tone_proc.enabled;}
|
||||
int maxAnisotropicLevel() const {return max_anisotropic;}
|
||||
QString environmentMapFile() const {return renderer_.tex_env.fileHDR();}
|
||||
|
||||
QColor ambientColor() const {return ambientColor_;}
|
||||
QColor fogColor() const {return fogColor_;}
|
||||
float fogDensity() const {return fogDensity_;}
|
||||
float fogDecay() const {return fogDecay_;}
|
||||
bool isFogEnabled() const {return fogEnabled_;}
|
||||
bool isLightEnabled() const {return lightEnabled_;}
|
||||
bool isGrabMouseEnabled() const {return mouse.isGrabMouseEnabled();}
|
||||
bool isMouseRotateEnabled() const {return mouse.isMouseRotateEnabled();}
|
||||
bool isMouseSelectionEnabled() const {return mouse.isMouseSelectionEnabled();}
|
||||
bool isCameraOrbit() const {return mouse.isCameraOrbit();}
|
||||
bool isHoverHaloEnabled() const {return hoverHalo_;}
|
||||
QColor hoverHaloColor() const {return hoverHaloColor_;}
|
||||
float hoverHaloFillAlpha() const {return hoverHaloFill_;}
|
||||
bool isSelectionHaloEnabled() const {return selectionHalo_;}
|
||||
QColor selectionHaloColor() const {return selectionHaloColor_;}
|
||||
float selectionHaloFillAlpha() const {return selectionHaloFill_;}
|
||||
|
||||
QVariant feature(Feature f) const {return features_.value(int(f));}
|
||||
QVariant setFeature(Feature f, const QVariant & value) {QVariant ret = features_.value(int(f)); features_[int(f)] = value; return ret;}
|
||||
bool isFeatureEnabled(Feature f) const {return features_[int(f)].toBool();}
|
||||
|
||||
int renderMode() const {return (int)rmode;}
|
||||
void setRenderMode(int mode) {rmode = (ObjectBase::RenderMode)mode;}
|
||||
|
||||
bool isServiceMode() const {return renderer_.edit_mode;}
|
||||
void setServiceMode(bool yes) {renderer_.edit_mode = yes;}
|
||||
|
||||
|
||||
Scene::SelectionMode selectionMode() const {return scene_->selectionMode();}
|
||||
Qt::MouseButton selectionButton() const {return mouse.selectionButton();}
|
||||
Qt::KeyboardModifier selectionModifier() const {return mouse.selectionModifier();}
|
||||
|
||||
void setSelectionMode(Scene::SelectionMode m) {scene_->setSelectionMode(m);}
|
||||
void setSelectionButton(Qt::MouseButton v) {mouse.setSelectionButton(v);}
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) {mouse.setSelectionModifier(v);}
|
||||
|
||||
void selectObject(ObjectBase * o, bool add_to_selection = false) {scene_->selectObject(o, add_to_selection);}
|
||||
void clearSelection() {scene_->clearSelection();}
|
||||
ObjectBaseList selectedObjects(bool top_only = false) const {return scene_->selectedObjects(top_only);}
|
||||
QList<Light * > selectedLights() const;
|
||||
QList<Camera * > selectedCameras() const;
|
||||
ObjectBase * selectedObject() const {return scene_->selectedObject();}
|
||||
|
||||
TextureManager * textureManager() {return renderer_.textures_manager;}
|
||||
void reloadTextures() {renderer_.markReloadTextures();}
|
||||
|
||||
Scene * scene() {return scene_;}
|
||||
void focusOn(const Box3D & bb);
|
||||
void setCameraLightMode(CameraLightMode m) {renderer_.setCameraLightMode(m);}
|
||||
CameraLightMode cameraLightMode() const {return (CameraLightMode)renderer_.cameraLightMode();}
|
||||
|
||||
Camera * camera() {return camera_;}
|
||||
const Camera * camera() const {return camera_;}
|
||||
void setCamera(Camera * camera) {camera_ = camera;}
|
||||
void setDefaultCamera() {camera_ = default_camera;}
|
||||
QByteArray saveCamera();
|
||||
void restoreCamera(const QByteArray & ba);
|
||||
QByteArray saveFeatures();
|
||||
void restoreFeatures(const QByteArray & ba);
|
||||
|
||||
QImage materialThumbnail(Material * m) {return renderer_.materialThumbnail(m);}
|
||||
void setCurrentAction(RendererService::HandleAction ha) {renderer_.rend_service.setCurrentAction(ha);}
|
||||
void setContextActions(QList<QAction*> al) {context_menu.clear(); context_menu.addActions(al);}
|
||||
|
||||
GLfloat aspect, iaspect;
|
||||
Renderer renderer_;
|
||||
|
||||
protected:
|
||||
void render();
|
||||
void resizeEvent(QResizeEvent * e);
|
||||
|
||||
void timerEvent(QTimerEvent * );
|
||||
void initialize();
|
||||
void resizeGL(int width, int height);
|
||||
void mousePressEvent(QMouseEvent * e) {mouse.mousePressEvent(e);}
|
||||
void mouseMoveEvent(QMouseEvent * e) {mouse.mouseMoveEvent(e);}
|
||||
void mouseReleaseEvent(QMouseEvent * e) {mouse.mouseReleaseEvent(e);}
|
||||
void wheelEvent(QWheelEvent * e) {mouse.wheelEvent(e);}
|
||||
void mouseDoubleClickEvent(QMouseEvent * e) {mouse.mouseDoubleClickEvent(e);}
|
||||
void leaveEvent(QEvent * );
|
||||
|
||||
void keyPressEvent(QKeyEvent * e);
|
||||
void keyReleaseEvent(QKeyEvent * e);
|
||||
void focusOutEvent(QFocusEvent *);
|
||||
|
||||
void checkCaps();
|
||||
|
||||
private:
|
||||
void processKeys();
|
||||
bool setupViewport();
|
||||
|
||||
Scene * scene_;
|
||||
Camera * camera_, * default_camera;
|
||||
MouseController mouse;
|
||||
QMenu context_menu;
|
||||
QSet<int> keys_;
|
||||
QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_;
|
||||
QTime time, ktm_;
|
||||
GLint max_anisotropic, max_texture_chanels;
|
||||
ObjectBase::RenderMode rmode;
|
||||
GLRendererBase::RenderingParameters start_rp;
|
||||
QHash<int, QVariant> features_;
|
||||
QSize prev_size;
|
||||
float lineWidth_;
|
||||
float fps_, fps_tm, fogDensity_, fogDecay_;
|
||||
float hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor;
|
||||
int timer, fps_cnt, sh_id_loc, deleting_;
|
||||
bool is_first_draw, is_init, fogEnabled_, lightEnabled_;
|
||||
bool shaders_supported, changed_, need_init_;
|
||||
bool hoverHalo_, selectionHalo_, shaders_bind;
|
||||
|
||||
private slots:
|
||||
void __destroyed();
|
||||
void __objectDeleted(ObjectBase * o);
|
||||
|
||||
public slots:
|
||||
void setBackColor(const QColor & arg) {backColor_ = arg;}
|
||||
void setLineWidth(const float & arg) {lineWidth_ = arg;}
|
||||
void setFOV(const float & arg) {camera()->fov_ = arg;}
|
||||
void setDepthStart(const float & arg) {camera()->depth_start = arg;}
|
||||
void setGamma(const float & arg) {renderer_.gamma_ = arg;}
|
||||
void setAutoExposure(bool arg) {renderer_.tone_proc.enabled = arg;}
|
||||
void setAmbientColor(const QColor & arg) {ambientColor_ = arg;}
|
||||
void setEnvironmentMapFile(QString file) {renderer_.tex_env.setFileHDR(file); renderer_.recreateMaterialThumbnails(true);}
|
||||
void setFogColor(const QColor & arg) {fogColor_ = arg;}
|
||||
void setFogDensity(const float & arg) {fogDensity_ = arg;}
|
||||
void setFogDecay(const float & arg) {fogDecay_ = arg;}
|
||||
void setFogEnabled(const bool & arg) {fogEnabled_ = arg;}
|
||||
void setLightEnabled(const bool & arg) {lightEnabled_ = arg;}
|
||||
void setGrabMouseEnabled(const bool & arg) {mouse.setGrabMouseEnabled(arg);}
|
||||
void setMouseRotateEnabled(const bool & arg) {mouse.setMouseRotateEnabled(arg);}
|
||||
void setMouseSelectionEnabled(const bool & arg) {mouse.setMouseSelectionEnabled(arg);}
|
||||
void setCustomMouseMove(const bool & arg) {mouse.setCustomMouseMove(arg);}
|
||||
void setCameraOrbit(const bool & arg) {mouse.setCameraOrbit(arg);}
|
||||
void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;}
|
||||
void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;}
|
||||
void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;}
|
||||
void setSelectionHaloEnabled(const bool & arg) {selectionHalo_ = arg;}
|
||||
void setSelectionHaloColor(const QColor & arg) {selectionHaloColor_ = arg;}
|
||||
void setSelectionHaloFillAlpha(const float & arg) {selectionHaloFill_ = arg;}
|
||||
|
||||
void reloadShaders() {renderer_.reloadShaders();}
|
||||
|
||||
signals:
|
||||
void glBeginPaint();
|
||||
void glEndPaint();
|
||||
void glKeyPressEvent(QKeyEvent * e);
|
||||
void glKeyReleaseEvent(QKeyEvent * e);
|
||||
void glMousePressEvent(QMouseEvent * e);
|
||||
void glMouseMoveEvent(QMouseEvent * e);
|
||||
void glMouseReleaseEvent(QMouseEvent * e);
|
||||
void glWheelEvent(QWheelEvent * e);
|
||||
void glResize(int, int);
|
||||
void glInitializeDone();
|
||||
void cameraPosChanged(QVector3D pos);
|
||||
void keyEvent(Qt::Key key, Qt::KeyboardModifiers mod);
|
||||
void customMouseMoveEvent(QPoint curpos, QPoint lastpos, Qt::MouseButtons buttons);
|
||||
|
||||
void hoverChanged(ObjectBase * cur, ObjectBase * prev);
|
||||
void selectionChanged();
|
||||
void objectsPositionChanged();
|
||||
void materialsChanged();
|
||||
void materialThumbnailCreated(Material*);
|
||||
void doubleClick();
|
||||
|
||||
};
|
||||
|
||||
#endif // QGLVIEW_H
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>shaders/ds_final.glsl</file>
|
||||
<file>shaders/ds_geom.glsl</file>
|
||||
<file>shaders/ds_light.glsl</file>
|
||||
<file>shaders/ds_tonemap.glsl</file>
|
||||
<file>shaders/fxaa.frag</file>
|
||||
<file>shaders/fxaa.vert</file>
|
||||
<file>shaders/fxaa_v3.h</file>
|
||||
<file>shaders/selection.glsl</file>
|
||||
<file>shaders/selection_apply.glsl</file>
|
||||
<file>shaders/selection_frame.glsl</file>
|
||||
<file>shaders/selection_halo.glsl</file>
|
||||
<file>shaders/service_fill.glsl</file>
|
||||
<file>shaders/service_frame.glsl</file>
|
||||
<file>shaders/service_line.glsl</file>
|
||||
<file>shaders/sum.glsl</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>shaders/ds_final.glsl</file>
|
||||
<file>shaders/ds_geom.glsl</file>
|
||||
<file>shaders/ds_light.glsl</file>
|
||||
<file>shaders/ds_tonemap.glsl</file>
|
||||
<file>shaders/fxaa.frag</file>
|
||||
<file>shaders/fxaa.vert</file>
|
||||
<file>shaders/fxaa_v3.h</file>
|
||||
<file>shaders/selection.glsl</file>
|
||||
<file>shaders/selection_apply.glsl</file>
|
||||
<file>shaders/selection_frame.glsl</file>
|
||||
<file>shaders/selection_halo.glsl</file>
|
||||
<file>shaders/service_fill.glsl</file>
|
||||
<file>shaders/service_frame.glsl</file>
|
||||
<file>shaders/service_line.glsl</file>
|
||||
<file>shaders/sum.glsl</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(qglengine_widgets)
|
||||
if (POLICY CMP0017)
|
||||
cmake_policy(SET CMP0017 NEW)
|
||||
endif()
|
||||
find_qt(Qt5 Core Gui Widgets)
|
||||
qt_sources(SRC)
|
||||
qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM)
|
||||
file(GLOB PHS "*_p.h")
|
||||
list(REMOVE_ITEM out_HDR "${PHS}")
|
||||
import_version(${PROJECT_NAME} qglengine)
|
||||
set_deploy_property(${PROJECT_NAME} SHARED
|
||||
LABEL "QGLEngine widgets library"
|
||||
FULLNAME "${_DOMAIN}.${PROJECT_NAME}"
|
||||
COMPANY "${_COMPANY}"
|
||||
INFO "QGLEngine widgets library")
|
||||
make_rc(${PROJECT_NAME} _RC)
|
||||
qt_add_library(${PROJECT_NAME} SHARED out_CPP ${_RC})
|
||||
qt_generate_export_header(${PROJECT_NAME})
|
||||
list(APPEND out_HDR "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_export.h")
|
||||
qt_target_link_libraries(${PROJECT_NAME} qad_utils qad_widgets qglengine_core)
|
||||
qt_target_include_directories(${PROJECT_NAME} PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/../" "${CMAKE_CURRENT_SOURCE_DIR}/../core")
|
||||
list(APPEND QT_MULTILIB_LIST ${PROJECT_NAME})
|
||||
copy_to_parent("")
|
||||
#message(STATUS "Building ${PROJECT_NAME}")
|
||||
sdk_install("qglengine" FALSE "${PROJECT_NAME}" "${out_HDR}" "${out_QM}")
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(qglengine_widgets)
|
||||
if (POLICY CMP0017)
|
||||
cmake_policy(SET CMP0017 NEW)
|
||||
endif()
|
||||
find_qt(Qt5 Core Gui Widgets)
|
||||
qt_sources(SRC)
|
||||
qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM)
|
||||
file(GLOB PHS "*_p.h")
|
||||
list(REMOVE_ITEM out_HDR "${PHS}")
|
||||
import_version(${PROJECT_NAME} qglengine)
|
||||
set_deploy_property(${PROJECT_NAME} SHARED
|
||||
LABEL "QGLEngine widgets library"
|
||||
FULLNAME "${_DOMAIN}.${PROJECT_NAME}"
|
||||
COMPANY "${_COMPANY}"
|
||||
INFO "QGLEngine widgets library")
|
||||
make_rc(${PROJECT_NAME} _RC)
|
||||
qt_add_library(${PROJECT_NAME} SHARED out_CPP ${_RC})
|
||||
qt_generate_export_header(${PROJECT_NAME})
|
||||
list(APPEND out_HDR "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_export.h")
|
||||
qt_target_link_libraries(${PROJECT_NAME} qad_utils qad_widgets qglengine_core)
|
||||
qt_target_include_directories(${PROJECT_NAME} PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/../" "${CMAKE_CURRENT_SOURCE_DIR}/../core")
|
||||
list(APPEND QT_MULTILIB_LIST ${PROJECT_NAME})
|
||||
copy_to_parent("")
|
||||
#message(STATUS "Building ${PROJECT_NAME}")
|
||||
sdk_install("qglengine" FALSE "${PROJECT_NAME}" "${out_HDR}" "${out_QM}")
|
||||
|
||||
@@ -1,259 +1,259 @@
|
||||
/*
|
||||
QGL PrimitiveEditor
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "primitiveeditor.h"
|
||||
#include "ui_primitiveeditor.h"
|
||||
#include <QMetaEnum>
|
||||
#include "glprimitives.h"
|
||||
#include "glmesh.h"
|
||||
|
||||
|
||||
PrimitiveEditor::PrimitiveEditor(QWidget *parent) : QWidget(parent), ui(new Ui::PrimitiveEditor) {
|
||||
view = 0;
|
||||
can_replace = false;
|
||||
ui->setupUi(this);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,12,0)
|
||||
ui->spinSegments->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType);
|
||||
ui->spinSegments2->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType);
|
||||
#endif
|
||||
editors[Plane] << ui->widgetWidth;
|
||||
editors[Plane] << ui->widgetLength;
|
||||
editors[Cube] << ui->widgetWidth;
|
||||
editors[Cube] << ui->widgetLength;
|
||||
editors[Cube] << ui->widgetHeight;
|
||||
editors[Ellipsoid] << ui->widgetRadius1;
|
||||
editors[Ellipsoid] << ui->widgetSegments;
|
||||
editors[Ellipsoid] << ui->widgetSegments2;
|
||||
editors[Ellipsoid] << ui->widgetAngle;
|
||||
editors[Disc] << ui->widgetRadius1;
|
||||
editors[Disc] << ui->widgetSegments;
|
||||
editors[Disc] << ui->widgetAngle;
|
||||
editors[Cone] << ui->widgetRadius1;
|
||||
editors[Cone] << ui->widgetHeight;
|
||||
editors[Cone] << ui->widgetSegments;
|
||||
editors[Cylinder] << ui->widgetRadius1;
|
||||
editors[Cylinder] << ui->widgetHeight;
|
||||
editors[Cylinder] << ui->widgetSegments;
|
||||
editors[Cylinder] << ui->widgetAngle;
|
||||
editors[Torus] << ui->widgetRadius1;
|
||||
editors[Torus] << ui->widgetRadius2;
|
||||
editors[Torus] << ui->widgetSegments;
|
||||
editors[Torus] << ui->widgetSegments2;
|
||||
editors[Torus] << ui->widgetAngle;
|
||||
QSet<QWidget *> all;
|
||||
QMetaEnum me = metaObject()->enumerator(0);
|
||||
for (int i=0; i<me.keyCount(); ++i) {
|
||||
ui->comboPrimitives->addItem(me.key(i));
|
||||
all.unite(editors[(PrimitiveType)me.value(i)].toSet());
|
||||
}
|
||||
all_editors = all.toList();
|
||||
foreach (QWidget * w, all_editors) {
|
||||
if (w->layout()) w->layout()->setContentsMargins(0, layout()->spacing(), 0, 0);
|
||||
}
|
||||
|
||||
ui->comboPrimitives->setCurrentIndex(Plane);
|
||||
on_comboPrimitives_currentIndexChanged(ui->comboPrimitives->currentIndex());
|
||||
}
|
||||
|
||||
|
||||
PrimitiveEditor::~PrimitiveEditor() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::assignQGLView(QGLView * v) {
|
||||
view = v;
|
||||
connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
Mesh * PrimitiveEditor::createMesh(QVariantList & params) {
|
||||
Mesh * m = 0;
|
||||
PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex();
|
||||
params << pt;
|
||||
switch (pt) {
|
||||
case Plane:
|
||||
m = Primitive::plane(ui->spinWidth->value(),
|
||||
ui->spinLength->value());
|
||||
params << ui->spinWidth->value()
|
||||
<< ui->spinLength->value();
|
||||
break;
|
||||
case Cube:
|
||||
m = Primitive::cube(ui->spinWidth->value(),
|
||||
ui->spinLength->value(),
|
||||
ui->spinHeight->value());
|
||||
params << ui->spinWidth->value()
|
||||
<< ui->spinLength->value()
|
||||
<< ui->spinHeight->value();
|
||||
break;
|
||||
case Ellipsoid:
|
||||
m = Primitive::ellipsoid(ui->spinSegments->value(),
|
||||
ui->spinSegments2->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinAngle->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinSegments2->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinAngle->value();
|
||||
break;
|
||||
case Disc:
|
||||
m = Primitive::disc(ui->spinSegments->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinAngle->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinAngle->value();
|
||||
break;
|
||||
case Cone:
|
||||
m = Primitive::cone(ui->spinSegments->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinHeight->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinHeight->value();
|
||||
break;
|
||||
case Cylinder:
|
||||
m = Primitive::cylinder(ui->spinSegments->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinHeight->value(),
|
||||
ui->spinAngle->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinHeight->value()
|
||||
<< ui->spinAngle->value();
|
||||
break;
|
||||
case Torus:
|
||||
m = Primitive::torus(ui->spinSegments->value(),
|
||||
ui->spinSegments2->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinRadius2->value(),
|
||||
ui->spinAngle->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinSegments2->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinRadius2->value()
|
||||
<< ui->spinAngle->value();
|
||||
break;
|
||||
default: return 0;
|
||||
}
|
||||
params << ui->flipNormals->isChecked();
|
||||
params << ui->colorButton->color();
|
||||
if (ui->flipNormals->isChecked())
|
||||
m->flipNormals();
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::showEditors() {
|
||||
foreach (QWidget * w, all_editors) w->hide();
|
||||
PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex();
|
||||
QList<QWidget *> wds = editors[pt];
|
||||
foreach (QWidget * w, wds) w->show();
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::selectionChanged() {
|
||||
ObjectBase * so = view->selectedObject();\
|
||||
can_replace = false;
|
||||
if (so) {
|
||||
QVariantList vl = so->property("primitive", &can_replace).toList();
|
||||
if (can_replace && !vl.isEmpty()) {
|
||||
PrimitiveType pt = (PrimitiveType)vl.takeFirst().toInt();
|
||||
ui->comboPrimitives->setCurrentIndex(pt);
|
||||
switch (pt) {
|
||||
case Plane:
|
||||
ui->spinWidth->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinLength->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Cube:
|
||||
ui->spinWidth->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinLength->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinHeight->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Ellipsoid:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinSegments2->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinAngle->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Disc:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinAngle->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Cone:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinHeight->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Cylinder:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinHeight->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinAngle->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Torus:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinSegments2->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius2->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinAngle->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
}
|
||||
ui->flipNormals->setChecked(vl.takeFirst().toBool());
|
||||
ui->colorButton->setColor(vl.takeFirst().value<QColor>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::replaceMesh() {
|
||||
if (!view) return;
|
||||
if (!can_replace) return;
|
||||
ObjectBase * so = view->selectedObject();
|
||||
if (!so) return;
|
||||
QVariantList params;
|
||||
Mesh * m = createMesh(params);
|
||||
if (!m) return;
|
||||
so->setMesh(m);
|
||||
so->setColor(ui->colorButton->color());
|
||||
so->setName(ui->comboPrimitives->currentText());
|
||||
so->setProperty("primitive", params);
|
||||
delete m;
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::on_buttonAdd_clicked() {
|
||||
if (!view) return;
|
||||
QVariantList params;
|
||||
Mesh * m = createMesh(params);
|
||||
if (!m) return;
|
||||
ObjectBase * o = new ObjectBase(m);
|
||||
o->setColor(ui->colorButton->color());
|
||||
o->setName(ui->comboPrimitives->currentText());
|
||||
o->setProperty("primitive", params);
|
||||
view->scene()->addObject(o);
|
||||
view->scene()->selectObject(o);
|
||||
delete m;
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::on_comboPrimitives_currentIndexChanged(int index) {
|
||||
showEditors();
|
||||
}
|
||||
/*
|
||||
QGL PrimitiveEditor
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "primitiveeditor.h"
|
||||
#include "ui_primitiveeditor.h"
|
||||
#include <QMetaEnum>
|
||||
#include "glprimitives.h"
|
||||
#include "glmesh.h"
|
||||
|
||||
|
||||
PrimitiveEditor::PrimitiveEditor(QWidget *parent) : QWidget(parent), ui(new Ui::PrimitiveEditor) {
|
||||
view = 0;
|
||||
can_replace = false;
|
||||
ui->setupUi(this);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,12,0)
|
||||
ui->spinSegments->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType);
|
||||
ui->spinSegments2->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType);
|
||||
#endif
|
||||
editors[Plane] << ui->widgetWidth;
|
||||
editors[Plane] << ui->widgetLength;
|
||||
editors[Cube] << ui->widgetWidth;
|
||||
editors[Cube] << ui->widgetLength;
|
||||
editors[Cube] << ui->widgetHeight;
|
||||
editors[Ellipsoid] << ui->widgetRadius1;
|
||||
editors[Ellipsoid] << ui->widgetSegments;
|
||||
editors[Ellipsoid] << ui->widgetSegments2;
|
||||
editors[Ellipsoid] << ui->widgetAngle;
|
||||
editors[Disc] << ui->widgetRadius1;
|
||||
editors[Disc] << ui->widgetSegments;
|
||||
editors[Disc] << ui->widgetAngle;
|
||||
editors[Cone] << ui->widgetRadius1;
|
||||
editors[Cone] << ui->widgetHeight;
|
||||
editors[Cone] << ui->widgetSegments;
|
||||
editors[Cylinder] << ui->widgetRadius1;
|
||||
editors[Cylinder] << ui->widgetHeight;
|
||||
editors[Cylinder] << ui->widgetSegments;
|
||||
editors[Cylinder] << ui->widgetAngle;
|
||||
editors[Torus] << ui->widgetRadius1;
|
||||
editors[Torus] << ui->widgetRadius2;
|
||||
editors[Torus] << ui->widgetSegments;
|
||||
editors[Torus] << ui->widgetSegments2;
|
||||
editors[Torus] << ui->widgetAngle;
|
||||
QSet<QWidget *> all;
|
||||
QMetaEnum me = metaObject()->enumerator(0);
|
||||
for (int i=0; i<me.keyCount(); ++i) {
|
||||
ui->comboPrimitives->addItem(me.key(i));
|
||||
all.unite(editors[(PrimitiveType)me.value(i)].toSet());
|
||||
}
|
||||
all_editors = all.toList();
|
||||
foreach (QWidget * w, all_editors) {
|
||||
if (w->layout()) w->layout()->setContentsMargins(0, layout()->spacing(), 0, 0);
|
||||
}
|
||||
|
||||
ui->comboPrimitives->setCurrentIndex(Plane);
|
||||
on_comboPrimitives_currentIndexChanged(ui->comboPrimitives->currentIndex());
|
||||
}
|
||||
|
||||
|
||||
PrimitiveEditor::~PrimitiveEditor() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::assignQGLView(QGLView * v) {
|
||||
view = v;
|
||||
connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
Mesh * PrimitiveEditor::createMesh(QVariantList & params) {
|
||||
Mesh * m = 0;
|
||||
PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex();
|
||||
params << pt;
|
||||
switch (pt) {
|
||||
case Plane:
|
||||
m = Primitive::plane(ui->spinWidth->value(),
|
||||
ui->spinLength->value());
|
||||
params << ui->spinWidth->value()
|
||||
<< ui->spinLength->value();
|
||||
break;
|
||||
case Cube:
|
||||
m = Primitive::cube(ui->spinWidth->value(),
|
||||
ui->spinLength->value(),
|
||||
ui->spinHeight->value());
|
||||
params << ui->spinWidth->value()
|
||||
<< ui->spinLength->value()
|
||||
<< ui->spinHeight->value();
|
||||
break;
|
||||
case Ellipsoid:
|
||||
m = Primitive::ellipsoid(ui->spinSegments->value(),
|
||||
ui->spinSegments2->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinAngle->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinSegments2->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinAngle->value();
|
||||
break;
|
||||
case Disc:
|
||||
m = Primitive::disc(ui->spinSegments->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinAngle->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinAngle->value();
|
||||
break;
|
||||
case Cone:
|
||||
m = Primitive::cone(ui->spinSegments->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinHeight->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinHeight->value();
|
||||
break;
|
||||
case Cylinder:
|
||||
m = Primitive::cylinder(ui->spinSegments->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinHeight->value(),
|
||||
ui->spinAngle->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinHeight->value()
|
||||
<< ui->spinAngle->value();
|
||||
break;
|
||||
case Torus:
|
||||
m = Primitive::torus(ui->spinSegments->value(),
|
||||
ui->spinSegments2->value(),
|
||||
ui->spinRadius->value(),
|
||||
ui->spinRadius2->value(),
|
||||
ui->spinAngle->value());
|
||||
params << ui->spinSegments->value()
|
||||
<< ui->spinSegments2->value()
|
||||
<< ui->spinRadius->value()
|
||||
<< ui->spinRadius2->value()
|
||||
<< ui->spinAngle->value();
|
||||
break;
|
||||
default: return 0;
|
||||
}
|
||||
params << ui->flipNormals->isChecked();
|
||||
params << ui->colorButton->color();
|
||||
if (ui->flipNormals->isChecked())
|
||||
m->flipNormals();
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::showEditors() {
|
||||
foreach (QWidget * w, all_editors) w->hide();
|
||||
PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex();
|
||||
QList<QWidget *> wds = editors[pt];
|
||||
foreach (QWidget * w, wds) w->show();
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::selectionChanged() {
|
||||
ObjectBase * so = view->selectedObject();\
|
||||
can_replace = false;
|
||||
if (so) {
|
||||
QVariantList vl = so->property("primitive", &can_replace).toList();
|
||||
if (can_replace && !vl.isEmpty()) {
|
||||
PrimitiveType pt = (PrimitiveType)vl.takeFirst().toInt();
|
||||
ui->comboPrimitives->setCurrentIndex(pt);
|
||||
switch (pt) {
|
||||
case Plane:
|
||||
ui->spinWidth->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinLength->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Cube:
|
||||
ui->spinWidth->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinLength->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinHeight->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Ellipsoid:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinSegments2->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinAngle->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Disc:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinAngle->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Cone:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinHeight->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Cylinder:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinHeight->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinAngle->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
case Torus:
|
||||
ui->spinSegments->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinSegments2->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinRadius2->setValue(vl.takeFirst().toDouble());
|
||||
ui->spinAngle->setValue(vl.takeFirst().toDouble());
|
||||
break;
|
||||
}
|
||||
ui->flipNormals->setChecked(vl.takeFirst().toBool());
|
||||
ui->colorButton->setColor(vl.takeFirst().value<QColor>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::replaceMesh() {
|
||||
if (!view) return;
|
||||
if (!can_replace) return;
|
||||
ObjectBase * so = view->selectedObject();
|
||||
if (!so) return;
|
||||
QVariantList params;
|
||||
Mesh * m = createMesh(params);
|
||||
if (!m) return;
|
||||
so->setMesh(m);
|
||||
so->setColor(ui->colorButton->color());
|
||||
so->setName(ui->comboPrimitives->currentText());
|
||||
so->setProperty("primitive", params);
|
||||
delete m;
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::on_buttonAdd_clicked() {
|
||||
if (!view) return;
|
||||
QVariantList params;
|
||||
Mesh * m = createMesh(params);
|
||||
if (!m) return;
|
||||
ObjectBase * o = new ObjectBase(m);
|
||||
o->setColor(ui->colorButton->color());
|
||||
o->setName(ui->comboPrimitives->currentText());
|
||||
o->setProperty("primitive", params);
|
||||
view->scene()->addObject(o);
|
||||
view->scene()->selectObject(o);
|
||||
delete m;
|
||||
}
|
||||
|
||||
|
||||
void PrimitiveEditor::on_comboPrimitives_currentIndexChanged(int index) {
|
||||
showEditors();
|
||||
}
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
/*
|
||||
QGL PrimitiveEditor
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PRIMITIVEEDITOR_H
|
||||
#define PRIMITIVEEDITOR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "qglview.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class PrimitiveEditor;
|
||||
}
|
||||
|
||||
|
||||
class PrimitiveEditor : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum PrimitiveType {
|
||||
Plane,
|
||||
Cube,
|
||||
Ellipsoid,
|
||||
Disc,
|
||||
Cone,
|
||||
Cylinder,
|
||||
Torus
|
||||
};
|
||||
Q_ENUMS(PrimitiveType)
|
||||
|
||||
explicit PrimitiveEditor(QWidget *parent = nullptr);
|
||||
~PrimitiveEditor();
|
||||
|
||||
void assignQGLView(QGLView * v);
|
||||
|
||||
protected:
|
||||
Mesh * createMesh(QVariantList & params);
|
||||
void showEditors();
|
||||
|
||||
Ui::PrimitiveEditor *ui;
|
||||
QGLView * view;
|
||||
QMap<PrimitiveType, QList<QWidget *> > editors;
|
||||
QList<QWidget *> all_editors;
|
||||
bool can_replace;
|
||||
|
||||
private slots:
|
||||
void selectionChanged();
|
||||
void replaceMesh();
|
||||
void on_buttonAdd_clicked();
|
||||
void on_comboPrimitives_currentIndexChanged(int index);
|
||||
};
|
||||
|
||||
|
||||
#endif // PRIMITIVEEDITOR_H
|
||||
/*
|
||||
QGL PrimitiveEditor
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PRIMITIVEEDITOR_H
|
||||
#define PRIMITIVEEDITOR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "qglview.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class PrimitiveEditor;
|
||||
}
|
||||
|
||||
|
||||
class PrimitiveEditor : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum PrimitiveType {
|
||||
Plane,
|
||||
Cube,
|
||||
Ellipsoid,
|
||||
Disc,
|
||||
Cone,
|
||||
Cylinder,
|
||||
Torus
|
||||
};
|
||||
Q_ENUMS(PrimitiveType)
|
||||
|
||||
explicit PrimitiveEditor(QWidget *parent = nullptr);
|
||||
~PrimitiveEditor();
|
||||
|
||||
void assignQGLView(QGLView * v);
|
||||
|
||||
protected:
|
||||
Mesh * createMesh(QVariantList & params);
|
||||
void showEditors();
|
||||
|
||||
Ui::PrimitiveEditor *ui;
|
||||
QGLView * view;
|
||||
QMap<PrimitiveType, QList<QWidget *> > editors;
|
||||
QList<QWidget *> all_editors;
|
||||
bool can_replace;
|
||||
|
||||
private slots:
|
||||
void selectionChanged();
|
||||
void replaceMesh();
|
||||
void on_buttonAdd_clicked();
|
||||
void on_comboPrimitives_currentIndexChanged(int index);
|
||||
};
|
||||
|
||||
|
||||
#endif // PRIMITIVEEDITOR_H
|
||||
|
||||
@@ -1,597 +1,597 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PrimitiveEditor</class>
|
||||
<widget class="QWidget" name="PrimitiveEditor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>360</width>
|
||||
<height>536</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="EComboBox" name="comboPrimitives"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetRows" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetWidth" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinWidth">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetLength" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Length:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinLength">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetHeight" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinHeight">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetRadius1" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Radius 1:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinRadius">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetRadius2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Radius 2:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinRadius2">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetAngle" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Angle:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SpinSlider" name="spinAngle">
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>4.500000000000000</double>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<double>90.000000000000000</double>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string>°</string>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksAbove</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>90</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetSegments" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Segments:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinSegments">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetSegments2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Segments 2:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinSegments2">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetColor" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ColorButton" name="colorButton">
|
||||
<property name="color">
|
||||
<color>
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="flipNormals">
|
||||
<property name="text">
|
||||
<string>Flip normals</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>176</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonAdd">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../qad/utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>SpinSlider</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>spinslider.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>colorbutton.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>EComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>ecombobox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ScrollSpinBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>scroll_spin_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../qad/utils/qad_utils.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>spinWidth</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>331</x>
|
||||
<y>51</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>368</x>
|
||||
<y>45</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinLength</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>330</x>
|
||||
<y>84</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>369</x>
|
||||
<y>82</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinHeight</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>334</x>
|
||||
<y>116</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>366</x>
|
||||
<y>114</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinRadius</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>332</x>
|
||||
<y>144</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>370</x>
|
||||
<y>145</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinRadius2</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>334</x>
|
||||
<y>186</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>371</x>
|
||||
<y>181</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinAngle</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>335</x>
|
||||
<y>210</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>372</x>
|
||||
<y>213</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinSegments</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>329</x>
|
||||
<y>246</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>370</x>
|
||||
<y>247</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinSegments2</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>336</x>
|
||||
<y>284</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>372</x>
|
||||
<y>279</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>flipNormals</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>70</x>
|
||||
<y>344</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>370</x>
|
||||
<y>341</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>comboPrimitives</sender>
|
||||
<signal>currentIndexChanged(int)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>348</x>
|
||||
<y>9</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>367</x>
|
||||
<y>9</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>colorButton</sender>
|
||||
<signal>colorChanged(QColor)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>271</x>
|
||||
<y>285</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>179</x>
|
||||
<y>267</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>replaceMesh()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PrimitiveEditor</class>
|
||||
<widget class="QWidget" name="PrimitiveEditor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>360</width>
|
||||
<height>536</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="EComboBox" name="comboPrimitives"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetRows" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetWidth" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinWidth">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetLength" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Length:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinLength">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetHeight" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinHeight">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetRadius1" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Radius 1:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinRadius">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetRadius2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Radius 2:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ScrollSpinBox" name="spinRadius2">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetAngle" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Angle:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SpinSlider" name="spinAngle">
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>4.500000000000000</double>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<double>90.000000000000000</double>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string>°</string>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksAbove</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>90</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetSegments" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Segments:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinSegments">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetSegments2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Segments 2:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinSegments2">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetColor" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ColorButton" name="colorButton">
|
||||
<property name="color">
|
||||
<color>
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="flipNormals">
|
||||
<property name="text">
|
||||
<string>Flip normals</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>176</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonAdd">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../qad/utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>SpinSlider</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>spinslider.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>colorbutton.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>EComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>ecombobox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ScrollSpinBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>scroll_spin_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../qad/utils/qad_utils.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>spinWidth</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>331</x>
|
||||
<y>51</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>368</x>
|
||||
<y>45</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinLength</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>330</x>
|
||||
<y>84</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>369</x>
|
||||
<y>82</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinHeight</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>334</x>
|
||||
<y>116</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>366</x>
|
||||
<y>114</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinRadius</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>332</x>
|
||||
<y>144</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>370</x>
|
||||
<y>145</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinRadius2</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>334</x>
|
||||
<y>186</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>371</x>
|
||||
<y>181</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinAngle</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>335</x>
|
||||
<y>210</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>372</x>
|
||||
<y>213</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinSegments</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>329</x>
|
||||
<y>246</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>370</x>
|
||||
<y>247</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinSegments2</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>336</x>
|
||||
<y>284</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>372</x>
|
||||
<y>279</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>flipNormals</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>70</x>
|
||||
<y>344</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>370</x>
|
||||
<y>341</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>comboPrimitives</sender>
|
||||
<signal>currentIndexChanged(int)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>348</x>
|
||||
<y>9</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>367</x>
|
||||
<y>9</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>colorButton</sender>
|
||||
<signal>colorChanged(QColor)</signal>
|
||||
<receiver>PrimitiveEditor</receiver>
|
||||
<slot>replaceMesh()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>271</x>
|
||||
<y>285</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>179</x>
|
||||
<y>267</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>replaceMesh()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
|
||||
Reference in New Issue
Block a user