Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fix] wrong scale value #1285

Merged
merged 5 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions ui/zenoedit/viewport/cameracontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ void CameraControl::fakeMousePressEvent(QMouseEvent *event)
}
}
if (event->buttons() & Qt::MiddleButton) {
m_lastPos = event->pos();
m_lastMidButtonPos = event->pos();
} else if (event->buttons() & Qt::LeftButton) {
m_boundRectStartPos = event->pos();
// check if clicked a selected object
Expand Down Expand Up @@ -271,11 +271,11 @@ void CameraControl::fakeMouseMoveEvent(QMouseEvent *event)
{
auto session = m_zenovis->getSession();
auto scene = session->get_scene();
float xpos = event->x(), ypos = event->y();

if (event->buttons() & Qt::MiddleButton) {
float ratio = QApplication::desktop()->devicePixelRatio();
float xpos = event->x(), ypos = event->y();
float dx = xpos - m_lastPos.x(), dy = ypos - m_lastPos.y();
float dx = xpos - m_lastMidButtonPos.x(), dy = ypos - m_lastMidButtonPos.y();
dx *= ratio / m_res[0];
dy *= ratio / m_res[1];
bool shift_pressed = event->modifiers() & Qt::ShiftModifier;
Expand All @@ -299,20 +299,25 @@ void CameraControl::fakeMouseMoveEvent(QMouseEvent *event)
setTheta(getTheta() - dy * M_PI);
setPhi(getPhi() + dx * M_PI);
}
m_lastPos = QPointF(xpos, ypos);
m_lastMidButtonPos = QPointF(xpos, ypos);
} else if (event->buttons() & Qt::LeftButton) {
if (m_transformer)
{
if (m_transformer->isTransforming()) {
auto dir = screenToWorldRay(event->pos().x() / res().x(), event->pos().y() / res().y());
auto camera_pos = realPos();
auto x = event->x() * 1.0f;
auto y = event->y() * 1.0f;
x = (2 * x / res().x()) - 1;
y = 1 - (2 * y / res().y());
auto mouse_pos = glm::vec2(x, y);

// mouse pos
auto mouse_pos = glm::vec2(xpos, ypos);
mouse_pos[0] = (2 * mouse_pos[0] / res().x()) - 1;
mouse_pos[1] = 1 - (2 * mouse_pos[1] / res().y());
// mouse start
auto mouse_start = glm::vec2(m_boundRectStartPos.x(), m_boundRectStartPos.y());
mouse_start[0] = (2 * mouse_start[0] / res().x()) - 1;
mouse_start[1] = 1 - (2 * mouse_start[1] / res().y());

auto vp = scene->camera->m_proj * scene->camera->m_view;
m_transformer->transform(camera_pos, mouse_pos, dir, scene->camera->m_lodfront, vp);
m_transformer->transform(camera_pos, dir, mouse_start, mouse_pos, scene->camera->m_lodfront, vp);
zenoApp->getMainWindow()->updateViewport();
} else {
float min_x = std::min((float)m_boundRectStartPos.x(), (float)event->x()) / m_res.x();
Expand Down
2 changes: 1 addition & 1 deletion ui/zenoedit/viewport/cameracontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class CameraControl : public QObject
void resizeTransformHandler(int dir);

private:
QPointF m_lastPos;
QPointF m_lastMidButtonPos;
QPoint m_boundRectStartPos;
QVector2D m_res;
QSet<int> m_pressedKeys;
Expand Down
16 changes: 12 additions & 4 deletions ui/zenoedit/viewportinteraction/transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ bool FakeTransformer::clickedAnyHandler(QVector3D ori, QVector3D dir, glm::vec3
return m_operation_mode != zenovis::INTERACT_NONE;
}

void FakeTransformer::transform(QVector3D camera_pos, glm::vec2 mouse_pos, QVector3D ray_dir, glm::vec3 front, glm::mat4 vp) {
void FakeTransformer::transform(QVector3D camera_pos, QVector3D ray_dir, glm::vec2 mouse_start, glm::vec2 mouse_pos, glm::vec3 front, glm::mat4 vp) {
if (m_operation == NONE) return;

auto pZenovis = m_viewport->getZenoVis();
Expand Down Expand Up @@ -256,9 +256,17 @@ void FakeTransformer::transform(QVector3D camera_pos, glm::vec2 mouse_pos, QVect
}
}
else if (m_operation == SCALE) {
// make a circle, center is m_objects_center
// when mouse press, get the circle's radius, r = len(m_objects_center - mouse_start)
// when mouse move, get the len from center to mouse_pos, d = len(m_objects_center - mouse_pos)
// so the scale is d / r
auto t_ctr = vp * glm::vec4(m_objects_center, 1.0f);
glm::vec2 ctr = t_ctr / t_ctr[3];
auto scale_size = glm::length(ctr - mouse_pos);
auto len_ctr_start = glm::length(ctr - mouse_start);
if (len_ctr_start < 0.001) return;

auto len_ctr_pos = glm::length(ctr - mouse_pos);
auto scale_size = len_ctr_pos / len_ctr_start;
if (m_operation_mode == zenovis::INTERACT_X) {
scale(scale_size, {1, 0, 0});
}
Expand Down Expand Up @@ -635,8 +643,8 @@ void FakeTransformer::translate(glm::vec3 start, glm::vec3 end, glm::vec3 axis)

void FakeTransformer::scale(float scale_size, vec3i axis) {
glm::vec3 scale(1.0f);
for (int i=0; i<3; i++)
if (axis[i] == 1) scale[i] = fmax(scale_size * 3, 0.1);
for (int i = 0; i < 3; i++)
if (axis[i] == 1) scale[i] = std::max(scale_size, 0.1f);
m_scale = scale;
doTransform();
}
Expand Down
2 changes: 1 addition & 1 deletion ui/zenoedit/viewportinteraction/transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class FakeTransformer {
void removeObject(const std::unordered_set<std::string>& names);
bool calcTransformStart(glm::vec3 ori, glm::vec3 dir, glm::vec3 front);
bool clickedAnyHandler(QVector3D ori, QVector3D dir, glm::vec3 front);
void transform(QVector3D camera_pos, glm::vec2 mouse_pos, QVector3D ray_dir, glm::vec3 front, glm::mat4 vp);
void transform(QVector3D camera_pos, QVector3D ray_dir, glm::vec2 mouse_start, glm::vec2 mouse_pos, glm::vec3 front, glm::mat4 vp);
void startTransform();
void endTransform(bool moved);
bool isTransforming() const;
Expand Down
37 changes: 34 additions & 3 deletions zenovis/include/zenovis/bate/GraphicHandlerUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,11 @@ void drawSquare(vec3f pos, vec3f a, vec3f b, vec3f color, float size, std::uniqu
}

void drawCircle(vec3f pos, vec3f a, vec3f b, vec3f color, float size, std::unique_ptr<Buffer> &vbo) {
constexpr int point_num = 100;
constexpr double step = 1.0 / point_num;
std::vector<vec3f> mem;
mem.reserve(point_num * 2);

double point_num = 100;
double step = 1.0 / point_num;
for (double t = 0; t < 1.0; t += step) {
double theta = 2.0 * PI * t;
auto p = pos + size * cos(theta) * a + size * sin(theta) * b;
Expand All @@ -133,13 +134,43 @@ void drawCircle(vec3f pos, vec3f a, vec3f b, vec3f color, float size, std::uniqu
vbo->attribute(0, sizeof(float) * 0, sizeof(float) * 6, GL_FLOAT, 3);
vbo->attribute(1, sizeof(float) * 3, sizeof(float) * 6, GL_FLOAT, 3);

CHECK_GL(glDrawArrays(GL_LINE_STRIP, 0, vertex_count));
CHECK_GL(glDrawArrays(GL_LINE_LOOP, 0, vertex_count));

vbo->disable_attribute(0);
vbo->disable_attribute(1);
vbo->unbind();
}

void drawCircle(vec3f pos, vec3f a, vec3f b, vec3f color, float size, float width, std::unique_ptr<Buffer> &vbo) {
constexpr int point_num = 100;
constexpr double step = 1.0 / point_num;
std::vector<vec3f> mem;
mem.reserve(point_num * 4);

float inner_size = size - width / 2.0;
float outer_size = size + width / 2.0;
for (double t = 0; t < 1.0 + step; t += step) {
double theta = 2.0 * PI * t;
auto p1 = pos + inner_size * cos(theta) * a + inner_size * sin(theta) * b;
auto p2 = pos + outer_size * cos(theta) * a + outer_size * sin(theta) * b;
mem.push_back(p1);
mem.push_back(color);
mem.push_back(p2);
mem.push_back(color);
}

auto vertex_count = mem.size() / 2;
vbo->bind_data(mem.data(), mem.size() * sizeof(mem[0]));

vbo->attribute(0, sizeof(float) * 0, sizeof(float) * 6, GL_FLOAT, 3);
vbo->attribute(1, sizeof(float) * 3, sizeof(float) * 6, GL_FLOAT, 3);

CHECK_GL(glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count));

vbo->disable_attribute(0);
vbo->disable_attribute(1);
vbo->unbind();
}

void drawCube(vec3f pos, vec3f a, vec3f b, vec3f color, float size, std::unique_ptr<Buffer> &vbo) {
std::vector<vec3f> mem;
Expand Down
78 changes: 54 additions & 24 deletions zenovis/src/bate/GraphicScaleHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ struct ScaleHandler final : IGraphicHandler {
std::unique_ptr<Buffer> lines_ebo;
size_t lines_count;

static constexpr float cube_factor = 0.08f;
static constexpr float axis_factor = 0.8f;
static constexpr float square_factor = 0.1f;
static constexpr float icircle_factor = 0.2f; // inner circle
static constexpr float ocircle_factor = 1.0f; // outer circle

explicit ScaleHandler(Scene *scene_, vec3f &center_, float scale_)
: scene(scene_), center(center_), scale(scale_), mode(INTERACT_NONE) {
vbo = std::make_unique<Buffer>(GL_ARRAY_BUFFER);
Expand Down Expand Up @@ -113,53 +119,64 @@ struct ScaleHandler final : IGraphicHandler {
auto y_axis = vec3f(0, 1, 0);
auto z_axis = vec3f(0, 0, 1);

auto axis_size = bound * axis_factor;
auto cube_size = bound * cube_factor;
auto square_size = bound * square_factor;
auto icircle_size = bound * icircle_factor;
auto ocircle_size = bound * ocircle_factor;

// x axis
if (mode == INTERACT_NONE || mode == INTERACT_X) {
drawAxis(center, x_axis, r, bound, vbo);
drawCube(center + bound * x_axis, y_axis, z_axis, r, bound * 0.08f, vbo);
drawAxis(center, x_axis, r, axis_size, vbo);
drawCube(center + axis_size * x_axis, y_axis, z_axis, r, cube_size, vbo);
}

if (mode == INTERACT_NONE || mode == INTERACT_Y) {
drawAxis(center, y_axis, g, bound, vbo);
drawCube(center + bound * y_axis, z_axis, x_axis, g, bound * 0.08f, vbo);
drawAxis(center, y_axis, g, axis_size, vbo);
drawCube(center + axis_size * y_axis, z_axis, x_axis, g, cube_size, vbo);
}

if (mode == INTERACT_NONE || mode == INTERACT_Z) {
drawAxis(center, z_axis, b, bound, vbo);
drawCube(center + bound * z_axis, x_axis, y_axis, b, bound * 0.08f, vbo);
drawAxis(center, z_axis, b, axis_size, vbo);
drawCube(center + axis_size * z_axis, x_axis, y_axis, b, cube_size, vbo);
}

if (mode == INTERACT_NONE || mode == INTERACT_YZ)
drawSquare(center, y_axis, z_axis, {0.6, 0.2, 0.2}, bound * 0.1f, vbo);
drawSquare(center, y_axis, z_axis, {0.6, 0.2, 0.2}, square_size, vbo);

if (mode == INTERACT_NONE || mode == INTERACT_XZ)
drawSquare(center, z_axis, x_axis, {0.2, 0.6, 0.2}, bound * 0.1f, vbo);
drawSquare(center, z_axis, x_axis, {0.2, 0.6, 0.2}, square_size, vbo);

if (mode == INTERACT_NONE || mode == INTERACT_XY)
drawSquare(center, x_axis, y_axis, {0.2, 0.2, 0.6}, bound * 0.1f, vbo);

if (mode == INTERACT_NONE || mode == INTERACT_XYZ)
drawCube(center, y_axis, z_axis, {0.51, 0.17, 0.85}, bound * 0.08f, vbo);
drawSquare(center, x_axis, y_axis, {0.2, 0.2, 0.6}, square_size, vbo);

const auto& view = scene->camera->m_view;
if (mode == INTERACT_NONE || mode == INTERACT_XYZ) {
// http://www.opengl-tutorial.org/cn/intermediate-tutorials/billboards-particles/billboards/
// always face camera
// This is equivalent to mlutiplying (1,0,0) and (0,1,0) by inverse(ViewMatrix).
// ViewMatrix is orthogonal (it was made this way),
// so its inverse is also its transpose,
// and transposing a matrix is "free" (inversing is slooow)
auto right_world = vec3f(view[0][0], view[1][0], view[2][0]);
auto up_world = vec3f(view[0][1], view[1][1], view[2][1]);
drawCircle(center, right_world, up_world, { 1.0, 1.0, 1.0 }, icircle_size, bound * 0.01f, vbo);
drawCircle(center, right_world, up_world, { 1.0, 1.0, 1.0 }, ocircle_size, bound * 0.01f, vbo);
}
}

virtual int collisionTest(glm::vec3 ori, glm::vec3 dir) override {
auto x_axis = glm::vec3(1, 0, 0);
auto y_axis = glm::vec3(0, 1, 0);
auto z_axis = glm::vec3(0, 0, 1);

auto model_matrix =glm::translate(zeno::vec_to_other<glm::vec3>(center));

// xyz handler
float cube_size = bound * 0.08f; float t;
auto xyz_handler_max = cube_size * glm::vec3(1.0f);
auto xyz_handler_min = -xyz_handler_max;
if (rayIntersectOBB(ori, dir, xyz_handler_min, xyz_handler_max, model_matrix, t)) {
mode = INTERACT_XYZ;
return INTERACT_XYZ;
}
auto model_matrix = glm::translate(zeno::vec_to_other<glm::vec3>(center));
const auto& view = scene->camera->m_view;

float t;

// axis handlers
float axis_handler_l = bound * 1.1f;
float axis_handler_l = bound * axis_factor;
float axis_handler_w = bound * 0.1f;

// x handler
Expand Down Expand Up @@ -188,7 +205,7 @@ struct ScaleHandler final : IGraphicHandler {

// plane handlers
float square_ctr_offset = bound;
float square_size = bound * 0.1f;
float square_size = bound * square_factor;

// xy handler
auto xy_base = glm::normalize(x_axis + y_axis);
Expand Down Expand Up @@ -217,6 +234,19 @@ struct ScaleHandler final : IGraphicHandler {
return INTERACT_XZ;
}

// xyz handler
// the other handlers are in the range of xyz handler, so check xyz at last
float i_radius = bound * icircle_factor;
float o_radius = bound * ocircle_factor;
float thickness = bound * 0.1f;
auto right_world = vec3f(view[0][0], view[1][0], view[2][0]);
auto up_world = vec3f(view[0][1], view[1][1], view[2][1]);
if (rayIntersectRing(ori, dir, glm::vec3(0), o_radius, i_radius, zeno::vec_to_other<glm::vec3>(right_world),
zeno::vec_to_other<glm::vec3>(up_world), thickness, model_matrix)) {
mode = INTERACT_XYZ;
return INTERACT_XYZ;
}

mode = INTERACT_NONE;
return INTERACT_NONE;
}
Expand Down
Loading