Skip to content

Commit 67226b9

Browse files
authored
Merge pull request #1164 from 3DStreet/tiles-flattening-experiment
Tiles flattening experiment
2 parents ac87cd7 + 52837ba commit 67226b9

File tree

6 files changed

+353
-51
lines changed

6 files changed

+353
-51
lines changed

package-lock.json

Lines changed: 30 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"@gltf-transform/functions": "^3.10.0",
3232
"@react-google-maps/api": "^2.19.3",
3333
"@stripe/stripe-js": "^3.4.1",
34-
"3d-tiles-renderer": "^0.4.8",
34+
"3d-tiles-renderer": "^0.4.10",
3535
"aframe-atlas-uvs-component": "^3.0.0",
3636
"aframe-cursor-teleport-component": "^1.6.0",
3737
"aframe-extras": "^7.5.1",

src/aframe-components/google-maps-aerial.js

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import {
33
TilesFadePlugin,
44
TileCompressionPlugin,
55
GLTFExtensionsPlugin,
6-
GoogleCloudAuthPlugin
6+
GoogleCloudAuthPlugin,
7+
TileFlatteningPlugin
78
} from '3d-tiles-renderer/plugins';
89

9-
console.log('3d-tiles-renderer', TilesRenderer);
1010
const MathUtils = AFRAME.THREE.MathUtils;
11+
const Vector3 = AFRAME.THREE.Vector3;
12+
const Box3 = AFRAME.THREE.Box3;
1113

1214
if (typeof AFRAME === 'undefined') {
1315
throw new Error(
@@ -23,7 +25,9 @@ AFRAME.registerComponent('google-maps-aerial', {
2325
minDistance: { type: 'number', default: 500 },
2426
maxDistance: { type: 'number', default: 20000 },
2527
ellipsoidalHeight: { type: 'number', default: 0 },
26-
copyrightEl: { type: 'selector' }
28+
copyrightEl: { type: 'selector' },
29+
enableFlattening: { type: 'boolean', default: false },
30+
flatteningShape: { type: 'string', default: '' }
2731
},
2832

2933
init: function () {
@@ -44,6 +48,9 @@ AFRAME.registerComponent('google-maps-aerial', {
4448
})
4549
);
4650

51+
// Always create flattening plugin to support runtime toggling
52+
this.flatteningPlugin = new TileFlatteningPlugin();
53+
this.tiles.registerPlugin(this.flatteningPlugin);
4754
// Set location
4855
this.tiles.setLatLonToYUp(
4956
this.data.latitude * MathUtils.DEG2RAD,
@@ -55,6 +62,15 @@ AFRAME.registerComponent('google-maps-aerial', {
5562
this.data.copyrightEl.innerHTML =
5663
this.tiles.getAttributions()[0]?.value || '';
5764
}
65+
66+
// Add flattening shape after tiles are loaded
67+
if (
68+
this.data.enableFlattening &&
69+
this.data.flatteningShape &&
70+
!this.flatteningShape
71+
) {
72+
this.addFlatteningShape(this.data.flatteningShape);
73+
}
5874
});
5975

6076
// Create a child entity for the height offset
@@ -77,6 +93,46 @@ AFRAME.registerComponent('google-maps-aerial', {
7793
}
7894
},
7995

96+
addFlatteningShape: function (shapeSelector) {
97+
if (!this.flatteningPlugin || !shapeSelector) return;
98+
99+
const testMeshEl = document.querySelector(shapeSelector);
100+
if (!testMeshEl) return;
101+
102+
const testMesh = testMeshEl.object3D.children[0];
103+
if (!testMesh) return;
104+
105+
// Ensure world transforms are up to date
106+
this.tiles.group.updateMatrixWorld();
107+
testMesh.updateMatrixWorld(true);
108+
109+
// Transform the shape into the local frame of the tile set
110+
const relativeShape = testMesh.clone();
111+
relativeShape.matrixWorld
112+
.premultiply(this.tiles.group.matrixWorldInverse)
113+
.decompose(
114+
relativeShape.position,
115+
relativeShape.quaternion,
116+
relativeShape.scale
117+
);
118+
119+
// Calculate the direction to flatten on using ellipsoid
120+
const direction = new Vector3();
121+
const box = new Box3();
122+
box.setFromObject(relativeShape);
123+
box.getCenter(direction);
124+
this.tiles.ellipsoid
125+
.getPositionToNormal(direction, direction)
126+
.multiplyScalar(-1);
127+
128+
// Add the transformed plane as a flattening shape
129+
this.flatteningPlugin.addShape(relativeShape, direction, Infinity);
130+
131+
// Store references for cleanup and updates
132+
this.flatteningShape = relativeShape;
133+
this.originalFlatteningMesh = testMesh;
134+
},
135+
80136
tick: function () {
81137
if (this.tiles && this.el.sceneEl.camera) {
82138
// Ensure camera is set on each tick
@@ -85,12 +141,45 @@ AFRAME.registerComponent('google-maps-aerial', {
85141
this.el.sceneEl.camera,
86142
this.renderer
87143
);
144+
145+
// Update flattening shape if it exists
146+
if (
147+
this.flatteningPlugin &&
148+
this.flatteningShape &&
149+
this.originalFlatteningMesh
150+
) {
151+
// Update world transforms
152+
this.tiles.group.updateMatrixWorld();
153+
this.originalFlatteningMesh.updateMatrixWorld(true);
154+
155+
// Re-transform the shape into the local frame of the tile set
156+
this.flatteningShape.matrixWorld.copy(
157+
this.originalFlatteningMesh.matrixWorld
158+
);
159+
this.flatteningShape.matrixWorld
160+
.premultiply(this.tiles.group.matrixWorldInverse)
161+
.decompose(
162+
this.flatteningShape.position,
163+
this.flatteningShape.quaternion,
164+
this.flatteningShape.scale
165+
);
166+
167+
this.flatteningPlugin.updateShape(this.flatteningShape);
168+
}
169+
88170
this.tiles.update();
89171
}
90172
},
91173

92174
remove: function () {
93175
if (this.tiles) {
176+
// Clean up flattening shape
177+
if (this.flatteningPlugin && this.flatteningShape) {
178+
this.flatteningPlugin.deleteShape(this.flatteningShape);
179+
this.flatteningShape = null;
180+
this.originalFlatteningMesh = null;
181+
}
182+
94183
if (this.offsetEl) {
95184
this.offsetEl.removeFromParent();
96185
this.offsetEl = null;
@@ -114,5 +203,24 @@ AFRAME.registerComponent('google-maps-aerial', {
114203
);
115204
this.offsetEl.object3D.position.y = -this.data.ellipsoidalHeight;
116205
}
206+
207+
// Handle flattening changes
208+
const flatteningChanged =
209+
oldData.enableFlattening !== this.data.enableFlattening;
210+
const shapeChanged = oldData.flatteningShape !== this.data.flatteningShape;
211+
212+
if (flatteningChanged || shapeChanged) {
213+
// Remove old shape if it exists
214+
if (this.flatteningShape) {
215+
this.flatteningPlugin.deleteShape(this.flatteningShape);
216+
this.flatteningShape = null;
217+
this.originalFlatteningMesh = null;
218+
}
219+
220+
// Add new shape if flattening is enabled and we have a shape
221+
if (this.data.enableFlattening && this.data.flatteningShape) {
222+
this.addFlatteningShape(this.data.flatteningShape);
223+
}
224+
}
117225
}
118226
});

0 commit comments

Comments
 (0)