This commit is contained in:
Nick Fisher
2023-04-18 14:17:05 +08:00
parent 67ac8990b8
commit 8298e473c2
13 changed files with 431 additions and 175 deletions

View File

@@ -11,6 +11,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
var width: Double = 0
var height: Double = 0
var createdAt = Date()
var targetPixelBuffer: CVPixelBuffer?;
// var context: EAGLContext?;
@@ -74,6 +75,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
do {
let c1 = try found!.resourceValues(forKeys: [.creationDateKey]).creationDate
let c2 = try fileURL.resourceValues(forKeys: [.creationDateKey]).creationDate
if c1! < c2! {
found = fileURL
print("\(fileURL) is newer, replacing")
@@ -86,11 +88,18 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
}
}
}
if found != nil {
print("Using hot reloaded asset : \(found)")
path = found?.path
} else {
do {
if let cd = try found?.resourceValues(forKeys:[.creationDateKey]).creationDate {
if cd > instance.createdAt {
print("Using hot reloaded asset : \(found)")
path = found!.path
}
}
} catch {
}
if path == nil {
if(uriString.hasPrefix("file://")) {
path = String(uriString.dropFirst(7))
} else if(uriString.hasPrefix("asset://")) {
@@ -103,7 +112,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
}
} else {
// TODO
}
}
}
do {
print("Opening data from path \(path)")
@@ -115,9 +124,8 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
return ResourceBuffer(data:rawPtr, size:UInt32(nsData.count), id:UInt32(resId))
} catch {
print("Error opening file: \(error)")
return ResourceBuffer()
}
return ResourceBuffer()
return ResourceBuffer()
}
var freeResource : @convention(c) (UInt32,UnsafeMutableRawPointer) -> () = { rid, resourcesPtr in
@@ -349,7 +357,8 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
remove_skybox(self.viewer!)
result("OK");
case "loadGlb":
let assetPtr = load_glb(self.viewer, call.arguments as! String)
let args = call.arguments as! Array<Any>
let assetPtr = load_glb(self.viewer, args[0] as! String, args[1] as! Bool)
result(unsafeBitCast(assetPtr, to:Int64.self));
case "loadGltf":
let args = call.arguments as! Array<Any?>
@@ -463,16 +472,21 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
case "rotateEnd":
grab_end(self.viewer)
result("OK")
case "clearBackgroundImage":
clear_background_image(self.viewer!)
result("OK")
case "setBackgroundColor":
let args = call.arguments as! Array<Any>
set_background_color(self.viewer!, Float(args[0] as! Double),Float(args[1] as! Double),Float(args[2] as! Double), Float(args[3] as! Double))
result("OK")
case "setBackgroundImage":
let uri = call.arguments as! String
set_background_image(self.viewer!, uri)
render(self.viewer!, 0)
self.registry.textureFrameAvailable(self.textureId!)
result("OK")
let uri = call.arguments as? String
set_background_image(self.viewer!, uri)
result("OK")
case "setBackgroundImagePosition":
let args = call.arguments as! Array<Any>
set_background_image_position(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), args[2] as! Bool)
result("OK");
let args = call.arguments as! Array<Any>
set_background_image_position(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), args[2] as! Bool)
result("OK");
case "setPosition":
let args = call.arguments as! Array<Any>
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)

View File

@@ -56,7 +56,7 @@ namespace polyvox {
void loadIbl(const char* const iblUri, float intensity);
void removeIbl();
SceneAsset* loadGlb(const char* const uri);
SceneAsset* loadGlb(const char* const uri, bool unlit);
SceneAsset* loadGltf(const char* const uri, const char* relativeResourcePath);
void removeAsset(SceneAsset* asset);
// removes all add assets from the current scene
@@ -76,8 +76,9 @@ namespace polyvox {
Renderer* getRenderer();
void setBackgroundColor(const float* color);
void setBackgroundColor(const float r, const float g, const float b, const float a);
void setBackgroundImage(const char* resourcePath);
void clearBackgroundImage();
void setBackgroundImagePosition(float x, float y, bool clamp);
void setCameraExposure(float aperture, float shutterSpeed, float sensitivity);
void setCameraPosition(float x, float y, float z);
@@ -125,8 +126,8 @@ namespace polyvox {
vector<SceneAsset*> _assets;
AssetLoader* _assetLoader;
SceneAssetLoader* _sceneAssetLoader;
SceneAssetLoader* _ubershaderAssetLoader;
SceneAssetLoader* _unlitAssetLoader;
NameComponentManager* _ncm;
std::mutex mtx; // mutex to ensure thread safety when removing assets
@@ -148,7 +149,9 @@ namespace polyvox {
float _cameraFocalLength = 28.0f;
float _cameraFocusDistance = 0.0f;
// these flags relate to the textured quad we use for rendering unlit background images
ColorGrading *colorGrading = nullptr;
// background image properties
uint32_t _imageHeight = 0;
uint32_t _imageWidth = 0;
mat4f _imageScale;
@@ -158,12 +161,12 @@ namespace polyvox {
IndexBuffer* _imageIb = nullptr;
Material* _imageMaterial = nullptr;
TextureSampler _imageSampler;
ColorGrading *colorGrading = nullptr;
void loadKtx2Texture(string path, ResourceBuffer data);
void loadKtxTexture(string path, ResourceBuffer data);
void loadPngTexture(string path, ResourceBuffer data);
void loadTextureFromPath(string path);
void _createManipulator();
uint32_t _lastFrameTimeInNanos;
};

View File

@@ -26,11 +26,11 @@ typedef struct BoneAnimation BoneAnimation;
void* filament_viewer_new(void* context, ResourceBuffer (*loadResource)(const char*), void (*freeResource)(uint32_t));
void filament_viewer_delete(void* viewer);
void create_render_target(void* viewer, uint32_t textureId, uint32_t width, uint32_t height);
void clear_background_image(void* viewer);
void set_background_image(void* viewer, const char* path);
// color is rgba
void set_background_color(void* viewer, const float* color);
void set_background_image_position(void* viewer, float x, float y, bool clamp);
void set_background_color(void* viewer, const float r, const float g, const float b, const float a);
void load_skybox(void* viewer, const char* skyboxPath);
void load_ibl(void* viewer, const char* iblPath, float intensity);
void remove_skybox(void* viewer);
@@ -38,7 +38,7 @@ void remove_ibl(void* viewer);
int32_t add_light(void* viewer, uint8_t type, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows);
void remove_light(void* viewer, int32_t entityId);
void clear_lights(void* viewer);
void* load_glb(void* viewer, const char* assetPath);
void* load_glb(void* viewer, const char* assetPath, bool unlit);
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath);
bool set_camera(void* viewer, void* asset, const char* nodeName);
void render(void* viewer, uint64_t frameTimeInNanos);

View File

@@ -20,23 +20,30 @@ namespace polyvox {
SceneAssetLoader(
LoadResource loadResource,
FreeResource freeResource,
AssetLoader* assetLoader,
MaterialProvider* materialProvider,
EntityManager* entityManager,
ResourceLoader* resourceLoader,
NameComponentManager* ncm,
Engine* engine,
Scene* scene);
~SceneAssetLoader();
SceneAsset* fromGltf(const char* uri, const char* relativeResourcePath);
SceneAsset* fromGlb(const char* uri);
void remove(SceneAsset* asset);
void destroyAll();
private:
LoadResource _loadResource;
FreeResource _freeResource;
MaterialProvider* _materialProvider;
EntityManager* _entityManager;
AssetLoader* _assetLoader;
ResourceLoader* _resourceLoader;
NameComponentManager* _ncm;
Engine* _engine;
Scene* _scene;
vector<SceneAsset*> _assets;
};
}

View File

@@ -6,8 +6,11 @@ namespace polyvox {
const Material* _m;
const Material* _ms[1];
const Engine* _engine;
public:
UnlitMaterialProvider(Engine* engine) {
_engine = engine;
_m = Material::Builder()
.package( UNLIT_OPAQUE_UNLIT_OPAQUE_DATA, UNLIT_OPAQUE_UNLIT_OPAQUE_SIZE)
.build(*engine);
@@ -35,11 +38,11 @@ namespace polyvox {
}
void destroyMaterials() {
// TODO - do we need to do anything here?
}
bool needsDummyData(filament::VertexAttribute attrib) const noexcept {
return true;
return false;
}
};
}

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b4ce6e725e4beb9d7cd494f24b2bd4608de06b5dcc7290d07c8a6f3668cec6ec
size 905232
oid sha256:6f40a337ca4ae110bbfee332e03ee496b0f3706b6b9d264a44f3c248733f4f23
size 376488

View File

@@ -106,14 +106,12 @@ struct Vertex {
uint32_t color;
};
// static const Vertex TRIANGLE_VERTICES[3] = {
// {{1, 0}, 0xffff0000u},
// {{cos(M_PI * 2 / 3), sin(M_PI * 2 / 3)}, 0xff00ff00u},
// {{cos(M_PI * 4 / 3), sin(M_PI * 4 / 3)}, 0xff0000ffu},
// };
// static constexpr uint16_t TRIANGLE_INDICES[3] = { 0, 1, 2 };
static constexpr float4 sFullScreenTriangleVertices[3] = {
{ -1.0f, -1.0f, 1.0f, 1.0f },
{ 3.0f, -1.0f, 1.0f, 1.0f },
{ -1.0f, 3.0f, 1.0f, 1.0f } };
static const uint16_t sFullScreenTriangleIndices[3] = {0, 1, 2};
FilamentViewer::FilamentViewer(void* context, LoadResource loadResource,
FreeResource freeResource)
@@ -196,34 +194,85 @@ FilamentViewer::FilamentViewer(void* context, LoadResource loadResource,
_unlitProvider = new UnlitMaterialProvider(_engine);
_ubershaderProvider = gltfio::createUbershaderProvider(
_engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
Log("Created material provider");
EntityManager &em = EntityManager::get();
_ncm = new NameComponentManager(em);
_assetLoader = AssetLoader::create({_engine, _ubershaderProvider, _ncm, &em});
_resourceLoader = new ResourceLoader({.engine = _engine,
.normalizeSkinningWeights = true });
_stbDecoder = createStbProvider(_engine);
_resourceLoader->addTextureProvider("image/png", _stbDecoder);
_resourceLoader->addTextureProvider("image/jpeg", _stbDecoder);
_sceneAssetLoader = new SceneAssetLoader(_loadResource,
_ubershaderAssetLoader = new SceneAssetLoader(_loadResource,
_freeResource,
_assetLoader,
_ubershaderProvider,
&em,
_resourceLoader,
_ncm,
_engine,
_scene);
_unlitAssetLoader = new SceneAssetLoader(_loadResource,
_freeResource,
_unlitProvider,
&em,
_resourceLoader,
_ncm,
_engine,
_scene);
_imageTexture = Texture::Builder()
.width(1)
.height(1)
.levels(0x01)
.format(Texture::InternalFormat::RGB16F)
.sampler(Texture::Sampler::SAMPLER_2D)
.build(*_engine);
_imageMaterial =
Material::Builder()
.package(IMAGE_PACKAGE, IMAGE_IMAGE_SIZE)
.build(*_engine);
_imageMaterial->setDefaultParameter("showImage",0);
_imageMaterial->setDefaultParameter("backgroundColor", RgbType::sRGB, float3(0.f));
_imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler);
_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)});
Entity 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);
_imageEntity = &imageEntity;
_scene->addEntity(imageEntity);
}
static constexpr float4 sFullScreenTriangleVertices[3] = {
{ -1.0f, -1.0f, 1.0f, 1.0f },
{ 3.0f, -1.0f, 1.0f, 1.0f },
{ -1.0f, 3.0f, 1.0f, 1.0f } };
static const uint16_t sFullScreenTriangleIndices[3] = {0, 1, 2};
void FilamentViewer::setFrameInterval(float frameInterval) {
Renderer::FrameRateOptions fro;
fro.interval = frameInterval;
@@ -260,52 +309,6 @@ void FilamentViewer::clearLights() {
_lights.clear();
}
void FilamentViewer::createImageRenderable() {
if (_imageEntity)
return;
auto &em = EntityManager::get();
_imageMaterial =
Material::Builder()
.package(IMAGE_PACKAGE, IMAGE_IMAGE_SIZE)
.build(*_engine);
_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)});
Entity 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);
_imageEntity = &imageEntity;
}
static bool endsWith(string path, string ending) {
return path.compare(path.length() - ending.length(), ending.length(), ending) == 0;
}
@@ -367,7 +370,7 @@ void FilamentViewer::loadPngTexture(string path, ResourceBuffer rb) {
_imageTexture = Texture::Builder()
.width(_imageWidth)
.height(_imageHeight)
.levels(0xff)
.levels(0x01)
.format(channels == 3 ? Texture::InternalFormat::RGB16F
: Texture::InternalFormat::RGBA16F)
.sampler(Texture::Sampler::SAMPLER_2D)
@@ -411,26 +414,32 @@ void FilamentViewer::loadTextureFromPath(string path) {
}
void FilamentViewer::setBackgroundColor(const float* color) {
void FilamentViewer::setBackgroundColor(const float r, const float g, const float b, const float a) {
_imageMaterial->setDefaultParameter("showImage", 0);
_imageMaterial->setDefaultParameter("backgroundColor", RgbType::sRGB, float3(color[0], color[1], color[2]));
_imageMaterial->setDefaultParameter("backgroundColor", RgbaType::sRGB, float4(r, g, b, a));
const Viewport& vp = _view->getViewport();
Log("Image width %d height %d vp width %d height %d", _imageWidth, _imageHeight, vp.width, vp.height);
_imageMaterial->setDefaultParameter("transform", _imageScale);
}
void FilamentViewer::clearBackgroundImage() {
_imageMaterial->setDefaultParameter("showImage", 0);
if (_imageTexture) {
Log("Destroying existing texture");
_engine->destroy(_imageTexture);
Log("Destroyed.");
_imageTexture = nullptr;
}
}
void FilamentViewer::setBackgroundImage(const char *resourcePath) {
string resourcePathString(resourcePath);
Log("Setting background image to %s", resourcePath);
createImageRenderable();
if (_imageTexture) {
Log("Destroying existing texture");
_engine->destroy(_imageTexture);
Log("Destroyed.");
_imageTexture = nullptr;
}
clearBackgroundImage();
loadTextureFromPath(resourcePathString);
@@ -442,11 +451,8 @@ void FilamentViewer::setBackgroundImage(const char *resourcePath) {
_imageMaterial->setDefaultParameter("transform", _imageScale);
_imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler);
_imageMaterial->setDefaultParameter("showImage", 1);
_imageMaterial->setDefaultParameter("backgroundColor", RgbType::sRGB,
float3(0.f));
}
@@ -529,11 +535,12 @@ void FilamentViewer::setBackgroundImagePosition(float x, float y, bool clamp=fal
FilamentViewer::~FilamentViewer() {
clearAssets();
delete _sceneAssetLoader;
delete _ubershaderAssetLoader;
delete _unlitAssetLoader;
_resourceLoader->asyncCancelLoad();
_ubershaderProvider->destroyMaterials();
_unlitProvider->destroyMaterials();
AssetLoader::destroy(&_assetLoader);
for(auto it : _lights) {
_engine->destroy(it);
}
@@ -609,14 +616,20 @@ void FilamentViewer::destroySwapChain() {
}
}
SceneAsset *FilamentViewer::loadGlb(const char *const uri) {
SceneAsset *asset = _sceneAssetLoader->fromGlb(uri);
SceneAsset *FilamentViewer::loadGlb(const char *const uri, bool unlit) {
SceneAsset *asset;
if(unlit) {
asset = _unlitAssetLoader->fromGlb(uri);
} else {
asset = _ubershaderAssetLoader->fromGlb(uri);
}
if (!asset) {
Log("Unknown error loading asset.");
} else {
_assets.push_back(asset);
Log("GLB loaded, asset at index %d", _assets.size() - 1);
}
return asset;
}
@@ -624,7 +637,7 @@ SceneAsset *FilamentViewer::loadGltf(const char *const uri,
const char *const relativeResourcePath) {
Log("Loading GLTF at URI %s with relativeResourcePath %s", uri,
relativeResourcePath);
SceneAsset *asset = _sceneAssetLoader->fromGltf(uri, relativeResourcePath);
SceneAsset *asset = _ubershaderAssetLoader->fromGltf(uri, relativeResourcePath);
if (!asset) {
Log("Unknown error loading asset.");
} else {
@@ -633,7 +646,6 @@ SceneAsset *FilamentViewer::loadGltf(const char *const uri,
return asset;
}
void FilamentViewer::clearAssets() {
Log("Clearing all assets");
if(_mainCamera) {
@@ -644,13 +656,10 @@ void FilamentViewer::clearAssets() {
delete _manipulator;
_manipulator = nullptr;
}
_ubershaderAssetLoader->destroyAll();
_unlitAssetLoader->destroyAll();
int i = 0;
for (auto asset : _assets) {
_sceneAssetLoader->remove(asset);
Log("Cleared asset %d", i);
i++;
}
_assets.clear();
Log("Cleared all assets");
}
@@ -661,19 +670,8 @@ void FilamentViewer::removeAsset(SceneAsset *asset) {
mtx.lock();
// todo - what if we are using a camera from this asset?
_view->setCamera(_mainCamera);
_sceneAssetLoader->remove(asset);
bool erased = false;
for (auto it = _assets.begin(); it != _assets.end();++it) {
if (*it == asset) {
_assets.erase(it);
erased = true;
break;
}
}
if (!erased) {
Log("Error removing asset from scene : not found");
}
_ubershaderAssetLoader->remove(asset);
_unlitAssetLoader->remove(asset);
mtx.unlock();
}

View File

@@ -23,8 +23,12 @@ extern "C" {
delete((FilamentViewer*)viewer);
}
void set_background_color(void* viewer, const float* color) {
((FilamentViewer*)viewer)->setBackgroundColor(color);
void set_background_color(void* viewer, const float r, const float g, const float b, const float a) {
((FilamentViewer*)viewer)->setBackgroundColor(r, g, b, a);
}
void clear_background_image(void* viewer) {
((FilamentViewer*)viewer)->clearBackgroundImage();
}
void set_background_image(void* viewer, const char* path) {
@@ -63,8 +67,8 @@ extern "C" {
((FilamentViewer*)viewer)->clearLights();
}
void* load_glb(void* viewer, const char* assetPath) {
return ((FilamentViewer*)viewer)->loadGlb(assetPath);
void* load_glb(void* viewer, const char* assetPath, bool unlit) {
return ((FilamentViewer*)viewer)->loadGlb(assetPath, unlit);
}
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath) {

View File

@@ -10,14 +10,22 @@ using namespace filament::gltfio;
SceneAssetLoader::SceneAssetLoader(LoadResource loadResource,
FreeResource freeResource,
AssetLoader *assetLoader,
MaterialProvider* materialProvider,
EntityManager* entityManager,
ResourceLoader *resourceLoader,
NameComponentManager *ncm,
Engine *engine,
Scene *scene)
: _loadResource(loadResource), _freeResource(freeResource),
_assetLoader(assetLoader), _resourceLoader(resourceLoader), _ncm(ncm),
_engine(engine), _scene(scene) {}
: _loadResource(loadResource), _freeResource(freeResource), _materialProvider(materialProvider), _entityManager(entityManager),
_resourceLoader(resourceLoader), _ncm(ncm),
_engine(engine), _scene(scene) {
_assetLoader = AssetLoader::create({_engine, materialProvider, _ncm, entityManager});
}
SceneAssetLoader::~SceneAssetLoader() {
destroyAll();
AssetLoader::destroy(&_assetLoader);
}
SceneAsset *SceneAssetLoader::fromGltf(const char *uri,
const char *relativeResourcePath) {
@@ -87,6 +95,7 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
FilamentAsset *asset = _assetLoader->createAsset(
(const uint8_t *)rbuf.data, rbuf.size);
if (!asset) {
Log("Unknown error loading GLB asset.");
return nullptr;
@@ -105,12 +114,18 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
const Entity *entities = asset->getEntities();
RenderableManager &rm = _engine->getRenderableManager();
MaterialKey config;
auto mi_new = _materialProvider->createMaterialInstance(&config, nullptr);
// why did I need to explicitly enable culling?
for (int i = 0; i < asset->getEntityCount(); i++) {
auto entityInstance = rm.getInstance(entities[i]);
rm.setCulling(entityInstance, true);
}
auto entityInstance = rm.getInstance(entities[i]);
auto mi = rm.getMaterialInstanceAt(entityInstance, 0);
// auto m = mi->getMaterial();
// auto shading = m->getShading();
// Log("Shading %d", shading);
}
auto lights = asset->getLightEntities();
_scene->addEntities(lights, asset->getLightEntityCount());
@@ -118,6 +133,8 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
Log("Added %d lights to scene from asset", asset->getLightEntityCount());
FilamentInstance* inst = asset->getInstance();
inst->getAnimator()->updateBoneMatrices();
inst->recomputeBoundingBoxes();
@@ -128,10 +145,43 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
_freeResource(rbuf.id);
Log("Successfully loaded GLB.");
return new SceneAsset(asset, _engine, _ncm, _loadResource, _freeResource);
SceneAsset* sceneAsset = new SceneAsset(asset, _engine, _ncm, _loadResource, _freeResource);
_assets.push_back(sceneAsset);
return sceneAsset;
}
void SceneAssetLoader::destroyAll() {
for (auto asset : _assets) {
_scene->removeEntities(asset->_asset->getEntities(),
asset->_asset->getEntityCount());
_scene->removeEntities(asset->getLightEntities(),
asset->getLightEntityCount());
_resourceLoader->evictResourceData();
_assetLoader->destroyAsset(asset->_asset);
delete asset;
}
_assets.clear();
}
void SceneAssetLoader::remove(SceneAsset *asset) {
bool erased = false;
for (auto it = _assets.begin(); it != _assets.end();++it) {
if (*it == asset) {
_assets.erase(it);
erased = true;
break;
}
}
if (!erased) {
Log("Error removing asset from scene : not found");
return;
}
Log("Removing asset and all associated entities/lights.");

View File

@@ -1,12 +1,12 @@
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/services.dart';
import 'animations/animation_builder.dart';
import 'animations/animations.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
// this is confusing - "FilamentAsset" actually defines a pointer to a SceneAsset, whereas FilamentLight is an Entity ID.
// should make this consistent
typedef FilamentAsset = int;
@@ -26,11 +26,12 @@ abstract class FilamentController {
void setPixelRatio(double ratio);
Future resize(int width, int height, {double contentScaleFactor = 1});
Future setBackgroundColor(Color color);
Future clearBackgroundImage();
Future setBackgroundImage(String path);
Future setBackgroundImagePosition(double x, double y, {bool clamp = false});
Future loadSkybox(String skyboxPath);
Future removeSkybox();
Future loadIbl(String path);
Future loadIbl(String path, {double intensity = 30000});
Future removeIbl();
// copied from LightManager.h
@@ -54,7 +55,7 @@ abstract class FilamentController {
bool castShadows);
Future removeLight(FilamentLight light);
Future clearLights();
Future<FilamentAsset> loadGlb(String path);
Future<FilamentAsset> loadGlb(String path, {bool unlit = false});
Future<FilamentAsset> loadGltf(String path, String relativeResourcePath);
Future zoomBegin();
Future zoomUpdate(double z);
@@ -172,6 +173,11 @@ class PolyvoxFilamentController extends FilamentController {
_textureIdController.add(_textureId);
}
@override
Future clearBackgroundImage() async {
await _channel.invokeMethod("clearBackgroundImage");
}
@override
Future setBackgroundImage(String path) async {
await _channel.invokeMethod("setBackgroundImage", path);
@@ -179,15 +185,12 @@ class PolyvoxFilamentController extends FilamentController {
@override
Future setBackgroundColor(Color color) async {
print(
"setting to ${color.red.toDouble() / 255.0} ${color.blue.toDouble() / 255.0} ${color.red.toDouble() / 255.0}");
await _channel.invokeMethod(
"setBackgroundColor",
Float32List.fromList([
color.red.toDouble() / 255.0,
color.green.toDouble() / 255.0,
color.blue.toDouble() / 255.0
]));
await _channel.invokeMethod("setBackgroundColor", [
color.red.toDouble() / 255.0,
color.green.toDouble() / 255.0,
color.blue.toDouble() / 255.0,
color.alpha.toDouble() / 255.0
]);
}
@override
@@ -253,9 +256,9 @@ class PolyvoxFilamentController extends FilamentController {
return _channel.invokeMethod("clearLights");
}
Future<FilamentAsset> loadGlb(String path) async {
Future<FilamentAsset> loadGlb(String path, {bool unlit = false}) async {
print("Loading GLB at $path ");
var asset = await _channel.invokeMethod("loadGlb", path);
var asset = await _channel.invokeMethod("loadGlb", [path, unlit]);
if (asset == FILAMENT_ASSET_ERROR) {
throw Exception("An error occurred loading the asset at $path");
}

View File

@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
@@ -35,6 +36,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
};
bool _rotating = false;
bool _scaling = false;
// to avoid duplicating code for pan/rotate (panStart, panUpdate, panEnd, rotateStart, rotateUpdate etc)
// we have only a single function for start/update/end.
@@ -100,6 +102,8 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
onScaleStart: !widget.enableControls
? null
: (d) async {
_scaling = true;
print("SCALE START");
if (d.pointerCount == 2) {
await widget.controller.zoomEnd();
await widget.controller.zoomBegin();
@@ -108,6 +112,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
onScaleEnd: !widget.enableControls
? null
: (d) async {
_scaling = false;
if (d.pointerCount == 2) {
_lastScale = 0;
await widget.controller.zoomEnd();
@@ -118,8 +123,9 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
: (d) async {
if (d.pointerCount == 2) {
if (_lastScale != 0) {
await widget.controller
.zoomUpdate(100 * (_lastScale - d.scale));
await widget.controller.zoomUpdate(Platform.isIOS
? 1000 * (_lastScale - d.scale)
: 100 * (_lastScale - d.scale));
}
}
_lastScale = d.scale;
@@ -128,6 +134,8 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
onPointerSignal: !widget.enableControls
? null
: (pointerSignal) async {
print("ponter signal");
// scroll-wheel zoom on desktop
if (pointerSignal is PointerScrollEvent) {
_scrollTimer?.cancel();
@@ -146,6 +154,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
onPointerDown: !widget.enableControls
? null
: (d) async {
print("piinterodoiwn");
if (d.buttons == kTertiaryButton || _rotating) {
await widget.controller.rotateStart(
d.localPosition.dx, d.localPosition.dy);
@@ -157,6 +166,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
onPointerMove: !widget.enableControls
? null
: (d) async {
print("pointermove");
if (d.buttons == kTertiaryButton || _rotating) {
await widget.controller.rotateUpdate(
d.localPosition.dx, d.localPosition.dy);
@@ -168,6 +178,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
onPointerUp: !widget.enableControls
? null
: (d) async {
print("pointerup");
if (d.buttons == kTertiaryButton || _rotating) {
await widget.controller.rotateEnd();
} else {

View File

@@ -17,7 +17,7 @@ set(PLUGIN_NAME "polyvox_filament_plugin")
link_directories("${CMAKE_CURRENT_SOURCE_DIR}/lib")
add_library(FILAMENT_SHADERS SHARED
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/include/material/image_material.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/include/material/image.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/include/material/unlit_opaque.c"
)

View File

@@ -1,15 +1,178 @@
material {
name : BakedColor,
requires : [
color
],
name : unlit_opaque,
requires : [ uv0, uv1, color ],
shadingModel : unlit,
culling : none
blending : ${BLENDING},
doubleSided : ${DOUBLESIDED},
transparency : ${TRANSPARENCY},
flipUV : false,
specularAmbientOcclusion : simple,
specularAntiAliasing : true,
clearCoatIorChange : false,
reflections : screenspace,
parameters : [
{ type : float3, name : specularFactor },
{ type : float, name : glossinessFactor },
// Base Color
{ type : int, name : baseColorIndex },
{ type : float4, name : baseColorFactor },
{ type : sampler2d, name : baseColorMap },
{ type : mat3, name : baseColorUvMatrix, precision: high },
// Metallic-Roughness Map
{ type : int, name : metallicRoughnessIndex },
{ type : float, name : metallicFactor },
{ type : float, name : roughnessFactor },
{ type : sampler2d, name : metallicRoughnessMap },
{ type : mat3, name : metallicRoughnessUvMatrix, precision: high },
// Normal Map
{ type : int, name : normalIndex },
{ type : float, name : normalScale },
{ type : sampler2d, name : normalMap },
{ type : mat3, name : normalUvMatrix, precision: high },
// Ambient Occlusion
{ type : int, name : aoIndex },
{ type : float, name : aoStrength },
{ type : sampler2d, name : occlusionMap },
{ type : mat3, name : occlusionUvMatrix, precision: high },
// Emissive Map
{ type : int, name : emissiveIndex },
{ type : float3, name : emissiveFactor },
{ type : float, name : emissiveStrength },
{ type : sampler2d, name : emissiveMap },
{ type : mat3, name : emissiveUvMatrix, precision: high },
// Clear coat
{ type : float, name : clearCoatFactor },
{ type : float, name : clearCoatRoughnessFactor },
{ type : int, name : clearCoatIndex },
{ type : sampler2d, name : clearCoatMap },
{ type : mat3, name : clearCoatUvMatrix, precision: high },
{ type : int, name : clearCoatRoughnessIndex },
{ type : sampler2d, name : clearCoatRoughnessMap },
{ type : mat3, name : clearCoatRoughnessUvMatrix, precision: high },
{ type : int, name : clearCoatNormalIndex },
{ type : sampler2d, name : clearCoatNormalMap },
{ type : mat3, name : clearCoatNormalUvMatrix, precision: high },
{ type : float, name : clearCoatNormalScale },
// Reflectance
{ type : float, name : reflectance }
${CUSTOM_PARAMS}
],
}
vertex {
void materialVertex(inout MaterialVertexInputs material) {
${CUSTOM_VERTEX}
}
}
fragment {
void material(inout MaterialInputs material) {
highp float2 uvs[2];
uvs[0] = getUV0();
uvs[1] = getUV1();
#if !defined(SHADING_MODEL_UNLIT)
if (materialParams.normalIndex > -1) {
highp float2 uv = uvs[materialParams.normalIndex];
uv = (vec3(uv, 1.0) * materialParams.normalUvMatrix).xy;
material.normal = texture(materialParams_normalMap, uv).xyz * 2.0 - 1.0;
material.normal.xy *= materialParams.normalScale;
}
#if defined(SHADING_MODEL_LIT)
if (materialParams.clearCoatNormalIndex > -1) {
highp float2 uv = uvs[materialParams.clearCoatNormalIndex];
uv = (vec3(uv, 1.0) * materialParams.clearCoatNormalUvMatrix).xy;
material.clearCoatNormal = texture(materialParams_clearCoatNormalMap, uv).xyz * 2.0 - 1.0;
material.clearCoatNormal.xy *= materialParams.clearCoatNormalScale;
}
#endif
#endif
prepareMaterial(material);
material.baseColor = getColor();
material.baseColor = materialParams.baseColorFactor;
if (materialParams.baseColorIndex > -1) {
highp float2 uv = uvs[materialParams.baseColorIndex];
uv = (vec3(uv, 1.0) * materialParams.baseColorUvMatrix).xy;
material.baseColor *= texture(materialParams_baseColorMap, uv);
}
#if defined(BLEND_MODE_TRANSPARENT)
material.baseColor.rgb *= material.baseColor.a;
#endif
material.baseColor *= getColor();
#if !defined(SHADING_MODEL_UNLIT)
#if defined(SHADING_MODEL_LIT)
material.roughness = materialParams.roughnessFactor;
material.metallic = materialParams.metallicFactor;
// KHR_materials_clearcoat forbids clear coat from
// being applied in the specular/glossiness model
material.clearCoat = materialParams.clearCoatFactor;
material.clearCoatRoughness = materialParams.clearCoatRoughnessFactor;
if (materialParams.clearCoatIndex > -1) {
highp float2 uv = uvs[materialParams.clearCoatIndex];
uv = (vec3(uv, 1.0) * materialParams.clearCoatUvMatrix).xy;
material.clearCoat *= texture(materialParams_clearCoatMap, uv).r;
}
if (materialParams.clearCoatRoughnessIndex > -1) {
highp float2 uv = uvs[materialParams.clearCoatRoughnessIndex];
uv = (vec3(uv, 1.0) * materialParams.clearCoatRoughnessUvMatrix).xy;
material.clearCoatRoughness *= texture(materialParams_clearCoatRoughnessMap, uv).g;
}
#endif
material.emissive = vec4(materialParams.emissiveStrength *
materialParams.emissiveFactor.rgb, 0.0);
#if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
material.glossiness = materialParams.glossinessFactor;
material.specularColor = materialParams.specularFactor;
#else
material.reflectance = materialParams.reflectance;
#endif
if (materialParams.metallicRoughnessIndex > -1) {
highp float2 uv = uvs[materialParams.metallicRoughnessIndex];
uv = (vec3(uv, 1.0) * materialParams.metallicRoughnessUvMatrix).xy;
#if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
vec4 sg = texture(materialParams_metallicRoughnessMap, uv);
material.specularColor *= sg.rgb;
material.glossiness *= sg.a;
#else
vec4 mr = texture(materialParams_metallicRoughnessMap, uv);
material.roughness *= mr.g;
material.metallic *= mr.b;
#endif
}
if (materialParams.aoIndex > -1) {
highp float2 uv = uvs[materialParams.aoIndex];
uv = (vec3(uv, 1.0) * materialParams.occlusionUvMatrix).xy;
float occlusion = texture(materialParams_occlusionMap, uv).r;
material.ambientOcclusion = 1.0 + materialParams.aoStrength * (occlusion - 1.0);
}
if (materialParams.emissiveIndex > -1) {
highp float2 uv = uvs[materialParams.emissiveIndex];
uv = (vec3(uv, 1.0) * materialParams.emissiveUvMatrix).xy;
material.emissive.rgb *= texture(materialParams_emissiveMap, uv).rgb;
}
#endif
${CUSTOM_FRAGMENT}
}
}