-
Notifications
You must be signed in to change notification settings - Fork 36
Open
Description
When displaying multiple 3D scenes, sizes are assigned incorrectly and swapped. In the example, you can see that the second scene is rendered with the smaller size, and the first with the larger one.
Expected
The first scene should be rendered with a size of 100x100, and the second with 200x200.
Issue
The sizes are swapped; the first is rendered with 200x200, and the second with 100x100.
Assigning different renderNumber values to ThreeJS makes no difference.
Tested on MacOS and Android.
Render result
Simple example showing the issue
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:three_js/three_js.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatefulWidget {
const ExampleApp({super.key});
@override
State<ExampleApp> createState() => _MyAppState();
}
class _MyAppState extends State<ExampleApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.blue),
home: Scaffold(
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const SizedBox(
width: 100,
height: 100,
child: FlutterGame(size: Size(100, 100), text: '100'),
),
const SizedBox(
width: 200,
height: 200,
child: FlutterGame(size: Size(200, 200), text: '200'),
),
],
),
),
),
);
}
}
class FlutterGame extends StatefulWidget {
const FlutterGame({super.key, required this.size, required this.text});
final Size size;
final String text;
@override
State<FlutterGame> createState() => _FlutterGameState();
}
class _FlutterGameState extends State<FlutterGame> {
static const url =
'https://raw.githubusercontent.com/mrdoob/three.js/refs/heads/master/examples/fonts/helvetiker_regular.typeface.json';
late ThreeJS threeJs;
@override
void initState() {
threeJs = ThreeJS(
onSetupComplete: () => setState(() {}),
setup: setup,
size: widget.size,
);
super.initState();
}
@override
void dispose() {
threeJs.dispose();
loading.clear();
super.dispose();
}
@override
Widget build(BuildContext context) {
return threeJs.build();
}
Future<void> setup() async {
final aspect = threeJs.width / threeJs.height;
threeJs.camera = PerspectiveCamera(45, aspect, 1, 200);
threeJs.camera.position.setValues(0, 0, 10);
threeJs.scene = Scene();
final pointLight = PointLight(0xffffff, 20);
pointLight.position.setValues(1, 1, 2);
threeJs.camera.add(pointLight);
threeJs.scene.add(threeJs.camera);
final geometry = TextGeometry(
widget.text,
TextGeometryOptions(font: await loadFont(), size: 5, depth: 2),
);
geometry.computeBoundingBox();
final material = MeshStandardMaterial()..color = Color(1, 0, 0);
final mesh = Mesh(geometry, material);
mesh.position.x =
-0.5 * (geometry.boundingBox!.max.x - geometry.boundingBox!.min.x);
mesh.position.y =
-0.5 * (geometry.boundingBox!.max.y - geometry.boundingBox!.min.y);
threeJs.scene.add(mesh);
}
Future<TTFFont> loadFont() async {
final loader = FontLoader();
final uri = Uri.parse(url);
final font = await loader.fromNetwork(uri);
loader.dispose();
return font!;
}
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels