Мы используем файлы cookie, чтобы упростить навигацию на этом сайте. Если вы даете свое согласие на использование файлов cookie и обработку ваших персональных данных, нажмите «Принимаю».

Управление 3D моделью с сервера

Домой Форумы Для программистов Управление 3D моделью с сервера

Просмотр 6 сообщений - с 1 по 6 (из 6 всего)
  • Автор
    Сообщения
  • #17984
    xfish3
    Участник

    Скажите пожалуйста, возможно ли управление интерактивной 3D моделью с сервера?
    Т.е. идея такая – 3D-модель загружается с сервера, а из стороннего приложения на этот сервер посылаются команды, посредством которых идет управление этой моделью.
    По аналогии, как это можно сделать в Unity

    #17990

    Здравствуйте, такое можно сделать через веб-сокеты.
    Вот небольшой пример сервера на nodejs:

    
    const express = require('express');
    const ws = require('ws');
    
    const URL = 'ws://192.168.2.72:3000';
    
    const app = express();
    app.get('/', (request, response) => {
        response.send(`
            <html>
                <head>
                    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0"/>
                    <style>
                        button { display: block; font-size: 12vh; }
                    </style>
                </head>
                <body>
                    <button id="btn">MOVE SCENE</button>
                </body>
                <script>
                    const socket = new WebSocket('${URL}');
                    document.getElementById('btn').addEventListener('click', e => {
                        socket.send(JSON.stringify({ type: 'scene', data: 'move' }));
                    });
                </script>
            </html>
        `);
    });
    
    const wsServer = new ws.Server({ noServer: true });
    wsServer.on('connection', socket => {
        socket.on('message', message => {
            wsServer.clients.forEach(client => client.send(message.toString()));
        });
    });
    
    const server = app.listen(3000, 'localhost');
    server.on('upgrade', (request, socket, head) => {
        wsServer.handleUpgrade(request, socket, head, (socket, request) => {
            wsServer.emit('connection', socket, request);
        });
    });
    

    – он делает 2 вещи: организует передачу сообщений между приложениями через веб-сокеты, и ещё отдаёт страницу с кнопкой для отправления команд серверу.

    В коде выше в строчке const URL = 'ws://192.168.2.72:3000'; нужно подставить адрес, на котором будет поднят этот сервер. После этого можно зайти на него (на МОЙ_АДРЕС:3000) с мобильного устройства и с него посылать команды серверу, нажимая на кнопку на странице.

    Потом в любом приложении на verge3d можно добавить следующий код:

    
    const URL = 'ws://192.168.2.72:3000';
    
    const socket = new WebSocket(URL);
    socket.addEventListener('message', e => {
        const { type, data } = JSON.parse(e.data);
        if (type === 'scene') {
            if (data === 'move') {
                app.scene.position.x += Math.random() - 0.5;
                app.scene.position.y += Math.random() - 0.5;
                app.scene.position.z += Math.random() - 0.5;
            }
        }
    });
    

    – он подключается к указанному серверу через веб-сокет и реагирует на принятые сообщения. Здесь в const URL = 'ws://192.168.2.72:3000'; нужно подставить тот же адрес сервера, что и в первом случае.

    Co-founder and lead developer at Soft8Soft.

    #17991
    xfish3
    Участник

    Спасибо огромное!

    #18009
    xfish3
    Участник

    Могли бы подсказать еще код для сервера на Python?
    Отправку сообщений через вебсокеты сделал, работает, но через костыли…

    #18011

    Вот, аналогичный только на питоне:

    
    import asyncio
    import http
    
    import websockets
    
    URL = 'ws://192.168.2.72:3000'
    
    async def httpHandler(path, req_headers):
        if req_headers.get('Upgrade', None) == 'websocket':
            return
    
        if path != '/':
            return http.HTTPStatus.NOT_FOUND, [],
    
        body = bytes(f'''
        <html>
            <head>
                <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0"/>
                <style>
                    button {{ display: block; font-size: 12vh; }}
                </style>
            </head>
            <body>
                <button id="btn">MOVE SCENE</button>
            </body>
            <script>
                const socket = new WebSocket('{URL}');
                document.getElementById('btn').addEventListener('click', e => {{
                    socket.send(JSON.stringify({{ type: 'scene', data: 'move' }}));
                }});
            </script>
        </html>
        ''', 'utf-8')
    
        return http.HTTPStatus.OK, [('Content-Type', 'text/html')], body
    
    WS_CLIENTS = set()
    
    async def wsHandler(websocket):
        WS_CLIENTS.add(websocket)
        try:
            async for message in websocket:
                for client in WS_CLIENTS:
                    if client != websocket:
                        await client.send(message)
        finally:
            WS_CLIENTS.remove(websocket)
    
    async def wsServer():
        async with websockets.serve(wsHandler, 'localhost', 3000,
                process_request=httpHandler):
            await asyncio.Future()
    
    if __name__ == '__main__':
        asyncio.run(wsServer())
    

    Co-founder and lead developer at Soft8Soft.

    #18012
    xfish3
    Участник

    Вот спасибо! :good:
    Буду экспериментировать

Просмотр 6 сообщений - с 1 по 6 (из 6 всего)
  • Для ответа в этой теме необходимо авторизоваться.