Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/40: Рейтинг темы: голосов - 40, средняя оценка - 4.80
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
1

Вращение сцены мышью

15.04.2013, 16:33. Показов 7450. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем доброго времени суток.
Сижу, тренирусь в OpenGL. Сделал 3D фигуру, написал перемещение по сцене стрелками ("вращение камеры" влево/вправо и движение вперёд/назад относительно угла поворота). Работает всё хорошо, но загорелся идеей делать вращение мышью.
Суть алгоритма:
• Ждём сообщение WM_MOUSEMOVE
• Получаем текущие координаты курсора мыши (GetCursorPos)
• Если курсор в центре - возвращаем 0
• Иначе забираем HIWORD и LOWORD из lParam и считаем смещение координат курсора относительно центра экрана
• Добавляем это смещение в угол поворота
Выглядит это примерно так:

C++
1
2
3
4
5
6
7
GetCursorPos(&ml);
if (!(ml.x != centerX && ml.y != centerY))
    return 0;
 
SetCursorPos(centerX, centerY);
_txa += (centerX - LOWORD(lParam)) / 10;
_tya += (HIWORD(lParam) - centerY) / 10;
_txa - угол по оси OX, _tya - угол по OY.
Вся проблема в том, что вращение работает, но происходит это рывками. То есть бывает не при каждом движении мыши, и, вообщем, не плавно (слишком большой шаг вращения). Такое ощущение, что камера будто тупит, плохо слушается пользователя. Игрался с делением (там где деление на 10) - ставил больше, меньше... убрать не вариант, так как вращение получается слишком сильное. Какие есть варианты решения этой проблемы?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.04.2013, 16:33
Ответы с готовыми решениями:

Вращение сцены мышью
Здавствуйте! В общем не получается вращать сцену как хотелось бы. Помогите определить проблему. А...

Вращение сцены
Как вращать сцену? В исходнике, что я приложил при помощи wasd и кнопок- стрелочек происходит...

Выбор объектов сцены мышью
Есть сцена с шарами. Нужно реализовать возможность выбора шара мышью. Находил примеры, но они...

GLUT, вращение сцены с помощью мыши или клавиатуры
Нужно было сделать "Задачу трёх тел", изобразил в виде вращающихся частиц вокруг массивной частицы,...

12
Модератор
3387 / 2159 / 352
Регистрация: 13.01.2012
Сообщений: 8,378
16.04.2013, 09:22 2
Цитата Сообщение от IIARTEMII Посмотреть сообщение
рывками
наверное потому что координаты целые. а вообще вращать курсором на мой вкус не правильно. вращать надо матрицей.
1
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
16.04.2013, 20:06  [ТС] 3
Рывки из-за нецелых координат имеют немного другой характер, но за это спасибо) немножко изменил код и всё стало вертеться плавно:
C++
1
2
3
4
5
6
7
8
GetCursorPos(&ml);
if (!(ml.x != centerX || ml.y != centerY)) // тут || вместо &&
// иначе идут "рывки" из-за отсутствия смещения по одной из осей
    return 0;
 
SetCursorPos(centerX, centerY);
_txa += (centerX - LOWORD(lParam)) / 10.; // Деление не нацело
_tya += (HIWORD(lParam) - centerY) / 10.;
Единственное осталось вот что: в оконном режиме странное смещение по OY - камера ползёт вверх. При полноэкранном режиме этого не наблюдается

Добавлено через 14 минут
В оконном режиме частью окна считаются границы (от этого и неровное смещение по OY; верхняя граница больше нижней) - фиксится легко игрой с координатами. Все проблемы решены. Спасибо =)
1
2062 / 618 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
19.04.2013, 09:12 4
Цитата Сообщение от IIARTEMII Посмотреть сообщение
Рывки из-за нецелых координат имеют немного другой характер, но за это спасибо) немножко изменил код и всё стало вертеться плавно:
C++
1
2
3
4
5
6
7
8
GetCursorPos(&ml);
if (!(ml.x != centerX || ml.y != centerY)) // тут || вместо &&
// иначе идут "рывки" из-за отсутствия смещения по одной из осей
    return 0;
 
SetCursorPos(centerX, centerY);
_txa += (centerX - LOWORD(lParam)) / 10.; // Деление не нацело
_tya += (HIWORD(lParam) - centerY) / 10.;
Просто сеткурсорпоз ставьте в начале цикла, а геткурсорпоз в конце, и все будет плавно.
0
545 / 344 / 12
Регистрация: 05.11.2010
Сообщений: 1,076
Записей в блоге: 1
20.04.2013, 13:44 5
наверное потому что координаты целые. а вообще вращать курсором на мой вкус не правильно. вращать надо матрицей.
Как это ты можешь сравнивать вращение курсором и применение матрицы поворота?
0
2062 / 618 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
23.04.2013, 12:23 6
Цитата Сообщение от Герц Посмотреть сообщение
Как это ты можешь сравнивать вращение курсором и применение матрицы поворота?
в эту матрицу передаются производные данные от координат курсора!
0
1 / 1 / 0
Регистрация: 30.03.2014
Сообщений: 10
07.06.2014, 01:00 7
IIARTEMII, подскажите а как вы решили проблему с оконным режимом? Что вы делали с centerY?? Как получили правильное значение centerX и centerY? в полноэкранном режиме легко получаю с помощью
C++
1
2
3
4
RECT rect;
GetWindowRect(hWnd, &rect);
centerX=(rect.right - rect.left)/2;
centerY=(rect.bottom - rect.top)/2;
0
Модератор
3387 / 2159 / 352
Регистрация: 13.01.2012
Сообщений: 8,378
07.06.2014, 06:16 8
Цитата Сообщение от Никита Александ Посмотреть сообщение
Что вы делали с centerY
для оконного режима все точно так же. просто hwnd вашего окна подставьте
1
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
07.06.2014, 08:57  [ТС] 9
Никита Александ, это было так давно) если я правильно помню, то в оконном режиме я учитывал границы окна, иначе неправильно смещался обзор или плыл по сторонам, даже когда мышь в центре (больше связано с осью OY, так как вернхняя граница больше нижней, а с OX при равных границах всё остаётся так же, как и в полноэкранном режиме)
0
1 / 1 / 0
Регистрация: 30.03.2014
Сообщений: 10
08.06.2014, 16:38 10
Так подождите у меня одно и тоже окно,когда я переключаюсь из фуллскрина в оконный режим,я удаляю фуллскрин-окно и пересоздаю его же только оконным,hWnd одно и тоже и там и там

Добавлено через 2 минуты
Цитата Сообщение от IIARTEMII Посмотреть сообщение
оконном режиме я учитывал границы окна
а подскажите как вы учитывали? как вы получали размеры границ окна в оконном режиме?
0
Модератор
3387 / 2159 / 352
Регистрация: 13.01.2012
Сообщений: 8,378
08.06.2014, 16:45 11
что-то я чувствую что я что-то упускаю)
размер и в том и в другом случае лично я брал через одну и ту же функцию GetWindowRect и все было в порядке
0
1 / 1 / 0
Регистрация: 30.03.2014
Сообщений: 10
08.06.2014, 17:08 12
Вот собственно как я делаю:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
case WM_MOUSEMOVE:
        {
 
 
            int centerX=0;
            int centerY=0;
            RECT rect;
            GetWindowRect(hWnd, &rect);
            centerX=(rect.right - rect.left)/2;
            centerY=(rect.bottom - rect.top)/2;
            GetCursorPos(&mouse);
            if (!(mouse.x != centerX || mouse.y != centerY)) 
                return 0;
            SetCursorPos(centerX, centerY);
            heading += (centerX - LOWORD(lParam)) / 12.0f;
            yrot=heading;
            lookupdown+=(HIWORD(lParam) - centerY) / 11.0f;
            if (!(lookupdown>-80.0f && lookupdown<80.0f))
            {
                lookupdown-=(HIWORD(lParam) - centerY) / 11.0f;
                
            }
            return 0;
 
        }
0
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
08.06.2014, 21:43  [ТС] 13
Никита Александ, Вариант 1: создать окно без границ и считать как в полноэкранном режиме;
вариант 2: гляньте реестр и WindowMetrics, если мне не изменяет память, то параметр CaptionHeight. Формат точно не назову, но там что-то связанное с дюймами. Получите значение, переведите параметр в пиксели - решайте что делать при вычислении позиции курсора.

Добавлено через 27 минут
Никита Александ, я тут немножко наговнокодил:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <windows.h>
#include <iostream>
#include <conio.h>
using namespace std;
 
int main()
{
    HKEY key, hkey = HKEY_CURRENT_USER;
    if (!RegOpenKey(hkey, "Control Panel\\Desktop\\WindowMetrics", &key)) {
        unsigned long bsize = 256, _type = REG_SZ;
        unsigned char *value = new unsigned char[256];
        if (!RegQueryValueEx(key, "CaptionHeight", 0, &_type, value, &bsize))
            cout << value << endl , _getch();
        delete [] value;
        RegCloseKey(key);
    }
    return 0;
}
Вообщем, значение высоты верхней границы в, так называемых, "твипах" (или как-то так), которые нужно перевести в пиксели. Значение в реестре - строка. Переводите строку в число, число из "твипов" в пиксели. Работаете. Удачи)
0
08.06.2014, 21:43
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.06.2014, 21:43
Помогаю со студенческими работами здесь

Вращение фигуры мышью
Подскажите, как сделать что бы данная фигура вращалась при помощи мыши. Делал в Lazarus

Вращение камеры мышью
Здравствуйте, можете мне пожалуйста объяснить, как при помощи мыши можно повернуться на 360...

Вращение призмы мышью
Вот код: #include &lt;glut.h&gt; #include &lt;math.h&gt; #include &lt;iostream&gt; #include &lt;glaux.h&gt; using...

[GLUT] Вращение камеры мышью
Всем доброго времени суток! Есть класс Camera в котором определены методы перемещения в ращения...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru