From 40a7f86cef3205285ee8330f65f65f010d8766fe Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Thu, 19 Sep 2024 12:50:57 +0800 Subject: [PATCH] fixes for createMaterialInstance --- .../viewer/ffi/thermion_dart.g.dart | 15 +- .../viewer/ffi/thermion_viewer_ffi.dart | 8 +- thermion_dart/native/include/SceneManager.hpp | 8 +- .../native/include/ThermionDartApi.h | 3 +- thermion_dart/native/src/SceneManager.cpp | 26 +-- thermion_dart/native/src/ThermionDartApi.cpp | 173 ++++++++++++------ 6 files changed, 149 insertions(+), 84 deletions(-) diff --git a/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_dart.g.dart b/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_dart.g.dart index 4aa6fe9f..4e8176ec 100644 --- a/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_dart.g.dart +++ b/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_dart.g.dart @@ -16,6 +16,16 @@ external ffi.Pointer make_resource_loader( ffi.Pointer owner, ); +@ffi.Native< + ffi.Pointer Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer)>(isLeaf: true) +external ffi.Pointer create_filament_viewer( + ffi.Pointer context, + ffi.Pointer loader, + ffi.Pointer platform, + ffi.Pointer uberArchivePath, +); + @ffi.Native)>(isLeaf: true) external void destroy_filament_viewer( ffi.Pointer viewer, @@ -211,13 +221,14 @@ external int load_glb( @ffi.Native< EntityId Function(ffi.Pointer, ffi.Pointer, ffi.Size, - ffi.Bool, ffi.Int)>(isLeaf: true) + ffi.Bool, ffi.Int, ffi.Int)>(isLeaf: true) external int load_glb_from_buffer( ffi.Pointer sceneManager, ffi.Pointer data, int length, bool keepData, int priority, + int layer, ); @ffi.Native< @@ -418,7 +429,7 @@ external bool set_morph_animation( ffi.Pointer, TMaterialKey)>(isLeaf: true) external ffi.Pointer create_material_instance( ffi.Pointer sceneManager, - TMaterialKey key, + TMaterialKey materialConfig, ); @ffi.Native< diff --git a/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_viewer_ffi.dart b/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_viewer_ffi.dart index 56ba1161..a1ba8d29 100644 --- a/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_viewer_ffi.dart @@ -2045,7 +2045,6 @@ class ThermionViewerFFI extends ThermionViewer { bool hasVolume = false}) async { final key = Struct.create(); - // Set all the fields of the TMaterialKey struct key.doubleSided = doubleSided; key.unlit = unlit; key.hasVertexColors = hasVertexColors; @@ -2058,7 +2057,7 @@ class ThermionViewerFFI extends ThermionViewer { key.enableDiagnostics = enableDiagnostics; key.unnamed.unnamed.hasMetallicRoughnessTexture = hasMetallicRoughnessTexture; - key.unnamed.unnamed.metallicRoughnessUV = metallicRoughnessUV; + key.unnamed.unnamed.metallicRoughnessUV = 0; key.baseColorUV = baseColorUV; key.hasClearCoatTexture = hasClearCoatTexture; key.clearCoatUV = clearCoatUV; @@ -2084,14 +2083,11 @@ class ThermionViewerFFI extends ThermionViewer { 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); } @@ -2100,7 +2096,7 @@ class ThermionViewerFFI extends ThermionViewer { /// Future destroyMaterialInstance( ThermionFFIMaterialInstance materialInstance) async { - destroy_material_instance(_viewer!, materialInstance._pointer); + destroy_material_instance(_sceneManager!, materialInstance._pointer); } } diff --git a/thermion_dart/native/include/SceneManager.hpp b/thermion_dart/native/include/SceneManager.hpp index addfcc7f..8d958880 100644 --- a/thermion_dart/native/include/SceneManager.hpp +++ b/thermion_dart/native/include/SceneManager.hpp @@ -253,9 +253,6 @@ namespace thermion_filament bool keepData = false ); - MaterialInstance* createUbershaderInstance(TMaterialKey key); - void destroy(MaterialInstance* materialInstance); - friend class FilamentViewer; Gizmo* gizmo = nullptr; @@ -291,6 +288,11 @@ namespace thermion_filament void setMaterialProperty(EntityId entityId, int materialIndex, const char* property, filament::math::float4 value); MaterialInstance* createUbershaderMaterialInstance(MaterialKey key); + void destroy(MaterialInstance* materialInstance); + + gltfio::MaterialProvider* getUbershaderProvider() { + return _ubershaderProvider; + } private: gltfio::AssetLoader *_assetLoader = nullptr; diff --git a/thermion_dart/native/include/ThermionDartApi.h b/thermion_dart/native/include/ThermionDartApi.h index 1732be0e..35b09957 100644 --- a/thermion_dart/native/include/ThermionDartApi.h +++ b/thermion_dart/native/include/ThermionDartApi.h @@ -141,7 +141,8 @@ extern "C" int numMorphTargets, int numFrames, float frameLengthInMs); - EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_material_instance(void *const sceneManager, TMaterialKey key); + EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_material_instance(void *const sceneManager, TMaterialKey materialConfig); + EMSCRIPTEN_KEEPALIVE void destroy_material_instance(void *const sceneManager, TMaterialInstance *instance); EMSCRIPTEN_KEEPALIVE void clear_morph_animation( void *sceneManager, diff --git a/thermion_dart/native/src/SceneManager.cpp b/thermion_dart/native/src/SceneManager.cpp index 14579d41..2892ae62 100644 --- a/thermion_dart/native/src/SceneManager.cpp +++ b/thermion_dart/native/src/SceneManager.cpp @@ -2451,14 +2451,17 @@ EntityId SceneManager::createGeometry( filament::Material *mat = nullptr; - if (!materialInstance){ + if (!materialInstance) { + Log("Using default ubershader material"); filament::gltfio::MaterialKey config; - config.unlit = true; + memset(&config, 0, sizeof(config)); // Initialize all bits to zero + + config.unlit = false; config.doubleSided = false; config.useSpecularGlossiness = false; config.alphaMode = filament::gltfio::AlphaMode::OPAQUE; - config.hasBaseColorTexture = false; //uvs != nullptr; + config.hasBaseColorTexture = numUvs > 0; config.hasClearCoat = false; config.hasClearCoatNormalTexture = false; config.hasClearCoatRoughnessTexture = false; @@ -2479,18 +2482,13 @@ EntityId SceneManager::createGeometry( config.baseColorUV = 0; config.hasVertexColors = false; config.hasVolume = false; - - filament::gltfio::UvMap uvmap; - materialInstance = _ubershaderProvider->createMaterialInstance(&config, &uvmap); + materialInstance = createUbershaderMaterialInstance(config); if(!materialInstance) { Log("Failed to create material instance"); return Entity::smuggle(Entity()); } - - materialInstance->setParameter("baseColorFactor", RgbaType::sRGB, filament::math::float4{1.0f, 1.0f, 1.0f, 1.0f}); - materialInstance->setParameter("baseColorIndex", 0); } // Set up texture and sampler if UVs are available @@ -2575,15 +2573,17 @@ EntityId SceneManager::createGeometry( } MaterialInstance* SceneManager::createUbershaderMaterialInstance(filament::gltfio::MaterialKey config) { - - filament::gltfio::UvMap uvmap; + filament::gltfio::UvMap uvmap {}; auto * materialInstance = _ubershaderProvider->createMaterialInstance(&config, &uvmap); if(!materialInstance) { Log("Invalid material configuration"); + return nullptr; } - materialInstance->setParameter("baseColorFactor", RgbaType::sRGB, filament::math::float4{1.0f, 1.0f, 1.0f, 1.0f}); - materialInstance->setParameter("baseColorIndex", 0); + materialInstance->setParameter("baseColorFactor", RgbaType::sRGB, filament::math::float4{0.0f, 1.0f, 1.0f, 1.0f}); + materialInstance->setParameter("baseColorIndex", -1); return materialInstance; } + + } // namespace thermion_filament diff --git a/thermion_dart/native/src/ThermionDartApi.cpp b/thermion_dart/native/src/ThermionDartApi.cpp index f5ab7c2e..73ad329e 100644 --- a/thermion_dart/native/src/ThermionDartApi.cpp +++ b/thermion_dart/native/src/ThermionDartApi.cpp @@ -35,14 +35,13 @@ extern "C" } // Helper function to convert double4x4 to filament::math::mat4 - static filament::math::mat4 convert_double4x4_to_mat4(const double4x4& d_mat) + static filament::math::mat4 convert_double4x4_to_mat4(const double4x4 &d_mat) { return filament::math::mat4{ filament::math::float4{float(d_mat.col1[0]), float(d_mat.col1[1]), float(d_mat.col1[2]), float(d_mat.col1[3])}, filament::math::float4{float(d_mat.col2[0]), float(d_mat.col2[1]), float(d_mat.col2[2]), float(d_mat.col2[3])}, filament::math::float4{float(d_mat.col3[0]), float(d_mat.col3[1]), float(d_mat.col3[2]), float(d_mat.col3[3])}, - filament::math::float4{float(d_mat.col4[0]), float(d_mat.col4[1]), float(d_mat.col4[2]), float(d_mat.col4[3])} - }; + filament::math::float4{float(d_mat.col4[0]), float(d_mat.col4[1]), float(d_mat.col4[2]), float(d_mat.col4[3])}}; } EMSCRIPTEN_KEEPALIVE const void *create_filament_viewer(const void *context, const void *const loader, void *const platform, const char *uberArchivePath) @@ -178,9 +177,9 @@ extern "C" return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances, keepData); } - EMSCRIPTEN_KEEPALIVE EntityId load_glb_from_buffer(void *sceneManager, const void *const data, size_t length, bool keepData) + EMSCRIPTEN_KEEPALIVE EntityId load_glb_from_buffer(void *sceneManager, const void *const data, size_t length, bool keepData, int priority, int layer) { - return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, keepData); + return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, 1, keepData, priority, layer); } EMSCRIPTEN_KEEPALIVE EntityId create_instance(void *sceneManager, EntityId entityId) @@ -218,82 +217,84 @@ extern "C" return ((FilamentViewer *)viewer)->setCamera(asset, nodeName); } - EMSCRIPTEN_KEEPALIVE float get_camera_fov(CameraPtr* camera, bool horizontal) + EMSCRIPTEN_KEEPALIVE float get_camera_fov(CameraPtr *camera, bool horizontal) { - auto cam = reinterpret_cast(camera); + auto cam = reinterpret_cast(camera); return cam->getFieldOfViewInDegrees(horizontal ? Camera::Fov::HORIZONTAL : Camera::Fov::VERTICAL); } - EMSCRIPTEN_KEEPALIVE double get_camera_focal_length(CameraPtr* const camera) { - auto cam = reinterpret_cast(camera); + EMSCRIPTEN_KEEPALIVE double get_camera_focal_length(CameraPtr *const camera) + { + auto cam = reinterpret_cast(camera); return cam->getFocalLength(); } - EMSCRIPTEN_KEEPALIVE void set_camera_projection_from_fov(CameraPtr* camera, double fovInDegrees, double aspect, double near, double far, bool horizontal) + EMSCRIPTEN_KEEPALIVE void set_camera_projection_from_fov(CameraPtr *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal) { - auto cam = reinterpret_cast(camera); + auto cam = reinterpret_cast(camera); cam->setProjection(fovInDegrees, aspect, near, far, horizontal ? Camera::Fov::HORIZONTAL : Camera::Fov::VERTICAL); } - EMSCRIPTEN_KEEPALIVE CameraPtr* get_camera(const void *const viewer, EntityId entity) { - auto filamentCamera = ((FilamentViewer*)viewer)->getCamera(entity); - return reinterpret_cast(filamentCamera); + EMSCRIPTEN_KEEPALIVE CameraPtr *get_camera(const void *const viewer, EntityId entity) + { + auto filamentCamera = ((FilamentViewer *)viewer)->getCamera(entity); + return reinterpret_cast(filamentCamera); } - double4x4 get_camera_model_matrix(CameraPtr* camera) + double4x4 get_camera_model_matrix(CameraPtr *camera) { - const auto &mat = reinterpret_cast(camera)->getModelMatrix(); + const auto &mat = reinterpret_cast(camera)->getModelMatrix(); return convert_mat4_to_double4x4(mat); } - double4x4 get_camera_view_matrix(CameraPtr* camera) + double4x4 get_camera_view_matrix(CameraPtr *camera) { - const auto &mat = reinterpret_cast(camera)->getViewMatrix(); + const auto &mat = reinterpret_cast(camera)->getViewMatrix(); return convert_mat4_to_double4x4(mat); } - double4x4 get_camera_projection_matrix(CameraPtr* camera) + double4x4 get_camera_projection_matrix(CameraPtr *camera) { - const auto &mat = reinterpret_cast(camera)->getProjectionMatrix(); + const auto &mat = reinterpret_cast(camera)->getProjectionMatrix(); return convert_mat4_to_double4x4(mat); } - double4x4 get_camera_culling_projection_matrix(CameraPtr* camera) + double4x4 get_camera_culling_projection_matrix(CameraPtr *camera) { - const auto &mat = reinterpret_cast(camera)->getCullingProjectionMatrix(); + const auto &mat = reinterpret_cast(camera)->getCullingProjectionMatrix(); return convert_mat4_to_double4x4(mat); } - void set_camera_projection_matrix(CameraPtr* camera, double4x4 matrix, double near, double far) + void set_camera_projection_matrix(CameraPtr *camera, double4x4 matrix, double near, double far) { - auto cam = reinterpret_cast(camera); - const auto& mat = convert_double4x4_to_mat4(matrix); + auto cam = reinterpret_cast(camera); + const auto &mat = convert_double4x4_to_mat4(matrix); cam->setCustomProjection(mat, near, far); } - void set_camera_lens_projection(CameraPtr* camera, double near, double far, double aspect, double focalLength) + void set_camera_lens_projection(CameraPtr *camera, double near, double far, double aspect, double focalLength) { - auto cam = reinterpret_cast(camera); + auto cam = reinterpret_cast(camera); cam->setLensProjection(focalLength, aspect, near, far); } - double get_camera_near(CameraPtr* camera) + double get_camera_near(CameraPtr *camera) { - auto cam = reinterpret_cast(camera); + auto cam = reinterpret_cast(camera); return cam->getNear(); } - double get_camera_culling_far(CameraPtr* camera) + double get_camera_culling_far(CameraPtr *camera) { - auto cam = reinterpret_cast(camera); + auto cam = reinterpret_cast(camera); return cam->getCullingFar(); } - const double *const get_camera_frustum(CameraPtr* camera) + const double *const get_camera_frustum(CameraPtr *camera) { - - const auto frustum = reinterpret_cast(camera)->getFrustum(); - + + const auto frustum = reinterpret_cast(camera)->getFrustum(); + const math::float4 *planes = frustum.getNormalizedPlanes(); double *array = (double *)calloc(24, sizeof(double)); for (int i = 0; i < 6; i++) @@ -318,22 +319,22 @@ extern "C" ((FilamentViewer *)viewer)->setViewFrustumCulling(enabled); } - EMSCRIPTEN_KEEPALIVE void set_camera_focus_distance(CameraPtr* camera, float distance) + EMSCRIPTEN_KEEPALIVE void set_camera_focus_distance(CameraPtr *camera, float distance) { - auto * cam = reinterpret_cast(camera); + auto *cam = reinterpret_cast(camera); cam->setFocusDistance(distance); } - EMSCRIPTEN_KEEPALIVE void set_camera_exposure(CameraPtr* camera, float aperture, float shutterSpeed, float sensitivity) + EMSCRIPTEN_KEEPALIVE void set_camera_exposure(CameraPtr *camera, float aperture, float shutterSpeed, float sensitivity) { - auto * cam = reinterpret_cast(camera); + auto *cam = reinterpret_cast(camera); cam->setExposure(aperture, shutterSpeed, sensitivity); } - EMSCRIPTEN_KEEPALIVE void set_camera_model_matrix(CameraPtr* camera, double4x4 matrix) + EMSCRIPTEN_KEEPALIVE void set_camera_model_matrix(CameraPtr *camera, double4x4 matrix) { - auto * cam = reinterpret_cast(camera); - const filament::math::mat4& mat = convert_double4x4_to_mat4(matrix); + auto *cam = reinterpret_cast(camera); + const filament::math::mat4 &mat = convert_double4x4_to_mat4(matrix); cam->setModelMatrix(mat); } @@ -352,11 +353,11 @@ extern "C" uint8_t *pixelBuffer, void (*callback)(void)) { - #ifdef __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ bool useFence = true; - #else +#else bool useFence = false; - #endif +#endif ((FilamentViewer *)viewer)->capture(pixelBuffer, useFence, callback); }; @@ -855,10 +856,21 @@ extern "C" ((SceneManager *)sceneManager)->removeAnimationComponent(entityId); } - - EMSCRIPTEN_KEEPALIVE EntityId create_geometry(void *const sceneManager, float *vertices, int numVertices, float *normals, int numNormals, float *uvs, int numUvs, uint16_t *indices, int numIndices, int primitiveType, const char *materialPath) + EMSCRIPTEN_KEEPALIVE EntityId create_geometry( + void *const sceneManager, + float *vertices, + int numVertices, + float *normals, + int numNormals, + float *uvs, + int numUvs, + uint16_t *indices, + int numIndices, + int primitiveType, + TMaterialInstance *materialInstance, + bool keepData) { - return ((SceneManager *)sceneManager)->createGeometry(vertices, (uint32_t)numVertices, normals, (uint32_t)numNormals, uvs, numUvs, indices, numIndices, (filament::RenderableManager::PrimitiveType)primitiveType, materialPath); + return ((SceneManager *)sceneManager)->createGeometry(vertices, (uint32_t)numVertices, normals, (uint32_t)numNormals, uvs, numUvs, indices, numIndices, (filament::RenderableManager::PrimitiveType)primitiveType, reinterpret_cast(materialInstance), keepData); } EMSCRIPTEN_KEEPALIVE EntityId find_child_entity_by_name(void *const sceneManager, const EntityId parent, const char *name) @@ -945,30 +957,73 @@ extern "C" ((SceneManager *)sceneManager)->removeStencilHighlight(entityId); } - EMSCRIPTEN_KEEPALIVE void set_material_property_float(void *const sceneManager, EntityId entity, int materialIndex, const char* property, float value) { + EMSCRIPTEN_KEEPALIVE void set_material_property_float(void *const sceneManager, EntityId entity, int materialIndex, const char *property, float value) + { ((SceneManager *)sceneManager)->setMaterialProperty(entity, materialIndex, property, value); } - - EMSCRIPTEN_KEEPALIVE void set_material_property_float4(void *const sceneManager, EntityId entity, int materialIndex, const char* property, float4 value) { - filament::math::float4 filamentValue { value.x, value.y, value.z, value.w }; + + EMSCRIPTEN_KEEPALIVE void set_material_property_float4(void *const sceneManager, EntityId entity, int materialIndex, const char *property, float4 value) + { + filament::math::float4 filamentValue{value.x, value.y, value.z, value.w}; ((SceneManager *)sceneManager)->setMaterialProperty(entity, materialIndex, property, filamentValue); } - EMSCRIPTEN_KEEPALIVE void unproject_texture(void *const viewer, EntityId entity, uint8_t* out, uint32_t outWidth, uint32_t outHeight) { + EMSCRIPTEN_KEEPALIVE void unproject_texture(void *const viewer, EntityId entity, uint8_t *out, uint32_t outWidth, uint32_t outHeight) + { ((FilamentViewer *)viewer)->unprojectTexture(entity, out, outWidth, outHeight); } - EMSCRIPTEN_KEEPALIVE void* const create_texture(void *const sceneManager, uint8_t* data, size_t length) { - return (void* const) ((SceneManager *)sceneManager)->createTexture(data, length, "SOMETEXTURE"); + EMSCRIPTEN_KEEPALIVE void *const create_texture(void *const sceneManager, uint8_t *data, size_t length) + { + return (void *const)((SceneManager *)sceneManager)->createTexture(data, length, "SOMETEXTURE"); } - EMSCRIPTEN_KEEPALIVE void apply_texture_to_material(void *const sceneManager, EntityId entity, void* const texture, const char* parameterName, int materialIndex) { - ((SceneManager*)sceneManager)->applyTexture(entity, reinterpret_cast(texture), parameterName, materialIndex); + EMSCRIPTEN_KEEPALIVE void apply_texture_to_material(void *const sceneManager, EntityId entity, void *const texture, const char *parameterName, int materialIndex) + { + ((SceneManager *)sceneManager)->applyTexture(entity, reinterpret_cast(texture), parameterName, materialIndex); } - EMSCRIPTEN_KEEPALIVE void destroy_texture(void *const sceneManager, void* const texture) { - ((SceneManager*)sceneManager)->destroyTexture(reinterpret_cast(texture)); + EMSCRIPTEN_KEEPALIVE void destroy_texture(void *const sceneManager, void *const texture) + { + ((SceneManager *)sceneManager)->destroyTexture(reinterpret_cast(texture)); } + EMSCRIPTEN_KEEPALIVE TMaterialInstance* create_material_instance(void *const sceneManager, TMaterialKey materialConfig) +{ + + filament::gltfio::MaterialKey config; + memset(&config, 0, sizeof(MaterialKey)); + + // Set and log each field + config.unlit = materialConfig.unlit; + config.doubleSided = materialConfig.doubleSided; + config.useSpecularGlossiness = materialConfig.useSpecularGlossiness; + config.alphaMode = static_cast(materialConfig.alphaMode); + config.hasBaseColorTexture = materialConfig.hasBaseColorTexture; + config.hasClearCoat = materialConfig.hasClearCoat; + config.hasClearCoatNormalTexture = materialConfig.hasClearCoatNormalTexture; + config.hasClearCoatRoughnessTexture = materialConfig.hasClearCoatRoughnessTexture; + config.hasEmissiveTexture = materialConfig.hasEmissiveTexture; + config.hasIOR = materialConfig.hasIOR; + config.hasMetallicRoughnessTexture = materialConfig.hasMetallicRoughnessTexture; + config.hasNormalTexture = materialConfig.hasNormalTexture; + config.hasOcclusionTexture = materialConfig.hasOcclusionTexture; + config.hasSheen = materialConfig.hasSheen; + config.hasSheenColorTexture = materialConfig.hasSheenColorTexture; + config.hasSheenRoughnessTexture = materialConfig.hasSheenRoughnessTexture; + config.hasTextureTransforms = materialConfig.hasTextureTransforms; + config.hasTransmission = materialConfig.hasTransmission; + config.hasTransmissionTexture = materialConfig.hasTransmissionTexture; + config.hasVolume = materialConfig.hasVolume; + config.hasVolumeThicknessTexture = materialConfig.hasVolumeThicknessTexture; + config.baseColorUV = materialConfig.baseColorUV; + config.hasVertexColors = materialConfig.hasVertexColors; + auto materialInstance = ((SceneManager *)sceneManager)->createUbershaderMaterialInstance(config); + return reinterpret_cast(materialInstance); +} + +EMSCRIPTEN_KEEPALIVE void destroy_material_instance(void *const sceneManager, TMaterialInstance *instance) { + ((SceneManager *)sceneManager)->destroy(reinterpret_cast(instance)); +} }