Skip to content

Commit 43e5d63

Browse files
feat: add fisheye example
Add example for heavily distorted fisheye.
1 parent e8e0ca0 commit 43e5d63

File tree

2 files changed

+210
-1
lines changed

2 files changed

+210
-1
lines changed

doc/src/js/utils/ChunkDataProvider.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ const IMAGE_TILES_Y = 10;
1919

2020
export const REFERENCE = {alt: 0, lat: 0, lng: 0};
2121

22+
function cloneMesh(mesh) {
23+
return {faces: mesh.faces.slice(), vertices: mesh.vertices.slice()};
24+
}
25+
2226
export class ChunkDataProvider extends DataProviderBase {
2327
constructor() {
2428
super(new S2GeometryProvider());
@@ -27,6 +31,7 @@ export class ChunkDataProvider extends DataProviderBase {
2731
this.cells = new Map();
2832
this.clusters = new Map();
2933
this.images = new Map();
34+
this.mesh = {faces: [], vertices: []};
3035
this.sequences = new Map();
3136
}
3237

@@ -143,7 +148,7 @@ export class ChunkDataProvider extends DataProviderBase {
143148

144149
// eslint-disable-next-line class-methods-use-this
145150
getMesh(_url) {
146-
return Promise.resolve({faces: [], vertices: []});
151+
return Promise.resolve(cloneMesh(this.mesh));
147152
}
148153

149154
getSequence(sequenceId) {
@@ -157,4 +162,8 @@ export class ChunkDataProvider extends DataProviderBase {
157162
getSpatialImages(imageIds) {
158163
return this.getImages(imageIds);
159164
}
165+
166+
setMesh(mesh) {
167+
this.mesh = mesh;
168+
}
160169
}

examples/debug/fisheye.html

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Fisheye</title>
5+
<link rel="icon" href="data:," />
6+
<meta charset="utf-8" />
7+
<meta
8+
name="viewport"
9+
content="width=device-width, initial-scale=1.0, user-scalable=no"
10+
/>
11+
12+
<link rel="stylesheet" href="/dist/mapillary.css" />
13+
14+
<style>
15+
body {
16+
margin: 0;
17+
padding: 0;
18+
}
19+
20+
html,
21+
body,
22+
.viewer {
23+
width: 100%;
24+
height: 100%;
25+
}
26+
</style>
27+
</head>
28+
29+
<body>
30+
<script type="module">
31+
import { accessToken } from "/doc-src/.access-token/token.js";
32+
import {
33+
CameraControls,
34+
Viewer,
35+
S2GeometryProvider,
36+
} from "/dist/mapillary.module.js";
37+
import { ChunkDataProvider } from "/doc-src/src/js/utils/ChunkDataProvider.js";
38+
import {
39+
CAMERA_TYPE_FISHEYE,
40+
cameraTypeToAspect,
41+
generateCluster,
42+
} from "/doc-src/src/js/utils/provider.js";
43+
44+
let viewer;
45+
let dataProvider;
46+
let chunks;
47+
let chunkCounter = 0;
48+
49+
const INTERVALS = 1;
50+
const REFERENCE = { alt: 0, lat: 0, lng: 0 };
51+
52+
(function main() {
53+
const container = document.createElement("div");
54+
container.className = "viewer";
55+
document.body.append(container);
56+
57+
dataProvider = new ChunkDataProvider({
58+
geometry: new S2GeometryProvider(18),
59+
});
60+
const options = {
61+
dataProvider,
62+
cameraControls: CameraControls.Earth,
63+
component: {
64+
cache: false,
65+
cover: false,
66+
image: true,
67+
spatial: {
68+
cameraSize: 0.3,
69+
cellGridDepth: 2,
70+
cellsVisible: true,
71+
},
72+
},
73+
container,
74+
imageTiling: false,
75+
};
76+
viewer = new Viewer(options);
77+
chunks = [];
78+
79+
dataProvider.addChunk(generateChunk());
80+
dataProvider.setMesh(generateMesh());
81+
82+
const imageId = dataProvider.images
83+
.keys()
84+
.next().value;
85+
viewer
86+
.moveTo(imageId)
87+
.catch((error) => console.error(error));
88+
89+
listen();
90+
})();
91+
92+
function generateChunk() {
93+
const cameraType = CAMERA_TYPE_FISHEYE;
94+
const height = 2495;
95+
const width = 2496;
96+
const focal = 0.2212;
97+
const k1 = 0.1282;
98+
const k2 = -0.01223;
99+
100+
const distance = 1;
101+
const counter = chunks.length;
102+
const shift = counter * 1;
103+
const mod = 3;
104+
const config = {
105+
cameraType,
106+
color: [1, (counter % mod) / (mod - 1), 0],
107+
distance,
108+
east: shift,
109+
focal,
110+
height,
111+
id: counter.toString(),
112+
idCounter: counter * (INTERVALS + 1),
113+
k1,
114+
k2,
115+
reference: REFERENCE,
116+
width,
117+
};
118+
119+
const chunk = generateCluster(config, INTERVALS);
120+
chunk.id = chunk.cluster.id;
121+
return chunk;
122+
}
123+
124+
function listen() {
125+
window.document.addEventListener("keydown", (e) => {
126+
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
127+
return;
128+
}
129+
130+
switch (e.key) {
131+
case "c": {
132+
// Change camera controls
133+
viewer.getCameraControls()
134+
.then(c => {
135+
switch (c) {
136+
case CameraControls.Earth: {
137+
viewer.setCameraControls(CameraControls.Street);
138+
break;
139+
}
140+
case CameraControls.Street: {
141+
viewer.setCameraControls(CameraControls.Gravity);
142+
break;
143+
}
144+
default:
145+
viewer.setCameraControls(CameraControls.Earth);
146+
break;
147+
}
148+
});
149+
}
150+
default:
151+
break;
152+
}
153+
});
154+
}
155+
156+
function generateMesh() {
157+
const vertices = [
158+
// Bottom
159+
-1, -1, -1,
160+
1, -1, -1,
161+
1, 1, -1,
162+
-1, 1, -1,
163+
// Top
164+
-1, -1, 1,
165+
1, -1, 1,
166+
1, 1, 1,
167+
-1, 1, 1,
168+
];
169+
170+
const length = 10 / Math.sqrt(3);
171+
for (let i = 0; i < vertices.length; i++) {
172+
vertices[i] = length * vertices[i];
173+
}
174+
175+
const faces = [
176+
// Back (z=-1)
177+
0, 1, 3,
178+
1, 3, 2,
179+
// Left (x=-1)
180+
0, 4, 3,
181+
3, 7, 4,
182+
// Up (y=-1)
183+
0, 4, 1,
184+
1, 5, 4,
185+
// Right (x=1)
186+
1, 5, 2,
187+
2, 6, 5,
188+
// Bottom (y=1)
189+
2, 6, 3,
190+
3, 7, 6,
191+
// Front (z=1)
192+
4, 5, 7,
193+
5, 7, 6,
194+
];
195+
196+
return {faces, vertices};
197+
}
198+
</script>
199+
</body>
200+
</html>

0 commit comments

Comments
 (0)