Перейти к содержимому


Фотография

3D-графика для очков из OpenPeripheral

Развлечение 3dgraphics openperipheral

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 7

#1 Оффлайн   Trientalis

Trientalis
  • Пользователи
  • Сообщений: 4
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 07 Апрель 2016 - 15:32

Думаю, тут самое подходящее место, чтобы опубликовать мое новое творение :)


Узнал я недавно о таком прекрасной модификации для любимой игры: OpenComputers. Разузнав подробности, решил попробовать что-нибудь для нее написать, ведь изучение нового яп всегда пойдет на пользу. И тут меня потянуло на графику. Но стандартные мониторы оставляют желать и искать лучшего. Благо, есть такое дополнение, как OpenPeripheral, расширяющее возможности OC, и, помимо прочего, добавляющее очки, через которые можно нарисовать на экране что-то четкое.

Думаю, не стоит больше растягивать предисловие. Представляю вашему вниманию простенький низкоуровневый(пока) графический интерфейс: я назвал его Glass3D.

 

Что можно с ним сделать?

Добавить в список вершины по x,y,z

Создать полигоны по 3-м вершинам

Преобразовывать группы вершин при помощи матриц

Быстро все отрисовывать благодаря sync-функции из api моста очков(~30 fps может)

 

Зачем?

Отрисовывать красивые схемы, голлограммы из ваших программ, которые смогут быть всегда перед глазами :D

 

Исходники

https://raw.githubus...ter/Glass3D.lua

 

Использование

Описание интерфейсов

addVertex3D(x,y,z,h):index -- создает новую вершину, параметр h пока не используется(вообще нужен для масштаба)

 

addVertices3D({x1,y1,z1,x2,y2,z2...,xn,yn,zn}):{index1,...indexn}  -- принимает координаты точек, возвращает массив индексов

 

removeVertex3D(index)  -- удаляет вершину, побочный эффект: смещение, будет решено в будующих версиях

 

addPolygon3D({index1,index2,index3},{color,opacity=1}):name  -- добавляет полигон по трем точкам и цвету, возвращает имя полигона index1+"_"+index2+"_"+index3

 

removePolygon3D(name)  -- удаляет полигон, без побочных эффектов

 

transform({index1,...,indexn},{number1,...,number16})  -- умножает текущую матрицу вершин на переданную

 

update()  -- применяет матрицы вершин на их координаты, рисует полигоны

 

setFocalLenght(number)  -- задает расстояние от глаз пользователя до экрана

 

 

демо: 

--Тетраэдр, немного кривой, ну да ладно
local gl=dofile("Glass3D.lua")
--gl.setFocalLenght(200)
gl.addPolygon3D({gl.addVertex3D(-20,15,0),gl.addVertex3D(20,15,0),gl.addVertex3D(0,-20,0)},{color=0xff00ff,opacity=1})--Добавляет 3 вершины и полигон из них
gl.addPolygon3D({1,2,gl.addVertex3D(0,0,-25)},{color=0x00ff00,opacity=1})--2вершины у нас уже есть, нужна еще одна
gl.addPolygon3D({2,3,4},{color=0x0000ff,opacity=1})--остальные 2 грани
gl.addPolygon3D({3,1,4},{color=0xff0000,opacity=1})
local angle=-0.1*math.pi/180--угол поворота

for i=1,50 do--вращение по Y
gl.transform({1,2,3,4},{math.cos(angle),0,-math.sin(angle),0,
                        0,1,0,0,
                        math.sin(angle),0,math.cos(angle),0,
                        0,0,0,1})
gl.update()
os.sleep(0.03)
end

for i=1,50 do--вращение по Y+Z
gl.transform({1,2,3,4},{math.cos(angle),math.sin(angle),0,0,-math.sin(angle),math.cos(angle),0,0,0,0,1,0,0,0,0,1})
gl.update()
os.sleep(0.03)
end

for i=1,60 do--вращение по Y+X+Z
gl.transform({1,2,3,4},{1,0,0,0,
                        0,math.cos(angle),math.sin(angle),0,
                        0,-math.sin(angle),math.cos(angle),0,
                        0,0,0,1})
gl.update()
os.sleep(0.03)
end

2016-04-07_19.24.53.png 2016-04-07_19.24.54.png 2016-04-07_19.25.00.png

 

О матрицах

матрица параллельного переноса:

  [ 1  0  0  0 ]

  [ 0  1  0  0 ]

  [ 0  0  1  0 ]

  [ x  y  z  1 ]

матрица растяжения/сжатия:

  [ z  0  0  0 ]

  [ 0  y  0  0 ]

  [ 0  0  x  0 ]

  [ 0  0  0  1 ]

матрица поворота вокруг оси x:

  [ 1    0      0    0 ]

  [ 0  cos α  sin α  0 ]

  [ 0 -sin α  cos α  0 ]

  [ 0    0      0    1 ]

матрица поворота вокруг оси y:

  [ cos α  0 -sin α  0 ]

  [  0    1    0    0 ]

  [ sin α  0  cos α  0 ]

  [  0    0    0    1 ]

матрица поворота вокруг оси z:

  [ cos α  sin α  0  0 ]

  [-sin α  cos α  0  0 ]

  [  0      0    1  0 ]

  [  0      0    0  1 ]

 

 

 

Баги, ошибки

Сейчас уже можно нормально пользоваться этим api для простых целей, но имеется один старанный баг, и я никак не могу найти ошибочное место в коде: если применить матрицу поворота по одной оси, потом обновить экран(матрица сольется с вершиной), потом применить поворот по другой оси, эффект прежней матрицы остается :smile14:А, может быть, это вообще не баг, с матрицы я раньше использовал только для одной из осей.

И еще подхрамывает постоянность частота кадров: увеличивается со временем.

 

Спасибо за внимание, надеюсь, вам понравилась моя работа.


Сообщение отредактировал Trientalis: 08 Апрель 2016 - 07:46


#2 Оффлайн   Zer0Galaxy

Zer0Galaxy
  • Гуру
  • Сообщений: 1 230
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

   5                              

Отправлено 07 Апрель 2016 - 16:04

Ну, про отступы сейчас тебе Лёша расскажет. Я скажу вот что:

- библиотеку желательно называть строчными буквами, размещать в директории lib и подключать процедурой require.

- обращаться к вершинам по индексу - не слишком удачное решение. Представь, что у тебя не четыре вершины, а сто четыре. На втором десятке ты в них запутаешься. Я бы сделал, чтоб функция addVertex3D возвращала объект-вершину, а не её индекс.

- хотелось бы описание функций библиотеки. Какие параметры принимают, что возвращают.

А так, очень даже не плохо.



#3 Оффлайн   Trientalis

Trientalis
  • Автор темы
  • Пользователи
  • Сообщений: 4
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 07 Апрель 2016 - 16:17

Спасибо за отзыв :)

процедурой require.
 

Это был тестовый код, его удобно использовать, если вносишь изменения в либу

 

- хотелось бы описание функций библиотеки. Какие параметры принимают, что возвращают.

В исходниках, где не понятно, я описал

 

 

Я бы сделал, чтоб функция addVertex3D возвращала объект-вершину, а не её индекс.

Хорошо, так и сделаю в следующей версии

 

Еще забыл указать один важный момент: спасибо, Fingercomp, за инфу про якори


Сообщение отредактировал Trientalis: 07 Апрель 2016 - 16:26


#4 Оффлайн   Zer0Galaxy

Zer0Galaxy
  • Гуру
  • Сообщений: 1 230
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

   5                              

Отправлено 07 Апрель 2016 - 16:28

В исходниках, где не понятно, я описал
Комментарии это, конечно, хорошо. Но, согласись, рыться в чужом исходнике, что б понять, какие параметры нужны функции и какие функции есть вообще, не очень удобно.
  • Trientalis это нравится

#5 Оффлайн   Totoro

Totoro
  • Хранители Кода
  • Сообщений: 1 750
  • Уровень сигнала: 0,26%
  • В игре: 2 час. 13 мин.

Награды

                                      

Отправлено 07 Апрель 2016 - 18:01

Немного ворчания по поводу тщательно выписанной лицензии.

 

Все что публикуется на Pastebin получает автоматом лицензию cc by-sa 3.0 .

Если планируется публиковать под другой, следует воспользоваться другим сервисом. ;)



#6 Оффлайн   qwertyMAN

qwertyMAN
  • Пользователи
  • Сообщений: 1 458
  • Уровень сигнала: 0,22%
  • В игре: 1 час. 54 мин.
  • ГородCity17

Награды

                             

Отправлено 07 Апрель 2016 - 18:54

--Тетраэдр, немного кривой, ну да ладно

Аааааа, как? Зачем? Ты убиваешь во мне перфекциониста такими методами.

Когда я тестировал и писал 3D рендеринг, я делал идеальный тетраэдр (моя любимая геометрическая фигура). Но ты меня убил вот этим "немного кривой". Так сложно использовать формулы? Так сложно логически составить формулы для составления точных точек тетраэдра?

Учи тригонометрию.

for i=1,60 do--вращение по Y+X+Z
gl.transform({1,2,3,4},{1,0,0,0,
                        0,math.cos(angle),math.sin(angle),0,
                        0,-math.sin(angle),math.cos(angle),0,
                        0,0,0,1})
gl.update()
os.sleep(0.03)
end 

Правильное применение отступам? Ага, их как раз так и применяют  :smile3:


Сообщение отредактировал qwertyMAN: 07 Апрель 2016 - 18:54


#7 Оффлайн   Trientalis

Trientalis
  • Автор темы
  • Пользователи
  • Сообщений: 4
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 08 Апрель 2016 - 07:37

Так сложно использовать формулы?

Наизусть не помню, а зач специально искать в сети, это же просто тестовый код

Ага, их как раз так и применяют

Не понял. Что не так?

[a,b,c,d,

 e,f,g,h,

 i, j, k, l,

 m,n,o,p]

Матрица 4 на 4, эти отступы увеличивают читаемость кода.


Все что публикуется на Pastebin получает автоматом лицензию cc by-sa 3.0 .

Спасибо, не знал



#8 Оффлайн   qwertyMAN

qwertyMAN
  • Пользователи
  • Сообщений: 1 458
  • Уровень сигнала: 0,22%
  • В игре: 1 час. 54 мин.
  • ГородCity17

Награды

                             

Отправлено 08 Апрель 2016 - 20:31

Наизусть не помню, а зач специально искать в сети, это же просто тестовый код

Да забудь вообще слово "учить". Формулы нужно самому уметь выводить, а не надеяться на интернет, таблицу сложения и прочий мусор выдуманный гуманитариями.

В общем я решил за тебя сделать столь сложный труд, вот 4 координаты точек правильного тетраэдра:

local x=10 -- любое число - длинна грани тетраэдра
{-x/2,0,0}
{x/2,0,0}
{0,0,math.sqrt(3)*x/2}
{0,math.sqrt(x^2-(x/(2*math.sqrt(3)))^2),x/(2*math.sqrt(3))}

Тригонометрия и не такое может.

 

Не понял. Что не так?

Мне кажется можно было читаемость повысить другим способом. Вынести таблицу в отдельную локальную переменную или например добавить отступы в коде где их нет. А их нигде нет.

 

local angle=-0.1*math.pi/180--угол поворота

Используешь по старинке math.pi/180 ?

Так уже давно никто не делает. Почитай тут про библиотеку math, там есть такие полезные функции как math.deg и math.rad, они делают то что тебе надо.

 

И да, если часто используешь какую то библиотеку, то желательно написать следующее в начале кода:

local math = math

По идее локальная переменная должна работать быстрее чем глобальная и это должно ускорить код.


  • SergOmarov и Hello это нравится





Темы с аналогичным тегами Развлечение, 3dgraphics, openperipheral

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных