add priority/layer to FFI viewer, use struct for model matrix, add createUbershaderMaterialInstance and destroyMaterialInstance

This commit is contained in:
Nick Fisher
2024-09-19 09:14:55 +08:00
parent 98cedf821c
commit 10b919e4f4

View File

@@ -506,17 +506,27 @@ class ThermionViewerFFI extends ThermionViewer {
/// ///
@override @override
Future<ThermionEntity> loadGlbFromBuffer(Uint8List data, Future<ThermionEntity> loadGlbFromBuffer(Uint8List data,
{bool unlit = false, int numInstances = 1, bool keepData = false}) async { {bool unlit = false,
int numInstances = 1,
bool keepData = false,
int priority = 4,
int layer = 0}) async {
if (unlit) { if (unlit) {
throw Exception("Not yet implemented"); throw Exception("Not yet implemented");
} }
if (layer < 0 || layer > 6) {
throw Exception("Layer must be between 0 and 6");
}
var entity = await withIntCallback((callback) => load_glb_from_buffer_ffi( var entity = await withIntCallback((callback) => load_glb_from_buffer_ffi(
_sceneManager!, _sceneManager!,
data.address, data.address,
data.length, data.length,
numInstances, numInstances,
keepData, keepData,
priority,
layer,
callback)); callback));
if (entity == _FILAMENT_ASSET_ERROR) { if (entity == _FILAMENT_ASSET_ERROR) {
@@ -1335,10 +1345,9 @@ class ThermionViewerFFI extends ThermionViewer {
@override @override
Future setCameraModelMatrix4(Matrix4 modelMatrix) async { Future setCameraModelMatrix4(Matrix4 modelMatrix) async {
var mainCamera = get_camera(_viewer!, await getMainCamera()); var mainCamera = get_camera(_viewer!, await getMainCamera());
final out = allocator<double4x4>(1); final out = Struct.create<double4x4>();
matrix4ToDouble4x4(modelMatrix, out.ref); matrix4ToDouble4x4(modelMatrix, out);
set_camera_model_matrix(mainCamera, out.ref); set_camera_model_matrix(mainCamera, out);
allocator.free(out);
} }
/// ///
@@ -1809,14 +1818,11 @@ class ThermionViewerFFI extends ThermionViewer {
/// ///
@override @override
Future<ThermionEntity> createGeometry(Geometry geometry, Future<ThermionEntity> createGeometry(Geometry geometry,
{bool keepData = false}) async { {MaterialInstance? materialInstance, bool keepData = false}) async {
if (_viewer == null) { if (_viewer == null) {
throw Exception("Viewer must not be null"); throw Exception("Viewer must not be null");
} }
final materialPathPtr =
geometry.materialPath?.toNativeUtf8(allocator: allocator) ?? nullptr;
var entity = await withIntCallback((callback) => create_geometry_ffi( var entity = await withIntCallback((callback) => create_geometry_ffi(
_sceneManager!, _sceneManager!,
geometry.vertices.address, geometry.vertices.address,
@@ -1828,7 +1834,9 @@ class ThermionViewerFFI extends ThermionViewer {
geometry.indices.address, geometry.indices.address,
geometry.indices.length, geometry.indices.length,
geometry.primitiveType.index, geometry.primitiveType.index,
materialPathPtr.cast<Char>(), materialInstance == null
? nullptr
: (materialInstance as ThermionFFIMaterialInstance)._pointer,
keepData, keepData,
callback)); callback));
if (entity == _FILAMENT_ASSET_ERROR) { if (entity == _FILAMENT_ASSET_ERROR) {
@@ -1991,9 +1999,109 @@ class ThermionViewerFFI extends ThermionViewer {
}); });
} }
///
///
///
Future destroyTexture(ThermionFFITexture texture) async { Future destroyTexture(ThermionFFITexture texture) async {
destroy_texture(_sceneManager!, texture._pointer); destroy_texture(_sceneManager!, texture._pointer);
} }
Future<MaterialInstance> createUbershaderMaterialInstance(
{bool doubleSided = false,
bool unlit = false,
bool hasVertexColors = false,
bool hasBaseColorTexture = false,
bool hasNormalTexture = false,
bool hasOcclusionTexture = false,
bool hasEmissiveTexture = false,
bool useSpecularGlossiness = false,
AlphaMode alphaMode = AlphaMode.OPAQUE,
bool enableDiagnostics = false,
bool hasMetallicRoughnessTexture = false,
int metallicRoughnessUV = 0,
int baseColorUV = 0,
bool hasClearCoatTexture = false,
int clearCoatUV = 0,
bool hasClearCoatRoughnessTexture = false,
int clearCoatRoughnessUV = 0,
bool hasClearCoatNormalTexture = false,
int clearCoatNormalUV = 0,
bool hasClearCoat = false,
bool hasTransmission = false,
bool hasTextureTransforms = false,
int emissiveUV = 0,
int aoUV = 0,
int normalUV = 0,
bool hasTransmissionTexture = false,
int transmissionUV = 0,
bool hasSheenColorTexture = false,
int sheenColorUV = 0,
bool hasSheenRoughnessTexture = false,
int sheenRoughnessUV = 0,
bool hasVolumeThicknessTexture = false,
int volumeThicknessUV = 0,
bool hasSheen = false,
bool hasIOR = false,
bool hasVolume = false}) async {
final key = Struct.create<TMaterialKey>();
// Set all the fields of the TMaterialKey struct
key.doubleSided = doubleSided;
key.unlit = unlit;
key.hasVertexColors = hasVertexColors;
key.hasBaseColorTexture = hasBaseColorTexture;
key.hasNormalTexture = hasNormalTexture;
key.hasOcclusionTexture = hasOcclusionTexture;
key.hasEmissiveTexture = hasEmissiveTexture;
key.useSpecularGlossiness = useSpecularGlossiness;
key.alphaMode = alphaMode.index;
key.enableDiagnostics = enableDiagnostics;
key.unnamed.unnamed.hasMetallicRoughnessTexture =
hasMetallicRoughnessTexture;
key.unnamed.unnamed.metallicRoughnessUV = metallicRoughnessUV;
key.baseColorUV = baseColorUV;
key.hasClearCoatTexture = hasClearCoatTexture;
key.clearCoatUV = clearCoatUV;
key.hasClearCoatRoughnessTexture = hasClearCoatRoughnessTexture;
key.clearCoatRoughnessUV = clearCoatRoughnessUV;
key.hasClearCoatNormalTexture = hasClearCoatNormalTexture;
key.clearCoatNormalUV = clearCoatNormalUV;
key.hasClearCoat = hasClearCoat;
key.hasTransmission = hasTransmission;
key.hasTextureTransforms = hasTextureTransforms;
key.emissiveUV = emissiveUV;
key.aoUV = aoUV;
key.normalUV = normalUV;
key.hasTransmissionTexture = hasTransmissionTexture;
key.transmissionUV = transmissionUV;
key.hasSheenColorTexture = hasSheenColorTexture;
key.sheenColorUV = sheenColorUV;
key.hasSheenRoughnessTexture = hasSheenRoughnessTexture;
key.sheenRoughnessUV = sheenRoughnessUV;
key.hasVolumeThicknessTexture = hasVolumeThicknessTexture;
key.volumeThicknessUV = volumeThicknessUV;
key.hasSheen = hasSheen;
key.hasIOR = hasIOR;
key.hasVolume = hasVolume;
// Assuming there's a method to create the MaterialInstance using the key
final materialInstance = create_material_instance(_sceneManager!, key);
if (materialInstance == nullptr) {
throw Exception("Failed to create material instance");
}
// Don't forget to free the memory allocated for the struct
return ThermionFFIMaterialInstance(materialInstance);
}
///
///
///
Future destroyMaterialInstance(
ThermionFFIMaterialInstance materialInstance) async {
destroy_material_instance(_viewer!, materialInstance._pointer);
}
} }
class ThermionFFITexture extends ThermionTexture { class ThermionFFITexture extends ThermionTexture {
@@ -2001,3 +2109,9 @@ class ThermionFFITexture extends ThermionTexture {
ThermionFFITexture(this._pointer); ThermionFFITexture(this._pointer);
} }
class ThermionFFIMaterialInstance extends MaterialInstance {
final Pointer<TMaterialInstance> _pointer;
ThermionFFIMaterialInstance(this._pointer);
}