test updates
This commit is contained in:
@@ -7,21 +7,21 @@ void main() async {
|
|||||||
final testHelper = TestHelper("assets");
|
final testHelper = TestHelper("assets");
|
||||||
await testHelper.setup();
|
await testHelper.setup();
|
||||||
group("assets", () {
|
group("assets", () {
|
||||||
// test('load/clear skybox', () async {
|
test('load/clear skybox', () async {
|
||||||
// await testHelper.withViewer((viewer) async {
|
await testHelper.withViewer((viewer) async {
|
||||||
// final camera = await viewer.getActiveCamera();
|
final camera = await viewer.getActiveCamera();
|
||||||
// print(await camera.getModelMatrix());
|
print(await camera.getModelMatrix());
|
||||||
// print(await camera.getViewMatrix());
|
print(await camera.getViewMatrix());
|
||||||
// print(await camera.getProjectionMatrix());
|
print(await camera.getProjectionMatrix());
|
||||||
// await camera.lookAt(Vector3(0, 0, 10),
|
await camera.lookAt(Vector3(0, 0, 10),
|
||||||
// focus: Vector3.zero(), up: Vector3(0, 1, 0));
|
focus: Vector3.zero(), up: Vector3(0, 1, 0));
|
||||||
// await viewer.loadSkybox(
|
await viewer.loadSkybox(
|
||||||
// "file://${testHelper.testDir}/assets/default_env_skybox.ktx");
|
"file://${testHelper.testDir}/assets/default_env_skybox.ktx");
|
||||||
// await testHelper.capture(viewer.view, "load_skybox");
|
await testHelper.capture(viewer.view, "load_skybox");
|
||||||
// await viewer.removeSkybox();
|
await viewer.removeSkybox();
|
||||||
// await testHelper.capture(viewer.view, "remove_skybox");
|
await testHelper.capture(viewer.view, "remove_skybox");
|
||||||
// });
|
});
|
||||||
// });
|
});
|
||||||
|
|
||||||
test('load/remove ibl', () async {
|
test('load/remove ibl', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
await testHelper.withViewer((viewer) async {
|
||||||
@@ -35,39 +35,41 @@ void main() async {
|
|||||||
}, cameraPosition: Vector3(0, 0, 5));
|
}, cameraPosition: Vector3(0, 0, 5));
|
||||||
});
|
});
|
||||||
|
|
||||||
// test('add/remove asset from scene ', () async {
|
test('load/remove gltf', () async {
|
||||||
// await testHelper.withViewer((viewer) async {
|
await testHelper.withViewer((viewer) async {
|
||||||
// var asset = await viewer
|
var asset = await viewer
|
||||||
// .loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
.loadGlb("file://${testHelper.testDir}/assets/cube.gltf", relativeResourcePath: "${testHelper.testDir}/assets");
|
||||||
// await viewer
|
await viewer
|
||||||
// .loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
.loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
||||||
// await testHelper.capture(viewer.view, "asset_added");
|
await testHelper.capture(viewer.view, "gltf_loaded");
|
||||||
// await viewer.removeFromScene(asset);
|
await viewer.removeFromScene(asset);
|
||||||
// await testHelper.capture(viewer.view, "asset_removed");
|
await testHelper.capture(viewer.view, "gltf_removed");
|
||||||
// }, cameraPosition: Vector3(0, 0, 5));
|
}, cameraPosition: Vector3(0, 0, 5));
|
||||||
// });
|
});
|
||||||
|
|
||||||
// test('destroy assets', () async {
|
test('add/remove asset from scene ', () async {
|
||||||
// await testHelper.withViewer((viewer) async {
|
await testHelper.withViewer((viewer) async {
|
||||||
// var asset = await viewer
|
var asset = await viewer
|
||||||
// .loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
||||||
// await viewer
|
await viewer
|
||||||
// .loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
.loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
||||||
// await testHelper.capture(viewer.view, "assets_present");
|
await testHelper.capture(viewer.view, "asset_added");
|
||||||
// await viewer.destroyAssets();
|
await viewer.removeFromScene(asset);
|
||||||
// await testHelper.capture(viewer.view, "assets_destroyed");
|
await testHelper.capture(viewer.view, "asset_removed");
|
||||||
// }, cameraPosition: Vector3(0, 0, 5));
|
}, cameraPosition: Vector3(0, 0, 5));
|
||||||
// });
|
});
|
||||||
|
|
||||||
|
test('destroy assets', () async {
|
||||||
|
await testHelper.withViewer((viewer) async {
|
||||||
|
var asset = await viewer
|
||||||
|
.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
||||||
|
await viewer
|
||||||
|
.loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
||||||
|
await testHelper.capture(viewer.view, "assets_present");
|
||||||
|
await viewer.destroyAssets();
|
||||||
|
await testHelper.capture(viewer.view, "assets_destroyed");
|
||||||
|
}, cameraPosition: Vector3(0, 0, 5));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// await viewer.destroyLights();
|
|
||||||
// await viewer.removeSkybox();
|
|
||||||
// await viewer.removeIbl();
|
|
||||||
|
|
||||||
// asset = await viewer
|
|
||||||
// .loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
|
||||||
// await testHelper.capture(viewer.view, "asset_reloaded");
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
thermion_dart/test/assets/cube.bin
Normal file
BIN
thermion_dart/test/assets/cube.bin
Normal file
Binary file not shown.
121
thermion_dart/test/assets/cube.gltf
Normal file
121
thermion_dart/test/assets/cube.gltf
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
{
|
||||||
|
"asset":{
|
||||||
|
"generator":"Khronos glTF Blender I/O v4.2.60",
|
||||||
|
"version":"2.0"
|
||||||
|
},
|
||||||
|
"scene":0,
|
||||||
|
"scenes":[
|
||||||
|
{
|
||||||
|
"name":"Scene",
|
||||||
|
"nodes":[
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes":[
|
||||||
|
{
|
||||||
|
"mesh":0,
|
||||||
|
"name":"Cube"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"materials":[
|
||||||
|
{
|
||||||
|
"doubleSided":true,
|
||||||
|
"name":"Material",
|
||||||
|
"pbrMetallicRoughness":{
|
||||||
|
"baseColorFactor":[
|
||||||
|
0.800000011920929,
|
||||||
|
0.800000011920929,
|
||||||
|
0.800000011920929,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"metallicFactor":0,
|
||||||
|
"roughnessFactor":0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meshes":[
|
||||||
|
{
|
||||||
|
"name":"Cube",
|
||||||
|
"primitives":[
|
||||||
|
{
|
||||||
|
"attributes":{
|
||||||
|
"POSITION":0,
|
||||||
|
"NORMAL":1,
|
||||||
|
"TEXCOORD_0":2
|
||||||
|
},
|
||||||
|
"indices":3,
|
||||||
|
"material":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"accessors":[
|
||||||
|
{
|
||||||
|
"bufferView":0,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":24,
|
||||||
|
"max":[
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"min":[
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1
|
||||||
|
],
|
||||||
|
"type":"VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":1,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":24,
|
||||||
|
"type":"VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":2,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":24,
|
||||||
|
"type":"VEC2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":3,
|
||||||
|
"componentType":5123,
|
||||||
|
"count":36,
|
||||||
|
"type":"SCALAR"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bufferViews":[
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":288,
|
||||||
|
"byteOffset":0,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":288,
|
||||||
|
"byteOffset":288,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":192,
|
||||||
|
"byteOffset":576,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":72,
|
||||||
|
"byteOffset":768,
|
||||||
|
"target":34963
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buffers":[
|
||||||
|
{
|
||||||
|
"byteLength":840,
|
||||||
|
"uri":"cube.bin"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
24
thermion_dart/test/background_tests.dart
Normal file
24
thermion_dart/test/background_tests.dart
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'helpers.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
final testHelper = TestHelper("assets");
|
||||||
|
await testHelper.setup();
|
||||||
|
group("background", () {
|
||||||
|
test('set background color', () async {
|
||||||
|
await testHelper.withViewer((viewer) async {
|
||||||
|
await viewer.setBackgroundColor(0, 1, 0, 1);
|
||||||
|
await testHelper.capture(viewer.view, "background_green");
|
||||||
|
await viewer.setBackgroundColor(1, 0, 0, 1);
|
||||||
|
await testHelper.capture(viewer.view, "background_red");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('set background image', () async {
|
||||||
|
await testHelper.withViewer((viewer) async {
|
||||||
|
await viewer.setBackgroundImage("file://${testHelper.testDir}/assets/cube_texture2_512x512.png");
|
||||||
|
await testHelper.capture(viewer.view, "background_image");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,240 +1,235 @@
|
|||||||
// ignore_for_file: unused_local_variable
|
// ignore_for_file: unused_local_variable
|
||||||
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
|
||||||
import 'helpers.dart';
|
import 'helpers.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
final testHelper = TestHelper("integration");
|
final testHelper = TestHelper("camera");
|
||||||
|
await testHelper.setup();
|
||||||
group('camera', () {
|
group('camera', () {
|
||||||
test('model matrix', () async {
|
test('model matrix', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
await testHelper.withViewer((viewer) async {
|
||||||
var matrix = await viewer.getCameraModelMatrix();
|
final camera = await viewer.getActiveCamera();
|
||||||
expect(matrix.trace(), 4);
|
await camera.setModelMatrix(Matrix4.translation(Vector3.all(4.0)));
|
||||||
|
var matrix = await camera.getModelMatrix();
|
||||||
await viewer.setCameraPosition(2.0, 2.0, 2.0);
|
|
||||||
matrix = await viewer.getCameraModelMatrix();
|
await camera.lookAt(Vector3(2.0, 2.0, 2.0));
|
||||||
var position = matrix.getColumn(3).xyz;
|
matrix = await camera.getModelMatrix();
|
||||||
|
var position = await camera.getPosition();
|
||||||
expect(position.x, 2.0);
|
expect(position.x, 2.0);
|
||||||
expect(position.y, 2.0);
|
expect(position.y, 2.0);
|
||||||
expect(position.z, 2.0);
|
expect(position.z, 2.0);
|
||||||
|
|
||||||
position = await viewer.getCameraPosition();
|
|
||||||
expect(position.x, 2.0);
|
|
||||||
expect(position.y, 2.0);
|
|
||||||
expect(position.z, 2.0);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getCameraViewMatrix', () async {
|
// test('getCameraViewMatrix', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
await viewer.setCameraModelMatrix4(Matrix4.identity());
|
// await viewer.setCameraModelMatrix4(Matrix4.identity());
|
||||||
var modelMatrix = await viewer.getCameraModelMatrix();
|
// var modelMatrix = await camera.getModelMatrix();
|
||||||
var viewMatrix = await viewer.getCameraViewMatrix();
|
// var viewMatrix = await viewer.getCameraViewMatrix();
|
||||||
|
|
||||||
// The view matrix should be the inverse of the model matrix
|
// // The view matrix should be the inverse of the model matrix
|
||||||
var identity = modelMatrix * viewMatrix;
|
// var identity = modelMatrix * viewMatrix;
|
||||||
expect(identity.isIdentity(), isTrue);
|
// expect(identity.isIdentity(), isTrue);
|
||||||
var camera = await viewer.getMainCamera();
|
// var camera = await viewer.getMainCamera();
|
||||||
identity = modelMatrix * (await camera.getViewMatrix());
|
// identity = modelMatrix * (await camera.getViewMatrix());
|
||||||
expect(identity.isIdentity(), isTrue);
|
// expect(identity.isIdentity(), isTrue);
|
||||||
|
|
||||||
// Check that moving the camera affects the view matrix
|
// // Check that moving the camera affects the view matrix
|
||||||
await viewer.setCameraPosition(3.0, 4.0, 5.0);
|
// await viewer.setCameraPosition(3.0, 4.0, 5.0);
|
||||||
viewMatrix = await viewer.getCameraViewMatrix();
|
// viewMatrix = await viewer.getCameraViewMatrix();
|
||||||
var invertedView = viewMatrix.clone()..invert();
|
// var invertedView = viewMatrix.clone()..invert();
|
||||||
var position = invertedView.getColumn(3).xyz;
|
// var position = invertedView.getColumn(3).xyz;
|
||||||
expect(position.x, closeTo(3.0, 1e-6));
|
// expect(position.x, closeTo(3.0, 1e-6));
|
||||||
expect(position.y, closeTo(4.0, 1e-6));
|
// expect(position.y, closeTo(4.0, 1e-6));
|
||||||
expect(position.z, closeTo(5.0, 1e-6));
|
// expect(position.z, closeTo(5.0, 1e-6));
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('getCameraProjectionMatrix', () async {
|
// test('getCameraProjectionMatrix', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var projectionMatrix = await viewer.getCameraProjectionMatrix();
|
// var projectionMatrix = await viewer.getCameraProjectionMatrix();
|
||||||
print(projectionMatrix);
|
// print(projectionMatrix);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('getCameraCullingProjectionMatrix', () async {
|
// test('getCameraCullingProjectionMatrix', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
// ignore: dead_code
|
// // ignore: dead_code
|
||||||
var viewer = await testHelper.createViewer();
|
// var viewer = await testHelper.createViewer();
|
||||||
var matrix = await viewer.getCameraCullingProjectionMatrix();
|
// var matrix = await viewer.getCameraCullingProjectionMatrix();
|
||||||
print(matrix);
|
// print(matrix);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('getCameraFrustum', () async {
|
// test('getCameraFrustum', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var frustum = await viewer.getCameraFrustum();
|
// var frustum = await viewer.getCameraFrustum();
|
||||||
print(frustum.plane5.normal);
|
// print(frustum.plane5.normal);
|
||||||
print(frustum.plane5.constant);
|
// print(frustum.plane5.constant);
|
||||||
|
|
||||||
var camera = await viewer.getMainCamera();
|
// var camera = await viewer.getMainCamera();
|
||||||
|
|
||||||
await camera.setLensProjection(
|
// await camera.setLensProjection(
|
||||||
near: 10.0, far: 1000.0, aspect: 1.0, focalLength: 28.0);
|
// near: 10.0, far: 1000.0, aspect: 1.0, focalLength: 28.0);
|
||||||
frustum = await viewer.getCameraFrustum();
|
// frustum = await viewer.getCameraFrustum();
|
||||||
print(frustum.plane5.normal);
|
// print(frustum.plane5.normal);
|
||||||
print(frustum.plane5.constant);
|
// print(frustum.plane5.constant);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('set orthographic projection', () async {
|
// test('set orthographic projection', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var camera = await viewer.getMainCamera();
|
// var camera = await viewer.getMainCamera();
|
||||||
await viewer.createGeometry(GeometryHelper.cube());
|
// await viewer.createGeometry(GeometryHelper.cube());
|
||||||
|
|
||||||
await camera.setProjection(
|
// await camera.setProjection(
|
||||||
Projection.Orthographic, -0.05, 0.05, -0.05, 0.05, 0.05, 10000);
|
// Projection.Orthographic, -0.05, 0.05, -0.05, 0.05, 0.05, 10000);
|
||||||
await testHelper.capture(viewer, "camera_set_orthographic_projection");
|
// await testHelper.capture(viewer, "camera_set_orthographic_projection");
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('set perspective projection/culling matrix', () async {
|
// test('set perspective projection/culling matrix', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var camera = await viewer.getMainCamera();
|
// var camera = await viewer.getMainCamera();
|
||||||
final cube = await viewer.createGeometry(GeometryHelper.cube());
|
// final cube = await viewer.createGeometry(GeometryHelper.cube());
|
||||||
|
|
||||||
var fovY = pi / 2;
|
// var fovY = pi / 2;
|
||||||
await camera.setProjectionMatrixWithCulling(
|
// await camera.setProjectionMatrixWithCulling(
|
||||||
makePerspectiveMatrix(fovY, 1.0, 0.05, 10000), 0.05, 10000);
|
// makePerspectiveMatrix(fovY, 1.0, 0.05, 10000), 0.05, 10000);
|
||||||
|
|
||||||
await testHelper.capture(viewer,
|
// await testHelper.capture(viewer,
|
||||||
"camera_set_perspective_projection_culling_matrix_object_fov90");
|
// "camera_set_perspective_projection_culling_matrix_object_fov90");
|
||||||
|
|
||||||
// cube no longer visible when the far plane is moved closer to camera so cube is outside
|
// // cube no longer visible when the far plane is moved closer to camera so cube is outside
|
||||||
fovY = 2 * (pi / 3);
|
// fovY = 2 * (pi / 3);
|
||||||
await camera.setProjectionMatrixWithCulling(
|
// await camera.setProjectionMatrixWithCulling(
|
||||||
makePerspectiveMatrix(fovY, 1.0, 0.05, 10000), 0.05, 10000);
|
// makePerspectiveMatrix(fovY, 1.0, 0.05, 10000), 0.05, 10000);
|
||||||
|
|
||||||
await testHelper.capture(viewer,
|
// await testHelper.capture(viewer,
|
||||||
"camera_set_perspective_projection_culling_matrix_object_fov120");
|
// "camera_set_perspective_projection_culling_matrix_object_fov120");
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('set custom projection/culling matrix (orthographic)', () async {
|
// test('set custom projection/culling matrix (orthographic)', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var camera = await viewer.getMainCamera();
|
// var camera = await viewer.getMainCamera();
|
||||||
final cube = await viewer.createGeometry(GeometryHelper.cube());
|
// final cube = await viewer.createGeometry(GeometryHelper.cube());
|
||||||
|
|
||||||
// cube is visible when inside the frustum, cube is visible
|
// // cube is visible when inside the frustum, cube is visible
|
||||||
var projectionMatrix =
|
// var projectionMatrix =
|
||||||
makeOrthographicMatrix(-10.0, 10.0, -10.0, 10.0, 0.05, 10000);
|
// makeOrthographicMatrix(-10.0, 10.0, -10.0, 10.0, 0.05, 10000);
|
||||||
await camera.setProjectionMatrixWithCulling(
|
// await camera.setProjectionMatrixWithCulling(
|
||||||
projectionMatrix, 0.05, 10000);
|
// projectionMatrix, 0.05, 10000);
|
||||||
|
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer, "camera_projection_culling_matrix_object_in_frustum");
|
// viewer, "camera_projection_culling_matrix_object_in_frustum");
|
||||||
|
|
||||||
// cube no longer visible when the far plane is moved closer to camera so cube is outside
|
// // cube no longer visible when the far plane is moved closer to camera so cube is outside
|
||||||
projectionMatrix =
|
// projectionMatrix =
|
||||||
makeOrthographicMatrix(-10.0, 10.0, -10.0, 10.0, 0.05, 1);
|
// makeOrthographicMatrix(-10.0, 10.0, -10.0, 10.0, 0.05, 1);
|
||||||
await camera.setProjectionMatrixWithCulling(projectionMatrix, 0.05, 1);
|
// await camera.setProjectionMatrixWithCulling(projectionMatrix, 0.05, 1);
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer, "camera_projection_culling_matrix_object_outside_frustum");
|
// viewer, "camera_projection_culling_matrix_object_outside_frustum");
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('setting transform on camera updates model matrix (no parent)',
|
// test('setting transform on camera updates model matrix (no parent)',
|
||||||
() async {
|
// () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var cameraEntity = await viewer.getMainCameraEntity();
|
// var cameraEntity = await viewer.getMainCameraEntity();
|
||||||
var camera = await viewer.getMainCamera();
|
// var camera = await viewer.getMainCamera();
|
||||||
|
|
||||||
await viewer.setTransform(
|
// await viewer.setTransform(
|
||||||
cameraEntity, Matrix4.translation(Vector3.all(1)));
|
// cameraEntity, Matrix4.translation(Vector3.all(1)));
|
||||||
|
|
||||||
var modelMatrix = await viewer.getCameraModelMatrix();
|
// var modelMatrix = await camera.getModelMatrix();
|
||||||
expect(modelMatrix.getColumn(3).x, 1.0);
|
// expect(modelMatrix.getColumn(3).x, 1.0);
|
||||||
expect(modelMatrix.getColumn(3).y, 1.0);
|
// expect(modelMatrix.getColumn(3).y, 1.0);
|
||||||
expect(modelMatrix.getColumn(3).z, 1.0);
|
// expect(modelMatrix.getColumn(3).z, 1.0);
|
||||||
expect(modelMatrix.getColumn(3).w, 1.0);
|
// expect(modelMatrix.getColumn(3).w, 1.0);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('setting transform on camera updates model matrix (with parent)',
|
// test('setting transform on camera updates model matrix (with parent)',
|
||||||
() async {
|
// () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var cameraEntity = await viewer.getMainCameraEntity();
|
// var cameraEntity = await viewer.getMainCameraEntity();
|
||||||
var camera = await viewer.getMainCamera();
|
// var camera = await viewer.getMainCamera();
|
||||||
|
|
||||||
var parent = await viewer.createGeometry(GeometryHelper.cube());
|
// var parent = await viewer.createGeometry(GeometryHelper.cube());
|
||||||
|
|
||||||
await viewer.setParent(camera.getEntity(), parent.entity);
|
// await viewer.setParent(camera.getEntity(), parent.entity);
|
||||||
await viewer.setTransform(
|
// await viewer.setTransform(
|
||||||
cameraEntity, Matrix4.translation(Vector3(1, 0, 0)));
|
// cameraEntity, Matrix4.translation(Vector3(1, 0, 0)));
|
||||||
|
|
||||||
var modelMatrix = await viewer.getCameraModelMatrix();
|
// var modelMatrix = await camera.getModelMatrix();
|
||||||
expect(modelMatrix.getColumn(3).x, 1.0);
|
// expect(modelMatrix.getColumn(3).x, 1.0);
|
||||||
expect(modelMatrix.getColumn(3).y, 0.0);
|
// expect(modelMatrix.getColumn(3).y, 0.0);
|
||||||
expect(modelMatrix.getColumn(3).z, 0.0);
|
// expect(modelMatrix.getColumn(3).z, 0.0);
|
||||||
expect(modelMatrix.getColumn(3).w, 1.0);
|
// expect(modelMatrix.getColumn(3).w, 1.0);
|
||||||
|
|
||||||
await viewer.setTransform(
|
// await viewer.setTransform(
|
||||||
parent.entity, Matrix4.translation(Vector3(0, 1, 0)));
|
// parent.entity, Matrix4.translation(Vector3(0, 1, 0)));
|
||||||
modelMatrix = await viewer.getCameraModelMatrix();
|
// modelMatrix = await camera.getModelMatrix();
|
||||||
expect(modelMatrix.getColumn(3).x, 1.0);
|
// expect(modelMatrix.getColumn(3).x, 1.0);
|
||||||
expect(modelMatrix.getColumn(3).y, 1.0);
|
// expect(modelMatrix.getColumn(3).y, 1.0);
|
||||||
expect(modelMatrix.getColumn(3).z, 0.0);
|
// expect(modelMatrix.getColumn(3).z, 0.0);
|
||||||
expect(modelMatrix.getColumn(3).w, 1.0);
|
// expect(modelMatrix.getColumn(3).w, 1.0);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test(
|
// test(
|
||||||
'when a camera is the parent of another entity, setting the model matrix updates the parent transform ',
|
// 'when a camera is the parent of another entity, setting the model matrix updates the parent transform ',
|
||||||
() async {
|
// () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var camera = await viewer.createCamera();
|
// var camera = await viewer.createCamera();
|
||||||
|
|
||||||
var child = await viewer
|
// var child = await viewer
|
||||||
.createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
// .createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
||||||
await viewer.setParent(child.entity, camera.getEntity());
|
// await viewer.setParent(child.entity, camera.getEntity());
|
||||||
|
|
||||||
await testHelper.capture(viewer, "camera_as_parent1");
|
// await testHelper.capture(viewer, "camera_as_parent1");
|
||||||
|
|
||||||
await camera.setModelMatrix(Matrix4.translation(Vector3(1, 0, 0)));
|
// await camera.setModelMatrix(Matrix4.translation(Vector3(1, 0, 0)));
|
||||||
|
|
||||||
await testHelper.capture(viewer, "camera_as_parent2");
|
// await testHelper.capture(viewer, "camera_as_parent2");
|
||||||
}, bg: kRed, cameraPosition: Vector3(0, 0, 10));
|
// }, bg: kRed, cameraPosition: Vector3(0, 0, 10));
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('create camera', () async {
|
// test('create camera', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
await viewer.setCameraPosition(0, 0, 5);
|
// await viewer.setCameraPosition(0, 0, 5);
|
||||||
await viewer.setBackgroundColor(1.0, 0.0, 1.0, 1.0);
|
// await viewer.setBackgroundColor(1.0, 0.0, 1.0, 1.0);
|
||||||
await viewer
|
// await viewer
|
||||||
.createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
// .createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
||||||
await testHelper.capture(viewer, "create_camera_main_camera");
|
// await testHelper.capture(viewer, "create_camera_main_camera");
|
||||||
|
|
||||||
expect(viewer.getCameraCount(), 1);
|
// expect(viewer.getCameraCount(), 1);
|
||||||
var newCamera = await viewer.createCamera();
|
// var newCamera = await viewer.createCamera();
|
||||||
expect(viewer.getCameraCount(), 2);
|
// expect(viewer.getCameraCount(), 2);
|
||||||
await newCamera.setTransform(Matrix4.translation(Vector3(0, 0, 4)));
|
// await newCamera.setTransform(Matrix4.translation(Vector3(0, 0, 4)));
|
||||||
newCamera.setLensProjection();
|
// newCamera.setLensProjection();
|
||||||
await viewer.setActiveCamera(newCamera);
|
// await viewer.setActiveCamera(newCamera);
|
||||||
|
|
||||||
expect(await viewer.getActiveCamera(), newCamera);
|
// expect(await viewer.getActiveCamera(), newCamera);
|
||||||
|
|
||||||
await testHelper.capture(viewer, "create_camera_new_camera");
|
// await testHelper.capture(viewer, "create_camera_new_camera");
|
||||||
|
|
||||||
final mainCamera = await viewer.getMainCamera();
|
// final mainCamera = await viewer.getMainCamera();
|
||||||
await viewer.setActiveCamera(mainCamera);
|
// await viewer.setActiveCamera(mainCamera);
|
||||||
expect(await viewer.getActiveCamera(), mainCamera);
|
// expect(await viewer.getActiveCamera(), mainCamera);
|
||||||
await testHelper.capture(viewer, "create_camera_back_to_main");
|
// await testHelper.capture(viewer, "create_camera_back_to_main");
|
||||||
|
|
||||||
expect(viewer.getCameraCount(), 2);
|
// expect(viewer.getCameraCount(), 2);
|
||||||
expect(viewer.getCameraAt(0), await viewer.getMainCamera());
|
// expect(viewer.getCameraAt(0), await viewer.getMainCamera());
|
||||||
expect(viewer.getCameraAt(1), newCamera);
|
// expect(viewer.getCameraAt(1), newCamera);
|
||||||
await expectLater(
|
// await expectLater(
|
||||||
() => viewer.getCameraAt(2), throwsA(isA<Exception>()));
|
// () => viewer.getCameraAt(2), throwsA(isA<Exception>()));
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
// ignore_for_file: unused_local_variable
|
// ignore_for_file: unused_local_variable
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
|
|
||||||
import 'helpers.dart';
|
import 'helpers.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
final testHelper = TestHelper("geometry");
|
final testHelper = TestHelper("geometry");
|
||||||
|
await testHelper.setup();
|
||||||
group("custom geometry", () {
|
group("custom geometry", () {
|
||||||
|
test('create cube (uvs only)', () async {
|
||||||
|
var viewer = await testHelper.createViewer();
|
||||||
|
await viewer
|
||||||
|
.createGeometry(GeometryHelper.cube(normals: false, uvs: true));
|
||||||
|
await testHelper.capture(viewer, "geometry_cube_with_uvs");
|
||||||
|
});
|
||||||
test('create cube with normals & uvs', () async {
|
test('create cube with normals & uvs', () async {
|
||||||
var viewer = await testHelper.createViewer();
|
var viewer = await testHelper.createViewer();
|
||||||
await viewer
|
await viewer
|
||||||
@@ -185,15 +188,18 @@ void main() async {
|
|||||||
final cube = await viewer.createGeometry(
|
final cube = await viewer.createGeometry(
|
||||||
GeometryHelper.cube(uvs: true, normals: true),
|
GeometryHelper.cube(uvs: true, normals: true),
|
||||||
materialInstances: [materialInstance]);
|
materialInstances: [materialInstance]);
|
||||||
var textureData =
|
final image = await viewer.decodeImage(
|
||||||
File("${testHelper.testDir}/assets/cube_texture_512x512.png")
|
File("${testHelper.testDir}/assets/cube_texture_512x512.png")
|
||||||
.readAsBytesSync();
|
.readAsBytesSync());
|
||||||
var texture = await viewer.createTexture(textureData);
|
var texture = await viewer.createTexture(
|
||||||
await viewer.applyTexture(texture as ThermionFFITexture, cube.entity);
|
await image.getWidth(), await image.getHeight());
|
||||||
|
await texture.setLinearImage(
|
||||||
|
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
|
||||||
await testHelper.capture(
|
await testHelper.capture(
|
||||||
viewer, "geometry_cube_with_custom_material_ubershader_texture");
|
viewer, "geometry_cube_with_custom_material_ubershader_texture");
|
||||||
await viewer.destroyAsset(cube);
|
await viewer.destroyAsset(cube);
|
||||||
await viewer.destroyTexture(texture);
|
await texture.dispose();
|
||||||
|
await image.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('unlit material with color only', () async {
|
test('unlit material with color only', () async {
|
||||||
@@ -216,11 +222,14 @@ void main() async {
|
|||||||
materialInstances: [materialInstance]);
|
materialInstances: [materialInstance]);
|
||||||
|
|
||||||
await materialInstance.setParameterInt("baseColorIndex", 0);
|
await materialInstance.setParameterInt("baseColorIndex", 0);
|
||||||
var textureData =
|
|
||||||
|
final image = await viewer.decodeImage(
|
||||||
File("${testHelper.testDir}/assets/cube_texture_512x512.png")
|
File("${testHelper.testDir}/assets/cube_texture_512x512.png")
|
||||||
.readAsBytesSync();
|
.readAsBytesSync());
|
||||||
var texture = await viewer.createTexture(textureData);
|
var texture = await viewer.createTexture(
|
||||||
await viewer.applyTexture(texture, cube.entity);
|
await image.getWidth(), await image.getHeight());
|
||||||
|
await texture.setLinearImage(
|
||||||
|
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
|
||||||
await testHelper.capture(viewer, "unlit_material_texture_only");
|
await testHelper.capture(viewer, "unlit_material_texture_only");
|
||||||
await viewer.destroyAsset(cube);
|
await viewer.destroyAsset(cube);
|
||||||
});
|
});
|
||||||
@@ -237,24 +246,26 @@ void main() async {
|
|||||||
cube2.entity, Matrix4.translation(Vector3(1, 1, 1)));
|
cube2.entity, Matrix4.translation(Vector3(1, 1, 1)));
|
||||||
|
|
||||||
await materialInstance.setParameterInt("baseColorIndex", 0);
|
await materialInstance.setParameterInt("baseColorIndex", 0);
|
||||||
var textureData =
|
final image = await viewer.decodeImage(
|
||||||
File("${testHelper.testDir}/assets/cube_texture_512x512.png")
|
File("${testHelper.testDir}/assets/cube_texture_512x512.png")
|
||||||
.readAsBytesSync();
|
.readAsBytesSync());
|
||||||
var texture = await viewer.createTexture(textureData);
|
var texture = await viewer.createTexture(
|
||||||
await viewer.applyTexture(texture, cube1.entity);
|
await image.getWidth(), await image.getHeight());
|
||||||
await viewer.applyTexture(texture, cube2.entity);
|
await texture.setLinearImage(
|
||||||
|
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
|
||||||
|
|
||||||
await testHelper.capture(viewer, "unlit_material_shared");
|
await testHelper.capture(viewer, "unlit_material_shared");
|
||||||
await viewer.destroyTexture(texture);
|
await texture.dispose();
|
||||||
|
await image.destroy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('create sphere (no normals)', () async {
|
test('create sphere (no normals)', () async {
|
||||||
var viewer = await testHelper.createViewer();
|
await testHelper.withViewer((viewer) async {
|
||||||
await viewer.setBackgroundColor(0.0, 0.0, 1.0, 1.0);
|
await viewer
|
||||||
await viewer.setCameraPosition(0, 0, 6);
|
.createGeometry(GeometryHelper.sphere(normals: false, uvs: false));
|
||||||
await viewer
|
await testHelper.capture(viewer, "geometry_sphere_no_normals");
|
||||||
.createGeometry(GeometryHelper.sphere(normals: false, uvs: false));
|
}, bg: kBlue, cameraPosition: Vector3(0, 0, 6));
|
||||||
await testHelper.capture(viewer, "geometry_sphere_no_normals");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('create multiple (non-instanced) geometry', () async {
|
test('create multiple (non-instanced) geometry', () async {
|
||||||
|
|||||||
@@ -1,153 +1,153 @@
|
|||||||
// ignore_for_file: unused_local_variable
|
// // ignore_for_file: unused_local_variable
|
||||||
|
|
||||||
import 'dart:io';
|
// import 'dart:io';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
// import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:test/test.dart';
|
// import 'package:test/test.dart';
|
||||||
|
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
// import 'package:vector_math/vector_math_64.dart';
|
||||||
|
|
||||||
import 'helpers.dart';
|
// import 'helpers.dart';
|
||||||
|
|
||||||
void main() async {
|
// void main() async {
|
||||||
final testHelper = TestHelper("gltf");
|
// final testHelper = TestHelper("gltf");
|
||||||
group("gltf", () {
|
// group("gltf", () {
|
||||||
test('load glb from file', () async {
|
// test('load glb from file', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var model = await viewer
|
// var model = await viewer
|
||||||
.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
// .loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
||||||
await testHelper.capture(viewer, "load_glb_from_file");
|
// await testHelper.capture(viewer, "load_glb_from_file");
|
||||||
await viewer.destroyAsset(model);
|
// await viewer.destroyAsset(model);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('load glb from buffer', () async {
|
// test('load glb from buffer', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var buffer =
|
// var buffer =
|
||||||
File("${testHelper.testDir}/assets/cube.glb").readAsBytesSync();
|
// File("${testHelper.testDir}/assets/cube.glb").readAsBytesSync();
|
||||||
var model = await viewer.loadGlbFromBuffer(buffer);
|
// var model = await viewer.loadGlbFromBuffer(buffer);
|
||||||
await testHelper.capture(viewer, "load_glb_from_buffer");
|
// await testHelper.capture(viewer, "load_glb_from_buffer");
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('load glb from buffer with instances', () async {
|
// test('load glb from buffer with instances', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var buffer =
|
// var buffer =
|
||||||
File("${testHelper.testDir}/assets/cube.glb").readAsBytesSync();
|
// File("${testHelper.testDir}/assets/cube.glb").readAsBytesSync();
|
||||||
var model = await viewer.loadGlbFromBuffer(buffer, numInstances: 2);
|
// var model = await viewer.loadGlbFromBuffer(buffer, numInstances: 2);
|
||||||
var instance = await model.createInstance();
|
// var instance = await model.createInstance();
|
||||||
await instance.addToScene();
|
// await instance.addToScene();
|
||||||
await viewer.setTransform(
|
// await viewer.setTransform(
|
||||||
instance.entity, Matrix4.translation(Vector3(1, 0, 0)));
|
// instance.entity, Matrix4.translation(Vector3(1, 0, 0)));
|
||||||
|
|
||||||
await testHelper.capture(viewer, "load_glb_from_buffer_with_instances");
|
// await testHelper.capture(viewer, "load_glb_from_buffer_with_instances");
|
||||||
|
|
||||||
await viewer.destroyAsset(instance);
|
// await viewer.destroyAsset(instance);
|
||||||
|
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer, "load_glb_from_buffer_instance_removed");
|
// viewer, "load_glb_from_buffer_instance_removed");
|
||||||
|
|
||||||
await viewer.destroyAsset(model);
|
// await viewer.destroyAsset(model);
|
||||||
|
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer, "load_glb_from_buffer_original_removed");
|
// viewer, "load_glb_from_buffer_original_removed");
|
||||||
}, bg: kRed);
|
// }, bg: kRed);
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('load glb from buffer with priority', () async {
|
// test('load glb from buffer with priority', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
viewer.addDirectLight(DirectLight.sun());
|
// viewer.addDirectLight(DirectLight.sun());
|
||||||
var buffer =
|
// var buffer =
|
||||||
File("${testHelper.testDir}/assets/cube.glb").readAsBytesSync();
|
// File("${testHelper.testDir}/assets/cube.glb").readAsBytesSync();
|
||||||
|
|
||||||
// priority 0 gets drawn first
|
// // priority 0 gets drawn first
|
||||||
var greenModel = await viewer.loadGlbFromBuffer(buffer, priority: 0);
|
// var greenModel = await viewer.loadGlbFromBuffer(buffer, priority: 0);
|
||||||
for (final entity in await viewer.getChildEntities(greenModel)) {
|
// for (final entity in await viewer.getChildEntities(greenModel)) {
|
||||||
final material = await viewer.getMaterialInstanceAt(entity, 0);
|
// final material = await viewer.getMaterialInstanceAt(entity, 0);
|
||||||
await material!.setParameterFloat4("baseColorFactor", 0, 1, 0.0, 1.0);
|
// await material!.setParameterFloat4("baseColorFactor", 0, 1, 0.0, 1.0);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// priority 7 gets drawn last
|
// // priority 7 gets drawn last
|
||||||
var blueModel = await viewer.loadGlbFromBuffer(buffer, priority: 7);
|
// var blueModel = await viewer.loadGlbFromBuffer(buffer, priority: 7);
|
||||||
for (final entity in await viewer.getChildEntities(blueModel)) {
|
// for (final entity in await viewer.getChildEntities(blueModel)) {
|
||||||
final material = await viewer.getMaterialInstanceAt(entity, 0);
|
// final material = await viewer.getMaterialInstanceAt(entity, 0);
|
||||||
await material!.setParameterFloat4("baseColorFactor", 0, 0, 1.0, 1.0);
|
// await material!.setParameterFloat4("baseColorFactor", 0, 0, 1.0, 1.0);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// blue model rendered in front
|
// // blue model rendered in front
|
||||||
await testHelper.capture(viewer, "load_glb_from_buffer_with_priority");
|
// await testHelper.capture(viewer, "load_glb_from_buffer_with_priority");
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('create instance from gltf', () async {
|
// test('create instance from gltf', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var model = await viewer.loadGlb(
|
// var model = await viewer.loadGlb(
|
||||||
"file://${testHelper.testDir}/assets/cube.glb",
|
// "file://${testHelper.testDir}/assets/cube.glb",
|
||||||
numInstances: 32);
|
// numInstances: 32);
|
||||||
await testHelper.capture(viewer, "gltf_create_instance_0");
|
// await testHelper.capture(viewer, "gltf_create_instance_0");
|
||||||
var instance = await model.createInstance();
|
// var instance = await model.createInstance();
|
||||||
await instance.addToScene();
|
// await instance.addToScene();
|
||||||
await viewer.setRendering(true);
|
// await viewer.setRendering(true);
|
||||||
|
|
||||||
await viewer.setTransform(
|
// await viewer.setTransform(
|
||||||
instance.entity, Matrix4.translation(Vector3.all(1)));
|
// instance.entity, Matrix4.translation(Vector3.all(1)));
|
||||||
await testHelper.capture(viewer, "gltf_create_instance_1");
|
// await testHelper.capture(viewer, "gltf_create_instance_1");
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('create instance from gltf with new material', () async {
|
// test('create instance from gltf with new material', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var model = await viewer.loadGlb(
|
// var model = await viewer.loadGlb(
|
||||||
"file://${testHelper.testDir}/assets/cube.glb",
|
// "file://${testHelper.testDir}/assets/cube.glb",
|
||||||
numInstances: 2);
|
// numInstances: 2);
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer, "gltf_create_instance_with_material_0");
|
// viewer, "gltf_create_instance_with_material_0");
|
||||||
|
|
||||||
final materialInstance = await viewer.createUnlitMaterialInstance();
|
// final materialInstance = await viewer.createUnlitMaterialInstance();
|
||||||
await materialInstance.setParameterFloat4(
|
// await materialInstance.setParameterFloat4(
|
||||||
"baseColorFactor", 1.0, 0.0, 0.0, 1.0);
|
// "baseColorFactor", 1.0, 0.0, 0.0, 1.0);
|
||||||
var instance =
|
// var instance =
|
||||||
await model.createInstance(materialInstances: [materialInstance]);
|
// await model.createInstance(materialInstances: [materialInstance]);
|
||||||
await instance.addToScene();
|
// await instance.addToScene();
|
||||||
|
|
||||||
await viewer.setTransform(
|
// await viewer.setTransform(
|
||||||
instance.entity, Matrix4.translation(Vector3.all(1)));
|
// instance.entity, Matrix4.translation(Vector3.all(1)));
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer, "gltf_create_instance_with_material_1");
|
// viewer, "gltf_create_instance_with_material_1");
|
||||||
await viewer.destroyMaterialInstance(materialInstance);
|
// await viewer.destroyMaterialInstance(materialInstance);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('replace material instance with unlit material', () async {
|
// test('replace material instance with unlit material', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var model = await viewer
|
// var model = await viewer
|
||||||
.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
// .loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
||||||
await testHelper.capture(viewer, "gltf_default_material_instance");
|
// await testHelper.capture(viewer, "gltf_default_material_instance");
|
||||||
var materialInstance = await viewer.createUnlitMaterialInstance();
|
// var materialInstance = await viewer.createUnlitMaterialInstance();
|
||||||
await materialInstance.setParameterFloat4(
|
// await materialInstance.setParameterFloat4(
|
||||||
"baseColorFactor", 1.0, 1.0, 0.0, 1.0);
|
// "baseColorFactor", 1.0, 1.0, 0.0, 1.0);
|
||||||
await model.setMaterialInstanceAt(materialInstance);
|
// await model.setMaterialInstanceAt(materialInstance);
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer, "gltf_replace_material_instance_unlit");
|
// viewer, "gltf_replace_material_instance_unlit");
|
||||||
await viewer.destroyAsset(model);
|
// await viewer.destroyAsset(model);
|
||||||
await viewer.destroyMaterialInstance(materialInstance);
|
// await viewer.destroyMaterialInstance(materialInstance);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('replace material instance with ubershader material', () async {
|
// test('replace material instance with ubershader material', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var model = await viewer
|
// var model = await viewer
|
||||||
.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
// .loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
||||||
await viewer
|
// await viewer
|
||||||
.loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
// .loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
||||||
var materialInstance = await viewer.createUbershaderMaterialInstance();
|
// var materialInstance = await viewer.createUbershaderMaterialInstance();
|
||||||
await materialInstance.setParameterFloat4(
|
// await materialInstance.setParameterFloat4(
|
||||||
"baseColorFactor", 1.0, 1.0, 0.0, 1.0);
|
// "baseColorFactor", 1.0, 1.0, 0.0, 1.0);
|
||||||
await model.setMaterialInstanceAt(materialInstance);
|
// await model.setMaterialInstanceAt(materialInstance);
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer, "gltf_replace_material_instance_ubershader");
|
// viewer, "gltf_replace_material_instance_ubershader");
|
||||||
await viewer.destroyAsset(model);
|
// await viewer.destroyAsset(model);
|
||||||
await viewer.destroyMaterialInstance(materialInstance);
|
// await viewer.destroyMaterialInstance(materialInstance);
|
||||||
}, bg: kRed);
|
// }, bg: kRed);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
// ignore_for_file: unused_local_variable
|
// ignore_for_file: unused_local_variable
|
||||||
|
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:image/image.dart' as img;
|
import 'package:image/image.dart' as img;
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:image/image.dart';
|
import 'package:image/image.dart';
|
||||||
import 'swift/swift_bindings.g.dart';
|
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||||
|
import 'package:thermion_dart/src/swift/swift_bindings.g.dart';
|
||||||
import 'package:thermion_dart/src/utils/src/dart_resources.dart';
|
import 'package:thermion_dart/src/utils/src/dart_resources.dart';
|
||||||
|
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||||
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||||
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
||||||
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/thermion_viewer_ffi.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/thermion_viewer_ffi.dart';
|
||||||
@@ -32,7 +34,7 @@ Color kBlue = ColorFloat32(4)..setRgba(0.0, 0.0, 1.0, 1.0);
|
|||||||
Uri findPackageRoot(String packageName) {
|
Uri findPackageRoot(String packageName) {
|
||||||
final script = Platform.script;
|
final script = Platform.script;
|
||||||
final fileName = script.name;
|
final fileName = script.name;
|
||||||
if (fileName.endsWith('_test.dart')) {
|
if (fileName.contains('_test')) {
|
||||||
// We're likely running from source.
|
// We're likely running from source.
|
||||||
var directory = script.resolve('.');
|
var directory = script.resolve('.');
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -69,73 +71,88 @@ Future<Uint8List> savePixelBufferToBmp(
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Uint8List> savePixelBufferToPng(
|
||||||
|
Uint8List pixelBuffer, int width, int height, String outputPath) async {
|
||||||
|
var data = await pixelBufferToPng(pixelBuffer, width, height);
|
||||||
|
File(outputPath).writeAsBytesSync(data);
|
||||||
|
print("Wrote bitmap to ${outputPath}");
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
class TestHelper {
|
class TestHelper {
|
||||||
late SwapChain swapChain;
|
late FFISwapChain swapChain;
|
||||||
late Directory outDir;
|
late Directory outDir;
|
||||||
late String testDir;
|
late String testDir;
|
||||||
|
|
||||||
TestHelper(String dir) {
|
TestHelper(String dir) {
|
||||||
final packageUri = findPackageRoot('thermion_dart');
|
final packageUri = findPackageRoot('thermion_dart').toFilePath();
|
||||||
print("Package URIL $packageUri");
|
testDir = Directory("${packageUri}test").path;
|
||||||
testDir = Directory("${packageUri.toFilePath()}/test").path;
|
|
||||||
print("Test dir : $packageUri");
|
|
||||||
|
|
||||||
outDir = Directory("$testDir/output/${dir}");
|
outDir = Directory("$testDir/output/${dir}");
|
||||||
print("Out dir : $packageUri");
|
|
||||||
outDir.createSync(recursive: true);
|
outDir.createSync(recursive: true);
|
||||||
print("Created out dir : $packageUri");
|
|
||||||
if (Platform.isMacOS) {
|
if (Platform.isMacOS) {
|
||||||
DynamicLibrary.open('${testDir}/libThermionTextureSwift.dylib');
|
DynamicLibrary.open('${testDir}/libThermionTextureSwift.dylib');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future capture(ThermionViewer viewer, String outputFilename,
|
///
|
||||||
{View? view, SwapChain? swapChain, RenderTarget? renderTarget}) async {
|
///
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
///
|
||||||
var outPath = p.join(outDir.path, "$outputFilename.bmp");
|
Future<Uint8List> capture(View view, String? outputFilename) async {
|
||||||
|
final rt = await view.getRenderTarget();
|
||||||
var pixelBuffer = await viewer.capture(
|
var pixelBuffer = await FilamentApp.instance!
|
||||||
view: view,
|
.capture(view, captureRenderTarget: rt != null);
|
||||||
swapChain: swapChain ?? this.swapChain,
|
|
||||||
renderTarget: renderTarget);
|
|
||||||
await viewer.render();
|
|
||||||
|
|
||||||
view ??= await viewer.getViewAt(0);
|
|
||||||
var vp = await view.getViewport();
|
var vp = await view.getViewport();
|
||||||
await savePixelBufferToBmp(pixelBuffer, vp.width, vp.height, outPath);
|
|
||||||
|
if (outputFilename != null) {
|
||||||
|
var outPath = p.join(outDir.path, "$outputFilename.png");
|
||||||
|
await savePixelBufferToPng(pixelBuffer, vp.width, vp.height, outPath);
|
||||||
|
}
|
||||||
|
|
||||||
return pixelBuffer;
|
return pixelBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ThermionTextureSwift> createTexture(int width, int height) async {
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future<List<Uint8List>> captureMultiple(
|
||||||
|
ThermionViewer viewer,
|
||||||
|
String? outputFilename, {
|
||||||
|
View? view,
|
||||||
|
SwapChain? swapChain,
|
||||||
|
RenderTarget? renderTarget,
|
||||||
|
}) async {
|
||||||
|
throw UnimplementedError();
|
||||||
|
|
||||||
|
// view ??= await viewer.view;
|
||||||
|
// final targets = [
|
||||||
|
// (view: view!, swapChain: swapChain, renderTarget: renderTarget)
|
||||||
|
// ];
|
||||||
|
// var pixelBuffers = await viewer.capture(targets);
|
||||||
|
|
||||||
|
// for (final entry in targets) {
|
||||||
|
// var vp = await entry.view.getViewport();
|
||||||
|
// if (outputFilename != null) {
|
||||||
|
// var outPath = p.join(outDir.path, "$outputFilename.png");
|
||||||
|
// await savePixelBufferToPng(
|
||||||
|
// pixelBuffers[targets.indexOf(entry)], vp.width, vp.height, outPath);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return pixelBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future<ThermionTextureSwift> createTexture(int width, int height,
|
||||||
|
{bool depth = false}) async {
|
||||||
final object = ThermionTextureSwift.new1();
|
final object = ThermionTextureSwift.new1();
|
||||||
object.initWithWidth_height_(width, height);
|
object.initWithWidth_height_isDepth_(width, height, depth);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future withViewer(Future Function(ThermionViewer viewer) fn,
|
Future setup() async {
|
||||||
{img.Color? bg,
|
|
||||||
Vector3? cameraPosition,
|
|
||||||
viewportDimensions = (width: 500, height: 500),
|
|
||||||
bool postProcessing = false}) async {
|
|
||||||
var viewer = await createViewer(
|
|
||||||
bg: bg,
|
|
||||||
cameraPosition: cameraPosition,
|
|
||||||
viewportDimensions: viewportDimensions,
|
|
||||||
postProcessing: postProcessing);
|
|
||||||
|
|
||||||
await fn.call(viewer);
|
|
||||||
await viewer.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ThermionViewer> createViewer(
|
|
||||||
{img.Color? bg,
|
|
||||||
Vector3? cameraPosition,
|
|
||||||
bool postProcessing = false,
|
|
||||||
viewportDimensions = (width: 500, height: 500)}) async {
|
|
||||||
final resourceLoader = calloc<ResourceLoaderWrapper>(1);
|
final resourceLoader = calloc<ResourceLoaderWrapper>(1);
|
||||||
|
|
||||||
cameraPosition ??= Vector3(0, 2, 6);
|
|
||||||
|
|
||||||
var loadToOut = NativeCallable<
|
var loadToOut = NativeCallable<
|
||||||
Void Function(Pointer<Char>,
|
Void Function(Pointer<Char>,
|
||||||
Pointer<ResourceBuffer>)>.listener(DartResourceLoader.loadResource);
|
Pointer<ResourceBuffer>)>.listener(DartResourceLoader.loadResource);
|
||||||
@@ -146,96 +163,88 @@ class TestHelper {
|
|||||||
DartResourceLoader.freeResource);
|
DartResourceLoader.freeResource);
|
||||||
|
|
||||||
resourceLoader.ref.freeResource = freeResource.nativeFunction;
|
resourceLoader.ref.freeResource = freeResource.nativeFunction;
|
||||||
|
await FFIFilamentApp.create();
|
||||||
|
|
||||||
var viewer = ThermionViewerFFI(resourceLoader: resourceLoader.cast<Void>());
|
await FilamentApp.instance!.setClearColor(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future withViewer(Future Function(ThermionViewer viewer) fn,
|
||||||
|
{img.Color? bg,
|
||||||
|
Vector3? cameraPosition,
|
||||||
|
({int width, int height}) viewportDimensions = (width: 500, height: 500),
|
||||||
|
bool postProcessing = false,
|
||||||
|
bool createRenderTarget = false}) async {
|
||||||
|
cameraPosition ??= Vector3(0, 2, 6);
|
||||||
|
|
||||||
|
var swapChain = await FilamentApp.instance!.createHeadlessSwapChain(
|
||||||
|
viewportDimensions.width, viewportDimensions.height) as FFISwapChain;
|
||||||
|
|
||||||
|
FFIRenderTarget? renderTarget;
|
||||||
|
if (createRenderTarget) {
|
||||||
|
var metalColorTexture = await createTexture(
|
||||||
|
viewportDimensions.width, viewportDimensions.height);
|
||||||
|
var metalDepthTexture = await createTexture(
|
||||||
|
viewportDimensions.width, viewportDimensions.height,
|
||||||
|
depth: true);
|
||||||
|
var color = await FilamentApp.instance!
|
||||||
|
.createTexture(viewportDimensions.width, viewportDimensions.height,
|
||||||
|
flags: {
|
||||||
|
TextureUsage.TEXTURE_USAGE_BLIT_SRC,
|
||||||
|
TextureUsage.TEXTURE_USAGE_COLOR_ATTACHMENT,
|
||||||
|
TextureUsage.TEXTURE_USAGE_SAMPLEABLE
|
||||||
|
},
|
||||||
|
textureFormat: TextureFormat.RGB32F,
|
||||||
|
importedTextureHandle: metalColorTexture.metalTextureAddress);
|
||||||
|
|
||||||
|
var depth = await FilamentApp.instance!
|
||||||
|
.createTexture(viewportDimensions.width, viewportDimensions.height,
|
||||||
|
flags: {
|
||||||
|
TextureUsage.TEXTURE_USAGE_BLIT_SRC,
|
||||||
|
TextureUsage.TEXTURE_USAGE_DEPTH_ATTACHMENT,
|
||||||
|
TextureUsage.TEXTURE_USAGE_SAMPLEABLE,
|
||||||
|
},
|
||||||
|
textureFormat: TextureFormat.DEPTH32F,
|
||||||
|
importedTextureHandle: metalDepthTexture.metalTextureAddress);
|
||||||
|
|
||||||
|
renderTarget = await FilamentApp.instance!.createRenderTarget(
|
||||||
|
viewportDimensions.width, viewportDimensions.height,
|
||||||
|
color: color, depth: depth) as FFIRenderTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewer = ThermionViewerFFI(
|
||||||
|
loadAssetFromUri: (path) async =>
|
||||||
|
File(path.replaceAll("file://", "")).readAsBytesSync(),
|
||||||
|
renderTarget: renderTarget);
|
||||||
|
|
||||||
await viewer.initialized;
|
await viewer.initialized;
|
||||||
swapChain = await viewer.createHeadlessSwapChain(
|
await FilamentApp.instance!.register(swapChain, viewer.view);
|
||||||
viewportDimensions.width, viewportDimensions.height);
|
|
||||||
|
|
||||||
await viewer.updateViewportAndCameraProjection(
|
await viewer.view
|
||||||
viewportDimensions.width.toDouble(),
|
.setViewport(viewportDimensions.width, viewportDimensions.height);
|
||||||
viewportDimensions.height.toDouble());
|
|
||||||
|
await viewer.view.setBloom(false, 0);
|
||||||
|
|
||||||
if (bg != null) {
|
if (bg != null) {
|
||||||
await viewer.setBackgroundColor(
|
await viewer.setBackgroundColor(
|
||||||
bg.r.toDouble(), bg.g.toDouble(), bg.b.toDouble(), bg.a.toDouble());
|
bg.r.toDouble(), bg.g.toDouble(), bg.b.toDouble(), bg.a.toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
await viewer.setCameraPosition(
|
final camera = await viewer.getActiveCamera();
|
||||||
cameraPosition.x, cameraPosition.y, cameraPosition.z);
|
|
||||||
|
await camera.setLensProjection(
|
||||||
|
near: kNear, far: kFar, aspect: 1.0, focalLength: kFocalLength);
|
||||||
|
|
||||||
|
await camera.lookAt(cameraPosition);
|
||||||
|
|
||||||
await viewer.setPostProcessing(postProcessing);
|
await viewer.setPostProcessing(postProcessing);
|
||||||
|
|
||||||
await viewer.setToneMapping(ToneMapper.LINEAR);
|
await viewer.setToneMapping(ToneMapper.LINEAR);
|
||||||
|
|
||||||
return viewer;
|
await fn.call(viewer);
|
||||||
}
|
await viewer.dispose();
|
||||||
}
|
|
||||||
|
|
||||||
Future<Uint8List> pixelsToPng(Uint8List pixelBuffer, int width, int height,
|
|
||||||
{bool linearToSrgb = false, bool invertAces = false}) async {
|
|
||||||
final image = img.Image(width: width, height: height);
|
|
||||||
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
for (int x = 0; x < width; x++) {
|
|
||||||
final int pixelIndex = (y * width + x) * 4;
|
|
||||||
double r = pixelBuffer[pixelIndex] / 255.0;
|
|
||||||
double g = pixelBuffer[pixelIndex + 1] / 255.0;
|
|
||||||
double b = pixelBuffer[pixelIndex + 2] / 255.0;
|
|
||||||
int a = pixelBuffer[pixelIndex + 3];
|
|
||||||
|
|
||||||
// Apply inverse ACES tone mapping
|
|
||||||
if (invertAces) {
|
|
||||||
r = _inverseACESToneMapping(r);
|
|
||||||
g = _inverseACESToneMapping(g);
|
|
||||||
b = _inverseACESToneMapping(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (linearToSrgb) {
|
|
||||||
// Convert from linear to sRGB
|
|
||||||
|
|
||||||
image.setPixel(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
img.ColorUint8(4)
|
|
||||||
..setRgba(
|
|
||||||
_linearToSRGB(r), _linearToSRGB(g), _linearToSRGB(b), 1.0));
|
|
||||||
} else {
|
|
||||||
image.setPixel(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
img.ColorUint8(4)
|
|
||||||
..setRgba((r * 255).toInt(), (g * 255).toInt(), (b * 255).toInt(),
|
|
||||||
1.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return img.encodePng(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
double _inverseACESToneMapping(double x) {
|
|
||||||
const double a = 2.51;
|
|
||||||
const double b = 0.03;
|
|
||||||
const double c = 2.43;
|
|
||||||
const double d = 0.59;
|
|
||||||
const double e = 0.14;
|
|
||||||
|
|
||||||
// Ensure x is in the valid range [0, 1]
|
|
||||||
x = x.clamp(0.0, 1.0);
|
|
||||||
|
|
||||||
// Inverse ACES filmic tone mapping function
|
|
||||||
return (x * (x * a + b)) / (x * (x * c + d) + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _linearToSRGB(double linearValue) {
|
|
||||||
if (linearValue <= 0.0031308) {
|
|
||||||
return (linearValue * 12.92 * 255.0).round().clamp(0, 255);
|
|
||||||
} else {
|
|
||||||
return ((1.055 * pow(linearValue, 1.0 / 2.4) - 0.055) * 255.0)
|
|
||||||
.round()
|
|
||||||
.clamp(0, 255);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import 'package:animation_tools_dart/animation_tools_dart.dart' as _i9;
|
|||||||
import 'package:mockito/mockito.dart' as _i1;
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:thermion_dart/src/utils/src/gizmo.dart' as _i4;
|
import 'package:thermion_dart/src/utils/src/gizmo.dart' as _i4;
|
||||||
import 'package:thermion_dart/src/viewer/src/events.dart' as _i7;
|
import 'package:thermion_dart/src/viewer/src/events.dart' as _i7;
|
||||||
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart'
|
import 'package:thermion_dart/src/filament/src/shared_types.dart'
|
||||||
as _i2;
|
as _i2;
|
||||||
import 'package:thermion_dart/src/viewer/src/thermion_viewer_base.dart' as _i5;
|
import 'package:thermion_dart/src/viewer/src/thermion_viewer_base.dart' as _i5;
|
||||||
import 'package:vector_math/vector_math_64.dart' as _i3;
|
import 'package:vector_math/vector_math_64.dart' as _i3;
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
|
|
||||||
import 'helpers.dart';
|
import 'helpers.dart';
|
||||||
|
|
||||||
Future<
|
Future<
|
||||||
@@ -43,8 +40,8 @@ Future<
|
|||||||
void main() async {
|
void main() async {
|
||||||
final testHelper = TestHelper("material");
|
final testHelper = TestHelper("material");
|
||||||
|
|
||||||
group("unlit material tests", () {
|
group("unlit material", () {
|
||||||
test('unlit material with color only', () async {
|
test('unlit + baseColorFactor', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
await testHelper.withViewer((viewer) async {
|
||||||
await viewer.setPostProcessing(true);
|
await viewer.setPostProcessing(true);
|
||||||
await viewer.setToneMapping(ToneMapper.LINEAR);
|
await viewer.setToneMapping(ToneMapper.LINEAR);
|
||||||
@@ -62,6 +59,116 @@ void main() async {
|
|||||||
}, bg: kRed);
|
}, bg: kRed);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('unlit + baseColorMap', () async {
|
||||||
|
await testHelper.withViewer((viewer) async {
|
||||||
|
var materialInstance = await viewer.createUnlitMaterialInstance();
|
||||||
|
var cube = await viewer.createGeometry(GeometryHelper.cube(),
|
||||||
|
materialInstances: [materialInstance]);
|
||||||
|
|
||||||
|
await materialInstance.setParameterFloat4(
|
||||||
|
"baseColorFactor", 1.0, 1.0, 1.0, 1.0);
|
||||||
|
await materialInstance.setParameterFloat2("uvScale", 1.0, 1.0);
|
||||||
|
await materialInstance.setParameterInt("baseColorIndex", 0);
|
||||||
|
|
||||||
|
var data =
|
||||||
|
File("${testHelper.testDir}/assets/cube_texture2_512x512.png")
|
||||||
|
.readAsBytesSync();
|
||||||
|
final image = await viewer.decodeImage(data);
|
||||||
|
|
||||||
|
final texture = await viewer.createTexture(
|
||||||
|
await image.getWidth(), await image.getHeight(),
|
||||||
|
textureFormat: TextureFormat.RGBA32F);
|
||||||
|
await texture.setLinearImage(
|
||||||
|
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
|
||||||
|
final sampler = await viewer.createTextureSampler();
|
||||||
|
|
||||||
|
await materialInstance.setParameterTexture(
|
||||||
|
"baseColorMap", texture, sampler);
|
||||||
|
|
||||||
|
await testHelper.capture(viewer, "unlit_baseColorMap");
|
||||||
|
|
||||||
|
await image.destroy();
|
||||||
|
await texture.dispose();
|
||||||
|
await sampler.dispose();
|
||||||
|
|
||||||
|
await viewer.destroyMaterialInstance(materialInstance);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('unlit + baseColorMap (apply material after creation)', () async {
|
||||||
|
await testHelper.withViewer((viewer) async {
|
||||||
|
var cube = await viewer
|
||||||
|
.createGeometry(GeometryHelper.cube(), materialInstances: []);
|
||||||
|
var materialInstance = await viewer.createUnlitMaterialInstance();
|
||||||
|
await materialInstance.setParameterFloat4(
|
||||||
|
"baseColorFactor", 1.0, 1.0, 1.0, 1.0);
|
||||||
|
await materialInstance.setParameterFloat2("uvScale", 1.0, 1.0);
|
||||||
|
await materialInstance.setParameterInt("baseColorIndex", 0);
|
||||||
|
|
||||||
|
var data =
|
||||||
|
File("${testHelper.testDir}/assets/cube_texture2_512x512.png")
|
||||||
|
.readAsBytesSync();
|
||||||
|
final image = await viewer.decodeImage(data);
|
||||||
|
|
||||||
|
final texture = await viewer.createTexture(
|
||||||
|
await image.getWidth(), await image.getHeight(),
|
||||||
|
textureFormat: TextureFormat.RGBA32F);
|
||||||
|
await texture.setLinearImage(
|
||||||
|
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
|
||||||
|
final sampler = await viewer.createTextureSampler();
|
||||||
|
|
||||||
|
await materialInstance.setParameterTexture(
|
||||||
|
"baseColorMap", texture, sampler);
|
||||||
|
await cube.setMaterialInstanceAt(materialInstance);
|
||||||
|
await testHelper.capture(
|
||||||
|
viewer, "unlit_baseColorMap_material_created_after");
|
||||||
|
|
||||||
|
await image.destroy();
|
||||||
|
await texture.dispose();
|
||||||
|
await sampler.dispose();
|
||||||
|
|
||||||
|
await viewer.destroyMaterialInstance(materialInstance);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('unlit + baseColorMap (fetch material after creation)', () async {
|
||||||
|
await testHelper.withViewer((viewer) async {
|
||||||
|
var materialInstance = await viewer.createUnlitMaterialInstance();
|
||||||
|
var cube = await viewer.createGeometry(GeometryHelper.cube(),
|
||||||
|
materialInstances: [materialInstance]);
|
||||||
|
|
||||||
|
materialInstance = await viewer.getMaterialInstanceAt(cube.entity, 0);
|
||||||
|
|
||||||
|
await materialInstance.setParameterFloat4(
|
||||||
|
"baseColorFactor", 1.0, 1.0, 1.0, 1.0);
|
||||||
|
await materialInstance.setParameterInt("baseColorIndex", 0);
|
||||||
|
|
||||||
|
var data =
|
||||||
|
File("${testHelper.testDir}/assets/cube_texture2_512x512.png")
|
||||||
|
.readAsBytesSync();
|
||||||
|
final image = await viewer.decodeImage(data);
|
||||||
|
|
||||||
|
final texture = await viewer.createTexture(
|
||||||
|
await image.getWidth(), await image.getHeight(),
|
||||||
|
textureFormat: TextureFormat.RGBA32F);
|
||||||
|
await texture.setLinearImage(
|
||||||
|
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
|
||||||
|
final sampler = await viewer.createTextureSampler();
|
||||||
|
|
||||||
|
await materialInstance.setParameterTexture(
|
||||||
|
"baseColorMap", texture, sampler);
|
||||||
|
await cube.setMaterialInstanceAt(materialInstance);
|
||||||
|
await testHelper.capture(
|
||||||
|
viewer, "unlit_baseColorMap_fetch_material");
|
||||||
|
|
||||||
|
await image.destroy();
|
||||||
|
await texture.dispose();
|
||||||
|
await sampler.dispose();
|
||||||
|
|
||||||
|
await viewer.destroyMaterialInstance(materialInstance);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('unlit material with color + alpha', () async {
|
test('unlit material with color + alpha', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
await testHelper.withViewer((viewer) async {
|
||||||
await viewer.setPostProcessing(true);
|
await viewer.setPostProcessing(true);
|
||||||
@@ -123,18 +230,13 @@ void main() async {
|
|||||||
}, bg: kRed, postProcessing: true);
|
}, bg: kRed, postProcessing: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set ubershader texture', () async {
|
test('ubershader + baseColorMap texture', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
await testHelper.withViewer((viewer) async {
|
||||||
await viewer.addLight(LightType.SUN, 6500, 1000000, 0, 0, 0, 0, 0, -1);
|
var materialInstance = await viewer.createUbershaderMaterialInstance(unlit: true);
|
||||||
await viewer.setCameraPosition(0, 2, 6);
|
|
||||||
await viewer
|
|
||||||
.setCameraRotation(Quaternion.axisAngle(Vector3(1, 0, 0), -pi / 8));
|
|
||||||
|
|
||||||
var materialInstance = await viewer.createUbershaderMaterialInstance();
|
|
||||||
final cube = await viewer.createGeometry(
|
final cube = await viewer.createGeometry(
|
||||||
GeometryHelper.cube(uvs: true, normals: true),
|
GeometryHelper.cube(),
|
||||||
materialInstances: [materialInstance]);
|
materialInstances: [materialInstance]);
|
||||||
var data = File("${testHelper.testDir}/assets/cube_texture_512x512.png")
|
var data = File("${testHelper.testDir}/assets/cube_texture2_512x512_flipped.png")
|
||||||
.readAsBytesSync();
|
.readAsBytesSync();
|
||||||
final image = await viewer.decodeImage(data);
|
final image = await viewer.decodeImage(data);
|
||||||
final texture = await viewer.createTexture(
|
final texture = await viewer.createTexture(
|
||||||
@@ -153,7 +255,7 @@ void main() async {
|
|||||||
viewer, "geometry_cube_with_custom_material_ubershader_texture");
|
viewer, "geometry_cube_with_custom_material_ubershader_texture");
|
||||||
await viewer.destroyAsset(cube);
|
await viewer.destroyAsset(cube);
|
||||||
await viewer.destroyMaterialInstance(materialInstance);
|
await viewer.destroyMaterialInstance(materialInstance);
|
||||||
await viewer.destroyTexture(texture);
|
await texture.dispose();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -340,159 +442,6 @@ void main() async {
|
|||||||
}, postProcessing: true);
|
}, postProcessing: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('projection', () {
|
|
||||||
test('apply projection material', () async {
|
|
||||||
await testHelper.withViewer((viewer) async {
|
|
||||||
await viewer
|
|
||||||
.setCameraModelMatrix4(Matrix4.translation(Vector3(0, 0, 5)));
|
|
||||||
// // Rotate the camera in 30-degree increments and capture at each position
|
|
||||||
// for (int i = 0; i <= 180; i += 30) {
|
|
||||||
// int i = 60;
|
|
||||||
// final angle = i * (pi / 180); // Convert to radians
|
|
||||||
|
|
||||||
// // Calculate camera position
|
|
||||||
// // Start at (0, 1, 5) (facing the sphere from +z) and rotate around to (-5, 1, 0)
|
|
||||||
// final radius = 5.0;
|
|
||||||
// final x = -radius * sin(angle);
|
|
||||||
// final z = radius * cos(angle);
|
|
||||||
|
|
||||||
// // Create view matrix for this camera position
|
|
||||||
// final matrix = makeViewMatrix(
|
|
||||||
// Vector3(x, 1, z),
|
|
||||||
// Vector3.zero(), // Looking at origin
|
|
||||||
// Vector3(0, 1, 0) // Up vector
|
|
||||||
// )
|
|
||||||
// ..invert();
|
|
||||||
|
|
||||||
// await viewer.setCameraModelMatrix4(matrix);
|
|
||||||
|
|
||||||
// // Take a snapshot at this position
|
|
||||||
// await testHelper.capture(viewer, "projection_${i}deg");
|
|
||||||
// }
|
|
||||||
|
|
||||||
final view = await viewer.getViewAt(0);
|
|
||||||
final rtTextureHandle = await testHelper.createTexture(512, 512);
|
|
||||||
final rt = await viewer.createRenderTarget(
|
|
||||||
512, 512, rtTextureHandle.metalTextureAddress);
|
|
||||||
await view.setRenderTarget(rt);
|
|
||||||
final rtTexture = await rt.getColorTexture();
|
|
||||||
|
|
||||||
final ppuvMaterial = await viewer.createMaterial(File(
|
|
||||||
"/Users/nickfisher/Documents/thermion/materials/postprocess_uv.filamat")
|
|
||||||
.readAsBytesSync());
|
|
||||||
final ppuvInstance = await ppuvMaterial.createInstance();
|
|
||||||
|
|
||||||
// Setup the scene (lighting, materials, etc.)
|
|
||||||
await viewer.loadIbl(
|
|
||||||
"file://${testHelper.testDir}/assets/default_env_ibl.ktx",
|
|
||||||
intensity: 1000);
|
|
||||||
|
|
||||||
await viewer.addDirectLight(DirectLight.sun(
|
|
||||||
intensity: 500000,
|
|
||||||
castShadows: true,
|
|
||||||
direction: Vector3(1, -0.5, 0).normalized()));
|
|
||||||
|
|
||||||
// input texture
|
|
||||||
var inputTextureData =
|
|
||||||
File("${testHelper.testDir}/assets/cube_texture_512x512.png")
|
|
||||||
.readAsBytesSync();
|
|
||||||
var inputImage = await viewer.decodeImage(inputTextureData);
|
|
||||||
var inputTexture = await viewer.createTexture(
|
|
||||||
await inputImage.getWidth(), await inputImage.getHeight(),
|
|
||||||
textureFormat: TextureFormat.RGBA32F);
|
|
||||||
await inputTexture.setLinearImage(
|
|
||||||
inputImage, PixelDataFormat.RGBA, PixelDataType.FLOAT);
|
|
||||||
|
|
||||||
var captureUvMaterial = await viewer.createMaterial(File(
|
|
||||||
"/Users/nickfisher/Documents/thermion/materials/capture_uv.filamat")
|
|
||||||
.readAsBytesSync());
|
|
||||||
var captureUvMaterialInstance =
|
|
||||||
await captureUvMaterial.createInstance();
|
|
||||||
var sampler = await viewer.createTextureSampler();
|
|
||||||
|
|
||||||
// Create sphere and plane
|
|
||||||
final sphere = await viewer.createGeometry(
|
|
||||||
GeometryHelper.sphere(normals: true, uvs: true),
|
|
||||||
materialInstances: []);
|
|
||||||
// await viewer.setTransform(
|
|
||||||
// sphere.entity, Matrix4.compose(Vector3(2, 1, -1), Quaternion.identity(), Vector3(1.0,1.0,1.0)));
|
|
||||||
await sphere.addToScene();
|
|
||||||
|
|
||||||
await testHelper.capture(viewer, "color", renderTarget: rt);
|
|
||||||
|
|
||||||
await captureUvMaterialInstance.setParameterTexture(
|
|
||||||
"color", rtTexture, sampler);
|
|
||||||
await sphere.setMaterialInstanceAt(captureUvMaterialInstance);
|
|
||||||
|
|
||||||
await testHelper.capture(viewer, "uv_capture", renderTarget: rt);
|
|
||||||
|
|
||||||
// await ppuvInstance.setParameterTexture("uvTexture", rtTexture, sampler);
|
|
||||||
|
|
||||||
await sphere.setMaterialInstanceAt(ppuvInstance);
|
|
||||||
|
|
||||||
await testHelper.capture(viewer, "ppuv", renderTarget: rt);
|
|
||||||
|
|
||||||
// final quad = await viewer.createGeometry(
|
|
||||||
// GeometryHelper.plane(width: 100.0, height: 100.0),
|
|
||||||
// materialInstances: [materialInstance]);
|
|
||||||
// await viewer.setTransform(
|
|
||||||
// quad.entity, Matrix4.translation(Vector3(0, -1, 0)));
|
|
||||||
// await quad.addToScene();
|
|
||||||
|
|
||||||
var bytePixelBuffer = await viewer.capture(renderTarget: rt);
|
|
||||||
|
|
||||||
var floatPixelBuffer = Float32List.fromList(
|
|
||||||
bytePixelBuffer.map((p) => p.toDouble() / 255.0).toList());
|
|
||||||
|
|
||||||
print("pixelBuffer ${floatPixelBuffer.lengthInBytes} bytes");
|
|
||||||
|
|
||||||
var output = unprojectTexture(
|
|
||||||
renderTarget: await inputImage.getData(),
|
|
||||||
uvCoordinates: floatPixelBuffer,
|
|
||||||
renderTargetWidth: 512,
|
|
||||||
renderTargetHeight: 512,
|
|
||||||
renderTargetChannels: 4,
|
|
||||||
uvWidth: 512,
|
|
||||||
uvHeight: 512,
|
|
||||||
uvChannels: 4,
|
|
||||||
outputWidth: 512,
|
|
||||||
outputHeight: 512);
|
|
||||||
var byteOutput =
|
|
||||||
Uint8List.fromList(output.map((o) => (o * 255.0).toInt()).toList());
|
|
||||||
await savePixelBufferToBmp(byteOutput, 512, 512, "/tmp/foo.bmp");
|
|
||||||
|
|
||||||
final reappliedImage = await viewer.createImage(512, 512, 4);
|
|
||||||
final data = await reappliedImage.getData();
|
|
||||||
data.setRange(0, data.length, output);
|
|
||||||
final reappliedTexture = await viewer.createTexture(512, 512,
|
|
||||||
textureFormat: TextureFormat.RGBA32F);
|
|
||||||
await reappliedTexture.setLinearImage(
|
|
||||||
reappliedImage, PixelDataFormat.RGBA, PixelDataType.FLOAT);
|
|
||||||
var newMaterialInstance =
|
|
||||||
await viewer.createUbershaderMaterialInstance(unlit: true);
|
|
||||||
await newMaterialInstance.setParameterInt("baseColorIndex", 0);
|
|
||||||
|
|
||||||
await newMaterialInstance.setParameterTexture(
|
|
||||||
"baseColorMap",
|
|
||||||
reappliedTexture,
|
|
||||||
// inputTexture,
|
|
||||||
|
|
||||||
sampler);
|
|
||||||
await newMaterialInstance.setParameterFloat4(
|
|
||||||
"baseColorFactor", 1.0, 1.0, 1.0, 1.0);
|
|
||||||
await sphere.setMaterialInstanceAt(newMaterialInstance);
|
|
||||||
await testHelper.capture(viewer, "capture2");
|
|
||||||
|
|
||||||
// final view = await viewer.getViewAt(0);
|
|
||||||
// final renderTargetTexture = await testHelper.createTexture(512, 512);
|
|
||||||
// final rt = await viewer.createRenderTarget(
|
|
||||||
// 512, 512, renderTargetTexture.metalTextureAddress);
|
|
||||||
// await view.setRenderTarget(rt);
|
|
||||||
// pixelBuffer = await viewer.capture(renderTarget: rt);
|
|
||||||
}, viewportDimensions: (width: 512, height: 512));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Float32List unprojectTexture({
|
Float32List unprojectTexture({
|
||||||
|
|||||||
44
thermion_dart/test/render_thread_tests.dart
Normal file
44
thermion_dart/test/render_thread_tests.dart
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
|
import 'helpers.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
final testHelper = TestHelper("render_thread");
|
||||||
|
|
||||||
|
await testHelper.setup();
|
||||||
|
|
||||||
|
group("render thread/capture", () {
|
||||||
|
test("request frame on render thread", () async {
|
||||||
|
await testHelper.withViewer((viewer) async {
|
||||||
|
var metalTexture = await testHelper.createTexture(500, 500);
|
||||||
|
var texture = await FilamentApp.instance!.createTexture(
|
||||||
|
500, 500,
|
||||||
|
importedTextureHandle: metalTexture.metalTextureAddress,
|
||||||
|
flags: {
|
||||||
|
TextureUsage.TEXTURE_USAGE_BLIT_DST,
|
||||||
|
TextureUsage.TEXTURE_USAGE_SAMPLEABLE,
|
||||||
|
TextureUsage.TEXTURE_USAGE_COLOR_ATTACHMENT
|
||||||
|
});
|
||||||
|
|
||||||
|
var renderTarget = await FilamentApp.instance!
|
||||||
|
.createRenderTarget(500, 500, color: texture);
|
||||||
|
|
||||||
|
await viewer.view.setRenderTarget(renderTarget);
|
||||||
|
|
||||||
|
await viewer.render();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 1));
|
||||||
|
|
||||||
|
var data = metalTexture.getTextureBytes()!;
|
||||||
|
var pixels = data.bytes.cast<Uint8>().asTypedList(data.length);
|
||||||
|
|
||||||
|
savePixelBufferToBmp(
|
||||||
|
pixels, 500, 500, "${testHelper.testDir}/request_frame.bmp");
|
||||||
|
await viewer.dispose();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -316,7 +316,13 @@ void main() async {
|
|||||||
test('depth visualization', () async {
|
test('depth visualization', () async {
|
||||||
RenderLoop_create();
|
RenderLoop_create();
|
||||||
final engine = await withPointerCallback<TEngine>(
|
final engine = await withPointerCallback<TEngine>(
|
||||||
(cb) => Engine_createRenderThread(TBackend.BACKEND_METAL.index, cb));
|
(cb) => Engine_createRenderThread(TBackend.BACKEND_METAL.index, nullptr, nullptr, 1, false, cb));
|
||||||
|
|
||||||
|
final gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
|
||||||
|
(cb) => GltfResourceLoader_createRenderThread(engine, cb));
|
||||||
|
final gltfAssetLoader = await withPointerCallback<TGltfAssetLoader>(
|
||||||
|
(cb) => GltfAssetLoader_createRenderThread(engine, nullptr, cb));
|
||||||
|
|
||||||
final renderer = await withPointerCallback<TRenderer>(
|
final renderer = await withPointerCallback<TRenderer>(
|
||||||
(cb) => Engine_createRendererRenderThread(engine, cb));
|
(cb) => Engine_createRendererRenderThread(engine, cb));
|
||||||
final swapchain = await withPointerCallback<TSwapChain>((cb) =>
|
final swapchain = await withPointerCallback<TSwapChain>((cb) =>
|
||||||
@@ -328,20 +334,63 @@ void main() async {
|
|||||||
cb));
|
cb));
|
||||||
final camera = await withPointerCallback<TCamera>(
|
final camera = await withPointerCallback<TCamera>(
|
||||||
(cb) => Engine_createCameraRenderThread(engine, cb));
|
(cb) => Engine_createCameraRenderThread(engine, cb));
|
||||||
|
|
||||||
|
final offscreenView = await withPointerCallback<TView>(
|
||||||
|
(cb) => Engine_createViewRenderThread(engine, cb));
|
||||||
final view = await withPointerCallback<TView>(
|
final view = await withPointerCallback<TView>(
|
||||||
(cb) => Engine_createViewRenderThread(engine, cb));
|
(cb) => Engine_createViewRenderThread(engine, cb));
|
||||||
|
|
||||||
|
final colorTexture = await withPointerCallback<TTexture>((cb) =>
|
||||||
|
Texture_buildRenderThread(
|
||||||
|
engine,
|
||||||
|
500,
|
||||||
|
500,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
TTextureUsage.TEXTURE_USAGE_COLOR_ATTACHMENT.value |
|
||||||
|
TTextureUsage.TEXTURE_USAGE_SAMPLEABLE.value |
|
||||||
|
TTextureUsage.TEXTURE_USAGE_BLIT_SRC.value,
|
||||||
|
0,
|
||||||
|
TTextureSamplerType.SAMPLER_2D,
|
||||||
|
TTextureFormat.TEXTUREFORMAT_RGBA8,
|
||||||
|
cb));
|
||||||
|
|
||||||
|
final depthTexture = await withPointerCallback<TTexture>((cb) =>
|
||||||
|
Texture_buildRenderThread(
|
||||||
|
engine,
|
||||||
|
500,
|
||||||
|
500,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
TTextureUsage.TEXTURE_USAGE_DEPTH_ATTACHMENT.value |
|
||||||
|
TTextureUsage.TEXTURE_USAGE_SAMPLEABLE.value,
|
||||||
|
0,
|
||||||
|
TTextureSamplerType.SAMPLER_2D,
|
||||||
|
TTextureFormat.TEXTUREFORMAT_DEPTH32F,
|
||||||
|
cb));
|
||||||
|
|
||||||
|
final renderTarget = await withPointerCallback<TRenderTarget>((cb) =>
|
||||||
|
RenderTarget_createRenderThread(
|
||||||
|
engine, 500, 500, colorTexture, depthTexture, cb));
|
||||||
|
View_setRenderTarget(offscreenView, renderTarget);
|
||||||
|
final offscreenScene = Engine_createScene(engine);
|
||||||
final scene = Engine_createScene(engine);
|
final scene = Engine_createScene(engine);
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
await withVoidCallback((cb) {
|
||||||
Renderer_setClearOptionsRenderThread(
|
Renderer_setClearOptionsRenderThread(
|
||||||
renderer, 1.0, 0.0, 1.0, 1.0, 0, true, true, cb);
|
renderer, 1.0, 0.0, 1.0, 1.0, 0, true, true, cb);
|
||||||
});
|
});
|
||||||
|
View_setFrustumCullingEnabled(offscreenView, false);
|
||||||
View_setFrustumCullingEnabled(view, false);
|
View_setFrustumCullingEnabled(view, false);
|
||||||
|
View_setScene(offscreenView, offscreenScene);
|
||||||
View_setScene(view, scene);
|
View_setScene(view, scene);
|
||||||
|
View_setCamera(offscreenView, camera);
|
||||||
View_setCamera(view, camera);
|
View_setCamera(view, camera);
|
||||||
|
View_setViewport(offscreenView, 500, 500);
|
||||||
View_setViewport(view, 500, 500);
|
View_setViewport(view, 500, 500);
|
||||||
final eye = Struct.create<double3>()
|
final eye = Struct.create<double3>()
|
||||||
..x = 0.0
|
..x = 5.0
|
||||||
..y = 0.0
|
..y = 1.0
|
||||||
..z = 5.0;
|
..z = 5.0;
|
||||||
Camera_lookAt(
|
Camera_lookAt(
|
||||||
camera,
|
camera,
|
||||||
@@ -354,11 +403,21 @@ void main() async {
|
|||||||
..x = 0.0
|
..x = 0.0
|
||||||
..y = 1.0
|
..y = 1.0
|
||||||
..z = 0.0);
|
..z = 0.0);
|
||||||
View_setBloomRenderThread(view, false, 0.0);
|
View_setBloomRenderThread(offscreenView, false, 0.0);
|
||||||
|
|
||||||
Camera_setLensProjection(camera, 0.05, 100000, 1.0, kFocalLength);
|
Camera_setLensProjection(camera, 0.05, 100000, 1.0, kFocalLength);
|
||||||
|
View_setPostProcessing(offscreenView, false);
|
||||||
View_setPostProcessing(view, false);
|
View_setPostProcessing(view, false);
|
||||||
|
|
||||||
|
final iblData = File("${testHelper.testDir}/assets/default_env_ibl.ktx")
|
||||||
|
.readAsBytesSync();
|
||||||
|
final ibl = await withPointerCallback<TIndirectLight>((cb) =>
|
||||||
|
Engine_buildIndirectLightRenderThread(
|
||||||
|
engine, iblData.address, iblData.length, 30000, cb, nullptr));
|
||||||
|
|
||||||
|
Scene_setIndirectLight(offscreenScene, ibl);
|
||||||
|
Scene_setIndirectLight(scene, ibl);
|
||||||
|
|
||||||
final skyboxData =
|
final skyboxData =
|
||||||
File("${testHelper.testDir}/assets/default_env_skybox.ktx")
|
File("${testHelper.testDir}/assets/default_env_skybox.ktx")
|
||||||
.readAsBytesSync();
|
.readAsBytesSync();
|
||||||
@@ -367,25 +426,98 @@ void main() async {
|
|||||||
Engine_buildSkyboxRenderThread(
|
Engine_buildSkyboxRenderThread(
|
||||||
engine, skyboxData.address, skyboxData.length, cb, nullptr));
|
engine, skyboxData.address, skyboxData.length, cb, nullptr));
|
||||||
|
|
||||||
|
Scene_setSkybox(offscreenScene, skybox);
|
||||||
Scene_setSkybox(scene, skybox);
|
Scene_setSkybox(scene, skybox);
|
||||||
|
|
||||||
final cubeData = GeometryHelper.cube();
|
// final cubeData = GeometryHelper.cube();
|
||||||
final cube = await withPointerCallback<TSceneAsset>((cb) =>
|
// final cube = await withPointerCallback<TSceneAsset>((cb) =>
|
||||||
SceneAsset_createGeometryRenderThread(
|
// SceneAsset_createGeometryRenderThread(
|
||||||
|
// engine,
|
||||||
|
// cubeData.vertices.address,
|
||||||
|
// cubeData.vertices.length,
|
||||||
|
// cubeData.normals.address,
|
||||||
|
// cubeData.normals.length,
|
||||||
|
// cubeData.uvs.address,
|
||||||
|
// cubeData.uvs.length,
|
||||||
|
// cubeData.indices.address,
|
||||||
|
// cubeData.indices.length,
|
||||||
|
// TPrimitiveType.PRIMITIVETYPE_POINTS,
|
||||||
|
// nullptr,
|
||||||
|
// 0,
|
||||||
|
// cb));
|
||||||
|
// Scene_addEntity(offscreenScene, SceneAsset_getEntity(cube));
|
||||||
|
var cube =
|
||||||
|
File("${testHelper.testDir}/assets/cube.glb").readAsBytesSync();
|
||||||
|
final filamentAsset = await withPointerCallback<TFilamentAsset>((cb) =>
|
||||||
|
GltfAssetLoader_loadRenderThread(gltfAssetLoader,
|
||||||
|
cube.address, cube.length, 1, cb));
|
||||||
|
var entities = Int32List(FilamentAsset_getEntityCount(filamentAsset));
|
||||||
|
FilamentAsset_getEntities(filamentAsset, entities.address);
|
||||||
|
|
||||||
|
final unlitMaData =
|
||||||
|
File("/Users/nickfisher/Documents/thermion/materials/unlit.filamat")
|
||||||
|
.readAsBytesSync();
|
||||||
|
final unlitMa =
|
||||||
|
Engine_buildMaterial(engine, unlitMaData.address, unlitMaData.length);
|
||||||
|
final unlitMi = await withPointerCallback<TMaterialInstance>(
|
||||||
|
(cb) => Material_createInstanceRenderThread(unlitMa, cb));
|
||||||
|
MaterialInstance_setParameterFloat2(
|
||||||
|
unlitMi, "uvScale".toNativeUtf8().cast<Char>(), 1.0, 1.0);
|
||||||
|
MaterialInstance_setParameterFloat4(unlitMi,
|
||||||
|
"baseColorFactor".toNativeUtf8().cast<Char>(), 1.0, 1.0, 0.0, 1.0);
|
||||||
|
MaterialInstance_setParameterInt(
|
||||||
|
unlitMi, "baseColorIndex".toNativeUtf8().cast<Char>(), -1);
|
||||||
|
for (int i = 0; i < entities.length; i++) {
|
||||||
|
RenderableManager_setMaterialInstanceAt(
|
||||||
|
Engine_getRenderableManager(engine), entities[i], 0, unlitMi);
|
||||||
|
}
|
||||||
|
|
||||||
|
// final materialInstance = GltfAssetLoader_getMaterialInstance(
|
||||||
|
// Engine_getRenderableManager(engine), filamentAsset);
|
||||||
|
// MaterialInstance_setParameterFloat4(materialInstance,
|
||||||
|
// "baseColorFactor".toNativeUtf8().cast<Char>(), 1.0, 0, 0, 1);
|
||||||
|
|
||||||
|
final imageData =
|
||||||
|
File("${testHelper.testDir}/assets/cube_texture2_512x512.png")
|
||||||
|
.readAsBytesSync();
|
||||||
|
final image = await Image_decode(imageData.address, imageData.length,
|
||||||
|
"unused".toNativeUtf8().cast<Char>());
|
||||||
|
final texture = await withPointerCallback<TTexture>((cb) =>
|
||||||
|
Texture_buildRenderThread(
|
||||||
engine,
|
engine,
|
||||||
cubeData.vertices.address,
|
Image_getWidth(image),
|
||||||
cubeData.vertices.length,
|
Image_getHeight(image),
|
||||||
cubeData.normals.address,
|
1,
|
||||||
cubeData.normals.length,
|
1,
|
||||||
cubeData.uvs.address,
|
TTextureUsage.TEXTURE_USAGE_SAMPLEABLE.index,
|
||||||
cubeData.uvs.length,
|
|
||||||
cubeData.indices.address,
|
|
||||||
cubeData.indices.length,
|
|
||||||
TPrimitiveType.PRIMITIVETYPE_POINTS,
|
|
||||||
nullptr,
|
|
||||||
0,
|
0,
|
||||||
|
TTextureSamplerType.SAMPLER_2D,
|
||||||
|
TTextureFormat.TEXTUREFORMAT_RGBA32F,
|
||||||
cb));
|
cb));
|
||||||
Scene_addEntity(scene, SceneAsset_getEntity(cube));
|
|
||||||
|
await withBoolCallback((cb) => Texture_loadImageRenderThread(
|
||||||
|
engine,
|
||||||
|
texture,
|
||||||
|
image,
|
||||||
|
TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
||||||
|
TPixelDataType.PIXELDATATYPE_FLOAT,
|
||||||
|
cb));
|
||||||
|
MaterialInstance_setParameterInt(
|
||||||
|
unlitMi, "baseColorIndex".toNativeUtf8().cast<Char>(), 0);
|
||||||
|
MaterialInstance_setParameterTexture(
|
||||||
|
unlitMi,
|
||||||
|
"baseColorMap".toNativeUtf8().cast<Char>(),
|
||||||
|
RenderTarget_getDepthTexture(renderTarget),
|
||||||
|
// texture,
|
||||||
|
TextureSampler_create());
|
||||||
|
|
||||||
|
await withVoidCallback((cb) {
|
||||||
|
Scene_addFilamentAssetRenderThread(offscreenScene, filamentAsset, cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
await withVoidCallback((cb) {
|
||||||
|
Scene_addFilamentAssetRenderThread(scene, filamentAsset, cb);
|
||||||
|
});
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
await withVoidCallback((cb) {
|
||||||
Engine_flushAndWaitRenderThead(engine, cb);
|
Engine_flushAndWaitRenderThead(engine, cb);
|
||||||
@@ -400,13 +532,29 @@ void main() async {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// for (int i = 0; i < 10; i++) {
|
await withVoidCallback((cb) {
|
||||||
await withVoidCallback((cb) {
|
Renderer_renderRenderThread(renderer, offscreenView, cb);
|
||||||
Renderer_renderRenderThread(renderer, view, cb);
|
});
|
||||||
});
|
|
||||||
// }
|
|
||||||
|
|
||||||
var view1Out = Uint8List(500 * 500 * 4);
|
await withVoidCallback((cb) {
|
||||||
|
Renderer_renderRenderThread(renderer, view, cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
var offscreenViewOut = Uint8List(500 * 500 * 4);
|
||||||
|
|
||||||
|
await withVoidCallback((cb) {
|
||||||
|
Renderer_readPixelsRenderThread(
|
||||||
|
renderer,
|
||||||
|
offscreenView,
|
||||||
|
renderTarget,
|
||||||
|
TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
||||||
|
TPixelDataType.PIXELDATATYPE_UBYTE,
|
||||||
|
offscreenViewOut.address,
|
||||||
|
cb,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
var swapchainOut = Uint8List(500 * 500 * 4);
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
await withVoidCallback((cb) {
|
||||||
Renderer_readPixelsRenderThread(
|
Renderer_readPixelsRenderThread(
|
||||||
@@ -415,7 +563,7 @@ void main() async {
|
|||||||
nullptr,
|
nullptr,
|
||||||
TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
||||||
TPixelDataType.PIXELDATATYPE_UBYTE,
|
TPixelDataType.PIXELDATATYPE_UBYTE,
|
||||||
view1Out.address,
|
swapchainOut.address,
|
||||||
cb,
|
cb,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -425,72 +573,23 @@ void main() async {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await savePixelBufferToPng(
|
await savePixelBufferToPng(
|
||||||
view1Out,
|
offscreenViewOut,
|
||||||
500,
|
500,
|
||||||
500,
|
500,
|
||||||
"/tmp/view1.png",
|
"/tmp/view1.png",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await savePixelBufferToPng(
|
||||||
|
swapchainOut,
|
||||||
|
500,
|
||||||
|
500,
|
||||||
|
"/tmp/sc1.png",
|
||||||
|
);
|
||||||
|
|
||||||
|
await withVoidCallback((cb) => Engine_destroyIndirectLightRenderThread(engine, ibl, cb));
|
||||||
|
await withVoidCallback((cb) => Engine_destroySkyboxRenderThread(engine, skybox, cb));
|
||||||
RenderLoop_destroy();
|
RenderLoop_destroy();
|
||||||
|
|
||||||
// await camera.lookAt(Vector3(100, 1500, 1500));
|
|
||||||
|
|
||||||
// // first view just renders a normal unlit cube, but into a render target
|
|
||||||
// final vp = await (await viewer.getViewAt(0)).getViewport();
|
|
||||||
// FFIView view = await viewer.createView()
|
|
||||||
// as FFIView; // await viewer.getViewAt(0) as FFIView;
|
|
||||||
// await view.setViewport(vp.width, vp.height);
|
|
||||||
// await view.setCamera(camera);
|
|
||||||
// await view.setFrustumCullingEnabled(false);
|
|
||||||
|
|
||||||
// var scene1 = Engine_createScene(engine);
|
|
||||||
// View_setScene(view.view, scene1);
|
|
||||||
// Scene_setSkybox(scene1, skybox);
|
|
||||||
// await view.setPostProcessing(false);
|
|
||||||
|
|
||||||
// await viewer.setClearOptions(Vector4(0, 0, 1, 0), 1, false, false);
|
|
||||||
// final colorTextureHandle = await testHelper.createTexture(
|
|
||||||
// vp.width,
|
|
||||||
// vp.height,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// final rt = await viewer.createRenderTarget(
|
|
||||||
// vp.width,
|
|
||||||
// vp.height,
|
|
||||||
// // colorTextureHandle.metalTextureAddress,
|
|
||||||
// ) as FFIRenderTarget;
|
|
||||||
// await view.setRenderTarget(rt);
|
|
||||||
|
|
||||||
// final unlit = await viewer.createUnlitMaterialInstance();
|
|
||||||
// await unlit.setParameterInt("baseColorIndex", -1);
|
|
||||||
// await unlit.setParameterFloat4("baseColorFactor", 1.0, 0, 0, 1);
|
|
||||||
// await unlit.setDepthWriteEnabled(true);
|
|
||||||
|
|
||||||
// final cube = await viewer
|
|
||||||
// .createGeometry(GeometryHelper.cube(), materialInstances: [unlit]);
|
|
||||||
// Scene_addEntity(scene1, cube.entity);
|
|
||||||
|
|
||||||
// final cube2 = await viewer
|
|
||||||
// .createGeometry(GeometryHelper.cube(), materialInstances: [unlit]);
|
|
||||||
// Scene_addEntity(scene1, cube2.entity);
|
|
||||||
|
|
||||||
// await viewer.setTransform(
|
|
||||||
// cube.entity,
|
|
||||||
// Matrix4.compose(
|
|
||||||
// Vector3.zero(),
|
|
||||||
// Quaternion.identity(),
|
|
||||||
// Vector3(950, 950, 500),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// await viewer.setTransform(
|
|
||||||
// cube2.entity,
|
|
||||||
// Matrix4.compose(
|
|
||||||
// Vector3(-500, -500, -2000),
|
|
||||||
// Quaternion.identity(),
|
|
||||||
// Vector3(500, 500, 500),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
|
|
||||||
// final mirrorMaterial = await viewer.createMaterial(
|
// final mirrorMaterial = await viewer.createMaterial(
|
||||||
// File(
|
// File(
|
||||||
// "/Users/nickfisher/Documents/thermion/materials/mirror.filamat",
|
// "/Users/nickfisher/Documents/thermion/materials/mirror.filamat",
|
||||||
@@ -524,15 +623,6 @@ void main() async {
|
|||||||
// await view2.setCamera(camera);
|
// await view2.setCamera(camera);
|
||||||
// await view2.setFrustumCullingEnabled(false);
|
// await view2.setFrustumCullingEnabled(false);
|
||||||
|
|
||||||
// final image = await viewer.decodeImage(
|
|
||||||
// File("${testHelper.testDir}/assets/cube_texture2_512x512.png")
|
|
||||||
// .readAsBytesSync());
|
|
||||||
// final texture = await viewer.createTexture(
|
|
||||||
// await image.getWidth(), await image.getHeight(),
|
|
||||||
// textureFormat: TextureFormat.RGBA32F);
|
|
||||||
// await texture.setLinearImage(
|
|
||||||
// image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
|
|
||||||
|
|
||||||
// await mirrorMi.setParameterTexture(
|
// await mirrorMi.setParameterTexture(
|
||||||
// "albedo",
|
// "albedo",
|
||||||
// // texture as FFITexture,
|
// // texture as FFITexture,
|
||||||
|
|||||||
@@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
|
||||||
|
|
||||||
import 'helpers.dart';
|
import 'helpers.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
|
|||||||
@@ -1,157 +1,157 @@
|
|||||||
// ignore_for_file: unused_local_variable
|
// // ignore_for_file: unused_local_variable
|
||||||
|
|
||||||
import 'dart:async';
|
// import 'dart:async';
|
||||||
|
|
||||||
import 'package:test/test.dart';
|
// import 'package:test/test.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
// import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
// import 'package:vector_math/vector_math_64.dart';
|
||||||
import 'helpers.dart';
|
// import 'helpers.dart';
|
||||||
|
|
||||||
void main() async {
|
// void main() async {
|
||||||
final testHelper = TestHelper("view");
|
// final testHelper = TestHelper("view");
|
||||||
|
|
||||||
group('view tests', () {
|
// group('view tests', () {
|
||||||
test('get camera from view', () async {
|
// test('get camera from view', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
var view = await viewer.getViewAt(0);
|
// var view = await viewer.getViewAt(0);
|
||||||
expect(await view.getCamera(), isNotNull);
|
// expect(await view.getCamera(), isNotNull);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('one swapchain, render view to render target', () async {
|
// test('one swapchain, render view to render target', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
final texture = await testHelper.createTexture(500, 500);
|
// final texture = await testHelper.createTexture(500, 500);
|
||||||
final renderTarget = await viewer.createRenderTarget(
|
// final renderTarget = await viewer.createRenderTarget(
|
||||||
500, 500, texture.metalTextureAddress);
|
// 500, 500, texture.metalTextureAddress);
|
||||||
final view = await viewer.getViewAt(0);
|
// final view = await viewer.getViewAt(0);
|
||||||
await view.setRenderTarget(renderTarget);
|
// await view.setRenderTarget(renderTarget);
|
||||||
|
|
||||||
await viewer.setBackgroundColor(1.0, 0, 0, 1);
|
// await viewer.setBackgroundColor(1.0, 0, 0, 1);
|
||||||
final cube = await viewer
|
// final cube = await viewer
|
||||||
.createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
// .createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
||||||
|
|
||||||
var mainCamera = await viewer.getMainCamera();
|
// var mainCamera = await viewer.getMainCamera();
|
||||||
mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5)));
|
// mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5)));
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer,
|
// viewer,
|
||||||
renderTarget: renderTarget,
|
// renderTarget: renderTarget,
|
||||||
"default_swapchain_default_view_render_target");
|
// "default_swapchain_default_view_render_target");
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('create secondary view, default swapchain', () async {
|
// test('create secondary view, default swapchain', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
final cube = await viewer
|
// final cube = await viewer
|
||||||
.createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
// .createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
||||||
|
|
||||||
var mainCamera = await viewer.getMainCamera();
|
// var mainCamera = await viewer.getMainCamera();
|
||||||
mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5)));
|
// mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5)));
|
||||||
await testHelper.capture(viewer, "default_swapchain_default_view");
|
// await testHelper.capture(viewer, "default_swapchain_default_view");
|
||||||
|
|
||||||
final view = await viewer.createView();
|
// final view = await viewer.createView();
|
||||||
view.updateViewport(500, 500);
|
// view.setViewport(500, 500);
|
||||||
view.setCamera(mainCamera);
|
// view.setCamera(mainCamera);
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer,
|
// viewer,
|
||||||
"default_swapchain_new_view_with_main_camera",
|
// "default_swapchain_new_view_with_main_camera",
|
||||||
view: view,
|
// view: view,
|
||||||
);
|
// );
|
||||||
|
|
||||||
var newCamera = await viewer.createCamera();
|
// var newCamera = await viewer.createCamera();
|
||||||
newCamera.setTransform(Matrix4.translation(Vector3(0.0, 0.0, 10.0)));
|
// newCamera.setTransform(Matrix4.translation(Vector3(0.0, 0.0, 10.0)));
|
||||||
newCamera.setLensProjection();
|
// newCamera.setLensProjection();
|
||||||
view.setCamera(newCamera);
|
// view.setCamera(newCamera);
|
||||||
|
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer,
|
// viewer,
|
||||||
"default_swapchain_new_view_new_camera",
|
// "default_swapchain_new_view_new_camera",
|
||||||
view: view,
|
// view: view,
|
||||||
);
|
// );
|
||||||
|
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer,
|
// viewer,
|
||||||
"default_swapchain_default_view_main_camera_no_change",
|
// "default_swapchain_default_view_main_camera_no_change",
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('create secondary view, different swapchain', () async {
|
// test('create secondary view, different swapchain', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
final cube = await viewer.createGeometry(GeometryHelper.cube());
|
// final cube = await viewer.createGeometry(GeometryHelper.cube());
|
||||||
|
|
||||||
var mainCamera = await viewer.getMainCamera();
|
// var mainCamera = await viewer.getMainCamera();
|
||||||
mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5)));
|
// mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5)));
|
||||||
final swapChain = await viewer.createHeadlessSwapChain(1, 1);
|
// final swapChain = await viewer.createHeadlessSwapChain(1, 1);
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer, "create_swapchain_default_view_default_swapchain");
|
// viewer, "create_swapchain_default_view_default_swapchain");
|
||||||
|
|
||||||
final view = await viewer.createView();
|
// final view = await viewer.createView();
|
||||||
|
|
||||||
final texture = await testHelper.createTexture(200, 400);
|
// final texture = await testHelper.createTexture(200, 400);
|
||||||
final renderTarget = await viewer.createRenderTarget(
|
// final renderTarget = await viewer.createRenderTarget(
|
||||||
200, 400, texture.metalTextureAddress);
|
// 200, 400, texture.metalTextureAddress);
|
||||||
await view.setRenderTarget(renderTarget);
|
// await view.setRenderTarget(renderTarget);
|
||||||
|
|
||||||
await view.updateViewport(200, 400);
|
// await view.setViewport(200, 400);
|
||||||
view.setCamera(mainCamera);
|
// view.setCamera(mainCamera);
|
||||||
mainCamera.setLensProjection(aspect: 0.5);
|
// mainCamera.setLensProjection(aspect: 0.5);
|
||||||
|
|
||||||
await testHelper.capture(
|
// await testHelper.capture(
|
||||||
viewer,
|
// viewer,
|
||||||
view: view,
|
// view: view,
|
||||||
swapChain: swapChain,
|
// swapChain: swapChain,
|
||||||
renderTarget: renderTarget,
|
// renderTarget: renderTarget,
|
||||||
"create_swapchain_secondary_view_new_swapchain",
|
// "create_swapchain_secondary_view_new_swapchain",
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('pick', () async {
|
// test('pick', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
final view = await viewer.getViewAt(0);
|
// final view = await viewer.getViewAt(0);
|
||||||
|
|
||||||
await view.setRenderable(true, testHelper.swapChain);
|
// await view.setRenderable(true, testHelper.swapChain);
|
||||||
|
|
||||||
final cube = await viewer
|
// final cube = await viewer
|
||||||
.createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
// .createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
||||||
|
|
||||||
await testHelper.capture(viewer, "view_pick");
|
// await testHelper.capture(viewer, "view_pick");
|
||||||
|
|
||||||
final completer = Completer();
|
// final completer = Completer();
|
||||||
|
|
||||||
await viewer.pick(250, 250, (result) {
|
// await viewer.pick(250, 250, (result) {
|
||||||
completer.complete(result.entity);
|
// completer.complete(result.entity);
|
||||||
print(
|
// print(
|
||||||
"Pick result : ${result.fragX} ${result.fragY} ${result.fragZ}");
|
// "Pick result : ${result.fragX} ${result.fragY} ${result.fragZ}");
|
||||||
});
|
// });
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
// for (int i = 0; i < 10; i++) {
|
||||||
await testHelper.capture(viewer, "view_pick");
|
// await testHelper.capture(viewer, "view_pick");
|
||||||
if (completer.isCompleted) {
|
// if (completer.isCompleted) {
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
expect(completer.isCompleted, true);
|
// expect(completer.isCompleted, true);
|
||||||
expect(await completer.future, cube.entity);
|
// expect(await completer.future, cube.entity);
|
||||||
}, cameraPosition: Vector3(0, 0, 3));
|
// }, cameraPosition: Vector3(0, 0, 3));
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('dithering', () async {
|
// test('dithering', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
// await testHelper.withViewer((viewer) async {
|
||||||
final view = await viewer.getViewAt(0);
|
// final view = await viewer.getViewAt(0);
|
||||||
|
|
||||||
expect(await view.isDitheringEnabled(), true);
|
// expect(await view.isDitheringEnabled(), true);
|
||||||
|
|
||||||
final cube = await viewer
|
// final cube = await viewer
|
||||||
.createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
// .createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
||||||
|
|
||||||
await testHelper.capture(viewer, "dithering_enabled");
|
// await testHelper.capture(viewer, "dithering_enabled");
|
||||||
|
|
||||||
await view.setDithering(false);
|
// await view.setDithering(false);
|
||||||
expect(await view.isDitheringEnabled(), false);
|
// expect(await view.isDitheringEnabled(), false);
|
||||||
await testHelper.capture(viewer, "dithering_disabled");
|
// await testHelper.capture(viewer, "dithering_disabled");
|
||||||
}, cameraPosition: Vector3(0, 0, 3));
|
// }, cameraPosition: Vector3(0, 0, 3));
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|||||||
Reference in New Issue
Block a user