diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_material.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_material.dart index 0851da7b..82a1cfaf 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_material.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_material.dart @@ -1,6 +1,9 @@ +import 'dart:typed_data'; + import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart'; import 'package:thermion_dart/thermion_dart.dart'; +import 'package:vector_math/vector_math_64.dart'; class FFIMaterial extends Material { final Pointer engine; @@ -51,10 +54,9 @@ class FFIMaterialInstance extends MaterialInstance { } @override - Future setParameterFloat4( - String name, double x, double y, double z, double w) async { - MaterialInstance_setParameterFloat4( - pointer, name.toNativeUtf8().cast(), x, y, z, w); + Future setParameterFloat(String name, double value) async { + MaterialInstance_setParameterFloat( + pointer, name.toNativeUtf8().cast(), value); } @override @@ -64,9 +66,32 @@ class FFIMaterialInstance extends MaterialInstance { } @override - Future setParameterFloat(String name, double value) async { - MaterialInstance_setParameterFloat( - pointer, name.toNativeUtf8().cast(), value); + Future setParameterFloat3(String name, double x, double y, double z) async { + MaterialInstance_setParameterFloat3( + pointer, name.toNativeUtf8().cast(), x, y, z); + } + + @override + Future setParameterFloat3Array(String name, List array) async { + final ptr = name.toNativeUtf8(allocator: calloc).cast(); + final data = Float64List(array.length * 3); + int i = 0; + for (final item in array) { + data[i] = item.x; + data[i + 1] = item.y; + data[i + 2] = item.z; + i += 3; + } + MaterialInstance_setParameterFloat3Array( + pointer, ptr, data.address, array.length * 3); + calloc.free(ptr); + } + + @override + Future setParameterFloat4( + String name, double x, double y, double z, double w) async { + MaterialInstance_setParameterFloat4( + pointer, name.toNativeUtf8().cast(), x, y, z, w); } @override diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_texture.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_texture.dart index 3bd20c76..5dbba1c5 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_texture.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_texture.dart @@ -112,12 +112,33 @@ class FFITexture extends Texture { int zOffset, int width, int height, + int channels, int depth, Uint8List buffer, PixelDataFormat format, - PixelDataType type) { - // TODO: implement setImage3D - throw UnimplementedError(); + PixelDataType type) async { + final success = await withBoolCallback((cb) { + Texture_setImageWithDepthRenderThread( + _engine, + pointer, + level, + buffer.address, + buffer.lengthInBytes, + 0, + 0, + zOffset, + width, + height, + channels, + depth, + format.index, + type.index, + cb); + }); + + if (!success) { + throw Exception("Failed to set image"); + } } @override diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart index 7dd34bff..19315ca5 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart @@ -64,14 +64,11 @@ external void MaterialInstance_setDepthCulling( @ffi.Native< ffi.Void Function(ffi.Pointer, ffi.Pointer, - ffi.Double, ffi.Double, ffi.Double, ffi.Double)>(isLeaf: true) -external void MaterialInstance_setParameterFloat4( + ffi.Double)>(isLeaf: true) +external void MaterialInstance_setParameterFloat( ffi.Pointer materialInstance, ffi.Pointer propertyName, - double x, - double y, - double w, - double z, + double value, ); @ffi.Native< @@ -86,11 +83,35 @@ external void MaterialInstance_setParameterFloat2( @ffi.Native< ffi.Void Function(ffi.Pointer, ffi.Pointer, - ffi.Double)>(isLeaf: true) -external void MaterialInstance_setParameterFloat( + ffi.Double, ffi.Double, ffi.Double)>(isLeaf: true) +external void MaterialInstance_setParameterFloat3( ffi.Pointer materialInstance, ffi.Pointer propertyName, - double value, + double x, + double y, + double z, +); + +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Uint32)>(isLeaf: true) +external void MaterialInstance_setParameterFloat3Array( + ffi.Pointer tMaterialInstance, + ffi.Pointer propertyName, + ffi.Pointer raw, + int length, +); + +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Pointer, + ffi.Double, ffi.Double, ffi.Double, ffi.Double)>(isLeaf: true) +external void MaterialInstance_setParameterFloat4( + ffi.Pointer materialInstance, + ffi.Pointer propertyName, + double x, + double y, + double w, + double z, ); @ffi.Native< @@ -912,6 +933,39 @@ external bool Texture_setImage( int pixelDataType, ); +@ffi.Native< + ffi.Bool Function( + ffi.Pointer, + ffi.Pointer, + ffi.Uint32, + ffi.Pointer, + ffi.Size, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32)>(isLeaf: true) +external bool Texture_setImageWithDepth( + ffi.Pointer tEngine, + ffi.Pointer tTexture, + int level, + ffi.Pointer data, + int size, + int x_offset, + int y_offset, + int z_offset, + int width, + int height, + int channels, + int depth, + int bufferFormat, + int pixelDataType, +); + @ffi.Native< ffi.Pointer Function( ffi.Uint32, ffi.Uint32, ffi.Uint32)>(isLeaf: true) @@ -1634,6 +1688,7 @@ external void Engine_destroyMaterialRenderThread( ffi.Pointer, ffi.Uint32, ffi.Uint32, + ffi.Uint32, ffi.Uint8, ffi.UnsignedInt, ffi.UnsignedInt, @@ -1644,6 +1699,7 @@ external void _Engine_buildTextureRenderThread( ffi.Pointer engine, int width, int height, + int depth, int levels, int sampler, int format, @@ -1655,6 +1711,7 @@ void Engine_buildTextureRenderThread( ffi.Pointer engine, int width, int height, + int depth, int levels, TTextureSamplerType sampler, TTextureFormat format, @@ -1665,6 +1722,7 @@ void Engine_buildTextureRenderThread( engine, width, height, + depth, levels, sampler.value, format.value, @@ -2267,6 +2325,42 @@ external void Texture_setImageRenderThread( ffi.Pointer> onComplete, ); +@ffi.Native< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Uint32, + ffi.Pointer, + ffi.Size, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Uint32, + ffi.Pointer>)>( + isLeaf: true) +external void Texture_setImageWithDepthRenderThread( + ffi.Pointer tEngine, + ffi.Pointer tTexture, + int level, + ffi.Pointer data, + int size, + int x_offset, + int y_offset, + int z_offset, + int width, + int height, + int channels, + int depth, + int bufferFormat, + int pixelDataType, + ffi.Pointer> onComplete, +); + @ffi.Native< ffi.Void Function( ffi.Pointer, @@ -3007,6 +3101,7 @@ external ffi.Pointer Engine_getEntityManager( ffi.Pointer, ffi.Uint32, ffi.Uint32, + ffi.Uint32, ffi.Uint8, ffi.UnsignedInt, ffi.UnsignedInt)>(symbol: "Engine_buildTexture", isLeaf: true) @@ -3014,6 +3109,7 @@ external ffi.Pointer _Engine_buildTexture( ffi.Pointer engine, int width, int height, + int depth, int levels, int sampler, int format, @@ -3023,6 +3119,7 @@ ffi.Pointer Engine_buildTexture( ffi.Pointer engine, int width, int height, + int depth, int levels, TTextureSamplerType sampler, TTextureFormat format, @@ -3031,6 +3128,7 @@ ffi.Pointer Engine_buildTexture( engine, width, height, + depth, levels, sampler.value, format.value, @@ -3808,20 +3906,22 @@ typedef DartPickCallbackFunction = void Function( enum TTextureSamplerType { SAMPLER_2D(0), - SAMPLER_CUBEMAP(1), - SAMPLER_EXTERNAL(2), - SAMPLER_3D(3), - SAMPLER_2D_ARRAY(4); + SAMPLER_2D_ARRAY(1), + SAMPLER_CUBEMAP(2), + SAMPLER_EXTERNAL(3), + SAMPLER_3D(4), + SAMPLER_CUBEMAP_ARRAY(5); final int value; const TTextureSamplerType(this.value); static TTextureSamplerType fromValue(int value) => switch (value) { 0 => SAMPLER_2D, - 1 => SAMPLER_CUBEMAP, - 2 => SAMPLER_EXTERNAL, - 3 => SAMPLER_3D, - 4 => SAMPLER_2D_ARRAY, + 1 => SAMPLER_2D_ARRAY, + 2 => SAMPLER_CUBEMAP, + 3 => SAMPLER_EXTERNAL, + 4 => SAMPLER_3D, + 5 => SAMPLER_CUBEMAP_ARRAY, _ => throw ArgumentError("Unknown value for TTextureSamplerType: $value"), }; diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart index 8d8ca69c..7b7c3379 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart @@ -1830,7 +1830,7 @@ class ThermionViewerFFI extends ThermionViewer { /// /// Future createTexture(int width, int height, - {int levels = 1, + {int depth = 1, int levels = 1, TextureSamplerType textureSamplerType = TextureSamplerType.SAMPLER_2D, TextureFormat textureFormat = TextureFormat.RGBA16F}) async { final texturePtr = await withPointerCallback((cb) { @@ -1838,6 +1838,7 @@ class ThermionViewerFFI extends ThermionViewer { _engine!, width, height, + depth, levels, TTextureSamplerType.values[textureSamplerType.index], TTextureFormat.values[textureFormat.index], diff --git a/thermion_dart/lib/src/viewer/src/shared_types/geometry.dart b/thermion_dart/lib/src/viewer/src/shared_types/geometry.dart index 993718f4..05c2fb26 100644 --- a/thermion_dart/lib/src/viewer/src/shared_types/geometry.dart +++ b/thermion_dart/lib/src/viewer/src/shared_types/geometry.dart @@ -18,7 +18,7 @@ class Geometry { }) : indices = Uint16List.fromList(indices), normals = normals ?? Float32List(0), uvs = uvs ?? Float32List(0) { - assert(this.uvs.length == 0 || this.uvs.length == (vertices.length ~/ 3) * 2); + assert(this.uvs.length == 0 || this.uvs.length == (vertices.length ~/ 3 * 2), "Expected either zero or ${indices.length * 2} UVs, got ${this.uvs.length}"); } void scale(double factor) { diff --git a/thermion_dart/lib/src/viewer/src/shared_types/material.dart b/thermion_dart/lib/src/viewer/src/shared_types/material.dart index d2c00195..8b65308e 100644 --- a/thermion_dart/lib/src/viewer/src/shared_types/material.dart +++ b/thermion_dart/lib/src/viewer/src/shared_types/material.dart @@ -1,4 +1,7 @@ +import 'dart:typed_data'; + import 'package:thermion_dart/thermion_dart.dart'; +import 'package:vector_math/vector_math_64.dart'; enum SamplerCompareFunction { /// !< Less or equal @@ -102,10 +105,13 @@ abstract class MaterialInstance { Future setDepthWriteEnabled(bool enabled); Future setDepthFunc(SamplerCompareFunction depthFunc); Future setDepthCullingEnabled(bool enabled); + Future setParameterFloat(String name, double x); + Future setParameterFloat2(String name, double x, double y); + Future setParameterFloat3(String name, double x, double y, double z); + Future setParameterFloat3Array(String name, List data); Future setParameterFloat4( String name, double x, double y, double z, double w); - Future setParameterFloat2(String name, double x, double y); - Future setParameterFloat(String name, double x); + Future setParameterInt(String name, int value); Future setParameterBool(String name, bool value); Future setParameterTexture( diff --git a/thermion_dart/lib/src/viewer/src/shared_types/texture.dart b/thermion_dart/lib/src/viewer/src/shared_types/texture.dart index 08c4a133..e021f56e 100644 --- a/thermion_dart/lib/src/viewer/src/shared_types/texture.dart +++ b/thermion_dart/lib/src/viewer/src/shared_types/texture.dart @@ -1,24 +1,13 @@ import 'dart:typed_data'; -import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart'; -import 'package:thermion_dart/thermion_dart.dart'; - /// Defines the type of sampler to use with a texture enum TextureSamplerType { - /// 2D texture SAMPLER_2D, - - /// Cubemap texture + SAMPLER_2D_ARRAY, SAMPLER_CUBEMAP, - - /// External texture (video/camera) SAMPLER_EXTERNAL, - - /// 3D texture SAMPLER_3D, - - /// 2D array texture - SAMPLER_2D_ARRAY + SAMPLER_CUBEMAP_ARRAY } /// Defines internal texture formats @@ -306,7 +295,7 @@ abstract class Texture { covariant LinearImage image, PixelDataFormat format, PixelDataType type); /// Sets the image data for a 2D texture or a texture level - Future setImage(int level, Uint8List buffer, int width, int height, + Future setImage(int level, Uint8List buffer, int width, int height, int channels, PixelDataFormat format, PixelDataType type); /// Sets the image data for a region of a 2D texture @@ -321,6 +310,7 @@ abstract class Texture { int zOffset, int width, int height, + int channels, int depth, Uint8List buffer, PixelDataFormat format, diff --git a/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart b/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart index 3f69bfab..d9fdb603 100644 --- a/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart +++ b/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart @@ -776,7 +776,7 @@ abstract class ThermionViewer { /// /// Future createTexture(int width, int height, - {TextureSamplerType textureSamplerType = TextureSamplerType.SAMPLER_2D, + {int depth = 1, int levels = 1, TextureSamplerType textureSamplerType = TextureSamplerType.SAMPLER_2D, TextureFormat textureFormat = TextureFormat.RGBA32F}); /// diff --git a/thermion_dart/native/include/c_api/TEngine.h b/thermion_dart/native/include/c_api/TEngine.h index b2e9c7d0..23728311 100644 --- a/thermion_dart/native/include/c_api/TEngine.h +++ b/thermion_dart/native/include/c_api/TEngine.h @@ -23,6 +23,7 @@ EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine); EMSCRIPTEN_KEEPALIVE TTexture *Engine_buildTexture(TEngine *engine, uint32_t width, uint32_t height, + uint32_t depth, uint8_t levels, TTextureSamplerType sampler, TTextureFormat format); diff --git a/thermion_dart/native/include/c_api/TMaterialInstance.h b/thermion_dart/native/include/c_api/TMaterialInstance.h index 85d2d8a8..0dd620a5 100644 --- a/thermion_dart/native/include/c_api/TMaterialInstance.h +++ b/thermion_dart/native/include/c_api/TMaterialInstance.h @@ -75,9 +75,11 @@ extern "C" EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance *materialInstance, bool enabled); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance *materialInstance, bool enabled); - EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance *materialInstance, const char *propertyName, double x, double y, double w, double z); - EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance *materialInstance, const char *propertyName, double x, double y); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance *materialInstance, const char *propertyName, double value); + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance *materialInstance, const char *propertyName, double x, double y); + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat3(TMaterialInstance *materialInstance, const char *propertyName, double x, double y, double z); + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat3Array(TMaterialInstance *tMaterialInstance, const char *propertyName, double *raw, uint32_t length); + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance *materialInstance, const char *propertyName, double x, double y, double w, double z); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance *materialInstance, const char *propertyName, int value); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterBool(TMaterialInstance *materialInstance, const char *propertyName, bool value); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterTexture(TMaterialInstance *materialInstance, const char *propertyName, TTexture *texture, TTextureSampler *sampler); diff --git a/thermion_dart/native/include/c_api/TTexture.h b/thermion_dart/native/include/c_api/TTexture.h index 9dbf3e0d..ae74f1ef 100644 --- a/thermion_dart/native/include/c_api/TTexture.h +++ b/thermion_dart/native/include/c_api/TTexture.h @@ -15,11 +15,12 @@ extern "C" enum TTextureSamplerType { - SAMPLER_2D = 0, // 2D texture - SAMPLER_CUBEMAP, // Cubemap texture - SAMPLER_EXTERNAL, // External texture (video/camera) - SAMPLER_3D, // 3D texture - SAMPLER_2D_ARRAY // 2D array texture + SAMPLER_2D = 0, + SAMPLER_2D_ARRAY = 1, + SAMPLER_CUBEMAP=2, + SAMPLER_EXTERNAL=3, + SAMPLER_3D=4, + SAMPLER_CUBEMAP_ARRAY=5 }; enum TTextureFormat @@ -204,6 +205,22 @@ EMSCRIPTEN_KEEPALIVE bool Texture_setImage( uint32_t bufferFormat, uint32_t pixelDataType ); +EMSCRIPTEN_KEEPALIVE bool Texture_setImageWithDepth( + TEngine *tEngine, + TTexture *tTexture, + uint32_t level, + uint8_t *data, + size_t size, + uint32_t x_offset, + uint32_t y_offset, + uint32_t z_offset, + uint32_t width, + uint32_t height, + uint32_t channels, + uint32_t depth, + uint32_t bufferFormat, + uint32_t pixelDataType +); EMSCRIPTEN_KEEPALIVE TLinearImage *Image_createEmpty(uint32_t width,uint32_t height,uint32_t channel); EMSCRIPTEN_KEEPALIVE TLinearImage *Image_decode(uint8_t* data, size_t length, const char* name = "image"); EMSCRIPTEN_KEEPALIVE float *Image_getBytes(TLinearImage *tLinearImage); diff --git a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h index 1d690728..4a488f59 100644 --- a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h +++ b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h @@ -53,6 +53,7 @@ namespace thermion EMSCRIPTEN_KEEPALIVE void Engine_buildTextureRenderThread(TEngine *engine, uint32_t width, uint32_t height, + uint32_t depth, uint8_t levels, TTextureSamplerType sampler, TTextureFormat format, @@ -169,6 +170,23 @@ namespace thermion uint32_t pixelDataType, void (*onComplete)(bool) ); + EMSCRIPTEN_KEEPALIVE void Texture_setImageWithDepthRenderThread( + TEngine *tEngine, + TTexture *tTexture, + uint32_t level, + uint8_t *data, + size_t size, + uint32_t x_offset, + uint32_t y_offset, + uint32_t z_offset, + uint32_t width, + uint32_t height, + uint32_t channels, + uint32_t depth, + uint32_t bufferFormat, + uint32_t pixelDataType, + void (*onComplete)(bool) + ); EMSCRIPTEN_KEEPALIVE void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *)); // TextureSampler methods diff --git a/thermion_dart/native/src/c_api/TEngine.cpp b/thermion_dart/native/src/c_api/TEngine.cpp index 8c42a0d2..46de1e9a 100644 --- a/thermion_dart/native/src/c_api/TEngine.cpp +++ b/thermion_dart/native/src/c_api/TEngine.cpp @@ -226,21 +226,29 @@ namespace thermion EMSCRIPTEN_KEEPALIVE TTexture *Engine_buildTexture(TEngine *tEngine, uint32_t width, uint32_t height, + uint32_t depth, uint8_t levels, TTextureSamplerType tSamplerType, TTextureFormat tFormat) { + TRACE("Creating texture %dx%d (depth %d), sampler type %d, format %d", width, height, depth, static_cast(tSamplerType), static_cast(tFormat)); auto *engine = reinterpret_cast(tEngine); auto format = convertToFilamentFormat(tFormat); auto samplerType = static_cast<::filament::Texture::Sampler>(static_cast(tSamplerType)); auto *texture = Texture::Builder() .width(width) .height(height) + .depth(depth) .levels(levels) .sampler(samplerType) .format(format) .build(*engine); - Log("Created texture %d x %d, format %d", texture->getWidth(), texture->getHeight(), texture->getFormat()); + if(texture) { + TRACE("Texture successfully created"); + } else { + Log("Error: failed to created texture"); + } + return reinterpret_cast(texture); } diff --git a/thermion_dart/native/src/c_api/TMaterialInstance.cpp b/thermion_dart/native/src/c_api/TMaterialInstance.cpp index d364dbac..aef8c8e2 100644 --- a/thermion_dart/native/src/c_api/TMaterialInstance.cpp +++ b/thermion_dart/native/src/c_api/TMaterialInstance.cpp @@ -1,3 +1,5 @@ +#include + #include #include #include @@ -41,11 +43,11 @@ namespace thermion reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setDepthCulling(enabled); } - EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance *tMaterialInstance, const char *propertyName, double x, double y, double z, double w) + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance *tMaterialInstance, const char *propertyName, double value) { auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance); - filament::math::float4 data{static_cast(x), static_cast(y), static_cast(z), static_cast(w)}; - materialInstance->setParameter(propertyName, data); + auto fValue = static_cast(value); + materialInstance->setParameter(propertyName, fValue); } EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance *materialInstance, const char *propertyName, double x, double y) @@ -54,16 +56,36 @@ namespace thermion reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setParameter(propertyName, data); } - EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance *tMaterialInstance, const char *propertyName, double value) + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat3(TMaterialInstance *materialInstance, const char *propertyName, double x, double y, double z) { - auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance); - auto fValue = static_cast(value); - materialInstance->setParameter(propertyName, fValue); + filament::math::float3 data{static_cast(x), static_cast(y), static_cast(z) }; + reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setParameter(propertyName, data); } - EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance *materialInstance, const char *propertyName, int value) + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat3Array(TMaterialInstance *tMaterialInstance, const char *propertyName, double* raw, uint32_t length) { + TRACE("Setting property %s to array from raw length %d", propertyName, length); + + std::vector data; + + for(int i = 0; i < length; i+=3) { + // TRACE("Vector %f %f %f", static_cast(raw[i]), static_cast(raw[i+1]), static_cast(raw[i+2])); + data.push_back(filament::math::float3 { static_cast(raw[i]), static_cast(raw[i+1]), static_cast(raw[i+2]) }); + } + auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance); + materialInstance->setParameter(propertyName, data.data(), data.size()); + } + + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance *tMaterialInstance, const char *propertyName, double x, double y, double z, double w) { - reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setParameter(propertyName, value); + auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance); + filament::math::float4 data{static_cast(x), static_cast(y), static_cast(z), static_cast(w)}; + materialInstance->setParameter(propertyName, data); + } + + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance *tMaterialInstance, const char *propertyName, int value) + { + auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance); + materialInstance->setParameter(propertyName, value); } EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterBool(TMaterialInstance *materialInstance, const char *propertyName, bool value) diff --git a/thermion_dart/native/src/c_api/TTexture.cpp b/thermion_dart/native/src/c_api/TTexture.cpp index b36b208f..2612e793 100644 --- a/thermion_dart/native/src/c_api/TTexture.cpp +++ b/thermion_dart/native/src/c_api/TTexture.cpp @@ -93,7 +93,7 @@ namespace thermion return false; } - Log("Dimensions %d x %d, channels %d, size %d, buffer format %d and pixel data type %d", w, h, channels, size, bufferFormat, pixelDataType); + TRACE("Loading image from dimensions %d x %d, channels %d, size %d, buffer format %d and pixel data type %d", w, h, channels, size, bufferFormat, pixelDataType); filament::Texture::PixelBufferDescriptor buffer( image->getPixelRef(), @@ -115,51 +115,151 @@ namespace thermion uint32_t height, uint32_t channels, uint32_t tBufferFormat, - uint32_t tPixelDataType - ) { + uint32_t tPixelDataType) + { auto engine = reinterpret_cast(tEngine); - + auto texture = reinterpret_cast(tTexture); auto bufferFormat = static_cast(tBufferFormat); auto pixelDataType = static_cast(tPixelDataType); switch (bufferFormat) { - case PixelBufferDescriptor::PixelDataFormat::RGB: - case PixelBufferDescriptor::PixelDataFormat::RGBA: - if(size != width * height * channels * sizeof(float)) { - Log("Size mismatch"); - return false; - } - break; - case PixelBufferDescriptor::PixelDataFormat::RGB_INTEGER: - case PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER: - if(size != width * height * channels * sizeof(uint8_t)) { - Log("Size mismatch"); - // return false; - } - break; - default: - Log("Unsupported buffer format type : %d", bufferFormat); + case PixelBufferDescriptor::PixelDataFormat::RGB: + case PixelBufferDescriptor::PixelDataFormat::RGBA: + if (size != width * height * channels * sizeof(float)) + { + Log("Size mismatch"); return false; + } + break; + case PixelBufferDescriptor::PixelDataFormat::RGB_INTEGER: + case PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER: + if (size != width * height * channels * sizeof(uint8_t)) + { + Log("Size mismatch"); + // return false; + } + break; + default: + Log("Unsupported buffer format type : %d", bufferFormat); + return false; } - filament::Texture::PixelBufferDescriptor buffer( - data, + // the texture upload is async, so we need to copy the buffer + auto *buffer = new std::vector(size); + std::copy(data, data + size, buffer->begin()); + + filament::Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t, + void *data) + { + delete reinterpret_cast *>(data); + }; + + filament::Texture::PixelBufferDescriptor pbd( + buffer->data(), size, bufferFormat, - pixelDataType); - - texture->setImage(*engine, level, std::move(buffer)); + pixelDataType, + 1, // alignment + 0, // left + 0, // top + 0, // stride + freeCallback, + buffer); + + texture->setImage(*engine, level, std::move(pbd)); return true; } + EMSCRIPTEN_KEEPALIVE bool Texture_setImageWithDepth( + TEngine *tEngine, + TTexture *tTexture, + uint32_t level, + uint8_t *data, + size_t size, + uint32_t x_offset, + uint32_t y_offset, + uint32_t z_offset, + uint32_t width, + uint32_t height, + uint32_t channels, + uint32_t depth, + uint32_t tBufferFormat, + uint32_t tPixelDataType) + { + auto engine = reinterpret_cast(tEngine); - EMSCRIPTEN_KEEPALIVE TLinearImage *Image_createEmpty(uint32_t width,uint32_t height,uint32_t channel) { - auto *image = new ::image::LinearImage(width, height, channel); - return reinterpret_cast(image); + auto texture = reinterpret_cast(tTexture); + auto bufferFormat = static_cast(tBufferFormat); + auto pixelDataType = static_cast(tPixelDataType); + TRACE("Setting texture image (depth %d, %dx%dx%d (%d bytes, z_offset %d)", depth, width, height, channels, size, z_offset); + + switch (bufferFormat) + { + case PixelBufferDescriptor::PixelDataFormat::RGB: + case PixelBufferDescriptor::PixelDataFormat::RGBA: + if (size != width * height * channels * sizeof(float)) + { + Log("Size mismatch"); + return false; + } + break; + case PixelBufferDescriptor::PixelDataFormat::RGB_INTEGER: + case PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER: + if (size != width * height * channels * sizeof(uint8_t)) + { + Log("Size mismatch"); + // return false; + } + break; + default: + Log("Unsupported buffer format type : %d", bufferFormat); + return false; + } + + // the texture upload is async, so we need to copy the buffer + auto *buffer = new std::vector(size); + std::copy(data, data + size, buffer->begin()); + + filament::Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t, + void *data) + { + + delete reinterpret_cast *>(data); + }; + + filament::Texture::PixelBufferDescriptor pbd( + buffer->data(), + size, + bufferFormat, + pixelDataType, + 1, // alignment + 0, // left + 0, // top + 0, // stride + freeCallback, + buffer); + + texture->setImage( + *engine, + level, + x_offset, + y_offset, + z_offset, + width, + height, + depth, + std::move(pbd)); + + return true; + } + + EMSCRIPTEN_KEEPALIVE TLinearImage *Image_createEmpty(uint32_t width, uint32_t height, uint32_t channel) + { + auto *image = new ::image::LinearImage(width, height, channel); + return reinterpret_cast(image); } - EMSCRIPTEN_KEEPALIVE TTextureSampler *TextureSampler_create() { @@ -288,11 +388,12 @@ namespace thermion delete textureSampler; } } - - EMSCRIPTEN_KEEPALIVE TTexture *RenderTarget_getColorTexture(TRenderTarget *tRenderTarget) { - auto renderTarget = reinterpret_cast(tRenderTarget); + + EMSCRIPTEN_KEEPALIVE TTexture *RenderTarget_getColorTexture(TRenderTarget *tRenderTarget) + { + auto renderTarget = reinterpret_cast(tRenderTarget); auto texture = renderTarget->getTexture(filament::RenderTarget::AttachmentPoint::COLOR0); - return reinterpret_cast(texture); + return reinterpret_cast(texture); } #ifdef __cplusplus diff --git a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp index dce1b31e..46e5605f 100644 --- a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp +++ b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp @@ -332,6 +332,7 @@ extern "C" EMSCRIPTEN_KEEPALIVE void Engine_buildTextureRenderThread(TEngine *engine, uint32_t width, uint32_t height, + uint32_t depth, uint8_t levels, TTextureSamplerType sampler, TTextureFormat format, @@ -340,7 +341,7 @@ extern "C" std::packaged_task lambda( [=]() mutable { - auto texture = Engine_buildTexture(engine, width, height, levels, sampler, format); + auto texture = Engine_buildTexture(engine, width, height, depth, levels, sampler, format); onComplete(texture); }); auto fut = _rl->add_task(lambda); @@ -909,6 +910,47 @@ extern "C" auto fut = _rl->add_task(lambda); } + EMSCRIPTEN_KEEPALIVE void Texture_setImageWithDepthRenderThread( + TEngine *tEngine, + TTexture *tTexture, + uint32_t level, + uint8_t *data, + size_t size, + uint32_t x_offset, + uint32_t y_offset, + uint32_t z_offset, + uint32_t width, + uint32_t height, + uint32_t channels, + uint32_t depth, + uint32_t bufferFormat, + uint32_t pixelDataType, + void (*onComplete)(bool) +) { + std::packaged_task lambda( + [=]() mutable + { + bool result = Texture_setImageWithDepth( + tEngine, + tTexture, + level, + data, + size, + x_offset, + y_offset, + z_offset, + width, + height, + channels, + depth, + bufferFormat, + pixelDataType + ); + onComplete(result); + }); + auto fut = _rl->add_task(lambda); +} + EMSCRIPTEN_KEEPALIVE void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *)) { std::packaged_task lambda(