Compare commits
2 Commits
sim_stereo
...
cloudxr
| Author | SHA1 | Date | |
|---|---|---|---|
| 510e610a27 | |||
| 623e05f250 |
13
deps/cloudxr/Dockerfile.wss.proxy
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
FROM haproxy:3.2
|
||||||
|
USER root
|
||||||
|
RUN apt-get update && apt-get install -y bash gettext-base openssl && rm -rf /var/lib/apt/lists/*
|
||||||
|
RUN mkdir -p /usr/local/etc/haproxy/certs && chown -R haproxy:haproxy /usr/local/etc/haproxy
|
||||||
|
|
||||||
|
RUN printf '#!/bin/bash\ncd /usr/local/etc/haproxy/certs\nopenssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=localhost" -quiet\ncat server.crt server.key > server.pem\nchown haproxy:haproxy server.key server.crt server.pem\nchmod 600 server.key server.pem\nchmod 644 server.crt\n' > /usr/local/bin/generate-cert.sh && chmod +x /usr/local/bin/generate-cert.sh
|
||||||
|
|
||||||
|
RUN printf 'global\n log stdout local0 info\n stats timeout 30s\n user haproxy\ndefaults\n log global\n option httplog\n option dontlognull\n timeout connect 5s\n timeout client 3600s\n timeout server 3600s\n timeout tunnel 3600s\nfrontend websocket_frontend\n bind *:${PROXY_PORT} ${PROXY_SSL_BIND_OPTIONS}\n mode http\n http-response set-header Access-Control-Allow-Origin "*"\n http-response set-header Access-Control-Allow-Headers "*"\n http-response set-header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"\n http-request return status 200 content-type "text/plain" string "OK" if METH_OPTIONS\n default_backend websocket_backend\nbackend websocket_backend\n mode http\n server local_websocket ${BACKEND_HOST}:${BACKEND_PORT} check inter 2s rise 2 fall 3 on-marked-down shutdown-sessions\n' > /usr/local/etc/haproxy/haproxy.cfg.template && chown haproxy:haproxy /usr/local/etc/haproxy/haproxy.cfg.template
|
||||||
|
|
||||||
|
RUN printf '#!/bin/bash\nexport BACKEND_HOST=${BACKEND_HOST:-localhost}\nexport BACKEND_PORT=${BACKEND_PORT:-49100}\nexport PROXY_PORT=${PROXY_PORT:-48322}\n/usr/local/bin/generate-cert.sh\nexport PROXY_SSL_BIND_OPTIONS="ssl crt /usr/local/etc/haproxy/certs/server.pem"\nenvsubst < /usr/local/etc/haproxy/haproxy.cfg.template > /usr/local/etc/haproxy/haproxy.cfg\necho "WSS Proxy: wss://0.0.0.0:${PROXY_PORT} -> ws://${BACKEND_HOST}:${BACKEND_PORT}"\nexec haproxy -f /usr/local/etc/haproxy/haproxy.cfg\n' > /entrypoint.sh && chmod +x /entrypoint.sh
|
||||||
|
|
||||||
|
USER haproxy
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
257
deps/cloudxr/INSTALL.md
vendored
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
# CloudXR VR Teleoperation Setup Guide
|
||||||
|
|
||||||
|
将 Isaac Lab 仿真画面通过 NVIDIA CloudXR 流式传输到 PICO 4 Ultra,实现沉浸式 VR 遥操作。
|
||||||
|
|
||||||
|
## 架构
|
||||||
|
|
||||||
|
```
|
||||||
|
Isaac Sim (本地) ──OpenXR──► CloudXR Runtime (Docker)
|
||||||
|
│
|
||||||
|
WebSocket (port 49100)
|
||||||
|
│
|
||||||
|
HAProxy WSS Proxy (port 48322)
|
||||||
|
│
|
||||||
|
PICO 4 Ultra 浏览器
|
||||||
|
https://<IP>:8080 (Web App)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 系统要求
|
||||||
|
|
||||||
|
- Ubuntu 22.04 / 24.04
|
||||||
|
- NVIDIA GPU (RTX 系列)
|
||||||
|
- NVIDIA Driver 最新版
|
||||||
|
- Docker + NVIDIA Container Toolkit
|
||||||
|
- Isaac Lab 本地安装(`~/IsaacLab`)
|
||||||
|
- PICO 4 Ultra (OS 15.4.4U 或更高)
|
||||||
|
- CloudXR Early Access 资格([申请地址](https://developer.nvidia.com/cloudxr-sdk))
|
||||||
|
- Node.js 20 LTS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、系统环境准备
|
||||||
|
|
||||||
|
### 1.1 安装 NVIDIA Container Toolkit
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
|
||||||
|
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
|
||||||
|
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
|
||||||
|
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y nvidia-container-toolkit
|
||||||
|
sudo nvidia-ctk runtime configure --runtime=docker
|
||||||
|
sudo systemctl restart docker
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 配置 Docker(国内镜像 + NVIDIA runtime)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo tee /etc/docker/daemon.json << 'EOF'
|
||||||
|
{
|
||||||
|
"registry-mirrors": [
|
||||||
|
"https://docker.1ms.run",
|
||||||
|
"https://docker.1panel.live",
|
||||||
|
"https://hub.rat.dev"
|
||||||
|
],
|
||||||
|
"runtimes": {
|
||||||
|
"nvidia": {
|
||||||
|
"path": "nvidia-container-runtime",
|
||||||
|
"runtimeArgs": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
sudo systemctl restart docker
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 开放防火墙端口
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ufw allow 47998:48000/udp
|
||||||
|
sudo ufw allow 48005/udp
|
||||||
|
sudo ufw allow 48008/udp
|
||||||
|
sudo ufw allow 48012/udp
|
||||||
|
sudo ufw allow 48010/tcp
|
||||||
|
sudo ufw allow 49100/tcp
|
||||||
|
sudo ufw allow 48322/tcp
|
||||||
|
sudo ufw allow 8080/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.4 安装 Node.js 20 LTS(通过 nvm)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
|
||||||
|
source ~/.bashrc
|
||||||
|
nvm install 20
|
||||||
|
nvm use 20
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、获取 CloudXR Early Access SDK
|
||||||
|
|
||||||
|
CloudXR.js SDK 已包含在本仓库 `deps/cloudxr/` 目录中,无需单独下载。
|
||||||
|
|
||||||
|
只需登录 NGC Docker registry 以拉取 CloudXR Runtime 镜像:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo docker login nvcr.io
|
||||||
|
# Username: $oauthtoken
|
||||||
|
# Password: <你的 NGC API Key>
|
||||||
|
```
|
||||||
|
|
||||||
|
> NGC API Key 获取:[ngc.nvidia.com](https://ngc.nvidia.com) → 右上角头像 → Setup → Generate API Key
|
||||||
|
>
|
||||||
|
> Early Access 申请:[申请地址](https://developer.nvidia.com/cloudxr-sdk) — 申请通过后才能拉取 `cloudxr-runtime-early-access` 镜像。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、配置 Isaac Lab Docker
|
||||||
|
|
||||||
|
修改 `~/IsaacLab/docker/.env.cloudxr-runtime`:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
CLOUDXR_RUNTIME_BASE_IMAGE_ARG=nvcr.io/nvidia/cloudxr-runtime-early-access
|
||||||
|
CLOUDXR_RUNTIME_VERSION_ARG=6.0.1-webrtc
|
||||||
|
ACCEPT_EULA=yes
|
||||||
|
```
|
||||||
|
|
||||||
|
修改 `~/IsaacLab/docker/docker-compose.cloudxr-runtime.patch.yaml`,将 cloudxr-runtime service 的 `ports` 替换为 `network_mode: host`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
cloudxr-runtime:
|
||||||
|
image: ${CLOUDXR_RUNTIME_BASE_IMAGE_ARG}:${CLOUDXR_RUNTIME_VERSION_ARG}
|
||||||
|
network_mode: host
|
||||||
|
# ... 其余保持不变
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、构建 WSS 代理(HAProxy)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd deps/cloudxr
|
||||||
|
|
||||||
|
# 构建镜像
|
||||||
|
sudo docker build -t websocket-ssl-proxy -f Dockerfile.wss.proxy .
|
||||||
|
|
||||||
|
# 启动代理(监听 48322,转发到 CloudXR Runtime 的 49100)
|
||||||
|
sudo docker run -d --name wss-proxy \
|
||||||
|
--network host \
|
||||||
|
-e BACKEND_HOST=localhost \
|
||||||
|
-e BACKEND_PORT=49100 \
|
||||||
|
-e PROXY_PORT=48322 \
|
||||||
|
websocket-ssl-proxy
|
||||||
|
|
||||||
|
# 验证
|
||||||
|
sudo docker logs wss-proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、构建 Web 客户端
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd deps/cloudxr/isaac
|
||||||
|
|
||||||
|
# 安装依赖(需要先安装本地 CloudXR SDK)
|
||||||
|
npm install ../nvidia-cloudxr-6.0.0-beta.tgz
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# 启动 HTTPS 开发服务器(端口 8080)
|
||||||
|
npm run dev-server:https
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注意**:首次运行会下载 WebXR controller profile 资源,需要网络连接。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、启动流程
|
||||||
|
|
||||||
|
每次使用前按以下顺序启动:
|
||||||
|
|
||||||
|
### 6.1 启动 CloudXR Runtime + Isaac Lab
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/IsaacLab
|
||||||
|
./docker/container.py start \
|
||||||
|
--files docker-compose.cloudxr-runtime.patch.yaml \
|
||||||
|
--env-file .env.cloudxr-runtime
|
||||||
|
|
||||||
|
# 进入 Isaac Lab 容器
|
||||||
|
./docker/container.py enter base
|
||||||
|
```
|
||||||
|
|
||||||
|
容器内运行 MindBot 遥操作:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
~/IsaacLab/isaaclab.sh -p scripts/environments/teleoperation/teleop_xr_agent.py \
|
||||||
|
--task Isaac-MindRobot-2i-DualArm-IK-Abs-v0 \
|
||||||
|
--cloudxr
|
||||||
|
```
|
||||||
|
|
||||||
|
Isaac Sim 启动后:**AR 面板 → OpenXR → System OpenXR Runtime → 点击 Start AR**
|
||||||
|
|
||||||
|
### 6.2 启动 WSS 代理
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo docker start wss-proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.3 启动 Web 服务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd deps/cloudxr/isaac
|
||||||
|
npm run dev-server:https
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、PICO 4 Ultra 配置
|
||||||
|
|
||||||
|
### 7.1 启用手部追踪
|
||||||
|
|
||||||
|
设置 → Interaction → 选择 **Auto Switch between Hands & Controllers**
|
||||||
|
|
||||||
|
### 7.2 接受证书
|
||||||
|
|
||||||
|
1. 打开 PICO 浏览器,访问 `https://<工作站IP>:48322/`
|
||||||
|
- 点击 **Advanced** → **Proceed (unsafe)**
|
||||||
|
- 看到 "501 Not Implemented" 是正常的
|
||||||
|
2. 访问 `https://<工作站IP>:8080/`
|
||||||
|
- 点击 **Advanced** → **Proceed (unsafe)**
|
||||||
|
- Web App 加载成功
|
||||||
|
|
||||||
|
### 7.3 连接
|
||||||
|
|
||||||
|
1. 在 Web App 中输入工作站 IP
|
||||||
|
2. 点击 **CONNECT**
|
||||||
|
3. 点击 **Enter XR** 进入沉浸式模式
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、验证端口状态
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ss -tlnp | grep -E "49100|48322|8080"
|
||||||
|
```
|
||||||
|
|
||||||
|
预期输出:
|
||||||
|
```
|
||||||
|
LISTEN 0.0.0.0:49100 cloudxr-service # CloudXR Runtime
|
||||||
|
LISTEN 0.0.0.0:48322 haproxy # WSS Proxy
|
||||||
|
LISTEN 0.0.0.0:8080 node # Web App
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
| 症状 | 原因 | 解决 |
|
||||||
|
|---|---|---|
|
||||||
|
| 503 Service Unavailable (48322) | CloudXR Runtime 未运行 | 重启 docker-cloudxr-runtime-1 容器 |
|
||||||
|
| 501 Not Implemented (48322) | 正常 — HAProxy 只处理 WebSocket | 直接接受证书即可 |
|
||||||
|
| Stream start failed 0xC0F22202 | HTTPS + ws:// 混合内容 | 必须先接受 48322 代理证书 |
|
||||||
|
| EMFILE: too many open files | webpack 文件监听超限 | 已通过 `watchOptions.ignored` 修复 |
|
||||||
|
| Isaac Sim AR 面板看不到 | 未传 --cloudxr 或 --xr flag | 使用 `--cloudxr` 启动脚本 |
|
||||||
307
deps/cloudxr/LICENSE
vendored
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
NVIDIA SOFTWARE EVALUATION LICENSE AGREEMENT
|
||||||
|
|
||||||
|
IMPORTANT NOTICE – PLEASE READ AND AGREE BEFORE USING THE SOFTWARE
|
||||||
|
|
||||||
|
This software evaluation license agreement (“Agreement”) is a legal agreement between you, whether an
|
||||||
|
individual or entity, (“you”) and NVIDIA Corporation and its affiliates (“NVIDIA”) and governs the use of certain
|
||||||
|
NVIDIA CloudXR software and documentation that NVIDIA delivers to you under this Agreement (“Software”).
|
||||||
|
NVIDIA and you are each a “party” and collectively the “parties.”
|
||||||
|
This Agreement can be accepted only by an adult of legal age of majority in the country in which the Software is
|
||||||
|
used. If you don’t have the required age or authority to accept this Agreement, or if you don’t accept all the
|
||||||
|
terms and conditions of this Agreement, do not use the Software.
|
||||||
|
|
||||||
|
1. License Grants.
|
||||||
|
|
||||||
|
1.1 License Grant to You. The Software is licensed, not sold. Subject to the terms of this Agreement,
|
||||||
|
NVIDIA grants you a limited, non-exclusive, revocable, non-transferable, non-sublicensable (except
|
||||||
|
as expressly granted in this Agreement), license to:
|
||||||
|
(a) access, install and use copies of the Software,
|
||||||
|
(b) configure the Software using configuration files provided (if applicable),
|
||||||
|
(c) modify and create derivative works of any source code NVIDIA delivers to you as part of the
|
||||||
|
Software (“Derivatives”) (if applicable).
|
||||||
|
|
||||||
|
All the foregoing grants are only for internal test and evaluation purposes and, as applicable, for use (a) in
|
||||||
|
client systems, or (b) in server systems with NVIDIA GPUs (“Purpose”).
|
||||||
|
|
||||||
|
1.2 License Grant to NVIDIA. Subject to the terms of this Agreement, you grant NVIDIA a non-exclusive,
|
||||||
|
perpetual, irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license,
|
||||||
|
under your intellectual property rights, to publicly perform, publicly display, reproduce, use, make,
|
||||||
|
have made, sell, offer for sale, distribute (through multiple tiers of distribution), import, create
|
||||||
|
derivative works of and otherwise commercialize and exploit at NVIDIA’s discretion any Derivatives
|
||||||
|
created by or for you. You may, but are not required to, deliver any Derivatives to NVIDIA.
|
||||||
|
|
||||||
|
2. License Restrictions. Your license to use the Software and Derivatives is restricted as stated in this “License
|
||||||
|
Restrictions” Section. You will cooperate with NVIDIA and, upon NVIDIA’s written request, you will confirm
|
||||||
|
in writing and provide reasonably requested information to verify your compliance with the terms of this
|
||||||
|
Agreement. You may not:
|
||||||
|
|
||||||
|
2.1 Use the Software or Derivatives for any purpose other than the Purpose, including but not limited to
|
||||||
|
in production;
|
||||||
|
|
||||||
|
2.2 Sell, rent, sublicense, transfer, distribute or otherwise make available to others (except Authorized
|
||||||
|
Users as stated in the “Authorized Users” Section) any portion of the Software or Derivatives, except
|
||||||
|
as expressly granted in Section 1.1 (“License Grant to You”);
|
||||||
|
|
||||||
|
2.3 Reverse engineer, decompile, or disassemble the Software components provided in binary form, nor
|
||||||
|
attempt in any other manner to obtain source code of such Software;
|
||||||
|
|
||||||
|
2.4 Modify or create derivative works of the Software, except as expressly granted in Section 1.1
|
||||||
|
(“License Grant to You”);
|
||||||
|
|
||||||
|
2.5 Change or remove copyright or other proprietary notices in the Software;
|
||||||
|
|
||||||
|
2.6 Bypass, disable, or circumvent any technical limitation, encryption, security, digital rights
|
||||||
|
management or authentication mechanism in the Software;
|
||||||
|
|
||||||
|
2.7 Use the Software or Derivatives in any manner that would cause them to become subject to an open
|
||||||
|
source software license; subject to the terms in Section 7 (“Components Under Other Licenses”);
|
||||||
|
|
||||||
|
2.8 Use the Software or Derivatives for the purpose of developing competing products or technologies
|
||||||
|
or assist a third party in such activities;
|
||||||
|
|
||||||
|
2.9 Replace any Software components governed by this Agreement with other software that
|
||||||
|
implements NVIDIA APIs;
|
||||||
|
|
||||||
|
2.10 Use the Software or Derivatives in violation of any applicable law or regulation in the relevant
|
||||||
|
jurisdictions; or
|
||||||
|
|
||||||
|
2.11 Use the Software in or with any system or application where the use or failure of such system or
|
||||||
|
application developed or deployed with Software could result in injury, death or catastrophic
|
||||||
|
damage (“Mission Critical Applications”). NVIDIA will not be liable to you or any third party, in whole
|
||||||
|
or in part, for any claims or damages arising from uses in Mission Critical Applications.
|
||||||
|
|
||||||
|
2.12 Disclose any evaluation or test results regarding the Software or Derivatives without NVIDIA’s prior
|
||||||
|
written consent.
|
||||||
|
|
||||||
|
3. Authorized Users. You may allow employees and contractors of your entity or of your subsidiary(ies), and
|
||||||
|
for educational institutions also enrolled students, to internally access and use the Software as authorized
|
||||||
|
by this Agreement from your secure network to perform the work authorized by this Agreement on your
|
||||||
|
behalf. You are responsible for the compliance with the terms of this Agreement by your authorized users.
|
||||||
|
Any act or omission that if committed by you would constitute a breach of this Agreement will be deemed to
|
||||||
|
constitute a breach of this Agreement if committed by your authorized users.
|
||||||
|
|
||||||
|
4. Pre-Release. Software versions identified as alpha, beta, preview, early access or otherwise as pre-release
|
||||||
|
may not be fully functional, may contain errors or design flaws, and may have reduced or different security,
|
||||||
|
privacy, availability and reliability standards relative to NVIDIA commercial offerings. You use pre-release
|
||||||
|
Software at your own risk. NVIDIA did not design or test the Software for use in production or business
|
||||||
|
critical systems. NVIDIA may choose not to make available a commercial version of pre-release Software.
|
||||||
|
NVIDIA may also choose to abandon development and terminate the availability of pre-release Software at
|
||||||
|
any time without liability.
|
||||||
|
|
||||||
|
5. Your Privacy: Collection and Use of Information.
|
||||||
|
|
||||||
|
5.1 Privacy Policy. Please review the NVIDIA Privacy Policy, located at https://www.nvidia.com/enus/about-nvidia/privacy-policy, which explains NVIDIA’s policy for collecting and using data, as well
|
||||||
|
as visit the NVIDIA Privacy Center, located at https://www.nvidia.com/en-us/privacy-center, to
|
||||||
|
manage your consent and privacy preferences.
|
||||||
|
|
||||||
|
5.2 Collection Purposes. You also acknowledge that the Software collects data for the following
|
||||||
|
purposes: (a) properly configure and optimize products for use with Software; and (b) improve
|
||||||
|
NVIDIA products and services. Information collected by the Software includes: (i) application
|
||||||
|
configuration; (ii) browser version; (iii) and session metadata (i.e. performance and usage
|
||||||
|
statistics). Additionally, NVIDIA may collect certain personal information, such as your name
|
||||||
|
and email address or those of your authorized users, and other information necessary to
|
||||||
|
authenticate and enable you or your authorized users’ access to the Software. Where appropriate
|
||||||
|
you will disclose to, and obtain any necessary consent from, your authorized users to allow NVIDIA
|
||||||
|
to collect such information.
|
||||||
|
|
||||||
|
5.3 Third Party Privacy Practices. The Software may contain links to third party websites and services.
|
||||||
|
NVIDIA encourages you to review the privacy statements on those sites and services that you choose
|
||||||
|
to visit to understand how they may collect, use and share your data. NVIDIA is not responsible for
|
||||||
|
the privacy statements or practices of third-party sites or services.
|
||||||
|
|
||||||
|
6. Updates. NVIDIA may at any time and at its option, change, discontinue, or deprecate any part, or all, of the
|
||||||
|
Software, or change or remove features or functionality, or make available patches, workarounds or other
|
||||||
|
updates to the Software. Unless the updates are provided with their separate governing terms, they are
|
||||||
|
deemed part of the Software licensed to you under this Agreement, and your continued use of the Software
|
||||||
|
is deemed acceptance of such changes.
|
||||||
|
|
||||||
|
7. Components Under Other Licenses. The Software may include or be distributed with components provided
|
||||||
|
with separate legal notices or terms that accompany the components, such as open source software licenses
|
||||||
|
and other license terms (“Other Licenses”). The components are subject to the applicable Other Licenses,
|
||||||
|
including any proprietary notices, disclaimers, requirements and extended use rights; except that this
|
||||||
|
Agreement will prevail regarding the use of third-party open source software, unless a third-party open
|
||||||
|
source software license requires its license terms to prevail. Open source software license means any
|
||||||
|
software, data or documentation subject to any license identified as an open source license by the Open
|
||||||
|
Source Initiative (http://opensource.org), Free Software Foundation (http://www.fsf.org) or other similar
|
||||||
|
open source organization or listed by the Software Package Data Exchange (SPDX) Workgroup under the
|
||||||
|
Linux Foundation (http://www.spdx.org).
|
||||||
|
|
||||||
|
8. Ownership.
|
||||||
|
|
||||||
|
8.1 NVIDIA Ownership. The Software, including all intellectual property rights, is and will remain the sole
|
||||||
|
and exclusive property of NVIDIA or its licensors. Except as expressly granted in this Agreement,
|
||||||
|
(a) NVIDIA reserves all rights, interests and remedies in connection with the Software, and (b) no
|
||||||
|
other license or right is granted to you by implication, estoppel or otherwise.
|
||||||
|
|
||||||
|
8.2 Your Ownership. Subject to the rights of NVIDIA and its suppliers in the Software, which continue to
|
||||||
|
be licensed as stated in this Agreement, even when incorporated in your products, and the extent
|
||||||
|
permitted by applicable law, as between you and NVIDIA, you hold all rights, title and interest in and
|
||||||
|
to your services, applications and Derivatives you develop as permitted in this Agreement including
|
||||||
|
their respective intellectual property rights.
|
||||||
|
|
||||||
|
9. Feedback. You may, but are not obligated to, provide suggestions, requests, fixes, modifications,
|
||||||
|
enhancements or other feedback regarding your use of the Software (“Feedback”). Feedback, even if
|
||||||
|
designated as confidential by you, will not create any confidentiality obligation for NVIDIA or its affiliates. If
|
||||||
|
you provide Feedback, you hereby grant NVIDIA, its affiliates and its designees a nonexclusive, perpetual,
|
||||||
|
irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license, under your
|
||||||
|
intellectual property rights, to publicly perform, publicly display, reproduce, use, make, have made, sell,
|
||||||
|
offer for sale, distribute (through multiple tiers of distribution), import, create derivative works of and
|
||||||
|
otherwise commercialize and exploit the Feedback at NVIDIA’s discretion.
|
||||||
|
|
||||||
|
10. Confidentiality. You may use confidential information only to exercise your rights and perform your
|
||||||
|
obligations under this Agreement. You will not disclose, nor authorize others to disclose NVIDIA Confidential
|
||||||
|
Information to any third party, except as expressly authorized in this Agreement and as necessary for the
|
||||||
|
Purpose, without obtaining NVIDIA’s prior written approval. Each recipient of confidential information must
|
||||||
|
be subject to a written agreement that includes confidentiality obligations consistent with these terms and
|
||||||
|
must have a need to know for the Purpose. You will protect the NVIDIA Confidential Information with at
|
||||||
|
least the same degree of care that you use to protect your own similar confidential and proprietary
|
||||||
|
information, but no less than a reasonable degree of care. Confidential information includes, but is not
|
||||||
|
limited to, the Software, including its features and functionality, Derivatives, and any results of
|
||||||
|
benchmarking or other competitive analysis or regression or performance data relating to the Software.
|
||||||
|
No Publicity. You may not issue any public statements about this Agreement, disclose the Software or
|
||||||
|
Derivatives, or any information or results related to your use of the Software, without prior written approval
|
||||||
|
of NVIDIA.
|
||||||
|
|
||||||
|
11. Term and Termination.
|
||||||
|
|
||||||
|
11.1 Term. This Agreement has a duration of twelve (12) months starting from the date of initial
|
||||||
|
download (even if you download the same version or updates of the Software later and it is
|
||||||
|
accompanied by this Agreement or another Agreement), unless terminated earlier in accordance
|
||||||
|
with this Agreement.
|
||||||
|
|
||||||
|
11.2 Termination for Convenience. Either party may terminate this Agreement at any time with thirty (30)
|
||||||
|
days’ advance written notice to the other party.
|
||||||
|
|
||||||
|
11.3 Termination for Cause. If you commence or participate in any legal proceeding against NVIDIA with
|
||||||
|
respect to the Software, this Agreement will terminate immediately without notice. Either party may
|
||||||
|
terminate this Agreement upon notice for cause if:
|
||||||
|
(a) the other party fails to cure a material breach of this Agreement within ten (10) days of the
|
||||||
|
non-breaching party’s notice of the breach; or
|
||||||
|
(b) the other party breaches its confidentiality obligations or license rights under this
|
||||||
|
Agreement, which termination will be effective immediately upon written notice.
|
||||||
|
|
||||||
|
11.4 Effect of Termination. Upon any expiration or termination of this Agreement, you will promptly
|
||||||
|
(a) stop using and return, delete or destroy NVIDIA confidential information and all Software
|
||||||
|
received under this Agreement, and (b) delete or destroy Derivatives created under this Agreement,
|
||||||
|
unless an authorized NVIDIA representative provides prior written approval that you may keep a
|
||||||
|
copy of the Derivatives solely for archival purposes. Upon written request, you will certify in writing
|
||||||
|
that you have complied with your obligations under this “Effect of Termination” Section.
|
||||||
|
|
||||||
|
11.5 Survival. The “License Grant to NVIDIA”, “Updates”, “Components Under Other Licenses”,
|
||||||
|
“Ownership”, “Feedback”, “Confidentiality”, “No Publicity”, “Effect of Termination”, “Survival”,
|
||||||
|
“Disclaimer of Warranties”, “Limitation of Liability”, “Indemnity” and all “General” Sections of this
|
||||||
|
Agreement will survive any expiration or termination of this Agreement.
|
||||||
|
|
||||||
|
12. Disclaimer of Warranties. THE SOFTWARE IS PROVIDED BY NVIDIA AS-IS AND WITH ALL FAULTS. TO THE
|
||||||
|
MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NVIDIA DISCLAIMS ALL WARRANTIES AND
|
||||||
|
REPRESENTATIONS OF ANY KIND, WHETHER EXPRESS, IMPLIED OR STATUTORY, RELATING TO OR ARISING
|
||||||
|
UNDER THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF TITLE,
|
||||||
|
NONINFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, USAGE OF TRADE AND
|
||||||
|
COURSE OF DEALING. NVIDIA DOES NOT WARRANT OR ASSUME RESPONSIBILITY FOR THE ACCURACY OR
|
||||||
|
COMPLETENESS OF ANY THIRD-PARTY INFORMATION, TEXT, GRAPHICS, LINKS CONTAINED IN THE
|
||||||
|
SOFTWARE. WITHOUT LIMITING THE FOREGOING, NVIDIA DOES NOT WARRANT THAT THE SOFTWARE WILL
|
||||||
|
MEET YOUR REQUIREMENTS, ANY DEFECTS OR ERRORS WILL BE CORRECTED, ANY CERTAIN CONTENT WILL
|
||||||
|
BE AVAILABLE; OR THAT THE SOFTWARE IS FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS. NO
|
||||||
|
INFORMATION OR ADVICE GIVEN BY NVIDIA WILL IN ANY WAY INCREASE THE SCOPE OF ANY WARRANTY
|
||||||
|
EXPRESSLY PROVIDED IN THIS AGREEMENT. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE
|
||||||
|
APPROPRIATENESS OF USING THE SOFTWARE OR DERIVATIVES AND ASSUME ANY RISKS ASSOCIATED WITH
|
||||||
|
YOUR USE OF THE SOFTWARE OR DERIVATIVES.
|
||||||
|
|
||||||
|
13. Limitations of Liability.
|
||||||
|
|
||||||
|
13.1 EXCLUSIONS. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
|
||||||
|
NVIDIA BE LIABLE FOR ANY (A) INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES, OR (B) DAMAGES FOR THE (I) COST OF PROCURING SUBSTITUTE GOODS OR (II) LOSS OF
|
||||||
|
PROFITS, REVENUES, USE, DATA OR GOODWILL ARISING OUT OF OR RELATED TO THIS AGREEMENT,
|
||||||
|
WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR
|
||||||
|
OTHERWISE, AND EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND
|
||||||
|
EVEN IF A PARTY’S REMEDIES FAIL THEIR ESSENTIAL PURPOSE.
|
||||||
|
|
||||||
|
13.2 DAMAGES CAP. ADDITIONALLY, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
|
||||||
|
NVIDIA’S TOTAL CUMULATIVE AGGREGATE LIABILITY FOR ANY AND ALL LIABILITIES, OBLIGATIONS OR
|
||||||
|
CLAIMS ARISING OUT OF OR RELATED TO THIS AGREEMENT WILL NOT EXCEED ONE HUNDRED U.S.
|
||||||
|
DOLLARS (US$100).
|
||||||
|
|
||||||
|
14. Indemnity. You will defend, indemnify and hold harmless NVIDIA and its affiliates, and their respective
|
||||||
|
employees, contractors, agents, officers and directors, from and against any and all third party claims,
|
||||||
|
damages, obligations, losses, liabilities, costs or debt, fines, restitutions and expenses (including but not
|
||||||
|
limited to attorney’s fees and costs incident to establishing the right of indemnification) arising out of use of
|
||||||
|
the Software and Derivatives outside of the scope of this Agreement or in breach of the terms of this
|
||||||
|
Agreement.
|
||||||
|
|
||||||
|
15. General.
|
||||||
|
|
||||||
|
15.1 Governing Law and Jurisdiction. This Agreement will be governed in all respects by the laws of the
|
||||||
|
United States and the laws of the State of Delaware, without regard to conflict of laws principles or
|
||||||
|
the United Nations Convention on Contracts for the International Sale of Goods. The state and
|
||||||
|
federal courts residing in Santa Clara County, California will have exclusive jurisdiction over any
|
||||||
|
dispute or claim arising out of or related to this Agreement, and the parties irrevocably consent to
|
||||||
|
personal jurisdiction and venue in those courts; except that either party may apply for injunctive
|
||||||
|
remedies or an equivalent type of urgent legal relief in any jurisdiction.
|
||||||
|
|
||||||
|
15.2 Independent Contractors. The parties are independent contractors, and this Agreement does not
|
||||||
|
create a joint venture, partnership, agency or other form of business association between the
|
||||||
|
parties. Neither party will have the power to bind the other party or incur any obligation on its
|
||||||
|
behalf without the other party’s prior written consent. Nothing in this Agreement prevents either
|
||||||
|
party from participating in similar arrangements with third parties.
|
||||||
|
|
||||||
|
15.3 No Assignment. NVIDIA may assign, delegate or transfer its rights or obligations under this
|
||||||
|
Agreement by any means or operation of law. You may not, without NVIDIA’s prior written consent,
|
||||||
|
assign, delegate or transfer any of your rights or obligations under this Agreement by any means or
|
||||||
|
operation of law, and any attempt to do so is null and void.
|
||||||
|
|
||||||
|
15.4 No Waiver. No failure or delay by a party to enforce any term or obligation of this Agreement will
|
||||||
|
operate as a waiver by that party, or prevent the enforcement of such term or obligation later.
|
||||||
|
|
||||||
|
15.5 Trade Compliance. You agree to comply with all applicable export, import, trade and economic
|
||||||
|
sanctions laws and regulations, as amended, including without limitation U.S. Export Administration
|
||||||
|
Regulations and Office of Foreign Assets Control regulations. You confirm (a) your understanding
|
||||||
|
that export or reexport of certain NVIDIA products or technologies may require a license or other
|
||||||
|
approval from appropriate authorities and (b) that you will not export or reexport any products or
|
||||||
|
technology, directly or indirectly, without first obtaining any required license or other approval from
|
||||||
|
appropriate authorities, (i) to any countries that are subject to any U.S. or local export restrictions
|
||||||
|
(currently including, but not necessarily limited to, Belarus, Cuba, Iran, North Korea, Russia, Syria,
|
||||||
|
the Region of Crimea, Donetsk People’s Republic Region and Luhansk People’s Republic Region); (ii)
|
||||||
|
to any end-user who you know or have reason to know will utilize them in the design, development
|
||||||
|
or production of nuclear, chemical or biological weapons, missiles, rocket systems, unmanned air
|
||||||
|
vehicles capable of a maximum range of at least 300 kilometers, regardless of payload, or intended
|
||||||
|
for military end-use, or any weapons of mass destruction; (iii) to any end-user who has been
|
||||||
|
prohibited from participating in the U.S. or local export transactions by any governing authority; or
|
||||||
|
(iv) to any known military or military-intelligence end-user or for any known military or military-
|
||||||
|
intelligence end-use in accordance with U.S. trade compliance laws and regulations.
|
||||||
|
|
||||||
|
15.6 Government Rights. The Software, documentation and technology (“Protected Items”) are
|
||||||
|
“Commercial products” as this term is defined at 48 C.F.R. 2.101, consisting of “commercial
|
||||||
|
computer software” and “commercial computer software documentation” as such terms are used
|
||||||
|
in, respectively, 48 C.F.R. 12.212 and 48 C.F.R. 227.7202 & 252.227-7014(a)(1). Before any Protected
|
||||||
|
Items are supplied to the U.S. Government, you will (i) inform the U.S. Government in writing that
|
||||||
|
the Protected Items are and must be treated as commercial computer software and commercial
|
||||||
|
computer software documentation developed at private expense; (ii) inform the U.S. Government
|
||||||
|
that the Protected Items are provided subject to the terms of the Agreement; and (iii) mark the
|
||||||
|
Protected Items as commercial computer software and commercial computer software
|
||||||
|
documentation developed at private expense. In no event will you permit the U.S. Government to
|
||||||
|
acquire rights in Protected Items beyond those specified in 48 C.F.R. 52.227-19(b)(1)-(2) or 252.227-
|
||||||
|
7013(c) except as expressly approved by NVIDIA in writing.
|
||||||
|
|
||||||
|
15.7 Notices. Please direct your legal notices or other correspondence to legalnotices@nvidia.com with a
|
||||||
|
copy mailed to NVIDIA Corporation, 2788 San Tomas Expressway, Santa Clara, California 95051,
|
||||||
|
United States of America, Attention: Legal Department. If NVIDIA needs to contact you about the
|
||||||
|
Software, you consent to receive the notices by email and agree that such notices will satisfy any
|
||||||
|
legal communication requirements.
|
||||||
|
|
||||||
|
15.8 Severability. If a court of competent jurisdiction rules that a provision of this Agreement is
|
||||||
|
unenforceable, that provision will be deemed modified to the extent necessary to make it
|
||||||
|
enforceable and the remainder of this Agreement will continue in full force and effect.
|
||||||
|
|
||||||
|
15.9 Amendment. Any amendment to this Agreement must be in writing and signed by authorized
|
||||||
|
representatives of both parties.
|
||||||
|
|
||||||
|
15.10 Entire Agreement. Regarding the subject matter of this Agreement, the parties agree that (a) this
|
||||||
|
Agreement constitutes the entire and exclusive agreement between the parties and supersedes all
|
||||||
|
prior and contemporaneous communications and (b) any additional or different terms or conditions,
|
||||||
|
whether contained in purchase orders, order acknowledgments, invoices or otherwise, will not be
|
||||||
|
binding and are null and void.
|
||||||
|
|
||||||
|
(v. February 25, 2025)
|
||||||
|
|
||||||
|
NVIDIA Confidential
|
||||||
71
deps/cloudxr/README.md
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# NVIDIA CloudXR.js SDK - Getting Started
|
||||||
|
|
||||||
|
> **Note:** For detailed documentation, see the `docs/` folder (open `docs/index.html` in browser).
|
||||||
|
|
||||||
|
[The NVIDIA CloudXR.js SDK](#) enables developers to build web clients that stream high-quality spatial content from CloudXR servers with powerful GPUs to web browsers on XR devices. It consists of:
|
||||||
|
- **CloudXR.js SDK** - a JavaScript client library
|
||||||
|
- **WebGL-based simple sample client** that uses core Web APIs (WebGL, WebXR)
|
||||||
|
- **React-based sample client** that uses the R3F (React-Three-Fiber) framework stack
|
||||||
|
|
||||||
|
<!-- #region firstRunGuide -->
|
||||||
|
|
||||||
|
It is *strongly recommended* that you work through this guide if you have never run CloudXR.js before.
|
||||||
|
|
||||||
|
## The Pieces of a CloudXR.js Deployment
|
||||||
|
|
||||||
|
Even for development, you'll need all the pieces of a CloudXR.js deployment in order to build and test a client. These are:
|
||||||
|
|
||||||
|
- a CloudXR Server
|
||||||
|
- with a _top-end_ NVIDIA GPU or 2 (e.g. dual RTX 6000 Ada)
|
||||||
|
- which will run
|
||||||
|
- the CloudXR Runtime
|
||||||
|
- an OpenXR application (the thing you want to render on the server but see on the client)
|
||||||
|
- a CloudXR.js development workstation
|
||||||
|
- with Node.js and `npm`
|
||||||
|
- which will run
|
||||||
|
- the CloudXR.js sample client build
|
||||||
|
- a Node-based development web server
|
||||||
|
- a CloudXR.js client
|
||||||
|
- which is one of:
|
||||||
|
- a Meta Quest 3 with its built-in Browser app
|
||||||
|
- a desktop browser: [Google Chrome](https://www.google.com/chrome) or Edge (IWER automatically loads for WebXR emulation)
|
||||||
|
- which will run...
|
||||||
|
- the CloudXR.js sample client *served from the development web server*.
|
||||||
|
|
||||||
|
We *recommend* that for your first experience, all above run on *the same computer* to eliminate networking related issues.
|
||||||
|
|
||||||
|
## High Level Workflow
|
||||||
|
|
||||||
|
You need both a working client and a working server in order to test. Typically we follow a startup flow where server starts before the client:
|
||||||
|
|
||||||
|
1. CloudXR Runtime
|
||||||
|
2. Server XR application
|
||||||
|
3. Sample client build + web server
|
||||||
|
4. Test from the same computer
|
||||||
|
5. Test from Quest 3 or a different computer
|
||||||
|
|
||||||
|
<!-- #endregion firstRunGuide -->
|
||||||
|
|
||||||
|
Please refer to [the CloudXR.js SDK documentations](#sdk-documentation) for details.
|
||||||
|
|
||||||
|
## SDK Documentation
|
||||||
|
|
||||||
|
The `docs/` folder contains comprehensive documentation including:
|
||||||
|
- Getting Started guides with example server applications
|
||||||
|
- API reference for building custom clients
|
||||||
|
- Common issues and solutions
|
||||||
|
|
||||||
|
Open `docs/index.html` in your browser for organized navigation with table of contents.
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For technical support and questions about this early access release:
|
||||||
|
- Review the troubleshooting sections in the SDK documentation
|
||||||
|
- Study the example implementations for integration patterns
|
||||||
|
- Contact the NVIDIA CloudXR team for additional assistance
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
> **Important**: This is an [evaluation license](LICENSE) for internal test and evaluation purposes only. For commercial use, please contact NVIDIA for appropriate licensing terms.
|
||||||
|
|
||||||
|
> **Note**: This is an early access release of CloudXR.js. Features and APIs may change in future releases.
|
||||||
1
deps/cloudxr/docs/.nojekyll
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.
|
||||||
1
deps/cloudxr/docs/assets/hierarchy.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
window.hierarchyData = "eJyrVirKzy8pVrKKjtVRKkpNy0lNLsnMzytWsqqurQUAmx4Kpg=="
|
||||||
120
deps/cloudxr/docs/assets/highlight.css
vendored
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
:root {
|
||||||
|
--light-hl-0: #795E26;
|
||||||
|
--dark-hl-0: #DCDCAA;
|
||||||
|
--light-hl-1: #000000;
|
||||||
|
--dark-hl-1: #D4D4D4;
|
||||||
|
--light-hl-2: #A31515;
|
||||||
|
--dark-hl-2: #CE9178;
|
||||||
|
--light-hl-3: #008000;
|
||||||
|
--dark-hl-3: #6A9955;
|
||||||
|
--light-hl-4: #001080;
|
||||||
|
--dark-hl-4: #9CDCFE;
|
||||||
|
--light-hl-5: #0070C1;
|
||||||
|
--dark-hl-5: #4FC1FF;
|
||||||
|
--light-hl-6: #0000FF;
|
||||||
|
--dark-hl-6: #569CD6;
|
||||||
|
--light-hl-7: #098658;
|
||||||
|
--dark-hl-7: #B5CEA8;
|
||||||
|
--light-hl-8: #000000;
|
||||||
|
--dark-hl-8: #C8C8C8;
|
||||||
|
--light-hl-9: #AF00DB;
|
||||||
|
--dark-hl-9: #C586C0;
|
||||||
|
--light-hl-10: #EE0000;
|
||||||
|
--dark-hl-10: #D7BA7D;
|
||||||
|
--light-hl-11: #800000;
|
||||||
|
--dark-hl-11: #569CD6;
|
||||||
|
--light-hl-12: #0000FF;
|
||||||
|
--dark-hl-12: #CE9178;
|
||||||
|
--light-hl-13: #267F99;
|
||||||
|
--dark-hl-13: #4EC9B0;
|
||||||
|
--light-code-background: #FFFFFF;
|
||||||
|
--dark-code-background: #1E1E1E;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) { :root {
|
||||||
|
--hl-0: var(--light-hl-0);
|
||||||
|
--hl-1: var(--light-hl-1);
|
||||||
|
--hl-2: var(--light-hl-2);
|
||||||
|
--hl-3: var(--light-hl-3);
|
||||||
|
--hl-4: var(--light-hl-4);
|
||||||
|
--hl-5: var(--light-hl-5);
|
||||||
|
--hl-6: var(--light-hl-6);
|
||||||
|
--hl-7: var(--light-hl-7);
|
||||||
|
--hl-8: var(--light-hl-8);
|
||||||
|
--hl-9: var(--light-hl-9);
|
||||||
|
--hl-10: var(--light-hl-10);
|
||||||
|
--hl-11: var(--light-hl-11);
|
||||||
|
--hl-12: var(--light-hl-12);
|
||||||
|
--hl-13: var(--light-hl-13);
|
||||||
|
--code-background: var(--light-code-background);
|
||||||
|
} }
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) { :root {
|
||||||
|
--hl-0: var(--dark-hl-0);
|
||||||
|
--hl-1: var(--dark-hl-1);
|
||||||
|
--hl-2: var(--dark-hl-2);
|
||||||
|
--hl-3: var(--dark-hl-3);
|
||||||
|
--hl-4: var(--dark-hl-4);
|
||||||
|
--hl-5: var(--dark-hl-5);
|
||||||
|
--hl-6: var(--dark-hl-6);
|
||||||
|
--hl-7: var(--dark-hl-7);
|
||||||
|
--hl-8: var(--dark-hl-8);
|
||||||
|
--hl-9: var(--dark-hl-9);
|
||||||
|
--hl-10: var(--dark-hl-10);
|
||||||
|
--hl-11: var(--dark-hl-11);
|
||||||
|
--hl-12: var(--dark-hl-12);
|
||||||
|
--hl-13: var(--dark-hl-13);
|
||||||
|
--code-background: var(--dark-code-background);
|
||||||
|
} }
|
||||||
|
|
||||||
|
:root[data-theme='light'] {
|
||||||
|
--hl-0: var(--light-hl-0);
|
||||||
|
--hl-1: var(--light-hl-1);
|
||||||
|
--hl-2: var(--light-hl-2);
|
||||||
|
--hl-3: var(--light-hl-3);
|
||||||
|
--hl-4: var(--light-hl-4);
|
||||||
|
--hl-5: var(--light-hl-5);
|
||||||
|
--hl-6: var(--light-hl-6);
|
||||||
|
--hl-7: var(--light-hl-7);
|
||||||
|
--hl-8: var(--light-hl-8);
|
||||||
|
--hl-9: var(--light-hl-9);
|
||||||
|
--hl-10: var(--light-hl-10);
|
||||||
|
--hl-11: var(--light-hl-11);
|
||||||
|
--hl-12: var(--light-hl-12);
|
||||||
|
--hl-13: var(--light-hl-13);
|
||||||
|
--code-background: var(--light-code-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme='dark'] {
|
||||||
|
--hl-0: var(--dark-hl-0);
|
||||||
|
--hl-1: var(--dark-hl-1);
|
||||||
|
--hl-2: var(--dark-hl-2);
|
||||||
|
--hl-3: var(--dark-hl-3);
|
||||||
|
--hl-4: var(--dark-hl-4);
|
||||||
|
--hl-5: var(--dark-hl-5);
|
||||||
|
--hl-6: var(--dark-hl-6);
|
||||||
|
--hl-7: var(--dark-hl-7);
|
||||||
|
--hl-8: var(--dark-hl-8);
|
||||||
|
--hl-9: var(--dark-hl-9);
|
||||||
|
--hl-10: var(--dark-hl-10);
|
||||||
|
--hl-11: var(--dark-hl-11);
|
||||||
|
--hl-12: var(--dark-hl-12);
|
||||||
|
--hl-13: var(--dark-hl-13);
|
||||||
|
--code-background: var(--dark-code-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hl-0 { color: var(--hl-0); }
|
||||||
|
.hl-1 { color: var(--hl-1); }
|
||||||
|
.hl-2 { color: var(--hl-2); }
|
||||||
|
.hl-3 { color: var(--hl-3); }
|
||||||
|
.hl-4 { color: var(--hl-4); }
|
||||||
|
.hl-5 { color: var(--hl-5); }
|
||||||
|
.hl-6 { color: var(--hl-6); }
|
||||||
|
.hl-7 { color: var(--hl-7); }
|
||||||
|
.hl-8 { color: var(--hl-8); }
|
||||||
|
.hl-9 { color: var(--hl-9); }
|
||||||
|
.hl-10 { color: var(--hl-10); }
|
||||||
|
.hl-11 { color: var(--hl-11); }
|
||||||
|
.hl-12 { color: var(--hl-12); }
|
||||||
|
.hl-13 { color: var(--hl-13); }
|
||||||
|
pre, code { background: var(--code-background); }
|
||||||
18
deps/cloudxr/docs/assets/icons.js
vendored
Normal file
1
deps/cloudxr/docs/assets/icons.svg
vendored
Normal file
|
After Width: | Height: | Size: 12 KiB |
60
deps/cloudxr/docs/assets/main.js
vendored
Normal file
1
deps/cloudxr/docs/assets/navigation.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
window.navigationData = "eJydlG9LwzAQxr9KyOv5B6dj7N1QkMF00zoURI6sva3FNinpdVPE7y7NYtd2nW1923vu9zxJ7vr6xQk/iI/4bIN6E+CW93gsyOcj7ik3jVBScvZbO/UpCnmPvwfS46NhfzgcnA+/eznjFokCuWYOCU3o1aGsBKykltjjrh+EnkbJR6853BFRHCK7DgOUxE7YMy5vp20sdo2wa4QTMI1NR6m6PaJw6T9uprHe7a3oh0kSKMnG80mdiy3DeD5pSm4jO0hpXIeyyUy9iXWPtFX63bzpMd5e047p+GrLrkWCSe1BfbUFU+0wGpNECJdNxZI9YYiqNmYBbOQwFUvYybsMoZ3wRcwc1BvUbKW0dUUtKFCyq7lFwiKGHRJWSkMJ2XSlBbFcMyXZHZJgDykmxPpd85RgoCRkMDAw6Dclqb4Ee9IqXYaY+EplvK5hqh+gwju2WG+V24mQ9GedeV5svOPmg7TKVlxUlXovj3tSpLw0xGxDTaHcf3FsIM2PwSFBuCehTKM9p6iphDr8A91giGtBxe0MJKFeCRcPkLm4kvVqcAiexdkot8JaaQtoG9pfGFejIDyArVLpmgg5qyQsEweX2cD9API9f+w="
|
||||||
1
deps/cloudxr/docs/assets/search.js
vendored
Normal file
1611
deps/cloudxr/docs/assets/style.css
vendored
Normal file
247
deps/cloudxr/docs/documents/Client_Setup.html
vendored
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Client Setup | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Client_Setup.html">Client Setup</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="client-setup-guide" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Client Setup Guide<a href="#client-setup-guide" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>This guide provides configuration examples for CloudXR.js client devices, including browser setup, web server hosting options, and connection modes. These examples demonstrate common deployment scenarios you may encounter.</p>
|
||||||
|
<a id="web-application-hosting" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Web Application Hosting<a href="#web-application-hosting" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>CloudXR.js client applications can be hosted using either HTTP or HTTPS protocols. We provide examples for both modes to help you choose the right approach for your deployment.</p>
|
||||||
|
<a id="http-mode-development" class="tsd-anchor"></a><h3 class="tsd-anchor-link">HTTP Mode (Development)<a href="#http-mode-development" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>This example demonstrates the simplest configuration for local development and testing.</p>
|
||||||
|
<p><strong>Example command:</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">run</span><span class="hl-1"> </span><span class="hl-2">dev-server</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<p><strong>Access URLs:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Local: <code>http://localhost:8080/</code></li>
|
||||||
|
<li>Network: <code>http://<server-ip>:8080/</code></li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Characteristics:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Simplified setup with minimal configuration</li>
|
||||||
|
<li>Supports connections to both <code>ws://</code> (direct) and <code>wss://</code> (proxied) CloudXR Runtime endpoints</li>
|
||||||
|
<li>Requires browser security flags for WebXR functionality (see <a href="#meta-quest-3-browser-configuration">Browser Configuration</a>)</li>
|
||||||
|
<li>Recommended for: Local development, trusted network environments</li>
|
||||||
|
</ul>
|
||||||
|
<a id="https-mode-development-and-production" class="tsd-anchor"></a><h3 class="tsd-anchor-link">HTTPS Mode (Development and Production)<a href="#https-mode-development-and-production" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>This example demonstrates HTTPS hosting, which is used for both development with WebXR devices and production deployments. It provides encrypted client connections and is required for secure WebSocket connections.</p>
|
||||||
|
<p><strong>Example command:</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">run</span><span class="hl-1"> </span><span class="hl-2">dev-server:https</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<p><strong>Access URLs:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Local: <code>https://localhost:8080/</code></li>
|
||||||
|
<li>Network: <code>https://<server-ip>:8080/</code></li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Characteristics:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Automatically generates self-signed SSL certificates (for development) or custom certificates (for production)</li>
|
||||||
|
<li><strong>Requires</strong> <code>wss://</code> (secure WebSocket) connection to CloudXR Runtime</li>
|
||||||
|
<li>Browsers enforce mixed content policy, blocking <code>ws://</code> connections from HTTPS pages</li>
|
||||||
|
<li>Requires certificate trust configuration in client browser</li>
|
||||||
|
<li>Recommended for: WebXR device testing, production deployments, remote access, security-sensitive environments</li>
|
||||||
|
</ul>
|
||||||
|
<a id="connection-mode-examples" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Connection Mode Examples<a href="#connection-mode-examples" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The following table shows example connection configurations between the web application server and CloudXR Runtime:</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Client Web Server</th>
|
||||||
|
<th>Runtime Connection</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Use Case</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>HTTP</td>
|
||||||
|
<td><code>ws://server-ip:49100</code></td>
|
||||||
|
<td>✅ Supported</td>
|
||||||
|
<td>Local development (simplest path)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HTTP</td>
|
||||||
|
<td><code>wss://proxy-ip:48322</code></td>
|
||||||
|
<td>✅ Supported</td>
|
||||||
|
<td>Testing proxy configuration</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HTTPS</td>
|
||||||
|
<td><code>ws://server-ip:49100</code></td>
|
||||||
|
<td>❌ Blocked</td>
|
||||||
|
<td>Mixed content security policy violation</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HTTPS</td>
|
||||||
|
<td><code>wss://proxy-ip:48322</code></td>
|
||||||
|
<td>✅ Supported</td>
|
||||||
|
<td>WebXR device testing, production deployment</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Important</strong>: When using HTTPS mode for your web application, you must configure a WebSocket proxy with TLS support. See the <a href="Networking_Setup.html#websocket-proxy-setup">Networking Setup Guide - WebSocket Proxy Setup</a> for configuration details.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="meta-quest-3-browser-configuration" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Meta Quest 3 Browser Configuration<a href="#meta-quest-3-browser-configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>This section provides configurations for Meta Quest 3 to enable WebXR functionality with CloudXR.js applications.</p>
|
||||||
|
<a id="configure-insecure-origins-http-mode" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Configure Insecure Origins (HTTP Mode)<a href="#configure-insecure-origins-http-mode" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>When using HTTP mode, the Meta Quest 3 browser needs explicit permission to access WebXR APIs from non-HTTPS origins. Here's how to configure it:</p>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Access Chrome flags:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Open the Meta Quest 3 Browser</li>
|
||||||
|
<li>Navigate to <code>chrome://flags</code></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Enable insecure origins:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Search for "insecure" in the search field</li>
|
||||||
|
<li>Locate the flag: <code>unsafely-treat-insecure-origin-as-secure</code></li>
|
||||||
|
<li>Set the flag to <strong>Enabled</strong></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Add your development server:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>In the text field below the flag, enter your web server URL</li>
|
||||||
|
<li><strong>Format</strong>: <code>http://<server-ip>:8080</code></li>
|
||||||
|
<li>Include the protocol (<code>http://</code>) and port number (<code>:8080</code>)</li>
|
||||||
|
<li>Multiple URLs can be separated by commas if needed</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Apply configuration:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Click or tap outside the text field to defocus</li>
|
||||||
|
<li>A "Relaunch" button will appear at the bottom of the screen</li>
|
||||||
|
<li>Click <strong>Relaunch</strong> to apply changes</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Verify configuration:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Return to <code>chrome://flags</code> after relaunch</li>
|
||||||
|
<li>Confirm the flag remains enabled and your URL is saved</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<a id="trust-ssl-certificates-https-mode" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Trust SSL Certificates (HTTPS Mode)<a href="#trust-ssl-certificates-https-mode" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>When using HTTPS mode with self-signed certificates (for the web server and the WebSocket proxy), you need to configure the browser to trust these certificates.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Note</strong>: Certificate trust settings persist across browser sessions. You only need to perform this configuration once per certificate.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="trust-websocket-proxy-certificate" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Trust WebSocket Proxy Certificate<a href="#trust-websocket-proxy-certificate" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Access the proxy endpoint:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<p>In Meta Quest 3 Browser in the sample client page, fill in the proxy IP as server IP and corresponding port, and click "click xxx to accept cert" as shown below. Or you can directly navigate to <code>https://<proxy-ip>:48322/</code></p>
|
||||||
|
<p><img src="../media/accept-proxy-cert.png" alt=""></p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Accept certificate warning:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<p>Click <strong>Advanced</strong></p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Click <strong>Proceed to <code><proxy-ip></code> (unsafe)</strong> or similar option</p>
|
||||||
|
<p><img src="../media/accept-cert.png" alt=""></p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Expected behavior:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>The page may display a <code>501 Not Implemented</code> error</li>
|
||||||
|
<li><strong>This is expected</strong> - the proxy only handles WebSocket connections, not HTTP requests</li>
|
||||||
|
<li>The certificate is now trusted for WebSocket connections</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Note</strong>: If you restart or recreate the proxy container (using the Docker HAProxy example with auto-generated certificates), a new self-signed certificate will be generated. You must repeat the certificate trust process by visiting <code>https://<proxy-ip>:48322/</code> again and accepting the new certificate warning. If you mount your own certificate (see <a href="Networking_Setup.html#using-custom-certificates">Networking Setup - Using Custom Certificates</a>), the same certificate persists across restarts and you only need to trust it once.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="trust-web-application-certificate" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Trust Web Application Certificate<a href="#trust-web-application-certificate" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Access the web application:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Open Meta Quest 3 Browser</li>
|
||||||
|
<li>Navigate to <code>https://<server-ip>:8080/</code></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Accept certificate warning:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<p>Click <strong>Advanced</strong></p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Click <strong>Proceed to <code><server-ip></code> (unsafe)</strong> or similar option</p>
|
||||||
|
<p><img src="../media/accept-cert.png" alt=""></p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Verify access:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>The web application should load successfully</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<a id="verify-webxr-permissions" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Verify WebXR Permissions<a href="#verify-webxr-permissions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>When connecting to a CloudXR.js application:</p>
|
||||||
|
<ol>
|
||||||
|
<li>The browser will prompt for WebXR permissions</li>
|
||||||
|
<li>Select <strong>Allow</strong> when prompted</li>
|
||||||
|
<li>The immersive session will begin after permission is granted</li>
|
||||||
|
</ol>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Tip</strong>: For rapid development and debugging, you can test your CloudXR.js application on a desktop browser before deploying to Meta Quest 3. Detailed setup instructions are provided in the <a href="Show_Cases.Isaac_Lab_Teleop.Teleoperating_on_Meta_Quest_3.html">Isaac Lab Client</a> guide.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="network-configuration" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Network Configuration<a href="#network-configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>For network and firewall configuration requirements, including port setup and bandwidth recommendations, see the <a href="Networking_Setup.html">Networking Setup Guide</a>.</p>
|
||||||
|
<a id="common-issues-and-solutions" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Common Issues and Solutions<a href="#common-issues-and-solutions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="webxr-api-not-available" class="tsd-anchor"></a><h3 class="tsd-anchor-link">WebXR API Not Available<a href="#webxr-api-not-available" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>Symptoms:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Application displays "WebXR not supported" or similar error</li>
|
||||||
|
<li>Connect button is disabled or missing</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Solutions:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Verify browser flags are configured correctly (<a href="#configure-insecure-origins-http-mode">HTTP mode example</a>)</li>
|
||||||
|
<li>Ensure you're accessing via the configured URL exactly as specified</li>
|
||||||
|
<li>Confirm the browser has been relaunched after changing flags</li>
|
||||||
|
<li>Try accessing via incognito/private browsing mode</li>
|
||||||
|
</ul>
|
||||||
|
<a id="certificate-trust-issues" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Certificate Trust Issues<a href="#certificate-trust-issues" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>Symptoms:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Connection fails with security warnings</li>
|
||||||
|
<li>WebSocket connection shows "SSL certificate error"</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Solutions:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Complete the certificate trust process for both web server and proxy</li>
|
||||||
|
<li>Verify you clicked "Proceed" on the certificate warning pages</li>
|
||||||
|
<li>Clear browser cache and retry the trust process</li>
|
||||||
|
<li>For persistent issues, regenerate certificates</li>
|
||||||
|
</ul>
|
||||||
|
<a id="mixed-content-errors" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Mixed Content Errors<a href="#mixed-content-errors" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>Symptoms:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Console shows "blocked by mixed content policy" errors</li>
|
||||||
|
<li>WebSocket connection fails from HTTPS page</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Solutions:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>When using <code>npm run dev-server:https</code>, ensure runtime connection uses <code>wss://</code> not <code>ws://</code></li>
|
||||||
|
<li>Verify a WebSocket proxy is configured and running (see <a href="Networking_Setup.html#websocket-proxy-setup">Networking Setup examples</a>)</li>
|
||||||
|
<li>Check that proxy URL is accessible and trusted</li>
|
||||||
|
</ul>
|
||||||
|
<a id="connection-drops-or-instability" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Connection Drops or Instability<a href="#connection-drops-or-instability" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>Symptoms:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Frequent disconnections during streaming</li>
|
||||||
|
<li>Poor video quality or high latency</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Solutions:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Review <a href="Networking_Setup.html">Networking Setup Guide</a> for bandwidth and latency requirements</li>
|
||||||
|
<li>Verify firewall allows traffic on required ports</li>
|
||||||
|
<li>Ensure Wi-Fi connection is on 5GHz or 6GHz band</li>
|
||||||
|
<li>Check for network congestion from other devices</li>
|
||||||
|
</ul>
|
||||||
|
<a id="next-steps" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Next Steps<a href="#next-steps" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
|
||||||
|
<li>Configure networking and firewall: <a href="Networking_Setup.html">Networking Setup Guide</a></li>
|
||||||
|
<li>Set up Isaac Lab teleoperation: <a href="Show_Cases.Isaac_Lab_Teleop.html">Isaac Lab Guide</a></li>
|
||||||
|
</ul>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#client-setup-guide"><span>Client <wbr/>Setup <wbr/>Guide</span></a><ul><li><a href="#web-application-hosting"><span>Web <wbr/>Application <wbr/>Hosting</span></a></li><li><ul><li><a href="#http-mode-development"><span>HTTP <wbr/>Mode (<wbr/>Development)</span></a></li><li><a href="#https-mode-development-and-production"><span>HTTPS <wbr/>Mode (<wbr/>Development and <wbr/>Production)</span></a></li></ul></li><li><a href="#connection-mode-examples"><span>Connection <wbr/>Mode <wbr/>Examples</span></a></li><li><a href="#meta-quest-3-browser-configuration"><span>Meta <wbr/>Quest 3 <wbr/>Browser <wbr/>Configuration</span></a></li><li><ul><li><a href="#configure-insecure-origins-http-mode"><span>Configure <wbr/>Insecure <wbr/>Origins (HTTP <wbr/>Mode)</span></a></li><li><a href="#trust-ssl-certificates-https-mode"><span>Trust SSL <wbr/>Certificates (HTTPS <wbr/>Mode)</span></a></li><li><ul><li><a href="#trust-websocket-proxy-certificate"><span>Trust <wbr/>Web<wbr/>Socket <wbr/>Proxy <wbr/>Certificate</span></a></li><li><a href="#trust-web-application-certificate"><span>Trust <wbr/>Web <wbr/>Application <wbr/>Certificate</span></a></li></ul></li><li><a href="#verify-webxr-permissions"><span>Verify <wbr/>WebXR <wbr/>Permissions</span></a></li></ul></li><li><a href="#network-configuration"><span>Network <wbr/>Configuration</span></a></li><li><a href="#common-issues-and-solutions"><span>Common <wbr/>Issues and <wbr/>Solutions</span></a></li><li><ul><li><a href="#webxr-api-not-available"><span>WebXR API <wbr/>Not <wbr/>Available</span></a></li><li><a href="#certificate-trust-issues"><span>Certificate <wbr/>Trust <wbr/>Issues</span></a></li><li><a href="#mixed-content-errors"><span>Mixed <wbr/>Content <wbr/>Errors</span></a></li><li><a href="#connection-drops-or-instability"><span>Connection <wbr/>Drops or <wbr/>Instability</span></a></li></ul></li><li><a href="#next-steps"><span>Next <wbr/>Steps</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
150
deps/cloudxr/docs/documents/Getting_Started.Sample_Client_-_React.html
vendored
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Sample Client - React | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Getting_Started.html">Getting Started</a></li><li><a href="Getting_Started.Sample_Client_-_React.html">Sample Client - React</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="react-three-fiber-example" class="tsd-anchor"></a><h1 class="tsd-anchor-link">React Three Fiber Example<a href="#react-three-fiber-example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>This is a comprehensive CloudXR.js React Three Fiber example application that demonstrates how to integrate CloudXR streaming with modern React development patterns. This example showcases the power of combining CloudXR.js with React Three Fiber, React Three XR, and React Three UIKit to create immersive XR experiences with rich 3D user interfaces.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>NOTE: This example is not meant to be used for production.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="overview" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Overview<a href="#overview" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>This example showcases the integration of CloudXR.js with the React Three Fiber ecosystem, providing:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>React Three Fiber Integration</strong>: Seamless integration with Three.js through React components</li>
|
||||||
|
<li><strong>React Three XR</strong>: WebXR session management with React hooks and state management</li>
|
||||||
|
<li><strong>React Three UIKit</strong>: Rich 3D user interface components for VR/AR experiences</li>
|
||||||
|
<li><strong>CloudXR Streaming</strong>: Real-time streaming of XR content from a CloudXR server</li>
|
||||||
|
<li><strong>Modern React Patterns</strong>: Hooks, context, and component-based architecture</li>
|
||||||
|
<li><strong>Dual UI System</strong>: 2D HTML interface for configuration and 3D VR interface for interaction</li>
|
||||||
|
</ul>
|
||||||
|
<a id="quick-start" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Quick Start<a href="#quick-start" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="prerequisites" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Prerequisites<a href="#prerequisites" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul>
|
||||||
|
<li>Node.js (v20 or higher)</li>
|
||||||
|
<li>A CloudXR server running and accessible</li>
|
||||||
|
<li>A WebXR-compatible device (VR headset, AR device)</li>
|
||||||
|
</ul>
|
||||||
|
<a id="installation" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Installation<a href="#installation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Navigate to the example folder</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">cd</span><span class="hl-1"> </span><span class="hl-2">react</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Install Dependencies</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-3"># For this early access release, please run the following to install SDK from the given tarball. This step will not be needed when SDK is publicly accessible.</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">install</span><span class="hl-1"> </span><span class="hl-2">../nvidia-cloudxr-6.0.0-beta.tgz</span><br/><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">install</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Build the Application</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">run</span><span class="hl-1"> </span><span class="hl-2">build</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Start Development Server</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">run</span><span class="hl-1"> </span><span class="hl-2">dev-server</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Open in Browser</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Navigate to <code>http://localhost:8080</code> (or the port shown in terminal)</li>
|
||||||
|
<li>For desktop browsers, IWER (Immersive Web Emulator Runtime) will automatically load to emulate a Meta Quest 3 headset</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<a id="basic-usage" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Basic Usage<a href="#basic-usage" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Configure Connection</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Enter your CloudXR server IP address</li>
|
||||||
|
<li>Set the port (default: 49100)</li>
|
||||||
|
<li>Select AR or VR immersive mode</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Adjust Settings</strong> (Optional)</p>
|
||||||
|
<ul>
|
||||||
|
<li>Configure per-eye resolution (perEyeWidth and perEyeHeight, must be multiples of 16)</li>
|
||||||
|
<li>Set target frame rate and bitrate</li>
|
||||||
|
<li>Adjust XR reference space</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Start Streaming</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Click "CONNECT" to initiate the XR session</li>
|
||||||
|
<li>Grant XR permissions when prompted</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<blockquote>
|
||||||
|
<p>NOTE: In order to connect to an actual server and start streaming, you need:</p>
|
||||||
|
<ul>
|
||||||
|
<li>A CloudXR server running and accessible</li>
|
||||||
|
<li>A WebXR-compatible device (VR/AR headset) or desktop browser (IWER loads automatically for emulation)</li>
|
||||||
|
</ul>
|
||||||
|
</blockquote>
|
||||||
|
<a id="technical-architecture" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Technical Architecture<a href="#technical-architecture" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="core-components" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Core Components<a href="#core-components" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><a id="apptsx" class="tsd-anchor"></a><h4 class="tsd-anchor-link"><code>App.tsx</code><a href="#apptsx" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Main React application component managing:</p>
|
||||||
|
<ul>
|
||||||
|
<li>XR store configuration and session state</li>
|
||||||
|
<li>CloudXR component integration</li>
|
||||||
|
<li>2D UI management and event handling</li>
|
||||||
|
<li>Error handling and capability checking</li>
|
||||||
|
<li>React Three Fiber Canvas setup</li>
|
||||||
|
</ul>
|
||||||
|
<a id="cloudxrcomponenttsx" class="tsd-anchor"></a><h4 class="tsd-anchor-link"><code>CloudXRComponent.tsx</code><a href="#cloudxrcomponenttsx" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Handles the core CloudXR streaming functionality:</p>
|
||||||
|
<ul>
|
||||||
|
<li>CloudXR session lifecycle management</li>
|
||||||
|
<li>WebXR session event handling</li>
|
||||||
|
<li>WebGL state management and render target preservation</li>
|
||||||
|
<li>Frame-by-frame rendering loop with pose tracking</li>
|
||||||
|
<li>Integration with Three.js WebXRManager</li>
|
||||||
|
</ul>
|
||||||
|
<a id="cloudxr2duitsx" class="tsd-anchor"></a><h4 class="tsd-anchor-link"><code>CloudXR2DUI.tsx</code><a href="#cloudxr2duitsx" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Manages the 2D HTML interface:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Form field management and localStorage persistence</li>
|
||||||
|
<li>Proxy configuration based on protocol</li>
|
||||||
|
<li>Event listener management and cleanup</li>
|
||||||
|
<li>Error handling and user feedback</li>
|
||||||
|
<li>Configuration validation and updates</li>
|
||||||
|
</ul>
|
||||||
|
<a id="cloudxruitsx-3d-ui" class="tsd-anchor"></a><h4 class="tsd-anchor-link"><code>CloudXRUI.tsx</code> (3D UI)<a href="#cloudxruitsx-3d-ui" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Renders the in-VR user interface:</p>
|
||||||
|
<ul>
|
||||||
|
<li>React Three UIKit components for 3D UI</li>
|
||||||
|
<li>Interactive control buttons with hover effects</li>
|
||||||
|
<li>Server information and status display</li>
|
||||||
|
<li>Event handler integration</li>
|
||||||
|
</ul>
|
||||||
|
<a id="development" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Development<a href="#development" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="project-structure" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Project Structure<a href="#project-structure" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="bash"><span class="hl-0">react/</span><br/><span class="hl-0">├──</span><span class="hl-1"> </span><span class="hl-2">src/</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">├──</span><span class="hl-1"> </span><span class="hl-2">App.tsx</span><span class="hl-1"> </span><span class="hl-3"># Main React application</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">├──</span><span class="hl-1"> </span><span class="hl-2">CloudXRComponent.tsx</span><span class="hl-1"> </span><span class="hl-3"># CloudXR streaming component</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">├──</span><span class="hl-1"> </span><span class="hl-2">CloudXR2DUI.tsx</span><span class="hl-1"> </span><span class="hl-3"># 2D UI management class</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">├──</span><span class="hl-1"> </span><span class="hl-2">CloudXRUI.tsx</span><span class="hl-1"> </span><span class="hl-3"># 3D VR UI component</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">├──</span><span class="hl-1"> </span><span class="hl-2">index.tsx</span><span class="hl-1"> </span><span class="hl-3"># React app entry point</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">└──</span><span class="hl-1"> </span><span class="hl-2">index.html</span><span class="hl-1"> </span><span class="hl-3"># HTML template</span><br/><span class="hl-0">├──</span><span class="hl-1"> </span><span class="hl-2">public/</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">├──</span><span class="hl-1"> </span><span class="hl-2">play-circle.svg</span><span class="hl-1"> </span><span class="hl-3"># Play button icon (Heroicons)</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">├──</span><span class="hl-1"> </span><span class="hl-2">stop-circle.svg</span><span class="hl-1"> </span><span class="hl-3"># Stop button icon (Heroicons)</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">├──</span><span class="hl-1"> </span><span class="hl-2">arrow-uturn-left.svg</span><span class="hl-1"> </span><span class="hl-3"># Reset button icon (Heroicons)</span><br/><span class="hl-0">│</span><span class="hl-1"> </span><span class="hl-2">└──</span><span class="hl-1"> </span><span class="hl-2">arrow-left-start-on-rectangle.svg</span><span class="hl-1"> </span><span class="hl-3"># Disconnect button icon (Heroicons)</span><br/><span class="hl-0">├──</span><span class="hl-1"> </span><span class="hl-2">package.json</span><span class="hl-1"> </span><span class="hl-3"># Dependencies and scripts</span><br/><span class="hl-0">├──</span><span class="hl-1"> </span><span class="hl-2">webpack.common.js</span><span class="hl-1"> </span><span class="hl-3"># Webpack configuration</span><br/><span class="hl-0">├──</span><span class="hl-1"> </span><span class="hl-2">webpack.dev.js</span><span class="hl-1"> </span><span class="hl-3"># Development webpack config</span><br/><span class="hl-0">├──</span><span class="hl-1"> </span><span class="hl-2">webpack.prod.js</span><span class="hl-1"> </span><span class="hl-3"># Production webpack config</span><br/><span class="hl-0">└──</span><span class="hl-1"> </span><span class="hl-2">tsconfig.json</span><span class="hl-1"> </span><span class="hl-3"># TypeScript configuration</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<a id="react-three-fiber-integration" class="tsd-anchor"></a><h2 class="tsd-anchor-link">React Three Fiber Integration<a href="#react-three-fiber-integration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="xr-store-configuration" class="tsd-anchor"></a><h3 class="tsd-anchor-link">XR Store Configuration<a href="#xr-store-configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>The application uses React Three XR's store for XR session management:</p>
|
||||||
|
<pre><code class="javascript"><span class="hl-6">const</span><span class="hl-1"> </span><span class="hl-5">store</span><span class="hl-1"> = </span><span class="hl-0">createXRStore</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-4">foveation:</span><span class="hl-1"> </span><span class="hl-7">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">emulate:</span><span class="hl-1"> { </span><span class="hl-4">syntheticEnvironment:</span><span class="hl-1"> </span><span class="hl-6">false</span><span class="hl-1"> },</span><br/><span class="hl-1">});</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<a id="canvas-setup" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Canvas Setup<a href="#canvas-setup" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>React Three Fiber Canvas with WebXR integration:</p>
|
||||||
|
<pre><code class="typescript"><span class="hl-1"><</span><span class="hl-4">Canvas</span><span class="hl-1"> </span><span class="hl-4">events</span><span class="hl-1">={</span><span class="hl-4">noEvents</span><span class="hl-1">} </span><span class="hl-4">gl</span><span class="hl-1">={{ </span><span class="hl-8">preserveDrawingBuffer</span><span class="hl-1">: </span><span class="hl-6">true</span><span class="hl-1"> }}></span><br/><span class="hl-1"> <</span><span class="hl-5">XR</span><span class="hl-1"> </span><span class="hl-4">store</span><span class="hl-1">={</span><span class="hl-4">store</span><span class="hl-1">}></span><br/><span class="hl-1"> <</span><span class="hl-4">CloudXRComponent</span><span class="hl-1"> </span><span class="hl-4">config</span><span class="hl-1">={</span><span class="hl-4">config</span><span class="hl-1">} /></span><br/><span class="hl-1"> <</span><span class="hl-4">CloudXR3DUI</span><span class="hl-1"> </span><span class="hl-4">onAction1</span><span class="hl-1">={</span><span class="hl-4">handleAction1</span><span class="hl-1">} /></span><br/><span class="hl-1"> </</span><span class="hl-5">XR</span><span class="hl-1">></span><br/><span class="hl-1"></</span><span class="hl-4">Canvas</span><span class="hl-1">></span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<a id="custom-render-loop" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Custom Render Loop<a href="#custom-render-loop" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>The CloudXR component uses <code>useFrame</code> for custom rendering:</p>
|
||||||
|
<pre><code class="typescript"><span class="hl-0">useFrame</span><span class="hl-1">((</span><span class="hl-4">state</span><span class="hl-1">, </span><span class="hl-4">delta</span><span class="hl-1">) </span><span class="hl-6">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-9">if</span><span class="hl-1"> (</span><span class="hl-4">webXRManager</span><span class="hl-1">.</span><span class="hl-4">isPresenting</span><span class="hl-1"> && </span><span class="hl-4">session</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">// CloudXR rendering logic</span><br/><span class="hl-1"> </span><span class="hl-4">cxrSession</span><span class="hl-1">.</span><span class="hl-0">sendTrackingStateToServer</span><span class="hl-1">(</span><span class="hl-4">timestamp</span><span class="hl-1">, </span><span class="hl-4">xrFrame</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">cxrSession</span><span class="hl-1">.</span><span class="hl-0">render</span><span class="hl-1">(</span><span class="hl-4">timestamp</span><span class="hl-1">, </span><span class="hl-4">xrFrame</span><span class="hl-1">, </span><span class="hl-4">layer</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}, -</span><span class="hl-7">1000</span><span class="hl-1">);</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<a id="3d-user-interface" class="tsd-anchor"></a><h2 class="tsd-anchor-link">3D User Interface<a href="#3d-user-interface" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="react-three-uikit-components" class="tsd-anchor"></a><h3 class="tsd-anchor-link">React Three UIKit Components<a href="#react-three-uikit-components" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>The 3D UI uses React Three UIKit for modern VR/AR interfaces:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Container</strong>: Layout and positioning components</li>
|
||||||
|
<li><strong>Text</strong>: 3D text rendering with custom fonts</li>
|
||||||
|
<li><strong>Button</strong>: Interactive buttons with hover effects</li>
|
||||||
|
<li><strong>Image</strong>: Texture-based image display</li>
|
||||||
|
<li><strong>Root</strong>: Main UI container with pixel-perfect rendering</li>
|
||||||
|
</ul>
|
||||||
|
<a id="ui-positioning" class="tsd-anchor"></a><h3 class="tsd-anchor-link">UI Positioning<a href="#ui-positioning" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>3D UI elements are positioned in world space:</p>
|
||||||
|
<pre><code class="typescript"><span class="hl-1"><</span><span class="hl-4">group</span><span class="hl-1"> </span><span class="hl-4">position</span><span class="hl-1">={</span><span class="hl-4">[</span><span class="hl-7">1.8</span><span class="hl-4">, </span><span class="hl-1">-</span><span class="hl-7">0.5</span><span class="hl-4">, </span><span class="hl-1">-</span><span class="hl-7">1.3</span><span class="hl-4">]} rotation={[</span><span class="hl-7">0</span><span class="hl-4">, </span><span class="hl-1">-</span><span class="hl-7">0.3</span><span class="hl-4">, </span><span class="hl-7">0</span><span class="hl-4">]}></span><br/><span class="hl-4"> <Root pixelSize={0.001} width={1920} height={1440}></span><br/><span class="hl-4"> {</span><span class="hl-3">/* UI components */</span><span class="hl-4">}</span><br/><span class="hl-4"> </Root></span><br/><span class="hl-4"></group></span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<a id="webgl-state-tracking" class="tsd-anchor"></a><h3 class="tsd-anchor-link">WebGL State Tracking<a href="#webgl-state-tracking" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>This example uses WebGL state tracking to prevent rendering conflicts between React Three Fiber and CloudXR. Both libraries render to the same WebGL context, but CloudXR's rendering operations modify WebGL state (framebuffers, textures, buffers, VAOs, shaders, blend modes, etc.) which can interfere with React Three Fiber's expectations. The example wraps the WebGL context with <code>bindGL()</code> from <code>@helpers/WebGLStateBinding</code>, then uses CloudXR's <code>onWebGLStateChangeBegin</code> and <code>onWebGLStateChangeEnd</code> callbacks to automatically save and restore state around CloudXR's rendering. This ensures React Three Fiber always finds the WebGL context in the expected state after each CloudXR render operation.</p>
|
||||||
|
<p>See <code>examples/helpers/WebGLStateBinding.ts</code>, <code>WebGLState.ts</code>, and <code>WebGLStateApply.ts</code> for implementation details. Comprehensive tests are available in <code>tests/unit/WebGLState.test.ts</code> and <code>tests/playwright/WebGLTests/src/WebGLStateBindingTests.ts</code>.</p>
|
||||||
|
<a id="license" class="tsd-anchor"></a><h2 class="tsd-anchor-link">License<a href="#license" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>See the <a href="../media/LICENSE-2">LICENSE</a> file for details.</p>
|
||||||
|
<a id="third-party-assets" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Third-Party Assets<a href="#third-party-assets" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Icons used in the immersive UI are from <a href="https://heroicons.com/">Heroicons</a> by Tailwind Labs, licensed under the MIT License. See <a href="../media/HEROICONS_LICENSE">HEROICONS_LICENSE</a> for details.</p>
|
||||||
|
<a id="next-steps" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Next Steps<a href="#next-steps" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Experience one of the compatible OpenXR applications with CloudXR Runtime</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="Show_Cases.Isaac_Lab_Teleop.html">Isaac Lab Teleoperation</a></li>
|
||||||
|
</ul>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#react-three-fiber-example"><span>React <wbr/>Three <wbr/>Fiber <wbr/>Example</span></a><ul><li><a href="#overview"><span>Overview</span></a></li><li><a href="#quick-start"><span>Quick <wbr/>Start</span></a></li><li><ul><li><a href="#prerequisites"><span>Prerequisites</span></a></li><li><a href="#installation"><span>Installation</span></a></li><li><a href="#basic-usage"><span>Basic <wbr/>Usage</span></a></li></ul></li><li><a href="#technical-architecture"><span>Technical <wbr/>Architecture</span></a></li><li><ul><li><a href="#core-components"><span>Core <wbr/>Components</span></a></li><li><ul><li><a href="#apptsx"><span>App.tsx</span></a></li><li><a href="#cloudxrcomponenttsx"><span>CloudXRComponent.tsx</span></a></li><li><a href="#cloudxr2duitsx"><span>CloudXR2DUI.tsx</span></a></li><li><a href="#cloudxruitsx-3d-ui"><span>CloudXRUI.tsx (3<wbr/>D UI)</span></a></li></ul></li></ul></li><li><a href="#development"><span>Development</span></a></li><li><ul><li><a href="#project-structure"><span>Project <wbr/>Structure</span></a></li></ul></li><li><a href="#react-three-fiber-integration"><span>React <wbr/>Three <wbr/>Fiber <wbr/>Integration</span></a></li><li><ul><li><a href="#xr-store-configuration"><span>XR <wbr/>Store <wbr/>Configuration</span></a></li><li><a href="#canvas-setup"><span>Canvas <wbr/>Setup</span></a></li><li><a href="#custom-render-loop"><span>Custom <wbr/>Render <wbr/>Loop</span></a></li></ul></li><li><a href="#3d-user-interface"><span>3<wbr/>D <wbr/>User <wbr/>Interface</span></a></li><li><ul><li><a href="#react-three-uikit-components"><span>React <wbr/>Three UIKit <wbr/>Components</span></a></li><li><a href="#ui-positioning"><span>UI <wbr/>Positioning</span></a></li><li><a href="#webgl-state-tracking"><span>WebGL <wbr/>State <wbr/>Tracking</span></a></li></ul></li><li><a href="#license"><span>License</span></a></li><li><ul><li><a href="#third-party-assets"><span>Third-<wbr/>Party <wbr/>Assets</span></a></li></ul></li><li><a href="#next-steps"><span>Next <wbr/>Steps</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
118
deps/cloudxr/docs/documents/Getting_Started.Sample_Client_-_WebGL.html
vendored
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Sample Client - WebGL | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Getting_Started.html">Getting Started</a></li><li><a href="Getting_Started.Sample_Client_-_WebGL.html">Sample Client - WebGL</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="cloudxrjs-simple-example" class="tsd-anchor"></a><h1 class="tsd-anchor-link">CloudXR.js Simple Example<a href="#cloudxrjs-simple-example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>A minimal WebGL example demonstrating WebXR streaming from a CloudXR server to a web browser. This example shows how to integrate WebXR with CloudXR to stream immersive VR/AR content.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Note:</strong> This example is for learning purposes, not production use.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="quick-start" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Quick Start<a href="#quick-start" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="prerequisites" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Prerequisites<a href="#prerequisites" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul>
|
||||||
|
<li>Node.js (v20 or higher)</li>
|
||||||
|
</ul>
|
||||||
|
<a id="installation" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Installation<a href="#installation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Navigate to the example folder</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">cd</span><span class="hl-1"> </span><span class="hl-2">simple</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Install Dependencies</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-3"># For this early access release, please run the following to install SDK from the given tarball. This step will not be needed when SDK is publicly accessible.</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">install</span><span class="hl-1"> </span><span class="hl-2">../nvidia-cloudxr-6.0.0-beta.tgz</span><br/><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">install</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Build the Application</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">run</span><span class="hl-1"> </span><span class="hl-2">build</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Start Development Server</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">run</span><span class="hl-1"> </span><span class="hl-2">dev-server</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Open in Browser</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Navigate to <code>http://localhost:8080</code> (or the port shown in terminal)</li>
|
||||||
|
<li>For desktop browsers, IWER (Immersive Web Emulator Runtime) will automatically load to emulate a Meta Quest 3 headset</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<a id="basic-usage" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Basic Usage<a href="#basic-usage" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Configure Connection</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Enter CloudXR server IP address (default: localhost)</li>
|
||||||
|
<li>Set port (default: 49100)</li>
|
||||||
|
<li>Select AR or VR mode</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Adjust Settings (Optional)</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Per-eye resolution (must be multiples of 16)</li>
|
||||||
|
<li>Target frame rate (72, 90, or 120 FPS)</li>
|
||||||
|
<li>Streaming bitrate</li>
|
||||||
|
<li>XR reference space and camera offsets</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Start Streaming</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Click "CONNECT"</li>
|
||||||
|
<li>Grant XR permissions when prompted</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<p><strong>Requirements:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>CloudXR server running and accessible</li>
|
||||||
|
<li>WebXR-compatible device (VR/AR headset) or desktop browser (IWER loads automatically for emulation)</li>
|
||||||
|
</ul>
|
||||||
|
<a id="architecture" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Architecture<a href="#architecture" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="cloudxrclient-class" class="tsd-anchor"></a><h3 class="tsd-anchor-link">CloudXRClient Class<a href="#cloudxrclient-class" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>The main application class (<code>CloudXRClient</code> in <code>main.ts</code>) handles:</p>
|
||||||
|
<p><strong>Initialization:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>UI element management and localStorage persistence</li>
|
||||||
|
<li>Browser capability checks (WebXR, WebGL2, WebRTC)</li>
|
||||||
|
<li>Event listener setup</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Connection Flow:</strong></p>
|
||||||
|
<ol>
|
||||||
|
<li><strong>WebGL Setup</strong> - Creates high-performance WebGL2 context</li>
|
||||||
|
<li><strong>WebXR Session</strong> - Enters immersive VR/AR mode</li>
|
||||||
|
<li><strong>Reference Space</strong> - Configures coordinate system for tracking</li>
|
||||||
|
<li><strong>CloudXR Session</strong> - Establishes streaming connection to server</li>
|
||||||
|
<li><strong>Render Loop</strong> - Sends tracking data, receives video, renders frames</li>
|
||||||
|
</ol>
|
||||||
|
<p><strong>Key Components:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>WebXR Session</strong> - Hardware access (headset, controllers)</li>
|
||||||
|
<li><strong>WebGL Context</strong> - Video rendering</li>
|
||||||
|
<li><strong>CloudXR Session</strong> - Streaming management (WebRTC-based)</li>
|
||||||
|
<li><strong>XRWebGLLayer</strong> - Bridge between WebXR and WebGL</li>
|
||||||
|
</ul>
|
||||||
|
<a id="project-structure" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Project Structure<a href="#project-structure" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><pre><code><span class="hl-4">simple</span><span class="hl-1">/</span><br/><span class="hl-1">├── </span><span class="hl-4">src</span><span class="hl-1">/</span><br/><span class="hl-1">│ └── </span><span class="hl-4">main</span><span class="hl-1">.</span><span class="hl-4">ts</span><span class="hl-1"> # </span><span class="hl-4">Main</span><span class="hl-1"> </span><span class="hl-4">application</span><span class="hl-1"> </span><span class="hl-4">sample</span><br/><span class="hl-1">├── </span><span class="hl-4">index</span><span class="hl-1">.</span><span class="hl-4">html</span><span class="hl-1"> # </span><span class="hl-5">UI</span><span class="hl-1"> </span><span class="hl-4">and</span><span class="hl-1"> </span><span class="hl-4">form</span><span class="hl-1"> </span><span class="hl-4">elements</span><span class="hl-1"> </span><span class="hl-4">sample</span><br/><span class="hl-1">├── </span><span class="hl-4">package</span><span class="hl-1">.</span><span class="hl-4">json</span><span class="hl-1"> # </span><span class="hl-4">Dependencies</span><span class="hl-1"> </span><span class="hl-4">and</span><span class="hl-1"> </span><span class="hl-4">scripts</span><br/><span class="hl-1">├── </span><span class="hl-4">webpack</span><span class="hl-1">.</span><span class="hl-4">common</span><span class="hl-1">.</span><span class="hl-4">js</span><span class="hl-1"> # </span><span class="hl-4">Webpack</span><span class="hl-1"> </span><span class="hl-4">base</span><span class="hl-1"> </span><span class="hl-4">configuration</span><span class="hl-1"> </span><span class="hl-4">sample</span><br/><span class="hl-1">├── </span><span class="hl-4">webpack</span><span class="hl-1">.</span><span class="hl-4">dev</span><span class="hl-1">.</span><span class="hl-4">js</span><span class="hl-1"> # </span><span class="hl-4">Development</span><span class="hl-1"> </span><span class="hl-4">configuration</span><span class="hl-1"> </span><span class="hl-4">sample</span><br/><span class="hl-1">├── </span><span class="hl-4">webpack</span><span class="hl-1">.</span><span class="hl-4">prod</span><span class="hl-1">.</span><span class="hl-4">js</span><span class="hl-1"> # </span><span class="hl-4">Production</span><span class="hl-1"> </span><span class="hl-4">configuration</span><span class="hl-1"> </span><span class="hl-4">sample</span><br/><span class="hl-1">└── </span><span class="hl-4">tsconfig</span><span class="hl-1">.</span><span class="hl-4">json</span><span class="hl-1"> # </span><span class="hl-4">TypeScript</span><span class="hl-1"> </span><span class="hl-4">configuration</span><span class="hl-1"> </span><span class="hl-4">sample</span>
|
||||||
|
</code><button>Copy</button></pre>
|
||||||
|
|
||||||
|
<a id="code-overview" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Code Overview<a href="#code-overview" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The <code>main.ts</code> file contains well-commented code explaining each step:</p>
|
||||||
|
<ol>
|
||||||
|
<li><strong>Browser Checks</strong> - Validates WebXR, WebGL2, and WebRTC support</li>
|
||||||
|
<li><strong>Connection Setup</strong> - Reads form inputs and validates configuration</li>
|
||||||
|
<li><strong>WebGL Initialization</strong> - Creates optimized rendering context</li>
|
||||||
|
<li><strong>WebXR Session</strong> - Enters immersive mode with requested features</li>
|
||||||
|
<li><strong>CloudXR Setup</strong> - Configures streaming session with event handlers</li>
|
||||||
|
<li><strong>Render Loop</strong> - Runs 72-120 times per second:
|
||||||
|
<ul>
|
||||||
|
<li>Sends tracking data to server</li>
|
||||||
|
<li>Receives video frame</li>
|
||||||
|
<li>Renders to display</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<p>Each method includes inline comments explaining the purpose and key concepts.</p>
|
||||||
|
<a id="license" class="tsd-anchor"></a><h2 class="tsd-anchor-link">License<a href="#license" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>See the <a href="../media/LICENSE-1">LICENSE</a> file for details.</p>
|
||||||
|
<a id="next-steps" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Next Steps<a href="#next-steps" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Experience one of the compatible OpenXR applications with CloudXR Runtime</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="Show_Cases.Isaac_Lab_Teleop.html">Isaac Lab Teleoperation</a></li>
|
||||||
|
</ul>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#cloudxrjs-simple-example"><span>CloudXR.js <wbr/>Simple <wbr/>Example</span></a><ul><li><a href="#quick-start"><span>Quick <wbr/>Start</span></a></li><li><ul><li><a href="#prerequisites"><span>Prerequisites</span></a></li><li><a href="#installation"><span>Installation</span></a></li><li><a href="#basic-usage"><span>Basic <wbr/>Usage</span></a></li></ul></li><li><a href="#architecture"><span>Architecture</span></a></li><li><ul><li><a href="#cloudxrclient-class"><span>CloudXRClient <wbr/>Class</span></a></li></ul></li><li><a href="#project-structure"><span>Project <wbr/>Structure</span></a></li><li><a href="#code-overview"><span>Code <wbr/>Overview</span></a></li><li><a href="#license"><span>License</span></a></li><li><a href="#next-steps"><span>Next <wbr/>Steps</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
103
deps/cloudxr/docs/documents/Getting_Started.html
vendored
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Getting Started | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Getting_Started.html">Getting Started</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="getting-started" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Getting Started<a href="#getting-started" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><!-- Below we include the sample README.md for the overview sections. -->
|
||||||
|
<p>It is <em>strongly recommended</em> that you work through this guide if you have never run CloudXR.js before.</p>
|
||||||
|
<a id="the-pieces-of-a-cloudxrjs-deployment" class="tsd-anchor"></a><h2 class="tsd-anchor-link">The Pieces of a CloudXR.js Deployment<a href="#the-pieces-of-a-cloudxrjs-deployment" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Even for development, you'll need all the pieces of a CloudXR.js deployment in order to build and test a client. These are:</p>
|
||||||
|
<ul>
|
||||||
|
<li>a CloudXR Server
|
||||||
|
<ul>
|
||||||
|
<li>with a <em>top-end</em> NVIDIA GPU or 2 (e.g. dual RTX 6000 Ada)</li>
|
||||||
|
<li>which will run
|
||||||
|
<ul>
|
||||||
|
<li>the CloudXR Runtime</li>
|
||||||
|
<li>an OpenXR application (the thing you want to render on the server but see on the client)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>a CloudXR.js development workstation
|
||||||
|
<ul>
|
||||||
|
<li>with Node.js and <code>npm</code></li>
|
||||||
|
<li>which will run
|
||||||
|
<ul>
|
||||||
|
<li>the CloudXR.js sample client build</li>
|
||||||
|
<li>a Node-based development web server</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>a CloudXR.js client
|
||||||
|
<ul>
|
||||||
|
<li>which is one of:
|
||||||
|
<ul>
|
||||||
|
<li>a Meta Quest 3 with its built-in Browser app</li>
|
||||||
|
<li>a desktop browser: <a href="https://www.google.com/chrome">Google Chrome</a> or Edge (IWER automatically loads for WebXR emulation)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>which will run...
|
||||||
|
<ul>
|
||||||
|
<li>the CloudXR.js sample client <em>served from the development web server</em>.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>We <em>recommend</em> that for your first experience, all above run on <em>the same computer</em> to eliminate networking related issues.</p>
|
||||||
|
<a id="high-level-workflow" class="tsd-anchor"></a><h2 class="tsd-anchor-link">High Level Workflow<a href="#high-level-workflow" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>You need both a working client and a working server in order to test. Typically we follow a startup flow where server starts before the client:</p>
|
||||||
|
<ol>
|
||||||
|
<li>CloudXR Runtime</li>
|
||||||
|
<li>Server XR application</li>
|
||||||
|
<li>Sample client build + web server</li>
|
||||||
|
<li>Test from the same computer</li>
|
||||||
|
<li>Test from Quest 3 or a different computer</li>
|
||||||
|
</ol>
|
||||||
|
<a id="detailed-requirements" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Detailed Requirements<a href="#detailed-requirements" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="cloudxr-server" class="tsd-anchor"></a><h3 class="tsd-anchor-link">CloudXR Server<a href="#cloudxr-server" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>Minimum:</strong> Single NVIDIA RTX 6000 Ada / L40 GPU or equivalent</p>
|
||||||
|
<p><strong>Recommended:</strong> Two (2x) NVIDIA RTX 6000-class Ada (or later) GPUs:</p>
|
||||||
|
<ul>
|
||||||
|
<li>RTX 6000 Ada</li>
|
||||||
|
<li>L40 / L40S</li>
|
||||||
|
<li>RTX 6000 PRO Blackwell (Workstation, Max-Q Workstation, or Server)</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Additional requirements:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Linux OS (required for Isaac Lab Teleoperation)</li>
|
||||||
|
<li>Docker and NVIDIA Container Toolkit (Linux only)</li>
|
||||||
|
<li>Network: Wired Ethernet connection recommended</li>
|
||||||
|
</ul>
|
||||||
|
<a id="client-device" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Client Device<a href="#client-device" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>Supported headset:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Meta Quest 3 (OS version 79 or later) - only headset validated for this release</li>
|
||||||
|
<li>Uses built-in Browser app (no special software installation needed)</li>
|
||||||
|
<li>Some manual browser configuration required (see <a href="Client_Setup.html">Client Setup Guide</a>)</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>For development/testing:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Desktop <a href="https://www.google.com/chrome">Google Chrome</a> (IWER automatically loads for WebXR emulation)</li>
|
||||||
|
</ul>
|
||||||
|
<a id="network-requirements" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Network Requirements<a href="#network-requirements" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>Critical requirements:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Latency: ≤ 40ms required, ≤ 20ms recommended</li>
|
||||||
|
<li>Bandwidth: 200+ Mbps per streaming connection</li>
|
||||||
|
<li>WiFi: WiFi 6 (WiFi 6e recommended) at 5GHz or 6GHz</li>
|
||||||
|
<li><strong>At most one WiFi hop:</strong> Either server or client must use wired Ethernet</li>
|
||||||
|
</ul>
|
||||||
|
<p>See <a href="Networking_Setup.html">Networking Setup Guide</a> for detailed configuration examples.</p>
|
||||||
|
<a id="step-by-step-guides" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Step-by-Step Guides<a href="#step-by-step-guides" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Following the high-level workflow above, use these guides to set up each component:</p>
|
||||||
|
<a id="1-set-up-cloudxr-runtime-and-server-application" class="tsd-anchor"></a><h3 class="tsd-anchor-link">1. Set Up CloudXR Runtime and Server Application<a href="#1-set-up-cloudxr-runtime-and-server-application" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Choose an OpenXR server application to stream:</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="Show_Cases.Isaac_Lab_Teleop.html">Isaac Lab Teleoperation</a> - Robot learning and teleoperation workflows</li>
|
||||||
|
</ul>
|
||||||
|
<p>The guide includes instructions for setting up the CloudXR Runtime alongside the server application.</p>
|
||||||
|
<a id="2-build-and-serve-a-sample-client" class="tsd-anchor"></a><h3 class="tsd-anchor-link">2. Build and Serve a Sample Client<a href="#2-build-and-serve-a-sample-client" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Build one of our example web clients:</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="Getting_Started.Sample_Client_-_WebGL.html">WebGL Sample</a> - Simple example using vanilla WebGL</li>
|
||||||
|
<li><a href="Getting_Started.Sample_Client_-_React.html">React Sample</a> - Example using React and Three.js</li>
|
||||||
|
</ul>
|
||||||
|
<a id="3-test-and-configure" class="tsd-anchor"></a><h3 class="tsd-anchor-link">3. Test and Configure<a href="#3-test-and-configure" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul>
|
||||||
|
<li><strong>Test from the same computer first</strong> - Follow the desktop testing sections in the sample guides</li>
|
||||||
|
<li><strong>Test from Meta Quest 3</strong> - See <a href="Client_Setup.html">Client Setup Guide</a> for browser configuration</li>
|
||||||
|
<li><strong>Configure networking</strong> (if needed) - See <a href="Networking_Setup.html">Networking Setup Guide</a> for firewall and proxy examples</li>
|
||||||
|
</ul>
|
||||||
|
<a id="advanced-topics" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Advanced Topics<a href="#advanced-topics" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
|
||||||
|
<li><a href="Session_API.html">Session APIs</a> - Programmatic control of CloudXR sessions</li>
|
||||||
|
<li><a href="Telemetry.html">Telemetry</a> - Performance monitoring and debugging</li>
|
||||||
|
</ul>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#getting-started"><span>Getting <wbr/>Started</span></a><ul><li><a href="#the-pieces-of-a-cloudxrjs-deployment"><span>The <wbr/>Pieces of a <wbr/>CloudXR.js <wbr/>Deployment</span></a></li><li><a href="#high-level-workflow"><span>High <wbr/>Level <wbr/>Workflow</span></a></li><li><a href="#detailed-requirements"><span>Detailed <wbr/>Requirements</span></a></li><li><ul><li><a href="#cloudxr-server"><span>CloudXR <wbr/>Server</span></a></li><li><a href="#client-device"><span>Client <wbr/>Device</span></a></li><li><a href="#network-requirements"><span>Network <wbr/>Requirements</span></a></li></ul></li><li><a href="#step-by-step-guides"><span>Step-<wbr/>by-<wbr/>Step <wbr/>Guides</span></a></li><li><ul><li><a href="#1-set-up-cloudxr-runtime-and-server-application"><span>1. <wbr/>Set <wbr/>Up <wbr/>CloudXR <wbr/>Runtime and <wbr/>Server <wbr/>Application</span></a></li><li><a href="#2-build-and-serve-a-sample-client"><span>2. <wbr/>Build and <wbr/>Serve a <wbr/>Sample <wbr/>Client</span></a></li><li><a href="#3-test-and-configure"><span>3. <wbr/>Test and <wbr/>Configure</span></a></li></ul></li><li><a href="#advanced-topics"><span>Advanced <wbr/>Topics</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
418
deps/cloudxr/docs/documents/Networking_Setup.html
vendored
Normal file
32
deps/cloudxr/docs/documents/Overview.html
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Overview | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Overview.html">Overview</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="nvidia-cloudxrjs" class="tsd-anchor"></a><h1 class="tsd-anchor-link">NVIDIA CloudXR.js<a href="#nvidia-cloudxrjs" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>CloudXR.js is a JavaScript Client SDK that enables developers to build enterprise web applications for streaming high-performance VR and AR content from the CloudXR Runtime. Built on NVIDIA's CloudXR technology, this library provides seamless integration between web browsers and remote rendering systems, allowing users to experience immersive 3D applications directly in their browser.</p>
|
||||||
|
<p>The SDK offers a complete solution for <a href="https://immersiveweb.dev/">WebXR</a> streaming, featuring automatic session management, optimized network protocols, and cross-platform compatibility. You can create rich VR/AR experiences that leverage the power of remote servers while maintaining the accessibility and ease of deployment that web applications provide. While we provide examples for WebGL and React Three Fiber implementations, CloudXR.js is a generic solution that can be integrated with any WebXR-compatible frameworks, making it suitable for a wide range of use cases from simple 3D visualizations to complex interactive applications.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Note</strong>: This is an early access beta release of CloudXR.js. Features and APIs may change in future releases.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="🖥️-compatible-server-applications" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🖥️ Compatible Server Applications<a href="#🖥️-compatible-server-applications" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>CloudXR.js works with any OpenXR-compatible application running on a local or remote server with the CloudXR Runtime, including:</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="Show_Cases.Isaac_Lab_Teleop.html"><strong>NVIDIA Isaac Lab</strong></a> - A unified and modular framework for robot learning that aims to simplify common workflows in robotics research.</li>
|
||||||
|
<li><strong>OpenXR applications</strong> - Any OpenXR-compatible application running with the CloudXR Runtime.</li>
|
||||||
|
</ul>
|
||||||
|
<a id="🥽-compatible-client-devices" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🥽 Compatible Client Devices<a href="#🥽-compatible-client-devices" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Our current release is optimized for Meta Quest 3.</p>
|
||||||
|
<a id="🚀-getting-started" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🚀 Getting Started<a href="#🚀-getting-started" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>We provide several web examples to integrate with CloudXR.js. Please follow our <a href="Getting_Started.html">Getting Started Guide</a>.</p>
|
||||||
|
<a id="📚-documentation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">📚 Documentation<a href="#📚-documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="client-configuration" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Client Configuration<a href="#client-configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Learn how to configure your client device and web application hosting. Includes browser setup for Meta Quest 3, HTTP vs HTTPS hosting modes, and connection architecture. See <a href="Client_Setup.html">Client Setup Guide</a> for configuration examples and best practices.</p>
|
||||||
|
<a id="session-api" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Session API<a href="#session-api" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Learn how to manage CloudXR streaming sessions, including connection lifecycle, configuration options, and event handling. See <a href="Session_API.html">Session API Guide</a> for comprehensive API documentation.</p>
|
||||||
|
<a id="networking-setup" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Networking Setup<a href="#networking-setup" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Configure your network for optimal CloudXR streaming performance. We provide example configurations for firewall rules, WiFi optimization, and WebSocket proxy deployments. See <a href="Networking_Setup.html">Networking Setup Guide</a> for sample configurations and recommendations.</p>
|
||||||
|
<a id="troubleshooting" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Troubleshooting<a href="#troubleshooting" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Resolve common issues with CloudXR.js applications, including connection problems, streaming issues, and performance optimization. See <a href="Troubleshooting.html">Troubleshooting Guide</a> for solutions to common problems.</p>
|
||||||
|
<a id="📄-licenses" class="tsd-anchor"></a><h2 class="tsd-anchor-link">📄 Licenses<a href="#📄-licenses" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="open-source-dependencies" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Open Source Dependencies<a href="#open-source-dependencies" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>CloudXR.js incorporates third-party open source libraries. The following dependencies require attention for license compliance:</p>
|
||||||
|
<a id="third-party-libraries-bundled-within-cloudxrjs" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Third-Party Libraries Bundled within CloudXR.js<a href="#third-party-libraries-bundled-within-cloudxrjs" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><ul>
|
||||||
|
<li><strong><a href="https://github.com/webrtchacks/adapter">webrtc-adapter</a></strong> - WebRTC compatibility shim for cross-browser support. Licensed under <a href="https://github.com/webrtcHacks/adapter/blob/main/LICENSE.md">BSD 3-Clause License</a>.</li>
|
||||||
|
<li><strong><a href="https://github.com/open-telemetry/opentelemetry-js">opentelemetry-js</a></strong> - An observability framework for creating and managing application telemetry including traces, metrics, and logs. Licensed under <a href="https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE">Apache License 2.0</a>.</li>
|
||||||
|
</ul>
|
||||||
|
<a id="peer-dependencies" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Peer Dependencies<a href="#peer-dependencies" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><ul>
|
||||||
|
<li><strong><a href="https://github.com/toji/gl-matrix">gl-matrix</a></strong> - Mathematics library for graphics programming. Licensed under <a href="https://github.com/toji/gl-matrix/blob/master/LICENSE.md">MIT License</a>.</li>
|
||||||
|
<li><strong><a href="https://github.com/dcodeIO/long.js">long.js</a></strong> - A Long class for representing a 64-bit two's-complement integer value. Used for accurate handling of uint64 fields in protobuf messages. Licensed under <a href="https://github.com/dcodeIO/long.js/blob/master/LICENSE">Apache License 2.0</a>.</li>
|
||||||
|
</ul>
|
||||||
|
<p>For a complete list of all dependencies and their licenses, refer to the <code>package.json</code> file in the root directory.</p>
|
||||||
|
<a id="cloudxrjs-license" class="tsd-anchor"></a><h3 class="tsd-anchor-link">CloudXR.js License<a href="#cloudxrjs-license" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>This project is licensed under the <a href="../media/LICENSE">NVIDIA CloudXR License</a>.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Important</strong>: This is an evaluation license for internal test and evaluation purposes only. For commercial use, please contact NVIDIA for appropriate licensing terms.</p>
|
||||||
|
<p>Please review the license terms before using this SDK in your projects.</p>
|
||||||
|
</blockquote>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#nvidia-cloudxrjs"><span>NVIDIA <wbr/>CloudXR.js</span></a><ul><li><a href="#🖥️-compatible-server-applications"><span>🖥️ <wbr/>Compatible <wbr/>Server <wbr/>Applications</span></a></li><li><a href="#🥽-compatible-client-devices"><span>🥽 <wbr/>Compatible <wbr/>Client <wbr/>Devices</span></a></li><li><a href="#🚀-getting-started"><span>🚀 <wbr/>Getting <wbr/>Started</span></a></li><li><a href="#📚-documentation"><span>📚 <wbr/>Documentation</span></a></li><li><ul><li><a href="#client-configuration"><span>Client <wbr/>Configuration</span></a></li><li><a href="#session-api"><span>Session API</span></a></li><li><a href="#networking-setup"><span>Networking <wbr/>Setup</span></a></li><li><a href="#troubleshooting"><span>Troubleshooting</span></a></li></ul></li><li><a href="#📄-licenses"><span>📄 <wbr/>Licenses</span></a></li><li><ul><li><a href="#open-source-dependencies"><span>Open <wbr/>Source <wbr/>Dependencies</span></a></li><li><ul><li><a href="#third-party-libraries-bundled-within-cloudxrjs"><span>Third-<wbr/>Party <wbr/>Libraries <wbr/>Bundled within <wbr/>CloudXR.js</span></a></li><li><a href="#peer-dependencies"><span>Peer <wbr/>Dependencies</span></a></li></ul></li><li><a href="#cloudxrjs-license"><span>CloudXR.js <wbr/>License</span></a></li></ul></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
92
deps/cloudxr/docs/documents/Session_API.html
vendored
Normal file
20
deps/cloudxr/docs/documents/Show_Cases.Isaac_Lab_Teleop.Isaac_Lab_Teleop_Troubleshooting.html
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Isaac Lab Teleop Troubleshooting | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Show_Cases.html">Show Cases</a></li><li><a href="Show_Cases.Isaac_Lab_Teleop.html">Isaac Lab Teleop</a></li><li><a href="Show_Cases.Isaac_Lab_Teleop.Isaac_Lab_Teleop_Troubleshooting.html">Isaac Lab Teleop Troubleshooting</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="troubleshooting-isaac-lab-teleop-using-cloudxrjs" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Troubleshooting Isaac Lab Teleop using CloudXR.js<a href="#troubleshooting-isaac-lab-teleop-using-cloudxrjs" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><a id="connected-successfully-but-no-video-content-displays-isaac-viewport-responds-to-tracking" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Connected successfully but no video content displays (Isaac viewport responds to tracking)<a href="#connected-successfully-but-no-video-content-displays-isaac-viewport-responds-to-tracking" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>When running the Docker container, also set the environment variable <code>NV_GPU_INDEX</code> for the runtime container to 0, 1, 2, etc., so the GPU index selected by CUDA matches the one selected by the host or other container.</p>
|
||||||
|
<a id="during-operation-i-accidentally-triggered-the-homemenu-gesture" class="tsd-anchor"></a><h2 class="tsd-anchor-link">During operation, I accidentally triggered the home/menu gesture<a href="#during-operation-i-accidentally-triggered-the-homemenu-gesture" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>This is a known limitation in Meta Quest 3, and we do not have a workaround to disable this gesture. We advise avoiding moving objects with this gesture.</p>
|
||||||
|
<a id="browser-does-not-show-the-buttons" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Browser does not show the buttons<a href="#browser-does-not-show-the-buttons" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>This usually happens if the streaming session does not start correctly. Please quit the WebXR session and refresh the page.</p>
|
||||||
|
<p>If you are using remote debugging view, the Meta Quest 3 browser will not show the DOM overlay of the webpage unless you quit the entire WebXR session.</p>
|
||||||
|
<p>In our upcoming release, we will provide ways to build immersive UIs so you do not need to rely on the webpage. The current workaround is to avoid using remote debugging.</p>
|
||||||
|
<a id="while-teleoperating-the-world-feels-too-highlow" class="tsd-anchor"></a><h3 class="tsd-anchor-link">While teleoperating, the world feels too high/low.<a href="#while-teleoperating-the-world-feels-too-highlow" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>In the CloudXR Client web page in the Meta Quest 3 browser, ensure that the <code>Preferred Reference Space</code> is set to <code>local</code> and adjust the offsets as recommended.</p>
|
||||||
|
<a id="while-teleoperating-i-noticed-significant-lag-sometimes" class="tsd-anchor"></a><h2 class="tsd-anchor-link">While teleoperating, I noticed significant lag sometimes<a href="#while-teleoperating-i-noticed-significant-lag-sometimes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>There might be different factors causing the issue. For example, if you run streaming for a long time, heat throttling can reduce performance and frame rate.
|
||||||
|
In this case, please power cycle your headset and give it time to cool down first. Other issues include networking, which can be improved by having less congested
|
||||||
|
network environments, and low battery. Please ensure your headset is charged to 50% or above.</p>
|
||||||
|
<a id="troubleshooting-the-web-application" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Troubleshooting the web application<a href="#troubleshooting-the-web-application" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>See the <a href="Troubleshooting.html">Generic Troubleshooting Guide</a>.</p>
|
||||||
|
<a id="other-issues" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Other Issues<a href="#other-issues" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>If you have encountered more issues, please reach out to NVIDIA CloudXR team and share the following files</p>
|
||||||
|
<pre><code class="bash"><span class="hl-3"># Checks filenames of the logs</span><br/><span class="hl-0">docker</span><span class="hl-1"> </span><span class="hl-2">exec</span><span class="hl-1"> </span><span class="hl-6">-it</span><span class="hl-1"> </span><span class="hl-2">cloudxr-runtime</span><span class="hl-1"> </span><span class="hl-2">ls</span><span class="hl-1"> </span><span class="hl-2">/tmp</span><br/><br/><span class="hl-3"># Copy the logs and ETLI files</span><br/><span class="hl-0">docker</span><span class="hl-1"> </span><span class="hl-2">cp</span><span class="hl-1"> </span><span class="hl-2">cloudxr-runtime:/tmp/xxx/cxr_server.xxx.log</span><span class="hl-1"> </span><span class="hl-2">.</span><br/><span class="hl-0">docker</span><span class="hl-1"> </span><span class="hl-2">cp</span><span class="hl-1"> </span><span class="hl-2">cloudxr-runtime:/tmp/xxx/xxx.etli</span><span class="hl-1"> </span><span class="hl-2">.</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<p>Isaac Lab console logs can also be helpful.</p>
|
||||||
|
<a id="known-limitations" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Known Limitations<a href="#known-limitations" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><ul>
|
||||||
|
<li>Re-connection may require page refresh</li>
|
||||||
|
<li>Meta Quest 3 home gesture cannot be disabled and may interfere with hand tracking</li>
|
||||||
|
</ul>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#troubleshooting-isaac-lab-teleop-using-cloudxrjs"><span>Troubleshooting <wbr/>Isaac <wbr/>Lab <wbr/>Teleop using <wbr/>CloudXR.js</span></a><ul><li><a href="#connected-successfully-but-no-video-content-displays-isaac-viewport-responds-to-tracking"><span>Connected successfully but no video content displays (<wbr/>Isaac viewport responds to tracking)</span></a></li><li><a href="#during-operation-i-accidentally-triggered-the-homemenu-gesture"><span>During operation, <wbr/>I accidentally triggered the home/menu gesture</span></a></li><li><a href="#browser-does-not-show-the-buttons"><span>Browser does not show the buttons</span></a></li><li><ul><li><a href="#while-teleoperating-the-world-feels-too-highlow"><span>While teleoperating, the world feels too high/low.</span></a></li></ul></li><li><a href="#while-teleoperating-i-noticed-significant-lag-sometimes"><span>While teleoperating, <wbr/>I noticed significant lag sometimes</span></a></li><li><a href="#troubleshooting-the-web-application"><span>Troubleshooting the web application</span></a></li><li><a href="#other-issues"><span>Other <wbr/>Issues</span></a></li></ul><a href="#known-limitations"><span>Known <wbr/>Limitations</span></a></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
116
deps/cloudxr/docs/documents/Show_Cases.Isaac_Lab_Teleop.Setting_Up_Server_for_Teleoperation.html
vendored
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Setting Up Server for Teleoperation | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Show_Cases.html">Show Cases</a></li><li><a href="Show_Cases.Isaac_Lab_Teleop.html">Isaac Lab Teleop</a></li><li><a href="Show_Cases.Isaac_Lab_Teleop.Setting_Up_Server_for_Teleoperation.html">Setting Up Server for Teleoperation</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="running-isaac-lab-with-the-cloudxr-runtime" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Running Isaac Lab with the CloudXR Runtime<a href="#running-isaac-lab-with-the-cloudxr-runtime" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><blockquote>
|
||||||
|
<p><strong>Note</strong>: For this early access release, make sure you have a valid subscription to the NVIDIA CloudXR Early Access program on NVIDIA NGC.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="download-cloudxr-runtime-container-from-nvidia-ngc" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Download CloudXR Runtime Container from NVIDIA NGC<a href="#download-cloudxr-runtime-container-from-nvidia-ngc" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><ol>
|
||||||
|
<li>Follow <a href="https://docs.nvidia.com/ai-enterprise/deployment/spark-rapids-accelerator/latest/appendix-ngc.html">NGC API Key</a> doc to get your
|
||||||
|
NGC API Key (<code>nvapi-xxxx</code>) for your NGC Organization.
|
||||||
|
<ul>
|
||||||
|
<li>The key should have granted permission to access <code>NGC Catalog</code></li>
|
||||||
|
<li>Save the key to a safe place as it will only appear once</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>Setup credential for docker (use username <code>$oauthtoken</code> as literal)<pre><code class="bash"><span class="hl-0">docker</span><span class="hl-1"> </span><span class="hl-2">login</span><span class="hl-1"> </span><span class="hl-2">nvcr.io</span><br/><span class="hl-0">Username:</span><span class="hl-1"> </span><span class="hl-4">$oauthtoken</span><br/><span class="hl-0">Password:</span><span class="hl-1"> <</span><span class="hl-2">your-ngc-api-ke</span><span class="hl-1">y></span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>Try to pull docker image and it should succeed<pre><code class="bash"><span class="hl-0">docker</span><span class="hl-1"> </span><span class="hl-2">pull</span><span class="hl-1"> </span><span class="hl-2">nvcr.io/nvidia/cloudxr-runtime-early-access:6.0.1-webrtc</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<a id="🖥️-option-1-running-isaac-lab-and-cloudxr-runtime-containers-together" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🖥️ Option 1: Running Isaac Lab and CloudXR Runtime Containers Together<a href="#🖥️-option-1-running-isaac-lab-and-cloudxr-runtime-containers-together" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>On your Isaac Lab workstation:</p>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
<p>From the root of the Isaac Lab repository, update <code>./docker/.env.cloudxr-runtime</code> to the following version tag</p>
|
||||||
|
<pre><code class="bash"><span class="hl-3"># NVIDIA CloudXR Runtime base image</span><br/><span class="hl-4">CLOUDXR_RUNTIME_BASE_IMAGE_ARG</span><span class="hl-1">=</span><span class="hl-2">nvcr.io/nvidia/cloudxr-runtime-early-access</span><br/><span class="hl-3"># NVIDIA CloudXR Runtime version to use</span><br/><span class="hl-4">CLOUDXR_RUNTIME_VERSION_ARG</span><span class="hl-1">=</span><span class="hl-2">6.0.1-webrtc</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Also update <code>./docker/docker-compose.cloudxr-runtime.patch.yaml</code> to use host network instead:</p>
|
||||||
|
<pre><code class="yaml"><span class="hl-11">services</span><span class="hl-1">:</span><br/><span class="hl-1"> </span><span class="hl-11">cloudxr-runtime</span><span class="hl-1">:</span><br/><span class="hl-1"> </span><span class="hl-11">image</span><span class="hl-1">: </span><span class="hl-12">${CLOUDXR_RUNTIME_BASE_IMAGE_ARG}:${CLOUDXR_RUNTIME_VERSION_ARG}</span><br/><span class="hl-1"> </span><span class="hl-11">network_mode</span><span class="hl-1">: </span><span class="hl-12">host</span><br/><span class="hl-1"> </span><span class="hl-3">#ports:</span><br/><span class="hl-1"> </span><span class="hl-3"># - "48010:48010/tcp" # signaling</span><br/><span class="hl-1"> </span><span class="hl-3"># - "47998:47998/udp" # media</span><br/><span class="hl-1"> </span><span class="hl-3"># - "47999:47999/udp" # media</span><br/><span class="hl-1"> </span><span class="hl-3"># - "48000:48000/udp" # media</span><br/><span class="hl-1"> </span><span class="hl-3"># - "48005:48005/udp" # media</span><br/><span class="hl-1"> </span><span class="hl-3"># - "48008:48008/udp" # media</span><br/><span class="hl-1"> </span><span class="hl-3"># - "48012:48012/udp" # media</span><br/><span class="hl-1"> </span><span class="hl-11">healthcheck</span><span class="hl-1">:</span><br/><span class="hl-1"> </span><span class="hl-7">...</span><br/><span class="hl-1">...</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Start the Isaac Lab and CloudXR Runtime containers using the Isaac Lab <a href="http://container.py">container.py</a> script</p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">./docker/container.py</span><span class="hl-1"> </span><span class="hl-2">start</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--files</span><span class="hl-1"> </span><span class="hl-2">docker-compose.cloudxr-runtime.patch.yaml</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--env-file</span><span class="hl-1"> </span><span class="hl-2">.env.cloudxr-runtime</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<p>If prompted, elect to activate X11 forwarding, which is necessary to see the Isaac Lab UI.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Note</strong>: The <code>container.py</code> script is a thin wrapper around Docker Compose. The additional <code>--files</code> and <code>--env-file</code> arguments augment the base Docker Compose configuration to additionally run the CloudXR Runtime.
|
||||||
|
For more details on <code>container.py</code> and running Isaac Lab with Docker Compose, see the <a href="https://isaac-sim.github.io/IsaacLab/main/source/deployment/docker.html#deployment-docker">Docker Guide</a>.</p>
|
||||||
|
</blockquote>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Enter the Isaac Lab base container with:</p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">./docker/container.py</span><span class="hl-1"> </span><span class="hl-2">enter</span><span class="hl-1"> </span><span class="hl-2">base</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<p>From within the Isaac Lab base container, you can run Isaac Lab scripts that use XR.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Run an example teleop task with:</p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">./isaaclab.sh</span><span class="hl-1"> </span><span class="hl-6">-p</span><span class="hl-1"> </span><span class="hl-2">scripts/environments/teleoperation/teleop_se3_agent.py</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--task</span><span class="hl-1"> </span><span class="hl-2">Isaac-PickPlace-Locomanipulation-G1-Abs-v0</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--teleop_device</span><span class="hl-1"> </span><span class="hl-2">handtracking</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--enable_pinocchio</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--info</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Note</strong>: You could also choose a different environment like <code>Isaac-PickPlace-GR1T2-Abs-v0</code>.</p>
|
||||||
|
</blockquote>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>You'll want to leave the container running for the next steps. But once you are finished, you can stop the containers with:</p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">./docker/container.py</span><span class="hl-1"> </span><span class="hl-2">stop</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--files</span><span class="hl-1"> </span><span class="hl-2">docker-compose.cloudxr-runtime.patch.yaml</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--env-file</span><span class="hl-1"> </span><span class="hl-2">.env.cloudxr-runtime</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<a id="🖥️-option-2-running-isaac-lab-as-local-process-and-cloudxr-runtime-container" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🖥️ Option 2: Running Isaac Lab as Local Process and CloudXR Runtime Container<a href="#🖥️-option-2-running-isaac-lab-as-local-process-and-cloudxr-runtime-container" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>You can also run Isaac Lab as a local process that connects to the CloudXR Runtime Docker container.
|
||||||
|
This method requires you to manually specify a shared directory for communication between the Isaac Lab instance and the CloudXR Runtime.</p>
|
||||||
|
<p>On your Isaac Lab workstation:</p>
|
||||||
|
<ol>
|
||||||
|
<li>From the root of the Isaac Lab repository, create a local folder for temporary cache files:</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="bash"><span class="hl-0">mkdir</span><span class="hl-1"> </span><span class="hl-6">-p</span><span class="hl-1"> $(</span><span class="hl-0">pwd</span><span class="hl-1">)</span><span class="hl-2">/openxr</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<ol start="2">
|
||||||
|
<li>Initiate the CloudXR Runtime Docker container, ensuring the previously created directory is mounted to the <code>/openxr</code> directory within the container for Isaac Lab visibility:</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="bash"><span class="hl-0">docker</span><span class="hl-1"> </span><span class="hl-2">run</span><span class="hl-1"> </span><span class="hl-6">-dit</span><span class="hl-1"> </span><span class="hl-6">--rm</span><span class="hl-1"> </span><span class="hl-6">--name</span><span class="hl-1"> </span><span class="hl-2">cloudxr-runtime</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--user</span><span class="hl-1"> $(</span><span class="hl-0">id</span><span class="hl-1"> </span><span class="hl-6">-u</span><span class="hl-1">)</span><span class="hl-2">:</span><span class="hl-1">$(</span><span class="hl-0">id</span><span class="hl-1"> </span><span class="hl-6">-g</span><span class="hl-1">) </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--gpus=all</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">-e</span><span class="hl-1"> </span><span class="hl-2">"ACCEPT_EULA=Y"</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--mount</span><span class="hl-1"> </span><span class="hl-2">type=bind,src=</span><span class="hl-1">$(</span><span class="hl-0">pwd</span><span class="hl-1">)</span><span class="hl-2">/openxr,dst=/openxr</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--network</span><span class="hl-1"> </span><span class="hl-2">host</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-2">nvcr.io/nvidia/cloudxr-runtime-early-access:6.0.1-webrtc</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>If you choose a particular GPU instead of all, you need to make sure Isaac Lab also runs on that GPU. See <a href="Show_Cases.Isaac_Lab_Teleop.Isaac_Lab_Teleop_Troubleshooting.html">Isaac Lab Teleop Troubleshooting</a> how to do so.</p>
|
||||||
|
</blockquote>
|
||||||
|
<ol start="3">
|
||||||
|
<li>In a new terminal where you intend to run Isaac Lab, export the following environment variables, which reference the directory created above:</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="bash"><span class="hl-6">export</span><span class="hl-1"> </span><span class="hl-4">XDG_RUNTIME_DIR</span><span class="hl-1">=$(</span><span class="hl-0">pwd</span><span class="hl-1">)/</span><span class="hl-4">openxr</span><span class="hl-1">/</span><span class="hl-4">run</span><br/><span class="hl-6">export</span><span class="hl-1"> </span><span class="hl-4">XR_RUNTIME_JSON</span><span class="hl-1">=$(</span><span class="hl-0">pwd</span><span class="hl-1">)/</span><span class="hl-4">openxr</span><span class="hl-1">/</span><span class="hl-4">share</span><span class="hl-1">/</span><span class="hl-4">openxr</span><span class="hl-1">/</span><span class="hl-4">1</span><span class="hl-1">/</span><span class="hl-4">openxr_cloudxr</span><span class="hl-1">.</span><span class="hl-4">json</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<ol start="4">
|
||||||
|
<li>Run the example teleop task with:</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="bash"><span class="hl-0">./isaaclab.sh</span><span class="hl-1"> </span><span class="hl-6">-p</span><span class="hl-1"> </span><span class="hl-2">scripts/environments/teleoperation/teleop_se3_agent.py</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--task</span><span class="hl-1"> </span><span class="hl-2">Isaac-PickPlace-GR1T2-Abs-v0</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--teleop_device</span><span class="hl-1"> </span><span class="hl-2">handtracking</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--enable_pinocchio</span><span class="hl-1"> </span><span class="hl-10">\</span><br/><span class="hl-1"> </span><span class="hl-6">--info</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<p>With Isaac Lab and the CloudXR Runtime running:</p>
|
||||||
|
<ol>
|
||||||
|
<li>In the Isaac Lab UI: locate the Panel named AR.</li>
|
||||||
|
</ol>
|
||||||
|
<p><img src="../media/ov-ar-panel.png" alt="Isaac Lab UI: AR Panel"></p>
|
||||||
|
<ol start="2">
|
||||||
|
<li>Click <strong>Start AR</strong></li>
|
||||||
|
</ol>
|
||||||
|
<p><img src="../media/startar.png" alt="Start AR"></p>
|
||||||
|
<p>The Viewport should show two eyes being rendered, and you should see the status "AR profile is active".</p>
|
||||||
|
<p><img src="../media/cloudxr_viewport.jpg" alt="Isaac Lab viewport rendering two eyes"></p>
|
||||||
|
<blockquote>
|
||||||
|
<p>Above instructions are <em>modified</em> from <a href="https://isaac-sim.github.io/IsaacLab/main/source/how-to/cloudxr_teleoperation.html#run-isaac-lab-with-the-cloudxr-runtime">these instructions</a>,
|
||||||
|
in particular, to provide the CloudXR Runtime with environment variables needed for streaming to the Meta Quest 3 Browser.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="next" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Next<a href="#next" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="Show_Cases.Isaac_Lab_Teleop.Teleoperating_on_Meta_Quest_3.html">Teleoperating on Meta Quest 3</a></p>
|
||||||
|
<a id="previous" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Previous<a href="#previous" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="Show_Cases.Isaac_Lab_Teleop.html">Running Isaac Lab Teleoperation on Meta Quest 3</a></p>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#running-isaac-lab-with-the-cloudxr-runtime"><span>Running <wbr/>Isaac <wbr/>Lab with the <wbr/>CloudXR <wbr/>Runtime</span></a><ul><li><a href="#download-cloudxr-runtime-container-from-nvidia-ngc"><span>Download <wbr/>CloudXR <wbr/>Runtime <wbr/>Container from NVIDIA NGC</span></a></li><li><a href="#🖥️-option-1-running-isaac-lab-and-cloudxr-runtime-containers-together"><span>🖥️ <wbr/>Option 1: <wbr/>Running <wbr/>Isaac <wbr/>Lab and <wbr/>CloudXR <wbr/>Runtime <wbr/>Containers <wbr/>Together</span></a></li><li><a href="#🖥️-option-2-running-isaac-lab-as-local-process-and-cloudxr-runtime-container"><span>🖥️ <wbr/>Option 2: <wbr/>Running <wbr/>Isaac <wbr/>Lab as <wbr/>Local <wbr/>Process and <wbr/>CloudXR <wbr/>Runtime <wbr/>Container</span></a></li><li><a href="#next"><span>Next</span></a></li><li><a href="#previous"><span>Previous</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
192
deps/cloudxr/docs/documents/Show_Cases.Isaac_Lab_Teleop.Teleoperating_on_Meta_Quest_3.html
vendored
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Teleoperating on Meta Quest 3 | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Show_Cases.html">Show Cases</a></li><li><a href="Show_Cases.Isaac_Lab_Teleop.html">Isaac Lab Teleop</a></li><li><a href="Show_Cases.Isaac_Lab_Teleop.Teleoperating_on_Meta_Quest_3.html">Teleoperating on Meta Quest 3</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="teleoperating-on-meta-quest-3" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Teleoperating on Meta Quest 3<a href="#teleoperating-on-meta-quest-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><a id="prerequisites" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Prerequisites<a href="#prerequisites" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Before building and hosting the web client, ensure you have the following installed:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Node.js</strong> (v20.19.0 or later) and <strong>npm</strong>
|
||||||
|
<ul>
|
||||||
|
<li>Download and installation instructions: <a href="https://nodejs.org/en/download">https://nodejs.org/en/download</a></li>
|
||||||
|
<li>Verify installation: <code>node --version</code> and <code>npm --version</code></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<a id="🔨-build-client-and-host-web-server" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🔨 Build Client and Host Web Server<a href="#🔨-build-client-and-host-web-server" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Once you have Isaac Lab and the CloudXR Runtime running, you can build and host the web server for the CloudXR.js client application.</p>
|
||||||
|
<a id="1-navigate-to-example-directory" class="tsd-anchor"></a><h3 class="tsd-anchor-link">1. Navigate to Example Directory<a href="#1-navigate-to-example-directory" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="bash"><span class="hl-0">cd</span><span class="hl-1"> </span><span class="hl-2">isaac</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<a id="2-install-dependencies" class="tsd-anchor"></a><h3 class="tsd-anchor-link">2. Install Dependencies<a href="#2-install-dependencies" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="bash"><span class="hl-3"># For this early access release, install the SDK from the provided tarball</span><br/><span class="hl-3"># This step will not be required when the SDK is publicly accessible</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">install</span><span class="hl-1"> </span><span class="hl-2">/path/to/nvidia-cloudxr-6.0.0-beta.tgz</span><br/><br/><span class="hl-3"># Install remaining dependencies</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">install</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<a id="3-choose-hosting-mode" class="tsd-anchor"></a><h3 class="tsd-anchor-link">3. Choose Hosting Mode<a href="#3-choose-hosting-mode" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Select the appropriate server mode based on your deployment requirements:</p>
|
||||||
|
<p><strong>For local development (HTTP):</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">run</span><span class="hl-1"> </span><span class="hl-2">dev-server</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Local: <code>http://localhost:8080/</code></li>
|
||||||
|
<li>Network: <code>http://<server-ip>:8080/</code></li>
|
||||||
|
<li>Supports both <code>ws://</code> (direct) and <code>wss://</code> (proxied) runtime connections</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>For local development or production (HTTPS):</strong></p>
|
||||||
|
<pre><code class="bash"><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">run</span><span class="hl-1"> </span><span class="hl-2">dev-server:https</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Local: <code>https://localhost:8080/</code></li>
|
||||||
|
<li>Network: <code>https://<server-ip>:8080/</code></li>
|
||||||
|
<li>Generates self-signed certificates for development, use custom certificates for production</li>
|
||||||
|
<li>See <a href="Client_Setup.html#trust-ssl-certificates-https-mode">Client Setup - Trust SSL Certificates</a> for trusting certs in your device</li>
|
||||||
|
</ul>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Note</strong>: When using HTTPS mode, you must configure a WebSocket proxy. Browsers enforce mixed content policies that block insecure <code>ws://</code> connections from HTTPS pages. See <a href="Networking_Setup.html#websocket-proxy-setup">Networking Setup - WebSocket Proxy</a> for proxy configuration example.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="🖥️-test-from-the-same-computer-optional-but-recommended" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🖥️ Test from the Same Computer (Optional but Recommended)<a href="#🖥️-test-from-the-same-computer-optional-but-recommended" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>For local development, our web app automatically loads IWER (Immersive Web Emulator Runtime) to emulate a Meta Quest 3 headset when no physical XR device is detected.</p>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
<p>Make sure you have:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Chromium browser or <a href="https://www.google.com/chrome">Google Chrome</a></li>
|
||||||
|
<li>IWER will automatically load when you start the application
|
||||||
|
<ul>
|
||||||
|
<li>If you have installed the <a href="https://chromewebstore.google.com/detail/immersive-web-emulator/cgffilbpcibhmcfbgggfhfolhkfbhmik?hl=en">Immersive Web Emulator Chrome extension</a>, please disable it as it will conflict with IWER</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Ensure your CloudXR Runtime and OpenXR application are running</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Navigate to the web application based on your chosen hosting mode:</p>
|
||||||
|
<ul>
|
||||||
|
<li>HTTP mode: <code>http://localhost:8080/</code></li>
|
||||||
|
<li>HTTPS mode: <code>https://localhost:8080/</code>
|
||||||
|
<ul>
|
||||||
|
<li>Accept the cert (see <a href="Client_Setup.html#trust-web-application-certificate">Client Setup - Trust Web Cert</a>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Make sure you see the following messaging, indicating IWER is loaded</p>
|
||||||
|
<p><img src="../media/iwer-message.png" alt=""></p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>(HTTPS mode only) Fill in the <code>Proxy URL</code> if you have any, or click to accept the cert</p>
|
||||||
|
<p><img src="../media/accept-proxy-cert.png" alt=""></p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Click <code>CONNECT</code></p>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<p>If successful, you should see the green <code>CONNECT</code> button change to <code>CONNECT (STREAMING)</code>, and the streamed content from your server application will appear in your browser!</p>
|
||||||
|
<p>You could use the develop UI from IWER to emulate device position and input, for example:</p>
|
||||||
|
<p><img src="../media/iwer-buttons.png" alt=""></p>
|
||||||
|
<a id="🥽-test-from-meta-quest-3" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🥽 Test from Meta Quest 3<a href="#🥽-test-from-meta-quest-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Once you've validated the setup works locally, you can test with an actual Meta Quest 3 headset.</p>
|
||||||
|
<a id="prerequisites-1" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Prerequisites<a href="#prerequisites-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Configure Browser</strong>: Follow the <a href="Client_Setup.html#meta-quest-3-browser-configuration">Client Setup Guide - Meta Quest 3 Browser Configuration</a> to:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Enable WebXR for HTTP origins (if using <code>npm run dev-server</code>)</li>
|
||||||
|
<li>Trust SSL certificates (if using <code>npm run dev-server:https</code>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Configure Network</strong>: Ensure required ports are open:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Web server: Port 8080 (TCP) or your configured port</li>
|
||||||
|
<li>CloudXR Runtime: Port 49100 (TCP) and 47998-48012 (UDP)</li>
|
||||||
|
<li>WebSocket proxy (if using HTTPS): Port 48322 (TCP) or your configured port</li>
|
||||||
|
<li>See <a href="Networking_Setup.html#firewall-configuration">Networking Setup - Firewall Configuration</a> for details</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<a id="connection-configuration" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Connection Configuration<a href="#connection-configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Navigate to the web application</strong> on your Meta Quest 3 Browser:</p>
|
||||||
|
<ul>
|
||||||
|
<li>HTTP mode: <code>http://<server-ip>:8080/</code></li>
|
||||||
|
<li>HTTPS mode: <code>https://<server-ip>:8080/</code></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Configure runtime connection</strong> based on your hosting mode:</p>
|
||||||
|
<p><strong>If using HTTP client</strong> (<code>npm run dev-server</code>):</p>
|
||||||
|
<ul>
|
||||||
|
<li>Direct: <code>ws://<server-ip>:49100</code></li>
|
||||||
|
<li>Proxied: <code>wss://<server-ip>:48322</code></li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>If using HTTPS client</strong> (<code>npm run dev-server:https</code>):</p>
|
||||||
|
<ul>
|
||||||
|
<li>Proxied: <code>wss://<server-ip>:48322</code> (required)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Grant permissions</strong>:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Click <code>CONNECT</code></li>
|
||||||
|
<li>Allow WebXR permissions when prompted</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<a id="application-specific-configuration" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Application-Specific Configuration<a href="#application-specific-configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Before connecting, verify your Isaac Lab server is ready:</p>
|
||||||
|
<ul>
|
||||||
|
<li>CloudXR Runtime is running</li>
|
||||||
|
<li>Isaac Lab is running with the desired task</li>
|
||||||
|
<li>Isaac Lab is using <code>System OpenXR Runtime</code></li>
|
||||||
|
<li>Isaac Lab is in AR mode (<code>Start AR</code> button pressed)</li>
|
||||||
|
</ul>
|
||||||
|
<p>Configure the following application settings in the client web page's <strong>Debug Settings</strong> section:</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Setting</th>
|
||||||
|
<th>Recommended Value</th>
|
||||||
|
<th>Notes</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Preferred Reference Space</td>
|
||||||
|
<td><code>local</code></td>
|
||||||
|
<td>Required for proper tracking</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>X Offset (cm)</td>
|
||||||
|
<td><code>0</code></td>
|
||||||
|
<td>Horizontal positioning</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Y Offset (cm)</td>
|
||||||
|
<td><code>-155</code></td>
|
||||||
|
<td>Vertical positioning</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Z Offset (cm)</td>
|
||||||
|
<td><code>10</code></td>
|
||||||
|
<td>Depth positioning</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Teleoperation Countdown Duration (s)</td>
|
||||||
|
<td>User preference</td>
|
||||||
|
<td>Time before recording starts (optional)</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Note</strong>: Offset values are task-dependent. Adjust based on robot height and workspace as needed.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="how-to-use" class="tsd-anchor"></a><h3 class="tsd-anchor-link">How to use<a href="#how-to-use" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Once streaming starts, you will see a window to your right with teleoperation controls:</p>
|
||||||
|
<p><img src="../media/react-isaac-sample-controls-start.jpg" alt="Isaac Teleoperation Buttons"></p>
|
||||||
|
<ul>
|
||||||
|
<li><code>Countdown</code> - you can use the <code>-</code> (minus) and <code>+</code> (plus) buttons to adjust the countdown timer for starting teleoperation.</li>
|
||||||
|
<li><code>Play</code> - this will start the countdown. Once countdown is finished, the teleoperation session recording starts.</li>
|
||||||
|
<li><code>Reset</code> - this will both <strong>stop and reset</strong> the teleoperation session. After pressing this you can press <code>Play</code> to continue teleoperation (following the countdown timer).</li>
|
||||||
|
<li><code>Disconnect</code> - this will exit the whole streaming and WebXR session</li>
|
||||||
|
</ul>
|
||||||
|
<p>To start teleoperating, click <code>Play</code>. It will start counting down in seconds as configured.</p>
|
||||||
|
<p><img src="../media/react-isaac-sample-controls-countdown.jpg" alt="Isaac Teleoperation Countdown"></p>
|
||||||
|
<p>During the countdown, position your hands at the right place and wait for recording to start.</p>
|
||||||
|
<p>Whenever you complete a task, it will automatically start a new recording and generate the recording file.</p>
|
||||||
|
<p><img src="../media/react-isaac-sample-controls-running.jpg" alt="Isaac Teleoperation Running"></p>
|
||||||
|
<p>To stop teleoperating and reset the position of robot arm, click the <code>Reset</code> button.</p>
|
||||||
|
<a id="next" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Next<a href="#next" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="Show_Cases.Isaac_Lab_Teleop.Isaac_Lab_Teleop_Troubleshooting.html">Troubleshooting Isaac Lab Teleoperation using CloudXR.js</a></p>
|
||||||
|
<a id="previous" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Previous<a href="#previous" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="Show_Cases.Isaac_Lab_Teleop.Setting_Up_Server_for_Teleoperation.html">Running Isaac Lab with the CloudXR Runtime</a></p>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#teleoperating-on-meta-quest-3"><span>Teleoperating on <wbr/>Meta <wbr/>Quest 3</span></a><ul><li><a href="#prerequisites"><span>Prerequisites</span></a></li><li><a href="#🔨-build-client-and-host-web-server"><span>🔨 <wbr/>Build <wbr/>Client and <wbr/>Host <wbr/>Web <wbr/>Server</span></a></li><li><ul><li><a href="#1-navigate-to-example-directory"><span>1. <wbr/>Navigate to <wbr/>Example <wbr/>Directory</span></a></li><li><a href="#2-install-dependencies"><span>2. <wbr/>Install <wbr/>Dependencies</span></a></li><li><a href="#3-choose-hosting-mode"><span>3. <wbr/>Choose <wbr/>Hosting <wbr/>Mode</span></a></li></ul></li><li><a href="#🖥️-test-from-the-same-computer-optional-but-recommended"><span>🖥️ <wbr/>Test from the <wbr/>Same <wbr/>Computer (<wbr/>Optional but <wbr/>Recommended)</span></a></li><li><a href="#🥽-test-from-meta-quest-3"><span>🥽 <wbr/>Test from <wbr/>Meta <wbr/>Quest 3</span></a></li><li><ul><li><a href="#prerequisites-1"><span>Prerequisites</span></a></li><li><a href="#connection-configuration"><span>Connection <wbr/>Configuration</span></a></li><li><a href="#application-specific-configuration"><span>Application-<wbr/>Specific <wbr/>Configuration</span></a></li><li><a href="#how-to-use"><span>How to use</span></a></li></ul></li><li><a href="#next"><span>Next</span></a></li><li><a href="#previous"><span>Previous</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
33
deps/cloudxr/docs/documents/Show_Cases.Isaac_Lab_Teleop.html
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Isaac Lab Teleop | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Show_Cases.html">Show Cases</a></li><li><a href="Show_Cases.Isaac_Lab_Teleop.html">Isaac Lab Teleop</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="running-isaac-lab-teleoperation-on-meta-quest-3" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Running Isaac Lab Teleoperation on Meta Quest 3<a href="#running-isaac-lab-teleoperation-on-meta-quest-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>NVIDIA CloudXR enables seamless, high-fidelity immersive streaming to extended reality (XR) devices over the network. Developers can use CloudXR with NVIDIA Isaac Lab to build teleoperation workflows that require immersive XR rendering for increased spatial acuity and hand tracking for teleoperation of dexterous robots.</p>
|
||||||
|
<p>In these workflows, a compatible XR system captures operator head and hand motion. CloudXR sends this data to Isaac Lab, which renders and submits stereo views of the robot simulation to CloudXR. CloudXR then encodes and streams the rendered views back to the XR system for display in realtime using a low-latency, GPU-accelerated pipeline.</p>
|
||||||
|
<p>This guide provides the Isaac Lab-specific details referenced in the First Run Guide, including installation, CloudXR Runtime configuration, and teleoperation settings.</p>
|
||||||
|
<a id="system-requirements" class="tsd-anchor"></a><h2 class="tsd-anchor-link">System Requirements<a href="#system-requirements" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Prior to using CloudXR with Isaac Lab, please review the following system requirements:</p>
|
||||||
|
<a id="🖥️-isaac-lab-workstation" class="tsd-anchor"></a><h3 class="tsd-anchor-link">🖥️ <strong>Isaac Lab Workstation</strong><a href="#🖥️-isaac-lab-workstation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul>
|
||||||
|
<li>Ubuntu 22.04 or Ubuntu 24.04
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://docs.docker.com/engine/install/ubuntu/#installation-methods">Docker</a> 26.0.0+, <a href="https://docs.docker.com/compose/install/linux/#install-using-the-repository">Docker Compose</a> 2.25.0+, and the <a href="https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html">NVIDIA Container Toolkit</a>. Refer to the <a href="https://isaac-sim.github.io/IsaacLab/main/source/deployment/docker.html#deployment-docker">Isaac Lab Docker Guide</a> for how to install.</li>
|
||||||
|
<li>For details on driver requirements, please see the <a href="https://docs.omniverse.nvidia.com/materials-and-rendering/latest/common/technical-requirements.html">Technical Requirements</a> guide</li>
|
||||||
|
<li>Follow the <a href="https://isaac-sim.github.io/IsaacLab/main/source/setup/installation/index.html#local-installation">Isaac Lab installation guide</a> to install Isaac Sim and Isaac Lab.</li>
|
||||||
|
<li>Required for best performance: 16 cores Intel Core i9, X-series or higher AMD Ryzen 9, Threadripper or higher</li>
|
||||||
|
<li>Required for best performance: 64GB RAM</li>
|
||||||
|
<li>Required for best performance: 2x RTX PRO 6000 GPUs (or equivalent e.g. 2x RTX 5090)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<a id="🥽-meta-quest-3" class="tsd-anchor"></a><h3 class="tsd-anchor-link">🥽 <strong>Meta Quest 3</strong><a href="#🥽-meta-quest-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Meta Quest 3 (OS version 79 or later).</p>
|
||||||
|
<a id="🌐-wifi-6-capable-router" class="tsd-anchor"></a><h3 class="tsd-anchor-link">🌐 <strong>WiFi 6 Capable Router</strong><a href="#🌐-wifi-6-capable-router" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul>
|
||||||
|
<li>A strong wireless connection is essential for a high-quality streaming experience. Refer to the requirements of <a href="Networking_Setup.html">Networking Setup</a> for more details.</li>
|
||||||
|
<li>We recommend using a dedicated router, as concurrent usage will degrade quality</li>
|
||||||
|
<li>The Meta Quest 3 and Isaac Lab workstation must be IP-reachable from one another
|
||||||
|
<ul>
|
||||||
|
<li>Many institutional wireless networks will prevent devices from reaching each other, resulting in the Meta Quest 3 being unable to find the Isaac Lab workstation on the network</li>
|
||||||
|
<li>See <a href="Networking_Setup.html">Networking Setup</a> guide for more details</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<a id="next" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Next<a href="#next" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><ol>
|
||||||
|
<li><a href="Show_Cases.Isaac_Lab_Teleop.Setting_Up_Server_for_Teleoperation.html">Running Isaac Lab with the CloudXR Runtime</a></li>
|
||||||
|
<li><a href="Show_Cases.Isaac_Lab_Teleop.Teleoperating_on_Meta_Quest_3.html">Running Teleop Client on Meta Quest 3</a></li>
|
||||||
|
</ol>
|
||||||
|
<p>If you encounter issues, please see <a href="Show_Cases.Isaac_Lab_Teleop.Isaac_Lab_Teleop_Troubleshooting.html">Troubleshooting</a>.</p>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#running-isaac-lab-teleoperation-on-meta-quest-3"><span>Running <wbr/>Isaac <wbr/>Lab <wbr/>Teleoperation on <wbr/>Meta <wbr/>Quest 3</span></a><ul><li><a href="#system-requirements"><span>System <wbr/>Requirements</span></a></li><li><ul><li><a href="#🖥️-isaac-lab-workstation"><span>🖥️ <wbr/>Isaac <wbr/>Lab <wbr/>Workstation</span></a></li><li><a href="#🥽-meta-quest-3"><span>🥽 <wbr/>Meta <wbr/>Quest 3</span></a></li><li><a href="#🌐-wifi-6-capable-router"><span>🌐 <wbr/>Wi<wbr/>Fi 6 <wbr/>Capable <wbr/>Router</span></a></li></ul></li><li><a href="#next"><span>Next</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
4
deps/cloudxr/docs/documents/Show_Cases.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Show Cases | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Show_Cases.html">Show Cases</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="show-cases" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Show Cases<a href="#show-cases" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><ul>
|
||||||
|
<li><a href="Show_Cases.Isaac_Lab_Teleop.html">Running Isaac Lab Teleoperation on Meta Quest 3</a></li>
|
||||||
|
</ul>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#show-cases"><span>Show <wbr/>Cases</span></a></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
40
deps/cloudxr/docs/documents/Telemetry.html
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Telemetry | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Telemetry.html">Telemetry</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="telemetry" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Telemetry<a href="#telemetry" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>Anonymous collection of system performance data to enhance service quality.</p>
|
||||||
|
<a id="overview" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Overview<a href="#overview" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>We collect the following functional events:</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<p><code>CXR_LifetimeEvent</code>: Tracks events when a <code>CloudXRSession</code> is created and destroyed.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><code>CXR_SessionConfiguration</code>: Gathers session initialization metadata such as resolution used to initialize a <code>CloudXRSession</code>.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><code>CXR_SessionState</code>: Monitors changes in the <code>SessionState</code>.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><code>CXR_ExceptionInfo</code>: Records exceptions, occurring within a <code>CloudXRSession</code>.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><code>CXR_ClientRequest</code>: Records the action when the client sends a message to server.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><code>CXR_ServerResponse</code>: Records the action when the server responds to client requests.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><code>CXR_ClientMetricEvent</code>: Records performance metrics for <code>CloudXRSession</code>, such as session duration, frame counts, and message statistics.</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Data is collected exclusively for service purposes, without capturing any persistent IDs or personal information, and it is not associated with any specific user or device. To opt out of telemetry data collection, disable telemetry in the session configuration.</p>
|
||||||
|
<a id="configuration" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Configuration<a href="#configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Telemetry can be configured when creating a CloudXR session:</p>
|
||||||
|
<pre><code class="typescript"><span class="hl-9">import</span><span class="hl-1"> </span><span class="hl-6">*</span><span class="hl-1"> </span><span class="hl-9">as</span><span class="hl-1"> </span><span class="hl-4">CloudXR</span><span class="hl-1"> </span><span class="hl-9">from</span><span class="hl-1"> </span><span class="hl-2">'@nvidia/cloudxr'</span><span class="hl-1">;</span><br/><br/><span class="hl-6">const</span><span class="hl-1"> </span><span class="hl-5">session</span><span class="hl-1"> = </span><span class="hl-4">CloudXR</span><span class="hl-1">.</span><span class="hl-0">createSession</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-3">// ... other session options</span><br/><span class="hl-1"> </span><span class="hl-4">telemetry:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">enabled:</span><span class="hl-1"> </span><span class="hl-6">true</span><span class="hl-1">, </span><span class="hl-3">// Enable telemetry collection (default: true)</span><br/><span class="hl-1"> </span><span class="hl-4">appInfo:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">product:</span><span class="hl-1"> </span><span class="hl-2">'My CloudXR App'</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">version:</span><span class="hl-1"> </span><span class="hl-2">'1.0.0'</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
<a id="telemetry-options" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Telemetry Options<a href="#telemetry-options" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul>
|
||||||
|
<li><code>enabled</code>: Boolean flag to enable/disable telemetry collection. Defaults to <code>true</code>.</li>
|
||||||
|
<li><code>appInfo</code>: Optional application information object containing:
|
||||||
|
<ul>
|
||||||
|
<li><code>product</code>: Product name (e.g., "MyApp")</li>
|
||||||
|
<li><code>version</code>: Application version (e.g., "1.0.0")</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#telemetry"><span>Telemetry</span></a><ul><li><a href="#overview"><span>Overview</span></a></li><li><a href="#configuration"><span>Configuration</span></a></li><li><ul><li><a href="#telemetry-options"><span>Telemetry <wbr/>Options</span></a></li></ul></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
56
deps/cloudxr/docs/documents/Troubleshooting.html
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Troubleshooting | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="Troubleshooting.html">Troubleshooting</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="troubleshooting" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Troubleshooting<a href="#troubleshooting" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>This guide helps you diagnose and resolve common issues when using CloudXR.js for WebXR streaming.</p>
|
||||||
|
<a id="common-issues" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Common Issues<a href="#common-issues" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="i-got-a-blank-page-when-opening-the-url-or-it-streams-2d-only-in-browser" class="tsd-anchor"></a><h3 class="tsd-anchor-link">I got a blank page when opening the URL or it streams 2D only in browser<a href="#i-got-a-blank-page-when-opening-the-url-or-it-streams-2d-only-in-browser" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>For HTTP Mode:</strong></p>
|
||||||
|
<p>If you're using HTTP mode (<code>http://</code>), you need to configure the Chromium browser to allow WebXR usage from insecure origins:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Open Meta Quest 3 Browser or desktop Google Chrome</li>
|
||||||
|
<li>Navigate to <code>chrome://flags</code></li>
|
||||||
|
<li>Search for "insecure", and locate "Treat insecure origins as secure"</li>
|
||||||
|
<li><em>Enable the flag</em></li>
|
||||||
|
<li>Then in the text box below the flag, add your development web server
|
||||||
|
<ul>
|
||||||
|
<li>You <em>must</em> include the protocol (<code>http</code>) and the port (<code>:8080</code>)</li>
|
||||||
|
<li><code>http://your-ip-address:8080</code></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><em>De-focus the text box</em> by "clicking somewhere else"</li>
|
||||||
|
<li>A "Relaunch" message should appear at the bottom of the window</li>
|
||||||
|
<li>Click "Relaunch"</li>
|
||||||
|
<li>Verify the flags are set as intended in <code>chrome://flags</code></li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>For HTTPS Mode:</strong></p>
|
||||||
|
<p>If you're using HTTPS mode (<code>https://</code>), you need to trust the SSL certificates:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Navigate to your web server URL in the browser: <code>https://your-ip-address:8080</code></li>
|
||||||
|
<li>Accept the certificate warning by clicking "Advanced" → "Proceed to [your-ip-address] (unsafe)"</li>
|
||||||
|
<li>If using a WebSocket proxy, also trust its certificate by visiting: <code>https://your-proxy-ip:48322</code></li>
|
||||||
|
</ul>
|
||||||
|
<p>See the <a href="Client_Setup.html#trust-ssl-certificates-https-mode">Client Setup Guide</a> for detailed SSL certificate configuration.</p>
|
||||||
|
<a id="handtracking-is-not-responsive-when-i-start-the-webxr-session" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Handtracking is not responsive when I start the WebXR session<a href="#handtracking-is-not-responsive-when-i-start-the-webxr-session" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>You could pause the session by clicking the MENU button and resume the WebXR session.
|
||||||
|
If the behavior persists, we advise to restart your Meta headset to clear up caches.</p>
|
||||||
|
<a id="connection-issues" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Connection Issues<a href="#connection-issues" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>You might see an error with an error code (shown in hexadecimal format like <code>0xC0F22202</code>). In most cases, they are because of the following reasons:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Verify the server address and port are correct</li>
|
||||||
|
<li>Check network connectivity between client and server</li>
|
||||||
|
<li>Ensure the CloudXR runtime is running on the server</li>
|
||||||
|
<li>Verify firewall rules allow traffic</li>
|
||||||
|
<li>Ensure UDP ports are not blocked</li>
|
||||||
|
<li>Check for high network latency or packet loss</li>
|
||||||
|
<li>Verify stable network connection (check for Wi-Fi disconnections)</li>
|
||||||
|
<li>Test network quality (ping, bandwidth, packet loss)</li>
|
||||||
|
<li>Ensure WebRTC is not blocked by browser settings or extensions</li>
|
||||||
|
<li>Review network topology (double NAT, symmetric NAT issues)</li>
|
||||||
|
<li>Setup TURN relay server if direct connection fails</li>
|
||||||
|
<li>Check server configuration and logs</li>
|
||||||
|
<li>Restart the CloudXR runtime if necessary</li>
|
||||||
|
</ul>
|
||||||
|
<p>For most issues, you can consult the <a href="Networking_Setup.html">Networking Setup Guide</a> for detailed configuration instructions and the issue should resolve.</p>
|
||||||
|
<a id="❓-getting-help" class="tsd-anchor"></a><h2 class="tsd-anchor-link">❓ Getting Help<a href="#❓-getting-help" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>If you're still experiencing issues:</p>
|
||||||
|
<ol>
|
||||||
|
<li><strong>Check the console</strong> for error messages</li>
|
||||||
|
<li>Test with <strong>different browsers</strong></li>
|
||||||
|
<li>Verify <strong>server configuration and logs</strong></li>
|
||||||
|
<li>Check <strong>network conditions</strong> and requirements</li>
|
||||||
|
<li>Review <strong>the <a href="Session_API.html">Session API</a></strong> documentation</li>
|
||||||
|
</ol>
|
||||||
|
<p>For additional support, please reach out to NVIDIA CloudXR team.</p>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#troubleshooting"><span>Troubleshooting</span></a><ul><li><a href="#common-issues"><span>Common <wbr/>Issues</span></a></li><li><ul><li><a href="#i-got-a-blank-page-when-opening-the-url-or-it-streams-2d-only-in-browser"><span>I got a blank page when opening the URL or it streams 2<wbr/>D only in browser</span></a></li><li><a href="#handtracking-is-not-responsive-when-i-start-the-webxr-session"><span>Handtracking is not responsive when <wbr/>I start the <wbr/>WebXR session</span></a></li><li><a href="#connection-issues"><span>Connection <wbr/>Issues</span></a></li></ul></li><li><a href="#❓-getting-help"><span>❓ <wbr/>Getting <wbr/>Help</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
33
deps/cloudxr/docs/enums/CloudXR.SessionState.html
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>SessionState | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="../modules/CloudXR.html">CloudXR</a></li><li><a href="CloudXR.SessionState.html">SessionState</a></li></ul><h1>Enumeration SessionState</h1></div><section class="tsd-panel tsd-comment"><div class="tsd-comment tsd-typography"><p>Defines the states of a CloudXR streaming session.</p>
|
||||||
|
<p>The session follows a well-defined lifecycle with distinct states and transitions:</p>
|
||||||
|
<pre><code><span class="hl-4">Initialized</span><span class="hl-1"> → </span><span class="hl-4">Connecting</span><span class="hl-1"> → </span><span class="hl-4">Connected</span><span class="hl-1"> → </span><span class="hl-4">Disconnecting</span><span class="hl-1"> → </span><span class="hl-4">Disconnected</span>
|
||||||
|
</code><button>Copy</button></pre>
|
||||||
|
|
||||||
|
</div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example" class="tsd-anchor"></a>Example<a href="#example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-3">// Check session state</span><br/><span class="hl-9">if</span><span class="hl-1"> (</span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-4">state</span><span class="hl-1"> === </span><span class="hl-4">SessionState</span><span class="hl-1">.</span><span class="hl-4">Connected</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'Session is ready for rendering'</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></section><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Enumeration Members</h3><div class="tsd-index-list"><a href="CloudXR.SessionState.html#initialized" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Initialized</span></a>
|
||||||
|
<a href="CloudXR.SessionState.html#connecting" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Connecting</span></a>
|
||||||
|
<a href="CloudXR.SessionState.html#connected" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Connected</span></a>
|
||||||
|
<a href="CloudXR.SessionState.html#disconnecting" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Disconnecting</span></a>
|
||||||
|
<a href="CloudXR.SessionState.html#disconnected" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Disconnected</span></a>
|
||||||
|
<a href="CloudXR.SessionState.html#error" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Error</span></a>
|
||||||
|
</div></section></div></details></section></section><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Enumeration Members"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Enumeration Members</h2></summary><section><section class="tsd-panel tsd-member"><a id="initialized" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>Initialized</span><a href="#initialized" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-enum-member">Initialized</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"Initialized"</span></div><div class="tsd-comment tsd-typography"><p>Initial state when the session is created but connect() has not been called.</p>
|
||||||
|
<p>The session is ready to be configured and connected.
|
||||||
|
No network activity or streaming occurs.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></section><section class="tsd-panel tsd-member"><a id="connecting" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>Connecting</span><a href="#connecting" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-enum-member">Connecting</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"Connecting"</span></div><div class="tsd-comment tsd-typography"><p>The session is attempting to establish a connection and start streaming.</p>
|
||||||
|
<p>The session is actively trying to connect to the CloudXR Runtime.
|
||||||
|
This state is temporary and transitions to either Connected or Error.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></section><section class="tsd-panel tsd-member"><a id="connected" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>Connected</span><a href="#connected" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-enum-member">Connected</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"Connected"</span></div><div class="tsd-comment tsd-typography"><p>The session is fully active and ready to render.</p>
|
||||||
|
<p>Connection is established, video streaming is active, and WebGL resources are ready.
|
||||||
|
This is the normal operational state for rendering CloudXR content.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></section><section class="tsd-panel tsd-member"><a id="disconnecting" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>Disconnecting</span><a href="#disconnecting" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-enum-member">Disconnecting</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"Disconnecting"</span></div><div class="tsd-comment tsd-typography"><p>The session is in the process of disconnecting from the CloudXR Runtime.</p>
|
||||||
|
<p>The session is actively closing the connection and cleaning up resources.
|
||||||
|
This state is temporary and transitions to Disconnected.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></section><section class="tsd-panel tsd-member"><a id="disconnected" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>Disconnected</span><a href="#disconnected" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-enum-member">Disconnected</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"Disconnected"</span></div><div class="tsd-comment tsd-typography"><p>The session has been disconnected and is ready to be reconnected.</p>
|
||||||
|
<p>The session has been cleanly disconnected and can be reconnected
|
||||||
|
by calling connect() again.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></section><section class="tsd-panel tsd-member"><a id="error" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>Error</span><a href="#error" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-enum-member">Error</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"Error"</span></div><div class="tsd-comment tsd-typography"><p>The session encountered a critical error and cannot continue.</p>
|
||||||
|
<p>The session has encountered an unrecoverable error. Destroy and recreate
|
||||||
|
the session to recover. Check error details in the onStreamStopped delegate callback.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Enumeration Members"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Enumeration Members</summary><div><a href="#initialized" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Initialized</span></a><a href="#connecting" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Connecting</span></a><a href="#connected" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Connected</span></a><a href="#disconnecting" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Disconnecting</span></a><a href="#disconnected" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Disconnected</span></a><a href="#error" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Enumeration Member"><use href="../assets/icons.svg#icon-16"></use></svg><span>Error</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
21
deps/cloudxr/docs/functions/CloudXR.createSession.html
vendored
Normal file
32
deps/cloudxr/docs/index.html
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base="."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script defer src="assets/main.js"></script><script async src="assets/icons.js" id="tsd-icons-script"></script><script async src="assets/search.js" id="tsd-search-script"></script><script async src="assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><h1>CloudXR.js SDK Documentation - v6.0.0-beta</h1></div><div class="tsd-panel tsd-typography"><a id="nvidia-cloudxrjs" class="tsd-anchor"></a><h1 class="tsd-anchor-link">NVIDIA CloudXR.js<a href="#nvidia-cloudxrjs" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p>CloudXR.js is a JavaScript Client SDK that enables developers to build enterprise web applications for streaming high-performance VR and AR content from the CloudXR Runtime. Built on NVIDIA's CloudXR technology, this library provides seamless integration between web browsers and remote rendering systems, allowing users to experience immersive 3D applications directly in their browser.</p>
|
||||||
|
<p>The SDK offers a complete solution for <a href="https://immersiveweb.dev/">WebXR</a> streaming, featuring automatic session management, optimized network protocols, and cross-platform compatibility. You can create rich VR/AR experiences that leverage the power of remote servers while maintaining the accessibility and ease of deployment that web applications provide. While we provide examples for WebGL and React Three Fiber implementations, CloudXR.js is a generic solution that can be integrated with any WebXR-compatible frameworks, making it suitable for a wide range of use cases from simple 3D visualizations to complex interactive applications.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Note</strong>: This is an early access beta release of CloudXR.js. Features and APIs may change in future releases.</p>
|
||||||
|
</blockquote>
|
||||||
|
<a id="🖥️-compatible-server-applications" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🖥️ Compatible Server Applications<a href="#🖥️-compatible-server-applications" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>CloudXR.js works with any OpenXR-compatible application running on a local or remote server with the CloudXR Runtime, including:</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="documents/Show_Cases.Isaac_Lab_Teleop.html"><strong>NVIDIA Isaac Lab</strong></a> - A unified and modular framework for robot learning that aims to simplify common workflows in robotics research.</li>
|
||||||
|
<li><strong>OpenXR applications</strong> - Any OpenXR-compatible application running with the CloudXR Runtime.</li>
|
||||||
|
</ul>
|
||||||
|
<a id="🥽-compatible-client-devices" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🥽 Compatible Client Devices<a href="#🥽-compatible-client-devices" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Our current release is optimized for Meta Quest 3.</p>
|
||||||
|
<a id="🚀-getting-started" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🚀 Getting Started<a href="#🚀-getting-started" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>We provide several web examples to integrate with CloudXR.js. Please follow our <a href="documents/Getting_Started.html">Getting Started Guide</a>.</p>
|
||||||
|
<a id="📚-documentation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">📚 Documentation<a href="#📚-documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="client-configuration" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Client Configuration<a href="#client-configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Learn how to configure your client device and web application hosting. Includes browser setup for Meta Quest 3, HTTP vs HTTPS hosting modes, and connection architecture. See <a href="documents/Client_Setup.html">Client Setup Guide</a> for configuration examples and best practices.</p>
|
||||||
|
<a id="session-api-1" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Session API<a href="#session-api-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Learn how to manage CloudXR streaming sessions, including connection lifecycle, configuration options, and event handling. See <a href="documents/Session_API.html">Session API Guide</a> for comprehensive API documentation.</p>
|
||||||
|
<a id="networking-setup-1" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Networking Setup<a href="#networking-setup-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Configure your network for optimal CloudXR streaming performance. We provide example configurations for firewall rules, WiFi optimization, and WebSocket proxy deployments. See <a href="documents/Networking_Setup.html">Networking Setup Guide</a> for sample configurations and recommendations.</p>
|
||||||
|
<a id="troubleshooting-1" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Troubleshooting<a href="#troubleshooting-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Resolve common issues with CloudXR.js applications, including connection problems, streaming issues, and performance optimization. See <a href="documents/Troubleshooting.html">Troubleshooting Guide</a> for solutions to common problems.</p>
|
||||||
|
<a id="📄-licenses" class="tsd-anchor"></a><h2 class="tsd-anchor-link">📄 Licenses<a href="#📄-licenses" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="open-source-dependencies" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Open Source Dependencies<a href="#open-source-dependencies" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>CloudXR.js incorporates third-party open source libraries. The following dependencies require attention for license compliance:</p>
|
||||||
|
<a id="third-party-libraries-bundled-within-cloudxrjs" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Third-Party Libraries Bundled within CloudXR.js<a href="#third-party-libraries-bundled-within-cloudxrjs" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><ul>
|
||||||
|
<li><strong><a href="https://github.com/webrtchacks/adapter">webrtc-adapter</a></strong> - WebRTC compatibility shim for cross-browser support. Licensed under <a href="https://github.com/webrtcHacks/adapter/blob/main/LICENSE.md">BSD 3-Clause License</a>.</li>
|
||||||
|
<li><strong><a href="https://github.com/open-telemetry/opentelemetry-js">opentelemetry-js</a></strong> - An observability framework for creating and managing application telemetry including traces, metrics, and logs. Licensed under <a href="https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE">Apache License 2.0</a>.</li>
|
||||||
|
</ul>
|
||||||
|
<a id="peer-dependencies" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Peer Dependencies<a href="#peer-dependencies" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><ul>
|
||||||
|
<li><strong><a href="https://github.com/toji/gl-matrix">gl-matrix</a></strong> - Mathematics library for graphics programming. Licensed under <a href="https://github.com/toji/gl-matrix/blob/master/LICENSE.md">MIT License</a>.</li>
|
||||||
|
<li><strong><a href="https://github.com/dcodeIO/long.js">long.js</a></strong> - A Long class for representing a 64-bit two's-complement integer value. Used for accurate handling of uint64 fields in protobuf messages. Licensed under <a href="https://github.com/dcodeIO/long.js/blob/master/LICENSE">Apache License 2.0</a>.</li>
|
||||||
|
</ul>
|
||||||
|
<p>For a complete list of all dependencies and their licenses, refer to the <code>package.json</code> file in the root directory.</p>
|
||||||
|
<a id="cloudxrjs-license" class="tsd-anchor"></a><h3 class="tsd-anchor-link">CloudXR.js License<a href="#cloudxrjs-license" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>This project is licensed under the <a href="media/LICENSE">NVIDIA CloudXR License</a>.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Important</strong>: This is an evaluation license for internal test and evaluation purposes only. For commercial use, please contact NVIDIA for appropriate licensing terms.</p>
|
||||||
|
<p>Please review the license terms before using this SDK in your projects.</p>
|
||||||
|
</blockquote>
|
||||||
|
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#nvidia-cloudxrjs"><span>NVIDIA <wbr/>CloudXR.js</span></a><ul><li><a href="#🖥️-compatible-server-applications"><span>🖥️ <wbr/>Compatible <wbr/>Server <wbr/>Applications</span></a></li><li><a href="#🥽-compatible-client-devices"><span>🥽 <wbr/>Compatible <wbr/>Client <wbr/>Devices</span></a></li><li><a href="#🚀-getting-started"><span>🚀 <wbr/>Getting <wbr/>Started</span></a></li><li><a href="#📚-documentation"><span>📚 <wbr/>Documentation</span></a></li><li><ul><li><a href="#client-configuration"><span>Client <wbr/>Configuration</span></a></li><li><a href="#session-api-1"><span>Session API</span></a></li><li><a href="#networking-setup-1"><span>Networking <wbr/>Setup</span></a></li><li><a href="#troubleshooting-1"><span>Troubleshooting</span></a></li></ul></li><li><a href="#📄-licenses"><span>📄 <wbr/>Licenses</span></a></li><li><ul><li><a href="#open-source-dependencies"><span>Open <wbr/>Source <wbr/>Dependencies</span></a></li><li><ul><li><a href="#third-party-libraries-bundled-within-cloudxrjs"><span>Third-<wbr/>Party <wbr/>Libraries <wbr/>Bundled within <wbr/>CloudXR.js</span></a></li><li><a href="#peer-dependencies"><span>Peer <wbr/>Dependencies</span></a></li></ul></li><li><a href="#cloudxrjs-license"><span>CloudXR.js <wbr/>License</span></a></li></ul></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
70
deps/cloudxr/docs/interfaces/CloudXR.Session.html
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Session | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="../modules/CloudXR.html">CloudXR</a></li><li><a href="CloudXR.Session.html">Session</a></li></ul><h1>Interface Session</h1></div><section class="tsd-panel tsd-comment"><div class="tsd-comment tsd-typography"><p>Defines the interface for CloudXR streaming sessions.</p>
|
||||||
|
<p>Provides the core functionality for managing CloudXR streaming
|
||||||
|
sessions, including connection management, rendering, and communication with
|
||||||
|
the CloudXR Runtime.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example" class="tsd-anchor"></a>Example<a href="#example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-3">// Create a session</span><br/><span class="hl-6">const</span><span class="hl-1"> </span><span class="hl-5">session</span><span class="hl-1"> = </span><span class="hl-0">createSession</span><span class="hl-1">(</span><span class="hl-4">sessionOptions</span><span class="hl-1">, </span><span class="hl-4">delegates</span><span class="hl-1">);</span><br/><br/><span class="hl-3">// Connect to CloudXR Runtime</span><br/><span class="hl-9">if</span><span class="hl-1"> (</span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">connect</span><span class="hl-1">()) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'Connection initiated'</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-3">// In your render loop</span><br/><span class="hl-6">function</span><span class="hl-1"> </span><span class="hl-0">renderFrame</span><span class="hl-1">(</span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">frame</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-9">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">// Send tracking data</span><br/><span class="hl-1"> </span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">sendTrackingStateToServer</span><span class="hl-1">(</span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">frame</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-3">// Render CloudXR content</span><br/><span class="hl-1"> </span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">render</span><span class="hl-1">(</span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">frame</span><span class="hl-1">, </span><span class="hl-4">xrWebGLLayer</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-9">catch</span><span class="hl-1"> (</span><span class="hl-4">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">error</span><span class="hl-1">(</span><span class="hl-2">'Error during frame rendering:'</span><span class="hl-1">, </span><span class="hl-4">error</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></section><div class="tsd-signature"><span class="tsd-signature-keyword">interface</span> <span class="tsd-kind-interface">Session</span> <span class="tsd-signature-symbol">{</span><br/> <a class="tsd-kind-property" href="CloudXR.Session.html#state">state</a><span class="tsd-signature-symbol">:</span> <a href="../enums/CloudXR.SessionState.html" class="tsd-signature-type tsd-kind-enum">SessionState</a><span class="tsd-signature-symbol">;</span><br/> <a class="tsd-kind-call-signature" href="CloudXR.Session.html#connect-1">connect</a><span class="tsd-signature-symbol">()</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">;</span><br/> <a class="tsd-kind-call-signature" href="CloudXR.Session.html#disconnect-1">disconnect</a><span class="tsd-signature-symbol">()</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">;</span><br/> <a class="tsd-kind-call-signature" href="CloudXR.Session.html#sendtrackingstatetoserver-1">sendTrackingStateToServer</a><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">timestamp</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol">,</span> <span class="tsd-kind-parameter">frame</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">XRFrame</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span><span class="tsd-signature-symbol">;</span><br/> <a class="tsd-kind-call-signature" href="CloudXR.Session.html#render-1">render</a><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">timestamp</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol">,</span> <span class="tsd-kind-parameter">frame</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">XRFrame</span><span class="tsd-signature-symbol">,</span> <span class="tsd-kind-parameter">layer</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">XRWebGLLayer</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">;</span><br/> <a class="tsd-kind-call-signature" href="CloudXR.Session.html#sendservermessage-1">sendServerMessage</a><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">message</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">;</span><br/><span class="tsd-signature-symbol">}</span></div><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Properties</h3><div class="tsd-index-list"><a href="CloudXR.Session.html#state" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>state</span></a>
|
||||||
|
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Methods</h3><div class="tsd-index-list"><a href="CloudXR.Session.html#connect" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>connect</span></a>
|
||||||
|
<a href="CloudXR.Session.html#disconnect" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>disconnect</span></a>
|
||||||
|
<a href="CloudXR.Session.html#sendtrackingstatetoserver" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>send<wbr/>Tracking<wbr/>State<wbr/>To<wbr/>Server</span></a>
|
||||||
|
<a href="CloudXR.Session.html#render" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>render</span></a>
|
||||||
|
<a href="CloudXR.Session.html#sendservermessage" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>send<wbr/>Server<wbr/>Message</span></a>
|
||||||
|
</div></section></div></details></section></section><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Properties"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Properties</h2></summary><section><section class="tsd-panel tsd-member"><a id="state" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><code class="tsd-tag">Readonly</code><span>state</span><a href="#state" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">state</span><span class="tsd-signature-symbol">:</span> <a href="../enums/CloudXR.SessionState.html" class="tsd-signature-type tsd-kind-enum">SessionState</a></div><div class="tsd-comment tsd-typography"><p>Current state of the session.</p>
|
||||||
|
<p>This readonly property provides the current state of the session,
|
||||||
|
which can be used to determine what operations are available
|
||||||
|
and to monitor the session lifecycle.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-1" class="tsd-anchor"></a>Example<a href="#example-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-3">// Check if session is ready for rendering</span><br/><span class="hl-9">if</span><span class="hl-1"> (</span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-4">state</span><span class="hl-1"> === </span><span class="hl-4">SessionState</span><span class="hl-1">.</span><span class="hl-4">Connected</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">// Safe to call render() and sendTrackingStateToServer()</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-3">// Monitor state changes</span><br/><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'Session state:'</span><span class="hl-1">, </span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-4">state</span><span class="hl-1">);</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></section></section></details><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Methods"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Methods</h2></summary><section><section class="tsd-panel tsd-member"><a id="connect" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>connect</span><a href="#connect" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class=""><div class="tsd-signature tsd-anchor-link"><a id="connect-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">connect</span><span class="tsd-signature-symbol">()</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span><a href="#connect-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></div><div class="tsd-description"><div class="tsd-comment tsd-typography"><p>Connect to the CloudXR server and start streaming.</p>
|
||||||
|
<p>Initiates connection to the CloudXR Runtime and transitions the session
|
||||||
|
to SessionState.Connecting, then SessionState.Connected once streaming is active.</p>
|
||||||
|
</div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4><div class="tsd-comment tsd-typography"><div class="tsd-tag-throws"><h4 class="tsd-anchor-link"><a id="throws" class="tsd-anchor"></a>Throws<a href="#throws" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>If called when session is not in Initialized or Disconnected state</p>
|
||||||
|
</div><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-2" class="tsd-anchor"></a>Example<a href="#example-2" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-9">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">connect</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'Connection initiated'</span><span class="hl-1">);</span><br/><span class="hl-1">} </span><span class="hl-9">catch</span><span class="hl-1"> (</span><span class="hl-4">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">error</span><span class="hl-1">(</span><span class="hl-2">'Failed to initiate connection:'</span><span class="hl-1">, </span><span class="hl-4">error</span><span class="hl-1">.</span><span class="hl-4">message</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></div></li></ul></section><section class="tsd-panel tsd-member"><a id="disconnect" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>disconnect</span><a href="#disconnect" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class=""><div class="tsd-signature tsd-anchor-link"><a id="disconnect-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">disconnect</span><span class="tsd-signature-symbol">()</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span><a href="#disconnect-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></div><div class="tsd-description"><div class="tsd-comment tsd-typography"><p>Disconnects from the CloudXR Runtime and terminates any streams.</p>
|
||||||
|
<p>Gracefully disconnects from the CloudXR Runtime and cleans up resources.
|
||||||
|
The session transitions through the following states:</p>
|
||||||
|
<ol>
|
||||||
|
<li><a href="../enums/CloudXR.SessionState.html#disconnecting" class="tsd-kind-enum-member">SessionState.Disconnecting</a> - Disconnection in progress</li>
|
||||||
|
<li><a href="../enums/CloudXR.SessionState.html#disconnected" class="tsd-kind-enum-member">SessionState.Disconnected</a> - Successfully disconnected</li>
|
||||||
|
</ol>
|
||||||
|
<p>After disconnection, the session can be reconnected by calling connect() again.</p>
|
||||||
|
</div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-3" class="tsd-anchor"></a>Example<a href="#example-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-3">// Disconnect when done</span><br/><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">disconnect</span><span class="hl-1">();</span><br/><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'Disconnection initiated'</span><span class="hl-1">);</span><br/><br/><span class="hl-3">// Disconnect on user action</span><br/><span class="hl-4">document</span><span class="hl-1">.</span><span class="hl-0">getElementById</span><span class="hl-1">(</span><span class="hl-2">'disconnect-btn'</span><span class="hl-1">).</span><span class="hl-0">onclick</span><span class="hl-1"> = () </span><span class="hl-6">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">disconnect</span><span class="hl-1">();</span><br/><span class="hl-1">};</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></div></li></ul></section><section class="tsd-panel tsd-member"><a id="sendtrackingstatetoserver" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>send<wbr/>Tracking<wbr/>State<wbr/>To<wbr/>Server</span><a href="#sendtrackingstatetoserver" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class=""><div class="tsd-signature tsd-anchor-link"><a id="sendtrackingstatetoserver-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">sendTrackingStateToServer</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">timestamp</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol">,</span> <span class="tsd-kind-parameter">frame</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">XRFrame</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span><a href="#sendtrackingstatetoserver-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></div><div class="tsd-description"><div class="tsd-comment tsd-typography"><p>Sends the view pose and input tracking data to the CloudXR Runtime.</p>
|
||||||
|
<p>Sends the current viewer pose (head position/orientation)
|
||||||
|
and input tracking data (controllers, hand tracking) to the CloudXR
|
||||||
|
Runtime. This data is essential for the Runtime to render the correct
|
||||||
|
view and handle user input.</p>
|
||||||
|
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">timestamp</span>: <span class="tsd-signature-type">number</span></span><div class="tsd-comment tsd-typography"><p>The current timestamp (DOMHighResTimeStamp) from the XR frame</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></li><li><span><span class="tsd-kind-parameter">frame</span>: <span class="tsd-signature-type">XRFrame</span></span><div class="tsd-comment tsd-typography"><p>The XR frame containing tracking data to send to the Runtime</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">boolean</span></h4><p>True if the tracking data was sent successfully, false otherwise.
|
||||||
|
Returns false if the session is not in Connected state.</p>
|
||||||
|
<div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-4" class="tsd-anchor"></a>Example<a href="#example-4" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-3">// In your WebXR render loop</span><br/><span class="hl-6">function</span><span class="hl-1"> </span><span class="hl-0">renderFrame</span><span class="hl-1">(</span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">frame</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-9">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">// Send tracking data first</span><br/><span class="hl-1"> </span><span class="hl-9">if</span><span class="hl-1"> (!</span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">sendTrackingStateToServer</span><span class="hl-1">(</span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">frame</span><span class="hl-1">)) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">warn</span><span class="hl-1">(</span><span class="hl-2">'Failed to send tracking state'</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-9">return</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-3">// Then render the frame</span><br/><span class="hl-1"> </span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">render</span><span class="hl-1">(</span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">frame</span><span class="hl-1">, </span><span class="hl-4">xrWebGLLayer</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-9">catch</span><span class="hl-1"> (</span><span class="hl-4">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">error</span><span class="hl-1">(</span><span class="hl-2">'Error in render frame:'</span><span class="hl-1">, </span><span class="hl-4">error</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-3">// Start the render loop</span><br/><span class="hl-4">xrSession</span><span class="hl-1">.</span><span class="hl-0">requestAnimationFrame</span><span class="hl-1">(</span><span class="hl-4">renderFrame</span><span class="hl-1">);</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></div></li></ul></section><section class="tsd-panel tsd-member"><a id="render" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>render</span><a href="#render" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class=""><div class="tsd-signature tsd-anchor-link"><a id="render-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">render</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">timestamp</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol">,</span> <span class="tsd-kind-parameter">frame</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">XRFrame</span><span class="tsd-signature-symbol">,</span> <span class="tsd-kind-parameter">layer</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">XRWebGLLayer</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span><a href="#render-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></div><div class="tsd-description"><div class="tsd-comment tsd-typography"><p>Renders a frame from CloudXR.</p>
|
||||||
|
<p>Renders the current frame received from the CloudXR Runtime
|
||||||
|
into the specified WebXR layer. Call this method every frame in your
|
||||||
|
WebXR render loop after sending tracking data.</p>
|
||||||
|
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">timestamp</span>: <span class="tsd-signature-type">number</span></span><div class="tsd-comment tsd-typography"><p>The current timestamp (DOMHighResTimeStamp) from the XR frame</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></li><li><span><span class="tsd-kind-parameter">frame</span>: <span class="tsd-signature-type">XRFrame</span></span><div class="tsd-comment tsd-typography"><p>The XR frame to render</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></li><li><span><span class="tsd-kind-parameter">layer</span>: <span class="tsd-signature-type">XRWebGLLayer</span></span><div class="tsd-comment tsd-typography"><p>The WebXR layer to render into (typically xrSession.renderState.baseLayer)</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-5" class="tsd-anchor"></a>Example<a href="#example-5" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-3">// Complete render loop</span><br/><span class="hl-6">function</span><span class="hl-1"> </span><span class="hl-0">renderFrame</span><span class="hl-1">(</span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">frame</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-9">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">// Send tracking data</span><br/><span class="hl-1"> </span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">sendTrackingStateToServer</span><span class="hl-1">(</span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">frame</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-3">// Render CloudXR content</span><br/><span class="hl-1"> </span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">render</span><span class="hl-1">(</span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">frame</span><span class="hl-1">, </span><span class="hl-4">xrSession</span><span class="hl-1">.</span><span class="hl-4">renderState</span><span class="hl-1">.</span><span class="hl-4">baseLayer</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-9">catch</span><span class="hl-1"> (</span><span class="hl-4">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">error</span><span class="hl-1">(</span><span class="hl-2">'Error in render frame:'</span><span class="hl-1">, </span><span class="hl-4">error</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-3">// Continue the loop</span><br/><span class="hl-1"> </span><span class="hl-4">xrSession</span><span class="hl-1">.</span><span class="hl-0">requestAnimationFrame</span><span class="hl-1">(</span><span class="hl-4">renderFrame</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-3">// Start rendering</span><br/><span class="hl-4">xrSession</span><span class="hl-1">.</span><span class="hl-0">requestAnimationFrame</span><span class="hl-1">(</span><span class="hl-4">renderFrame</span><span class="hl-1">);</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></div></li></ul></section><section class="tsd-panel tsd-member"><a id="sendservermessage" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>send<wbr/>Server<wbr/>Message</span><a href="#sendservermessage" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class=""><div class="tsd-signature tsd-anchor-link"><a id="sendservermessage-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">sendServerMessage</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">message</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span><a href="#sendservermessage-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></div><div class="tsd-description"><div class="tsd-comment tsd-typography"><p>Send a custom message to the CloudXR server.</p>
|
||||||
|
<p>Sends a custom JSON message to the server through the CloudXR protocol.
|
||||||
|
The message is serialized and sent via the streaming connection.</p>
|
||||||
|
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">message</span>: <span class="tsd-signature-type">any</span></span><div class="tsd-comment tsd-typography"><p>The message object to send to the server (must be a valid JSON object)</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4><div class="tsd-comment tsd-typography"><div class="tsd-tag-throws"><h4 class="tsd-anchor-link"><a id="throws-1" class="tsd-anchor"></a>Throws<a href="#throws-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>If session is not connected</p>
|
||||||
|
</div><div class="tsd-tag-throws"><h4 class="tsd-anchor-link"><a id="throws-2" class="tsd-anchor"></a>Throws<a href="#throws-2" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>If message is not a valid JSON object (null, primitive, or array)</p>
|
||||||
|
</div><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-6" class="tsd-anchor"></a>Example<a href="#example-6" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-9">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">const</span><span class="hl-1"> </span><span class="hl-5">customMessage</span><span class="hl-1"> = {</span><br/><span class="hl-1"> </span><span class="hl-4">type:</span><span class="hl-1"> </span><span class="hl-2">'userAction'</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">action:</span><span class="hl-1"> </span><span class="hl-2">'buttonPress'</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">data:</span><span class="hl-1"> { </span><span class="hl-4">buttonId:</span><span class="hl-1"> </span><span class="hl-7">1</span><span class="hl-1"> }</span><br/><span class="hl-1"> };</span><br/><span class="hl-1"> </span><span class="hl-4">session</span><span class="hl-1">.</span><span class="hl-0">sendServerMessage</span><span class="hl-1">(</span><span class="hl-4">customMessage</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'Message sent successfully'</span><span class="hl-1">);</span><br/><span class="hl-1">} </span><span class="hl-9">catch</span><span class="hl-1"> (</span><span class="hl-4">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">error</span><span class="hl-1">(</span><span class="hl-2">'Failed to send message:'</span><span class="hl-1">, </span><span class="hl-4">error</span><span class="hl-1">.</span><span class="hl-4">message</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></div></li></ul></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#state" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>state</span></a></div></details><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Methods"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Methods</summary><div><a href="#connect" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>connect</span></a><a href="#disconnect" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>disconnect</span></a><a href="#sendtrackingstatetoserver" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>send<wbr/>Tracking<wbr/>State<wbr/>To<wbr/>Server</span></a><a href="#render" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>render</span></a><a href="#sendservermessage" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Method"><use href="../assets/icons.svg#icon-2048"></use></svg><span>send<wbr/>Server<wbr/>Message</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
47
deps/cloudxr/docs/interfaces/CloudXR.SessionDelegates.html
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>SessionDelegates | CloudXR.js SDK Documentation - v6.0.0-beta</title><meta name="description" content="Documentation for CloudXR.js SDK Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CloudXR.js SDK Documentation - v6.0.0-beta</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CloudXR.js SDK Documentation</a></li><li><a href="../modules/CloudXR.html">CloudXR</a></li><li><a href="CloudXR.SessionDelegates.html">SessionDelegates</a></li></ul><h1>Interface SessionDelegates</h1></div><section class="tsd-panel tsd-comment"><div class="tsd-comment tsd-typography"><p>Defines callbacks for CloudXR session events.</p>
|
||||||
|
<p>Applications implement these callbacks to receive notifications about
|
||||||
|
session lifecycle events and WebGL state changes. All callbacks are optional.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example" class="tsd-anchor"></a>Example<a href="#example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-6">const</span><span class="hl-1"> </span><span class="hl-5">delegates</span><span class="hl-1">: </span><span class="hl-13">SessionDelegates</span><span class="hl-1"> = {</span><br/><span class="hl-1"> </span><span class="hl-0">onStreamStarted</span><span class="hl-4">:</span><span class="hl-1"> () </span><span class="hl-6">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'CloudXR streaming started'</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">// Update UI to show streaming status</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-0">onStreamStopped</span><span class="hl-4">:</span><span class="hl-1"> (</span><span class="hl-4">error</span><span class="hl-1">) </span><span class="hl-6">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-9">if</span><span class="hl-1"> (</span><span class="hl-4">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">error</span><span class="hl-1">(</span><span class="hl-2">'Streaming stopped due to error:'</span><span class="hl-1">, </span><span class="hl-4">error</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-9">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'Streaming stopped normally'</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">};</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></section><div class="tsd-signature"><span class="tsd-signature-keyword">interface</span> <span class="tsd-kind-interface">SessionDelegates</span> <span class="tsd-signature-symbol">{</span><br/> <a class="tsd-kind-property" href="CloudXR.SessionDelegates.html#onstreamstarted">onStreamStarted</a><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">()</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">;</span><br/> <a class="tsd-kind-property" href="CloudXR.SessionDelegates.html#onstreamstopped">onStreamStopped</a><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">error</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">Error</span><span class="tsd-signature-symbol">)</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">;</span><br/> <a class="tsd-kind-property" href="CloudXR.SessionDelegates.html#onwebglstatechangebegin">onWebGLStateChangeBegin</a><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">()</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">;</span><br/> <a class="tsd-kind-property" href="CloudXR.SessionDelegates.html#onwebglstatechangeend">onWebGLStateChangeEnd</a><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">()</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">;</span><br/> <a class="tsd-kind-property" href="CloudXR.SessionDelegates.html#onservermessagereceived">onServerMessageReceived</a><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">messageData</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Uint8Array</span><span class="tsd-signature-symbol">)</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">;</span><br/><span class="tsd-signature-symbol">}</span></div><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Properties</h3><div class="tsd-index-list"><a href="CloudXR.SessionDelegates.html#onstreamstarted" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>Stream<wbr/>Started?</span></a>
|
||||||
|
<a href="CloudXR.SessionDelegates.html#onstreamstopped" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>Stream<wbr/>Stopped?</span></a>
|
||||||
|
<a href="CloudXR.SessionDelegates.html#onwebglstatechangebegin" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>WebGLState<wbr/>Change<wbr/>Begin?</span></a>
|
||||||
|
<a href="CloudXR.SessionDelegates.html#onwebglstatechangeend" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>WebGLState<wbr/>Change<wbr/>End?</span></a>
|
||||||
|
<a href="CloudXR.SessionDelegates.html#onservermessagereceived" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>Server<wbr/>Message<wbr/>Received?</span></a>
|
||||||
|
</div></section></div></details></section></section><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Properties"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Properties</h2></summary><section><section class="tsd-panel tsd-member"><a id="onstreamstarted" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><code class="tsd-tag">Optional</code><span>on<wbr/>Stream<wbr/>Started</span><a href="#onstreamstarted" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">onStreamStarted</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">()</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span></div><div class="tsd-comment tsd-typography"><p>Invoked when streaming connects successfully.</p>
|
||||||
|
<p>Called when the session transitions to the Connected state
|
||||||
|
and streaming is ready to begin. At this point, the session is ready for
|
||||||
|
rendering and all WebGL resources have been initialized.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-1" class="tsd-anchor"></a>Example<a href="#example-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-8">onStreamStarted</span><span class="hl-1">: () </span><span class="hl-6">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'Ready to render CloudXR content'</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">// Start your render loop here</span><br/><span class="hl-1">}</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></section><section class="tsd-panel tsd-member"><a id="onstreamstopped" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><code class="tsd-tag">Optional</code><span>on<wbr/>Stream<wbr/>Stopped</span><a href="#onstreamstopped" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">onStreamStopped</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">error</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">Error</span><span class="tsd-signature-symbol">)</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span></div><div class="tsd-comment tsd-typography"><p>Invoked when streaming stops (either by client or server).</p>
|
||||||
|
<p>Called when the session stops streaming, either due to
|
||||||
|
a normal disconnection or an error condition. Check the error parameter
|
||||||
|
to determine the reason for the stop.</p>
|
||||||
|
</div><div class="tsd-type-declaration"><h4>Type declaration</h4><ul class="tsd-parameters"><li class="tsd-parameter-signature"><ul class="tsd-signatures"><li class="tsd-signature"><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">error</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">Error</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span></li><li class="tsd-description"><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><code class="tsd-tag">Optional</code><span class="tsd-kind-parameter">error</span>: <span class="tsd-signature-type">Error</span></span><div class="tsd-comment tsd-typography"><p>Optional error object if streaming stopped due to an error.
|
||||||
|
If undefined, the stop was intentional (e.g., disconnect() called).</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4></li></ul></li></ul></div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-2" class="tsd-anchor"></a>Example<a href="#example-2" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-8">onStreamStopped</span><span class="hl-1">: (</span><span class="hl-4">error</span><span class="hl-1">) </span><span class="hl-6">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-9">if</span><span class="hl-1"> (</span><span class="hl-4">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">error</span><span class="hl-1">(</span><span class="hl-2">'Streaming error:'</span><span class="hl-1">, </span><span class="hl-4">error</span><span class="hl-1">.</span><span class="hl-4">message</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">// Handle error condition</span><br/><span class="hl-1"> } </span><span class="hl-9">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">'Streaming stopped normally'</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">// Handle normal disconnection</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></section><section class="tsd-panel tsd-member"><a id="onwebglstatechangebegin" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><code class="tsd-tag">Optional</code><span>on<wbr/>WebGLState<wbr/>Change<wbr/>Begin</span><a href="#onwebglstatechangebegin" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">onWebGLStateChangeBegin</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">()</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span></div><div class="tsd-comment tsd-typography"><p>Invoked before the session changes any WebGL state.</p>
|
||||||
|
<p>Called before the session modifies WebGL state during
|
||||||
|
rendering operations. Use this to save the current WebGL state if needed
|
||||||
|
for your application's rendering pipeline.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-3" class="tsd-anchor"></a>Example<a href="#example-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-8">onWebGLStateChangeBegin</span><span class="hl-1">: () </span><span class="hl-6">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">// Save current WebGL state</span><br/><span class="hl-1"> </span><span class="hl-4">gl</span><span class="hl-1">.</span><span class="hl-0">bindFramebuffer</span><span class="hl-1">(</span><span class="hl-4">gl</span><span class="hl-1">.</span><span class="hl-5">FRAMEBUFFER</span><span class="hl-1">, </span><span class="hl-6">null</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></section><section class="tsd-panel tsd-member"><a id="onwebglstatechangeend" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><code class="tsd-tag">Optional</code><span>on<wbr/>WebGLState<wbr/>Change<wbr/>End</span><a href="#onwebglstatechangeend" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">onWebGLStateChangeEnd</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">()</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span></div><div class="tsd-comment tsd-typography"><p>Invoked after the session changes any WebGL state.</p>
|
||||||
|
<p>Called after the session has completed its WebGL state
|
||||||
|
modifications during rendering operations. Use this to restore any WebGL
|
||||||
|
state that your application needs.</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-4" class="tsd-anchor"></a>Example<a href="#example-4" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-8">onWebGLStateChangeEnd</span><span class="hl-1">: () </span><span class="hl-6">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">// Restore WebGL state</span><br/><span class="hl-1"> </span><span class="hl-4">gl</span><span class="hl-1">.</span><span class="hl-0">bindFramebuffer</span><span class="hl-1">(</span><span class="hl-4">gl</span><span class="hl-1">.</span><span class="hl-5">FRAMEBUFFER</span><span class="hl-1">, </span><span class="hl-4">myFramebuffer</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></section><section class="tsd-panel tsd-member"><a id="onservermessagereceived" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><code class="tsd-tag">Optional</code><span>on<wbr/>Server<wbr/>Message<wbr/>Received</span><a href="#onservermessagereceived" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">onServerMessageReceived</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">messageData</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Uint8Array</span><span class="tsd-signature-symbol">)</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span></div><div class="tsd-comment tsd-typography"><p>Invoked when a server message is received through any opaque data channel.</p>
|
||||||
|
</div><div class="tsd-type-declaration"><h4>Type declaration</h4><ul class="tsd-parameters"><li class="tsd-parameter-signature"><ul class="tsd-signatures"><li class="tsd-signature"><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">messageData</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Uint8Array</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span></li><li class="tsd-description"><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">messageData</span>: <span class="tsd-signature-type">Uint8Array</span></span><div class="tsd-comment tsd-typography"><p>Raw message data from the server</p>
|
||||||
|
</div><div class="tsd-comment tsd-typography"></div></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4></li></ul></li></ul></div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example-5" class="tsd-anchor"></a>Example<a href="#example-5" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-8">onServerMessageReceived</span><span class="hl-1">: (</span><span class="hl-4">messageData</span><span class="hl-1">) </span><span class="hl-6">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">const</span><span class="hl-1"> </span><span class="hl-5">messageString</span><span class="hl-1"> = </span><span class="hl-6">new</span><span class="hl-1"> </span><span class="hl-0">TextDecoder</span><span class="hl-1">().</span><span class="hl-0">decode</span><span class="hl-1">(</span><span class="hl-4">messageData</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">'Received message:'</span><span class="hl-1">, </span><span class="hl-4">messageString</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-3">// Parse JSON if expected</span><br/><span class="hl-1"> </span><span class="hl-9">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">const</span><span class="hl-1"> </span><span class="hl-5">message</span><span class="hl-1"> = </span><span class="hl-5">JSON</span><span class="hl-1">.</span><span class="hl-0">parse</span><span class="hl-1">(</span><span class="hl-4">messageString</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">'Parsed message:'</span><span class="hl-1">, </span><span class="hl-4">message</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-9">catch</span><span class="hl-1"> (</span><span class="hl-4">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">'Raw binary data:'</span><span class="hl-1">, </span><span class="hl-4">messageData</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
|
||||||
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
|
</div></div></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#onstreamstarted" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>Stream<wbr/>Started</span></a><a href="#onstreamstopped" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>Stream<wbr/>Stopped</span></a><a href="#onwebglstatechangebegin" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>WebGLState<wbr/>Change<wbr/>Begin</span></a><a href="#onwebglstatechangeend" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>WebGLState<wbr/>Change<wbr/>End</span></a><a href="#onservermessagereceived" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Property"><use href="../assets/icons.svg#icon-1024"></use></svg><span>on<wbr/>Server<wbr/>Message<wbr/>Received</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CloudXR.js SDK Documentation - v6.0.0-beta</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
||||||
131
deps/cloudxr/docs/interfaces/CloudXR.SessionOptions.html
vendored
Normal file
21
deps/cloudxr/docs/media/HEROICONS_LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Tailwind Labs, Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
307
deps/cloudxr/docs/media/LICENSE
vendored
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
NVIDIA SOFTWARE EVALUATION LICENSE AGREEMENT
|
||||||
|
|
||||||
|
IMPORTANT NOTICE – PLEASE READ AND AGREE BEFORE USING THE SOFTWARE
|
||||||
|
|
||||||
|
This software evaluation license agreement (“Agreement”) is a legal agreement between you, whether an
|
||||||
|
individual or entity, (“you”) and NVIDIA Corporation and its affiliates (“NVIDIA”) and governs the use of certain
|
||||||
|
NVIDIA CloudXR software and documentation that NVIDIA delivers to you under this Agreement (“Software”).
|
||||||
|
NVIDIA and you are each a “party” and collectively the “parties.”
|
||||||
|
This Agreement can be accepted only by an adult of legal age of majority in the country in which the Software is
|
||||||
|
used. If you don’t have the required age or authority to accept this Agreement, or if you don’t accept all the
|
||||||
|
terms and conditions of this Agreement, do not use the Software.
|
||||||
|
|
||||||
|
1. License Grants.
|
||||||
|
|
||||||
|
1.1 License Grant to You. The Software is licensed, not sold. Subject to the terms of this Agreement,
|
||||||
|
NVIDIA grants you a limited, non-exclusive, revocable, non-transferable, non-sublicensable (except
|
||||||
|
as expressly granted in this Agreement), license to:
|
||||||
|
(a) access, install and use copies of the Software,
|
||||||
|
(b) configure the Software using configuration files provided (if applicable),
|
||||||
|
(c) modify and create derivative works of any source code NVIDIA delivers to you as part of the
|
||||||
|
Software (“Derivatives”) (if applicable).
|
||||||
|
|
||||||
|
All the foregoing grants are only for internal test and evaluation purposes and, as applicable, for use (a) in
|
||||||
|
client systems, or (b) in server systems with NVIDIA GPUs (“Purpose”).
|
||||||
|
|
||||||
|
1.2 License Grant to NVIDIA. Subject to the terms of this Agreement, you grant NVIDIA a non-exclusive,
|
||||||
|
perpetual, irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license,
|
||||||
|
under your intellectual property rights, to publicly perform, publicly display, reproduce, use, make,
|
||||||
|
have made, sell, offer for sale, distribute (through multiple tiers of distribution), import, create
|
||||||
|
derivative works of and otherwise commercialize and exploit at NVIDIA’s discretion any Derivatives
|
||||||
|
created by or for you. You may, but are not required to, deliver any Derivatives to NVIDIA.
|
||||||
|
|
||||||
|
2. License Restrictions. Your license to use the Software and Derivatives is restricted as stated in this “License
|
||||||
|
Restrictions” Section. You will cooperate with NVIDIA and, upon NVIDIA’s written request, you will confirm
|
||||||
|
in writing and provide reasonably requested information to verify your compliance with the terms of this
|
||||||
|
Agreement. You may not:
|
||||||
|
|
||||||
|
2.1 Use the Software or Derivatives for any purpose other than the Purpose, including but not limited to
|
||||||
|
in production;
|
||||||
|
|
||||||
|
2.2 Sell, rent, sublicense, transfer, distribute or otherwise make available to others (except Authorized
|
||||||
|
Users as stated in the “Authorized Users” Section) any portion of the Software or Derivatives, except
|
||||||
|
as expressly granted in Section 1.1 (“License Grant to You”);
|
||||||
|
|
||||||
|
2.3 Reverse engineer, decompile, or disassemble the Software components provided in binary form, nor
|
||||||
|
attempt in any other manner to obtain source code of such Software;
|
||||||
|
|
||||||
|
2.4 Modify or create derivative works of the Software, except as expressly granted in Section 1.1
|
||||||
|
(“License Grant to You”);
|
||||||
|
|
||||||
|
2.5 Change or remove copyright or other proprietary notices in the Software;
|
||||||
|
|
||||||
|
2.6 Bypass, disable, or circumvent any technical limitation, encryption, security, digital rights
|
||||||
|
management or authentication mechanism in the Software;
|
||||||
|
|
||||||
|
2.7 Use the Software or Derivatives in any manner that would cause them to become subject to an open
|
||||||
|
source software license; subject to the terms in Section 7 (“Components Under Other Licenses”);
|
||||||
|
|
||||||
|
2.8 Use the Software or Derivatives for the purpose of developing competing products or technologies
|
||||||
|
or assist a third party in such activities;
|
||||||
|
|
||||||
|
2.9 Replace any Software components governed by this Agreement with other software that
|
||||||
|
implements NVIDIA APIs;
|
||||||
|
|
||||||
|
2.10 Use the Software or Derivatives in violation of any applicable law or regulation in the relevant
|
||||||
|
jurisdictions; or
|
||||||
|
|
||||||
|
2.11 Use the Software in or with any system or application where the use or failure of such system or
|
||||||
|
application developed or deployed with Software could result in injury, death or catastrophic
|
||||||
|
damage (“Mission Critical Applications”). NVIDIA will not be liable to you or any third party, in whole
|
||||||
|
or in part, for any claims or damages arising from uses in Mission Critical Applications.
|
||||||
|
|
||||||
|
2.12 Disclose any evaluation or test results regarding the Software or Derivatives without NVIDIA’s prior
|
||||||
|
written consent.
|
||||||
|
|
||||||
|
3. Authorized Users. You may allow employees and contractors of your entity or of your subsidiary(ies), and
|
||||||
|
for educational institutions also enrolled students, to internally access and use the Software as authorized
|
||||||
|
by this Agreement from your secure network to perform the work authorized by this Agreement on your
|
||||||
|
behalf. You are responsible for the compliance with the terms of this Agreement by your authorized users.
|
||||||
|
Any act or omission that if committed by you would constitute a breach of this Agreement will be deemed to
|
||||||
|
constitute a breach of this Agreement if committed by your authorized users.
|
||||||
|
|
||||||
|
4. Pre-Release. Software versions identified as alpha, beta, preview, early access or otherwise as pre-release
|
||||||
|
may not be fully functional, may contain errors or design flaws, and may have reduced or different security,
|
||||||
|
privacy, availability and reliability standards relative to NVIDIA commercial offerings. You use pre-release
|
||||||
|
Software at your own risk. NVIDIA did not design or test the Software for use in production or business
|
||||||
|
critical systems. NVIDIA may choose not to make available a commercial version of pre-release Software.
|
||||||
|
NVIDIA may also choose to abandon development and terminate the availability of pre-release Software at
|
||||||
|
any time without liability.
|
||||||
|
|
||||||
|
5. Your Privacy: Collection and Use of Information.
|
||||||
|
|
||||||
|
5.1 Privacy Policy. Please review the NVIDIA Privacy Policy, located at https://www.nvidia.com/enus/about-nvidia/privacy-policy, which explains NVIDIA’s policy for collecting and using data, as well
|
||||||
|
as visit the NVIDIA Privacy Center, located at https://www.nvidia.com/en-us/privacy-center, to
|
||||||
|
manage your consent and privacy preferences.
|
||||||
|
|
||||||
|
5.2 Collection Purposes. You also acknowledge that the Software collects data for the following
|
||||||
|
purposes: (a) properly configure and optimize products for use with Software; and (b) improve
|
||||||
|
NVIDIA products and services. Information collected by the Software includes: (i) application
|
||||||
|
configuration; (ii) browser version; (iii) and session metadata (i.e. performance and usage
|
||||||
|
statistics). Additionally, NVIDIA may collect certain personal information, such as your name
|
||||||
|
and email address or those of your authorized users, and other information necessary to
|
||||||
|
authenticate and enable you or your authorized users’ access to the Software. Where appropriate
|
||||||
|
you will disclose to, and obtain any necessary consent from, your authorized users to allow NVIDIA
|
||||||
|
to collect such information.
|
||||||
|
|
||||||
|
5.3 Third Party Privacy Practices. The Software may contain links to third party websites and services.
|
||||||
|
NVIDIA encourages you to review the privacy statements on those sites and services that you choose
|
||||||
|
to visit to understand how they may collect, use and share your data. NVIDIA is not responsible for
|
||||||
|
the privacy statements or practices of third-party sites or services.
|
||||||
|
|
||||||
|
6. Updates. NVIDIA may at any time and at its option, change, discontinue, or deprecate any part, or all, of the
|
||||||
|
Software, or change or remove features or functionality, or make available patches, workarounds or other
|
||||||
|
updates to the Software. Unless the updates are provided with their separate governing terms, they are
|
||||||
|
deemed part of the Software licensed to you under this Agreement, and your continued use of the Software
|
||||||
|
is deemed acceptance of such changes.
|
||||||
|
|
||||||
|
7. Components Under Other Licenses. The Software may include or be distributed with components provided
|
||||||
|
with separate legal notices or terms that accompany the components, such as open source software licenses
|
||||||
|
and other license terms (“Other Licenses”). The components are subject to the applicable Other Licenses,
|
||||||
|
including any proprietary notices, disclaimers, requirements and extended use rights; except that this
|
||||||
|
Agreement will prevail regarding the use of third-party open source software, unless a third-party open
|
||||||
|
source software license requires its license terms to prevail. Open source software license means any
|
||||||
|
software, data or documentation subject to any license identified as an open source license by the Open
|
||||||
|
Source Initiative (http://opensource.org), Free Software Foundation (http://www.fsf.org) or other similar
|
||||||
|
open source organization or listed by the Software Package Data Exchange (SPDX) Workgroup under the
|
||||||
|
Linux Foundation (http://www.spdx.org).
|
||||||
|
|
||||||
|
8. Ownership.
|
||||||
|
|
||||||
|
8.1 NVIDIA Ownership. The Software, including all intellectual property rights, is and will remain the sole
|
||||||
|
and exclusive property of NVIDIA or its licensors. Except as expressly granted in this Agreement,
|
||||||
|
(a) NVIDIA reserves all rights, interests and remedies in connection with the Software, and (b) no
|
||||||
|
other license or right is granted to you by implication, estoppel or otherwise.
|
||||||
|
|
||||||
|
8.2 Your Ownership. Subject to the rights of NVIDIA and its suppliers in the Software, which continue to
|
||||||
|
be licensed as stated in this Agreement, even when incorporated in your products, and the extent
|
||||||
|
permitted by applicable law, as between you and NVIDIA, you hold all rights, title and interest in and
|
||||||
|
to your services, applications and Derivatives you develop as permitted in this Agreement including
|
||||||
|
their respective intellectual property rights.
|
||||||
|
|
||||||
|
9. Feedback. You may, but are not obligated to, provide suggestions, requests, fixes, modifications,
|
||||||
|
enhancements or other feedback regarding your use of the Software (“Feedback”). Feedback, even if
|
||||||
|
designated as confidential by you, will not create any confidentiality obligation for NVIDIA or its affiliates. If
|
||||||
|
you provide Feedback, you hereby grant NVIDIA, its affiliates and its designees a nonexclusive, perpetual,
|
||||||
|
irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license, under your
|
||||||
|
intellectual property rights, to publicly perform, publicly display, reproduce, use, make, have made, sell,
|
||||||
|
offer for sale, distribute (through multiple tiers of distribution), import, create derivative works of and
|
||||||
|
otherwise commercialize and exploit the Feedback at NVIDIA’s discretion.
|
||||||
|
|
||||||
|
10. Confidentiality. You may use confidential information only to exercise your rights and perform your
|
||||||
|
obligations under this Agreement. You will not disclose, nor authorize others to disclose NVIDIA Confidential
|
||||||
|
Information to any third party, except as expressly authorized in this Agreement and as necessary for the
|
||||||
|
Purpose, without obtaining NVIDIA’s prior written approval. Each recipient of confidential information must
|
||||||
|
be subject to a written agreement that includes confidentiality obligations consistent with these terms and
|
||||||
|
must have a need to know for the Purpose. You will protect the NVIDIA Confidential Information with at
|
||||||
|
least the same degree of care that you use to protect your own similar confidential and proprietary
|
||||||
|
information, but no less than a reasonable degree of care. Confidential information includes, but is not
|
||||||
|
limited to, the Software, including its features and functionality, Derivatives, and any results of
|
||||||
|
benchmarking or other competitive analysis or regression or performance data relating to the Software.
|
||||||
|
No Publicity. You may not issue any public statements about this Agreement, disclose the Software or
|
||||||
|
Derivatives, or any information or results related to your use of the Software, without prior written approval
|
||||||
|
of NVIDIA.
|
||||||
|
|
||||||
|
11. Term and Termination.
|
||||||
|
|
||||||
|
11.1 Term. This Agreement has a duration of twelve (12) months starting from the date of initial
|
||||||
|
download (even if you download the same version or updates of the Software later and it is
|
||||||
|
accompanied by this Agreement or another Agreement), unless terminated earlier in accordance
|
||||||
|
with this Agreement.
|
||||||
|
|
||||||
|
11.2 Termination for Convenience. Either party may terminate this Agreement at any time with thirty (30)
|
||||||
|
days’ advance written notice to the other party.
|
||||||
|
|
||||||
|
11.3 Termination for Cause. If you commence or participate in any legal proceeding against NVIDIA with
|
||||||
|
respect to the Software, this Agreement will terminate immediately without notice. Either party may
|
||||||
|
terminate this Agreement upon notice for cause if:
|
||||||
|
(a) the other party fails to cure a material breach of this Agreement within ten (10) days of the
|
||||||
|
non-breaching party’s notice of the breach; or
|
||||||
|
(b) the other party breaches its confidentiality obligations or license rights under this
|
||||||
|
Agreement, which termination will be effective immediately upon written notice.
|
||||||
|
|
||||||
|
11.4 Effect of Termination. Upon any expiration or termination of this Agreement, you will promptly
|
||||||
|
(a) stop using and return, delete or destroy NVIDIA confidential information and all Software
|
||||||
|
received under this Agreement, and (b) delete or destroy Derivatives created under this Agreement,
|
||||||
|
unless an authorized NVIDIA representative provides prior written approval that you may keep a
|
||||||
|
copy of the Derivatives solely for archival purposes. Upon written request, you will certify in writing
|
||||||
|
that you have complied with your obligations under this “Effect of Termination” Section.
|
||||||
|
|
||||||
|
11.5 Survival. The “License Grant to NVIDIA”, “Updates”, “Components Under Other Licenses”,
|
||||||
|
“Ownership”, “Feedback”, “Confidentiality”, “No Publicity”, “Effect of Termination”, “Survival”,
|
||||||
|
“Disclaimer of Warranties”, “Limitation of Liability”, “Indemnity” and all “General” Sections of this
|
||||||
|
Agreement will survive any expiration or termination of this Agreement.
|
||||||
|
|
||||||
|
12. Disclaimer of Warranties. THE SOFTWARE IS PROVIDED BY NVIDIA AS-IS AND WITH ALL FAULTS. TO THE
|
||||||
|
MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NVIDIA DISCLAIMS ALL WARRANTIES AND
|
||||||
|
REPRESENTATIONS OF ANY KIND, WHETHER EXPRESS, IMPLIED OR STATUTORY, RELATING TO OR ARISING
|
||||||
|
UNDER THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF TITLE,
|
||||||
|
NONINFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, USAGE OF TRADE AND
|
||||||
|
COURSE OF DEALING. NVIDIA DOES NOT WARRANT OR ASSUME RESPONSIBILITY FOR THE ACCURACY OR
|
||||||
|
COMPLETENESS OF ANY THIRD-PARTY INFORMATION, TEXT, GRAPHICS, LINKS CONTAINED IN THE
|
||||||
|
SOFTWARE. WITHOUT LIMITING THE FOREGOING, NVIDIA DOES NOT WARRANT THAT THE SOFTWARE WILL
|
||||||
|
MEET YOUR REQUIREMENTS, ANY DEFECTS OR ERRORS WILL BE CORRECTED, ANY CERTAIN CONTENT WILL
|
||||||
|
BE AVAILABLE; OR THAT THE SOFTWARE IS FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS. NO
|
||||||
|
INFORMATION OR ADVICE GIVEN BY NVIDIA WILL IN ANY WAY INCREASE THE SCOPE OF ANY WARRANTY
|
||||||
|
EXPRESSLY PROVIDED IN THIS AGREEMENT. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE
|
||||||
|
APPROPRIATENESS OF USING THE SOFTWARE OR DERIVATIVES AND ASSUME ANY RISKS ASSOCIATED WITH
|
||||||
|
YOUR USE OF THE SOFTWARE OR DERIVATIVES.
|
||||||
|
|
||||||
|
13. Limitations of Liability.
|
||||||
|
|
||||||
|
13.1 EXCLUSIONS. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
|
||||||
|
NVIDIA BE LIABLE FOR ANY (A) INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES, OR (B) DAMAGES FOR THE (I) COST OF PROCURING SUBSTITUTE GOODS OR (II) LOSS OF
|
||||||
|
PROFITS, REVENUES, USE, DATA OR GOODWILL ARISING OUT OF OR RELATED TO THIS AGREEMENT,
|
||||||
|
WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR
|
||||||
|
OTHERWISE, AND EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND
|
||||||
|
EVEN IF A PARTY’S REMEDIES FAIL THEIR ESSENTIAL PURPOSE.
|
||||||
|
|
||||||
|
13.2 DAMAGES CAP. ADDITIONALLY, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
|
||||||
|
NVIDIA’S TOTAL CUMULATIVE AGGREGATE LIABILITY FOR ANY AND ALL LIABILITIES, OBLIGATIONS OR
|
||||||
|
CLAIMS ARISING OUT OF OR RELATED TO THIS AGREEMENT WILL NOT EXCEED ONE HUNDRED U.S.
|
||||||
|
DOLLARS (US$100).
|
||||||
|
|
||||||
|
14. Indemnity. You will defend, indemnify and hold harmless NVIDIA and its affiliates, and their respective
|
||||||
|
employees, contractors, agents, officers and directors, from and against any and all third party claims,
|
||||||
|
damages, obligations, losses, liabilities, costs or debt, fines, restitutions and expenses (including but not
|
||||||
|
limited to attorney’s fees and costs incident to establishing the right of indemnification) arising out of use of
|
||||||
|
the Software and Derivatives outside of the scope of this Agreement or in breach of the terms of this
|
||||||
|
Agreement.
|
||||||
|
|
||||||
|
15. General.
|
||||||
|
|
||||||
|
15.1 Governing Law and Jurisdiction. This Agreement will be governed in all respects by the laws of the
|
||||||
|
United States and the laws of the State of Delaware, without regard to conflict of laws principles or
|
||||||
|
the United Nations Convention on Contracts for the International Sale of Goods. The state and
|
||||||
|
federal courts residing in Santa Clara County, California will have exclusive jurisdiction over any
|
||||||
|
dispute or claim arising out of or related to this Agreement, and the parties irrevocably consent to
|
||||||
|
personal jurisdiction and venue in those courts; except that either party may apply for injunctive
|
||||||
|
remedies or an equivalent type of urgent legal relief in any jurisdiction.
|
||||||
|
|
||||||
|
15.2 Independent Contractors. The parties are independent contractors, and this Agreement does not
|
||||||
|
create a joint venture, partnership, agency or other form of business association between the
|
||||||
|
parties. Neither party will have the power to bind the other party or incur any obligation on its
|
||||||
|
behalf without the other party’s prior written consent. Nothing in this Agreement prevents either
|
||||||
|
party from participating in similar arrangements with third parties.
|
||||||
|
|
||||||
|
15.3 No Assignment. NVIDIA may assign, delegate or transfer its rights or obligations under this
|
||||||
|
Agreement by any means or operation of law. You may not, without NVIDIA’s prior written consent,
|
||||||
|
assign, delegate or transfer any of your rights or obligations under this Agreement by any means or
|
||||||
|
operation of law, and any attempt to do so is null and void.
|
||||||
|
|
||||||
|
15.4 No Waiver. No failure or delay by a party to enforce any term or obligation of this Agreement will
|
||||||
|
operate as a waiver by that party, or prevent the enforcement of such term or obligation later.
|
||||||
|
|
||||||
|
15.5 Trade Compliance. You agree to comply with all applicable export, import, trade and economic
|
||||||
|
sanctions laws and regulations, as amended, including without limitation U.S. Export Administration
|
||||||
|
Regulations and Office of Foreign Assets Control regulations. You confirm (a) your understanding
|
||||||
|
that export or reexport of certain NVIDIA products or technologies may require a license or other
|
||||||
|
approval from appropriate authorities and (b) that you will not export or reexport any products or
|
||||||
|
technology, directly or indirectly, without first obtaining any required license or other approval from
|
||||||
|
appropriate authorities, (i) to any countries that are subject to any U.S. or local export restrictions
|
||||||
|
(currently including, but not necessarily limited to, Belarus, Cuba, Iran, North Korea, Russia, Syria,
|
||||||
|
the Region of Crimea, Donetsk People’s Republic Region and Luhansk People’s Republic Region); (ii)
|
||||||
|
to any end-user who you know or have reason to know will utilize them in the design, development
|
||||||
|
or production of nuclear, chemical or biological weapons, missiles, rocket systems, unmanned air
|
||||||
|
vehicles capable of a maximum range of at least 300 kilometers, regardless of payload, or intended
|
||||||
|
for military end-use, or any weapons of mass destruction; (iii) to any end-user who has been
|
||||||
|
prohibited from participating in the U.S. or local export transactions by any governing authority; or
|
||||||
|
(iv) to any known military or military-intelligence end-user or for any known military or military-
|
||||||
|
intelligence end-use in accordance with U.S. trade compliance laws and regulations.
|
||||||
|
|
||||||
|
15.6 Government Rights. The Software, documentation and technology (“Protected Items”) are
|
||||||
|
“Commercial products” as this term is defined at 48 C.F.R. 2.101, consisting of “commercial
|
||||||
|
computer software” and “commercial computer software documentation” as such terms are used
|
||||||
|
in, respectively, 48 C.F.R. 12.212 and 48 C.F.R. 227.7202 & 252.227-7014(a)(1). Before any Protected
|
||||||
|
Items are supplied to the U.S. Government, you will (i) inform the U.S. Government in writing that
|
||||||
|
the Protected Items are and must be treated as commercial computer software and commercial
|
||||||
|
computer software documentation developed at private expense; (ii) inform the U.S. Government
|
||||||
|
that the Protected Items are provided subject to the terms of the Agreement; and (iii) mark the
|
||||||
|
Protected Items as commercial computer software and commercial computer software
|
||||||
|
documentation developed at private expense. In no event will you permit the U.S. Government to
|
||||||
|
acquire rights in Protected Items beyond those specified in 48 C.F.R. 52.227-19(b)(1)-(2) or 252.227-
|
||||||
|
7013(c) except as expressly approved by NVIDIA in writing.
|
||||||
|
|
||||||
|
15.7 Notices. Please direct your legal notices or other correspondence to legalnotices@nvidia.com with a
|
||||||
|
copy mailed to NVIDIA Corporation, 2788 San Tomas Expressway, Santa Clara, California 95051,
|
||||||
|
United States of America, Attention: Legal Department. If NVIDIA needs to contact you about the
|
||||||
|
Software, you consent to receive the notices by email and agree that such notices will satisfy any
|
||||||
|
legal communication requirements.
|
||||||
|
|
||||||
|
15.8 Severability. If a court of competent jurisdiction rules that a provision of this Agreement is
|
||||||
|
unenforceable, that provision will be deemed modified to the extent necessary to make it
|
||||||
|
enforceable and the remainder of this Agreement will continue in full force and effect.
|
||||||
|
|
||||||
|
15.9 Amendment. Any amendment to this Agreement must be in writing and signed by authorized
|
||||||
|
representatives of both parties.
|
||||||
|
|
||||||
|
15.10 Entire Agreement. Regarding the subject matter of this Agreement, the parties agree that (a) this
|
||||||
|
Agreement constitutes the entire and exclusive agreement between the parties and supersedes all
|
||||||
|
prior and contemporaneous communications and (b) any additional or different terms or conditions,
|
||||||
|
whether contained in purchase orders, order acknowledgments, invoices or otherwise, will not be
|
||||||
|
binding and are null and void.
|
||||||
|
|
||||||
|
(v. February 25, 2025)
|
||||||
|
|
||||||
|
NVIDIA Confidential
|
||||||
307
deps/cloudxr/docs/media/LICENSE-1
vendored
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
NVIDIA SOFTWARE EVALUATION LICENSE AGREEMENT
|
||||||
|
|
||||||
|
IMPORTANT NOTICE – PLEASE READ AND AGREE BEFORE USING THE SOFTWARE
|
||||||
|
|
||||||
|
This software evaluation license agreement (“Agreement”) is a legal agreement between you, whether an
|
||||||
|
individual or entity, (“you”) and NVIDIA Corporation and its affiliates (“NVIDIA”) and governs the use of certain
|
||||||
|
NVIDIA CloudXR software and documentation that NVIDIA delivers to you under this Agreement (“Software”).
|
||||||
|
NVIDIA and you are each a “party” and collectively the “parties.”
|
||||||
|
This Agreement can be accepted only by an adult of legal age of majority in the country in which the Software is
|
||||||
|
used. If you don’t have the required age or authority to accept this Agreement, or if you don’t accept all the
|
||||||
|
terms and conditions of this Agreement, do not use the Software.
|
||||||
|
|
||||||
|
1. License Grants.
|
||||||
|
|
||||||
|
1.1 License Grant to You. The Software is licensed, not sold. Subject to the terms of this Agreement,
|
||||||
|
NVIDIA grants you a limited, non-exclusive, revocable, non-transferable, non-sublicensable (except
|
||||||
|
as expressly granted in this Agreement), license to:
|
||||||
|
(a) access, install and use copies of the Software,
|
||||||
|
(b) configure the Software using configuration files provided (if applicable),
|
||||||
|
(c) modify and create derivative works of any source code NVIDIA delivers to you as part of the
|
||||||
|
Software (“Derivatives”) (if applicable).
|
||||||
|
|
||||||
|
All the foregoing grants are only for internal test and evaluation purposes and, as applicable, for use (a) in
|
||||||
|
client systems, or (b) in server systems with NVIDIA GPUs (“Purpose”).
|
||||||
|
|
||||||
|
1.2 License Grant to NVIDIA. Subject to the terms of this Agreement, you grant NVIDIA a non-exclusive,
|
||||||
|
perpetual, irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license,
|
||||||
|
under your intellectual property rights, to publicly perform, publicly display, reproduce, use, make,
|
||||||
|
have made, sell, offer for sale, distribute (through multiple tiers of distribution), import, create
|
||||||
|
derivative works of and otherwise commercialize and exploit at NVIDIA’s discretion any Derivatives
|
||||||
|
created by or for you. You may, but are not required to, deliver any Derivatives to NVIDIA.
|
||||||
|
|
||||||
|
2. License Restrictions. Your license to use the Software and Derivatives is restricted as stated in this “License
|
||||||
|
Restrictions” Section. You will cooperate with NVIDIA and, upon NVIDIA’s written request, you will confirm
|
||||||
|
in writing and provide reasonably requested information to verify your compliance with the terms of this
|
||||||
|
Agreement. You may not:
|
||||||
|
|
||||||
|
2.1 Use the Software or Derivatives for any purpose other than the Purpose, including but not limited to
|
||||||
|
in production;
|
||||||
|
|
||||||
|
2.2 Sell, rent, sublicense, transfer, distribute or otherwise make available to others (except Authorized
|
||||||
|
Users as stated in the “Authorized Users” Section) any portion of the Software or Derivatives, except
|
||||||
|
as expressly granted in Section 1.1 (“License Grant to You”);
|
||||||
|
|
||||||
|
2.3 Reverse engineer, decompile, or disassemble the Software components provided in binary form, nor
|
||||||
|
attempt in any other manner to obtain source code of such Software;
|
||||||
|
|
||||||
|
2.4 Modify or create derivative works of the Software, except as expressly granted in Section 1.1
|
||||||
|
(“License Grant to You”);
|
||||||
|
|
||||||
|
2.5 Change or remove copyright or other proprietary notices in the Software;
|
||||||
|
|
||||||
|
2.6 Bypass, disable, or circumvent any technical limitation, encryption, security, digital rights
|
||||||
|
management or authentication mechanism in the Software;
|
||||||
|
|
||||||
|
2.7 Use the Software or Derivatives in any manner that would cause them to become subject to an open
|
||||||
|
source software license; subject to the terms in Section 7 (“Components Under Other Licenses”);
|
||||||
|
|
||||||
|
2.8 Use the Software or Derivatives for the purpose of developing competing products or technologies
|
||||||
|
or assist a third party in such activities;
|
||||||
|
|
||||||
|
2.9 Replace any Software components governed by this Agreement with other software that
|
||||||
|
implements NVIDIA APIs;
|
||||||
|
|
||||||
|
2.10 Use the Software or Derivatives in violation of any applicable law or regulation in the relevant
|
||||||
|
jurisdictions; or
|
||||||
|
|
||||||
|
2.11 Use the Software in or with any system or application where the use or failure of such system or
|
||||||
|
application developed or deployed with Software could result in injury, death or catastrophic
|
||||||
|
damage (“Mission Critical Applications”). NVIDIA will not be liable to you or any third party, in whole
|
||||||
|
or in part, for any claims or damages arising from uses in Mission Critical Applications.
|
||||||
|
|
||||||
|
2.12 Disclose any evaluation or test results regarding the Software or Derivatives without NVIDIA’s prior
|
||||||
|
written consent.
|
||||||
|
|
||||||
|
3. Authorized Users. You may allow employees and contractors of your entity or of your subsidiary(ies), and
|
||||||
|
for educational institutions also enrolled students, to internally access and use the Software as authorized
|
||||||
|
by this Agreement from your secure network to perform the work authorized by this Agreement on your
|
||||||
|
behalf. You are responsible for the compliance with the terms of this Agreement by your authorized users.
|
||||||
|
Any act or omission that if committed by you would constitute a breach of this Agreement will be deemed to
|
||||||
|
constitute a breach of this Agreement if committed by your authorized users.
|
||||||
|
|
||||||
|
4. Pre-Release. Software versions identified as alpha, beta, preview, early access or otherwise as pre-release
|
||||||
|
may not be fully functional, may contain errors or design flaws, and may have reduced or different security,
|
||||||
|
privacy, availability and reliability standards relative to NVIDIA commercial offerings. You use pre-release
|
||||||
|
Software at your own risk. NVIDIA did not design or test the Software for use in production or business
|
||||||
|
critical systems. NVIDIA may choose not to make available a commercial version of pre-release Software.
|
||||||
|
NVIDIA may also choose to abandon development and terminate the availability of pre-release Software at
|
||||||
|
any time without liability.
|
||||||
|
|
||||||
|
5. Your Privacy: Collection and Use of Information.
|
||||||
|
|
||||||
|
5.1 Privacy Policy. Please review the NVIDIA Privacy Policy, located at https://www.nvidia.com/enus/about-nvidia/privacy-policy, which explains NVIDIA’s policy for collecting and using data, as well
|
||||||
|
as visit the NVIDIA Privacy Center, located at https://www.nvidia.com/en-us/privacy-center, to
|
||||||
|
manage your consent and privacy preferences.
|
||||||
|
|
||||||
|
5.2 Collection Purposes. You also acknowledge that the Software collects data for the following
|
||||||
|
purposes: (a) properly configure and optimize products for use with Software; and (b) improve
|
||||||
|
NVIDIA products and services. Information collected by the Software includes: (i) application
|
||||||
|
configuration; (ii) browser version; (iii) and session metadata (i.e. performance and usage
|
||||||
|
statistics). Additionally, NVIDIA may collect certain personal information, such as your name
|
||||||
|
and email address or those of your authorized users, and other information necessary to
|
||||||
|
authenticate and enable you or your authorized users’ access to the Software. Where appropriate
|
||||||
|
you will disclose to, and obtain any necessary consent from, your authorized users to allow NVIDIA
|
||||||
|
to collect such information.
|
||||||
|
|
||||||
|
5.3 Third Party Privacy Practices. The Software may contain links to third party websites and services.
|
||||||
|
NVIDIA encourages you to review the privacy statements on those sites and services that you choose
|
||||||
|
to visit to understand how they may collect, use and share your data. NVIDIA is not responsible for
|
||||||
|
the privacy statements or practices of third-party sites or services.
|
||||||
|
|
||||||
|
6. Updates. NVIDIA may at any time and at its option, change, discontinue, or deprecate any part, or all, of the
|
||||||
|
Software, or change or remove features or functionality, or make available patches, workarounds or other
|
||||||
|
updates to the Software. Unless the updates are provided with their separate governing terms, they are
|
||||||
|
deemed part of the Software licensed to you under this Agreement, and your continued use of the Software
|
||||||
|
is deemed acceptance of such changes.
|
||||||
|
|
||||||
|
7. Components Under Other Licenses. The Software may include or be distributed with components provided
|
||||||
|
with separate legal notices or terms that accompany the components, such as open source software licenses
|
||||||
|
and other license terms (“Other Licenses”). The components are subject to the applicable Other Licenses,
|
||||||
|
including any proprietary notices, disclaimers, requirements and extended use rights; except that this
|
||||||
|
Agreement will prevail regarding the use of third-party open source software, unless a third-party open
|
||||||
|
source software license requires its license terms to prevail. Open source software license means any
|
||||||
|
software, data or documentation subject to any license identified as an open source license by the Open
|
||||||
|
Source Initiative (http://opensource.org), Free Software Foundation (http://www.fsf.org) or other similar
|
||||||
|
open source organization or listed by the Software Package Data Exchange (SPDX) Workgroup under the
|
||||||
|
Linux Foundation (http://www.spdx.org).
|
||||||
|
|
||||||
|
8. Ownership.
|
||||||
|
|
||||||
|
8.1 NVIDIA Ownership. The Software, including all intellectual property rights, is and will remain the sole
|
||||||
|
and exclusive property of NVIDIA or its licensors. Except as expressly granted in this Agreement,
|
||||||
|
(a) NVIDIA reserves all rights, interests and remedies in connection with the Software, and (b) no
|
||||||
|
other license or right is granted to you by implication, estoppel or otherwise.
|
||||||
|
|
||||||
|
8.2 Your Ownership. Subject to the rights of NVIDIA and its suppliers in the Software, which continue to
|
||||||
|
be licensed as stated in this Agreement, even when incorporated in your products, and the extent
|
||||||
|
permitted by applicable law, as between you and NVIDIA, you hold all rights, title and interest in and
|
||||||
|
to your services, applications and Derivatives you develop as permitted in this Agreement including
|
||||||
|
their respective intellectual property rights.
|
||||||
|
|
||||||
|
9. Feedback. You may, but are not obligated to, provide suggestions, requests, fixes, modifications,
|
||||||
|
enhancements or other feedback regarding your use of the Software (“Feedback”). Feedback, even if
|
||||||
|
designated as confidential by you, will not create any confidentiality obligation for NVIDIA or its affiliates. If
|
||||||
|
you provide Feedback, you hereby grant NVIDIA, its affiliates and its designees a nonexclusive, perpetual,
|
||||||
|
irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license, under your
|
||||||
|
intellectual property rights, to publicly perform, publicly display, reproduce, use, make, have made, sell,
|
||||||
|
offer for sale, distribute (through multiple tiers of distribution), import, create derivative works of and
|
||||||
|
otherwise commercialize and exploit the Feedback at NVIDIA’s discretion.
|
||||||
|
|
||||||
|
10. Confidentiality. You may use confidential information only to exercise your rights and perform your
|
||||||
|
obligations under this Agreement. You will not disclose, nor authorize others to disclose NVIDIA Confidential
|
||||||
|
Information to any third party, except as expressly authorized in this Agreement and as necessary for the
|
||||||
|
Purpose, without obtaining NVIDIA’s prior written approval. Each recipient of confidential information must
|
||||||
|
be subject to a written agreement that includes confidentiality obligations consistent with these terms and
|
||||||
|
must have a need to know for the Purpose. You will protect the NVIDIA Confidential Information with at
|
||||||
|
least the same degree of care that you use to protect your own similar confidential and proprietary
|
||||||
|
information, but no less than a reasonable degree of care. Confidential information includes, but is not
|
||||||
|
limited to, the Software, including its features and functionality, Derivatives, and any results of
|
||||||
|
benchmarking or other competitive analysis or regression or performance data relating to the Software.
|
||||||
|
No Publicity. You may not issue any public statements about this Agreement, disclose the Software or
|
||||||
|
Derivatives, or any information or results related to your use of the Software, without prior written approval
|
||||||
|
of NVIDIA.
|
||||||
|
|
||||||
|
11. Term and Termination.
|
||||||
|
|
||||||
|
11.1 Term. This Agreement has a duration of twelve (12) months starting from the date of initial
|
||||||
|
download (even if you download the same version or updates of the Software later and it is
|
||||||
|
accompanied by this Agreement or another Agreement), unless terminated earlier in accordance
|
||||||
|
with this Agreement.
|
||||||
|
|
||||||
|
11.2 Termination for Convenience. Either party may terminate this Agreement at any time with thirty (30)
|
||||||
|
days’ advance written notice to the other party.
|
||||||
|
|
||||||
|
11.3 Termination for Cause. If you commence or participate in any legal proceeding against NVIDIA with
|
||||||
|
respect to the Software, this Agreement will terminate immediately without notice. Either party may
|
||||||
|
terminate this Agreement upon notice for cause if:
|
||||||
|
(a) the other party fails to cure a material breach of this Agreement within ten (10) days of the
|
||||||
|
non-breaching party’s notice of the breach; or
|
||||||
|
(b) the other party breaches its confidentiality obligations or license rights under this
|
||||||
|
Agreement, which termination will be effective immediately upon written notice.
|
||||||
|
|
||||||
|
11.4 Effect of Termination. Upon any expiration or termination of this Agreement, you will promptly
|
||||||
|
(a) stop using and return, delete or destroy NVIDIA confidential information and all Software
|
||||||
|
received under this Agreement, and (b) delete or destroy Derivatives created under this Agreement,
|
||||||
|
unless an authorized NVIDIA representative provides prior written approval that you may keep a
|
||||||
|
copy of the Derivatives solely for archival purposes. Upon written request, you will certify in writing
|
||||||
|
that you have complied with your obligations under this “Effect of Termination” Section.
|
||||||
|
|
||||||
|
11.5 Survival. The “License Grant to NVIDIA”, “Updates”, “Components Under Other Licenses”,
|
||||||
|
“Ownership”, “Feedback”, “Confidentiality”, “No Publicity”, “Effect of Termination”, “Survival”,
|
||||||
|
“Disclaimer of Warranties”, “Limitation of Liability”, “Indemnity” and all “General” Sections of this
|
||||||
|
Agreement will survive any expiration or termination of this Agreement.
|
||||||
|
|
||||||
|
12. Disclaimer of Warranties. THE SOFTWARE IS PROVIDED BY NVIDIA AS-IS AND WITH ALL FAULTS. TO THE
|
||||||
|
MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NVIDIA DISCLAIMS ALL WARRANTIES AND
|
||||||
|
REPRESENTATIONS OF ANY KIND, WHETHER EXPRESS, IMPLIED OR STATUTORY, RELATING TO OR ARISING
|
||||||
|
UNDER THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF TITLE,
|
||||||
|
NONINFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, USAGE OF TRADE AND
|
||||||
|
COURSE OF DEALING. NVIDIA DOES NOT WARRANT OR ASSUME RESPONSIBILITY FOR THE ACCURACY OR
|
||||||
|
COMPLETENESS OF ANY THIRD-PARTY INFORMATION, TEXT, GRAPHICS, LINKS CONTAINED IN THE
|
||||||
|
SOFTWARE. WITHOUT LIMITING THE FOREGOING, NVIDIA DOES NOT WARRANT THAT THE SOFTWARE WILL
|
||||||
|
MEET YOUR REQUIREMENTS, ANY DEFECTS OR ERRORS WILL BE CORRECTED, ANY CERTAIN CONTENT WILL
|
||||||
|
BE AVAILABLE; OR THAT THE SOFTWARE IS FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS. NO
|
||||||
|
INFORMATION OR ADVICE GIVEN BY NVIDIA WILL IN ANY WAY INCREASE THE SCOPE OF ANY WARRANTY
|
||||||
|
EXPRESSLY PROVIDED IN THIS AGREEMENT. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE
|
||||||
|
APPROPRIATENESS OF USING THE SOFTWARE OR DERIVATIVES AND ASSUME ANY RISKS ASSOCIATED WITH
|
||||||
|
YOUR USE OF THE SOFTWARE OR DERIVATIVES.
|
||||||
|
|
||||||
|
13. Limitations of Liability.
|
||||||
|
|
||||||
|
13.1 EXCLUSIONS. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
|
||||||
|
NVIDIA BE LIABLE FOR ANY (A) INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES, OR (B) DAMAGES FOR THE (I) COST OF PROCURING SUBSTITUTE GOODS OR (II) LOSS OF
|
||||||
|
PROFITS, REVENUES, USE, DATA OR GOODWILL ARISING OUT OF OR RELATED TO THIS AGREEMENT,
|
||||||
|
WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR
|
||||||
|
OTHERWISE, AND EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND
|
||||||
|
EVEN IF A PARTY’S REMEDIES FAIL THEIR ESSENTIAL PURPOSE.
|
||||||
|
|
||||||
|
13.2 DAMAGES CAP. ADDITIONALLY, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
|
||||||
|
NVIDIA’S TOTAL CUMULATIVE AGGREGATE LIABILITY FOR ANY AND ALL LIABILITIES, OBLIGATIONS OR
|
||||||
|
CLAIMS ARISING OUT OF OR RELATED TO THIS AGREEMENT WILL NOT EXCEED ONE HUNDRED U.S.
|
||||||
|
DOLLARS (US$100).
|
||||||
|
|
||||||
|
14. Indemnity. You will defend, indemnify and hold harmless NVIDIA and its affiliates, and their respective
|
||||||
|
employees, contractors, agents, officers and directors, from and against any and all third party claims,
|
||||||
|
damages, obligations, losses, liabilities, costs or debt, fines, restitutions and expenses (including but not
|
||||||
|
limited to attorney’s fees and costs incident to establishing the right of indemnification) arising out of use of
|
||||||
|
the Software and Derivatives outside of the scope of this Agreement or in breach of the terms of this
|
||||||
|
Agreement.
|
||||||
|
|
||||||
|
15. General.
|
||||||
|
|
||||||
|
15.1 Governing Law and Jurisdiction. This Agreement will be governed in all respects by the laws of the
|
||||||
|
United States and the laws of the State of Delaware, without regard to conflict of laws principles or
|
||||||
|
the United Nations Convention on Contracts for the International Sale of Goods. The state and
|
||||||
|
federal courts residing in Santa Clara County, California will have exclusive jurisdiction over any
|
||||||
|
dispute or claim arising out of or related to this Agreement, and the parties irrevocably consent to
|
||||||
|
personal jurisdiction and venue in those courts; except that either party may apply for injunctive
|
||||||
|
remedies or an equivalent type of urgent legal relief in any jurisdiction.
|
||||||
|
|
||||||
|
15.2 Independent Contractors. The parties are independent contractors, and this Agreement does not
|
||||||
|
create a joint venture, partnership, agency or other form of business association between the
|
||||||
|
parties. Neither party will have the power to bind the other party or incur any obligation on its
|
||||||
|
behalf without the other party’s prior written consent. Nothing in this Agreement prevents either
|
||||||
|
party from participating in similar arrangements with third parties.
|
||||||
|
|
||||||
|
15.3 No Assignment. NVIDIA may assign, delegate or transfer its rights or obligations under this
|
||||||
|
Agreement by any means or operation of law. You may not, without NVIDIA’s prior written consent,
|
||||||
|
assign, delegate or transfer any of your rights or obligations under this Agreement by any means or
|
||||||
|
operation of law, and any attempt to do so is null and void.
|
||||||
|
|
||||||
|
15.4 No Waiver. No failure or delay by a party to enforce any term or obligation of this Agreement will
|
||||||
|
operate as a waiver by that party, or prevent the enforcement of such term or obligation later.
|
||||||
|
|
||||||
|
15.5 Trade Compliance. You agree to comply with all applicable export, import, trade and economic
|
||||||
|
sanctions laws and regulations, as amended, including without limitation U.S. Export Administration
|
||||||
|
Regulations and Office of Foreign Assets Control regulations. You confirm (a) your understanding
|
||||||
|
that export or reexport of certain NVIDIA products or technologies may require a license or other
|
||||||
|
approval from appropriate authorities and (b) that you will not export or reexport any products or
|
||||||
|
technology, directly or indirectly, without first obtaining any required license or other approval from
|
||||||
|
appropriate authorities, (i) to any countries that are subject to any U.S. or local export restrictions
|
||||||
|
(currently including, but not necessarily limited to, Belarus, Cuba, Iran, North Korea, Russia, Syria,
|
||||||
|
the Region of Crimea, Donetsk People’s Republic Region and Luhansk People’s Republic Region); (ii)
|
||||||
|
to any end-user who you know or have reason to know will utilize them in the design, development
|
||||||
|
or production of nuclear, chemical or biological weapons, missiles, rocket systems, unmanned air
|
||||||
|
vehicles capable of a maximum range of at least 300 kilometers, regardless of payload, or intended
|
||||||
|
for military end-use, or any weapons of mass destruction; (iii) to any end-user who has been
|
||||||
|
prohibited from participating in the U.S. or local export transactions by any governing authority; or
|
||||||
|
(iv) to any known military or military-intelligence end-user or for any known military or military-
|
||||||
|
intelligence end-use in accordance with U.S. trade compliance laws and regulations.
|
||||||
|
|
||||||
|
15.6 Government Rights. The Software, documentation and technology (“Protected Items”) are
|
||||||
|
“Commercial products” as this term is defined at 48 C.F.R. 2.101, consisting of “commercial
|
||||||
|
computer software” and “commercial computer software documentation” as such terms are used
|
||||||
|
in, respectively, 48 C.F.R. 12.212 and 48 C.F.R. 227.7202 & 252.227-7014(a)(1). Before any Protected
|
||||||
|
Items are supplied to the U.S. Government, you will (i) inform the U.S. Government in writing that
|
||||||
|
the Protected Items are and must be treated as commercial computer software and commercial
|
||||||
|
computer software documentation developed at private expense; (ii) inform the U.S. Government
|
||||||
|
that the Protected Items are provided subject to the terms of the Agreement; and (iii) mark the
|
||||||
|
Protected Items as commercial computer software and commercial computer software
|
||||||
|
documentation developed at private expense. In no event will you permit the U.S. Government to
|
||||||
|
acquire rights in Protected Items beyond those specified in 48 C.F.R. 52.227-19(b)(1)-(2) or 252.227-
|
||||||
|
7013(c) except as expressly approved by NVIDIA in writing.
|
||||||
|
|
||||||
|
15.7 Notices. Please direct your legal notices or other correspondence to legalnotices@nvidia.com with a
|
||||||
|
copy mailed to NVIDIA Corporation, 2788 San Tomas Expressway, Santa Clara, California 95051,
|
||||||
|
United States of America, Attention: Legal Department. If NVIDIA needs to contact you about the
|
||||||
|
Software, you consent to receive the notices by email and agree that such notices will satisfy any
|
||||||
|
legal communication requirements.
|
||||||
|
|
||||||
|
15.8 Severability. If a court of competent jurisdiction rules that a provision of this Agreement is
|
||||||
|
unenforceable, that provision will be deemed modified to the extent necessary to make it
|
||||||
|
enforceable and the remainder of this Agreement will continue in full force and effect.
|
||||||
|
|
||||||
|
15.9 Amendment. Any amendment to this Agreement must be in writing and signed by authorized
|
||||||
|
representatives of both parties.
|
||||||
|
|
||||||
|
15.10 Entire Agreement. Regarding the subject matter of this Agreement, the parties agree that (a) this
|
||||||
|
Agreement constitutes the entire and exclusive agreement between the parties and supersedes all
|
||||||
|
prior and contemporaneous communications and (b) any additional or different terms or conditions,
|
||||||
|
whether contained in purchase orders, order acknowledgments, invoices or otherwise, will not be
|
||||||
|
binding and are null and void.
|
||||||
|
|
||||||
|
(v. February 25, 2025)
|
||||||
|
|
||||||
|
NVIDIA Confidential
|
||||||
307
deps/cloudxr/docs/media/LICENSE-2
vendored
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
NVIDIA SOFTWARE EVALUATION LICENSE AGREEMENT
|
||||||
|
|
||||||
|
IMPORTANT NOTICE – PLEASE READ AND AGREE BEFORE USING THE SOFTWARE
|
||||||
|
|
||||||
|
This software evaluation license agreement (“Agreement”) is a legal agreement between you, whether an
|
||||||
|
individual or entity, (“you”) and NVIDIA Corporation and its affiliates (“NVIDIA”) and governs the use of certain
|
||||||
|
NVIDIA CloudXR software and documentation that NVIDIA delivers to you under this Agreement (“Software”).
|
||||||
|
NVIDIA and you are each a “party” and collectively the “parties.”
|
||||||
|
This Agreement can be accepted only by an adult of legal age of majority in the country in which the Software is
|
||||||
|
used. If you don’t have the required age or authority to accept this Agreement, or if you don’t accept all the
|
||||||
|
terms and conditions of this Agreement, do not use the Software.
|
||||||
|
|
||||||
|
1. License Grants.
|
||||||
|
|
||||||
|
1.1 License Grant to You. The Software is licensed, not sold. Subject to the terms of this Agreement,
|
||||||
|
NVIDIA grants you a limited, non-exclusive, revocable, non-transferable, non-sublicensable (except
|
||||||
|
as expressly granted in this Agreement), license to:
|
||||||
|
(a) access, install and use copies of the Software,
|
||||||
|
(b) configure the Software using configuration files provided (if applicable),
|
||||||
|
(c) modify and create derivative works of any source code NVIDIA delivers to you as part of the
|
||||||
|
Software (“Derivatives”) (if applicable).
|
||||||
|
|
||||||
|
All the foregoing grants are only for internal test and evaluation purposes and, as applicable, for use (a) in
|
||||||
|
client systems, or (b) in server systems with NVIDIA GPUs (“Purpose”).
|
||||||
|
|
||||||
|
1.2 License Grant to NVIDIA. Subject to the terms of this Agreement, you grant NVIDIA a non-exclusive,
|
||||||
|
perpetual, irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license,
|
||||||
|
under your intellectual property rights, to publicly perform, publicly display, reproduce, use, make,
|
||||||
|
have made, sell, offer for sale, distribute (through multiple tiers of distribution), import, create
|
||||||
|
derivative works of and otherwise commercialize and exploit at NVIDIA’s discretion any Derivatives
|
||||||
|
created by or for you. You may, but are not required to, deliver any Derivatives to NVIDIA.
|
||||||
|
|
||||||
|
2. License Restrictions. Your license to use the Software and Derivatives is restricted as stated in this “License
|
||||||
|
Restrictions” Section. You will cooperate with NVIDIA and, upon NVIDIA’s written request, you will confirm
|
||||||
|
in writing and provide reasonably requested information to verify your compliance with the terms of this
|
||||||
|
Agreement. You may not:
|
||||||
|
|
||||||
|
2.1 Use the Software or Derivatives for any purpose other than the Purpose, including but not limited to
|
||||||
|
in production;
|
||||||
|
|
||||||
|
2.2 Sell, rent, sublicense, transfer, distribute or otherwise make available to others (except Authorized
|
||||||
|
Users as stated in the “Authorized Users” Section) any portion of the Software or Derivatives, except
|
||||||
|
as expressly granted in Section 1.1 (“License Grant to You”);
|
||||||
|
|
||||||
|
2.3 Reverse engineer, decompile, or disassemble the Software components provided in binary form, nor
|
||||||
|
attempt in any other manner to obtain source code of such Software;
|
||||||
|
|
||||||
|
2.4 Modify or create derivative works of the Software, except as expressly granted in Section 1.1
|
||||||
|
(“License Grant to You”);
|
||||||
|
|
||||||
|
2.5 Change or remove copyright or other proprietary notices in the Software;
|
||||||
|
|
||||||
|
2.6 Bypass, disable, or circumvent any technical limitation, encryption, security, digital rights
|
||||||
|
management or authentication mechanism in the Software;
|
||||||
|
|
||||||
|
2.7 Use the Software or Derivatives in any manner that would cause them to become subject to an open
|
||||||
|
source software license; subject to the terms in Section 7 (“Components Under Other Licenses”);
|
||||||
|
|
||||||
|
2.8 Use the Software or Derivatives for the purpose of developing competing products or technologies
|
||||||
|
or assist a third party in such activities;
|
||||||
|
|
||||||
|
2.9 Replace any Software components governed by this Agreement with other software that
|
||||||
|
implements NVIDIA APIs;
|
||||||
|
|
||||||
|
2.10 Use the Software or Derivatives in violation of any applicable law or regulation in the relevant
|
||||||
|
jurisdictions; or
|
||||||
|
|
||||||
|
2.11 Use the Software in or with any system or application where the use or failure of such system or
|
||||||
|
application developed or deployed with Software could result in injury, death or catastrophic
|
||||||
|
damage (“Mission Critical Applications”). NVIDIA will not be liable to you or any third party, in whole
|
||||||
|
or in part, for any claims or damages arising from uses in Mission Critical Applications.
|
||||||
|
|
||||||
|
2.12 Disclose any evaluation or test results regarding the Software or Derivatives without NVIDIA’s prior
|
||||||
|
written consent.
|
||||||
|
|
||||||
|
3. Authorized Users. You may allow employees and contractors of your entity or of your subsidiary(ies), and
|
||||||
|
for educational institutions also enrolled students, to internally access and use the Software as authorized
|
||||||
|
by this Agreement from your secure network to perform the work authorized by this Agreement on your
|
||||||
|
behalf. You are responsible for the compliance with the terms of this Agreement by your authorized users.
|
||||||
|
Any act or omission that if committed by you would constitute a breach of this Agreement will be deemed to
|
||||||
|
constitute a breach of this Agreement if committed by your authorized users.
|
||||||
|
|
||||||
|
4. Pre-Release. Software versions identified as alpha, beta, preview, early access or otherwise as pre-release
|
||||||
|
may not be fully functional, may contain errors or design flaws, and may have reduced or different security,
|
||||||
|
privacy, availability and reliability standards relative to NVIDIA commercial offerings. You use pre-release
|
||||||
|
Software at your own risk. NVIDIA did not design or test the Software for use in production or business
|
||||||
|
critical systems. NVIDIA may choose not to make available a commercial version of pre-release Software.
|
||||||
|
NVIDIA may also choose to abandon development and terminate the availability of pre-release Software at
|
||||||
|
any time without liability.
|
||||||
|
|
||||||
|
5. Your Privacy: Collection and Use of Information.
|
||||||
|
|
||||||
|
5.1 Privacy Policy. Please review the NVIDIA Privacy Policy, located at https://www.nvidia.com/enus/about-nvidia/privacy-policy, which explains NVIDIA’s policy for collecting and using data, as well
|
||||||
|
as visit the NVIDIA Privacy Center, located at https://www.nvidia.com/en-us/privacy-center, to
|
||||||
|
manage your consent and privacy preferences.
|
||||||
|
|
||||||
|
5.2 Collection Purposes. You also acknowledge that the Software collects data for the following
|
||||||
|
purposes: (a) properly configure and optimize products for use with Software; and (b) improve
|
||||||
|
NVIDIA products and services. Information collected by the Software includes: (i) application
|
||||||
|
configuration; (ii) browser version; (iii) and session metadata (i.e. performance and usage
|
||||||
|
statistics). Additionally, NVIDIA may collect certain personal information, such as your name
|
||||||
|
and email address or those of your authorized users, and other information necessary to
|
||||||
|
authenticate and enable you or your authorized users’ access to the Software. Where appropriate
|
||||||
|
you will disclose to, and obtain any necessary consent from, your authorized users to allow NVIDIA
|
||||||
|
to collect such information.
|
||||||
|
|
||||||
|
5.3 Third Party Privacy Practices. The Software may contain links to third party websites and services.
|
||||||
|
NVIDIA encourages you to review the privacy statements on those sites and services that you choose
|
||||||
|
to visit to understand how they may collect, use and share your data. NVIDIA is not responsible for
|
||||||
|
the privacy statements or practices of third-party sites or services.
|
||||||
|
|
||||||
|
6. Updates. NVIDIA may at any time and at its option, change, discontinue, or deprecate any part, or all, of the
|
||||||
|
Software, or change or remove features or functionality, or make available patches, workarounds or other
|
||||||
|
updates to the Software. Unless the updates are provided with their separate governing terms, they are
|
||||||
|
deemed part of the Software licensed to you under this Agreement, and your continued use of the Software
|
||||||
|
is deemed acceptance of such changes.
|
||||||
|
|
||||||
|
7. Components Under Other Licenses. The Software may include or be distributed with components provided
|
||||||
|
with separate legal notices or terms that accompany the components, such as open source software licenses
|
||||||
|
and other license terms (“Other Licenses”). The components are subject to the applicable Other Licenses,
|
||||||
|
including any proprietary notices, disclaimers, requirements and extended use rights; except that this
|
||||||
|
Agreement will prevail regarding the use of third-party open source software, unless a third-party open
|
||||||
|
source software license requires its license terms to prevail. Open source software license means any
|
||||||
|
software, data or documentation subject to any license identified as an open source license by the Open
|
||||||
|
Source Initiative (http://opensource.org), Free Software Foundation (http://www.fsf.org) or other similar
|
||||||
|
open source organization or listed by the Software Package Data Exchange (SPDX) Workgroup under the
|
||||||
|
Linux Foundation (http://www.spdx.org).
|
||||||
|
|
||||||
|
8. Ownership.
|
||||||
|
|
||||||
|
8.1 NVIDIA Ownership. The Software, including all intellectual property rights, is and will remain the sole
|
||||||
|
and exclusive property of NVIDIA or its licensors. Except as expressly granted in this Agreement,
|
||||||
|
(a) NVIDIA reserves all rights, interests and remedies in connection with the Software, and (b) no
|
||||||
|
other license or right is granted to you by implication, estoppel or otherwise.
|
||||||
|
|
||||||
|
8.2 Your Ownership. Subject to the rights of NVIDIA and its suppliers in the Software, which continue to
|
||||||
|
be licensed as stated in this Agreement, even when incorporated in your products, and the extent
|
||||||
|
permitted by applicable law, as between you and NVIDIA, you hold all rights, title and interest in and
|
||||||
|
to your services, applications and Derivatives you develop as permitted in this Agreement including
|
||||||
|
their respective intellectual property rights.
|
||||||
|
|
||||||
|
9. Feedback. You may, but are not obligated to, provide suggestions, requests, fixes, modifications,
|
||||||
|
enhancements or other feedback regarding your use of the Software (“Feedback”). Feedback, even if
|
||||||
|
designated as confidential by you, will not create any confidentiality obligation for NVIDIA or its affiliates. If
|
||||||
|
you provide Feedback, you hereby grant NVIDIA, its affiliates and its designees a nonexclusive, perpetual,
|
||||||
|
irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license, under your
|
||||||
|
intellectual property rights, to publicly perform, publicly display, reproduce, use, make, have made, sell,
|
||||||
|
offer for sale, distribute (through multiple tiers of distribution), import, create derivative works of and
|
||||||
|
otherwise commercialize and exploit the Feedback at NVIDIA’s discretion.
|
||||||
|
|
||||||
|
10. Confidentiality. You may use confidential information only to exercise your rights and perform your
|
||||||
|
obligations under this Agreement. You will not disclose, nor authorize others to disclose NVIDIA Confidential
|
||||||
|
Information to any third party, except as expressly authorized in this Agreement and as necessary for the
|
||||||
|
Purpose, without obtaining NVIDIA’s prior written approval. Each recipient of confidential information must
|
||||||
|
be subject to a written agreement that includes confidentiality obligations consistent with these terms and
|
||||||
|
must have a need to know for the Purpose. You will protect the NVIDIA Confidential Information with at
|
||||||
|
least the same degree of care that you use to protect your own similar confidential and proprietary
|
||||||
|
information, but no less than a reasonable degree of care. Confidential information includes, but is not
|
||||||
|
limited to, the Software, including its features and functionality, Derivatives, and any results of
|
||||||
|
benchmarking or other competitive analysis or regression or performance data relating to the Software.
|
||||||
|
No Publicity. You may not issue any public statements about this Agreement, disclose the Software or
|
||||||
|
Derivatives, or any information or results related to your use of the Software, without prior written approval
|
||||||
|
of NVIDIA.
|
||||||
|
|
||||||
|
11. Term and Termination.
|
||||||
|
|
||||||
|
11.1 Term. This Agreement has a duration of twelve (12) months starting from the date of initial
|
||||||
|
download (even if you download the same version or updates of the Software later and it is
|
||||||
|
accompanied by this Agreement or another Agreement), unless terminated earlier in accordance
|
||||||
|
with this Agreement.
|
||||||
|
|
||||||
|
11.2 Termination for Convenience. Either party may terminate this Agreement at any time with thirty (30)
|
||||||
|
days’ advance written notice to the other party.
|
||||||
|
|
||||||
|
11.3 Termination for Cause. If you commence or participate in any legal proceeding against NVIDIA with
|
||||||
|
respect to the Software, this Agreement will terminate immediately without notice. Either party may
|
||||||
|
terminate this Agreement upon notice for cause if:
|
||||||
|
(a) the other party fails to cure a material breach of this Agreement within ten (10) days of the
|
||||||
|
non-breaching party’s notice of the breach; or
|
||||||
|
(b) the other party breaches its confidentiality obligations or license rights under this
|
||||||
|
Agreement, which termination will be effective immediately upon written notice.
|
||||||
|
|
||||||
|
11.4 Effect of Termination. Upon any expiration or termination of this Agreement, you will promptly
|
||||||
|
(a) stop using and return, delete or destroy NVIDIA confidential information and all Software
|
||||||
|
received under this Agreement, and (b) delete or destroy Derivatives created under this Agreement,
|
||||||
|
unless an authorized NVIDIA representative provides prior written approval that you may keep a
|
||||||
|
copy of the Derivatives solely for archival purposes. Upon written request, you will certify in writing
|
||||||
|
that you have complied with your obligations under this “Effect of Termination” Section.
|
||||||
|
|
||||||
|
11.5 Survival. The “License Grant to NVIDIA”, “Updates”, “Components Under Other Licenses”,
|
||||||
|
“Ownership”, “Feedback”, “Confidentiality”, “No Publicity”, “Effect of Termination”, “Survival”,
|
||||||
|
“Disclaimer of Warranties”, “Limitation of Liability”, “Indemnity” and all “General” Sections of this
|
||||||
|
Agreement will survive any expiration or termination of this Agreement.
|
||||||
|
|
||||||
|
12. Disclaimer of Warranties. THE SOFTWARE IS PROVIDED BY NVIDIA AS-IS AND WITH ALL FAULTS. TO THE
|
||||||
|
MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NVIDIA DISCLAIMS ALL WARRANTIES AND
|
||||||
|
REPRESENTATIONS OF ANY KIND, WHETHER EXPRESS, IMPLIED OR STATUTORY, RELATING TO OR ARISING
|
||||||
|
UNDER THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF TITLE,
|
||||||
|
NONINFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, USAGE OF TRADE AND
|
||||||
|
COURSE OF DEALING. NVIDIA DOES NOT WARRANT OR ASSUME RESPONSIBILITY FOR THE ACCURACY OR
|
||||||
|
COMPLETENESS OF ANY THIRD-PARTY INFORMATION, TEXT, GRAPHICS, LINKS CONTAINED IN THE
|
||||||
|
SOFTWARE. WITHOUT LIMITING THE FOREGOING, NVIDIA DOES NOT WARRANT THAT THE SOFTWARE WILL
|
||||||
|
MEET YOUR REQUIREMENTS, ANY DEFECTS OR ERRORS WILL BE CORRECTED, ANY CERTAIN CONTENT WILL
|
||||||
|
BE AVAILABLE; OR THAT THE SOFTWARE IS FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS. NO
|
||||||
|
INFORMATION OR ADVICE GIVEN BY NVIDIA WILL IN ANY WAY INCREASE THE SCOPE OF ANY WARRANTY
|
||||||
|
EXPRESSLY PROVIDED IN THIS AGREEMENT. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE
|
||||||
|
APPROPRIATENESS OF USING THE SOFTWARE OR DERIVATIVES AND ASSUME ANY RISKS ASSOCIATED WITH
|
||||||
|
YOUR USE OF THE SOFTWARE OR DERIVATIVES.
|
||||||
|
|
||||||
|
13. Limitations of Liability.
|
||||||
|
|
||||||
|
13.1 EXCLUSIONS. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
|
||||||
|
NVIDIA BE LIABLE FOR ANY (A) INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES, OR (B) DAMAGES FOR THE (I) COST OF PROCURING SUBSTITUTE GOODS OR (II) LOSS OF
|
||||||
|
PROFITS, REVENUES, USE, DATA OR GOODWILL ARISING OUT OF OR RELATED TO THIS AGREEMENT,
|
||||||
|
WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR
|
||||||
|
OTHERWISE, AND EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND
|
||||||
|
EVEN IF A PARTY’S REMEDIES FAIL THEIR ESSENTIAL PURPOSE.
|
||||||
|
|
||||||
|
13.2 DAMAGES CAP. ADDITIONALLY, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
|
||||||
|
NVIDIA’S TOTAL CUMULATIVE AGGREGATE LIABILITY FOR ANY AND ALL LIABILITIES, OBLIGATIONS OR
|
||||||
|
CLAIMS ARISING OUT OF OR RELATED TO THIS AGREEMENT WILL NOT EXCEED ONE HUNDRED U.S.
|
||||||
|
DOLLARS (US$100).
|
||||||
|
|
||||||
|
14. Indemnity. You will defend, indemnify and hold harmless NVIDIA and its affiliates, and their respective
|
||||||
|
employees, contractors, agents, officers and directors, from and against any and all third party claims,
|
||||||
|
damages, obligations, losses, liabilities, costs or debt, fines, restitutions and expenses (including but not
|
||||||
|
limited to attorney’s fees and costs incident to establishing the right of indemnification) arising out of use of
|
||||||
|
the Software and Derivatives outside of the scope of this Agreement or in breach of the terms of this
|
||||||
|
Agreement.
|
||||||
|
|
||||||
|
15. General.
|
||||||
|
|
||||||
|
15.1 Governing Law and Jurisdiction. This Agreement will be governed in all respects by the laws of the
|
||||||
|
United States and the laws of the State of Delaware, without regard to conflict of laws principles or
|
||||||
|
the United Nations Convention on Contracts for the International Sale of Goods. The state and
|
||||||
|
federal courts residing in Santa Clara County, California will have exclusive jurisdiction over any
|
||||||
|
dispute or claim arising out of or related to this Agreement, and the parties irrevocably consent to
|
||||||
|
personal jurisdiction and venue in those courts; except that either party may apply for injunctive
|
||||||
|
remedies or an equivalent type of urgent legal relief in any jurisdiction.
|
||||||
|
|
||||||
|
15.2 Independent Contractors. The parties are independent contractors, and this Agreement does not
|
||||||
|
create a joint venture, partnership, agency or other form of business association between the
|
||||||
|
parties. Neither party will have the power to bind the other party or incur any obligation on its
|
||||||
|
behalf without the other party’s prior written consent. Nothing in this Agreement prevents either
|
||||||
|
party from participating in similar arrangements with third parties.
|
||||||
|
|
||||||
|
15.3 No Assignment. NVIDIA may assign, delegate or transfer its rights or obligations under this
|
||||||
|
Agreement by any means or operation of law. You may not, without NVIDIA’s prior written consent,
|
||||||
|
assign, delegate or transfer any of your rights or obligations under this Agreement by any means or
|
||||||
|
operation of law, and any attempt to do so is null and void.
|
||||||
|
|
||||||
|
15.4 No Waiver. No failure or delay by a party to enforce any term or obligation of this Agreement will
|
||||||
|
operate as a waiver by that party, or prevent the enforcement of such term or obligation later.
|
||||||
|
|
||||||
|
15.5 Trade Compliance. You agree to comply with all applicable export, import, trade and economic
|
||||||
|
sanctions laws and regulations, as amended, including without limitation U.S. Export Administration
|
||||||
|
Regulations and Office of Foreign Assets Control regulations. You confirm (a) your understanding
|
||||||
|
that export or reexport of certain NVIDIA products or technologies may require a license or other
|
||||||
|
approval from appropriate authorities and (b) that you will not export or reexport any products or
|
||||||
|
technology, directly or indirectly, without first obtaining any required license or other approval from
|
||||||
|
appropriate authorities, (i) to any countries that are subject to any U.S. or local export restrictions
|
||||||
|
(currently including, but not necessarily limited to, Belarus, Cuba, Iran, North Korea, Russia, Syria,
|
||||||
|
the Region of Crimea, Donetsk People’s Republic Region and Luhansk People’s Republic Region); (ii)
|
||||||
|
to any end-user who you know or have reason to know will utilize them in the design, development
|
||||||
|
or production of nuclear, chemical or biological weapons, missiles, rocket systems, unmanned air
|
||||||
|
vehicles capable of a maximum range of at least 300 kilometers, regardless of payload, or intended
|
||||||
|
for military end-use, or any weapons of mass destruction; (iii) to any end-user who has been
|
||||||
|
prohibited from participating in the U.S. or local export transactions by any governing authority; or
|
||||||
|
(iv) to any known military or military-intelligence end-user or for any known military or military-
|
||||||
|
intelligence end-use in accordance with U.S. trade compliance laws and regulations.
|
||||||
|
|
||||||
|
15.6 Government Rights. The Software, documentation and technology (“Protected Items”) are
|
||||||
|
“Commercial products” as this term is defined at 48 C.F.R. 2.101, consisting of “commercial
|
||||||
|
computer software” and “commercial computer software documentation” as such terms are used
|
||||||
|
in, respectively, 48 C.F.R. 12.212 and 48 C.F.R. 227.7202 & 252.227-7014(a)(1). Before any Protected
|
||||||
|
Items are supplied to the U.S. Government, you will (i) inform the U.S. Government in writing that
|
||||||
|
the Protected Items are and must be treated as commercial computer software and commercial
|
||||||
|
computer software documentation developed at private expense; (ii) inform the U.S. Government
|
||||||
|
that the Protected Items are provided subject to the terms of the Agreement; and (iii) mark the
|
||||||
|
Protected Items as commercial computer software and commercial computer software
|
||||||
|
documentation developed at private expense. In no event will you permit the U.S. Government to
|
||||||
|
acquire rights in Protected Items beyond those specified in 48 C.F.R. 52.227-19(b)(1)-(2) or 252.227-
|
||||||
|
7013(c) except as expressly approved by NVIDIA in writing.
|
||||||
|
|
||||||
|
15.7 Notices. Please direct your legal notices or other correspondence to legalnotices@nvidia.com with a
|
||||||
|
copy mailed to NVIDIA Corporation, 2788 San Tomas Expressway, Santa Clara, California 95051,
|
||||||
|
United States of America, Attention: Legal Department. If NVIDIA needs to contact you about the
|
||||||
|
Software, you consent to receive the notices by email and agree that such notices will satisfy any
|
||||||
|
legal communication requirements.
|
||||||
|
|
||||||
|
15.8 Severability. If a court of competent jurisdiction rules that a provision of this Agreement is
|
||||||
|
unenforceable, that provision will be deemed modified to the extent necessary to make it
|
||||||
|
enforceable and the remainder of this Agreement will continue in full force and effect.
|
||||||
|
|
||||||
|
15.9 Amendment. Any amendment to this Agreement must be in writing and signed by authorized
|
||||||
|
representatives of both parties.
|
||||||
|
|
||||||
|
15.10 Entire Agreement. Regarding the subject matter of this Agreement, the parties agree that (a) this
|
||||||
|
Agreement constitutes the entire and exclusive agreement between the parties and supersedes all
|
||||||
|
prior and contemporaneous communications and (b) any additional or different terms or conditions,
|
||||||
|
whether contained in purchase orders, order acknowledgments, invoices or otherwise, will not be
|
||||||
|
binding and are null and void.
|
||||||
|
|
||||||
|
(v. February 25, 2025)
|
||||||
|
|
||||||
|
NVIDIA Confidential
|
||||||
BIN
deps/cloudxr/docs/media/accept-cert.png
vendored
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
deps/cloudxr/docs/media/accept-proxy-cert.png
vendored
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
deps/cloudxr/docs/media/cloudxr_viewport.jpg
vendored
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
deps/cloudxr/docs/media/iwer-buttons.png
vendored
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
deps/cloudxr/docs/media/iwer-message.png
vendored
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
deps/cloudxr/docs/media/ov-ar-panel.png
vendored
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
deps/cloudxr/docs/media/react-isaac-sample-controls-countdown.jpg
vendored
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
deps/cloudxr/docs/media/react-isaac-sample-controls-running.jpg
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
deps/cloudxr/docs/media/react-isaac-sample-controls-start.jpg
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
deps/cloudxr/docs/media/startar.png
vendored
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
1
deps/cloudxr/docs/modules.html
vendored
Normal file
1
deps/cloudxr/docs/modules/CloudXR.html
vendored
Normal file
125
deps/cloudxr/helpers/BrowserCapabilities.ts
vendored
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
interface CapabilityCheck {
|
||||||
|
name: string;
|
||||||
|
required: boolean;
|
||||||
|
check: () => boolean | Promise<boolean>;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const capabilities: CapabilityCheck[] = [
|
||||||
|
{
|
||||||
|
name: 'WebGL2',
|
||||||
|
required: true,
|
||||||
|
check: () => {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const gl = canvas.getContext('webgl2');
|
||||||
|
return gl !== null;
|
||||||
|
},
|
||||||
|
message: 'WebGL2 is required for rendering',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'WebXR',
|
||||||
|
required: true,
|
||||||
|
check: () => {
|
||||||
|
return 'xr' in navigator;
|
||||||
|
},
|
||||||
|
message: 'WebXR is required for VR/AR functionality',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'RTCPeerConnection',
|
||||||
|
required: true,
|
||||||
|
check: () => {
|
||||||
|
return 'RTCPeerConnection' in window;
|
||||||
|
},
|
||||||
|
message: 'RTCPeerConnection is required for WebRTC streaming',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'requestVideoFrameCallback',
|
||||||
|
required: true,
|
||||||
|
check: () => {
|
||||||
|
const video = document.createElement('video');
|
||||||
|
return typeof video.requestVideoFrameCallback === 'function';
|
||||||
|
},
|
||||||
|
message: 'HTMLVideoElement.requestVideoFrameCallback is required for video frame processing',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Canvas.captureStream',
|
||||||
|
required: true,
|
||||||
|
check: () => {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
return typeof canvas.captureStream === 'function';
|
||||||
|
},
|
||||||
|
message: 'Canvas.captureStream is required for video streaming',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'AV1 Codec Support',
|
||||||
|
required: false,
|
||||||
|
check: async () => {
|
||||||
|
try {
|
||||||
|
// Check if MediaCapabilities API is available
|
||||||
|
if (!navigator.mediaCapabilities) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check MediaCapabilities for AV1 decoding support
|
||||||
|
const config = {
|
||||||
|
type: 'webrtc' as MediaDecodingType,
|
||||||
|
video: {
|
||||||
|
contentType: 'video/av1',
|
||||||
|
width: 1920,
|
||||||
|
height: 1080,
|
||||||
|
framerate: 60,
|
||||||
|
bitrate: 15000000, // 15 Mbps
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await navigator.mediaCapabilities.decodingInfo(config);
|
||||||
|
return result.supported;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error checking AV1 support:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
message: 'AV1 codec support is recommended for optimal streaming quality',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export async function checkCapabilities(): Promise<{
|
||||||
|
success: boolean;
|
||||||
|
failures: string[];
|
||||||
|
warnings: string[];
|
||||||
|
}> {
|
||||||
|
const failures: string[] = [];
|
||||||
|
const warnings: string[] = [];
|
||||||
|
const requiredFailures: string[] = [];
|
||||||
|
|
||||||
|
for (const capability of capabilities) {
|
||||||
|
try {
|
||||||
|
const result = await Promise.resolve(capability.check());
|
||||||
|
if (!result) {
|
||||||
|
if (capability.required) {
|
||||||
|
requiredFailures.push(capability.message);
|
||||||
|
console.error(`Required capability missing: ${capability.message}`);
|
||||||
|
} else {
|
||||||
|
warnings.push(capability.message);
|
||||||
|
console.warn(`Optional capability missing: ${capability.message}`);
|
||||||
|
}
|
||||||
|
failures.push(capability.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (capability.required) {
|
||||||
|
requiredFailures.push(capability.message);
|
||||||
|
console.error(`Error checking required capability ${capability.name}:`, error);
|
||||||
|
} else {
|
||||||
|
warnings.push(capability.message);
|
||||||
|
console.warn(`Error checking optional capability ${capability.name}:`, error);
|
||||||
|
}
|
||||||
|
failures.push(capability.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: requiredFailures.length === 0,
|
||||||
|
failures,
|
||||||
|
warnings,
|
||||||
|
};
|
||||||
|
}
|
||||||
98
deps/cloudxr/helpers/LoadIWER.ts
vendored
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
const IWER_version = '2.1.1';
|
||||||
|
const IWER_DEVUI_version = '1.1.2';
|
||||||
|
|
||||||
|
export interface IWERLoadResult {
|
||||||
|
supportsImmersive: boolean;
|
||||||
|
iwerLoaded: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadIWERIfNeeded(): Promise<IWERLoadResult> {
|
||||||
|
let supportsImmersive = false;
|
||||||
|
let iwerLoaded = false;
|
||||||
|
|
||||||
|
if ('xr' in navigator) {
|
||||||
|
try {
|
||||||
|
const vr = await (navigator.xr as XRSystem).isSessionSupported?.('immersive-vr');
|
||||||
|
const ar = await (navigator.xr as XRSystem).isSessionSupported?.('immersive-ar');
|
||||||
|
supportsImmersive = Boolean(vr || ar);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!supportsImmersive) {
|
||||||
|
console.info('Immersive mode not supported, loading IWER as fallback.');
|
||||||
|
|
||||||
|
// Load IWER first
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = `https://unpkg.com/iwer@${IWER_version}/build/iwer.min.js`;
|
||||||
|
script.async = true;
|
||||||
|
script.integrity = 'sha384-ZOdYbNlfA4q9jkBGcdmjy2ZYmjxy2uzncU6it3cPOHi12/WF048bamSU0Z5N+V5u';
|
||||||
|
script.crossOrigin = 'anonymous';
|
||||||
|
|
||||||
|
await new Promise<void>(resolve => {
|
||||||
|
script.onload = async () => {
|
||||||
|
console.info('IWER loaded as fallback.');
|
||||||
|
const IWERGlobal = (window as any).IWER || (globalThis as any).IWER;
|
||||||
|
if (!IWERGlobal) {
|
||||||
|
console.warn('IWER global not found after script load.');
|
||||||
|
supportsImmersive = false;
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load iwer-devui after IWER
|
||||||
|
const devUIScript = document.createElement('script');
|
||||||
|
devUIScript.src = `https://unpkg.com/@iwer/devui@${IWER_DEVUI_version}/build/iwer-devui.min.js`;
|
||||||
|
devUIScript.async = true;
|
||||||
|
devUIScript.integrity =
|
||||||
|
'sha384-CG/gISX6PadiSzc8i2paU7CYLVsnVJaJ0tgoVnAPq/gyiTX6bddG5rwOgMDGlq74';
|
||||||
|
devUIScript.crossOrigin = 'anonymous';
|
||||||
|
|
||||||
|
await new Promise<void>(devUIResolve => {
|
||||||
|
devUIScript.onload = () => {
|
||||||
|
console.info('IWER DevUI loaded.');
|
||||||
|
devUIResolve();
|
||||||
|
};
|
||||||
|
devUIScript.onerror = error => {
|
||||||
|
console.warn('Failed to load IWER DevUI:', error);
|
||||||
|
devUIResolve();
|
||||||
|
};
|
||||||
|
document.head.appendChild(devUIScript);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Create XRDevice with Meta Quest 3 profile
|
||||||
|
const xrDevice = new IWERGlobal.XRDevice(IWERGlobal.metaQuest3);
|
||||||
|
|
||||||
|
// Initialize DevUI with the XR device
|
||||||
|
const IWER_DevUI = (window as any).IWER_DevUI || (globalThis as any).IWER_DevUI;
|
||||||
|
if (IWER_DevUI?.DevUI) {
|
||||||
|
xrDevice.installDevUI(IWER_DevUI.DevUI);
|
||||||
|
console.info('IWER DevUI initialized with XR device.');
|
||||||
|
} else {
|
||||||
|
console.warn('IWER DevUI not found after script load, continuing without DevUI.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install the runtime and wait for it to be ready
|
||||||
|
const maybePromise = xrDevice.installRuntime?.();
|
||||||
|
if (maybePromise && typeof maybePromise.then === 'function') {
|
||||||
|
await maybePromise;
|
||||||
|
}
|
||||||
|
supportsImmersive = true;
|
||||||
|
iwerLoaded = true;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('IWER runtime install failed:', e);
|
||||||
|
supportsImmersive = false;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
script.onerror = () => {
|
||||||
|
console.warn('Failed to load IWER.');
|
||||||
|
supportsImmersive = false;
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { supportsImmersive, iwerLoaded };
|
||||||
|
}
|
||||||
2685
deps/cloudxr/helpers/WebGLState.ts
vendored
Normal file
1220
deps/cloudxr/helpers/WebGLStateApply.ts
vendored
Normal file
286
deps/cloudxr/helpers/WebGLStateBinding.ts
vendored
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
import { WebGLStateTracker, WebGLState } from './WebGLState';
|
||||||
|
import { apply } from './WebGLStateApply';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BoundWebGLState - A WebGL2 context with automatic state tracking
|
||||||
|
*
|
||||||
|
* This is the original WebGL2 context with state-changing functions rebound
|
||||||
|
* to call the tracker before forwarding to the original implementation.
|
||||||
|
*/
|
||||||
|
export class BoundWebGLState {
|
||||||
|
private gl: WebGL2RenderingContext;
|
||||||
|
private tracker: WebGLStateTracker;
|
||||||
|
private originalFunctions: Map<string, Function>;
|
||||||
|
private savedState?: WebGLState;
|
||||||
|
private trackingEnabled = true;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
gl: WebGL2RenderingContext,
|
||||||
|
tracker: WebGLStateTracker,
|
||||||
|
originalFunctions: Map<string, Function>
|
||||||
|
) {
|
||||||
|
this.gl = gl;
|
||||||
|
this.tracker = tracker;
|
||||||
|
this.originalFunctions = originalFunctions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the internal state tracker
|
||||||
|
*/
|
||||||
|
private getTracker(): WebGLStateTracker {
|
||||||
|
return this.tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the current tracked WebGL state
|
||||||
|
* This clones the state so it can be restored later
|
||||||
|
*/
|
||||||
|
save(): void {
|
||||||
|
this.savedState = this.tracker.getState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the previously saved WebGL state
|
||||||
|
* This applies the saved state back to the WebGL context
|
||||||
|
* @throws {Error} If no state has been saved
|
||||||
|
*/
|
||||||
|
restore(): void {
|
||||||
|
if (!this.savedState) {
|
||||||
|
throw new Error('No state has been saved. Call save() before restore().');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the current tracking state and enable tracking during restore
|
||||||
|
// This ensures the tracker stays synchronized with actual GL state
|
||||||
|
const wasTrackingEnabled = this.trackingEnabled;
|
||||||
|
this.trackingEnabled = true;
|
||||||
|
|
||||||
|
const currentState = this.tracker.getState();
|
||||||
|
apply(this.gl, this.savedState, currentState);
|
||||||
|
|
||||||
|
// Restore the original tracking state
|
||||||
|
this.trackingEnabled = wasTrackingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
enableTracking(enable: boolean): void {
|
||||||
|
this.trackingEnabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
_enabled(): boolean {
|
||||||
|
return this.trackingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revert all tracked functions back to their original implementations
|
||||||
|
* This removes state tracking from the WebGL context
|
||||||
|
*/
|
||||||
|
revert(): void {
|
||||||
|
const glAny = this.gl as any;
|
||||||
|
|
||||||
|
for (const [name, originalFunction] of this.originalFunctions.entries()) {
|
||||||
|
glAny[name] = originalFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the map
|
||||||
|
this.originalFunctions.clear();
|
||||||
|
|
||||||
|
// Remove the stored BoundWebGLState from the GL context
|
||||||
|
delete glAny.__cloudxrBoundState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind a WebGL2 context with automatic state tracking
|
||||||
|
*
|
||||||
|
* Rebinds state-changing methods on the WebGL context to automatically track
|
||||||
|
* state changes before forwarding to the original implementation.
|
||||||
|
*
|
||||||
|
* @param gl - The WebGL2RenderingContext to wrap
|
||||||
|
* @returns A BoundWebGLState instance that provides access to the tracker and revert functionality
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const canvas = document.getElementById('canvas') as HTMLCanvasElement;
|
||||||
|
* const gl = canvas.getContext('webgl2')!;
|
||||||
|
* const binding = bindGL(gl);
|
||||||
|
*
|
||||||
|
* // Use gl like a normal WebGL context - it's now tracked
|
||||||
|
* gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||||
|
* gl.bindVertexArray(vao);
|
||||||
|
*
|
||||||
|
* // Save the current state
|
||||||
|
* binding.save();
|
||||||
|
*
|
||||||
|
* // Make some temporary changes
|
||||||
|
* gl.bindBuffer(gl.ARRAY_BUFFER, tempBuffer);
|
||||||
|
* gl.enable(gl.BLEND);
|
||||||
|
*
|
||||||
|
* // Restore the saved state
|
||||||
|
* binding.restore();
|
||||||
|
*
|
||||||
|
* // Access tracked state
|
||||||
|
* const state = binding.getTracker().getState();
|
||||||
|
* console.log(state.buffers?.arrayBuffer); // The bound buffer
|
||||||
|
*
|
||||||
|
* // When done, revert to stop tracking
|
||||||
|
* binding.revert();
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function bindGL(gl: WebGL2RenderingContext): BoundWebGLState {
|
||||||
|
const glAny = gl as any;
|
||||||
|
|
||||||
|
// Check if this GL context is already wrapped - prevent double-wrapping
|
||||||
|
if (glAny.__cloudxrBoundState) {
|
||||||
|
console.warn(
|
||||||
|
'WebGL context is already wrapped with state tracking. Returning existing BoundWebGLState.'
|
||||||
|
);
|
||||||
|
return glAny.__cloudxrBoundState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the tracker
|
||||||
|
const tracker = new WebGLStateTracker();
|
||||||
|
|
||||||
|
// Store original functions for later reversion
|
||||||
|
const originalFunctions = new Map<string, Function>();
|
||||||
|
const wrappedFunctions = new Map<string, Function>();
|
||||||
|
|
||||||
|
const state = new BoundWebGLState(gl, tracker, originalFunctions);
|
||||||
|
|
||||||
|
// Store the BoundWebGLState on the GL context to prevent double-wrapping
|
||||||
|
glAny.__cloudxrBoundState = state;
|
||||||
|
|
||||||
|
// Helper function to bind a method
|
||||||
|
const bind = (name: string, trackerMethod: Function) => {
|
||||||
|
// CRITICAL: Store the original BEFORE we replace it, otherwise we'll store the wrapper
|
||||||
|
const originalMethod = glAny[name];
|
||||||
|
if (!originalMethod) {
|
||||||
|
throw new Error('Original method not found for ' + name);
|
||||||
|
}
|
||||||
|
if (originalMethod === wrappedFunctions.get(name)) {
|
||||||
|
throw new Error('Wrapped function already bound for ' + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const original = originalMethod.bind(gl);
|
||||||
|
originalFunctions.set(name, original);
|
||||||
|
const wrappedFunction = (...args: any[]) => {
|
||||||
|
if (state._enabled()) {
|
||||||
|
trackerMethod.apply(tracker, args);
|
||||||
|
}
|
||||||
|
return original(...args);
|
||||||
|
};
|
||||||
|
wrappedFunctions.set(name, wrappedFunction);
|
||||||
|
|
||||||
|
glAny[name] = wrappedFunction;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Buffer bindings
|
||||||
|
bind('bindBuffer', tracker.bindBuffer);
|
||||||
|
bind('bindBufferBase', tracker.bindBufferBase);
|
||||||
|
bind('bindBufferRange', tracker.bindBufferRange);
|
||||||
|
|
||||||
|
// Buffer lifecycle tracking (for validation without GPU calls)
|
||||||
|
const originalCreateBuffer = glAny.createBuffer.bind(gl);
|
||||||
|
originalFunctions.set('createBuffer', originalCreateBuffer);
|
||||||
|
glAny.createBuffer = (): WebGLBuffer | null => {
|
||||||
|
const buffer = originalCreateBuffer();
|
||||||
|
if (buffer) {
|
||||||
|
tracker.createBuffer(buffer);
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
};
|
||||||
|
bind('deleteBuffer', tracker.deleteBuffer);
|
||||||
|
|
||||||
|
// VAO and vertex attributes
|
||||||
|
bind('bindVertexArray', tracker.bindVertexArray);
|
||||||
|
bind('deleteVertexArray', tracker.deleteVertexArray);
|
||||||
|
bind('enableVertexAttribArray', tracker.enableVertexAttribArray);
|
||||||
|
bind('disableVertexAttribArray', tracker.disableVertexAttribArray);
|
||||||
|
bind('vertexAttribPointer', tracker.vertexAttribPointer);
|
||||||
|
bind('vertexAttribIPointer', tracker.vertexAttribIPointer);
|
||||||
|
bind('vertexAttribDivisor', tracker.vertexAttribDivisor);
|
||||||
|
|
||||||
|
// Texture bindings
|
||||||
|
bind('activeTexture', tracker.activeTexture);
|
||||||
|
bind('bindTexture', tracker.bindTexture);
|
||||||
|
|
||||||
|
// Program binding
|
||||||
|
bind('useProgram', tracker.useProgram);
|
||||||
|
|
||||||
|
// Framebuffer bindings
|
||||||
|
bind('bindFramebuffer', tracker.bindFramebuffer);
|
||||||
|
bind('framebufferTexture2D', tracker.framebufferTexture2D);
|
||||||
|
bind('framebufferRenderbuffer', tracker.framebufferRenderbuffer);
|
||||||
|
bind('framebufferTextureLayer', tracker.framebufferTextureLayer);
|
||||||
|
bind('drawBuffers', tracker.drawBuffers);
|
||||||
|
bind('readBuffer', tracker.readBuffer);
|
||||||
|
|
||||||
|
// Renderbuffer binding
|
||||||
|
bind('bindRenderbuffer', tracker.bindRenderbuffer);
|
||||||
|
|
||||||
|
// Transform feedback
|
||||||
|
bind('bindTransformFeedback', tracker.bindTransformFeedback);
|
||||||
|
bind('beginTransformFeedback', tracker.beginTransformFeedback);
|
||||||
|
bind('endTransformFeedback', tracker.endTransformFeedback);
|
||||||
|
bind('pauseTransformFeedback', tracker.pauseTransformFeedback);
|
||||||
|
bind('resumeTransformFeedback', tracker.resumeTransformFeedback);
|
||||||
|
|
||||||
|
// Capabilities (enable/disable)
|
||||||
|
bind('enable', tracker.enable);
|
||||||
|
bind('disable', tracker.disable);
|
||||||
|
|
||||||
|
// Viewport and scissor
|
||||||
|
bind('viewport', tracker.viewport);
|
||||||
|
bind('scissor', tracker.scissor);
|
||||||
|
|
||||||
|
// Clear values
|
||||||
|
bind('clearColor', tracker.clearColor);
|
||||||
|
bind('clearDepth', tracker.clearDepth);
|
||||||
|
bind('clearStencil', tracker.clearStencil);
|
||||||
|
|
||||||
|
// Blend state
|
||||||
|
bind('blendColor', tracker.blendColor);
|
||||||
|
bind('blendEquation', tracker.blendEquation);
|
||||||
|
bind('blendEquationSeparate', tracker.blendEquationSeparate);
|
||||||
|
bind('blendFunc', tracker.blendFunc);
|
||||||
|
bind('blendFuncSeparate', tracker.blendFuncSeparate);
|
||||||
|
|
||||||
|
// Depth state
|
||||||
|
bind('depthFunc', tracker.depthFunc);
|
||||||
|
bind('depthMask', tracker.depthMask);
|
||||||
|
bind('depthRange', tracker.depthRange);
|
||||||
|
|
||||||
|
// Stencil state
|
||||||
|
bind('stencilFunc', tracker.stencilFunc);
|
||||||
|
bind('stencilFuncSeparate', tracker.stencilFuncSeparate);
|
||||||
|
bind('stencilMask', tracker.stencilMask);
|
||||||
|
bind('stencilMaskSeparate', tracker.stencilMaskSeparate);
|
||||||
|
bind('stencilOp', tracker.stencilOp);
|
||||||
|
bind('stencilOpSeparate', tracker.stencilOpSeparate);
|
||||||
|
|
||||||
|
// Color mask
|
||||||
|
bind('colorMask', tracker.colorMask);
|
||||||
|
|
||||||
|
// Culling and face orientation
|
||||||
|
bind('cullFace', tracker.cullFace);
|
||||||
|
bind('frontFace', tracker.frontFace);
|
||||||
|
|
||||||
|
// Line width
|
||||||
|
bind('lineWidth', tracker.lineWidth);
|
||||||
|
|
||||||
|
// Polygon offset
|
||||||
|
bind('polygonOffset', tracker.polygonOffset);
|
||||||
|
|
||||||
|
// Sample coverage
|
||||||
|
bind('sampleCoverage', tracker.sampleCoverage);
|
||||||
|
|
||||||
|
// Pixel store parameters
|
||||||
|
bind('pixelStorei', tracker.pixelStorei);
|
||||||
|
|
||||||
|
// Sampler binding
|
||||||
|
bind('bindSampler', tracker.bindSampler);
|
||||||
|
|
||||||
|
// Query operations
|
||||||
|
bind('beginQuery', tracker.beginQuery);
|
||||||
|
bind('endQuery', tracker.endQuery);
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
54
deps/cloudxr/helpers/WebGlUtils.ts
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
export function getOrCreateCanvas(
|
||||||
|
id: string,
|
||||||
|
resolution?: { width: number; height: number }
|
||||||
|
): HTMLCanvasElement {
|
||||||
|
let canvas = document.getElementById(id) as HTMLCanvasElement | null;
|
||||||
|
if (!canvas) {
|
||||||
|
canvas = document.createElement('canvas') as HTMLCanvasElement;
|
||||||
|
canvas.id = id;
|
||||||
|
// canvas.style.display = "none";
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
}
|
||||||
|
if (!canvas) {
|
||||||
|
throw new Error('Failed to create canvas');
|
||||||
|
}
|
||||||
|
if (resolution) {
|
||||||
|
canvas.width = resolution.width;
|
||||||
|
canvas.height = resolution.height;
|
||||||
|
}
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function logOrThrow(tagString: string, gl: WebGL2RenderingContext) {
|
||||||
|
const err = gl.getError();
|
||||||
|
if (err !== gl.NO_ERROR) {
|
||||||
|
let errorString;
|
||||||
|
switch (err) {
|
||||||
|
case gl.INVALID_ENUM:
|
||||||
|
errorString = 'INVALID_ENUM';
|
||||||
|
break;
|
||||||
|
case gl.INVALID_VALUE:
|
||||||
|
errorString = 'INVALID_VALUE';
|
||||||
|
break;
|
||||||
|
case gl.INVALID_OPERATION:
|
||||||
|
errorString = 'INVALID_OPERATION';
|
||||||
|
break;
|
||||||
|
case gl.INVALID_FRAMEBUFFER_OPERATION:
|
||||||
|
errorString = 'INVALID_FRAMEBUFFER_OPERATION';
|
||||||
|
break;
|
||||||
|
case gl.OUT_OF_MEMORY:
|
||||||
|
errorString = 'OUT_OF_MEMORY';
|
||||||
|
break;
|
||||||
|
case gl.CONTEXT_LOST_WEBGL:
|
||||||
|
errorString = 'CONTEXT_LOST_WEBGL';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errorString = 'UNKNOWN_ERROR';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('WebGL error: ' + tagString + ': ' + errorString + ' (' + err + ')');
|
||||||
|
} else {
|
||||||
|
console.debug('WebGL no-error: ' + tagString);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
deps/cloudxr/helpers/overridePressureObserver.ts
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Override PressureObserver to catch errors from unexpected browser implementations.
|
||||||
|
*
|
||||||
|
* Some browsers have buggy PressureObserver implementations that throw errors
|
||||||
|
* when observe() is called. This wrapper catches and logs those errors instead
|
||||||
|
* of letting them propagate.
|
||||||
|
*
|
||||||
|
* This should be called early in your application, before any code attempts
|
||||||
|
* to use PressureObserver.
|
||||||
|
*/
|
||||||
|
export function overridePressureObserver(): void {
|
||||||
|
if (typeof window === 'undefined' || !(window as any).PressureObserver) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const OriginalPressureObserver = (window as any).PressureObserver;
|
||||||
|
|
||||||
|
(window as any).PressureObserver = class PressureObserver extends OriginalPressureObserver {
|
||||||
|
observe(source: any) {
|
||||||
|
try {
|
||||||
|
const result = super.observe(source);
|
||||||
|
if (result && typeof result.catch === 'function') {
|
||||||
|
return result.catch((e: Error) => {
|
||||||
|
console.warn('PressureObserver.observe() failed:', e.message);
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.warn('PressureObserver.observe() failed:', e.message);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
293
deps/cloudxr/helpers/utils.ts
vendored
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
/**
|
||||||
|
* Parses URL parameters and returns them as an object
|
||||||
|
* @param location - Optional location object (defaults to window.location)
|
||||||
|
* @returns Object with URL parameters as key-value pairs
|
||||||
|
*/
|
||||||
|
export function getUrlParams(location: Location = window.location): Record<string, string> {
|
||||||
|
const params: Record<string, string> = {};
|
||||||
|
const queryString = location.search.substring(1);
|
||||||
|
|
||||||
|
if (queryString) {
|
||||||
|
const pairs = queryString.split('&');
|
||||||
|
for (const pair of pairs) {
|
||||||
|
const [key, value = ''] = pair.split('=');
|
||||||
|
params[decodeURIComponent(key)] = decodeURIComponent(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables localStorage functionality for form elements
|
||||||
|
* @param element - The HTML input or select element to enable localStorage for
|
||||||
|
* @param key - The localStorage key to use for saving/loading the value
|
||||||
|
*/
|
||||||
|
export function enableLocalStorage(element: HTMLInputElement | HTMLSelectElement, key: string) {
|
||||||
|
// Check if localStorage is already enabled for this element and key
|
||||||
|
const localStorageKey = `__localStorageEnabled_${key}`;
|
||||||
|
if ((element as any)[localStorageKey]) {
|
||||||
|
console.warn(`localStorage already enabled for ${key}, skipping`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load saved value from localStorage
|
||||||
|
try {
|
||||||
|
// Check if the key exists in localStorage, not just if it has values
|
||||||
|
if (localStorage.hasOwnProperty(key)) {
|
||||||
|
const savedValue = localStorage.getItem(key);
|
||||||
|
element.value = savedValue || '';
|
||||||
|
console.info(`Loaded saved ${key} from localStorage:`, savedValue);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`${key}: Failed to load saved value from localStorage:`, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up event listener to save value when changed
|
||||||
|
const changeHandler = () => {
|
||||||
|
try {
|
||||||
|
// Always save the value, even if it's empty
|
||||||
|
localStorage.setItem(key, element.value);
|
||||||
|
console.info(`Saved ${key} to localStorage:`, JSON.stringify(element.value));
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`${key}: Failed to save to localStorage:`, error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
element.addEventListener('change', changeHandler);
|
||||||
|
|
||||||
|
// Mark this element as having localStorage enabled for this key
|
||||||
|
(element as any)[localStorageKey] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strips protocol prefixes (http:// or https://) from a URL string
|
||||||
|
* @param url - The URL string to clean
|
||||||
|
* @returns The URL without protocol prefix
|
||||||
|
*/
|
||||||
|
function stripProtocol(url: string): string {
|
||||||
|
return url.replace(/^https?:\/\//, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection configuration object containing server connection details
|
||||||
|
*/
|
||||||
|
export interface ConnectionConfiguration {
|
||||||
|
/** Final server IP address (may be modified for HTTPS proxy routing) */
|
||||||
|
serverIP: string;
|
||||||
|
|
||||||
|
/** Final port number (fixed to 443 for HTTPS, user-provided for HTTP) */
|
||||||
|
port: number;
|
||||||
|
|
||||||
|
/** Whether the connection will use secure protocol (HTTPS/WSS) */
|
||||||
|
useSecureConnection: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CloudXR configuration interface containing all streaming settings
|
||||||
|
*/
|
||||||
|
export interface CloudXRConfig {
|
||||||
|
/** IP address of the CloudXR streaming server */
|
||||||
|
serverIP: string;
|
||||||
|
|
||||||
|
/** Port number for the CloudXR server connection */
|
||||||
|
port: number;
|
||||||
|
|
||||||
|
/** Whether to use secure connection (HTTPS/WSS) or insecure (HTTP/WS) */
|
||||||
|
useSecureConnection: boolean;
|
||||||
|
|
||||||
|
/** Width of each eye in pixels (must be multiple of 16) */
|
||||||
|
perEyeWidth: number;
|
||||||
|
|
||||||
|
/** Height of each eye in pixels (must be multiple of 16) */
|
||||||
|
perEyeHeight: number;
|
||||||
|
|
||||||
|
/** Target frame rate for the XR device in frames per second (FPS) */
|
||||||
|
deviceFrameRate: number;
|
||||||
|
|
||||||
|
/** Maximum streaming bitrate in Megabits per second (Mbps) */
|
||||||
|
maxStreamingBitrateMbps: number;
|
||||||
|
|
||||||
|
/** XR immersive mode: 'ar' for augmented reality, 'vr' for virtual reality */
|
||||||
|
immersiveMode: 'ar' | 'vr';
|
||||||
|
|
||||||
|
/** Application identifier string for the CloudXR session */
|
||||||
|
app: string;
|
||||||
|
|
||||||
|
/** Type of server being connected to */
|
||||||
|
serverType: string;
|
||||||
|
|
||||||
|
/** Optional proxy URL for HTTPS routing (e.g., 'https://proxy.example.com/'); if empty, uses direct WSS connection */
|
||||||
|
proxyUrl: string;
|
||||||
|
|
||||||
|
/** Preferred XR reference space for tracking and positioning */
|
||||||
|
referenceSpaceType: 'auto' | 'local-floor' | 'local' | 'viewer' | 'unbounded';
|
||||||
|
|
||||||
|
/** XR reference space offset along X axis in meters (positive is right) */
|
||||||
|
xrOffsetX?: number;
|
||||||
|
/** XR reference space offset along Y axis in meters (positive is up) */
|
||||||
|
xrOffsetY?: number;
|
||||||
|
/** XR reference space offset along Z axis in meters (positive is backward) */
|
||||||
|
xrOffsetZ?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines connection configuration based on protocol and user inputs
|
||||||
|
* Supports both direct WSS connections and proxy routing for HTTPS
|
||||||
|
*
|
||||||
|
* @param serverIP - The user-provided server IP address
|
||||||
|
* @param port - The user-provided port number
|
||||||
|
* @param proxyUrl - Optional proxy URL for HTTPS routing (if provided, uses proxy routing; otherwise direct connection)
|
||||||
|
* @param location - Optional location object (defaults to window.location)
|
||||||
|
* @returns Object containing server IP, port, and security settings
|
||||||
|
* @throws {Error} When proxy URL format is invalid (must start with https://)
|
||||||
|
*/
|
||||||
|
export function getConnectionConfig(
|
||||||
|
serverIP: string,
|
||||||
|
port: number,
|
||||||
|
proxyUrl: string,
|
||||||
|
location: Location = window.location
|
||||||
|
): ConnectionConfiguration {
|
||||||
|
let finalServerIP = '';
|
||||||
|
let finalPort = port;
|
||||||
|
let finalUseSecureConnection = false;
|
||||||
|
|
||||||
|
// Determine if we should use secure connection based on page protocol
|
||||||
|
if (location.protocol === 'https:') {
|
||||||
|
console.info('Running on HTTPS protocol - using secure WebSocket (WSS)');
|
||||||
|
finalUseSecureConnection = true;
|
||||||
|
|
||||||
|
// Check if proxy URL is provided for routing
|
||||||
|
const trimmedProxyUrl = proxyUrl?.trim();
|
||||||
|
if (trimmedProxyUrl) {
|
||||||
|
// Proxy routing mode
|
||||||
|
console.info('Proxy URL provided - using proxy routing mode');
|
||||||
|
|
||||||
|
if (!trimmedProxyUrl.startsWith('https://')) {
|
||||||
|
throw new Error('Proxy URL must start with https://. Received: ' + trimmedProxyUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use port 443 for proxy routing (standard HTTPS port)
|
||||||
|
finalPort = 443;
|
||||||
|
|
||||||
|
// Route through proxy: if specific server IP provided, append it to proxy URL
|
||||||
|
if (serverIP && serverIP !== 'localhost' && serverIP !== '127.0.0.1') {
|
||||||
|
// Route to proxy with IP
|
||||||
|
const cleanServerIP = stripProtocol(serverIP);
|
||||||
|
// Clean proxy URL - strip protocol and trailing slash
|
||||||
|
const cleanProxyUrl = stripProtocol(trimmedProxyUrl).replace(/\/$/, '');
|
||||||
|
finalServerIP = `${cleanProxyUrl}/${cleanServerIP}`;
|
||||||
|
console.info(`Using HTTPS proxy with IP: ${finalServerIP}`);
|
||||||
|
} else {
|
||||||
|
// Route to proxy without IP
|
||||||
|
finalServerIP = stripProtocol(trimmedProxyUrl).replace(/\/$/, '');
|
||||||
|
console.info(`Using HTTPS proxy without specific IP: ${finalServerIP}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Direct WSS connection mode
|
||||||
|
console.info('No proxy URL - using direct WSS connection');
|
||||||
|
|
||||||
|
// Handle server IP input
|
||||||
|
if (serverIP && serverIP !== 'localhost' && serverIP !== '127.0.0.1') {
|
||||||
|
finalServerIP = stripProtocol(serverIP);
|
||||||
|
console.info('Using user-provided server IP:', finalServerIP);
|
||||||
|
} else {
|
||||||
|
finalServerIP = new URL(location.href).hostname;
|
||||||
|
console.info('Using default server IP from window location:', finalServerIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use user-provided port for direct WSS
|
||||||
|
if (port && !isNaN(port)) {
|
||||||
|
finalPort = port;
|
||||||
|
console.info('Using user-provided port:', finalPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// HTTP protocol - direct WS connection
|
||||||
|
console.info('Running on HTTP protocol - using insecure WebSocket (WS)');
|
||||||
|
finalUseSecureConnection = false;
|
||||||
|
|
||||||
|
// Handle server IP input
|
||||||
|
if (serverIP && serverIP !== 'localhost' && serverIP !== '127.0.0.1') {
|
||||||
|
finalServerIP = stripProtocol(serverIP);
|
||||||
|
console.info('Using user-provided server IP:', finalServerIP);
|
||||||
|
} else {
|
||||||
|
finalServerIP = new URL(location.href).hostname;
|
||||||
|
console.info('Using default server IP from window location:', finalServerIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle port input
|
||||||
|
if (port && !isNaN(port)) {
|
||||||
|
finalPort = port;
|
||||||
|
console.info('Using user-provided port:', finalPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
serverIP: finalServerIP,
|
||||||
|
port: finalPort,
|
||||||
|
useSecureConnection: finalUseSecureConnection,
|
||||||
|
} as ConnectionConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up certificate acceptance link for self-signed certificates in HTTPS mode
|
||||||
|
* Shows a link to accept certificates when using direct WSS connection (no proxy)
|
||||||
|
*
|
||||||
|
* @param serverIpInput - Input element for server IP address
|
||||||
|
* @param portInput - Input element for port number
|
||||||
|
* @param proxyUrlInput - Input element for proxy URL
|
||||||
|
* @param certAcceptanceLink - Container element for the certificate link
|
||||||
|
* @param certLink - Anchor element for the certificate URL
|
||||||
|
* @param location - Optional location object (defaults to window.location)
|
||||||
|
* @returns Cleanup function to remove event listeners
|
||||||
|
*/
|
||||||
|
export function setupCertificateAcceptanceLink(
|
||||||
|
serverIpInput: HTMLInputElement,
|
||||||
|
portInput: HTMLInputElement,
|
||||||
|
proxyUrlInput: HTMLInputElement,
|
||||||
|
certAcceptanceLink: HTMLElement,
|
||||||
|
certLink: HTMLAnchorElement,
|
||||||
|
location: Location = window.location
|
||||||
|
): () => void {
|
||||||
|
/**
|
||||||
|
* Updates the certificate acceptance link based on current configuration
|
||||||
|
* Shows link only when in HTTPS mode without proxy (direct WSS)
|
||||||
|
*/
|
||||||
|
const updateCertLink = () => {
|
||||||
|
const isHttps = location.protocol === 'https:';
|
||||||
|
const hasProxy = proxyUrlInput.value.trim().length > 0;
|
||||||
|
const portValue = parseInt(portInput.value, 10);
|
||||||
|
const defaultPort = hasProxy ? 443 : 48322;
|
||||||
|
const port = portValue || defaultPort;
|
||||||
|
|
||||||
|
// Show link only in HTTPS mode without proxy
|
||||||
|
if (isHttps && !hasProxy) {
|
||||||
|
let serverIp = serverIpInput.value.trim();
|
||||||
|
if (!serverIp) {
|
||||||
|
serverIp = new URL(location.href).hostname;
|
||||||
|
}
|
||||||
|
const url = `https://${serverIp}:${port}/`;
|
||||||
|
certAcceptanceLink.style.display = 'block';
|
||||||
|
certLink.href = url;
|
||||||
|
certLink.textContent = `Click ${url} to accept cert`;
|
||||||
|
} else {
|
||||||
|
certAcceptanceLink.style.display = 'none';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add event listeners to update link when inputs change
|
||||||
|
serverIpInput.addEventListener('input', updateCertLink);
|
||||||
|
portInput.addEventListener('input', updateCertLink);
|
||||||
|
proxyUrlInput.addEventListener('input', updateCertLink);
|
||||||
|
|
||||||
|
// Initial update after localStorage values are restored
|
||||||
|
setTimeout(updateCertLink, 0);
|
||||||
|
|
||||||
|
// Return cleanup function to remove event listeners
|
||||||
|
return () => {
|
||||||
|
serverIpInput.removeEventListener('input', updateCertLink);
|
||||||
|
portInput.removeEventListener('input', updateCertLink);
|
||||||
|
proxyUrlInput.removeEventListener('input', updateCertLink);
|
||||||
|
};
|
||||||
|
}
|
||||||
3
deps/cloudxr/isaac/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules/
|
||||||
|
build/
|
||||||
|
*.pem
|
||||||
307
deps/cloudxr/isaac/LICENSE
vendored
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
NVIDIA SOFTWARE EVALUATION LICENSE AGREEMENT
|
||||||
|
|
||||||
|
IMPORTANT NOTICE – PLEASE READ AND AGREE BEFORE USING THE SOFTWARE
|
||||||
|
|
||||||
|
This software evaluation license agreement (“Agreement”) is a legal agreement between you, whether an
|
||||||
|
individual or entity, (“you”) and NVIDIA Corporation and its affiliates (“NVIDIA”) and governs the use of certain
|
||||||
|
NVIDIA CloudXR software and documentation that NVIDIA delivers to you under this Agreement (“Software”).
|
||||||
|
NVIDIA and you are each a “party” and collectively the “parties.”
|
||||||
|
This Agreement can be accepted only by an adult of legal age of majority in the country in which the Software is
|
||||||
|
used. If you don’t have the required age or authority to accept this Agreement, or if you don’t accept all the
|
||||||
|
terms and conditions of this Agreement, do not use the Software.
|
||||||
|
|
||||||
|
1. License Grants.
|
||||||
|
|
||||||
|
1.1 License Grant to You. The Software is licensed, not sold. Subject to the terms of this Agreement,
|
||||||
|
NVIDIA grants you a limited, non-exclusive, revocable, non-transferable, non-sublicensable (except
|
||||||
|
as expressly granted in this Agreement), license to:
|
||||||
|
(a) access, install and use copies of the Software,
|
||||||
|
(b) configure the Software using configuration files provided (if applicable),
|
||||||
|
(c) modify and create derivative works of any source code NVIDIA delivers to you as part of the
|
||||||
|
Software (“Derivatives”) (if applicable).
|
||||||
|
|
||||||
|
All the foregoing grants are only for internal test and evaluation purposes and, as applicable, for use (a) in
|
||||||
|
client systems, or (b) in server systems with NVIDIA GPUs (“Purpose”).
|
||||||
|
|
||||||
|
1.2 License Grant to NVIDIA. Subject to the terms of this Agreement, you grant NVIDIA a non-exclusive,
|
||||||
|
perpetual, irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license,
|
||||||
|
under your intellectual property rights, to publicly perform, publicly display, reproduce, use, make,
|
||||||
|
have made, sell, offer for sale, distribute (through multiple tiers of distribution), import, create
|
||||||
|
derivative works of and otherwise commercialize and exploit at NVIDIA’s discretion any Derivatives
|
||||||
|
created by or for you. You may, but are not required to, deliver any Derivatives to NVIDIA.
|
||||||
|
|
||||||
|
2. License Restrictions. Your license to use the Software and Derivatives is restricted as stated in this “License
|
||||||
|
Restrictions” Section. You will cooperate with NVIDIA and, upon NVIDIA’s written request, you will confirm
|
||||||
|
in writing and provide reasonably requested information to verify your compliance with the terms of this
|
||||||
|
Agreement. You may not:
|
||||||
|
|
||||||
|
2.1 Use the Software or Derivatives for any purpose other than the Purpose, including but not limited to
|
||||||
|
in production;
|
||||||
|
|
||||||
|
2.2 Sell, rent, sublicense, transfer, distribute or otherwise make available to others (except Authorized
|
||||||
|
Users as stated in the “Authorized Users” Section) any portion of the Software or Derivatives, except
|
||||||
|
as expressly granted in Section 1.1 (“License Grant to You”);
|
||||||
|
|
||||||
|
2.3 Reverse engineer, decompile, or disassemble the Software components provided in binary form, nor
|
||||||
|
attempt in any other manner to obtain source code of such Software;
|
||||||
|
|
||||||
|
2.4 Modify or create derivative works of the Software, except as expressly granted in Section 1.1
|
||||||
|
(“License Grant to You”);
|
||||||
|
|
||||||
|
2.5 Change or remove copyright or other proprietary notices in the Software;
|
||||||
|
|
||||||
|
2.6 Bypass, disable, or circumvent any technical limitation, encryption, security, digital rights
|
||||||
|
management or authentication mechanism in the Software;
|
||||||
|
|
||||||
|
2.7 Use the Software or Derivatives in any manner that would cause them to become subject to an open
|
||||||
|
source software license; subject to the terms in Section 7 (“Components Under Other Licenses”);
|
||||||
|
|
||||||
|
2.8 Use the Software or Derivatives for the purpose of developing competing products or technologies
|
||||||
|
or assist a third party in such activities;
|
||||||
|
|
||||||
|
2.9 Replace any Software components governed by this Agreement with other software that
|
||||||
|
implements NVIDIA APIs;
|
||||||
|
|
||||||
|
2.10 Use the Software or Derivatives in violation of any applicable law or regulation in the relevant
|
||||||
|
jurisdictions; or
|
||||||
|
|
||||||
|
2.11 Use the Software in or with any system or application where the use or failure of such system or
|
||||||
|
application developed or deployed with Software could result in injury, death or catastrophic
|
||||||
|
damage (“Mission Critical Applications”). NVIDIA will not be liable to you or any third party, in whole
|
||||||
|
or in part, for any claims or damages arising from uses in Mission Critical Applications.
|
||||||
|
|
||||||
|
2.12 Disclose any evaluation or test results regarding the Software or Derivatives without NVIDIA’s prior
|
||||||
|
written consent.
|
||||||
|
|
||||||
|
3. Authorized Users. You may allow employees and contractors of your entity or of your subsidiary(ies), and
|
||||||
|
for educational institutions also enrolled students, to internally access and use the Software as authorized
|
||||||
|
by this Agreement from your secure network to perform the work authorized by this Agreement on your
|
||||||
|
behalf. You are responsible for the compliance with the terms of this Agreement by your authorized users.
|
||||||
|
Any act or omission that if committed by you would constitute a breach of this Agreement will be deemed to
|
||||||
|
constitute a breach of this Agreement if committed by your authorized users.
|
||||||
|
|
||||||
|
4. Pre-Release. Software versions identified as alpha, beta, preview, early access or otherwise as pre-release
|
||||||
|
may not be fully functional, may contain errors or design flaws, and may have reduced or different security,
|
||||||
|
privacy, availability and reliability standards relative to NVIDIA commercial offerings. You use pre-release
|
||||||
|
Software at your own risk. NVIDIA did not design or test the Software for use in production or business
|
||||||
|
critical systems. NVIDIA may choose not to make available a commercial version of pre-release Software.
|
||||||
|
NVIDIA may also choose to abandon development and terminate the availability of pre-release Software at
|
||||||
|
any time without liability.
|
||||||
|
|
||||||
|
5. Your Privacy: Collection and Use of Information.
|
||||||
|
|
||||||
|
5.1 Privacy Policy. Please review the NVIDIA Privacy Policy, located at https://www.nvidia.com/enus/about-nvidia/privacy-policy, which explains NVIDIA’s policy for collecting and using data, as well
|
||||||
|
as visit the NVIDIA Privacy Center, located at https://www.nvidia.com/en-us/privacy-center, to
|
||||||
|
manage your consent and privacy preferences.
|
||||||
|
|
||||||
|
5.2 Collection Purposes. You also acknowledge that the Software collects data for the following
|
||||||
|
purposes: (a) properly configure and optimize products for use with Software; and (b) improve
|
||||||
|
NVIDIA products and services. Information collected by the Software includes: (i) application
|
||||||
|
configuration; (ii) browser version; (iii) and session metadata (i.e. performance and usage
|
||||||
|
statistics). Additionally, NVIDIA may collect certain personal information, such as your name
|
||||||
|
and email address or those of your authorized users, and other information necessary to
|
||||||
|
authenticate and enable you or your authorized users’ access to the Software. Where appropriate
|
||||||
|
you will disclose to, and obtain any necessary consent from, your authorized users to allow NVIDIA
|
||||||
|
to collect such information.
|
||||||
|
|
||||||
|
5.3 Third Party Privacy Practices. The Software may contain links to third party websites and services.
|
||||||
|
NVIDIA encourages you to review the privacy statements on those sites and services that you choose
|
||||||
|
to visit to understand how they may collect, use and share your data. NVIDIA is not responsible for
|
||||||
|
the privacy statements or practices of third-party sites or services.
|
||||||
|
|
||||||
|
6. Updates. NVIDIA may at any time and at its option, change, discontinue, or deprecate any part, or all, of the
|
||||||
|
Software, or change or remove features or functionality, or make available patches, workarounds or other
|
||||||
|
updates to the Software. Unless the updates are provided with their separate governing terms, they are
|
||||||
|
deemed part of the Software licensed to you under this Agreement, and your continued use of the Software
|
||||||
|
is deemed acceptance of such changes.
|
||||||
|
|
||||||
|
7. Components Under Other Licenses. The Software may include or be distributed with components provided
|
||||||
|
with separate legal notices or terms that accompany the components, such as open source software licenses
|
||||||
|
and other license terms (“Other Licenses”). The components are subject to the applicable Other Licenses,
|
||||||
|
including any proprietary notices, disclaimers, requirements and extended use rights; except that this
|
||||||
|
Agreement will prevail regarding the use of third-party open source software, unless a third-party open
|
||||||
|
source software license requires its license terms to prevail. Open source software license means any
|
||||||
|
software, data or documentation subject to any license identified as an open source license by the Open
|
||||||
|
Source Initiative (http://opensource.org), Free Software Foundation (http://www.fsf.org) or other similar
|
||||||
|
open source organization or listed by the Software Package Data Exchange (SPDX) Workgroup under the
|
||||||
|
Linux Foundation (http://www.spdx.org).
|
||||||
|
|
||||||
|
8. Ownership.
|
||||||
|
|
||||||
|
8.1 NVIDIA Ownership. The Software, including all intellectual property rights, is and will remain the sole
|
||||||
|
and exclusive property of NVIDIA or its licensors. Except as expressly granted in this Agreement,
|
||||||
|
(a) NVIDIA reserves all rights, interests and remedies in connection with the Software, and (b) no
|
||||||
|
other license or right is granted to you by implication, estoppel or otherwise.
|
||||||
|
|
||||||
|
8.2 Your Ownership. Subject to the rights of NVIDIA and its suppliers in the Software, which continue to
|
||||||
|
be licensed as stated in this Agreement, even when incorporated in your products, and the extent
|
||||||
|
permitted by applicable law, as between you and NVIDIA, you hold all rights, title and interest in and
|
||||||
|
to your services, applications and Derivatives you develop as permitted in this Agreement including
|
||||||
|
their respective intellectual property rights.
|
||||||
|
|
||||||
|
9. Feedback. You may, but are not obligated to, provide suggestions, requests, fixes, modifications,
|
||||||
|
enhancements or other feedback regarding your use of the Software (“Feedback”). Feedback, even if
|
||||||
|
designated as confidential by you, will not create any confidentiality obligation for NVIDIA or its affiliates. If
|
||||||
|
you provide Feedback, you hereby grant NVIDIA, its affiliates and its designees a nonexclusive, perpetual,
|
||||||
|
irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and transferable license, under your
|
||||||
|
intellectual property rights, to publicly perform, publicly display, reproduce, use, make, have made, sell,
|
||||||
|
offer for sale, distribute (through multiple tiers of distribution), import, create derivative works of and
|
||||||
|
otherwise commercialize and exploit the Feedback at NVIDIA’s discretion.
|
||||||
|
|
||||||
|
10. Confidentiality. You may use confidential information only to exercise your rights and perform your
|
||||||
|
obligations under this Agreement. You will not disclose, nor authorize others to disclose NVIDIA Confidential
|
||||||
|
Information to any third party, except as expressly authorized in this Agreement and as necessary for the
|
||||||
|
Purpose, without obtaining NVIDIA’s prior written approval. Each recipient of confidential information must
|
||||||
|
be subject to a written agreement that includes confidentiality obligations consistent with these terms and
|
||||||
|
must have a need to know for the Purpose. You will protect the NVIDIA Confidential Information with at
|
||||||
|
least the same degree of care that you use to protect your own similar confidential and proprietary
|
||||||
|
information, but no less than a reasonable degree of care. Confidential information includes, but is not
|
||||||
|
limited to, the Software, including its features and functionality, Derivatives, and any results of
|
||||||
|
benchmarking or other competitive analysis or regression or performance data relating to the Software.
|
||||||
|
No Publicity. You may not issue any public statements about this Agreement, disclose the Software or
|
||||||
|
Derivatives, or any information or results related to your use of the Software, without prior written approval
|
||||||
|
of NVIDIA.
|
||||||
|
|
||||||
|
11. Term and Termination.
|
||||||
|
|
||||||
|
11.1 Term. This Agreement has a duration of twelve (12) months starting from the date of initial
|
||||||
|
download (even if you download the same version or updates of the Software later and it is
|
||||||
|
accompanied by this Agreement or another Agreement), unless terminated earlier in accordance
|
||||||
|
with this Agreement.
|
||||||
|
|
||||||
|
11.2 Termination for Convenience. Either party may terminate this Agreement at any time with thirty (30)
|
||||||
|
days’ advance written notice to the other party.
|
||||||
|
|
||||||
|
11.3 Termination for Cause. If you commence or participate in any legal proceeding against NVIDIA with
|
||||||
|
respect to the Software, this Agreement will terminate immediately without notice. Either party may
|
||||||
|
terminate this Agreement upon notice for cause if:
|
||||||
|
(a) the other party fails to cure a material breach of this Agreement within ten (10) days of the
|
||||||
|
non-breaching party’s notice of the breach; or
|
||||||
|
(b) the other party breaches its confidentiality obligations or license rights under this
|
||||||
|
Agreement, which termination will be effective immediately upon written notice.
|
||||||
|
|
||||||
|
11.4 Effect of Termination. Upon any expiration or termination of this Agreement, you will promptly
|
||||||
|
(a) stop using and return, delete or destroy NVIDIA confidential information and all Software
|
||||||
|
received under this Agreement, and (b) delete or destroy Derivatives created under this Agreement,
|
||||||
|
unless an authorized NVIDIA representative provides prior written approval that you may keep a
|
||||||
|
copy of the Derivatives solely for archival purposes. Upon written request, you will certify in writing
|
||||||
|
that you have complied with your obligations under this “Effect of Termination” Section.
|
||||||
|
|
||||||
|
11.5 Survival. The “License Grant to NVIDIA”, “Updates”, “Components Under Other Licenses”,
|
||||||
|
“Ownership”, “Feedback”, “Confidentiality”, “No Publicity”, “Effect of Termination”, “Survival”,
|
||||||
|
“Disclaimer of Warranties”, “Limitation of Liability”, “Indemnity” and all “General” Sections of this
|
||||||
|
Agreement will survive any expiration or termination of this Agreement.
|
||||||
|
|
||||||
|
12. Disclaimer of Warranties. THE SOFTWARE IS PROVIDED BY NVIDIA AS-IS AND WITH ALL FAULTS. TO THE
|
||||||
|
MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NVIDIA DISCLAIMS ALL WARRANTIES AND
|
||||||
|
REPRESENTATIONS OF ANY KIND, WHETHER EXPRESS, IMPLIED OR STATUTORY, RELATING TO OR ARISING
|
||||||
|
UNDER THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF TITLE,
|
||||||
|
NONINFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, USAGE OF TRADE AND
|
||||||
|
COURSE OF DEALING. NVIDIA DOES NOT WARRANT OR ASSUME RESPONSIBILITY FOR THE ACCURACY OR
|
||||||
|
COMPLETENESS OF ANY THIRD-PARTY INFORMATION, TEXT, GRAPHICS, LINKS CONTAINED IN THE
|
||||||
|
SOFTWARE. WITHOUT LIMITING THE FOREGOING, NVIDIA DOES NOT WARRANT THAT THE SOFTWARE WILL
|
||||||
|
MEET YOUR REQUIREMENTS, ANY DEFECTS OR ERRORS WILL BE CORRECTED, ANY CERTAIN CONTENT WILL
|
||||||
|
BE AVAILABLE; OR THAT THE SOFTWARE IS FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS. NO
|
||||||
|
INFORMATION OR ADVICE GIVEN BY NVIDIA WILL IN ANY WAY INCREASE THE SCOPE OF ANY WARRANTY
|
||||||
|
EXPRESSLY PROVIDED IN THIS AGREEMENT. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE
|
||||||
|
APPROPRIATENESS OF USING THE SOFTWARE OR DERIVATIVES AND ASSUME ANY RISKS ASSOCIATED WITH
|
||||||
|
YOUR USE OF THE SOFTWARE OR DERIVATIVES.
|
||||||
|
|
||||||
|
13. Limitations of Liability.
|
||||||
|
|
||||||
|
13.1 EXCLUSIONS. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
|
||||||
|
NVIDIA BE LIABLE FOR ANY (A) INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES, OR (B) DAMAGES FOR THE (I) COST OF PROCURING SUBSTITUTE GOODS OR (II) LOSS OF
|
||||||
|
PROFITS, REVENUES, USE, DATA OR GOODWILL ARISING OUT OF OR RELATED TO THIS AGREEMENT,
|
||||||
|
WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR
|
||||||
|
OTHERWISE, AND EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND
|
||||||
|
EVEN IF A PARTY’S REMEDIES FAIL THEIR ESSENTIAL PURPOSE.
|
||||||
|
|
||||||
|
13.2 DAMAGES CAP. ADDITIONALLY, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
|
||||||
|
NVIDIA’S TOTAL CUMULATIVE AGGREGATE LIABILITY FOR ANY AND ALL LIABILITIES, OBLIGATIONS OR
|
||||||
|
CLAIMS ARISING OUT OF OR RELATED TO THIS AGREEMENT WILL NOT EXCEED ONE HUNDRED U.S.
|
||||||
|
DOLLARS (US$100).
|
||||||
|
|
||||||
|
14. Indemnity. You will defend, indemnify and hold harmless NVIDIA and its affiliates, and their respective
|
||||||
|
employees, contractors, agents, officers and directors, from and against any and all third party claims,
|
||||||
|
damages, obligations, losses, liabilities, costs or debt, fines, restitutions and expenses (including but not
|
||||||
|
limited to attorney’s fees and costs incident to establishing the right of indemnification) arising out of use of
|
||||||
|
the Software and Derivatives outside of the scope of this Agreement or in breach of the terms of this
|
||||||
|
Agreement.
|
||||||
|
|
||||||
|
15. General.
|
||||||
|
|
||||||
|
15.1 Governing Law and Jurisdiction. This Agreement will be governed in all respects by the laws of the
|
||||||
|
United States and the laws of the State of Delaware, without regard to conflict of laws principles or
|
||||||
|
the United Nations Convention on Contracts for the International Sale of Goods. The state and
|
||||||
|
federal courts residing in Santa Clara County, California will have exclusive jurisdiction over any
|
||||||
|
dispute or claim arising out of or related to this Agreement, and the parties irrevocably consent to
|
||||||
|
personal jurisdiction and venue in those courts; except that either party may apply for injunctive
|
||||||
|
remedies or an equivalent type of urgent legal relief in any jurisdiction.
|
||||||
|
|
||||||
|
15.2 Independent Contractors. The parties are independent contractors, and this Agreement does not
|
||||||
|
create a joint venture, partnership, agency or other form of business association between the
|
||||||
|
parties. Neither party will have the power to bind the other party or incur any obligation on its
|
||||||
|
behalf without the other party’s prior written consent. Nothing in this Agreement prevents either
|
||||||
|
party from participating in similar arrangements with third parties.
|
||||||
|
|
||||||
|
15.3 No Assignment. NVIDIA may assign, delegate or transfer its rights or obligations under this
|
||||||
|
Agreement by any means or operation of law. You may not, without NVIDIA’s prior written consent,
|
||||||
|
assign, delegate or transfer any of your rights or obligations under this Agreement by any means or
|
||||||
|
operation of law, and any attempt to do so is null and void.
|
||||||
|
|
||||||
|
15.4 No Waiver. No failure or delay by a party to enforce any term or obligation of this Agreement will
|
||||||
|
operate as a waiver by that party, or prevent the enforcement of such term or obligation later.
|
||||||
|
|
||||||
|
15.5 Trade Compliance. You agree to comply with all applicable export, import, trade and economic
|
||||||
|
sanctions laws and regulations, as amended, including without limitation U.S. Export Administration
|
||||||
|
Regulations and Office of Foreign Assets Control regulations. You confirm (a) your understanding
|
||||||
|
that export or reexport of certain NVIDIA products or technologies may require a license or other
|
||||||
|
approval from appropriate authorities and (b) that you will not export or reexport any products or
|
||||||
|
technology, directly or indirectly, without first obtaining any required license or other approval from
|
||||||
|
appropriate authorities, (i) to any countries that are subject to any U.S. or local export restrictions
|
||||||
|
(currently including, but not necessarily limited to, Belarus, Cuba, Iran, North Korea, Russia, Syria,
|
||||||
|
the Region of Crimea, Donetsk People’s Republic Region and Luhansk People’s Republic Region); (ii)
|
||||||
|
to any end-user who you know or have reason to know will utilize them in the design, development
|
||||||
|
or production of nuclear, chemical or biological weapons, missiles, rocket systems, unmanned air
|
||||||
|
vehicles capable of a maximum range of at least 300 kilometers, regardless of payload, or intended
|
||||||
|
for military end-use, or any weapons of mass destruction; (iii) to any end-user who has been
|
||||||
|
prohibited from participating in the U.S. or local export transactions by any governing authority; or
|
||||||
|
(iv) to any known military or military-intelligence end-user or for any known military or military-
|
||||||
|
intelligence end-use in accordance with U.S. trade compliance laws and regulations.
|
||||||
|
|
||||||
|
15.6 Government Rights. The Software, documentation and technology (“Protected Items”) are
|
||||||
|
“Commercial products” as this term is defined at 48 C.F.R. 2.101, consisting of “commercial
|
||||||
|
computer software” and “commercial computer software documentation” as such terms are used
|
||||||
|
in, respectively, 48 C.F.R. 12.212 and 48 C.F.R. 227.7202 & 252.227-7014(a)(1). Before any Protected
|
||||||
|
Items are supplied to the U.S. Government, you will (i) inform the U.S. Government in writing that
|
||||||
|
the Protected Items are and must be treated as commercial computer software and commercial
|
||||||
|
computer software documentation developed at private expense; (ii) inform the U.S. Government
|
||||||
|
that the Protected Items are provided subject to the terms of the Agreement; and (iii) mark the
|
||||||
|
Protected Items as commercial computer software and commercial computer software
|
||||||
|
documentation developed at private expense. In no event will you permit the U.S. Government to
|
||||||
|
acquire rights in Protected Items beyond those specified in 48 C.F.R. 52.227-19(b)(1)-(2) or 252.227-
|
||||||
|
7013(c) except as expressly approved by NVIDIA in writing.
|
||||||
|
|
||||||
|
15.7 Notices. Please direct your legal notices or other correspondence to legalnotices@nvidia.com with a
|
||||||
|
copy mailed to NVIDIA Corporation, 2788 San Tomas Expressway, Santa Clara, California 95051,
|
||||||
|
United States of America, Attention: Legal Department. If NVIDIA needs to contact you about the
|
||||||
|
Software, you consent to receive the notices by email and agree that such notices will satisfy any
|
||||||
|
legal communication requirements.
|
||||||
|
|
||||||
|
15.8 Severability. If a court of competent jurisdiction rules that a provision of this Agreement is
|
||||||
|
unenforceable, that provision will be deemed modified to the extent necessary to make it
|
||||||
|
enforceable and the remainder of this Agreement will continue in full force and effect.
|
||||||
|
|
||||||
|
15.9 Amendment. Any amendment to this Agreement must be in writing and signed by authorized
|
||||||
|
representatives of both parties.
|
||||||
|
|
||||||
|
15.10 Entire Agreement. Regarding the subject matter of this Agreement, the parties agree that (a) this
|
||||||
|
Agreement constitutes the entire and exclusive agreement between the parties and supersedes all
|
||||||
|
prior and contemporaneous communications and (b) any additional or different terms or conditions,
|
||||||
|
whether contained in purchase orders, order acknowledgments, invoices or otherwise, will not be
|
||||||
|
binding and are null and void.
|
||||||
|
|
||||||
|
(v. February 25, 2025)
|
||||||
|
|
||||||
|
NVIDIA Confidential
|
||||||
5
deps/cloudxr/isaac/README.md
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Run Isaac Lab Teleoperation
|
||||||
|
|
||||||
|
This is the Isaac Lab Teleop client built on top of CloudXR.js.
|
||||||
|
|
||||||
|
See the CloudXR.js SDK documentation > Show Cases > Isaac Lab Teleop for detailed guide.
|
||||||
BIN
deps/cloudxr/isaac/favicon.ico
vendored
Normal file
|
After Width: | Height: | Size: 14 KiB |
7089
deps/cloudxr/isaac/package-lock.json
generated
vendored
Normal file
47
deps/cloudxr/isaac/package.json
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "cloudxr-isaac-lab-teleop",
|
||||||
|
"version": "6.0.0-beta",
|
||||||
|
"private": true,
|
||||||
|
"description": "CloudXR.js Isaac Lab Teleop application",
|
||||||
|
"author": "NVIDIA Corporation",
|
||||||
|
"license": "SEE LICENSE IN LICENSE",
|
||||||
|
"keywords": [
|
||||||
|
"react",
|
||||||
|
"three.js",
|
||||||
|
"webxr",
|
||||||
|
"cloudxr",
|
||||||
|
"vr"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --config ./webpack.prod.js",
|
||||||
|
"dev": "webpack --config ./webpack.dev.js",
|
||||||
|
"dev-server": "webpack serve --config ./webpack.dev.js --no-open",
|
||||||
|
"dev-server:https": "HTTPS=true webpack serve --config ./webpack.dev.js --no-open",
|
||||||
|
"clean": "rimraf dist"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nvidia/cloudxr": "file:../nvidia-cloudxr-6.0.0-beta.tgz",
|
||||||
|
"@react-three/drei": "^10.6.1",
|
||||||
|
"@react-three/fiber": "^9.3.0",
|
||||||
|
"@react-three/uikit": "^1.0.0",
|
||||||
|
"@react-three/uikit-default": "^1.0.0",
|
||||||
|
"@react-three/xr": "^6.6.22",
|
||||||
|
"react": "^19.2.0",
|
||||||
|
"react-dom": "^19.2.0",
|
||||||
|
"three": "^0.172.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "^19.2.0",
|
||||||
|
"@types/react-dom": "^19.2.0",
|
||||||
|
"@types/three": "^0.172.0",
|
||||||
|
"copy-webpack-plugin": "^13.0.0",
|
||||||
|
"css-loader": "^6.8.1",
|
||||||
|
"html-webpack-plugin": "^5.6.3",
|
||||||
|
"rimraf": "^5.0.5",
|
||||||
|
"style-loader": "^3.3.3",
|
||||||
|
"ts-loader": "^9.5.1",
|
||||||
|
"typescript": "^5.8.2",
|
||||||
|
"webpack-cli": "^6.0.1",
|
||||||
|
"webpack-dev-server": "^5.2.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
21
deps/cloudxr/isaac/public/HEROICONS_LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Tailwind Labs, Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
4
deps/cloudxr/isaac/public/arrow-left-start-on-rectangle.svg
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon">
|
||||||
|
<path fill-rule="evenodd" d="M16.5 3.75a1.5 1.5 0 0 1 1.5 1.5v13.5a1.5 1.5 0 0 1-1.5 1.5h-6a1.5 1.5 0 0 1-1.5-1.5V15a.75.75 0 0 0-1.5 0v3.75a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3V5.25a3 3 0 0 0-3-3h-6a3 3 0 0 0-3 3V9A.75.75 0 1 0 9 9V5.25a1.5 1.5 0 0 1 1.5-1.5h6ZM5.78 8.47a.75.75 0 0 0-1.06 0l-3 3a.75.75 0 0 0 0 1.06l3 3a.75.75 0 0 0 1.06-1.06l-1.72-1.72H15a.75.75 0 0 0 0-1.5H4.06l1.72-1.72a.75.75 0 0 0 0-1.06Z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 557 B |
4
deps/cloudxr/isaac/public/arrow-uturn-left.svg
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon">
|
||||||
|
<path fill-rule="evenodd" d="M9.53 2.47a.75.75 0 0 1 0 1.06L4.81 8.25H15a6.75 6.75 0 0 1 0 13.5h-3a.75.75 0 0 1 0-1.5h3a5.25 5.25 0 1 0 0-10.5H4.81l4.72 4.72a.75.75 0 1 1-1.06 1.06l-6-6a.75.75 0 0 1 0-1.06l6-6a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 381 B |
BIN
deps/cloudxr/isaac/public/assets/hdri/potsdamer_platz_1k.hdr
vendored
Normal file
13
deps/cloudxr/isaac/public/controller-icons.svg
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- Diamond (top-left) -->
|
||||||
|
<polygon points="6,2 10,6 6,10 2,6" fill="black"/>
|
||||||
|
|
||||||
|
<!-- Triangle (top-right) -->
|
||||||
|
<polygon points="18,2 22,10 14,10" fill="black"/>
|
||||||
|
|
||||||
|
<!-- Circle (bottom-left) -->
|
||||||
|
<circle cx="6" cy="18" r="4" fill="black"/>
|
||||||
|
|
||||||
|
<!-- Square (bottom-right) -->
|
||||||
|
<rect x="14" y="14" width="8" height="8" fill="black"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 435 B |
4
deps/cloudxr/isaac/public/play-circle.svg
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon">
|
||||||
|
<path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm14.024-.983a1.125 1.125 0 0 1 0 1.966l-5.603 3.113A1.125 1.125 0 0 1 9 15.113V8.887c0-.857.921-1.4 1.671-.983l5.603 3.113Z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 403 B |
4
deps/cloudxr/isaac/public/stop-circle.svg
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon">
|
||||||
|
<path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm6-2.438c0-.724.588-1.312 1.313-1.312h4.874c.725 0 1.313.588 1.313 1.313v4.874c0 .725-.588 1.313-1.313 1.313H9.564a1.312 1.312 0 0 1-1.313-1.313V9.564Z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 431 B |
558
deps/cloudxr/isaac/src/App.tsx
vendored
Normal file
@@ -0,0 +1,558 @@
|
|||||||
|
/**
|
||||||
|
* App.tsx - Main CloudXR React Application
|
||||||
|
*
|
||||||
|
* This is the root component of the CloudXR React example application. It sets up:
|
||||||
|
* - WebXR session management and XR store configuration
|
||||||
|
* - CloudXR server configuration (IP, port, stream settings)
|
||||||
|
* - UI state management (connection status, session state)
|
||||||
|
* - Integration between CloudXR rendering component and UI components
|
||||||
|
* - Entry point for AR/VR experiences with CloudXR streaming
|
||||||
|
*
|
||||||
|
* The app integrates with the HTML interface which provides a "CONNECT" button
|
||||||
|
* to enter AR mode and displays the CloudXR UI with controls for teleop actions
|
||||||
|
* and disconnect when in XR mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { checkCapabilities } from '@helpers/BrowserCapabilities';
|
||||||
|
import { loadIWERIfNeeded } from '@helpers/LoadIWER';
|
||||||
|
import { overridePressureObserver } from '@helpers/overridePressureObserver';
|
||||||
|
import * as CloudXR from '@nvidia/cloudxr';
|
||||||
|
import { Environment } from '@react-three/drei';
|
||||||
|
import { Canvas } from '@react-three/fiber';
|
||||||
|
import { setPreferredColorScheme } from '@react-three/uikit';
|
||||||
|
import { XR, createXRStore, noEvents, PointerEvents, XROrigin, useXR } from '@react-three/xr';
|
||||||
|
import { useState, useMemo, useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
import { CloudXR2DUI } from './CloudXR2DUI';
|
||||||
|
import CloudXRComponent from './CloudXRComponent';
|
||||||
|
import CloudXR3DUI from './CloudXRUI';
|
||||||
|
|
||||||
|
// Override PressureObserver early to catch errors from buggy browser implementations
|
||||||
|
overridePressureObserver();
|
||||||
|
|
||||||
|
const store = createXRStore({
|
||||||
|
foveation: 0,
|
||||||
|
emulate: false, // Disable IWER emulation from react in favor of custom iwer loading function
|
||||||
|
// Configure WebXR input profiles to use local assets
|
||||||
|
// Use relative path from current page location
|
||||||
|
baseAssetPath: `${new URL('.', window.location).href}npm/@webxr-input-profiles/assets@${process.env.WEBXR_ASSETS_VERSION}/dist/profiles/`,
|
||||||
|
hand: {
|
||||||
|
model: false, // Disable hand models but keep pointer functionality
|
||||||
|
},
|
||||||
|
controller: {
|
||||||
|
model: false, // Disable controller models but keep pointer functionality
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
setPreferredColorScheme('dark');
|
||||||
|
|
||||||
|
const START_TELEOP_COMMAND = {
|
||||||
|
type: 'teleop_command',
|
||||||
|
message: {
|
||||||
|
command: 'start teleop',
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// Environment component like controller-test
|
||||||
|
function NonAREnvironment() {
|
||||||
|
// Use local HDR file instead of preset so client doesn't need to download it from CDN
|
||||||
|
return (
|
||||||
|
<Environment
|
||||||
|
blur={0.2}
|
||||||
|
background={false}
|
||||||
|
environmentIntensity={2}
|
||||||
|
files="assets/hdri/potsdamer_platz_1k.hdr"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const COUNTDOWN_MAX_SECONDS = 9;
|
||||||
|
const COUNTDOWN_STORAGE_KEY = 'cxr.react.countdownSeconds';
|
||||||
|
// 2D UI management
|
||||||
|
const [cloudXR2DUI, setCloudXR2DUI] = useState<CloudXR2DUI | null>(null);
|
||||||
|
// IWER loading state
|
||||||
|
const [iwerLoaded, setIwerLoaded] = useState(false);
|
||||||
|
// Capability state management
|
||||||
|
const [capabilitiesValid, setCapabilitiesValid] = useState(false);
|
||||||
|
const capabilitiesCheckedRef = useRef(false);
|
||||||
|
// Connection state management
|
||||||
|
const [isConnected, setIsConnected] = useState(false);
|
||||||
|
// Session status management
|
||||||
|
const [sessionStatus, setSessionStatus] = useState('Disconnected');
|
||||||
|
// Error message management
|
||||||
|
const [errorMessage, setErrorMessage] = useState('');
|
||||||
|
// CloudXR session reference
|
||||||
|
const [cloudXRSession, setCloudXRSession] = useState<CloudXR.Session | null>(null);
|
||||||
|
// XR mode state for UI visibility
|
||||||
|
const [isXRMode, setIsXRMode] = useState(false);
|
||||||
|
// Server address being used for connection
|
||||||
|
const [serverAddress, setServerAddress] = useState<string>('');
|
||||||
|
// Teleop countdown and state
|
||||||
|
const [isCountingDown, setIsCountingDown] = useState(false);
|
||||||
|
const [countdownRemaining, setCountdownRemaining] = useState(0);
|
||||||
|
const [isTeleopRunning, setIsTeleopRunning] = useState(false);
|
||||||
|
const countdownTimerRef = useRef<number | null>(null);
|
||||||
|
const [countdownDuration, setCountdownDuration] = useState<number>(() => {
|
||||||
|
try {
|
||||||
|
const saved = localStorage.getItem(COUNTDOWN_STORAGE_KEY);
|
||||||
|
if (saved != null) {
|
||||||
|
const value = parseInt(saved, 10);
|
||||||
|
if (!isNaN(value)) {
|
||||||
|
return Math.min(COUNTDOWN_MAX_SECONDS, Math.max(0, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
return 3;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Persist countdown duration on change
|
||||||
|
useEffect(() => {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(COUNTDOWN_STORAGE_KEY, String(countdownDuration));
|
||||||
|
} catch (_) {}
|
||||||
|
}, [countdownDuration]);
|
||||||
|
|
||||||
|
// Load IWER first (must happen before anything else)
|
||||||
|
// Note: React Three Fiber's emulation is disabled (emulate: false) to avoid conflicts
|
||||||
|
useEffect(() => {
|
||||||
|
const loadIWER = async () => {
|
||||||
|
const { supportsImmersive, iwerLoaded: wasIwerLoaded } = await loadIWERIfNeeded();
|
||||||
|
if (!supportsImmersive) {
|
||||||
|
setErrorMessage('Immersive mode not supported');
|
||||||
|
setIwerLoaded(false);
|
||||||
|
setCapabilitiesValid(false);
|
||||||
|
capabilitiesCheckedRef.current = false; // Reset check flag on failure
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// IWER loaded successfully, now we can proceed with capability checks
|
||||||
|
setIwerLoaded(true);
|
||||||
|
// Store whether IWER was loaded for status message display later
|
||||||
|
if (wasIwerLoaded) {
|
||||||
|
sessionStorage.setItem('iwerWasLoaded', 'true');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loadIWER();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Update button state when IWER fails and UI becomes ready
|
||||||
|
useEffect(() => {
|
||||||
|
if (cloudXR2DUI && !iwerLoaded && !capabilitiesValid) {
|
||||||
|
cloudXR2DUI.setStartButtonState(true, 'CONNECT (immersive mode not supported)');
|
||||||
|
}
|
||||||
|
}, [cloudXR2DUI, iwerLoaded, capabilitiesValid]);
|
||||||
|
|
||||||
|
// Check capabilities once CloudXR2DUI is ready and IWER is loaded
|
||||||
|
useEffect(() => {
|
||||||
|
const checkCapabilitiesOnce = async () => {
|
||||||
|
if (!cloudXR2DUI || !iwerLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guard: only check capabilities once
|
||||||
|
if (capabilitiesCheckedRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
capabilitiesCheckedRef.current = true;
|
||||||
|
|
||||||
|
// Disable button and show checking status
|
||||||
|
cloudXR2DUI.setStartButtonState(true, 'CONNECT (checking capabilities)');
|
||||||
|
|
||||||
|
let result: { success: boolean; failures: string[]; warnings: string[] } = {
|
||||||
|
success: false,
|
||||||
|
failures: [],
|
||||||
|
warnings: [],
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
result = await checkCapabilities();
|
||||||
|
} catch (error) {
|
||||||
|
cloudXR2DUI.showStatus(`Capability check error: ${error}`, 'error');
|
||||||
|
setCapabilitiesValid(false);
|
||||||
|
cloudXR2DUI.setStartButtonState(true, 'CONNECT (capability check failed)');
|
||||||
|
capabilitiesCheckedRef.current = false; // Reset on error for potential retry
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!result.success) {
|
||||||
|
cloudXR2DUI.showStatus(
|
||||||
|
'Browser does not meet required capabilities:\n' + result.failures.join('\n'),
|
||||||
|
'error'
|
||||||
|
);
|
||||||
|
setCapabilitiesValid(false);
|
||||||
|
cloudXR2DUI.setStartButtonState(true, 'CONNECT (capability check failed)');
|
||||||
|
capabilitiesCheckedRef.current = false; // Reset on failure for potential retry
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show final status message with IWER info if applicable
|
||||||
|
const iwerWasLoaded = sessionStorage.getItem('iwerWasLoaded') === 'true';
|
||||||
|
if (result.warnings.length > 0) {
|
||||||
|
cloudXR2DUI.showStatus('Performance notice:\n' + result.warnings.join('\n'), 'info');
|
||||||
|
} else if (iwerWasLoaded) {
|
||||||
|
// Include IWER status in the final success message
|
||||||
|
cloudXR2DUI.showStatus(
|
||||||
|
'CloudXR.js SDK is supported. Ready to connect!\nUsing IWER (Immersive Web Emulator Runtime) - Emulating Meta Quest 3.',
|
||||||
|
'info'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
cloudXR2DUI.showStatus('CloudXR.js SDK is supported. Ready to connect!', 'success');
|
||||||
|
}
|
||||||
|
|
||||||
|
setCapabilitiesValid(true);
|
||||||
|
cloudXR2DUI.setStartButtonState(false, 'CONNECT');
|
||||||
|
};
|
||||||
|
|
||||||
|
checkCapabilitiesOnce();
|
||||||
|
}, [cloudXR2DUI, iwerLoaded]);
|
||||||
|
|
||||||
|
// Track config changes to trigger re-renders when form values change
|
||||||
|
const [configVersion, setConfigVersion] = useState(0);
|
||||||
|
|
||||||
|
// Initialize CloudXR2DUI
|
||||||
|
useEffect(() => {
|
||||||
|
// Create and initialize the 2D UI manager
|
||||||
|
const ui = new CloudXR2DUI(() => {
|
||||||
|
// Callback when configuration changes
|
||||||
|
setConfigVersion(v => v + 1);
|
||||||
|
});
|
||||||
|
ui.initialize();
|
||||||
|
ui.setupConnectButtonHandler(
|
||||||
|
async () => {
|
||||||
|
// Start XR session
|
||||||
|
if (ui.getConfiguration().immersiveMode === 'ar') {
|
||||||
|
await store.enterAR();
|
||||||
|
} else if (ui.getConfiguration().immersiveMode === 'vr') {
|
||||||
|
await store.enterVR();
|
||||||
|
} else {
|
||||||
|
setErrorMessage('Unrecognized immersive mode');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error: Error) => {
|
||||||
|
setErrorMessage(`Failed to start XR session: ${error}`);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
setCloudXR2DUI(ui);
|
||||||
|
|
||||||
|
// Cleanup function
|
||||||
|
return () => {
|
||||||
|
if (ui) {
|
||||||
|
ui.cleanup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Update HTML error message display when error state changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (cloudXR2DUI) {
|
||||||
|
if (errorMessage) {
|
||||||
|
cloudXR2DUI.showError(errorMessage);
|
||||||
|
} else {
|
||||||
|
cloudXR2DUI.hideError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [errorMessage, cloudXR2DUI]);
|
||||||
|
|
||||||
|
// Listen for XR session state changes to update button and UI visibility
|
||||||
|
useEffect(() => {
|
||||||
|
const handleXRStateChange = () => {
|
||||||
|
const xrState = store.getState();
|
||||||
|
|
||||||
|
if (xrState.mode === 'immersive-ar' || xrState.mode === 'immersive-vr') {
|
||||||
|
// XR session is active
|
||||||
|
setIsXRMode(true);
|
||||||
|
if (cloudXR2DUI) {
|
||||||
|
cloudXR2DUI.setStartButtonState(true, 'CONNECT (XR session active)');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// XR session ended
|
||||||
|
setIsXRMode(false);
|
||||||
|
if (cloudXR2DUI) {
|
||||||
|
cloudXR2DUI.setStartButtonState(false, 'CONNECT');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xrState.error) {
|
||||||
|
setErrorMessage(`XR session error: ${xrState.error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Subscribe to XR state changes
|
||||||
|
const unsubscribe = store.subscribe(handleXRStateChange);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
return () => {
|
||||||
|
unsubscribe();
|
||||||
|
setIsXRMode(false);
|
||||||
|
};
|
||||||
|
}, [cloudXR2DUI]);
|
||||||
|
|
||||||
|
// CloudXR status change handler
|
||||||
|
const handleStatusChange = (connected: boolean, status: string) => {
|
||||||
|
setIsConnected(connected);
|
||||||
|
setSessionStatus(status);
|
||||||
|
};
|
||||||
|
|
||||||
|
// UI Event Handlers
|
||||||
|
const handleStartTeleop = () => {
|
||||||
|
console.log('Start Teleop pressed');
|
||||||
|
|
||||||
|
if (!cloudXRSession) {
|
||||||
|
console.error('CloudXR session not available');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCountingDown || isTeleopRunning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin countdown before starting teleop (immediately if 0)
|
||||||
|
if (countdownDuration <= 0) {
|
||||||
|
setIsCountingDown(false);
|
||||||
|
setCountdownRemaining(0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
cloudXRSession.sendServerMessage(START_TELEOP_COMMAND);
|
||||||
|
console.log('Start teleop command sent');
|
||||||
|
setIsTeleopRunning(true);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to send teleop command:', error);
|
||||||
|
setIsTeleopRunning(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsCountingDown(true);
|
||||||
|
setCountdownRemaining(countdownDuration);
|
||||||
|
|
||||||
|
countdownTimerRef.current = window.setInterval(() => {
|
||||||
|
setCountdownRemaining(prev => {
|
||||||
|
if (prev <= 1) {
|
||||||
|
// Countdown finished
|
||||||
|
if (countdownTimerRef.current !== null) {
|
||||||
|
clearInterval(countdownTimerRef.current);
|
||||||
|
countdownTimerRef.current = null;
|
||||||
|
}
|
||||||
|
setIsCountingDown(false);
|
||||||
|
|
||||||
|
// Send start teleop command
|
||||||
|
|
||||||
|
try {
|
||||||
|
cloudXRSession.sendServerMessage(START_TELEOP_COMMAND);
|
||||||
|
console.log('Start teleop command sent');
|
||||||
|
setIsTeleopRunning(true);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to send teleop command:', error);
|
||||||
|
setIsTeleopRunning(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return prev - 1;
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStopTeleop = () => {
|
||||||
|
console.log('Stop Teleop pressed');
|
||||||
|
|
||||||
|
// If countdown is active, cancel it and reset state
|
||||||
|
if (isCountingDown) {
|
||||||
|
if (countdownTimerRef.current !== null) {
|
||||||
|
clearInterval(countdownTimerRef.current);
|
||||||
|
countdownTimerRef.current = null;
|
||||||
|
}
|
||||||
|
setIsCountingDown(false);
|
||||||
|
setCountdownRemaining(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cloudXRSession) {
|
||||||
|
console.error('CloudXR session not available');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send stop teleop command
|
||||||
|
const teleopCommand = {
|
||||||
|
type: 'teleop_command',
|
||||||
|
message: {
|
||||||
|
command: 'stop teleop',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
cloudXRSession.sendServerMessage(teleopCommand);
|
||||||
|
console.log('Stop teleop command sent');
|
||||||
|
setIsTeleopRunning(false);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to send teleop command:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResetTeleop = () => {
|
||||||
|
console.log('Reset Teleop pressed');
|
||||||
|
|
||||||
|
// Cancel any active countdown
|
||||||
|
if (countdownTimerRef.current !== null) {
|
||||||
|
clearInterval(countdownTimerRef.current);
|
||||||
|
countdownTimerRef.current = null;
|
||||||
|
}
|
||||||
|
setIsCountingDown(false);
|
||||||
|
setCountdownRemaining(0);
|
||||||
|
|
||||||
|
if (!cloudXRSession) {
|
||||||
|
console.error('CloudXR session not available');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send stop teleop command first
|
||||||
|
const stopCommand = {
|
||||||
|
type: 'teleop_command',
|
||||||
|
message: {
|
||||||
|
command: 'stop teleop',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send reset teleop command
|
||||||
|
const resetCommand = {
|
||||||
|
type: 'teleop_command',
|
||||||
|
message: {
|
||||||
|
command: 'reset teleop',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
cloudXRSession.sendServerMessage(stopCommand);
|
||||||
|
console.log('Stop teleop command sent');
|
||||||
|
cloudXRSession.sendServerMessage(resetCommand);
|
||||||
|
console.log('Reset teleop command sent');
|
||||||
|
setIsTeleopRunning(false);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to send teleop commands:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDisconnect = () => {
|
||||||
|
console.log('Disconnect pressed');
|
||||||
|
|
||||||
|
// Cleanup countdown state on disconnect
|
||||||
|
if (countdownTimerRef.current !== null) {
|
||||||
|
clearInterval(countdownTimerRef.current);
|
||||||
|
countdownTimerRef.current = null;
|
||||||
|
}
|
||||||
|
setIsCountingDown(false);
|
||||||
|
setCountdownRemaining(0);
|
||||||
|
setIsTeleopRunning(false);
|
||||||
|
|
||||||
|
const xrState = store.getState();
|
||||||
|
const session = xrState.session;
|
||||||
|
if (session) {
|
||||||
|
session.end().catch((err: unknown) => {
|
||||||
|
setErrorMessage(
|
||||||
|
`Failed to end XR session: ${err instanceof Error ? err.message : String(err)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Countdown configuration handlers (0-5 seconds)
|
||||||
|
const handleIncreaseCountdown = () => {
|
||||||
|
if (isCountingDown) return;
|
||||||
|
setCountdownDuration(prev => Math.min(COUNTDOWN_MAX_SECONDS, prev + 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDecreaseCountdown = () => {
|
||||||
|
if (isCountingDown) return;
|
||||||
|
setCountdownDuration(prev => Math.max(0, prev - 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Memo config based on configVersion (manual dependency tracker incremented on config changes)
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
const config = useMemo(
|
||||||
|
() => (cloudXR2DUI ? cloudXR2DUI.getConfiguration() : null),
|
||||||
|
[cloudXR2DUI, configVersion]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Sync XR mode state to body class for CSS styling
|
||||||
|
useEffect(() => {
|
||||||
|
if (isXRMode) {
|
||||||
|
document.body.classList.add('xr-mode');
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove('xr-mode');
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.body.classList.remove('xr-mode');
|
||||||
|
};
|
||||||
|
}, [isXRMode]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Canvas
|
||||||
|
events={noEvents}
|
||||||
|
style={{
|
||||||
|
background: '#000',
|
||||||
|
width: '100vw',
|
||||||
|
height: '100vh',
|
||||||
|
position: 'fixed',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
zIndex: -1,
|
||||||
|
}}
|
||||||
|
gl={{
|
||||||
|
preserveDrawingBuffer: true, // Keep buffer for custom rendering
|
||||||
|
antialias: true,
|
||||||
|
}}
|
||||||
|
camera={{ position: [0, 0, 0.65] }}
|
||||||
|
onWheel={e => {
|
||||||
|
e.preventDefault();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PointerEvents batchEvents={false} />
|
||||||
|
<XR store={store}>
|
||||||
|
<NonAREnvironment />
|
||||||
|
<XROrigin />
|
||||||
|
{cloudXR2DUI && config && (
|
||||||
|
<>
|
||||||
|
<CloudXRComponent
|
||||||
|
config={config}
|
||||||
|
onStatusChange={handleStatusChange}
|
||||||
|
onError={error => {
|
||||||
|
if (cloudXR2DUI) {
|
||||||
|
cloudXR2DUI.showError(error);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onSessionReady={setCloudXRSession}
|
||||||
|
onServerAddress={setServerAddress}
|
||||||
|
/>
|
||||||
|
<CloudXR3DUI
|
||||||
|
onStartTeleop={handleStartTeleop}
|
||||||
|
onStopTeleop={handleStopTeleop}
|
||||||
|
onDisconnect={handleDisconnect}
|
||||||
|
onResetTeleop={handleResetTeleop}
|
||||||
|
serverAddress={serverAddress || config.serverIP}
|
||||||
|
sessionStatus={sessionStatus}
|
||||||
|
playLabel={
|
||||||
|
isTeleopRunning
|
||||||
|
? 'Running'
|
||||||
|
: isCountingDown
|
||||||
|
? `Starting in ${countdownRemaining} sec...`
|
||||||
|
: 'Play'
|
||||||
|
}
|
||||||
|
playDisabled={isCountingDown || isTeleopRunning}
|
||||||
|
countdownSeconds={countdownDuration}
|
||||||
|
onCountdownIncrease={handleIncreaseCountdown}
|
||||||
|
onCountdownDecrease={handleDecreaseCountdown}
|
||||||
|
countdownDisabled={isCountingDown}
|
||||||
|
position={[0, 1.6, -1.8]}
|
||||||
|
rotation={[0, 0, 0]}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</XR>
|
||||||
|
</Canvas>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
438
deps/cloudxr/isaac/src/CloudXR2DUI.tsx
vendored
Normal file
@@ -0,0 +1,438 @@
|
|||||||
|
/**
|
||||||
|
* CloudXR2DUI.tsx - CloudXR 2D User Interface Management
|
||||||
|
*
|
||||||
|
* This class handles all the HTML form interactions, localStorage persistence,
|
||||||
|
* and form validation for the CloudXR React example. It follows the same pattern
|
||||||
|
* as the simple example's CloudXRWebUI class, providing a clean separation
|
||||||
|
* between UI management and React component logic.
|
||||||
|
*
|
||||||
|
* Features:
|
||||||
|
* - Form field management and localStorage persistence
|
||||||
|
* - Proxy configuration based on protocol
|
||||||
|
* - Form validation and default value handling
|
||||||
|
* - Event listener management
|
||||||
|
* - Error handling and logging
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { CloudXRConfig, enableLocalStorage, setupCertificateAcceptanceLink } from '@helpers/utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2D UI Management for CloudXR React Example
|
||||||
|
* Handles the main user interface for CloudXR streaming, including form management,
|
||||||
|
* localStorage persistence, and user interaction controls.
|
||||||
|
*/
|
||||||
|
export class CloudXR2DUI {
|
||||||
|
/** Button to initiate XR streaming session */
|
||||||
|
private startButton!: HTMLButtonElement;
|
||||||
|
/** Input field for the CloudXR server IP address */
|
||||||
|
private serverIpInput!: HTMLInputElement;
|
||||||
|
/** Input field for the CloudXR server port number */
|
||||||
|
private portInput!: HTMLInputElement;
|
||||||
|
/** Input field for proxy URL configuration */
|
||||||
|
private proxyUrlInput!: HTMLInputElement;
|
||||||
|
/** Dropdown to select between AR and VR immersive modes */
|
||||||
|
private immersiveSelect!: HTMLSelectElement;
|
||||||
|
/** Dropdown to select device frame rate (FPS) */
|
||||||
|
private deviceFrameRateSelect!: HTMLSelectElement;
|
||||||
|
/** Dropdown to select max streaming bitrate (Mbps) */
|
||||||
|
private maxStreamingBitrateMbpsSelect!: HTMLSelectElement;
|
||||||
|
/** Input field for per-eye width configuration */
|
||||||
|
private perEyeWidthInput!: HTMLInputElement;
|
||||||
|
/** Input field for per-eye height configuration */
|
||||||
|
private perEyeHeightInput!: HTMLInputElement;
|
||||||
|
/** Dropdown to select server backend type */
|
||||||
|
private serverTypeSelect!: HTMLSelectElement;
|
||||||
|
/** Dropdown to select application type */
|
||||||
|
private appSelect!: HTMLSelectElement;
|
||||||
|
/** Dropdown to select reference space for XR tracking */
|
||||||
|
private referenceSpaceSelect!: HTMLSelectElement;
|
||||||
|
/** Input for XR reference space X offset (cm) */
|
||||||
|
private xrOffsetXInput!: HTMLInputElement;
|
||||||
|
/** Input for XR reference space Y offset (cm) */
|
||||||
|
private xrOffsetYInput!: HTMLInputElement;
|
||||||
|
/** Input for XR reference space Z offset (cm) */
|
||||||
|
private xrOffsetZInput!: HTMLInputElement;
|
||||||
|
/** Text element displaying proxy configuration help */
|
||||||
|
private proxyDefaultText!: HTMLElement;
|
||||||
|
/** Error message box element */
|
||||||
|
private errorMessageBox!: HTMLElement;
|
||||||
|
/** Error message text element */
|
||||||
|
private errorMessageText!: HTMLElement;
|
||||||
|
/** Certificate acceptance link container */
|
||||||
|
private certAcceptanceLink!: HTMLElement;
|
||||||
|
/** Certificate acceptance link anchor */
|
||||||
|
private certLink!: HTMLAnchorElement;
|
||||||
|
/** Flag to track if the 2D UI has been initialized */
|
||||||
|
private initialized: boolean = false;
|
||||||
|
|
||||||
|
/** Current form configuration state */
|
||||||
|
private currentConfiguration: CloudXRConfig;
|
||||||
|
/** Callback function for configuration changes */
|
||||||
|
private onConfigurationChange: ((config: CloudXRConfig) => void) | null = null;
|
||||||
|
/** Connect button click handler for cleanup */
|
||||||
|
private handleConnectClick: ((event: Event) => void) | null = null;
|
||||||
|
/** Array to store all event listeners for proper cleanup */
|
||||||
|
private eventListeners: Array<{
|
||||||
|
element: HTMLElement;
|
||||||
|
event: string;
|
||||||
|
handler: EventListener;
|
||||||
|
}> = [];
|
||||||
|
/** Cleanup function for certificate acceptance link */
|
||||||
|
private certLinkCleanup: (() => void) | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new CloudXR2DUI instance
|
||||||
|
* @param onConfigurationChange - Callback function called when configuration changes
|
||||||
|
*/
|
||||||
|
constructor(onConfigurationChange?: (config: CloudXRConfig) => void) {
|
||||||
|
this.onConfigurationChange = onConfigurationChange || null;
|
||||||
|
this.currentConfiguration = this.getDefaultConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the CloudXR2DUI with all necessary components and event handlers
|
||||||
|
*/
|
||||||
|
public initialize(): void {
|
||||||
|
if (this.initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.initializeElements();
|
||||||
|
this.setupLocalStorage();
|
||||||
|
this.setupProxyConfiguration();
|
||||||
|
this.setupEventListeners();
|
||||||
|
this.updateConfiguration();
|
||||||
|
this.setStartButtonState(false, 'CONNECT');
|
||||||
|
this.initialized = true;
|
||||||
|
} catch (error) {
|
||||||
|
// Continue with default values if initialization fails
|
||||||
|
this.showError(`Failed to initialize CloudXR2DUI: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes all DOM element references by their IDs
|
||||||
|
* Throws an error if any required element is not found
|
||||||
|
*/
|
||||||
|
private initializeElements(): void {
|
||||||
|
this.startButton = this.getElement<HTMLButtonElement>('startButton');
|
||||||
|
this.serverIpInput = this.getElement<HTMLInputElement>('serverIpInput');
|
||||||
|
this.portInput = this.getElement<HTMLInputElement>('portInput');
|
||||||
|
this.proxyUrlInput = this.getElement<HTMLInputElement>('proxyUrl');
|
||||||
|
this.immersiveSelect = this.getElement<HTMLSelectElement>('immersive');
|
||||||
|
this.deviceFrameRateSelect = this.getElement<HTMLSelectElement>('deviceFrameRate');
|
||||||
|
this.maxStreamingBitrateMbpsSelect =
|
||||||
|
this.getElement<HTMLSelectElement>('maxStreamingBitrateMbps');
|
||||||
|
this.perEyeWidthInput = this.getElement<HTMLInputElement>('perEyeWidth');
|
||||||
|
this.perEyeHeightInput = this.getElement<HTMLInputElement>('perEyeHeight');
|
||||||
|
this.serverTypeSelect = this.getElement<HTMLSelectElement>('serverType');
|
||||||
|
this.appSelect = this.getElement<HTMLSelectElement>('app');
|
||||||
|
this.referenceSpaceSelect = this.getElement<HTMLSelectElement>('referenceSpace');
|
||||||
|
this.xrOffsetXInput = this.getElement<HTMLInputElement>('xrOffsetX');
|
||||||
|
this.xrOffsetYInput = this.getElement<HTMLInputElement>('xrOffsetY');
|
||||||
|
this.xrOffsetZInput = this.getElement<HTMLInputElement>('xrOffsetZ');
|
||||||
|
this.proxyDefaultText = this.getElement<HTMLElement>('proxyDefaultText');
|
||||||
|
this.errorMessageBox = this.getElement<HTMLElement>('errorMessageBox');
|
||||||
|
this.errorMessageText = this.getElement<HTMLElement>('errorMessageText');
|
||||||
|
this.certAcceptanceLink = this.getElement<HTMLElement>('certAcceptanceLink');
|
||||||
|
this.certLink = this.getElement<HTMLAnchorElement>('certLink');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a DOM element by ID with type safety
|
||||||
|
* @param id - The element ID to find
|
||||||
|
* @returns The found element with the specified type
|
||||||
|
* @throws Error if element is not found
|
||||||
|
*/
|
||||||
|
private getElement<T extends HTMLElement>(id: string): T {
|
||||||
|
const element = document.getElementById(id) as T;
|
||||||
|
if (!element) {
|
||||||
|
throw new Error(`Element with id '${id}' not found`);
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default configuration values
|
||||||
|
* @returns Default configuration object
|
||||||
|
*/
|
||||||
|
private getDefaultConfiguration(): CloudXRConfig {
|
||||||
|
const useSecure = typeof window !== 'undefined' ? window.location.protocol === 'https:' : false;
|
||||||
|
// Default port: HTTP → 49100, HTTPS without proxy → 48322, HTTPS with proxy → 443
|
||||||
|
const defaultPort = useSecure ? 48322 : 49100;
|
||||||
|
return {
|
||||||
|
serverIP: '127.0.0.1',
|
||||||
|
port: defaultPort,
|
||||||
|
useSecureConnection: useSecure,
|
||||||
|
perEyeWidth: 2048,
|
||||||
|
perEyeHeight: 1792,
|
||||||
|
deviceFrameRate: 90,
|
||||||
|
maxStreamingBitrateMbps: 150,
|
||||||
|
immersiveMode: 'ar',
|
||||||
|
app: 'generic',
|
||||||
|
serverType: 'manual',
|
||||||
|
proxyUrl: '',
|
||||||
|
referenceSpaceType: 'auto',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables localStorage persistence for form inputs
|
||||||
|
* Automatically saves and restores user preferences
|
||||||
|
*/
|
||||||
|
private setupLocalStorage(): void {
|
||||||
|
enableLocalStorage(this.serverTypeSelect, 'serverType');
|
||||||
|
enableLocalStorage(this.serverIpInput, 'serverIp');
|
||||||
|
enableLocalStorage(this.portInput, 'port');
|
||||||
|
enableLocalStorage(this.perEyeWidthInput, 'perEyeWidth');
|
||||||
|
enableLocalStorage(this.perEyeHeightInput, 'perEyeHeight');
|
||||||
|
enableLocalStorage(this.proxyUrlInput, 'proxyUrl');
|
||||||
|
enableLocalStorage(this.deviceFrameRateSelect, 'deviceFrameRate');
|
||||||
|
enableLocalStorage(this.maxStreamingBitrateMbpsSelect, 'maxStreamingBitrateMbps');
|
||||||
|
enableLocalStorage(this.immersiveSelect, 'immersiveMode');
|
||||||
|
enableLocalStorage(this.appSelect, 'app');
|
||||||
|
enableLocalStorage(this.referenceSpaceSelect, 'referenceSpace');
|
||||||
|
enableLocalStorage(this.xrOffsetXInput, 'xrOffsetX');
|
||||||
|
enableLocalStorage(this.xrOffsetYInput, 'xrOffsetY');
|
||||||
|
enableLocalStorage(this.xrOffsetZInput, 'xrOffsetZ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures proxy settings based on the current protocol (HTTP/HTTPS)
|
||||||
|
* Sets appropriate placeholders and help text for port and proxy URL inputs
|
||||||
|
*/
|
||||||
|
private setupProxyConfiguration(): void {
|
||||||
|
// Update port placeholder based on protocol
|
||||||
|
if (window.location.protocol === 'https:') {
|
||||||
|
this.portInput.placeholder = 'Port (default: 48322, or 443 if proxy URL set)';
|
||||||
|
} else {
|
||||||
|
this.portInput.placeholder = 'Port (default: 49100)';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default text and placeholder based on protocol
|
||||||
|
if (window.location.protocol === 'https:') {
|
||||||
|
this.proxyDefaultText.textContent =
|
||||||
|
'Optional: Leave empty for direct WSS connection, or provide URL for proxy routing (e.g., https://proxy.example.com/)';
|
||||||
|
this.proxyUrlInput.placeholder = '';
|
||||||
|
} else {
|
||||||
|
this.proxyDefaultText.textContent = 'Not needed for HTTP - uses direct WS connection';
|
||||||
|
this.proxyUrlInput.placeholder = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up event listeners for form input changes
|
||||||
|
* Handles both input and change events for better compatibility
|
||||||
|
*/
|
||||||
|
private setupEventListeners(): void {
|
||||||
|
// Update configuration when form inputs change
|
||||||
|
const updateConfig = () => this.updateConfiguration();
|
||||||
|
|
||||||
|
// Helper function to add listeners and store them for cleanup
|
||||||
|
const addListener = (element: HTMLElement, event: string, handler: EventListener) => {
|
||||||
|
element.addEventListener(event, handler);
|
||||||
|
this.eventListeners.push({ element, event, handler });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add event listeners for all form fields
|
||||||
|
addListener(this.serverTypeSelect, 'change', updateConfig);
|
||||||
|
addListener(this.serverIpInput, 'input', updateConfig);
|
||||||
|
addListener(this.serverIpInput, 'change', updateConfig);
|
||||||
|
addListener(this.portInput, 'input', updateConfig);
|
||||||
|
addListener(this.portInput, 'change', updateConfig);
|
||||||
|
addListener(this.perEyeWidthInput, 'input', updateConfig);
|
||||||
|
addListener(this.perEyeWidthInput, 'change', updateConfig);
|
||||||
|
addListener(this.perEyeHeightInput, 'input', updateConfig);
|
||||||
|
addListener(this.perEyeHeightInput, 'change', updateConfig);
|
||||||
|
addListener(this.deviceFrameRateSelect, 'change', updateConfig);
|
||||||
|
addListener(this.maxStreamingBitrateMbpsSelect, 'change', updateConfig);
|
||||||
|
addListener(this.immersiveSelect, 'change', updateConfig);
|
||||||
|
addListener(this.appSelect, 'change', updateConfig);
|
||||||
|
addListener(this.referenceSpaceSelect, 'change', updateConfig);
|
||||||
|
addListener(this.xrOffsetXInput, 'input', updateConfig);
|
||||||
|
addListener(this.xrOffsetXInput, 'change', updateConfig);
|
||||||
|
addListener(this.xrOffsetYInput, 'input', updateConfig);
|
||||||
|
addListener(this.xrOffsetYInput, 'change', updateConfig);
|
||||||
|
addListener(this.xrOffsetZInput, 'input', updateConfig);
|
||||||
|
addListener(this.xrOffsetZInput, 'change', updateConfig);
|
||||||
|
addListener(this.proxyUrlInput, 'input', updateConfig);
|
||||||
|
addListener(this.proxyUrlInput, 'change', updateConfig);
|
||||||
|
|
||||||
|
// Set up certificate acceptance link and store cleanup function
|
||||||
|
this.certLinkCleanup = setupCertificateAcceptanceLink(
|
||||||
|
this.serverIpInput,
|
||||||
|
this.portInput,
|
||||||
|
this.proxyUrlInput,
|
||||||
|
this.certAcceptanceLink,
|
||||||
|
this.certLink
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current configuration from form values
|
||||||
|
* Calls the configuration change callback if provided
|
||||||
|
*/
|
||||||
|
private updateConfiguration(): void {
|
||||||
|
const useSecure = this.getDefaultConfiguration().useSecureConnection;
|
||||||
|
const portValue = parseInt(this.portInput.value);
|
||||||
|
const hasProxy = this.proxyUrlInput.value.trim().length > 0;
|
||||||
|
|
||||||
|
// Smart default port based on connection type and proxy usage
|
||||||
|
let defaultPort = 49100; // HTTP default
|
||||||
|
if (useSecure) {
|
||||||
|
defaultPort = hasProxy ? 443 : 48322; // HTTPS with proxy → 443, HTTPS without → 48322
|
||||||
|
}
|
||||||
|
|
||||||
|
const newConfiguration: CloudXRConfig = {
|
||||||
|
serverIP: this.serverIpInput.value || this.getDefaultConfiguration().serverIP,
|
||||||
|
port: portValue || defaultPort,
|
||||||
|
useSecureConnection: useSecure,
|
||||||
|
perEyeWidth:
|
||||||
|
parseInt(this.perEyeWidthInput.value) || this.getDefaultConfiguration().perEyeWidth,
|
||||||
|
perEyeHeight:
|
||||||
|
parseInt(this.perEyeHeightInput.value) || this.getDefaultConfiguration().perEyeHeight,
|
||||||
|
deviceFrameRate:
|
||||||
|
parseInt(this.deviceFrameRateSelect.value) ||
|
||||||
|
this.getDefaultConfiguration().deviceFrameRate,
|
||||||
|
maxStreamingBitrateMbps:
|
||||||
|
parseInt(this.maxStreamingBitrateMbpsSelect.value) ||
|
||||||
|
this.getDefaultConfiguration().maxStreamingBitrateMbps,
|
||||||
|
immersiveMode:
|
||||||
|
(this.immersiveSelect.value as 'ar' | 'vr') || this.getDefaultConfiguration().immersiveMode,
|
||||||
|
app: this.appSelect.value || this.getDefaultConfiguration().app,
|
||||||
|
serverType: this.serverTypeSelect.value || this.getDefaultConfiguration().serverType,
|
||||||
|
proxyUrl: this.proxyUrlInput.value || this.getDefaultConfiguration().proxyUrl,
|
||||||
|
referenceSpaceType:
|
||||||
|
(this.referenceSpaceSelect.value as 'auto' | 'local-floor' | 'local' | 'viewer') ||
|
||||||
|
this.getDefaultConfiguration().referenceSpaceType,
|
||||||
|
// Convert cm from UI into meters for config (respect 0; if invalid, use 0)
|
||||||
|
xrOffsetX: (() => {
|
||||||
|
const v = parseFloat(this.xrOffsetXInput.value);
|
||||||
|
return Number.isFinite(v) ? v / 100 : 0;
|
||||||
|
})(),
|
||||||
|
xrOffsetY: (() => {
|
||||||
|
const v = parseFloat(this.xrOffsetYInput.value);
|
||||||
|
return Number.isFinite(v) ? v / 100 : 0;
|
||||||
|
})(),
|
||||||
|
xrOffsetZ: (() => {
|
||||||
|
const v = parseFloat(this.xrOffsetZInput.value);
|
||||||
|
return Number.isFinite(v) ? v / 100 : 0;
|
||||||
|
})(),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.currentConfiguration = newConfiguration;
|
||||||
|
|
||||||
|
// Call the configuration change callback if provided
|
||||||
|
if (this.onConfigurationChange) {
|
||||||
|
this.onConfigurationChange(newConfiguration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current configuration
|
||||||
|
* @returns Current configuration object
|
||||||
|
*/
|
||||||
|
public getConfiguration(): CloudXRConfig {
|
||||||
|
return { ...this.currentConfiguration };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the start button state
|
||||||
|
* @param disabled - Whether the button should be disabled
|
||||||
|
* @param text - Text to display on the button
|
||||||
|
*/
|
||||||
|
public setStartButtonState(disabled: boolean, text: string): void {
|
||||||
|
if (this.startButton) {
|
||||||
|
this.startButton.disabled = disabled;
|
||||||
|
this.startButton.innerHTML = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the connect button click handler
|
||||||
|
* @param onConnect - Function to call when connect button is clicked
|
||||||
|
* @param onError - Function to call when an error occurs
|
||||||
|
*/
|
||||||
|
public setupConnectButtonHandler(
|
||||||
|
onConnect: () => Promise<void>,
|
||||||
|
onError: (error: Error) => void
|
||||||
|
): void {
|
||||||
|
if (this.startButton) {
|
||||||
|
// Remove any existing listener
|
||||||
|
if (this.handleConnectClick) {
|
||||||
|
this.startButton.removeEventListener('click', this.handleConnectClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new handler
|
||||||
|
this.handleConnectClick = async () => {
|
||||||
|
// Disable button during XR session
|
||||||
|
this.setStartButtonState(true, 'CONNECT (starting XR session...)');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await onConnect();
|
||||||
|
} catch (error) {
|
||||||
|
this.setStartButtonState(false, 'CONNECT');
|
||||||
|
onError(error as Error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add the new listener
|
||||||
|
this.startButton.addEventListener('click', this.handleConnectClick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a status message in the UI with a specific type
|
||||||
|
* @param message - Message to display
|
||||||
|
* @param type - Message type: 'success', 'error', or 'info'
|
||||||
|
*/
|
||||||
|
public showStatus(message: string, type: 'success' | 'error' | 'info'): void {
|
||||||
|
if (this.errorMessageText && this.errorMessageBox) {
|
||||||
|
this.errorMessageText.textContent = message;
|
||||||
|
this.errorMessageBox.className = `error-message-box show ${type}`;
|
||||||
|
}
|
||||||
|
console[type === 'error' ? 'error' : 'info'](message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows an error message in the UI
|
||||||
|
* @param message - Error message to display
|
||||||
|
*/
|
||||||
|
public showError(message: string): void {
|
||||||
|
this.showStatus(message, 'error');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the error message
|
||||||
|
*/
|
||||||
|
public hideError(): void {
|
||||||
|
if (this.errorMessageBox) {
|
||||||
|
this.errorMessageBox.classList.remove('show');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up event listeners and resources
|
||||||
|
* Should be called when the component unmounts
|
||||||
|
*/
|
||||||
|
public cleanup(): void {
|
||||||
|
// Remove all stored event listeners
|
||||||
|
this.eventListeners.forEach(({ element, event, handler }) => {
|
||||||
|
element.removeEventListener(event, handler);
|
||||||
|
});
|
||||||
|
this.eventListeners = [];
|
||||||
|
|
||||||
|
// Remove CONNECT button listener
|
||||||
|
if (this.startButton && this.handleConnectClick) {
|
||||||
|
this.startButton.removeEventListener('click', this.handleConnectClick);
|
||||||
|
this.handleConnectClick = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up certificate acceptance link listeners
|
||||||
|
if (this.certLinkCleanup) {
|
||||||
|
this.certLinkCleanup();
|
||||||
|
this.certLinkCleanup = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
289
deps/cloudxr/isaac/src/CloudXRComponent.tsx
vendored
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
/**
|
||||||
|
* CloudXRComponent.tsx - CloudXR WebXR Integration Component
|
||||||
|
*
|
||||||
|
* This component handles the core CloudXR streaming functionality and WebXR integration.
|
||||||
|
* It manages:
|
||||||
|
* - CloudXR session lifecycle (creation, connection, disconnection, cleanup)
|
||||||
|
* - WebXR session event handling (sessionstart, sessionend)
|
||||||
|
* - WebGL state management and render target preservation
|
||||||
|
* - Frame-by-frame rendering loop with pose tracking and stream rendering
|
||||||
|
* - Server configuration and connection parameters
|
||||||
|
* - Status reporting back to parent components
|
||||||
|
*
|
||||||
|
* The component accepts configuration via props and communicates status changes
|
||||||
|
* and disconnect requests through callback props. It integrates with Three.js
|
||||||
|
* and React Three Fiber for WebXR rendering while preserving WebGL state
|
||||||
|
* for CloudXR's custom rendering pipeline.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getConnectionConfig, ConnectionConfiguration, CloudXRConfig } from '@helpers/utils';
|
||||||
|
import { bindGL } from '@helpers/WebGLStateBinding';
|
||||||
|
import * as CloudXR from '@nvidia/cloudxr';
|
||||||
|
import { useThree, useFrame } from '@react-three/fiber';
|
||||||
|
import { useXR } from '@react-three/xr';
|
||||||
|
import { useRef, useEffect } from 'react';
|
||||||
|
import type { WebGLRenderer } from 'three';
|
||||||
|
|
||||||
|
interface CloudXRComponentProps {
|
||||||
|
config: CloudXRConfig;
|
||||||
|
onStatusChange?: (isConnected: boolean, status: string) => void;
|
||||||
|
onError?: (error: string) => void;
|
||||||
|
onSessionReady?: (session: CloudXR.Session | null) => void;
|
||||||
|
onServerAddress?: (address: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// React component that integrates CloudXR with Three.js/WebXR
|
||||||
|
// This component handles the CloudXR session lifecycle and render loop
|
||||||
|
export default function CloudXRComponent({
|
||||||
|
config,
|
||||||
|
onStatusChange,
|
||||||
|
onError,
|
||||||
|
onSessionReady,
|
||||||
|
onServerAddress,
|
||||||
|
}: CloudXRComponentProps) {
|
||||||
|
const threeRenderer: WebGLRenderer = useThree().gl;
|
||||||
|
const { session } = useXR();
|
||||||
|
// React reference to the CloudXR session that persists across re-renders.
|
||||||
|
const cxrSessionRef = useRef<CloudXR.Session | null>(null);
|
||||||
|
|
||||||
|
// Disable Three.js so it doesn't clear the framebuffer after CloudXR renders.
|
||||||
|
threeRenderer.autoClear = false;
|
||||||
|
|
||||||
|
// Access Three.js WebXRManager and WebGL context.
|
||||||
|
const gl: WebGL2RenderingContext = threeRenderer.getContext() as WebGL2RenderingContext;
|
||||||
|
|
||||||
|
const trackedGL = bindGL(gl);
|
||||||
|
|
||||||
|
// Set up event listeners in useEffect to add them only once
|
||||||
|
useEffect(() => {
|
||||||
|
const webXRManager = threeRenderer.xr;
|
||||||
|
|
||||||
|
if (webXRManager) {
|
||||||
|
const handleSessionStart = async () => {
|
||||||
|
// Explicitly request the desired reference space from the XRSession to avoid
|
||||||
|
// inheriting a default 'local-floor' space that could stack with UI offsets.
|
||||||
|
let referenceSpace: XRReferenceSpace | null = null;
|
||||||
|
try {
|
||||||
|
const xrSession: XRSession | null = (webXRManager as any).getSession
|
||||||
|
? (webXRManager as any).getSession()
|
||||||
|
: null;
|
||||||
|
if (xrSession) {
|
||||||
|
if (config.referenceSpaceType === 'auto') {
|
||||||
|
const fallbacks: XRReferenceSpaceType[] = [
|
||||||
|
'local-floor',
|
||||||
|
'local',
|
||||||
|
'viewer',
|
||||||
|
'unbounded',
|
||||||
|
];
|
||||||
|
for (const t of fallbacks) {
|
||||||
|
try {
|
||||||
|
referenceSpace = await xrSession.requestReferenceSpace(t);
|
||||||
|
if (referenceSpace) break;
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
referenceSpace = await xrSession.requestReferenceSpace(
|
||||||
|
config.referenceSpaceType as XRReferenceSpaceType
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
`Failed to request reference space '${config.referenceSpaceType}':`,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to request XR reference space:', error);
|
||||||
|
referenceSpace = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!referenceSpace) {
|
||||||
|
// As a last resort, fall back to WebXRManager's current reference space
|
||||||
|
referenceSpace = webXRManager.getReferenceSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (referenceSpace) {
|
||||||
|
// Ensure that the session is not already created.
|
||||||
|
if (cxrSessionRef.current) {
|
||||||
|
console.error('CloudXR session already exists');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const glBinding = webXRManager.getBinding();
|
||||||
|
if (!glBinding) {
|
||||||
|
console.warn('No WebGL binding found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply proxy configuration logic
|
||||||
|
let connectionConfig: ConnectionConfiguration;
|
||||||
|
try {
|
||||||
|
connectionConfig = getConnectionConfig(config.serverIP, config.port, config.proxyUrl);
|
||||||
|
onServerAddress?.(connectionConfig.serverIP);
|
||||||
|
} catch (error) {
|
||||||
|
onStatusChange?.(false, 'Configuration Error');
|
||||||
|
onError?.(`Proxy configuration failed: ${error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply XR offset if provided in config (meters)
|
||||||
|
const offsetX = config.xrOffsetX || 0;
|
||||||
|
const offsetY = config.xrOffsetY || 0;
|
||||||
|
const offsetZ = config.xrOffsetZ || 0;
|
||||||
|
if (offsetX !== 0 || offsetY !== 0 || offsetZ !== 0) {
|
||||||
|
const offsetTransform = new XRRigidTransform(
|
||||||
|
{ x: offsetX, y: offsetY, z: offsetZ },
|
||||||
|
{ x: 0, y: 0, z: 0, w: 1 }
|
||||||
|
);
|
||||||
|
referenceSpace = referenceSpace.getOffsetReferenceSpace(offsetTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in CloudXR session options.
|
||||||
|
const cloudXROptions: CloudXR.SessionOptions = {
|
||||||
|
serverAddress: connectionConfig.serverIP,
|
||||||
|
serverPort: connectionConfig.port,
|
||||||
|
useSecureConnection: connectionConfig.useSecureConnection,
|
||||||
|
perEyeWidth: config.perEyeWidth,
|
||||||
|
perEyeHeight: config.perEyeHeight,
|
||||||
|
gl: gl,
|
||||||
|
referenceSpace: referenceSpace,
|
||||||
|
deviceFrameRate: config.deviceFrameRate,
|
||||||
|
maxStreamingBitrateKbps: config.maxStreamingBitrateMbps * 1000, // Convert Mbps to Kbps
|
||||||
|
glBinding: glBinding,
|
||||||
|
telemetry: {
|
||||||
|
enabled: true,
|
||||||
|
appInfo: {
|
||||||
|
version: '6.0.0-beta',
|
||||||
|
product: 'CloudXR.js React Example',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store the render target and key GL bindings to restore after CloudXR rendering
|
||||||
|
const cloudXRDelegates: CloudXR.SessionDelegates = {
|
||||||
|
onWebGLStateChangeBegin: () => {
|
||||||
|
// Save the current render target before CloudXR changes state
|
||||||
|
trackedGL.save();
|
||||||
|
},
|
||||||
|
onWebGLStateChangeEnd: () => {
|
||||||
|
// Restore the tracked GL state to the state before CloudXR rendering.
|
||||||
|
trackedGL.restore();
|
||||||
|
},
|
||||||
|
onStreamStarted: () => {
|
||||||
|
console.debug('CloudXR stream started');
|
||||||
|
onStatusChange?.(true, 'Connected');
|
||||||
|
},
|
||||||
|
onStreamStopped: (error?: Error) => {
|
||||||
|
if (error) {
|
||||||
|
onStatusChange?.(false, 'Error');
|
||||||
|
onError?.(`CloudXR session stopped with error: ${error.message}`);
|
||||||
|
} else {
|
||||||
|
console.debug('CloudXR session stopped');
|
||||||
|
onStatusChange?.(false, 'Disconnected');
|
||||||
|
}
|
||||||
|
// Clear the session reference
|
||||||
|
cxrSessionRef.current = null;
|
||||||
|
onSessionReady?.(null);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create the CloudXR session.
|
||||||
|
let cxrSession: CloudXR.Session;
|
||||||
|
try {
|
||||||
|
cxrSession = CloudXR.createSession(cloudXROptions, cloudXRDelegates);
|
||||||
|
} catch (error) {
|
||||||
|
onStatusChange?.(false, 'Session Creation Failed');
|
||||||
|
onError?.(`Failed to create CloudXR session: ${error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the session in the ref so it persists across re-renders
|
||||||
|
cxrSessionRef.current = cxrSession;
|
||||||
|
|
||||||
|
// Notify parent that session is ready
|
||||||
|
onSessionReady?.(cxrSession);
|
||||||
|
|
||||||
|
// Start session (synchronous call that initiates connection)
|
||||||
|
try {
|
||||||
|
cxrSession.connect();
|
||||||
|
console.log('CloudXR session connect initiated');
|
||||||
|
// Note: The session will transition to Connected state via the onStreamStarted callback
|
||||||
|
// Use cxrSession.state to check if streaming has actually started
|
||||||
|
} catch (error) {
|
||||||
|
onStatusChange?.(false, 'Connection Failed');
|
||||||
|
// Report error via callback
|
||||||
|
onError?.('Failed to connect CloudXR session');
|
||||||
|
// Clean up the failed session
|
||||||
|
cxrSessionRef.current = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSessionEnd = () => {
|
||||||
|
if (cxrSessionRef.current) {
|
||||||
|
cxrSessionRef.current.disconnect();
|
||||||
|
cxrSessionRef.current = null;
|
||||||
|
onSessionReady?.(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add start+end session event listeners to the WebXRManager.
|
||||||
|
webXRManager.addEventListener('sessionstart', handleSessionStart);
|
||||||
|
webXRManager.addEventListener('sessionend', handleSessionEnd);
|
||||||
|
|
||||||
|
// Cleanup function to remove listeners
|
||||||
|
return () => {
|
||||||
|
webXRManager.removeEventListener('sessionstart', handleSessionStart);
|
||||||
|
webXRManager.removeEventListener('sessionend', handleSessionEnd);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [threeRenderer, config]); // Re-register handlers when renderer or config changes
|
||||||
|
|
||||||
|
// Custom render loop - runs every frame
|
||||||
|
useFrame((state, delta) => {
|
||||||
|
const webXRManager = threeRenderer.xr;
|
||||||
|
|
||||||
|
if (webXRManager.isPresenting && session) {
|
||||||
|
// Access the current WebXR XRFrame
|
||||||
|
const xrFrame = state.gl.xr.getFrame();
|
||||||
|
if (xrFrame) {
|
||||||
|
// Get THREE WebXRManager from the the useFrame state.
|
||||||
|
const webXRManager = state.gl.xr;
|
||||||
|
|
||||||
|
if (!cxrSessionRef || !cxrSessionRef.current) {
|
||||||
|
console.debug('Skipping frame, no session yet');
|
||||||
|
// Clear the framebuffer as we've set autoClear to false.
|
||||||
|
threeRenderer.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get session from reference.
|
||||||
|
const cxrSession: CloudXR.Session = cxrSessionRef.current;
|
||||||
|
|
||||||
|
// If the CloudXR session is not connected, skip the frame.
|
||||||
|
if (cxrSession.state !== CloudXR.SessionState.Connected) {
|
||||||
|
console.debug('Skipping frame, session not connected, state:', cxrSession.state);
|
||||||
|
// Clear the framebuffer as we've set autoClear to false.
|
||||||
|
threeRenderer.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get timestamp from useFrame state and convert to milliseconds.
|
||||||
|
const timestamp: DOMHighResTimeStamp = state.clock.elapsedTime * 1000;
|
||||||
|
|
||||||
|
// Send the tracking state (including viewer pose and hand/controller data) to the server, this will trigger server-side rendering for frame.
|
||||||
|
cxrSession.sendTrackingStateToServer(timestamp, xrFrame);
|
||||||
|
|
||||||
|
// Get the WebXR layer from THREE WebXRManager.
|
||||||
|
let layer: XRWebGLLayer = webXRManager.getBaseLayer() as XRWebGLLayer;
|
||||||
|
|
||||||
|
// Render the current streamed CloudXR frame (not the frame that was just sent to the server).
|
||||||
|
cxrSession.render(timestamp, xrFrame, layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, -1000);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
218
deps/cloudxr/isaac/src/CloudXRUI.tsx
vendored
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/**
|
||||||
|
* CloudXRUI.tsx - CloudXR User Interface Component
|
||||||
|
*
|
||||||
|
* This component renders the in-VR user interface for the CloudXR application using
|
||||||
|
* React Three UIKit. It provides:
|
||||||
|
* - CloudXR branding and title display
|
||||||
|
* - Server connection information and status display
|
||||||
|
* - Interactive control buttons (Start Teleop, Reset Teleop, Disconnect)
|
||||||
|
* - Responsive button layout with hover effects
|
||||||
|
* - Integration with parent component event handlers
|
||||||
|
* - Configurable position and rotation in world space for flexible UI placement
|
||||||
|
*
|
||||||
|
* The UI is positioned in 3D space and designed for VR/AR interaction with
|
||||||
|
* visual feedback and clear button labeling. All interactions are passed
|
||||||
|
* back to the parent component through callback props.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Container, Text, Image } from '@react-three/uikit';
|
||||||
|
import { Button } from '@react-three/uikit-default';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
interface CloudXRUIProps {
|
||||||
|
onStartTeleop?: () => void;
|
||||||
|
onDisconnect?: () => void;
|
||||||
|
onResetTeleop?: () => void;
|
||||||
|
serverAddress?: string;
|
||||||
|
sessionStatus?: string;
|
||||||
|
playLabel?: string;
|
||||||
|
playDisabled?: boolean;
|
||||||
|
countdownSeconds?: number;
|
||||||
|
onCountdownIncrease?: () => void;
|
||||||
|
onCountdownDecrease?: () => void;
|
||||||
|
countdownDisabled?: boolean;
|
||||||
|
position?: [number, number, number];
|
||||||
|
rotation?: [number, number, number];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CloudXR3DUI({
|
||||||
|
onStartTeleop,
|
||||||
|
onDisconnect,
|
||||||
|
onResetTeleop,
|
||||||
|
serverAddress = '127.0.0.1',
|
||||||
|
sessionStatus = 'Disconnected',
|
||||||
|
playLabel = 'Play',
|
||||||
|
playDisabled = false,
|
||||||
|
countdownSeconds,
|
||||||
|
onCountdownIncrease,
|
||||||
|
onCountdownDecrease,
|
||||||
|
countdownDisabled = false,
|
||||||
|
position = [1.8, 1.75, -1.3],
|
||||||
|
rotation = [0, -0.3, 0],
|
||||||
|
}: CloudXRUIProps) {
|
||||||
|
return (
|
||||||
|
<group position={position} rotation={rotation}>
|
||||||
|
<Container
|
||||||
|
pixelSize={0.001}
|
||||||
|
width={1920}
|
||||||
|
height={1584}
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
pointerEvents="auto"
|
||||||
|
padding={40}
|
||||||
|
sizeX={3}
|
||||||
|
sizeY={2.475}
|
||||||
|
>
|
||||||
|
<Container
|
||||||
|
width={1600}
|
||||||
|
height={900}
|
||||||
|
backgroundColor="rgba(40, 40, 40, 0.85)"
|
||||||
|
borderRadius={20}
|
||||||
|
padding={60}
|
||||||
|
paddingBottom={80}
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
flexDirection="column"
|
||||||
|
gap={36}
|
||||||
|
>
|
||||||
|
{/* Title */}
|
||||||
|
<Text fontSize={96} fontWeight="bold" color="white" textAlign="center">
|
||||||
|
Controls
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Server Info */}
|
||||||
|
<Text fontSize={48} color="white" textAlign="center" marginBottom={24}>
|
||||||
|
Server address: {serverAddress}
|
||||||
|
</Text>
|
||||||
|
<Text fontSize={48} color="white" textAlign="center" marginBottom={48}>
|
||||||
|
Session status: {sessionStatus}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Countdown Config Row */}
|
||||||
|
<Container flexDirection="row" gap={24} alignItems="center" justifyContent="center">
|
||||||
|
<Text fontSize={40} color="white">
|
||||||
|
Countdown
|
||||||
|
</Text>
|
||||||
|
<Button
|
||||||
|
onClick={onCountdownDecrease}
|
||||||
|
variant="default"
|
||||||
|
width={105}
|
||||||
|
height={105}
|
||||||
|
borderRadius={52.5}
|
||||||
|
backgroundColor="rgba(220, 220, 220, 0.9)"
|
||||||
|
disabled={countdownDisabled}
|
||||||
|
>
|
||||||
|
<Text fontSize={48} color="black" fontWeight="bold">
|
||||||
|
-
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
<Container
|
||||||
|
width={180}
|
||||||
|
height={105}
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
backgroundColor="rgba(255,255,255,0.9)"
|
||||||
|
borderRadius={12}
|
||||||
|
>
|
||||||
|
<Text fontSize={56} color="black">
|
||||||
|
{countdownSeconds}s
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
<Button
|
||||||
|
onClick={onCountdownIncrease}
|
||||||
|
variant="default"
|
||||||
|
width={105}
|
||||||
|
height={105}
|
||||||
|
borderRadius={52.5}
|
||||||
|
backgroundColor="rgba(220, 220, 220, 0.9)"
|
||||||
|
disabled={countdownDisabled}
|
||||||
|
>
|
||||||
|
<Text fontSize={48} color="black" fontWeight="bold">
|
||||||
|
+
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
{/* Button Grid */}
|
||||||
|
<Container
|
||||||
|
flexDirection="column"
|
||||||
|
gap={60}
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
width="100%"
|
||||||
|
>
|
||||||
|
{/* Start/reset row*/}
|
||||||
|
<Container flexDirection="row" gap={60} justifyContent="center">
|
||||||
|
<Button
|
||||||
|
onClick={onStartTeleop}
|
||||||
|
variant="default"
|
||||||
|
width={480}
|
||||||
|
height={120}
|
||||||
|
borderRadius={40}
|
||||||
|
backgroundColor="rgba(220, 220, 220, 0.9)"
|
||||||
|
hover={{
|
||||||
|
backgroundColor: 'rgba(100, 150, 255, 1)',
|
||||||
|
borderColor: 'white',
|
||||||
|
borderWidth: 2,
|
||||||
|
}}
|
||||||
|
disabled={playDisabled}
|
||||||
|
>
|
||||||
|
<Container flexDirection="row" alignItems="center" gap={12}>
|
||||||
|
{playLabel === 'Play' && <Image src="./play-circle.svg" width={60} height={60} />}
|
||||||
|
<Text fontSize={48} color="black" fontWeight="medium">
|
||||||
|
{playLabel}
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
onClick={onResetTeleop}
|
||||||
|
variant="default"
|
||||||
|
width={480}
|
||||||
|
height={120}
|
||||||
|
borderRadius={40}
|
||||||
|
backgroundColor="rgba(220, 220, 220, 0.9)"
|
||||||
|
hover={{
|
||||||
|
backgroundColor: 'rgba(100, 150, 255, 1)',
|
||||||
|
borderColor: 'white',
|
||||||
|
borderWidth: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Container flexDirection="row" alignItems="center" gap={12}>
|
||||||
|
<Image src="./arrow-uturn-left.svg" width={60} height={60} />
|
||||||
|
<Text fontSize={48} color="black" fontWeight="medium">
|
||||||
|
Reset
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
</Button>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
{/* Bottom Row */}
|
||||||
|
<Container flexDirection="row" justifyContent="center">
|
||||||
|
<Button
|
||||||
|
onClick={onDisconnect}
|
||||||
|
variant="destructive"
|
||||||
|
width={330}
|
||||||
|
height={105}
|
||||||
|
borderRadius={35}
|
||||||
|
backgroundColor="rgba(255, 150, 150, 0.9)"
|
||||||
|
hover={{
|
||||||
|
backgroundColor: 'rgba(255, 50, 50, 1)',
|
||||||
|
borderColor: 'white',
|
||||||
|
borderWidth: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Container flexDirection="row" alignItems="center" gap={12}>
|
||||||
|
<Image src="./arrow-left-start-on-rectangle.svg" width={60} height={60} />
|
||||||
|
<Text fontSize={40} color="black" fontWeight="medium">
|
||||||
|
Disconnect
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
</Button>
|
||||||
|
</Container>
|
||||||
|
</Container>
|
||||||
|
</Container>
|
||||||
|
</Container>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
}
|
||||||
576
deps/cloudxr/isaac/src/index.html
vendored
Normal file
@@ -0,0 +1,576 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
|
<meta name="description" content="NVIDIA CloudXR.js Isaac Lab Teleop Client">
|
||||||
|
<title>NVIDIA CloudXR.js Isaac Lab Teleop application</title>
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--primary-green: #76b900;
|
||||||
|
--border-color: #e0e0e0;
|
||||||
|
--text-main: #111;
|
||||||
|
--background-main: #fff;
|
||||||
|
--input-radius: 0px;
|
||||||
|
--input-border: 2px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
|
||||||
|
background: var(--background-main);
|
||||||
|
color: var(--text-main);
|
||||||
|
touch-action: manipulation;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports (padding: max(0px)) {
|
||||||
|
body {
|
||||||
|
padding: max(0px, env(safe-area-inset-top)) max(0px, env(safe-area-inset-right)) max(0px, env(safe-area-inset-bottom)) max(0px, env(safe-area-inset-left));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Top Banner */
|
||||||
|
.top-banner {
|
||||||
|
width: 100vw;
|
||||||
|
height: 8px;
|
||||||
|
background: var(--primary-green);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header */
|
||||||
|
header {
|
||||||
|
background: var(--background-main);
|
||||||
|
padding: 16px 0 16px 24px;
|
||||||
|
min-height: unset;
|
||||||
|
box-shadow: none;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
height: calc(100vh - 64px);
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
width: 540px;
|
||||||
|
min-width: 400px;
|
||||||
|
padding: 32px 24px 24px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-right: 1px solid var(--border-color);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-title {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inputs and Selectors */
|
||||||
|
.ui-input,
|
||||||
|
select {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 300px;
|
||||||
|
padding: 16px 12px;
|
||||||
|
font-size: 1rem;
|
||||||
|
border: var(--input-border);
|
||||||
|
border-radius: var(--input-radius);
|
||||||
|
background: var(--background-main);
|
||||||
|
min-height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-input {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-input:focus,
|
||||||
|
select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--primary-green);
|
||||||
|
box-shadow: 0 0 0 3px rgba(118, 185, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-input::placeholder {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-table {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-table td {
|
||||||
|
padding: 12px 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-table label {
|
||||||
|
font-weight: 600;
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 140px;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-table select {
|
||||||
|
width: 200px;
|
||||||
|
padding: 12px 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: var(--primary-green);
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--input-radius);
|
||||||
|
padding: 16px 24px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
min-height: 56px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background: #8ac800;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled {
|
||||||
|
background: #666;
|
||||||
|
cursor: not-allowed;
|
||||||
|
transform: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-button {
|
||||||
|
margin-top: 16px;
|
||||||
|
width: auto;
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 12px 20px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
flex: 1;
|
||||||
|
padding: 48px 32px 32px;
|
||||||
|
background: #f8f8f8;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-title {
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-list {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-list li {
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-list li:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
main {
|
||||||
|
flex-direction: column;
|
||||||
|
height: auto;
|
||||||
|
min-height: calc(100vh - 64px);
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
width: 100%;
|
||||||
|
min-width: auto;
|
||||||
|
border-right: none;
|
||||||
|
border-bottom: 1px solid #404040;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
padding: 24px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
padding: 12px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-table select {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-contrast: high) {
|
||||||
|
|
||||||
|
body,
|
||||||
|
aside,
|
||||||
|
.ui-input,
|
||||||
|
select {
|
||||||
|
background: var(--background-main);
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
border-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-input,
|
||||||
|
select {
|
||||||
|
border-color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
* {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
animation-iteration-count: 1 !important;
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-input:focus-visible,
|
||||||
|
select:focus-visible,
|
||||||
|
button:focus-visible {
|
||||||
|
outline: 3px solid var(--primary-green);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.92rem;
|
||||||
|
color: #444;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
margin-top: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-label:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Console Logs Section */
|
||||||
|
.console-logs-section {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-logs-textarea {
|
||||||
|
height: 300px;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
resize: vertical;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-logs-buttons {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-logs-button {
|
||||||
|
background: #666;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 8px 16px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-logs-button:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configuration Section */
|
||||||
|
.config-section {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-input {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-text {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exit Button */
|
||||||
|
.exit-button {
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background: #ff3300cc;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
display: none;
|
||||||
|
z-index: 10000;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.exit-button:hover {
|
||||||
|
background: #ff3300;
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error Message Box */
|
||||||
|
.error-message-box {
|
||||||
|
display: none;
|
||||||
|
background: #ffebee;
|
||||||
|
border: 2px solid #f44336;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
margin: 16px 0;
|
||||||
|
color: #c62828;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message-box.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Success state - green */
|
||||||
|
.error-message-box.success {
|
||||||
|
background: #e8f5e9;
|
||||||
|
border-color: var(--primary-green);
|
||||||
|
color: #2e7d32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Info state - light blue */
|
||||||
|
.error-message-box.info {
|
||||||
|
background: #e3f2fd;
|
||||||
|
border-color: #2196f3;
|
||||||
|
color: #1565c0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error state - red (default) */
|
||||||
|
.error-message-box.error {
|
||||||
|
background: #ffebee;
|
||||||
|
border-color: #f44336;
|
||||||
|
color: #c62828;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message-box .error-icon {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Certificate Acceptance Link */
|
||||||
|
.cert-acceptance-link {
|
||||||
|
background: #e3f2fd;
|
||||||
|
border: 2px solid #2196f3;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
margin: 8px 0 16px 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-acceptance-link .cert-icon {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-acceptance-link a {
|
||||||
|
color: #1565c0;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
border-bottom: 1px solid #1565c0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-acceptance-link a:hover {
|
||||||
|
color: #0d47a1;
|
||||||
|
border-bottom-color: #0d47a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide 2D UI when in XR mode */
|
||||||
|
body.xr-mode #2d-ui {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="2d-ui">
|
||||||
|
<div class="top-banner"></div>
|
||||||
|
<header>
|
||||||
|
<h1>NVIDIA CloudXR.js Isaac Lab Teleop Client</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<aside>
|
||||||
|
<button id="startButton" class="start-button" type="button" aria-label="Connect"
|
||||||
|
disabled>CONNECT</button>
|
||||||
|
|
||||||
|
<div id="errorMessageBox" class="error-message-box" role="alert" aria-live="polite">
|
||||||
|
<span class="error-icon">⚠</span>
|
||||||
|
<span id="errorMessageText"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 class="settings-title">Settings</h2>
|
||||||
|
|
||||||
|
<form id="settingsForm">
|
||||||
|
<label for="serverType" class="input-label">Select Server Backend</label>
|
||||||
|
<select id="serverType" class="ui-input">
|
||||||
|
<option value="manual">Manual Input IP:Port</option>
|
||||||
|
<option value="nvcf" disabled>NVCF</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<div id="manualFields">
|
||||||
|
<label for="serverIpInput" class="input-label">Server IP</label>
|
||||||
|
<input id="serverIpInput" class="ui-input" type="text" placeholder="Server IP"
|
||||||
|
spellcheck="false">
|
||||||
|
<label for="portInput" class="input-label">Port</label>
|
||||||
|
<input id="portInput" class="ui-input" type="number" placeholder="Port (default: 49100)"
|
||||||
|
spellcheck="false" min="1" max="65535">
|
||||||
|
<div id="certAcceptanceLink" class="cert-acceptance-link" style="display: none;">
|
||||||
|
<span class="cert-icon">🔒</span>
|
||||||
|
<a id="certLink" href="#" target="_blank" rel="noopener noreferrer"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label for="app" class="input-label">Application</label>
|
||||||
|
<select id="app" name="app" class="ui-input" aria-label="Select application">
|
||||||
|
<option value="generic">Generic Client</option>
|
||||||
|
<!-- TODO: Add other applications here -->
|
||||||
|
</select>
|
||||||
|
<label for="immersive" class="input-label">Immersive Mode</label>
|
||||||
|
<select id="immersive" name="immersive" class="ui-input" aria-label="Select immersive mode">
|
||||||
|
<option value="ar" selected>AR Immersive</option>
|
||||||
|
<option value="vr">VR Immersive</option>
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3 class="debug-title">Debug Settings</h3>
|
||||||
|
|
||||||
|
<div class="config-section">
|
||||||
|
<label class="input-label">Proxy Configuration</label>
|
||||||
|
<label for="proxyUrl" class="input-label">Proxy URL</label>
|
||||||
|
<input id="proxyUrl" class="ui-input config-input" type="text" placeholder="" spellcheck="false">
|
||||||
|
<div class="config-text">
|
||||||
|
<span id="proxyDefaultText"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="config-section">
|
||||||
|
<label class="input-label">Frame Rate Configuration</label>
|
||||||
|
<label for="deviceFrameRate" class="input-label">Device Frame Rate</label>
|
||||||
|
<select id="deviceFrameRate" class="ui-input config-input">
|
||||||
|
<option value="72">72 FPS</option>
|
||||||
|
<option value="90" selected>90 FPS</option>
|
||||||
|
<option value="120">120 FPS</option>
|
||||||
|
</select>
|
||||||
|
<div class="config-text">
|
||||||
|
Select the target device frame rate for the XR session
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="config-section">
|
||||||
|
<label class="input-label">Maximum Streaming Bitrate</label>
|
||||||
|
<label for="maxStreamingBitrateMbps" class="input-label">Megabits per second</label>
|
||||||
|
<select id="maxStreamingBitrateMbps" class="ui-input config-input">
|
||||||
|
<option value="80">80 Mbps</option>
|
||||||
|
<option value="100">100 Mbps</option>
|
||||||
|
<option value="120">120 Mbps</option>
|
||||||
|
<option value="150" selected>150 Mbps</option>
|
||||||
|
<option value="180">180 Mbps</option>
|
||||||
|
<option value="200">200 Mbps</option>
|
||||||
|
</select>
|
||||||
|
<div class="config-text">
|
||||||
|
Select the maximum streaming bitrate (in Megabits per second) for the XR session
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="config-section">
|
||||||
|
<label class="input-label">Stream Resolution Configuration</label>
|
||||||
|
<label for="perEyeWidth" class="input-label">Per-Eye Width (default: 2048)</label>
|
||||||
|
<input id="perEyeWidth" class="ui-input config-input" type="number"
|
||||||
|
placeholder="Per-eye width in pixels" spellcheck="false" value="2048">
|
||||||
|
<label for="perEyeHeight" class="input-label">Per-Eye Height (default: 1792)</label>
|
||||||
|
<input id="perEyeHeight" class="ui-input config-input" type="number"
|
||||||
|
placeholder="Per-eye height in pixels" spellcheck="false" value="1792">
|
||||||
|
<div class="config-text">
|
||||||
|
Configure the per-eye resolution. Width and height must be multiples of 16.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="config-section">
|
||||||
|
<label for="referenceSpace" class="input-label">Reference Space</label>
|
||||||
|
<select id="referenceSpace" name="referenceSpace" class="ui-input" aria-label="Select reference space">
|
||||||
|
<option value="auto">Auto (local-floor preferred)</option>
|
||||||
|
<option value="local-floor">local-floor</option>
|
||||||
|
<option value="local" selected>local</option>
|
||||||
|
<option value="unbounded">unbounded</option>
|
||||||
|
<option value="viewer">viewer</option>
|
||||||
|
</select>
|
||||||
|
<div class="config-text">
|
||||||
|
Select the preferred reference space for XR tracking. "Auto" uses fallback logic (local-floor → local → viewer). Other options will attempt to use the specified space only.
|
||||||
|
</div>
|
||||||
|
<label class="input-label">XR Reference Space Offset</label>
|
||||||
|
<label for="xrOffsetX" class="input-label">X Offset (centimeters): Horizontal</label>
|
||||||
|
<input id="xrOffsetX" class="ui-input config-input" type="number" placeholder="X offset in centimeters"
|
||||||
|
spellcheck="false" value="0" step="1" min="-1000" max="1000">
|
||||||
|
<label for="xrOffsetY" class="input-label">Y Offset (centimeters): Vertical</label>
|
||||||
|
<input id="xrOffsetY" class="ui-input config-input" type="number" placeholder="Y offset in centimeters"
|
||||||
|
spellcheck="false" value="-155" step="1" min="-1000" max="1000">
|
||||||
|
<label for="xrOffsetZ" class="input-label">Z Offset (centimeters): Depth (forward/backward)</label>
|
||||||
|
<input id="xrOffsetZ" class="ui-input config-input" type="number" placeholder="Z offset in centimeters"
|
||||||
|
spellcheck="false" value="10" step="1" min="-1000" max="1000">
|
||||||
|
<div class="config-text">
|
||||||
|
Configure the XR reference space offset in centimeters. These values will be applied to the reference space transform to adjust the origin position of the XR experience.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<div id="3d-ui"></div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
27
deps/cloudxr/isaac/src/index.tsx
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom/client';
|
||||||
|
|
||||||
|
import App from './App';
|
||||||
|
|
||||||
|
// Start the React app immediately in the 3d-ui container
|
||||||
|
function startApp() {
|
||||||
|
const reactContainer = document.getElementById('3d-ui');
|
||||||
|
|
||||||
|
if (reactContainer) {
|
||||||
|
const root = ReactDOM.createRoot(reactContainer);
|
||||||
|
root.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.error('3d-ui container not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the app when DOM is ready
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', startApp);
|
||||||
|
} else {
|
||||||
|
startApp();
|
||||||
|
}
|
||||||
27
deps/cloudxr/isaac/tsconfig.json
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
|
"module": "CommonJS",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noEmit": false,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"incremental": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@helpers/*": ["../helpers/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
109
deps/cloudxr/isaac/webpack-plugins/DownloadAssetsPlugin.js
vendored
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const https = require('https');
|
||||||
|
|
||||||
|
class DownloadAssetsPlugin {
|
||||||
|
constructor(assets) {
|
||||||
|
this.assets = assets;
|
||||||
|
this.hasRun = false;
|
||||||
|
this.createdDirs = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
safeUnlink(filePath) {
|
||||||
|
try {
|
||||||
|
fs.unlinkSync(filePath);
|
||||||
|
} catch (err) {
|
||||||
|
// Ignore cleanup errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.beforeCompile.tapAsync('DownloadAssetsPlugin', (params, callback) => {
|
||||||
|
// Only run once per webpack process
|
||||||
|
if (this.hasRun) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('📦 Checking and downloading required assets...');
|
||||||
|
|
||||||
|
const downloadPromises = this.assets.map(asset => this.downloadFile(asset));
|
||||||
|
|
||||||
|
Promise.allSettled(downloadPromises)
|
||||||
|
.then((results) => {
|
||||||
|
const failed = results.filter(r => r.status === 'rejected');
|
||||||
|
if (failed.length > 0) {
|
||||||
|
console.warn(`⚠️ ${failed.length} asset(s) failed to download, continuing anyway...`);
|
||||||
|
}
|
||||||
|
console.log('✅ Asset check complete!');
|
||||||
|
this.hasRun = true;
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadFile({ url, output }) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Ensure directory exists (only once per unique path)
|
||||||
|
if (!this.createdDirs.has(output)) {
|
||||||
|
fs.mkdirSync(output, { recursive: true });
|
||||||
|
this.createdDirs.add(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
const filename = path.basename(url);
|
||||||
|
const filePath = path.join(output, filename);
|
||||||
|
|
||||||
|
// Skip if file already exists
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(` Downloading ${filename}...`);
|
||||||
|
|
||||||
|
const file = fs.createWriteStream(filePath);
|
||||||
|
|
||||||
|
const downloadFromUrl = (downloadUrl) => {
|
||||||
|
https.get(downloadUrl, (response) => {
|
||||||
|
// Handle redirects
|
||||||
|
if (response.statusCode === 302 || response.statusCode === 301) {
|
||||||
|
file.close();
|
||||||
|
this.safeUnlink(filePath);
|
||||||
|
downloadFromUrl(response.headers.location);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode !== 200) {
|
||||||
|
file.close();
|
||||||
|
this.safeUnlink(filePath);
|
||||||
|
reject(new Error(`Failed to download ${filename}: HTTP ${response.statusCode}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.pipe(file);
|
||||||
|
|
||||||
|
file.on('finish', () => {
|
||||||
|
file.close();
|
||||||
|
console.log(` ✓ Downloaded ${filename}`);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
file.on('error', (err) => {
|
||||||
|
this.safeUnlink(filePath);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
}).on('error', (err) => {
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
this.safeUnlink(filePath);
|
||||||
|
}
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
downloadFromUrl(url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = DownloadAssetsPlugin;
|
||||||
|
|
||||||
168
deps/cloudxr/isaac/webpack.common.js
vendored
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const DownloadAssetsPlugin = require('./webpack-plugins/DownloadAssetsPlugin');
|
||||||
|
|
||||||
|
const WEBXR_ASSETS_VERSION = '1.0.19';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: './src/index.tsx',
|
||||||
|
|
||||||
|
// Module rules define how different file types are processed
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'ts-loader',
|
||||||
|
options: {
|
||||||
|
// Only transpile, don't type-check (faster builds)
|
||||||
|
transpileOnly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
exclude: /node_modules/,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ['style-loader', 'css-loader'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Resolve configuration for module resolution
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.tsx', '.ts', '.js'],
|
||||||
|
alias: {
|
||||||
|
// @helpers can be used instead of relative paths to the helpers directory
|
||||||
|
'@helpers': path.resolve(__dirname, '../helpers')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Output configuration for bundled files
|
||||||
|
output: {
|
||||||
|
filename: 'bundle.js',
|
||||||
|
path: path.resolve(__dirname, './build'),
|
||||||
|
},
|
||||||
|
|
||||||
|
// Webpack plugins that extend webpack's functionality
|
||||||
|
plugins: [
|
||||||
|
// Generates HTML file and automatically injects bundled JavaScript
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: './src/index.html',
|
||||||
|
favicon: './favicon.ico'
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Inject environment variables
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.WEBXR_ASSETS_VERSION': JSON.stringify(WEBXR_ASSETS_VERSION),
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Download external assets during build
|
||||||
|
new DownloadAssetsPlugin([
|
||||||
|
// HDRI environment map
|
||||||
|
{
|
||||||
|
url: 'https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/1k/potsdamer_platz_1k.hdr',
|
||||||
|
output: path.resolve(__dirname, 'public/assets/hdri')
|
||||||
|
},
|
||||||
|
// WebXR controller profiles
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/profilesList.json`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles`)
|
||||||
|
},
|
||||||
|
// Generic hand profile
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-hand/profile.json`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-hand`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-hand/left.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-hand`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-hand/right.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-hand`)
|
||||||
|
},
|
||||||
|
// Generic trigger profile
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-trigger/profile.json`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-trigger`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-trigger/left.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-trigger`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-trigger/right.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/generic-trigger`)
|
||||||
|
},
|
||||||
|
// Oculus Touch v2
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v2/profile.json`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v2`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v2/left.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v2`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v2/right.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v2`)
|
||||||
|
},
|
||||||
|
// Oculus Touch v3
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v3/profile.json`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v3`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v3/left.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v3`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v3/right.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/oculus-touch-v3`)
|
||||||
|
},
|
||||||
|
// Meta Quest Touch Plus
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/meta-quest-touch-plus/profile.json`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/meta-quest-touch-plus`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/meta-quest-touch-plus/left.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/meta-quest-touch-plus`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/meta-quest-touch-plus/right.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/meta-quest-touch-plus`)
|
||||||
|
},
|
||||||
|
// Pico 4 Ultra
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/pico-4u/profile.json`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/pico-4u`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/pico-4u/left.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/pico-4u`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/pico-4u/right.glb`,
|
||||||
|
output: path.resolve(__dirname, `public/npm/@webxr-input-profiles/assets@${WEBXR_ASSETS_VERSION}/dist/profiles/pico-4u`)
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
|
||||||
|
// Copies static assets from public directory to build output
|
||||||
|
new CopyWebpackPlugin({
|
||||||
|
patterns: [
|
||||||
|
{
|
||||||
|
from: 'public',
|
||||||
|
to: '.',
|
||||||
|
globOptions: {
|
||||||
|
// Don't copy index.html since HtmlWebpackPlugin handles it
|
||||||
|
ignore: ['**/index.html'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ from: './favicon.ico', to: 'favicon.ico' },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
||||||
46
deps/cloudxr/isaac/webpack.dev.js
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
const { merge } = require('webpack-merge')
|
||||||
|
const common = require('./webpack.common.js')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
// Check if HTTPS mode is enabled via environment variable
|
||||||
|
const useHttps = process.env.HTTPS === 'true'
|
||||||
|
|
||||||
|
module.exports = merge(common, {
|
||||||
|
mode: 'development',
|
||||||
|
devtool: 'eval-source-map',
|
||||||
|
watchOptions: {
|
||||||
|
ignored: /node_modules/,
|
||||||
|
},
|
||||||
|
devServer: {
|
||||||
|
allowedHosts: 'all',
|
||||||
|
hot: false,
|
||||||
|
liveReload: false,
|
||||||
|
open: false,
|
||||||
|
// Enable HTTPS with self-signed certificate when HTTPS=true
|
||||||
|
...(useHttps && { server: 'https' }),
|
||||||
|
static: [
|
||||||
|
{
|
||||||
|
directory: path.join(__dirname, './build'),
|
||||||
|
watch: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
directory: path.join(__dirname, './public'),
|
||||||
|
publicPath: '/',
|
||||||
|
watch: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
watchFiles: [],
|
||||||
|
client: {
|
||||||
|
progress: true,
|
||||||
|
overlay: {
|
||||||
|
errors: true,
|
||||||
|
warnings: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
devMiddleware: {
|
||||||
|
writeToDisk: true,
|
||||||
|
},
|
||||||
|
compress: true,
|
||||||
|
port: 8080,
|
||||||
|
},
|
||||||
|
})
|
||||||
6
deps/cloudxr/isaac/webpack.prod.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const { merge } = require('webpack-merge');
|
||||||
|
const common = require('./webpack.common.js');
|
||||||
|
|
||||||
|
module.exports = merge(common, {
|
||||||
|
mode: 'production'
|
||||||
|
});
|
||||||