From e42cda919978f5015010f0434d4bade27a82395c Mon Sep 17 00:00:00 2001
From: Jonathan Lurie
rplcOpTP5}xrv1=^1(ml`vK2KJ^W=Mi+tO@
z=W0B!QrE4RMSg$3`5MnntL<0JB9A)rb&cmKkDXA=B2&LLo^N^o++r5l`TZA-XW%D`
zd>1_{!1M6Kt|a^~UuK^glUZc$b3yb!Rpyu!MSN0aj(JhUKUL uDa8d52Ks|*X5QbpHq|+@$n3Kq{HMy?
zXN~_XGRLGS;*%nJg@iaALiaQ
zwk0N|&b{aUkz3=(P4nY+TF=B*V_RZU>MR+tYJP*sOLB)l)}A|!ZHY;#Gwiqx@+<##
zX>P!@CW8%)ZHYsvbIvWB=KI|LeA6FGcB;Uh)MuSm=tzBuJ&9ZPUqTd&@BiuGB8EB(7k
zvRz`B@riXD{H~qZ1B2gYH2b?s62rW%l*gP!Vo%!g{s;X#jna<|w_*>BejhNuUuwgx
z*aM^IYP?UZ0(;U{?19m9LEd9lfjx;^v3~}?@o4smRbWrzR_uYn?|+&-W=7xqPGdW6
z#eNw4#-rIMR-rF3DfPwP7}I|}Z<3glI%02(iI09KkeHM@VsDIj_OZvtj2qZ9U}A{9
zWG4Rlw@Gcd75isQez8vsziWpvP-9!-Q|zBHI5fY_2z+9XO+~xJuvquR?~b-(SmIXf
zQ7rL#XddsBHr(?5H0*E0Z}6JEk@#&@v%k^Ym&Ux8<5uiftoU7J8*Zh(
z*t=++9sOP?F)4M#-bM3l>i0s4Td5=VE?RLbb;RDq3T#VEN*%Fx5x-BXYZ}0|*x!ZU
z+QmL_?C&-B!QR~p9f@19ztP}RuhC2FN!;?cwo@yr?NqHQM}=rG(ZOnOwW?Z4)e)^zz0?iSKF+%8SHBbuRcokK
zR0Gil)mPmd-59M$bUn49dLUX|H4<&4GKH&di8dm-k?N|}QTIm!hz?LYsM{k?ZAx@g
zwYhpIT3a;}ZB{$0P~8!2L39h%O+6Mp80|!KC$*cpJBrlSM7LJmRWW)r+Lh?8YERWe
zZL7u*9izspA!>JZ8qw3#*{WV`uO<+kpeCx}YAcshT{Vt=-+AQOs`eKxsPjLQR`^qRY|6~5F{cn_6Ok*3FVFu^VHI|Gr
z!zbp?8lOg)&Q=s?UM1%nHZt0Lq{?sD$jChpQTYuUnbz0HD@i=t$jCi^qw*UzGS;S8
zKVrUNBh#6L7~{X(@3xR>&o@3;n6I#8lo=*t8yV+j@E@Jgm1~&)lmB=9P))y$N2~o=8yUI(o7DcSjZ8V`xK8cQ
z+Q{^Gvm`Dt-?Ncv&oSPY-l6tq*C
z#zvO8f0}pV_t8dPo3L{g=7^MEvXSZUPQ`D~?=SFdBV#}30Q$y&XB!#$@}t%H85_Ao
zYnQLo`57B|D6L)2Qs-xEWL9UvMrLg;*vQN$v5m}p9^1$)rm>C8FcaIz43n{qd_Cn)
z&Q|9eZRFo5w!lB|Y$GGLG?K=D;MqpToTnenKY?c(8M*)M={E*=wvmCEQ|KGU_-rFT
zNV%o+$VV8TZRE`
FbwGPjZ#OQEi55N$8{LS^chI0gZwh(-AdqGhhbRepp{ND
z*JnB@oU=9*nSL{?KZSGFM}58#Z7Z_&r*O`EsLwZ|??vXH6wX!!d}9BQa&~;LQ_39Y)P9_KmiXkh
zZFF!JT4NaJr6oSOE%QTL4C9Qn#3%W-)t33WEryYkmH4FCwc4^c%Doh=L-=W?e3rx~
z^0>O3;UtA&b*8%H6Nb4h!(oo$P@k`czCMpFZJACA=dAu_R(}es+?MOG_7_?EQ?^`(
z`6q={Zp(F;|5I3HzD2o?5%8(8k-{pAT}p@HCxump4UW$e!zX0y#RH!yTf%lT<>TbM
zf-v8@*U#Ri_xB~XX
MapTiler 3D Examples
+
+
+
+
diff --git a/src/demos/mountains.ts b/src/demos/mountains.ts
new file mode 100644
index 0000000..ba86747
--- /dev/null
+++ b/src/demos/mountains.ts
@@ -0,0 +1,147 @@
+import * as maptilersdk from "@maptiler/sdk";
+import * as maptiler3d from "../maptiler-3d";
+
+import "@maptiler/sdk/dist/maptiler-sdk.css";
+
+const apiKey = new URLSearchParams(location.search).get("key") ?? import.meta.env.VITE_MAPTILER_API_KEY;
+
+if (apiKey === null || apiKey === undefined || apiKey === "") {
+ alert("Missing URL param with MapTiler API key ?key=XXXXX");
+}
+
+maptilersdk.config.apiKey = apiKey;
+
+const mapElement = document.getElementById("map");
+
+if (mapElement === null) {
+ throw new Error("Map element not found");
+}
+
+const map = new maptilersdk.Map({
+ container: mapElement,
+ style: maptilersdk.MapStyle.OUTDOOR.DEFAULT,
+ zoom: 14,
+ center: [86.922623, 27.986065],
+ antialias: false,
+ projection: "globe",
+ maxPitch: 89,
+ terrain: true,
+ terrainExaggeration: 1.0223,
+ terrainControl: true,
+ maptilerLogo: true,
+});
+
+const layer3D = new maptiler3d.Layer3D("custom-3D-layer");
+
+
+const TEMPLATE_OBJECT_ID = "template-object";
+let currentObjectID: string | undefined = undefined;
+
+const state: maptiler3d.MeshOptions = {
+ scale: 1000,
+ altitude: 8749,
+ heading: 0,
+ altitudeReference: maptiler3d.AltitudeReference.MEAN_SEA_LEVEL,
+ wireframe: true,
+ // https://www.peakbagger.com/peak.aspx?pid=18716
+ lngLat: { lng: 86.925812, lat: 27.985087 },
+};
+
+const createUI = () => {
+ // @ts-expect-error - lil added as script in .html file
+ const gui = new lil.GUI({ width: 400 });
+
+ const actions = {
+ addObject: () => {
+ currentObjectID = `object-${Math.random()}`;
+ layer3D.cloneMesh(TEMPLATE_OBJECT_ID, currentObjectID, {});
+ layer3D.modifyMesh(currentObjectID, { wireframe: false });
+ },
+ };
+
+ gui
+ .add(state, "heading", 0, 360, 0.1)
+ .onChange((heading: number) => {
+ layer3D.modifyMesh(TEMPLATE_OBJECT_ID, { heading });
+ })
+ .name("Heading");
+ gui
+ .add(state, "altitudeReference", { GROUND: 1, MEAN_SEA_LEVEL: 2 })
+ .onChange((value: string) => {
+ const altitudeReference =
+ value === "MEAN_SEA_LEVEL" ? maptiler3d.AltitudeReference.MEAN_SEA_LEVEL : maptiler3d.AltitudeReference.GROUND;
+
+ layer3D.modifyMesh(TEMPLATE_OBJECT_ID, { altitudeReference });
+ })
+ .name("Altitude Reference");
+ gui
+ .add(state, "altitude", 0, 10000, 1)
+ .onChange((altitude: number) => {
+ layer3D.modifyMesh(TEMPLATE_OBJECT_ID, { altitude });
+ })
+ .name("Altitude");
+ gui
+ .add(state, "scale", 0, 10000, 1)
+ .onChange((scale: number) => {
+ layer3D.modifyMesh(TEMPLATE_OBJECT_ID, { scale });
+ })
+ .name("Scale");
+ gui.add(actions, "addObject").name("Add Object");
+
+ const toggleProjectionButton = gui
+ .add(
+ {
+ changeProjection: () => {
+ const currentProjection = map.getProjection().type;
+
+ if (currentProjection === "globe") {
+ map.setProjection({ type: "mercator" });
+ } else if (currentProjection === "mercator") {
+ toggleProjectionButton.name("Activate Globe");
+ map.setProjection({ type: "globe" });
+ toggleProjectionButton.name("Activate Mercator");
+ } else {
+ throw new Error(`Unsupported projection: ${currentProjection}`);
+ }
+ },
+ },
+ "changeProjection",
+ )
+ .name("Activate Mercator");
+
+ return gui;
+};
+
+createUI();
+
+(async () => {
+ await map.onReadyAsync();
+
+ map.addLayer(layer3D);
+
+ layer3D.setAmbientLight({ intensity: 2 });
+ layer3D.addPointLight("point-light", { intensity: 30 });
+ layer3D.modifyPointLight("point-light", { intensity: 100 });
+
+ await layer3D.addMeshFromURL(TEMPLATE_OBJECT_ID, "models/position-indicator--y-up.glb", {
+ ...state,
+ sourceOrientation: maptiler3d.SourceOrientation.Y_UP,
+ });
+
+ map.on("mousemove", (e) => {
+ if (currentObjectID === undefined) {
+ return;
+ }
+
+ layer3D.modifyMesh(currentObjectID, { lngLat: e.lngLat });
+ });
+
+ map.on("click", (e) => {
+ if (currentObjectID === undefined) {
+ return;
+ }
+
+ layer3D.modifyMesh(currentObjectID, { lngLat: e.lngLat });
+ currentObjectID = undefined;
+ });
+})();
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/src/vite-env.d.ts
@@ -0,0 +1 @@
+///