Cardboard viewer profiles: the source
Open the live demo · Read the guide · View on GitHub
Regions the guide quotes: viewer (line 41), apply (line 47), compare (line 70).
1/// The numbers a folded cardboard holder and a moulded one differ by, turned
2/// into an off-centre frustum per eye — wider away from the nose than
3/// towards it, which is what a lens actually looks through.
4///
5/// Quoted by `viewer_profiles.md` and shown whole in the Source tab.
6library;
8import 'package:flutter/widgets.dart';
9import 'package:flutter3d/flutter3d.dart' hide Material;
10import 'package:flutter3d/flutter3d.dart' as f3d show Material;
11import 'package:flutter3d_showcase/src/demo/demo.dart';
12import 'package:flutter3d_stereo/flutter3d_stereo.dart';
13import 'package:vector_math/vector_math.dart';
15final class ViewerProfilesDemo extends ShowcaseDemo {
16 bool useV1 = false;
18 final StereoRig _rig = StereoRig();
19 late Scene _scene;
22 Scene build(DemoContext context) {
23 final material = f3d.Material(
24 name: 'ball',
25 baseColor: Vector4(0.8, 0.5, 0.3, 1.0),
26 );
27 final ball = MeshNode(
28 DeviceMesh.upload(context.device, SphereShape(segments: 24).build()),
29 material,
30 )..setPosition(0, 0, -2);
31 _scene = Scene()
32 ..add(_rig.stage)
33 ..add(ball)
34 ..add(
35 LightNode(name: 'sun', intensity: 3.0)
36 ..setLocalForward(Vector3(-0.4, -1.0, -0.3)),
37 );
38 return _scene;
39 }
41 StereoViewer get _viewer =>
42 useV1 ? StereoViewer.cardboardV1 : StereoViewer.cardboardV2;
43 static const _screen = StereoScreen(width: 0.13, height: 0.07);
46 Widget? customBody(BuildContext buildContext, DemoContext context) {
47 _rig.applyViewer(_viewer, _screen);
48 return StereoSurface(
49 renderer: context.renderer,
50 scene: _scene,
51 rig: _rig,
52 settings: () => const RenderSettings().forStereo(),
53 onBeforeFrame: () {},
54 viewer: _viewer,
55 screen: _screen,
56 );
57 }
60 List<DemoControl> controls(DemoContext context) => <DemoControl>[
61 ToggleControl(
62 'Cardboard v1 (narrower)',
63 value: () => useV1,
64 onChanged: (bool v) => useV1 = v,
65 ),
66 ];
69 void verify(Scene scene, FrameResult frame) {
70 // V1's lenses show less of the world than v2's wider window.
71 final v1 = StereoViewer.cardboardV1.projectionFor(Eye.left, _screen);
72 final v2 = StereoViewer.cardboardV2.projectionFor(Eye.left, _screen);
73 final v1Width = v1.tanRight - v1.tanLeft;
74 final v2Width = v2.tanRight - v2.tanLeft;
75 if (v1Width >= v2Width) {
76 throw StateError(
77 'the older, narrower viewer should show less of the '
78 'world than the newer one, at the same screen',
79 );
80 }
81 }
82}