Merge pull request #55 from nmfisher/develop

feat: shadows, web, docs, image material
This commit is contained in:
Nick Fisher
2024-07-04 16:42:25 +10:00
committed by GitHub
25 changed files with 435 additions and 143 deletions

View File

@@ -3,6 +3,40 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 2024-07-02
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`thermion_dart` - `v0.1.1+4`](#thermion_dart---v0114)
- [`thermion_flutter_web` - `v0.0.1+8`](#thermion_flutter_web---v0018)
- [`thermion_flutter` - `v0.1.1+9`](#thermion_flutter---v0119)
- [`thermion_flutter_platform_interface` - `v0.1.0+8`](#thermion_flutter_platform_interface---v0108)
- [`thermion_flutter_ffi` - `v0.1.0+8`](#thermion_flutter_ffi---v0108)
Packages with dependency updates only:
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
- `thermion_flutter_web` - `v0.0.1+8`
- `thermion_flutter` - `v0.1.1+9`
- `thermion_flutter_platform_interface` - `v0.1.0+8`
- `thermion_flutter_ffi` - `v0.1.0+8`
---
#### `thermion_dart` - `v0.1.1+4`
- **FIX**: defer creating image entity/material/etc until actually requested.
## 2024-06-27
### Changes

View File

@@ -40,7 +40,7 @@ and change the minimum deployment target to 13.0:
</Accordion>
<Accordion title="Click to open Windows instructions">
See the [/windows](Windows) page for steps needed to build on Windows.
See the [/windows](/Windows) page for steps needed to build on Windows.
</Accordion>
@@ -218,4 +218,4 @@ $ flutter run -d macos
![Screenshot of Thermion Quickstart project](images/thermion_sample_project.png)
Your first Thermion project is complete!
Your first Thermion project is complete!

View File

@@ -1,3 +1,7 @@
## 0.1.1+4
- **FIX**: defer creating image entity/material/etc until actually requested.
## 0.1.1+3
- **FIX**: bump ffigen dependency version & regenerate bindings (and revert to ffi.Int rather than ffi.Int32).

View File

@@ -796,6 +796,25 @@ external void set_post_processing(
bool enabled,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Bool)>()
external void set_shadows_enabled(
ffi.Pointer<ffi.Void> viewer,
bool enabled,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
external void set_shadow_type(
ffi.Pointer<ffi.Void> viewer,
int shadowType,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Float, ffi.Float)>()
external void set_soft_shadow_options(
ffi.Pointer<ffi.Void> viewer,
double penumbraScale,
double penumbraRatioScale,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Bool, ffi.Bool, ffi.Bool)>()
external void set_antialiasing(

View File

@@ -826,4 +826,19 @@ class ThermionViewerJS implements ThermionViewer {
void onDispose(Future Function() callback) {
_onDispose.add(callback);
}
@override
Future setShadowType(ShadowType shadowType) {
return _shim.setShadowType(shadowType).toDart;
}
@override
Future setShadowsEnabled(bool enabled) {
return _shim.setShadowsEnabled(enabled).toDart;
}
@override
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) {
return _shim.setSoftShadowOptions(penumbraScale, penumbraRatioScale).toDart;
}
}

View File

@@ -405,5 +405,17 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject {
@JS('setBoneTransform')
external JSPromise setBoneTransform(
ThermionEntity entity, int boneIndex, JSArray<JSNumber> transform, int skinIndex);
@JS('setShadowsEnabled')
external JSPromise setShadowsEnabled(
bool enabled);
@JS('setShadowType')
external JSPromise setShadowType(
ShadowType shadowType);
@JS('setSoftShadowOptions')
external JSPromise setSoftShadowOptions(
double penumbraScale, double penumbraRatioScale);
}

View File

@@ -631,8 +631,8 @@ class ThermionViewerWasm implements ThermionViewer {
final promise = _module.ccall(
"load_gltf",
"int",
["void*".toJS, "string".toJS, "string".toJS, "bool".toJS].toJS,
[_sceneManager!, path.toJS, relativeResourcePath.toJS, force.toJS].toJS,
["void*".toJS, "string".toJS, "string".toJS].toJS,
[_sceneManager!, path.toJS, relativeResourcePath.toJS].toJS,
{"async": true}.jsify()) as JSPromise<JSNumber>;
final entityId = (await promise.toDart).toDartInt;
if (entityId == -1) {
@@ -1847,4 +1847,34 @@ class ThermionViewerWasm implements ThermionViewer {
// TODO: implement zoomUpdate
throw UnimplementedError();
}
@override
Future setShadowType(ShadowType shadowType) async {
_module.ccall(
"set_shadow_type",
"void",
["void*".toJS, "int".toJS].toJS,
[_viewer!, shadowType.index.toJS].toJS,
null);
}
@override
Future setShadowsEnabled(bool enabled) async {
_module.ccall(
"set_shadows_enabled",
"void",
["void*".toJS, "bool".toJS].toJS,
[_viewer!, enabled.toJS].toJS,
null);
}
@override
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) async {
_module.ccall(
"set_soft_shadow_options",
"void",
["void*".toJS, "float".toJS, "float".toJS].toJS,
[_viewer!, penumbraScale.toJS, penumbraRatioScale.toJS].toJS,
null);
}
}

View File

@@ -19,6 +19,13 @@ enum LightType {
SPOT,
}
enum ShadowType {
PCF, //!< percentage-closer filtered shadows (default)
VSM, //!< variance shadows
DPCF, //!< PCF with contact hardening simulation
PCSS, //!< PCF with soft shadows and contact hardening
}
// copied from filament/backened/DriverEnums.h
enum PrimitiveType {
// don't change the enums values (made to match GL)
@@ -562,10 +569,25 @@ abstract class ThermionViewer {
{bool relative = false});
///
/// Enable/disable postprocessing.
/// Enable/disable postprocessing (disabled by default).
///
Future setPostProcessing(bool enabled);
///
/// Enable/disable shadows (disabled by default).
///
Future setShadowsEnabled(bool enabled);
///
/// Set shadow type.
///
Future setShadowType(ShadowType shadowType);
///
/// Set soft shadow options (ShadowType DPCF and PCSS)
///
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale);
///
/// Set antialiasing options.
///
@@ -707,6 +729,7 @@ abstract class ThermionViewer {
/// Register a callback to be invoked when this viewer is disposed.
///
void onDispose(Future Function() callback);
}
abstract class AbstractGizmo {

View File

@@ -198,6 +198,7 @@ class ThermionViewerFFI extends ThermionViewer {
await callback.call();
}
_onDispose.clear();
}
///
@@ -1063,6 +1064,29 @@ class ThermionViewerFFI extends ThermionViewer {
set_post_processing_ffi(_viewer!, enabled);
}
///
///
///
@override
Future setShadowsEnabled(bool enabled) async {
set_shadows_enabled(_viewer!, enabled);
}
///
///
///
Future setShadowType(ShadowType shadowType) async {
set_shadow_type(_viewer!, shadowType.index);
}
///
///
///
Future setSoftShadowOptions(
double penumbraScale, double penumbraRatioScale) async {
set_soft_shadow_options(_viewer!, penumbraScale, penumbraRatioScale);
}
///
///
///
@@ -1564,8 +1588,9 @@ class ThermionViewerFFI extends ThermionViewer {
// ignore: sdk_version_since
if (callback != null) {
var ptr = NativeCallable<
Void Function(Int entityId1, Int entityId2)>.listener(callback);
var ptr =
NativeCallable<Void Function(Int entityId1, Int entityId2)>.listener(
callback);
add_collision_component(
_sceneManager!, entity, ptr.nativeFunction, affectsTransform);
_collisions[entity] = ptr;

View File

@@ -726,4 +726,22 @@ class ThermionViewerStub extends ThermionViewer {
// TODO: implement zoomUpdate
throw UnimplementedError();
}
@override
Future setShadowType(ShadowType shadowType) {
// TODO: implement setShadowType
throw UnimplementedError();
}
@override
Future setShadowsEnabled(bool enabled) {
// TODO: implement setShadowsEnabled
throw UnimplementedError();
}
@override
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) {
// TODO: implement setSoftShadowOptions
throw UnimplementedError();
}
}

View File

@@ -153,6 +153,9 @@ namespace thermion_filament
void setAntiAliasing(bool msaaEnabled, bool fxaaEnabled, bool taaEnabled);
void setDepthOfField();
void setShadowsEnabled(bool enabled);
void setShadowType(ShadowType shadowType);
void setSoftShadowOptions( float penumbraScale, float penumbraRatioScale);
EntityId createGeometry(float *vertices, uint32_t numVertices, uint16_t *indices, uint32_t numIndices, filament::RenderableManager::PrimitiveType primitiveType = RenderableManager::PrimitiveType::TRIANGLES, const char *materialPath = nullptr);
@@ -222,6 +225,7 @@ namespace thermion_filament
void loadPngTexture(std::string path, ResourceBuffer data);
void loadTextureFromPath(std::string path);
void savePng(void *data, size_t size, int frameNumber);
void createBackgroundImage();
time_point_t _recordingStartTime = std::chrono::high_resolution_clock::now();
time_point_t _fpsCounterStartTime = std::chrono::high_resolution_clock::now();
@@ -229,6 +233,7 @@ namespace thermion_filament
bool _recording = false;
std::string _recordingOutputDirectory = std::string("/tmp");
std::mutex _recordingMutex;
std::mutex _imageMutex;
double _cumulativeAnimationUpdateTime = 0;
int _frameCount = 0;
int _skippedFrames = 0;

View File

@@ -216,6 +216,9 @@ extern "C"
EMSCRIPTEN_KEEPALIVE int hide_mesh(void *sceneManager, EntityId entity, const char *meshName);
EMSCRIPTEN_KEEPALIVE int reveal_mesh(void *sceneManager, EntityId entity, const char *meshName);
EMSCRIPTEN_KEEPALIVE void set_post_processing(void *const viewer, bool enabled);
EMSCRIPTEN_KEEPALIVE void set_shadows_enabled(void *const viewer, bool enabled);
EMSCRIPTEN_KEEPALIVE void set_shadow_type(void *const viewer, int shadowType);
EMSCRIPTEN_KEEPALIVE void set_soft_shadow_options(void *const viewer, float penumbraScale, float penumbraRatioScale);
EMSCRIPTEN_KEEPALIVE void set_antialiasing(void *const viewer, bool msaa, bool fxaa, bool taa);
EMSCRIPTEN_KEEPALIVE void filament_pick(void *const viewer, int x, int y, void (*callback)(EntityId entityId, int x, int y));
EMSCRIPTEN_KEEPALIVE const char *get_name_for_entity(void *const sceneManager, const EntityId entityId);

View File

@@ -214,60 +214,6 @@ namespace thermion_filament
Log("Created scene maager");
_dummyImageTexture = Texture::Builder()
.width(1)
.height(1)
.levels(0x01)
.format(Texture::InternalFormat::RGB16F)
.sampler(Texture::Sampler::SAMPLER_2D)
.build(*_engine);
try
{
_imageMaterial =
Material::Builder()
.package(IMAGE_IMAGE_DATA, IMAGE_IMAGE_SIZE)
.build(*_engine);
_imageMaterial->setDefaultParameter("showImage", 0);
_imageMaterial->setDefaultParameter("backgroundColor", RgbaType::sRGB, float4(1.0f, 1.0f, 1.0f, 0.0f));
_imageMaterial->setDefaultParameter("image", _dummyImageTexture, _imageSampler);
}
catch (...)
{
Log("Failed to load background image material provider");
std::rethrow_exception(std::current_exception());
}
_imageScale = mat4f{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
_imageMaterial->setDefaultParameter("transform", _imageScale);
_imageVb = VertexBuffer::Builder()
.vertexCount(3)
.bufferCount(1)
.attribute(VertexAttribute::POSITION, 0,
VertexBuffer::AttributeType::FLOAT4, 0)
.build(*_engine);
_imageVb->setBufferAt(
*_engine, 0,
{sFullScreenTriangleVertices, sizeof(sFullScreenTriangleVertices)});
_imageIb = IndexBuffer::Builder()
.indexCount(3)
.bufferType(IndexBuffer::IndexType::USHORT)
.build(*_engine);
_imageIb->setBuffer(*_engine, {sFullScreenTriangleIndices,
sizeof(sFullScreenTriangleIndices)});
_imageEntity = em.create();
RenderableManager::Builder(1)
.boundingBox({{}, {1.0f, 1.0f, 1.0f}})
.material(0, _imageMaterial->getDefaultInstance())
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, _imageVb,
_imageIb, 0, 3)
.culling(false)
.build(*_engine, _imageEntity);
_scene->addEntity(_imageEntity);
}
void FilamentViewer::setAntiAliasing(bool msaa, bool fxaa, bool taa)
@@ -287,6 +233,24 @@ namespace thermion_filament
_view->setPostProcessingEnabled(enabled);
}
void FilamentViewer::setShadowsEnabled(bool enabled)
{
_view->setShadowingEnabled(enabled);
}
void FilamentViewer::setShadowType(ShadowType shadowType)
{
_view->setShadowType(shadowType);
}
void FilamentViewer::setSoftShadowOptions(float penumbraScale, float penumbraRatioScale) {
SoftShadowOptions opts;
opts.penumbraRatioScale = penumbraRatioScale;
opts.penumbraScale = penumbraScale;
_view->setSoftShadowOptions(opts);
}
void FilamentViewer::setBloom(float strength)
{
#ifndef __EMSCRIPTEN__
@@ -541,14 +505,81 @@ namespace thermion_filament
void FilamentViewer::setBackgroundColor(const float r, const float g, const float b, const float a)
{
// Log("Setting background color to rgba(%f,%f,%f,%f)", r, g, b, a);
std::lock_guard lock(_imageMutex);
if(_imageEntity.isNull()) {
createBackgroundImage();
}
_imageMaterial->setDefaultParameter("showImage", 0);
_imageMaterial->setDefaultParameter("backgroundColor", RgbaType::sRGB, float4(r, g, b, a));
_imageMaterial->setDefaultParameter("transform", _imageScale);
}
void FilamentViewer::createBackgroundImage() {
_dummyImageTexture = Texture::Builder()
.width(1)
.height(1)
.levels(0x01)
.format(Texture::InternalFormat::RGB16F)
.sampler(Texture::Sampler::SAMPLER_2D)
.build(*_engine);
try
{
_imageMaterial =
Material::Builder()
.package(IMAGE_IMAGE_DATA, IMAGE_IMAGE_SIZE)
.build(*_engine);
_imageMaterial->setDefaultParameter("showImage", 0);
_imageMaterial->setDefaultParameter("backgroundColor", RgbaType::sRGB, float4(1.0f, 1.0f, 1.0f, 0.0f));
_imageMaterial->setDefaultParameter("image", _dummyImageTexture, _imageSampler);
}
catch (...)
{
Log("Failed to load background image material provider");
std::rethrow_exception(std::current_exception());
}
_imageScale = mat4f{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
_imageMaterial->setDefaultParameter("transform", _imageScale);
_imageVb = VertexBuffer::Builder()
.vertexCount(3)
.bufferCount(1)
.attribute(VertexAttribute::POSITION, 0,
VertexBuffer::AttributeType::FLOAT4, 0)
.build(*_engine);
_imageVb->setBufferAt(
*_engine, 0,
{sFullScreenTriangleVertices, sizeof(sFullScreenTriangleVertices)});
_imageIb = IndexBuffer::Builder()
.indexCount(3)
.bufferType(IndexBuffer::IndexType::USHORT)
.build(*_engine);
_imageIb->setBuffer(*_engine, {sFullScreenTriangleIndices,
sizeof(sFullScreenTriangleIndices)});
auto & em = EntityManager::get();
_imageEntity = em.create();
RenderableManager::Builder(1)
.boundingBox({{}, {1.0f, 1.0f, 1.0f}})
.material(0, _imageMaterial->getDefaultInstance())
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, _imageVb,
_imageIb, 0, 3)
.culling(false)
.build(*_engine, _imageEntity);
_scene->addEntity(_imageEntity);
}
void FilamentViewer::clearBackgroundImage()
{
std::lock_guard lock(_imageMutex);
if(_imageEntity.isNull()) {
createBackgroundImage();
}
_imageMaterial->setDefaultParameter("image", _dummyImageTexture, _imageSampler);
_imageMaterial->setDefaultParameter("showImage", 0);
if (_imageTexture)
@@ -562,6 +593,12 @@ namespace thermion_filament
void FilamentViewer::setBackgroundImage(const char *resourcePath, bool fillHeight)
{
std::lock_guard lock(_imageMutex);
if(_imageEntity.isNull()) {
createBackgroundImage();
}
string resourcePathString(resourcePath);
Log("Setting background image to %s", resourcePath);
@@ -602,6 +639,11 @@ namespace thermion_filament
///
void FilamentViewer::setBackgroundImagePosition(float x, float y, bool clamp = false)
{
std::lock_guard lock(_imageMutex);
if(_imageEntity.isNull()) {
createBackgroundImage();
}
// to translate the background image, we apply a transform to the UV coordinates of the quad texture, not the quad itself (see image.mat).
// this allows us to set a background colour for the quad when the texture has been translated outside the quad's bounds.
@@ -682,11 +724,13 @@ namespace thermion_filament
{
clearLights();
destroySwapChain();
_engine->destroy(_imageEntity);
_engine->destroy(_imageTexture);
_engine->destroy(_imageVb);
_engine->destroy(_imageIb);
_engine->destroy(_imageMaterial);
if(!_imageEntity.isNull()) {
_engine->destroy(_imageEntity);
_engine->destroy(_imageTexture);
_engine->destroy(_imageVb);
_engine->destroy(_imageIb);
_engine->destroy(_imageMaterial);
}
delete _sceneManager;
_engine->destroyCameraComponent(_mainCamera->getEntity());
_mainCamera = nullptr;

View File

@@ -443,6 +443,21 @@ extern "C"
((FilamentViewer *)viewer)->setPostProcessing(enabled);
}
EMSCRIPTEN_KEEPALIVE void set_shadows_enabled(void *const viewer, bool enabled)
{
((FilamentViewer *)viewer)->setShadowsEnabled(enabled);
}
EMSCRIPTEN_KEEPALIVE void set_shadow_type(void *const viewer, int shadowType)
{
((FilamentViewer *)viewer)->setShadowType((ShadowType)shadowType);
}
EMSCRIPTEN_KEEPALIVE void set_soft_shadow_options(void *const viewer, float penumbraScale, float penumbraRatioScale)
{
((FilamentViewer *)viewer)->setSoftShadowOptions(penumbraScale, penumbraRatioScale);
}
EMSCRIPTEN_KEEPALIVE void set_antialiasing(void *const viewer, bool msaa, bool fxaa, bool taa)
{
((FilamentViewer *)viewer)->setAntiAliasing(msaa, fxaa, taa);

View File

@@ -19,7 +19,7 @@ set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORT_NAME=${MODULE_NAME})
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sINITIAL_MEMORY=512mb)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sMODULARIZE)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sERROR_ON_UNDEFINED_SYMBOLS=0 )
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_RUNTIME_METHODS=wasmExports,wasmTable,addFunction,ccall,cwrap,allocate,intArrayFromString,intArrayToString,getValue,setValue,UTF8ToString,stringToUTF8,writeArrayToMemory,_free)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_RUNTIME_METHODS=wasmExports,wasmTable,addFunction,ccall,cwrap,allocate,intArrayFromString,intArrayToString,getValue,setValue,UTF8ToString,stringToUTF8,writeArrayToMemory)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_FUNCTIONS=_malloc,stackAlloc,_free)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFULL_ES3)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sASSERTIONS)
@@ -35,10 +35,13 @@ set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFETCH=1)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sUSE_PTHREADS)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sPROXY_TO_WORKER=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sSHARED_MEMORY=0)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -lidbfs.js)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFORCE_FILESYSTEM=1)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -pie)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-deprecated-literal-operator -stdlib=libc++ -std=c++17 -fPIC -O3 --no-entry")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-deprecated-literal-operator -stdlib=libc++ -std=c++17 -fPIC -O3 --no-entry ")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -pie")
add_link_options(${EMCC_CFLAGS})

View File

@@ -64,57 +64,20 @@ extern "C"
((PendingCall*)context)->HandleResponse(data, length);
}
EMSCRIPTEN_KEEPALIVE void thermion_filament_web_set(char* ptr, int32_t offset, int32_t val) {
memset(ptr+offset, val, 1);
}
EMSCRIPTEN_KEEPALIVE void thermion_filament_web_set_float(float* ptr, int32_t offset, float val) {
ptr[offset] = val;
}
EMSCRIPTEN_KEEPALIVE float thermion_filament_web_get_float(float* ptr, int32_t offset) {
return ptr[offset];
}
EMSCRIPTEN_KEEPALIVE double thermion_filament_web_get_double(double* ptr, int32_t offset) {
return ptr[offset];
}
EMSCRIPTEN_KEEPALIVE void thermion_filament_web_set_double(double* ptr, int32_t offset, double value) {
ptr[offset] = value;
}
EMSCRIPTEN_KEEPALIVE int32_t thermion_filament_web_get_int32(int32_t* ptr, int32_t offset) {
return ptr[offset];
}
EMSCRIPTEN_KEEPALIVE void thermion_filament_web_set_int32(int32_t* ptr, int32_t offset, int32_t value) {
ptr[offset] = value;
}
EMSCRIPTEN_KEEPALIVE void thermion_filament_web_set_pointer(void** ptr, int32_t offset, void* val) {
ptr[offset] = val;
}
EMSCRIPTEN_KEEPALIVE void* thermion_filament_web_get_pointer(void** ptr, int32_t offset) {
return ptr[offset];
}
EMSCRIPTEN_KEEPALIVE char thermion_filament_web_get(char* ptr, int32_t offset) {
return ptr[offset];
}
EMSCRIPTEN_KEEPALIVE void* thermion_filament_web_allocate(int32_t size) {
void* allocated = (void*)calloc(size, 1);
return allocated;
}
EMSCRIPTEN_KEEPALIVE long thermion_filament_web_get_address(void** out) {
return (long)*out;
}
EMSCRIPTEN_KEEPALIVE EMSCRIPTEN_WEBGL_CONTEXT_HANDLE thermion_dart_web_create_gl_context() {
EM_ASM(
FS.mkdir('/indexed');
FS.mount(IDBFS, {}, '/indexed');
FS.syncfs(true, function (err) {
if (err) {
console.error('Error mounting IDBFS:', err);
} else {
console.log('IDBFS mounted successfully');
}
});
);
std::cout << "Creating WebGL context." << std::endl;
EmscriptenWebGLContextAttributes attr;
@@ -181,7 +144,7 @@ extern "C"
// const char* headers[] = {"Accept-Encoding", "gzip, deflate", NULL};
// attr.requestHeaders = headers;
auto pathString = std::string(path);
// auto pathString = std::string(path);
// if(pathString.rfind("/",0) != 0) {
// pathString = std::string("/") + pathString;
// }
@@ -197,18 +160,81 @@ extern "C"
// memcpy(data, request->data, request->numBytes);
// emscripten_fetch_close(request);
// return ResourceBuffer { data, (int32_t) request->numBytes, _lastResourceId } ;
auto pathString = std::string(path);
void* data = nullptr;
int32_t numBytes = 0;
void** pBuffer = (void**)malloc(sizeof(void*));
int* pNum = (int*) malloc(sizeof(int*));
int* pError = (int*)malloc(sizeof(int*));
emscripten_wget_data(pathString.c_str(), pBuffer, pNum, pError);
data = *pBuffer;
numBytes = *pNum;
free(pBuffer);
free(pNum);
free(pError);
// Check if the file exists in IndexedDB first
bool fileExists = EM_ASM_INT({
var filename = UTF8ToString($0);
try {
var stat = FS.stat('/indexed/' + filename);
return stat.size > 0;
} catch (e) {
return false;
}
}, pathString.c_str());
if (fileExists) {
// File exists in IndexedDB, read it
EM_ASM({
var filename = UTF8ToString($0);
var content = FS.readFile('/indexed/' + filename);
var numBytes = content.length;
var ptr = _malloc(numBytes);
HEAPU8.set(content, ptr);
setValue($1, ptr, 'i32');
setValue($2, numBytes, 'i32');
}, pathString.c_str(), &data, &numBytes);
} else {
void** pBuffer = (void**)malloc(sizeof(void*));
int* pNum = (int*) malloc(sizeof(int*));
int* pError = (int*)malloc(sizeof(int*));
emscripten_wget_data(pathString.c_str(), pBuffer, pNum, pError);
data = *pBuffer;
numBytes = *pNum;
// Save the file to IndexedDB filesystem
EM_ASM({
var filename = UTF8ToString($0);
var data = new Uint8Array(HEAPU8.subarray($1, $1 + $2));
console.log('Analyinzg /indexed');
// Ensure the '/indexed' directory exists
if (!FS.analyzePath('/indexed').exists) {
FS.mkdir('/indexed');
console.log('Made dir /indexed');
}
// Create all parent directories
var parts = filename.split('/');
var currentPath = '/indexed';
for (var i = 0; i < parts.length - 1; i++) {
currentPath += '/' + parts[i];
if (!FS.analyzePath(currentPath).exists) {
FS.mkdir(currentPath);
console.log("Made dir " + currentPath);
}
}
console.log('Writing file to /indexed/' + filename);
// Write the file
FS.writeFile('/indexed/' + filename, data);
console.log('File written, syncing');
FS.syncfs(false, function (err) {
if (err) {
console.error('Failed to save file to IndexedDB:', err);
} else {
console.log('File saved to IndexedDB successfully');
}
});
}, pathString.c_str(), data, numBytes);
free(pBuffer);
free(pNum);
free(pError);
}
return ResourceBuffer { data, numBytes, _lastResourceId } ;
}

View File

@@ -1,6 +1,6 @@
name: thermion_dart
description: 3D rendering toolkit for Dart.
version: 0.1.1+3
version: 0.1.1+4
homepage: https://thermion.dev
repository: https://github.com/nmfisher/thermion

View File

@@ -1,3 +1,7 @@
## 0.1.1+9
- Update a dependency to the latest release.
## 0.1.1+8
- **DOCS**: update homepage links and minor documentation updates.

View File

@@ -1,6 +1,6 @@
name: thermion_flutter
description: Flutter plugin for 3D rendering with the Thermion toolkit.
version: 0.1.1+8
version: 0.1.1+9
homepage: https://thermion.dev
repository: https://github.com/nmfisher/thermion
@@ -17,10 +17,10 @@ dependencies:
plugin_platform_interface: ^2.0.0
ffi: ^2.1.2
animation_tools_dart: ^0.0.4
thermion_dart: ^0.1.1+3
thermion_flutter_platform_interface: ^0.1.0+7
thermion_flutter_ffi: ^0.1.0+7
thermion_flutter_web: ^0.0.1+7
thermion_dart: ^0.1.1+4
thermion_flutter_platform_interface: ^0.1.0+8
thermion_flutter_ffi: ^0.1.0+8
thermion_flutter_web: ^0.0.1+8
logging: ^1.2.0
dev_dependencies:

View File

@@ -1,3 +1,7 @@
## 0.1.0+8
- Update a dependency to the latest release.
## 0.1.0+7
- Update a dependency to the latest release.

View File

@@ -1,7 +1,7 @@
name: thermion_flutter_ffi
description: An FFI interface for the thermion_flutter plugin (all platforms except web).
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
version: 0.1.0+7
version: 0.1.0+8
environment:
sdk: ">=3.3.0 <4.0.0"
@@ -22,8 +22,8 @@ dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.1.0
thermion_flutter_platform_interface: ^0.1.0+7
thermion_dart: ^0.1.1+3
thermion_flutter_platform_interface: ^0.1.0+8
thermion_dart: ^0.1.1+4
dev_dependencies:
flutter_test:

View File

@@ -1,3 +1,7 @@
## 0.1.0+8
- Update a dependency to the latest release.
## 0.1.0+7
- Update a dependency to the latest release.

View File

@@ -1,7 +1,7 @@
name: thermion_flutter_platform_interface
description: A common platform interface for the thermion_flutter plugin.
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
version: 0.1.0+7
version: 0.1.0+8
environment:
sdk: ">=3.3.0 <4.0.0"
@@ -11,7 +11,7 @@ dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.1.0
thermion_dart: ^0.1.1+3
thermion_dart: ^0.1.1+4
dev_dependencies:
flutter_test:

View File

@@ -1,3 +1,7 @@
## 0.0.1+8
- Update a dependency to the latest release.
## 0.0.1+7
- Update a dependency to the latest release.

View File

@@ -1,7 +1,7 @@
name: thermion_flutter_web
description: A web platform interface for the thermion_flutter plugin.
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
version: 0.0.1+7
version: 0.0.1+8
environment:
sdk: ">=3.3.0 <4.0.0"
@@ -20,8 +20,8 @@ dependencies:
sdk: flutter
plugin_platform_interface: ^2.1.0
web: ^0.5.1
thermion_dart: ^0.1.1+3
thermion_flutter_platform_interface: ^0.1.0+7
thermion_dart: ^0.1.1+4
thermion_flutter_platform_interface: ^0.1.0+8
flutter_web_plugins:
sdk: flutter