flutter3d
Showcase Changelog 38 packages API reference

Surfaces of revolution: the source

since 0.1.0 Scene and geometry

Regions the guide quotes: profile (line 24), sweep (line 37), light (line 68), check (line 86).

1/// A vessel made by sweeping a profile around the Y axis.
2library;
3
4import 'dart:math' as math;
5
6import 'package:flutter3d/flutter3d.dart';
7import 'package:flutter3d_showcase/src/demo/demo.dart';
8import 'package:vector_math/vector_math.dart';
9
10final class LatheShapeDemo extends ShowcaseDemo {
11 final List<MeshNode> _vessels = <MeshNode>[];
13 @override
14 void configureView(DemoContext context) {
15 context.orbit
16 ..distance = 9.0
17 ..pitch = 0.24
18 ..yaw = 0.42;
19 context.orbit.target.setValues(0.0, 1.15, 0.0);
20 }
22 @override
23 Scene build(DemoContext context) {
24 final List<Vector2> profile = <Vector2>[
25 Vector2(0.0, -1.25),
26 Vector2(0.72, -1.25),
27 Vector2(0.78, -1.1),
28 Vector2(0.82, -0.55),
29 Vector2(0.62, 0.05),
30 Vector2(0.46, 0.7),
31 Vector2(0.46, 1.05),
32 Vector2(0.62, 1.18),
33 Vector2(0.62, 1.25),
34 Vector2(0.5, 1.25),
35 ];
37 final List<(String, double, int)> variants = <(String, double, int)>[
38 ('faceted', math.pi * 2.0, 12),
39 ('smooth', math.pi * 2.0, 48),
40 ('open sweep', math.pi * 1.5, 36),
41 ];
42 final Scene scene = Scene()
43 ..ambientColor = Vector3(0.48, 0.56, 0.72)
44 ..ambientIntensity = 0.14;
45 for (var i = 0; i < variants.length; i++) {
46 final (String name, double sweep, int segments) = variants[i];
47 final MeshData data = LatheShape(
48 profile: profile,
49 segments: segments,
50 sweepAngle: sweep,
51 name: name,
52 ).build();
53 final Material clay = Material(
54 name: '$name clay',
55 baseColor: Vector4(0.78, 0.35 + i * 0.12, 0.2 + i * 0.16, 1.0),
56 roughness: 0.48,
57 doubleSided: sweep < math.pi * 2.0,
58 );
59 final MeshNode node = MeshNode(
60 DeviceMesh.upload(context.device, data),
61 clay,
62 name: name,
63 )..setPosition((i - 1) * 2.6, 1.25, 0.0);
64 _vessels.add(node);
65 scene.add(node);
66 }
68 scene
69 ..add(
70 LightNode(name: 'key', intensity: 3.2)
71 ..setLocalForward(Vector3(-0.45, -0.82, -0.34)),
72 )
73 ..add(
74 LightNode(
75 type: LightType.point,
76 intensity: 8.0,
77 range: 10.0,
78 name: 'rim',
79 )..setPosition(2.5, 3.8, -2.5),
80 );
81 return scene;
82 }
84 @override
85 void verify(Scene scene, FrameResult frame) {
86 const Set<String> expected = <String>{'faceted', 'smooth', 'open sweep'};
87 final Set<String?> actual = <String?>{
88 for (final MeshNode node in _vessels) node.name,
89 };
90 if (_vessels.length != 3 ||
91 !actual.containsAll(expected) ||
92 frame.drawCalls < 3) {
93 throw StateError('the three lathe variants were not drawn');
94 }
95 }