Build a mesh in code: the source
Open the live demo · Read the guide · View on GitHub
Regions the guide quotes: builder (line 21), faces (line 32), scene (line 63), check (line 82).
1/// A pyramid, written vertex by vertex instead of generated from a shape.
2library;
4import 'package:flutter3d/flutter3d.dart';
5import 'package:flutter3d_showcase/src/demo/demo.dart';
6import 'package:vector_math/vector_math.dart';
8final class MeshBuilderDemo extends ShowcaseDemo {
9 late final MeshData _pyramid;
12 void configureView(DemoContext context) {
13 context.orbit
14 ..distance = 5.5
15 ..pitch = 0.28
16 ..yaw = 0.5;
17 }
20 Scene build(DemoContext context) {
21 final MeshBuilder builder = MeshBuilder(VertexLayout.standard);
22 const double half = 0.9;
23 const double apexHeight = 1.3;
24 final Vector3 apex = Vector3(0.0, apexHeight, 0.0);
25 final List<Vector3> base = <Vector3>[
26 Vector3(-half, 0.0, -half),
27 Vector3(half, 0.0, -half),
28 Vector3(half, 0.0, half),
29 Vector3(-half, 0.0, half),
30 ];
32 final int apexIndex = builder.addVertex(
33 position: apex,
34 normal: Vector3(0.0, 1.0, 0.0),
35 texcoord: Vector2(0.5, 0.0),
36 color: Vector4(1.0, 0.92, 0.6, 1.0),
37 );
38 final List<int> baseIndices = <int>[];
39 for (var i = 0; i < base.length; i++) {
40 final Vector3 edge = base[(i + 1) % base.length] - base[i];
41 final Vector3 toApex = apex - base[i];
42 final Vector3 normal = edge.cross(toApex)..normalize();
43 baseIndices.add(
44 builder.addVertex(
45 position: base[i],
46 normal: normal,
47 texcoord: Vector2(i / base.length, 1.0),
48 color: Vector4(0.65, 0.7, 0.8, 1.0),
49 ),
50 );
51 }
52 for (var i = 0; i < base.length; i++) {
53 builder.addTriangle(baseIndices[i], baseIndices[(i + 1) % 4], apexIndex);
54 }
55 builder.addQuad(
56 baseIndices[3],
57 baseIndices[2],
58 baseIndices[1],
59 baseIndices[0],
60 );
61 _pyramid = builder.build();
63 final Scene scene = Scene()
64 ..ambientColor = Vector3(0.42, 0.5, 0.66)
65 ..ambientIntensity = 0.16
66 ..add(
67 MeshNode(
68 DeviceMesh.upload(context.device, _pyramid),
69 Material(name: 'pyramid', roughness: 0.6),
70 name: 'pyramid',
71 ),
72 )
73 ..add(
74 LightNode(name: 'key', intensity: 3.2)
75 ..setLocalForward(Vector3(-0.42, -0.78, -0.4)),
76 );
77 return scene;
78 }
81 void verify(Scene scene, FrameResult frame) {
82 if (_pyramid.vertexCount != 5 ||
83 _pyramid.indexCount != 18 ||
84 frame.drawCalls < 1) {
85 throw StateError('the hand-built pyramid did not reach the frame');
86 }
87 }
88}