flutter3d
Showcase Changelog 38 packages API reference

Debug drawing: the source

since 0.7.0 Scene and geometry

Regions the guide quotes: model (line 27), rig (line 43), scene (line 61), options (line 77), controls (line 91), check (line 120).

1/// Built-in overlays for inspecting a scene while it runs.
2library;
3
4import 'package:flutter3d/flutter3d.dart';
5import 'package:flutter3d_showcase/src/demo/demo.dart';
6import 'package:vector_math/vector_math.dart';
7
8final class DebugDrawDemo extends ShowcaseDemo {
9 bool _bounds = true;
10 bool _normals = true;
11 bool _axes = true;
12 bool _lights = true;
13 bool _skeleton = true;
14 late final Skeleton _rig;
16 @override
17 void configureView(DemoContext context) {
18 context.orbit
19 ..distance = 7.2
20 ..pitch = 0.24
21 ..yaw = 0.55;
22 context.orbit.target.setValues(0.0, 0.8, 0.0);
23 }
25 @override
26 Scene build(DemoContext context) {
27 final MeshData bodyData = const CapsuleShape(
28 radius: 0.58,
29 height: 1.4,
30 segments: 20,
31 rings: 6,
32 ).build(layout: VertexLayout.skinned);
33 final MeshNode body = MeshNode(
34 DeviceMesh.upload(context.device, bodyData),
35 Material(
36 name: 'blue body',
37 baseColor: Vector4(0.12, 0.42, 0.78, 1.0),
38 roughness: 0.48,
39 ),
40 name: 'inspected capsule',
41 )..setPosition(0.0, 1.25, 0.0);
43 final SceneNode hip = SceneNode(name: 'hip')..setPosition(0.0, 0.45, 0.0);
44 final SceneNode chest = SceneNode(name: 'chest')
45 ..setPosition(0.0, 0.8, 0.0);
46 final SceneNode head = SceneNode(name: 'head')
47 ..setPosition(0.25, 0.72, 0.0);
48 hip.add(chest);
49 chest.add(head);
50 _rig = Skeleton(
51 name: 'three-joint rig',
52 joints: <SceneNode>[hip, chest, head],
53 inverseBindMatrices: <Matrix4>[
54 Matrix4.copy(hip.worldMatrix)..invert(),
55 Matrix4.copy(chest.worldMatrix)..invert(),
56 Matrix4.copy(head.worldMatrix)..invert(),
57 ],
58 );
59 body.skeleton = _rig;
61 final Scene scene = Scene()
62 ..ambientColor = Vector3(0.38, 0.46, 0.62)
63 ..ambientIntensity = 0.14
64 ..add(hip)
65 ..add(body)
66 ..add(
67 LightNode(
68 type: LightType.point,
69 intensity: 14.0,
70 range: 8.0,
71 name: 'debugged light',
72 )..setPosition(-2.2, 3.2, 2.0),
73 );
74 return scene;
75 }
77 DebugDrawOptions get _debug => DebugDrawOptions(
78 bounds: _bounds,
79 normals: _normals,
80 axes: _axes,
81 lightGizmos: _lights,
82 skeletons: _skeleton,
83 normalLength: 0.18,
84 );
86 @override
87 RenderSettings settings(DemoContext context) => RenderSettings(debug: _debug);
89 @override
90 List<DemoControl> controls(DemoContext context) => <DemoControl>[
91 ToggleControl(
92 'Bounds',
93 value: () => _bounds,
94 onChanged: (bool value) => _bounds = value,
95 ),
96 ToggleControl(
97 'Normals',
98 value: () => _normals,
99 onChanged: (bool value) => _normals = value,
100 ),
101 ToggleControl(
102 'World axes',
103 value: () => _axes,
104 onChanged: (bool value) => _axes = value,
105 ),
106 ToggleControl(
107 'Light gizmo',
108 value: () => _lights,
109 onChanged: (bool value) => _lights = value,
110 ),
111 ToggleControl(
112 'Skeleton',
113 value: () => _skeleton,
114 onChanged: (bool value) => _skeleton = value,
115 ),
116 ];
118 @override
119 void verify(Scene scene, FrameResult frame) {
120 if (!_debug.anyEnabled ||
121 _rig.jointCount != 3 ||
122 frame.debugLines <= 15 ||
123 frame.drawCalls < 2) {
124 throw StateError('the requested debug overlays were not drawn');
125 }
126 }