flutter3d
Showcase Changelog 38 packages API reference

Procedural shapes: the source

since 0.1.0 Scene and geometry

Regions the guide quotes: descriptions (line 22), build (line 41), lighting (line 68), check (line 86).

1/// Five meshes generated from shape values without loading an asset.
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 ProceduralShapesDemo extends ShowcaseDemo {
9 final List<MeshNode> _shapes = <MeshNode>[];
11 @override
12 void configureView(DemoContext context) {
13 context.orbit
14 ..distance = 11.0
15 ..pitch = 0.25
16 ..yaw = 0.12;
17 context.orbit.target.setValues(0.0, 0.35, 0.0);
18 }
20 @override
21 Scene build(DemoContext context) {
22 final List<(String, Shape)> descriptions = <(String, Shape)>[
23 ('cuboid', CuboidShape(size: Vector3(1.4, 1.4, 1.4))),
24 ('sphere', const SphereShape(radius: 0.8, segments: 32, rings: 16)),
25 (
26 'torus',
27 const TorusShape(
28 radius: 0.58,
29 tubeRadius: 0.24,
30 segments: 40,
31 tubeSegments: 18,
32 ),
33 ),
34 (
35 'capsule',
36 const CapsuleShape(radius: 0.45, height: 0.8, segments: 32, rings: 8),
37 ),
38 ('disc', const DiscShape(radius: 0.9, innerRadius: 0.28, segments: 40)),
39 ];
41 final Scene scene = Scene()
42 ..ambientColor = Vector3(0.55, 0.62, 0.78)
43 ..ambientIntensity = 0.16;
44 for (var i = 0; i < descriptions.length; i++) {
45 final (String name, Shape shape) = descriptions[i];
46 final MeshData data = shape.build();
47 final Material material = Material(
48 name: '$name material',
49 baseColor: Vector4(
50 0.28 + i * 0.12,
51 0.68 - i * 0.07,
52 0.82 - i * 0.1,
53 1.0,
54 ),
55 roughness: 0.42,
56 metallic: i == 2 ? 0.55 : 0.05,
57 doubleSided: name == 'disc',
58 );
59 final MeshNode node = MeshNode(
60 DeviceMesh.upload(context.device, data),
61 material,
62 name: name,
63 )..setPosition((i - 2) * 2.0, name == 'disc' ? 0.25 : 0.85, 0.0);
64 _shapes.add(node);
65 scene.add(node);
66 }
68 scene
69 ..add(
70 LightNode(name: 'key', intensity: 3.4)
71 ..setLocalForward(Vector3(-0.45, -0.8, -0.38)),
72 )
73 ..add(
74 LightNode(
75 type: LightType.point,
76 intensity: 10.0,
77 range: 12.0,
78 name: 'fill',
79 )..setPosition(-3.0, 3.5, 3.0),
80 );
81 return scene;
82 }
84 @override
85 void verify(Scene scene, FrameResult frame) {
86 final Set<String?> names = <String?>{
87 for (final MeshNode node in _shapes) node.name,
88 };
89 const Set<String> expected = <String>{
90 'cuboid',
91 'sphere',
92 'torus',
93 'capsule',
94 'disc',
95 };
96 if (_shapes.length != expected.length ||
97 !names.containsAll(expected) ||
98 frame.drawCalls < expected.length) {
99 throw StateError('not every procedural shape was drawn');
100 }
101 }