more camera work

This commit is contained in:
Nick Fisher
2024-09-26 16:51:14 +08:00
parent 239891c400
commit 4355d9c83f
14 changed files with 114 additions and 9 deletions

View File

@@ -1,4 +1,4 @@
output: '../lib/thermion_dart/viewer/ffi/src/thermion_dart.g.dart'
output: '../lib/src/viewer/src/ffi/src/thermion_dart.g.dart'
headers:
entry-points:
- '../native/include/ThermionDartRenderThreadApi.h'

View File

@@ -3,11 +3,11 @@ import 'dart:ffi';
import 'package:vector_math/vector_math_64.dart';
import '../../../../utils/matrix.dart';
import '../../shared_types/camera.dart';
import '../../thermion_viewer_base.dart';
import 'thermion_dart.g.dart';
class ThermionFFICamera extends Camera {
final Pointer<TCamera> camera;
final Pointer<TEngine> engine;
late ThermionEntity _entity;
@@ -51,4 +51,14 @@ class ThermionFFICamera extends Camera {
Future setModelMatrix(Matrix4 matrix) async {
Camera_setModelMatrix(camera, matrix4ToDouble4x4(matrix));
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ThermionFFICamera &&
runtimeType == other.runtimeType &&
camera == other.camera;
@override
int get hashCode => camera.hashCode;
}

View File

@@ -970,6 +970,19 @@ external void SceneManager_setCamera(
ffi.Pointer<TCamera> camera,
);
@ffi.Native<ffi.Size Function(ffi.Pointer<TSceneManager>)>(isLeaf: true)
external int SceneManager_getCameraCount(
ffi.Pointer<TSceneManager> sceneManager,
);
@ffi.Native<
ffi.Pointer<TCamera> Function(
ffi.Pointer<TSceneManager>, ffi.Size)>(isLeaf: true)
external ffi.Pointer<TCamera> SceneManager_getCameraAt(
ffi.Pointer<TSceneManager> sceneManager,
int index,
);
@ffi.Native<
ffi.Int Function(ffi.Pointer<TSceneManager>, EntityId,
ffi.Pointer<ffi.Char>)>(isLeaf: true)

View File

@@ -2205,6 +2205,25 @@ class ThermionViewerFFI extends ThermionViewer {
_hooks.remove(hook);
}
}
///
///
///
int getCameraCount() {
return SceneManager_getCameraCount(_sceneManager!);
}
///
/// Returns the camera specified by the given index. Note that the camera at
/// index 0 is always the main camera; this cannot be destroyed.
///
Camera getCameraAt(int index) {
final camera = SceneManager_getCameraAt(_sceneManager!, index);
if (camera == nullptr) {
throw Exception("No camera at index $index");
}
return ThermionFFICamera(camera, Viewer_getEngine(_viewer!));
}
}
class ThermionFFITexture extends ThermionTexture {

View File

@@ -979,4 +979,15 @@ abstract class ThermionViewer {
///
///
Future unregisterRequestFrameHook(Future Function() hook);
///
///
///
int getCameraCount();
///
/// Returns the camera specified by the given index. Note that the camera at
/// index 0 is always the main camera; this cannot be destroyed.
///
Camera getCameraAt(int index);
}

View File

@@ -995,6 +995,18 @@ class ThermionViewerStub extends ThermionViewer {
// TODO: implement unregisterRequestFrameHook
throw UnimplementedError();
}
@override
Camera getCameraAt(int index) {
// TODO: implement getCameraAt
throw UnimplementedError();
}
@override
int getCameraCount() {
// TODO: implement getCameraCount
throw UnimplementedError();
}
}

View File

@@ -1,7 +1,7 @@
library thermion_viewer;
export 'src/shared_types/shared_types.dart';
export 'src/thermion_viewer_base.dart';
export 'src/thermion_viewer_stub.dart'
if (dart.library.io) 'src/ffi/thermion_viewer_ffi.dart'
if (dart.library.js_interop) 'src/web_wasm/thermion_viewer_web_wasm.dart';
export 'src/shared_types/shared_types.dart';

View File

@@ -50,7 +50,8 @@ namespace thermion_filament
const ResourceLoaderWrapperImpl *const loader,
Engine *engine,
Scene *scene,
const char *uberArchivePath);
const char *uberArchivePath,
Camera* mainCamera);
~SceneManager();
enum LAYERS {
@@ -305,12 +306,17 @@ namespace thermion_filament
void setCamera(Camera* camera);
size_t getCameraCount();
Camera* getCameraAt(size_t index);
private:
gltfio::AssetLoader *_assetLoader = nullptr;
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
Engine *_engine = nullptr;
Scene *_scene = nullptr;
View* _view = nullptr;
Camera* _mainCamera;
gltfio::MaterialProvider *_ubershaderProvider = nullptr;
gltfio::MaterialProvider *_unlitMaterialProvider = nullptr;

View File

@@ -245,6 +245,8 @@ extern "C"
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_createCamera(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyCamera(TSceneManager *sceneManager, TCamera* camera);
EMSCRIPTEN_KEEPALIVE void SceneManager_setCamera(TSceneManager *sceneManager, TCamera* camera);
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getCameraAt(TSceneManager *sceneManager, size_t index);
EMSCRIPTEN_KEEPALIVE int hide_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
EMSCRIPTEN_KEEPALIVE int reveal_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
EMSCRIPTEN_KEEPALIVE void set_post_processing(TViewer *viewer, bool enabled);

View File

@@ -201,7 +201,8 @@ namespace thermion_filament
_resourceLoaderWrapper,
_engine,
_scene,
uberArchivePath);
uberArchivePath,
_mainCamera);
}
void FilamentViewer::setAntiAliasing(bool msaa, bool fxaa, bool taa)

View File

@@ -52,11 +52,13 @@ namespace thermion_filament
const ResourceLoaderWrapperImpl *const resourceLoaderWrapper,
Engine *engine,
Scene *scene,
const char *uberArchivePath)
const char *uberArchivePath,
Camera *mainCamera)
: _view(view),
_resourceLoaderWrapper(resourceLoaderWrapper),
_engine(engine),
_scene(scene)
_scene(scene),
_mainCamera(mainCamera)
{
_stbDecoder = createStbProvider(_engine);
@@ -2662,6 +2664,20 @@ EntityId SceneManager::createGeometry(
void SceneManager::setCamera(Camera* camera) {
_view->setCamera(camera);
}
size_t SceneManager::getCameraCount() {
return _cameras.size() + 1;
}
Camera* SceneManager::getCameraAt(size_t index) {
if(index == 0) {
return _mainCamera;
}
if(index - 1 > _cameras.size() - 1) {
return nullptr;
}
return _cameras[index-1];
}
} // namespace thermion_filament

View File

@@ -1119,4 +1119,14 @@ EMSCRIPTEN_KEEPALIVE void SceneManager_setCamera(TSceneManager* tSceneManager, T
auto * camera = reinterpret_cast<Camera*>(tCamera);
sceneManager->setCamera(camera);
}
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *tSceneManager) {
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
return sceneManager->getCameraCount();
}
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getCameraAt(TSceneManager *tSceneManager, size_t index) {
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
auto * camera = sceneManager->getCameraAt(index);
return reinterpret_cast<TCamera*>(camera);
}
}

View File

@@ -128,7 +128,7 @@ void main() async {
expect(modelMatrix.getColumn(3).w, 1.0);
await viewer.setTransform(parent, Matrix4.translation(Vector3(0, 1, 0)));
modelMatrix = await viewer.getCameraModelMatrix();
modelMatrix = await viewer.getCameraModelMatrix();
expect(modelMatrix.getColumn(3).x, 1.0);
expect(modelMatrix.getColumn(3).y, 1.0);
expect(modelMatrix.getColumn(3).z, 0.0);
@@ -150,6 +150,11 @@ void main() async {
final mainCamera = await viewer.getMainCamera();
await viewer.setActiveCamera(mainCamera);
await testHelper.capture(viewer, "create_camera_back_to_main");
expect(viewer.getCameraCount(), 2);
expect(viewer.getCameraAt(0), await viewer.getMainCamera());
expect(viewer.getCameraAt(1), newCamera);
await expectLater(() => viewer.getCameraAt(2), throwsA(isA<Exception>()));
});
});
}

View File

@@ -72,7 +72,7 @@ class TestHelper {
final packageUri = findPackageRoot('thermion_dart');
testDir = Directory("${packageUri.toFilePath()}/test").path;
var outDir = Directory("$testDir/output/${dir}");
outDir = Directory("$testDir/output/${dir}");
// outDir.deleteSync(recursive: true);
outDir.createSync();
}