last day (15 days later) » 

11:34 AM
0
Q: Как правильно проецировать воксельный мир в камеру?

Dimka4369Для выпускания лучей из камеры и проверки столкновения используется следующий код (основные части): typedef struct { int i; //// текущий индекс ячейки решётки double dt; //// шаг между пересечениями double next_t; //// момент следующего пересечения решётки int d...

 
На 1280*960 картинка нормальная?
 
@StanislavVolodarskiy по длине и ширине (цифры одинаковые) нормально. Я ещё чёрную линию нарисовал, но как я понимаю она должна быть зеркальной
да, повернул направо на 90 и отразил по вертикали - линии совпали, так что можно опереться только на размеры квадратов на экране
интересно, ширина квадратов (ближних, снизу) совпадает с шириной экрана / 10, т.к. расстояние от вокселя до камеры по оси Z составляет 10 единиц.
 
На 1980*960 картинка нормальная?
 
@StanislavVolodarskiy нет, обрезает.
 
Обрезание это нормально. Замените 960 на 96 и обрежется ещё больше.
У вас endZ равно screenWidth. Это означает что угол обзора камеры по горизонтали фиксирован. Угол обзора по вертикали меняется, зависит от разрешения по вертикали. Это нормально. Если вы недовольны тем как работает сейчас, объясните как вы хотите чтобы это было.
 
11:34 AM
@StanislavVolodarskiy получается в таком случае нужно зафиксировать угол обзора по вертикали. При endZ = screenWidth угол обзора по горизонтали получается равен 90 градусам. Я встречал следующую формулу: fovY = fovX * (Height/Width), однако не представляю как мне это применить. Я хочу чтобы правая и нижняя стороны куба были равны друг другу, как на скриншотах: 64 и 64, 128 и 128
 
Сделайте тогда endZ = screenHeight * <фиксированный коэффициент>. Коэффициент подберите руками от единицы до двух. Все кубы будут ровные. Угол обзора по горизонтали у вас был не 90 градусов, а примерно 53. Тригонометрия.
 
@StanislavVolodarskiy даже в 4:3 куб правильный. Однако, при попытке домножить на коэффициент - портится изображение. Хотелось бы так же иметь возможность менять угол обзора, это выгодно для приближения, просмотра вдаль. Как можно поступить в такой ситуации?
 
"фиксированный коэффициент" сверху отвечает за угол обзора. Углы обзора по вертикали и по горизонтали связаны, менять их независимо не получится.
 
@StanislavVolodarskiy да, мне как раз и нужно, чтобы углы были связаны, это очень хорошо. Я не правильно понял проблему. Я подумал, что обрезается из-за неправильной математики, однако часть куба просто оказалась за призмой - по этому и произошло обрезание. Я не сразу это понял из-за того, что обрезание происходит ровно на половине экрана. То есть, с 0, 0 до 959, 539 картинка есть, а дальше с 960, 540 до 1920, 1080 картинка пропадает.
@StanislavVolodarskiy камера получилась отзеркаленной. То есть, у меня в циклах for от - 960 до 959 и если я напишу координату куба -2 он должен быть слева, однако я увижу его справа. Видимо код, который выводит индексы пересекаемых вокселей ожидал на вход другие данные и происходит такая инверсия.
@StanislavVolodarskiy да, сравнил с предыдущей версией кода, где был постоянный шаг, если там координата X = -2, тогда куб будет слева! Буду разбираться...
 
Отрицательный endY порождает отрицательные индексы в Screen. Из-за этого на экране переставлены половины. С endX та же история.
 
11:34 AM
@StanislavVolodarskiy только сейчас перечитал и понял что вы имели ввиду про "индексы в Screen". Да, вы правы, там действительно ошибка, должно быть так: Screen[(endY + Screen_Half_Height) * Screen_Width * 3 + (endX + Screen_Half_Width) * 3 + 0] = 255; Куб будет по центру экрана, если координата камеры 0.5, 0.5, 0. Это нормально, меня устраивает. Всё ещё изучаю ваш код, который определяет пересечение сетки. Понял как работают структуры, но пока что не понимаю, где можно изменить размер сетки? Например, чтобы сетка была каждые 16 единиц: -32, -16, 0, 16, 32, 48, 64...
@StanislavVolodarskiy я попробовал поменять координаты камеры, до 5 единиц по горизонтали, однако не понятно, есть ли искажение? Я менял только начальную точку луча. Получается, что мне нужно так же менять и конечную точку луча? Для поворота камеры уже потребуются соответствующие матрицы. Я представляю это так: 1. Прибавить к конечной точке начальную и повернуть с помощью матрицы. После чего луч будет искать пересечение с сеткой. 2. Прибавить к конечной точке начальную. Луч ищет пересечение с сеткой, координаты которые он выдаёт умножаются на матрицу поворота и проверяется наличие вокселя.
 
Не надо менять размеры сетки. Если вы хотите применить к сетке какое-то преобразование, вместо это вы применяете обратное преобразование к лучу (к двум точкам, которые задают луч).
Камеру можно двигать так: создаёте луч через пиксель. Он определён двумя точками. Обе точки пропускаете через матрицу, которая определяет положение камеры в пространстве. Новый луч соответствует повернутой/смещённой камере.
 
@StanislavVolodarskiy с матрицами я понял, попробую. А вот с лучом и сеткой я не понял. Я хочу сделать оптимизацию, если в чанке размером 16х16х16 есть какие-либо воксели значит нужно сделать размер сетки 1х1х1. То есть, сначала луч идёт по большим чанкам и только если в чанке сказано, что существует воксель размер сетки уменьшается. Я вижу такую структуру: сканируется сетка 256х256х256, если в большом чанке есть маленький уменьшаем размер, после 16х16х16 и если там есть воксель только потом 1х1х1. Чтобы луч долго не сканировал маленькую сетку. Примерно так делают Voxel Octrees.
 
В Voxel Octrees другой способ трассировки луча. Старый код надо будет выкинуть, новый написать.
Надо не изобретать оптимизации, а реализовать честный октри. Это не сложно, если вы до этого решите все остальные проблемы с матрицами. У вас ещё осталось сделать отсечение луча по кубу.
 
@StanislavVolodarskiy я даже не представляю, какой там код в Voxel Octrees, я не знаю, где я мог бы найти пример? Чтобы пример при этом был понятен. Что за отсечение луча по кубу? В моём понимании это прекратить пускать луч если найден воксель, но это уже сделано, по этому я не понимаю, что вы имеете ввиду? Про октри я видел только несколько видео на английском языке, я даже не уверен в том, как они работают, однако сложно понять, о чём там говорят, тем более, что я сам не говорю на английском. Я постараюсь в ближайшее время решить все проблемы с матрицами.
 

last day (15 days later) »