#javascript #c #websocket #webgl
#javascript #c #websocket #webgl
Вопрос:
Я пытаюсь перенести очень сложную программу 3D-моделирования (написанную на C) на WebGL. Программа имеет собственный физический движок, написанный с нуля, и я хотел бы использовать данные преобразования, которые выводятся физическим движком, в виде матриц для преобразования объектов, отображаемых на веб-странице.
Программа настолько массивна, что я хотел бы сохранить физический движок на C как есть, но перенести графическую часть в браузер.
Моя сумасшедшая идея состоит в том, чтобы на сервере постоянно работал физический движок, а затем передавать матрицы преобразований клиенту и применять преобразования к предварительно отрисованным объектам WebGL.
Возможно ли это сделать?
Уточнение: Программа является средством просмотра, поэтому весь физический сервер изолирован от пользовательского ввода. Пользователь, однако, сможет управлять ракурсами камеры на стороне клиента.
Обновление: я решил реализовать следующее решение, дайте мне знать, если что-то из этого неправильно: я размещу программу C как демон, используя node.js и передача данных с помощью websockets во внешний интерфейс, который pixi.js (для 2D-элементов) и babylon.js (или three.js ) (для 3D-элементов). Данные будут состоять из объектов JSON (кватернионов или матриц синуса / косинуса), которые будут обрабатываться во внешнем интерфейсе на javascript и применяться один раз в секунду (в моей ситуации fps не имеет значения, так что все в порядке)
Комментарии:
1. рассматривали ли вы emscripten ?
2. Я уже пытался использовать emscripten, но мой проект просто слишком большой / сложный (в нем около 12 исходных файлов, одинаковое количество заголовочных файлов, каждый из которых содержит от 2000 до 6000строк кода), чтобы с ним можно было нормально работать. Также проект использует функции, доступные только в OpenGL 3.0 и более поздних версиях, поэтому у emscripten нет готового эмулятора для работы с ними.
Ответ №1:
Матрицы Push и pop являются вспомогательными (не являются основной частью конвейера рендеринга), поэтому вы можете реплицировать их с помощью пользовательского стека.
В целом об этой безумной идее:
В случае интерактивной физики задержка может быть проблемой, и вам потребуется своего рода экстраполяция положения на стороне клиента. В худшем случае у вас будет несколько клиентов. Представьте, что один клиент вызвал какое-то физическое событие, затем он отправит данные на сервер, а сервер отправит их другому клиенту. Таким образом, у вас будет фактически двойная задержка, и в конце будет действительно сложно устранить несоответствие, когда у вас есть 3 состояния (или даже больше, если у вас больше клиентов), по одному уникальному состоянию у каждого клиента и одному фактическому состоянию на сервере. Чем больше задержка — тем выше несогласованность. И физика действительно чувствительна к такого рода несоответствиям, потому что они имеют тенденцию нарастать как снежный ком. Таким образом, ваши клиенты, вероятно, будут видеть какие-то странные появления и исчезновения, телепортации, падения сквозь твердые объекты.
Комментарии:
1. Единственное взаимодействие, которое будет разрешено клиентам, — это перемещение камер, что будет еще одной матрицей преобразования на стороне клиента. Физический движок и создаваемые им данные будут защищены от пользователя (он создает матрицы преобразования, используя данные телеметрии в реальном времени, а не взаимодействие с пользователем). Извините за путаницу, я отредактирую сообщение, чтобы оно было более описательным. Тем не менее, спасибо за ваш ответ сверху :).
2. @Boogiechillin Таким образом, в принципе, вашему интерфейсу не обязательно знать, что является источником преобразования. Это могут быть предварительно записанные статические данные, какая-нибудь анимация или физический движок. Вы просто передадите преобразование в некоторый WebGL, отображаемый как three.js Итак, если вы научитесь им пользоваться и как настраивать WebSockets, то это будет тривиальная задача. Боюсь, простого способа нет 🙂
3. Да, это еще один маршрут, который я рассматривал. Спасибо за вашу помощь! Я буду публиковать обновления о том, что, по моему мнению, сработало лучше всего.
Ответ №2:
Успешно реализовал это, выполнив следующее:
В своем коде на C я использовал библиотеку hiredis для публикации строки в формате JSON в redis, размещенной на компьютере ec2 с nginx. Затем я использовал primus (node_module) для настройки веб-узла подписчика из redis в node.js сервер приложений. Затем узел передает данные (всякий раз, когда происходит публикация) клиенту, где я разобрал JSON и использовал объект для рисования моей сцены.
Это решение действительно быстрое и простое и является очень эффективным средством передачи больших объемов данных (в форме объекта JSON) многим клиентам. Это также позволяет настраивать несколько каналов в C (для разных наборов данных), после чего вы можете выбирать, какие каналы вы хотите прослушивать на стороне клиента (или прослушивать их все сразу!). Я нахожусь далеко от своего компьютера с кодом, но я могу опубликовать более подробные инструкции / примеры кода о том, как это сделать, позже.