transform hotspots

This commit is contained in:
Mark Hu 2020-12-29 00:19:39 +08:00
parent 670d8fa570
commit 15c86511b4

View file

@ -258,25 +258,26 @@ class _PanoramaState extends State<Panorama> with SingleTickerProviderStateMixin
} }
} }
Matrix4 matrixFromLatLon(double lat, double lon) {
return Matrix4.rotationY(radians(90.0 - lon))..rotateX(radians(lat));
}
Vector3 positionFromLatLon(double lat, double lon) { Vector3 positionFromLatLon(double lat, double lon) {
if (scene == null) return Vector3.all(double.maxFinite); if (scene != null) {
// generate a transform matrix // generate a transform matrix
final Matrix4 model = Matrix4.identity(); final Matrix4 m = scene.camera.projectionMatrix * scene.camera.lookAtMatrix * matrixFromLatLon(lat, lon);
model.rotateY(radians(90.0 - lon)); // apply transform
model.rotateX(radians(lat)); final Vector4 v = Vector4(0.0, 0.0, -_radius, 1.0)..applyMatrix4(m);
final Matrix4 m = scene.camera.projectionMatrix * scene.camera.lookAtMatrix * model; // transform homogeneous coordinates to NDC and remaps to the viewport
// apply transform if (v.z >= 0.0)
final Vector4 v = Vector4(0.0, 0.0, -_radius, 1.0); return Vector3(
v.applyMatrix4(m); (1.0 + v.x / v.w) * scene.camera.viewportWidth / 2,
return (v.z < 0.0) (1.0 - v.y / v.w) * scene.camera.viewportHeight / 2,
// make it invisible if the hotspot is behind the camera v.z,
? Vector3.all(double.maxFinite) );
// transform homogeneous coordinates to NDC and remaps to the viewport }
: Vector3( // make it invisible if not ready or hotspot is behind the camera
(1.0 + v.x / v.w) * scene.camera.viewportWidth / 2, return Vector3.all(double.maxFinite);
(1.0 - v.y / v.w) * scene.camera.viewportHeight / 2,
v.z,
);
} }
Widget buildHotspotWidgets(List<Hotspot> hotspots) { Widget buildHotspotWidgets(List<Hotspot> hotspots) {
@ -284,12 +285,18 @@ class _PanoramaState extends State<Panorama> with SingleTickerProviderStateMixin
if (hotspots != null) { if (hotspots != null) {
for (Hotspot hotspot in hotspots) { for (Hotspot hotspot in hotspots) {
final Vector3 pos = positionFromLatLon(hotspot.latitude, hotspot.longitude); final Vector3 pos = positionFromLatLon(hotspot.latitude, hotspot.longitude);
final Offset orgin = Offset(hotspot.width * hotspot.orgin.dx, hotspot.height * hotspot.orgin.dy);
final Matrix4 transform = scene.camera.lookAtMatrix * matrixFromLatLon(hotspot.latitude, hotspot.longitude);
final Widget child = Positioned( final Widget child = Positioned(
left: pos.x - hotspot.width * hotspot.orgin.dx, left: pos.x - orgin.dx,
top: pos.y - hotspot.height * hotspot.orgin.dy, top: pos.y - orgin.dy,
width: hotspot.width, width: hotspot.width,
height: hotspot.height, height: hotspot.height,
child: hotspot.widget, child: Transform(
origin: orgin,
transform: transform..invert(),
child: hotspot.widget,
),
); );
widgets.add(child); widgets.add(child);
} }