git-svn-id: svn://db.shs.com.ru/libs@629 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2019-11-24 18:49:53 +00:00
parent dbdda8ea3d
commit 6c8da692e2
14 changed files with 403 additions and 30 deletions

View File

@@ -29,19 +29,22 @@ using namespace QGLEngineShaders;
RendererService::RendererService(Renderer * r_): r(r_) {
line_width = 1;
current_handle = htNoHandle;
mat_xyz.resize(3);
color_xyz.resize(3);
const QVector3D _rot[3] = {QVector3D(0,1,0), QVector3D(-1,0,0), QVector3D(0,0,1)};
for (int i = 0; i < 3; ++i) {
QMatrix4x4 m;
m.rotate(90., _rot[i]);
mat_xyz[i] = m;
color_xyz[i] = QVector4D(0,0,0,1);
color_xyz[i][i] = 1.;
}
axis_camera = new Camera();
axis_camera->setAim(QVector3D());
axis_camera->setFOV(45.);
axis_mesh = Primitive::arrow(12);
axis_objects.resize(3);
const QVector3D _rot[3] = {QVector3D(0,1,0), QVector3D(-1,0,0), QVector3D(0,0,1)};
for (int i = 0; i < 3; ++i) {
axis_objects[i].color = QVector4D(0,0,0,1);
axis_objects[i].color[i] = 1.;
QMatrix4x4 m; m.rotate(90., _rot[i]);
m.transposed().copyDataTo(axis_objects[i].modelmatrix);
}
box_vp_scale = box_full_scale = 1.;
size_vp_scale = size_full_scale = 1.;
box_mesh = Primitive::cube();
box_mesh_f = Primitive::cubeFrame();
omni_mesh = Primitive::ellipsoid(2, 1);
@@ -50,6 +53,20 @@ RendererService::RendererService(Renderer * r_): r(r_) {
omni_mesh_f->scalePoints(1.5);
box_mesh ->scalePoints(1.3);
omni_mesh ->scalePoints(1.3);
handle_move_mesh = Primitive::arrow(12, 0.06);
handle_rotate_mesh = Primitive::arrow(12, 0.03);
Mesh * m = Primitive::torus(30, 12, 0.5, 0.06);
m->translatePoints(QVector3D(0., 0., 0.75));
handle_rotate_mesh->append(m);
delete m;
handle_scale_mesh = Primitive::cylinder(12, 0.06, 0.06, 0.85);
m = Primitive::ellipsoid(12, 12, 0.3, 0.3, 0.3);
m->translatePoints(QVector3D(0., 0., 0.85));
handle_scale_mesh->append(m);
delete m;
handle_move_mesh ->scalePoints(7.5);
handle_rotate_mesh->scalePoints(7.5);
handle_scale_mesh ->scalePoints(7.5);
}
@@ -60,11 +77,15 @@ RendererService::~RendererService() {
delete omni_mesh_f;
delete axis_camera;
delete axis_mesh;
delete handle_move_mesh;
delete handle_rotate_mesh;
delete handle_scale_mesh;
}
void RendererService::init(int width, int height) {
axis_mesh->loadObjects(r->view, axis_objects);
fillXYZObjects();
axis_mesh->loadObjects(r->view, cur_objects);
resize(width, height);
}
@@ -72,30 +93,79 @@ void RendererService::init(int width, int height) {
void RendererService::resize(int width, int height) {
axis_viewport = preferredIconSize(10.);
line_width = lineThickness();
box_vp_scale = 25. * appScale() / qMax(qMin(width, height), 1);
size_vp_scale = 25. * appScale() / qMax(qMin(width, height), 1);
//qDebug() << axis_viewport;
}
QMatrix4x4 RendererService::invariantSizeMatrix(QVector3D p) {
QVector4D pos = QVector4D(p, 1.);
double dist = -(v_mat * pos).z();
QMatrix4x4 m;
m.translate(pos.toVector3D());
m.scale(dist * size_full_scale);
return m;
}
void RendererService::fillXYZObjects() {
cur_objects.resize(3);
for (int i = 0; i < 3; ++i) {
cur_objects[i].color = color_xyz[i];
mat_xyz[i].transposed().copyDataTo(cur_objects[i].modelmatrix);
}
}
void RendererService::fillOmniObjects() {
cur_objects.clear();
Object o;
QList<Light*> ll = r->view->scene()->lights_used;
QMatrix4x4 v_mat = r->view->camera()->viewMatrix() * r->view->camera()->offsetMatrix();
box_full_scale = tan(r->view->camera()->FOV() / 2. * deg2rad) * box_vp_scale;
Object o;
cur_objects.clear();
foreach (Light * l, ll) {
QVector4D lpos = QVector4D(l->worldPos(), 1.);
double dist = -(v_mat * lpos).z();
QMatrix4x4 lmat;
lmat.translate(lpos.toVector3D());
lmat.scale(dist * box_full_scale);
lmat.transposed().copyDataTo(o.modelmatrix);
QMatrix4x4 m = invariantSizeMatrix(l->worldPos());
m.transposed().copyDataTo(o.modelmatrix);
o.object_id = l->id_;
cur_objects << o;
}
}
void RendererService::fillHandleObjects(QVector3D center, HandleType first, QMatrix4x4 add_mat) {
cur_objects.resize(3);
for (int i = 0; i < 3; ++i) {
cur_objects[i].color = color_xyz[i];
QMatrix4x4 m = invariantSizeMatrix(center);
m = m * add_mat * mat_xyz[i];
cur_objects[i].object_id = first + i;
m.transposed().copyDataTo(cur_objects[i].modelmatrix);
}
}
bool RendererService::fillCurrentHandleObjects() {
QList<ObjectBase*> sol = r->view->scene()->selectedObjects(true);
if (sol.isEmpty()) return false;
selection_center = QVector3D();
Box3D bb;
foreach (ObjectBase * o, sol) {
o->calculateBoundingBox();
bb |= o->boundingBox();
}
if (bb.isEmpty())
selection_center = sol[0]->worldPos();
else
selection_center = bb.center();
QMatrix4x4 rm;
if ((sol.size() == 1) && (current_handle >= htRotateX)) {
rm.rotate(sol[0]->angles_.z(), 0., 0., 1.);
rm.rotate(sol[0]->angles_.y(), 0., 1., 0.);
rm.rotate(sol[0]->angles_.x(), 1., 0., 0.);
}
fillHandleObjects(selection_center, current_handle, rm);
return true;
}
void RendererService::setObjectsColor(QVector<Object> & ol, QColor col) {
QVector4D cv = QColor2QVector(col);
for (int i = 0; i < ol.size(); ++i)
@@ -106,6 +176,8 @@ void RendererService::setObjectsColor(QVector<Object> & ol, QColor col) {
void RendererService::renderService() {
QOpenGLShaderProgram * prog = 0;
QOpenGLExtraFunctions * f = r->view;
size_full_scale = tan(r->view->camera()->FOV() / 2. * deg2rad) * size_vp_scale;
v_mat = r->view->camera()->fullViewMatrix();
f->glEnable(GL_MULTISAMPLE);
glEnableDepth();
f->glClear(GL_DEPTH_BUFFER_BIT);
@@ -135,15 +207,41 @@ void RendererService::renderService() {
}
if (r->bindShader(Renderer::srServiceFill, &prog)) {
r->setUniformCamera(prog, r->view->camera());
/// handles
if (fillCurrentHandleObjects()) {
Mesh * hm = currentHandleMesh();
if (hm) {
hm->loadObjects(r->view, cur_objects);
hm->draw(f, 3);
}
}
/// axis
f->glViewport(0, 0, axis_viewport.width(), axis_viewport.height());
axis_camera->setPos(-r->view->camera()->direction() * 3.);
r->setUniformCamera(prog, axis_camera, true, axis_viewport);
//axis_mesh->loadObjects(f, axis_objects);
axis_mesh->draw(f, axis_objects.size());
axis_mesh->draw(f, 3);
f->glViewport(0, 0, r->view->width(), r->view->height());
}
f->glDisable(GL_MULTISAMPLE);
}
Mesh * RendererService::currentHandleMesh() {
switch (current_handle) {
case htMoveX :
case htMoveY :
case htMoveZ : return handle_move_mesh;
case htRotateX:
case htRotateY:
case htRotateZ: return handle_rotate_mesh;
case htScaleX :
case htScaleY :
case htScaleZ : return handle_scale_mesh;
default: break;
}
return 0;
}