estellea radames commited on
Commit
71d12ce
·
0 Parent(s):

Duplicate from temp-org/ldm3d-gradio

Browse files

Co-authored-by: Radamés Ajna <[email protected]>

.gitattributes ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.png filter=lfs diff=lfs merge=lfs -text
37
+ *.jpg filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio_cached_examples
2
+ tmp
3
+ venv
4
+ __pycache__
5
+ *.py[cod]
README.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: LDM3D Gradio Three.js
3
+ emoji: 🔵🔴🟢🧊
4
+ sdk: gradio
5
+ sdk_version: 3.35.2
6
+ app_file: app.py
7
+ pinned: false
8
+ duplicated_from: temp-org/ldm3d-gradio
9
+ ---
10
+
11
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from diffusers import StableDiffusionLDM3DPipeline
2
+ import gradio as gr
3
+ import torch
4
+ from PIL import Image
5
+ import base64
6
+ from io import BytesIO
7
+ from tempfile import NamedTemporaryFile
8
+ from pathlib import Path
9
+
10
+ Path("tmp").mkdir(exist_ok=True)
11
+
12
+ device = "cuda" if torch.cuda.is_available() else "cpu"
13
+ pipe = StableDiffusionLDM3DPipeline.from_pretrained(
14
+ "Intel/ldm3d-4c",
15
+ torch_dtype=torch.float16
16
+ # , safety_checker=None
17
+ )
18
+ pipe.to(device)
19
+ pipe.enable_xformers_memory_efficient_attention()
20
+ pipe.enable_model_cpu_offload()
21
+
22
+
23
+ def get_iframe(rgb_path: str, depth_path: str, viewer_mode: str = "6DOF"):
24
+ # buffered = BytesIO()
25
+ # rgb.convert("RGB").save(buffered, format="JPEG")
26
+ # rgb_base64 = base64.b64encode(buffered.getvalue())
27
+ # buffered = BytesIO()
28
+ # depth.convert("RGB").save(buffered, format="JPEG")
29
+ # depth_base64 = base64.b64encode(buffered.getvalue())
30
+
31
+ # rgb_base64 = "data:image/jpeg;base64," + rgb_base64.decode("utf-8")
32
+ # depth_base64 = "data:image/jpeg;base64," + depth_base64.decode("utf-8")
33
+ rgb_base64 = f"/file={rgb_path}"
34
+ depth_base64 = f"/file={depth_path}"
35
+ if viewer_mode == "6DOF":
36
+ return f"""<iframe src="file=static/three6dof.html" width="100%" height="500px" data-rgb="{rgb_base64}" data-depth="{depth_base64}"></iframe>"""
37
+ else:
38
+ return f"""<iframe src="file=static/depthmap.html" width="100%" height="500px" data-rgb="{rgb_base64}" data-depth="{depth_base64}"></iframe>"""
39
+
40
+
41
+ def predict(
42
+ prompt: str,
43
+ negative_prompt: str,
44
+ guidance_scale: float = 5.0,
45
+ seed: int = 0,
46
+ randomize_seed: bool = True,
47
+ ):
48
+ generator = torch.Generator() if randomize_seed else torch.manual_seed(seed)
49
+ output = pipe(
50
+ prompt,
51
+ width=1024,
52
+ height=512,
53
+ negative_prompt=negative_prompt,
54
+ guidance_scale=guidance_scale,
55
+ generator=generator,
56
+ num_inference_steps=40,
57
+ ) # type: ignore
58
+ rgb_image, depth_image = output.rgb[0], output.depth[0] # type: ignore
59
+ with NamedTemporaryFile(suffix=".png", delete=False, dir="tmp") as rgb_file:
60
+ rgb_image.save(rgb_file.name)
61
+ rgb_image = rgb_file.name
62
+ with NamedTemporaryFile(suffix=".png", delete=False, dir="tmp") as depth_file:
63
+ depth_image.save(depth_file.name)
64
+ depth_image = depth_file.name
65
+
66
+ iframe = get_iframe(rgb_image, depth_image)
67
+ return rgb_image, depth_image, generator.seed(), iframe
68
+
69
+
70
+ with gr.Blocks() as block:
71
+ gr.Markdown(
72
+ """
73
+ ## LDM3d Demo
74
+
75
+ model: https://huggingface.co/Intel/ldm3d<br>
76
+ [Diffusers docs](https://huggingface.co/docs/diffusers/main/en/api/pipelines/stable_diffusion/ldm3d_diffusion)
77
+
78
+ """
79
+ )
80
+ with gr.Row():
81
+ with gr.Column(scale=1):
82
+ prompt = gr.Textbox(label="Prompt")
83
+ negative_prompt = gr.Textbox(label="Negative Prompt")
84
+ guidance_scale = gr.Slider(
85
+ label="Guidance Scale", minimum=0, maximum=10, step=0.1, value=5.0
86
+ )
87
+ randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
88
+ seed = gr.Slider(label="Seed", minimum=0,
89
+ maximum=2**64 - 1, step=1)
90
+ generated_seed = gr.Number(label="Generated Seed")
91
+ markdown = gr.Markdown(label="Output Box")
92
+ with gr.Row():
93
+ new_btn = gr.Button("New Image")
94
+ with gr.Column(scale=2):
95
+ html = gr.HTML()
96
+ with gr.Row():
97
+ rgb = gr.Image(label="RGB Image", type="filepath")
98
+ depth = gr.Image(label="Depth Image", type="filepath")
99
+ gr.Examples(
100
+ examples=[
101
+ ["A picture of some lemons on a table panoramic view", "", 5.0, 0, True]],
102
+ inputs=[prompt, negative_prompt, guidance_scale, seed, randomize_seed],
103
+ outputs=[rgb, depth, generated_seed, html],
104
+ fn=predict,
105
+ cache_examples=True)
106
+
107
+ new_btn.click(
108
+ fn=predict,
109
+ inputs=[prompt, negative_prompt, guidance_scale, seed, randomize_seed],
110
+ outputs=[rgb, depth, generated_seed, html],
111
+ )
112
+
113
+ block.launch()
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ git+https://github.com/huggingface/diffusers@07c9a08e67feb4d05ba22ba6b1a2d39468d68225
2
+ gradio
3
+ transformers
4
+ accelerate
5
+ Pillow
6
+ numpy
7
+ xformers
8
+ # --index-url https://download.pytorch.org/whl/cu118
9
+ torch
static/depthmap.html ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="utf-8" />
6
+ <title>depthmap-viewer-three</title>
7
+ <style>
8
+ body {
9
+ font-family: sans-serif;
10
+ margin: 0;
11
+ }
12
+
13
+ .dropzone {
14
+ box-sizing: border-box;
15
+ display: none;
16
+ position: fixed;
17
+ width: 100%;
18
+ height: 100%;
19
+ left: 0;
20
+ top: 0;
21
+ z-index: 99999;
22
+ background: rgba(#60a7dc, .8);
23
+ border: 11px dashed #60a7dc;
24
+ }
25
+ </style>
26
+ <script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
27
+ <script type="importmap">
28
+ {
29
+ "imports": {
30
+ "three": "https://unpkg.com/[email protected]/build/three.module.js",
31
+ "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
32
+ }
33
+ }
34
+ </script>
35
+ <script type="module">
36
+ import * as THREE from 'three';
37
+ import { OrbitControls } from "three/addons/controls/OrbitControls";
38
+ import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
39
+
40
+ var rgbBase64Img = window.frameElement?.getAttribute('data-rgb') || "public/images/rgb.png"
41
+ var depthBase64Img = window.frameElement?.getAttribute('data-depth') || "public/images/depth.png"
42
+
43
+
44
+
45
+ let mesh;
46
+ let material;
47
+ let stopAnimation = false;
48
+
49
+ const settings = {
50
+ metalness: 0.0,
51
+ roughness: 0.5,
52
+ ambientIntensity: 0.85,
53
+ displacementScale: 100,
54
+ displacementBias: -0.5,
55
+ };
56
+ const meshSettings = {
57
+ rotation: {
58
+ x: 0,
59
+ y: 0,
60
+ z: 0
61
+ }
62
+ }
63
+
64
+ // init
65
+ const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
66
+ camera.position.z = 3;
67
+
68
+ const scene = new THREE.Scene();
69
+
70
+ const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
71
+ scene.add(ambientLight);
72
+
73
+ const pointLight = new THREE.PointLight(0xff0000, 0.5);
74
+ pointLight.position.z = 2500;
75
+ scene.add(pointLight);
76
+
77
+
78
+ const renderer = new THREE.WebGLRenderer({ antialias: true });
79
+ renderer.setSize(window.innerWidth, window.innerHeight);
80
+ renderer.setAnimationLoop(animation);
81
+ // renderer.xr.enabled = true;
82
+ renderer.toneMapping = THREE.ACESFilmicToneMapping;
83
+ renderer.toneMappingExposure = 1;
84
+ renderer.outputEncoding = THREE.sRGBEncoding;
85
+ document.body.appendChild(renderer.domElement);
86
+
87
+ // animation
88
+ function animation(time) {
89
+ if (mesh && !stopAnimation) {
90
+ mesh.rotation.x = 0.5 * Math.sin(time / 2000);
91
+ mesh.rotation.y = 0.5 * Math.sin(time / 2000);
92
+ meshSettings.rotation.x = mesh.rotation.x;
93
+ meshSettings.rotation.y = mesh.rotation.y;
94
+ }
95
+ renderer.render(scene, camera);
96
+
97
+ }
98
+
99
+ function onWindowResize() {
100
+
101
+ const aspect = window.innerWidth / window.innerHeight;
102
+ camera.aspect = aspect;
103
+ camera.updateProjectionMatrix();
104
+
105
+ renderer.setSize(window.innerWidth, window.innerHeight);
106
+
107
+ }
108
+ window.addEventListener('resize', onWindowResize);
109
+
110
+
111
+ // orbit controls
112
+ const controls = new OrbitControls(camera, renderer.domElement);
113
+ controls.enableZoom = true;
114
+ controls.enableDamping = true;
115
+
116
+ async function getCanvasTexture(imageSrc) {
117
+ return new Promise((resolve, reject) => {
118
+ const image = new Image();
119
+ image.src = imageSrc;
120
+ image.onload = () => {
121
+ const ctx = document.createElement('canvas').getContext('2d');
122
+ ctx.canvas.width = image.width;
123
+ ctx.canvas.height = image.height;
124
+ ctx.drawImage(image, 0, 0, image.width, image.height);
125
+ const texture = new THREE.CanvasTexture(ctx.canvas);
126
+ resolve(texture);
127
+ }
128
+ })
129
+
130
+ }
131
+ (async () => {
132
+ const rgbTexture = await getCanvasTexture(rgbBase64Img);
133
+ const depthTexture = await getCanvasTexture(depthBase64Img);
134
+
135
+ if (mesh) {
136
+ mesh.geometry.dispose();
137
+ mesh.material.dispose();
138
+ scene.remove(mesh);
139
+ }
140
+ // material
141
+ material = new THREE.MeshStandardMaterial({
142
+
143
+ color: 0xaaaaaa,
144
+ roughness: settings.roughness,
145
+ metalness: settings.metalness,
146
+
147
+ map: rgbTexture,
148
+
149
+ displacementMap: depthTexture,
150
+ displacementScale: settings.displacementScale,
151
+ displacementBias: settings.displacementBias,
152
+
153
+ side: THREE.DoubleSide
154
+
155
+ });
156
+ // generating geometry and add mesh to scene
157
+ const geometry = new THREE.PlaneGeometry(rgbTexture.image.width, rgbTexture.image.height, 512, 512);
158
+ mesh = new THREE.Mesh(geometry, material);
159
+ const scale = 1 / Math.max(rgbTexture.image.width, rgbTexture.image.height);
160
+ mesh.scale.set(scale, scale, scale);
161
+ scene.add(mesh);
162
+
163
+ })()
164
+
165
+
166
+
167
+ // setup gui
168
+ const gui = new GUI();
169
+ gui.close();
170
+ const sceneGUI = gui.addFolder('Scene');
171
+ sceneGUI.add(settings, 'metalness').min(0).max(1).onChange(function (value) {
172
+ material.metalness = value;
173
+ });
174
+ sceneGUI.add(settings, 'roughness').min(0).max(1).onChange(function (value) {
175
+ material.roughness = value;
176
+ });
177
+ sceneGUI.add(settings, 'ambientIntensity').min(0).max(1).onChange(function (value) {
178
+ ambientLight.intensity = value;
179
+ });
180
+ sceneGUI.add(settings, 'displacementScale').min(0).max(500.0).onChange(function (value) {
181
+ material.displacementScale = value;
182
+ });
183
+ sceneGUI.add(settings, 'displacementBias').min(-500).max(500).onChange(function (value) {
184
+ material.displacementBias = value;
185
+ });
186
+ const meshGUI = gui.addFolder('Mesh');
187
+ meshGUI.add(meshSettings.rotation, 'x').min(-Math.PI).max(Math.PI).step(0.0001).onChange(function (value) {
188
+ mesh.rotation.x = value;
189
+ stopAnimation = true;
190
+ }).listen()
191
+
192
+
193
+ meshGUI.add(meshSettings.rotation, 'y').min(-Math.PI).max(Math.PI).step(0.0001).onChange(function (value) {
194
+ mesh.rotation.y = value;
195
+ stopAnimation = true;
196
+ }).listen()
197
+
198
+
199
+ meshGUI.add(meshSettings.rotation, 'z').min(-Math.PI).max(Math.PI).step(0.0001).onChange(function (value) {
200
+ mesh.rotation.z = value;
201
+ stopAnimation = true;
202
+ }).listen()
203
+
204
+
205
+ </script>
206
+ </head>
207
+
208
+ <body>
209
+ </body>
210
+
211
+ </html>
static/public/images/depth.png ADDED

Git LFS Details

  • SHA256: 04a8fb3d928d5d501767d89561d67d6c2bf1b16355d53246ccfd11273db571f2
  • Pointer size: 131 Bytes
  • Size of remote file: 352 kB
static/public/images/equirectangular/kandao3.jpg ADDED

Git LFS Details

  • SHA256: 814c1d7734415d80e048d97895dc03012814a66c84b0df3f4a05229071f2b324
  • Pointer size: 132 Bytes
  • Size of remote file: 1.26 MB
static/public/images/equirectangular/kandao3_depthmap.jpg ADDED

Git LFS Details

  • SHA256: b7d931995319cb52fb902e366f3b24a247e4d6d8eaceb4eecdfef9551704a40e
  • Pointer size: 130 Bytes
  • Size of remote file: 21.1 kB
static/public/images/favicon/android-chrome-192x192.png ADDED

Git LFS Details

  • SHA256: 8a4dcb11b409e2d0d1582d59c120de1e7366e0ac02b16c156ab79a4e3613f891
  • Pointer size: 130 Bytes
  • Size of remote file: 15.6 kB
static/public/images/favicon/android-chrome-512x512.png ADDED

Git LFS Details

  • SHA256: a39d9527a15a507e96ade9e8982e2f439d56060f548bfc260d73cd00b1bd4ca0
  • Pointer size: 130 Bytes
  • Size of remote file: 51.4 kB
static/public/images/favicon/apple-touch-icon.png ADDED

Git LFS Details

  • SHA256: 08fea76f5ed2e444b7f02ae41f85b079133a11d8332ad98f999c3816e77e011f
  • Pointer size: 130 Bytes
  • Size of remote file: 13.8 kB
static/public/images/favicon/favicon-16x16.png ADDED

Git LFS Details

  • SHA256: b77974b5b96849b3078af9232df4eb785e40a71036d1b4b5e7bcb13c378f969c
  • Pointer size: 128 Bytes
  • Size of remote file: 490 Bytes
static/public/images/favicon/favicon-32x32.png ADDED

Git LFS Details

  • SHA256: 79f28d07ef588b4bee4ad8a7846e0d38983c067e21a6d5654efcbb02ba4fc8f5
  • Pointer size: 129 Bytes
  • Size of remote file: 1.39 kB
static/public/images/favicon/favicon.ico ADDED
static/public/images/rgb.png ADDED

Git LFS Details

  • SHA256: 8247639b9bdf135816564a56a1cb92da4b2c88237ec661bb9ed28fe264e92d1b
  • Pointer size: 131 Bytes
  • Size of remote file: 319 kB
static/public/images/ruins_rgbd.png ADDED

Git LFS Details

  • SHA256: 5dd7730abe4494b2b2f8886b4b93cd9cef47bdba631aa28eb01d84a4b6fcf309
  • Pointer size: 131 Bytes
  • Size of remote file: 744 kB
static/public/js/GUIHelper.js ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ THREE.GUI = {
2
+ create: (viewer, scene) => {
3
+ var gui = new dat.GUI();
4
+
5
+ // Set some GUI params
6
+ var shaderParams = gui.addFolder('Shader');
7
+ shaderParams.add(sixDofViewer, 'displacement', 0, 7).name('Displacement');
8
+ shaderParams.add(sixDofViewer, 'opacity', 0, 1).name('Opacity');
9
+ shaderParams.add(sixDofViewer, 'pointSize', 0, 10).name('Point Size');
10
+ shaderParams.add({ 'debugDepth': false }, 'debugDepth')
11
+ .name('Debug Depth')
12
+ .onChange(val => {
13
+ sixDofViewer.toggleDepthDebug(val);
14
+ });
15
+ shaderParams.add({
16
+ 'changeStyle': () => { }
17
+ }, 'changeStyle', {
18
+ 'Mesh': SixDOF.Style[SixDOF.Style.MESH],
19
+ 'Wireframe': SixDOF.Style[SixDOF.Style.WIRE],
20
+ 'Pointcloud': SixDOF.Style[SixDOF.Style.POINTS]
21
+ })
22
+ .name('Rendering Style')
23
+ .onChange(val => {
24
+ scene.remove(sixDofViewer);
25
+ sixDofViewer = new SixDOF.Viewer(colorTexture, depthTexture, {
26
+ 'style': SixDOF.Style[val]
27
+ });
28
+ scene.add(sixDofViewer);
29
+ });
30
+
31
+
32
+ return gui;
33
+ }
34
+ }
static/public/js/WebVR.js ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @author mrdoob / http://mrdoob.com
3
+ * @author Mugen87 / https://github.com/Mugen87
4
+ *
5
+ * Based on @tojiro's vr-samples-utils.js
6
+ */
7
+
8
+ THREE.WEBVR = {
9
+
10
+ createButton: function ( renderer, options ) {
11
+
12
+ if ( options && options.referenceSpaceType ) {
13
+
14
+ renderer.vr.setReferenceSpaceType( options.referenceSpaceType );
15
+
16
+ }
17
+
18
+ function showEnterVR( device ) {
19
+
20
+ button.style.display = '';
21
+
22
+ button.style.cursor = 'pointer';
23
+ button.style.left = 'calc(50% - 50px)';
24
+ button.style.width = '100px';
25
+
26
+ button.textContent = 'ENTER VR';
27
+
28
+ button.onmouseenter = function () {
29
+
30
+ button.style.opacity = '1.0';
31
+
32
+ };
33
+
34
+ button.onmouseleave = function () {
35
+
36
+ button.style.opacity = '0.5';
37
+
38
+ };
39
+
40
+ button.onclick = function () {
41
+
42
+ device.isPresenting ? device.exitPresent() : device.requestPresent( [ { source: renderer.domElement } ] );
43
+
44
+ };
45
+
46
+ renderer.vr.setDevice( device );
47
+
48
+ }
49
+
50
+ function showEnterXR( /*device*/ ) {
51
+
52
+ var currentSession = null;
53
+
54
+ function onSessionStarted( session ) {
55
+
56
+ session.addEventListener( 'end', onSessionEnded );
57
+
58
+ renderer.vr.setSession( session );
59
+ button.textContent = 'EXIT XR';
60
+
61
+ currentSession = session;
62
+
63
+ }
64
+
65
+ function onSessionEnded( /*event*/ ) {
66
+
67
+ currentSession.removeEventListener( 'end', onSessionEnded );
68
+
69
+ renderer.vr.setSession( null );
70
+ button.textContent = 'ENTER XR';
71
+
72
+ currentSession = null;
73
+
74
+ }
75
+
76
+ //
77
+
78
+ button.style.display = '';
79
+
80
+ button.style.cursor = 'pointer';
81
+ button.style.left = 'calc(50% - 50px)';
82
+ button.style.width = '100px';
83
+
84
+ button.textContent = 'ENTER XR';
85
+
86
+ button.onmouseenter = function () {
87
+
88
+ button.style.opacity = '1.0';
89
+
90
+ };
91
+
92
+ button.onmouseleave = function () {
93
+
94
+ button.style.opacity = '0.5';
95
+
96
+ };
97
+
98
+ button.onclick = function () {
99
+
100
+ if ( currentSession === null ) {
101
+
102
+ // WebXR's requestReferenceSpace only works if the corresponding feature
103
+ // was requested at session creation time. For simplicity, just ask for
104
+ // the interesting ones as optional features, but be aware that the
105
+ // requestReferenceSpace call will fail if it turns out to be unavailable.
106
+ // ('local' is always available for immersive sessions and doesn't need to
107
+ // be requested separately.)
108
+
109
+ var sessionInit = { optionalFeatures: [ 'local-floor', 'bounded-floor' ] };
110
+ navigator.xr.requestSession( 'immersive-vr', sessionInit ).then( onSessionStarted );
111
+
112
+ } else {
113
+
114
+ currentSession.end();
115
+
116
+ }
117
+
118
+ };
119
+
120
+ }
121
+
122
+ function disableButton() {
123
+
124
+ button.style.display = '';
125
+
126
+ button.style.cursor = 'auto';
127
+ button.style.left = 'calc(50% - 75px)';
128
+ button.style.width = '150px';
129
+
130
+ button.onmouseenter = null;
131
+ button.onmouseleave = null;
132
+
133
+ button.onclick = null;
134
+
135
+ }
136
+
137
+ function showVRNotFound() {
138
+
139
+ disableButton();
140
+
141
+ button.textContent = 'VR NOT FOUND';
142
+
143
+ renderer.vr.setDevice( null );
144
+
145
+ }
146
+
147
+ function showXRNotFound() {
148
+
149
+ disableButton();
150
+
151
+ button.textContent = 'XR NOT FOUND';
152
+
153
+ }
154
+
155
+ function stylizeElement( element ) {
156
+
157
+ element.style.position = 'absolute';
158
+ element.style.bottom = '20px';
159
+ element.style.padding = '12px 6px';
160
+ element.style.border = '1px solid #fff';
161
+ element.style.borderRadius = '4px';
162
+ element.style.background = 'rgba(0,0,0,0.1)';
163
+ element.style.color = '#fff';
164
+ element.style.font = 'normal 13px sans-serif';
165
+ element.style.textAlign = 'center';
166
+ element.style.opacity = '0.5';
167
+ element.style.outline = 'none';
168
+ element.style.zIndex = '999';
169
+
170
+ }
171
+
172
+ if ( 'xr' in navigator ) {
173
+
174
+ var button = document.createElement( 'button' );
175
+ button.style.display = 'none';
176
+
177
+ stylizeElement( button );
178
+
179
+ navigator.xr.isSessionSupported( 'immersive-vr' ).then( function ( supported ) {
180
+
181
+ if ( supported ) {
182
+
183
+ showEnterXR();
184
+
185
+ } else {
186
+
187
+ showXRNotFound();
188
+
189
+ }
190
+
191
+ } );
192
+
193
+ return button;
194
+
195
+ } else if ( 'getVRDisplays' in navigator ) {
196
+
197
+ var button = document.createElement( 'button' );
198
+ button.style.display = 'none';
199
+
200
+ stylizeElement( button );
201
+
202
+ window.addEventListener( 'vrdisplayconnect', function ( event ) {
203
+
204
+ showEnterVR( event.display );
205
+
206
+ }, false );
207
+
208
+ window.addEventListener( 'vrdisplaydisconnect', function ( /*event*/ ) {
209
+
210
+ showVRNotFound();
211
+
212
+ }, false );
213
+
214
+ window.addEventListener( 'vrdisplaypresentchange', function ( event ) {
215
+
216
+ button.textContent = event.display.isPresenting ? 'EXIT VR' : 'ENTER VR';
217
+
218
+ }, false );
219
+
220
+ window.addEventListener( 'vrdisplayactivate', function ( event ) {
221
+
222
+ event.display.requestPresent( [ { source: renderer.domElement } ] );
223
+
224
+ }, false );
225
+
226
+ navigator.getVRDisplays()
227
+ .then( function ( displays ) {
228
+
229
+ if ( displays.length > 0 ) {
230
+
231
+ showEnterVR( displays[ 0 ] );
232
+
233
+ } else {
234
+
235
+ showVRNotFound();
236
+
237
+ }
238
+
239
+ } ).catch( showVRNotFound );
240
+
241
+ return button;
242
+
243
+ } else {
244
+
245
+ var message = document.createElement( 'a' );
246
+ message.href = 'https://webvr.info';
247
+ message.innerHTML = 'WEBVR NOT SUPPORTED';
248
+
249
+ message.style.left = 'calc(50% - 90px)';
250
+ message.style.width = '180px';
251
+ message.style.textDecoration = 'none';
252
+
253
+ stylizeElement( message );
254
+
255
+ return message;
256
+
257
+ }
258
+
259
+ }
260
+
261
+ };
static/public/js/three-6dof.min.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("three")):"function"==typeof define&&define.amd?define(["exports","three"],t):t((e=e||self).SixDOF={},e.THREE)}(this,(function(e,t){"use strict";var r,n,i,o="#define GLSLIFY 1\n\n/** Small util to get the depth texture */\nvec3 getDepth(sampler2D depth, vec2 uvs) {\n\n /** Return the depth texture */\n return texture2D(depth, uvs).rgb;\n}\n\n/** Small util to get the lower half of a texture (in our case the depthmap) */\nvec3 getDepthFromBottomHalf(sampler2D tex, vec2 uvs) {\n \n /** Chop the uvs to the lower half of the texture (i.e top-bottom) */\n vec2 lower_half_uvs = vec2(uvs.x, uvs.y * 0.5);\n\n /** Return the depth texture */\n return texture2D(tex, lower_half_uvs).rgb;\n}\n\n/** Small util to get the upper half of a texture (in our case the color texture) */\nvec3 getColorFromUpperHalf(sampler2D tex, vec2 uvs) {\n \n /** Chop the uvs to the lower half of the texture (i.e top-bottom) */\n vec2 upper_half_uvs = vec2(uvs.x, (uvs.y * 0.5) + 0.5);\n\n /** Return the depth texture */\n return texture2D(tex, upper_half_uvs).rgb;\n}\n\n// Uniforms\nuniform sampler2D colorTexture;\nuniform sampler2D depthTexture;\nuniform float debugDepth;\nuniform float opacity;\n\n// Varyings from vertex program\nvarying vec2 vUv;\n\n// Internal\nvec3 depth;\nvec3 color;\n\nvoid main() {\n\n/** Use compiler definitions to know which method to pick */\n#ifdef TOP_BOTTOM\n depth = getDepthFromBottomHalf(colorTexture, vUv);\n color = getColorFromUpperHalf(colorTexture, vUv);\n#endif\n\n#ifdef SEPERATE\n depth = getDepth(depthTexture, vUv);\n color = texture2D(colorTexture, vUv).rgb;\n#endif\n\n // Mix the depth and color based on debugDepth value\n vec3 depthColorMixer = mix(color, depth , debugDepth);\n\n // Render dat fragment\n gl_FragColor = vec4(depthColorMixer, opacity);\n}\n",s="#define GLSLIFY 1\n\n/** Small util to get the depth texture */\nvec3 getDepth(sampler2D depth, vec2 uvs) {\n\n /** Return the depth texture */\n return texture2D(depth, uvs).rgb;\n}\n\n/** Small util to get the lower half of a texture (in our case the depthmap) */\nvec3 getDepthFromBottomHalf(sampler2D tex, vec2 uvs) {\n \n /** Chop the uvs to the lower half of the texture (i.e top-bottom) */\n vec2 lower_half_uvs = vec2(uvs.x, uvs.y * 0.5);\n\n /** Return the depth texture */\n return texture2D(tex, lower_half_uvs).rgb;\n}\n\n// Uniforms\nuniform sampler2D colorTexture;\nuniform sampler2D depthTexture;\nuniform float pointSize;\nuniform float displacement;\n\n// Varyings passed to fragment\nvarying vec2 vUv;\n\n// Internal\nfloat depth;\n\nvoid main() {\n\n /** Transform and pass to fragment shader */\n vUv = uv;\n\n /** Set the GL point size for when rendering points, ignored otherwise */\n gl_PointSize = pointSize;\n\n/** Use compiler definitions to know which method to pick */\n#ifdef TOP_BOTTOM\n depth = getDepthFromBottomHalf(colorTexture, vUv).r;\n#endif\n\n#ifdef SEPERATE\n depth = getDepth(depthTexture, vUv).r;\n#endif\n\n /** \n * Invert the normals (since they are pointing outwards) and \n * move the position on the normal direction scaled by the \n * displacement which is the depth for the current vertex\n * multiplied by a `displacement` scalaer\n **/\n float disp = displacement * depth;\n vec3 offset = position + (-normal) * disp;\n\n /** Transform */\n gl_Position = projectionMatrix *\n modelViewMatrix *\n vec4(offset, 1.0);\n}",a={colorTexture:{type:"t",value:null},depthTexture:{type:"t",value:null},time:{type:"f",value:0},opacity:{type:"f",value:1},pointSize:{type:"f",value:3},debugDepth:{type:"f",value:0},displacement:{type:"f",value:1}};(r=e.MeshDensity||(e.MeshDensity={}))[r.LOW=64]="LOW",r[r.MEDIUM=128]="MEDIUM",r[r.HIGH=256]="HIGH",r[r.EXTRA_HIGH=512]="EXTRA_HIGH",r[r.EPIC=1024]="EPIC",(n=e.Style||(e.Style={}))[n.WIRE=0]="WIRE",n[n.POINTS=1]="POINTS",n[n.MESH=2]="MESH",(i=e.TextureType||(e.TextureType={}))[i.TOP_BOTTOM=0]="TOP_BOTTOM",i[i.SEPERATE=1]="SEPERATE";class u{constructor(){this.type=e.TextureType.SEPERATE,this.density=e.MeshDensity.HIGH,this.style=e.Style.MESH,this.displacement=4,this.radius=6}}class p extends t.Object3D{constructor(r,n,i){super(),this.props=new u,this.material=new t.ShaderMaterial({uniforms:a,vertexShader:s,fragmentShader:o,transparent:!0,side:t.BackSide}),this.setProps(this.props,i),this.setShaderDefines(this.material,[e.TextureType[this.props.type]]),p.geometry||(p.geometry=this.createSphereGeometry(this.props.radius,this.props.density)),this.assignTexture(this.props.type,r,n),this.displacement=this.props.displacement,super.add(this.createMesh(p.geometry,this.material,this.props.style))}setShaderDefines(e,t){t.forEach((function(t){return e.defines[t]=""}))}createSphereGeometry(e,r){return new t.SphereBufferGeometry(e,r,r)}setProps(e,t){if(t)for(var r in t)e[r]?e[r]=t[r]:console.warn("THREE.SixDOF: Provided ".concat(r," in config but it is not a valid property and being ignored"))}assignTexture(t,r,n){if(t===e.TextureType.SEPERATE){if(!n)throw new Error("When using seperate texture type, depthmap must be provided");this.depth=this.setDefaultTextureProps(n)}this.texture=this.setDefaultTextureProps(r)}setDefaultTextureProps(e){return e.minFilter=t.NearestFilter,e.magFilter=t.LinearFilter,e.format=t.RGBFormat,e.generateMipmaps=!1,e}createMesh(r,n,i){switch(i){case e.Style.WIRE:return this.material.wireframe||(this.material.wireframe=!0),new t.Mesh(r,n);case e.Style.MESH:return this.material.wireframe&&(this.material.wireframe=!1),new t.Mesh(r,n);case e.Style.POINTS:return new t.Points(r,n)}}toggleDepthDebug(e){this.material.uniforms.debugDepth.value=null!=e?e:!this.material.uniforms.debugDepth.value}set displacement(e){this.material.uniforms.displacement.value=e}set depth(e){this.material.uniforms.depthTexture.value=e}set texture(e){this.material.uniforms.colorTexture.value=e}set opacity(e){this.material.uniforms.opacity.value=e}set pointSize(e){this.material.uniforms.pointSize.value=e}get config(){return this.props}get opacity(){return this.material.uniforms.opacity.value}get pointSize(){return this.material.uniforms.pointSize.value}get displacement(){return this.material.uniforms.displacement.value}get texture(){return this.material.uniforms.colorTexture.value}get depth(){return this.material.uniforms.opacity.value}}p.geometry=void 0,e.Viewer=p,Object.defineProperty(e,"__esModule",{value:!0})}));
2
+ //# sourceMappingURL=three-6dof.min.js.map
static/public/js/three-6dof.min.js.map ADDED
@@ -0,0 +1 @@
 
 
1
+ {"version":3,"file":"three-6dof.min.js","sources":["../src/components/constants.ts","../src/components/uniforms.ts","../src/components/viewer.ts"],"sourcesContent":["enum MeshDensity {\n LOW = 64,\n MEDIUM = 128,\n HIGH = 256,\n EXTRA_HIGH = 512,\n EPIC = 1024,\n}\n\nenum Style {\n WIRE = 0,\n POINTS = 1,\n MESH = 2,\n}\n\nenum TextureType {\n TOP_BOTTOM,\n SEPERATE,\n}\n\nclass Props {\n public type: TextureType = TextureType.SEPERATE\n public density: MeshDensity = MeshDensity.HIGH\n public style: Style = Style.MESH\n public displacement: number = 4.0\n public radius: number = 6\n}\n\nexport { MeshDensity, Style, TextureType, Props }\n","export const Uniforms: object = {\n colorTexture: {\n type: 't',\n value: null,\n },\n depthTexture: {\n type: 't',\n value: null,\n },\n time: {\n type: 'f',\n value: 0.0,\n },\n opacity: {\n type: 'f',\n value: 1.0,\n },\n pointSize: {\n type: 'f',\n value: 3.0,\n },\n debugDepth: {\n type: 'f',\n value: 0.0,\n },\n displacement: {\n type: 'f',\n value: 1.0,\n },\n}\n","import {\n Object3D,\n ShaderMaterial,\n BackSide,\n Mesh,\n Points,\n SphereBufferGeometry,\n Texture,\n NearestFilter,\n LinearFilter,\n RGBFormat,\n} from './three'\n\n// @ts-ignore\nimport frag from '../shaders/sixdof.frag'\n// @ts-ignore\nimport vert from '../shaders/sixdof.vert'\n\nimport { Uniforms } from './uniforms'\nimport { Style, MeshDensity, TextureType, Props } from './constants'\n\nexport default class Viewer extends Object3D {\n /** Default props if not provided */\n private props: Props = new Props()\n\n private static geometry: SphereBufferGeometry\n private material: ShaderMaterial = new ShaderMaterial({\n uniforms: Uniforms,\n vertexShader: vert,\n fragmentShader: frag,\n transparent: true,\n side: BackSide,\n })\n\n constructor(texture: Texture, depth?: Texture, props?: object) {\n super()\n\n /** Assign the user provided props, if any */\n this.setProps(this.props, props)\n\n // /** Add the compiler definitions needed to pick the right GLSL methods */\n this.setShaderDefines(this.material, [TextureType[this.props.type]])\n\n /**\n * Create the geometry only once, it can be shared between instances\n * of the viewer since it's kept as a static class member\n **/\n if (!Viewer.geometry) {\n Viewer.geometry = this.createSphereGeometry(\n this.props.radius,\n this.props.density,\n )\n }\n\n /** Assign the textures and update the shader uniforms */\n this.assignTexture(this.props.type, texture, depth)\n\n /** Set the displacement using the public setter */\n this.displacement = this.props.displacement\n\n /** Create the Mesh/Points and add it to the viewer object */\n super.add(this.createMesh(Viewer.geometry, this.material, this.props.style))\n }\n\n /** Small util to set the defines of the GLSL program based on textureType */\n private setShaderDefines(\n material: ShaderMaterial,\n defines: Array<string>,\n ): void {\n defines.forEach(define => (material.defines[define] = ''))\n }\n\n /** Internal util to create buffer geometry */\n private createSphereGeometry(\n radius: number,\n meshDensity: MeshDensity,\n ): SphereBufferGeometry {\n return new SphereBufferGeometry(radius, meshDensity, meshDensity)\n }\n\n /** Internal util to set viewer props from config object */\n private setProps(viewerProps: Props, userProps?: object): void {\n if (!userProps) return\n\n /** Iterate over user provided props and assign to viewer props */\n for (let prop in userProps) {\n if (viewerProps[prop]) {\n viewerProps[prop] = userProps[prop]\n } else {\n console.warn(\n `THREE.SixDOF: Provided ${prop} in config but it is not a valid property and being ignored`,\n )\n }\n }\n }\n\n /** Internal util to assign the textures to the shader uniforms */\n private assignTexture(\n type: TextureType,\n colorTexture: Texture,\n depthTexture?: Texture,\n ): void {\n /** Check wheter we are rendering top bottom or just single textures */\n if (type === TextureType.SEPERATE) {\n if (!depthTexture)\n throw new Error(\n 'When using seperate texture type, depthmap must be provided',\n )\n this.depth = this.setDefaultTextureProps(depthTexture)\n }\n\n /** Assign the main texture */\n this.texture = this.setDefaultTextureProps(colorTexture)\n }\n\n private setDefaultTextureProps(texture: Texture): Texture {\n texture.minFilter = NearestFilter\n texture.magFilter = LinearFilter\n texture.format = RGBFormat\n texture.generateMipmaps = false\n return texture\n }\n\n /** An internal util to create the Mesh Object3D */\n private createMesh(\n geo: SphereBufferGeometry,\n mat: ShaderMaterial,\n style: Style,\n ): Object3D {\n switch (style) {\n case Style.WIRE:\n if (!this.material.wireframe) this.material.wireframe = true\n return new Mesh(geo, mat)\n case Style.MESH:\n if (this.material.wireframe) this.material.wireframe = false\n return new Mesh(geo, mat)\n case Style.POINTS:\n return new Points(geo, mat)\n }\n }\n\n /** Toggle vieweing texture or depthmap in viewer */\n public toggleDepthDebug(state?: boolean): void {\n this.material.uniforms.debugDepth.value =\n state != undefined ? state : !this.material.uniforms.debugDepth.value\n }\n\n /** Setter for displacement amount */\n public set displacement(val: number) {\n this.material.uniforms.displacement.value = val\n }\n\n /** Setter for depthmap uniform */\n public set depth(map: Texture) {\n this.material.uniforms.depthTexture.value = map\n }\n\n /** Setter for depthmap uniform */\n public set texture(map: Texture) {\n this.material.uniforms.colorTexture.value = map\n }\n\n /** Setter for the opacity */\n public set opacity(val: number) {\n this.material.uniforms.opacity.value = val\n }\n\n /** Setter for the point size */\n public set pointSize(val: number) {\n this.material.uniforms.pointSize.value = val\n }\n\n /** Getter for the current viewer props */\n public get config(): Props {\n return this.props\n }\n\n /** Getter for the opacity */\n public get opacity(): number {\n return this.material.uniforms.opacity.value\n }\n\n /** Getter for the point size */\n public get pointSize(): number {\n return this.material.uniforms.pointSize.value\n }\n\n /** Getter for displacement amount */\n public get displacement(): number {\n return this.material.uniforms.displacement.value\n }\n\n /** Getter for texture */\n public get texture(): Texture {\n return this.material.uniforms.colorTexture.value\n }\n\n /** Getter for the depth texture */\n public get depth(): Texture {\n return this.material.uniforms.opacity.value\n }\n}\n"],"names":["MeshDensity","Style","TextureType","Uniforms","colorTexture","type","value","depthTexture","time","opacity","pointSize","debugDepth","displacement","Props","SEPERATE","density","HIGH","style","MESH","radius","Viewer","Object3D","constructor","texture","depth","props","material","ShaderMaterial","uniforms","vertexShader","vert","fragmentShader","frag","transparent","side","BackSide","setProps","this","setShaderDefines","geometry","createSphereGeometry","assignTexture","add","createMesh","defines","forEach","define","meshDensity","SphereBufferGeometry","viewerProps","userProps","prop","console","warn","Error","setDefaultTextureProps","minFilter","NearestFilter","magFilter","LinearFilter","format","RGBFormat","generateMipmaps","geo","mat","WIRE","wireframe","Mesh","POINTS","Points","toggleDepthDebug","state","undefined","val","map"],"mappings":"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"}
static/public/site.webmanifest ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "",
3
+ "short_name": "",
4
+ "icons": [
5
+ {
6
+ "src": "/public/images/favicon/android-chrome-192x192.png",
7
+ "sizes": "192x192",
8
+ "type": "image/png"
9
+ },
10
+ {
11
+ "src": "/public/images/favicon/android-chrome-512x512.png",
12
+ "sizes": "512x512",
13
+ "type": "image/png"
14
+ }
15
+ ],
16
+ "theme_color": "#ffffff",
17
+ "background_color": "#ffffff",
18
+ "display": "standalone"
19
+ }
static/three6dof.html ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+
3
+ <head>
4
+ <title>THREE.6DOF - Image Viewer Example</title>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
7
+ <style>
8
+ body {
9
+ background: #000;
10
+ color: #fff;
11
+ padding: 0;
12
+ margin: 0;
13
+ overflow: hidden;
14
+ font-family: georgia;
15
+ text-align: center;
16
+ }
17
+
18
+ a {
19
+ color: skyblue;
20
+ text-decoration: none
21
+ }
22
+
23
+ video {
24
+ display: none;
25
+ }
26
+
27
+ #info {
28
+ position: absolute;
29
+ top: 15px;
30
+ width: 100%;
31
+ }
32
+
33
+ #info_wrapper {
34
+ background: rgba(0, 0, 0, 0.7);
35
+ }
36
+ </style>
37
+
38
+ <!-- Favicon -->
39
+ <link rel="apple-touch-icon" sizes="180x180" href="public/images/favicon/apple-touch-icon.png">
40
+ <link rel="icon" type="image/png" sizes="32x32" href="public/images/favicon/favicon-32x32.png">
41
+ <link rel="icon" type="image/png" sizes="16x16" href="public/images/favicon/favicon-16x16.png">
42
+ <link rel="manifest" href="public/site.webmanifest">
43
+
44
+ <!-- Libraries -->
45
+ <script src="https://unpkg.com/[email protected]/build/three.min.js"></script>
46
+ <script src="https://unpkg.com/[email protected]/examples/js/controls/OrbitControls.js"></script>
47
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
48
+ <!-- <script src="public/js/WebVR.js"></script> -->
49
+ <script src="public/js/GUIHelper.js"></script>
50
+
51
+ <!-- THREE-6DOF -->
52
+ <script src="public/js/three-6dof.min.js"></script>
53
+ </head>
54
+
55
+ <body>
56
+ <script>
57
+ 'use strict';
58
+ // get data-rgb from parent iframe tag
59
+ var rgbBase64Img = window.frameElement?.getAttribute('data-rgb');
60
+ var depthBase64Img = window.frameElement?.getAttribute('data-depth');
61
+
62
+ // debug GUI
63
+ var gui = new dat.GUI({ closed: true, closeOnTop: true });
64
+
65
+ // We will create the viewer once the textures are loaded
66
+ var sixDofViewer;
67
+
68
+ // Keep track of time
69
+ var clock = new THREE.Clock();
70
+
71
+ let enableAnimation = true;
72
+ // Create the scene, renderer and camera
73
+ var scene = new THREE.Scene();
74
+ const w = 1024
75
+ const h = 512
76
+ var renderer = new THREE.WebGLRenderer({ antialias: true });
77
+ // renderer.setSize(w, h); //window.innerWidth, window.innerHeight);
78
+ renderer.setSize(window.innerWidth, window.innerHeight);
79
+ // renderer.vr.enabled = true;
80
+ document.body.appendChild(renderer.domElement);
81
+ // document.body.appendChild(THREE.WEBVR.createButton(renderer));
82
+
83
+ var camera = new THREE.PerspectiveCamera(55, w / h, 0.001, 1000);
84
+ var cameraDolly = new THREE.Object3D(); // We use a camera dolly since WebVR/XR will override camera transform
85
+ cameraDolly.position.y = -1.7;
86
+
87
+ cameraDolly.add(camera);
88
+ scene.add(cameraDolly);
89
+
90
+
91
+ var loadingManager = new THREE.LoadingManager();
92
+ var textureLoader = new THREE.TextureLoader(loadingManager);
93
+
94
+ // Load the textures and store them
95
+ var colorTexture, depthTexture;
96
+ // three.js load texture from base64
97
+ if (rgbBase64Img && depthBase64Img) {
98
+
99
+ textureLoader.load(rgbBase64Img, texture => { colorTexture = texture });
100
+ textureLoader.load(depthBase64Img, texture => { depthTexture = texture });
101
+ } else {
102
+ textureLoader.load('public/images/equirectangular/kandao3.jpg', texture => { colorTexture = texture });
103
+ textureLoader.load('public/images/equirectangular/kandao3_depthmap.jpg', texture => { depthTexture = texture });
104
+ }
105
+
106
+ // On finish loading create the viewer with the textures
107
+ loadingManager.onLoad = () => {
108
+ sixDofViewer = new SixDOF.Viewer(colorTexture, depthTexture,
109
+ {
110
+ 'type': SixDOF.TextureType.SEPERATE, // For seperate depth and texture (for single top bottom use TextureType.TOP_BOTTOM)
111
+ 'style': SixDOF.Style.MESH, // Chooses the rendering style (defaults to Style.MESH)
112
+ 'density': SixDOF.MeshDensity.EXTRA_HIGH, // Chooses geometry tesselation level
113
+ 'displacement': 4.0, // Defaults to 4.0
114
+ 'radius': 6 // Defaults to 6
115
+ })
116
+ scene.add(sixDofViewer);
117
+
118
+ // Create the debug GUI and add some debug params
119
+ var shaderParams = gui.addFolder('Shader');
120
+ shaderParams.add(sixDofViewer, 'displacement', 0, 7).name('Displacement');
121
+ shaderParams.add(sixDofViewer, 'opacity', 0, 1).name('Opacity');
122
+ shaderParams.add(sixDofViewer, 'pointSize', 0, 10).name('Point Size');
123
+ shaderParams.add(camera, 'fov', 1, 100).name('Camera FOV').onChange(val => {
124
+ camera.updateProjectionMatrix();
125
+ });
126
+ shaderParams.add(camera.position, 'x', -10, 10).name('Camera X');
127
+ shaderParams.add(camera.position, 'y', -10, 10).name('Camera Y');
128
+ shaderParams.add(camera.position, 'z', -10, 10).name('Camera Z');
129
+
130
+ shaderParams.add({ 'debugDepth': false }, 'debugDepth')
131
+ .name('Debug Depth')
132
+ .onChange(val => {
133
+ sixDofViewer.toggleDepthDebug(val);
134
+ });
135
+ shaderParams.add({
136
+ 'changeStyle': () => { }
137
+ }, 'changeStyle', {
138
+ 'Mesh': SixDOF.Style[SixDOF.Style.MESH],
139
+ 'Wireframe': SixDOF.Style[SixDOF.Style.WIRE],
140
+ 'Pointcloud': SixDOF.Style[SixDOF.Style.POINTS]
141
+ })
142
+ .name('Rendering Style')
143
+ .onChange(val => {
144
+ scene.remove(sixDofViewer);
145
+ sixDofViewer = new SixDOF.Viewer(colorTexture, depthTexture, {
146
+ 'style': SixDOF.Style[val]
147
+ });
148
+ scene.add(sixDofViewer);
149
+ });
150
+
151
+ shaderParams.open();
152
+ }
153
+ const controls = new THREE.OrbitControls(cameraDolly, renderer.domElement);
154
+ controls.enableZoom = true
155
+ controls.enableDamping = true;
156
+ camera.rotation.x = Math.PI / 2;
157
+
158
+ controls.autoRotate = true;
159
+ controls.addEventListener('start', function () {
160
+ controls.autoRotate = false;
161
+ });
162
+
163
+
164
+ renderer.setAnimationLoop((time) => {
165
+
166
+ controls.update();
167
+ renderer.render(scene, camera);
168
+ });
169
+
170
+
171
+
172
+ window.addEventListener('resize', ev => {
173
+ camera.aspect = window.innerWidth / window.innerHeight;
174
+ camera.updateProjectionMatrix();
175
+ renderer.setSize(window.innerWidth, window.innerHeight);
176
+ });
177
+ </script>
178
+ </body>
179
+
180
+ </html>