work
This commit is contained in:
@@ -11,6 +11,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
|||||||
var width: Double = 0
|
var width: Double = 0
|
||||||
var height: Double = 0
|
var height: Double = 0
|
||||||
|
|
||||||
|
var createdAt = Date()
|
||||||
|
|
||||||
var targetPixelBuffer: CVPixelBuffer?;
|
var targetPixelBuffer: CVPixelBuffer?;
|
||||||
// var context: EAGLContext?;
|
// var context: EAGLContext?;
|
||||||
@@ -74,6 +75,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
|||||||
do {
|
do {
|
||||||
let c1 = try found!.resourceValues(forKeys: [.creationDateKey]).creationDate
|
let c1 = try found!.resourceValues(forKeys: [.creationDateKey]).creationDate
|
||||||
let c2 = try fileURL.resourceValues(forKeys: [.creationDateKey]).creationDate
|
let c2 = try fileURL.resourceValues(forKeys: [.creationDateKey]).creationDate
|
||||||
|
|
||||||
if c1! < c2! {
|
if c1! < c2! {
|
||||||
found = fileURL
|
found = fileURL
|
||||||
print("\(fileURL) is newer, replacing")
|
print("\(fileURL) is newer, replacing")
|
||||||
@@ -87,10 +89,17 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if found != nil {
|
do {
|
||||||
print("Using hot reloaded asset : \(found)")
|
if let cd = try found?.resourceValues(forKeys:[.creationDateKey]).creationDate {
|
||||||
path = found?.path
|
if cd > instance.createdAt {
|
||||||
} else {
|
print("Using hot reloaded asset : \(found)")
|
||||||
|
path = found!.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
}
|
||||||
|
if path == nil {
|
||||||
if(uriString.hasPrefix("file://")) {
|
if(uriString.hasPrefix("file://")) {
|
||||||
path = String(uriString.dropFirst(7))
|
path = String(uriString.dropFirst(7))
|
||||||
} else if(uriString.hasPrefix("asset://")) {
|
} else if(uriString.hasPrefix("asset://")) {
|
||||||
@@ -103,7 +112,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
print("Opening data from path \(path)")
|
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))
|
return ResourceBuffer(data:rawPtr, size:UInt32(nsData.count), id:UInt32(resId))
|
||||||
} catch {
|
} catch {
|
||||||
print("Error opening file: \(error)")
|
print("Error opening file: \(error)")
|
||||||
return ResourceBuffer()
|
|
||||||
}
|
}
|
||||||
return ResourceBuffer()
|
return ResourceBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
var freeResource : @convention(c) (UInt32,UnsafeMutableRawPointer) -> () = { rid, resourcesPtr in
|
var freeResource : @convention(c) (UInt32,UnsafeMutableRawPointer) -> () = { rid, resourcesPtr in
|
||||||
@@ -349,7 +357,8 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
|||||||
remove_skybox(self.viewer!)
|
remove_skybox(self.viewer!)
|
||||||
result("OK");
|
result("OK");
|
||||||
case "loadGlb":
|
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));
|
result(unsafeBitCast(assetPtr, to:Int64.self));
|
||||||
case "loadGltf":
|
case "loadGltf":
|
||||||
let args = call.arguments as! Array<Any?>
|
let args = call.arguments as! Array<Any?>
|
||||||
@@ -463,16 +472,21 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
|||||||
case "rotateEnd":
|
case "rotateEnd":
|
||||||
grab_end(self.viewer)
|
grab_end(self.viewer)
|
||||||
result("OK")
|
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":
|
case "setBackgroundImage":
|
||||||
let uri = call.arguments as! String
|
let uri = call.arguments as? String
|
||||||
set_background_image(self.viewer!, uri)
|
set_background_image(self.viewer!, uri)
|
||||||
render(self.viewer!, 0)
|
result("OK")
|
||||||
self.registry.textureFrameAvailable(self.textureId!)
|
|
||||||
result("OK")
|
|
||||||
case "setBackgroundImagePosition":
|
case "setBackgroundImagePosition":
|
||||||
let args = call.arguments as! Array<Any>
|
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)
|
set_background_image_position(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), args[2] as! Bool)
|
||||||
result("OK");
|
result("OK");
|
||||||
case "setPosition":
|
case "setPosition":
|
||||||
let args = call.arguments as! Array<Any>
|
let args = call.arguments as! Array<Any>
|
||||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace polyvox {
|
|||||||
void loadIbl(const char* const iblUri, float intensity);
|
void loadIbl(const char* const iblUri, float intensity);
|
||||||
void removeIbl();
|
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);
|
SceneAsset* loadGltf(const char* const uri, const char* relativeResourcePath);
|
||||||
void removeAsset(SceneAsset* asset);
|
void removeAsset(SceneAsset* asset);
|
||||||
// removes all add assets from the current scene
|
// removes all add assets from the current scene
|
||||||
@@ -76,8 +76,9 @@ namespace polyvox {
|
|||||||
|
|
||||||
Renderer* getRenderer();
|
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 setBackgroundImage(const char* resourcePath);
|
||||||
|
void clearBackgroundImage();
|
||||||
void setBackgroundImagePosition(float x, float y, bool clamp);
|
void setBackgroundImagePosition(float x, float y, bool clamp);
|
||||||
void setCameraExposure(float aperture, float shutterSpeed, float sensitivity);
|
void setCameraExposure(float aperture, float shutterSpeed, float sensitivity);
|
||||||
void setCameraPosition(float x, float y, float z);
|
void setCameraPosition(float x, float y, float z);
|
||||||
@@ -125,8 +126,8 @@ namespace polyvox {
|
|||||||
|
|
||||||
vector<SceneAsset*> _assets;
|
vector<SceneAsset*> _assets;
|
||||||
|
|
||||||
AssetLoader* _assetLoader;
|
SceneAssetLoader* _ubershaderAssetLoader;
|
||||||
SceneAssetLoader* _sceneAssetLoader;
|
SceneAssetLoader* _unlitAssetLoader;
|
||||||
NameComponentManager* _ncm;
|
NameComponentManager* _ncm;
|
||||||
std::mutex mtx; // mutex to ensure thread safety when removing assets
|
std::mutex mtx; // mutex to ensure thread safety when removing assets
|
||||||
|
|
||||||
@@ -148,7 +149,9 @@ namespace polyvox {
|
|||||||
float _cameraFocalLength = 28.0f;
|
float _cameraFocalLength = 28.0f;
|
||||||
float _cameraFocusDistance = 0.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 _imageHeight = 0;
|
||||||
uint32_t _imageWidth = 0;
|
uint32_t _imageWidth = 0;
|
||||||
mat4f _imageScale;
|
mat4f _imageScale;
|
||||||
@@ -158,12 +161,12 @@ namespace polyvox {
|
|||||||
IndexBuffer* _imageIb = nullptr;
|
IndexBuffer* _imageIb = nullptr;
|
||||||
Material* _imageMaterial = nullptr;
|
Material* _imageMaterial = nullptr;
|
||||||
TextureSampler _imageSampler;
|
TextureSampler _imageSampler;
|
||||||
ColorGrading *colorGrading = nullptr;
|
|
||||||
void loadKtx2Texture(string path, ResourceBuffer data);
|
void loadKtx2Texture(string path, ResourceBuffer data);
|
||||||
void loadKtxTexture(string path, ResourceBuffer data);
|
void loadKtxTexture(string path, ResourceBuffer data);
|
||||||
void loadPngTexture(string path, ResourceBuffer data);
|
void loadPngTexture(string path, ResourceBuffer data);
|
||||||
void loadTextureFromPath(string path);
|
void loadTextureFromPath(string path);
|
||||||
|
|
||||||
|
|
||||||
void _createManipulator();
|
void _createManipulator();
|
||||||
uint32_t _lastFrameTimeInNanos;
|
uint32_t _lastFrameTimeInNanos;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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_new(void* context, ResourceBuffer (*loadResource)(const char*), void (*freeResource)(uint32_t));
|
||||||
void filament_viewer_delete(void* viewer);
|
void filament_viewer_delete(void* viewer);
|
||||||
void create_render_target(void* viewer, uint32_t textureId, uint32_t width, uint32_t height);
|
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);
|
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_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_skybox(void* viewer, const char* skyboxPath);
|
||||||
void load_ibl(void* viewer, const char* iblPath, float intensity);
|
void load_ibl(void* viewer, const char* iblPath, float intensity);
|
||||||
void remove_skybox(void* viewer);
|
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);
|
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 remove_light(void* viewer, int32_t entityId);
|
||||||
void clear_lights(void* viewer);
|
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);
|
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath);
|
||||||
bool set_camera(void* viewer, void* asset, const char* nodeName);
|
bool set_camera(void* viewer, void* asset, const char* nodeName);
|
||||||
void render(void* viewer, uint64_t frameTimeInNanos);
|
void render(void* viewer, uint64_t frameTimeInNanos);
|
||||||
|
|||||||
@@ -20,23 +20,30 @@ namespace polyvox {
|
|||||||
SceneAssetLoader(
|
SceneAssetLoader(
|
||||||
LoadResource loadResource,
|
LoadResource loadResource,
|
||||||
FreeResource freeResource,
|
FreeResource freeResource,
|
||||||
AssetLoader* assetLoader,
|
MaterialProvider* materialProvider,
|
||||||
|
EntityManager* entityManager,
|
||||||
ResourceLoader* resourceLoader,
|
ResourceLoader* resourceLoader,
|
||||||
NameComponentManager* ncm,
|
NameComponentManager* ncm,
|
||||||
Engine* engine,
|
Engine* engine,
|
||||||
Scene* scene);
|
Scene* scene);
|
||||||
|
~SceneAssetLoader();
|
||||||
SceneAsset* fromGltf(const char* uri, const char* relativeResourcePath);
|
SceneAsset* fromGltf(const char* uri, const char* relativeResourcePath);
|
||||||
SceneAsset* fromGlb(const char* uri);
|
SceneAsset* fromGlb(const char* uri);
|
||||||
void remove(SceneAsset* asset);
|
void remove(SceneAsset* asset);
|
||||||
|
void destroyAll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LoadResource _loadResource;
|
LoadResource _loadResource;
|
||||||
FreeResource _freeResource;
|
FreeResource _freeResource;
|
||||||
|
MaterialProvider* _materialProvider;
|
||||||
|
EntityManager* _entityManager;
|
||||||
AssetLoader* _assetLoader;
|
AssetLoader* _assetLoader;
|
||||||
ResourceLoader* _resourceLoader;
|
ResourceLoader* _resourceLoader;
|
||||||
NameComponentManager* _ncm;
|
NameComponentManager* _ncm;
|
||||||
Engine* _engine;
|
Engine* _engine;
|
||||||
Scene* _scene;
|
Scene* _scene;
|
||||||
|
|
||||||
|
vector<SceneAsset*> _assets;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,11 @@ namespace polyvox {
|
|||||||
const Material* _m;
|
const Material* _m;
|
||||||
const Material* _ms[1];
|
const Material* _ms[1];
|
||||||
|
|
||||||
|
const Engine* _engine;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UnlitMaterialProvider(Engine* engine) {
|
UnlitMaterialProvider(Engine* engine) {
|
||||||
|
_engine = engine;
|
||||||
_m = Material::Builder()
|
_m = Material::Builder()
|
||||||
.package( UNLIT_OPAQUE_UNLIT_OPAQUE_DATA, UNLIT_OPAQUE_UNLIT_OPAQUE_SIZE)
|
.package( UNLIT_OPAQUE_UNLIT_OPAQUE_DATA, UNLIT_OPAQUE_UNLIT_OPAQUE_SIZE)
|
||||||
.build(*engine);
|
.build(*engine);
|
||||||
@@ -35,11 +38,11 @@ namespace polyvox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void destroyMaterials() {
|
void destroyMaterials() {
|
||||||
|
// TODO - do we need to do anything here?
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needsDummyData(filament::VertexAttribute attrib) const noexcept {
|
bool needsDummyData(filament::VertexAttribute attrib) const noexcept {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:b4ce6e725e4beb9d7cd494f24b2bd4608de06b5dcc7290d07c8a6f3668cec6ec
|
oid sha256:6f40a337ca4ae110bbfee332e03ee496b0f3706b6b9d264a44f3c248733f4f23
|
||||||
size 905232
|
size 376488
|
||||||
|
|||||||
@@ -106,14 +106,12 @@ struct Vertex {
|
|||||||
uint32_t color;
|
uint32_t color;
|
||||||
};
|
};
|
||||||
|
|
||||||
// static const Vertex TRIANGLE_VERTICES[3] = {
|
static constexpr float4 sFullScreenTriangleVertices[3] = {
|
||||||
// {{1, 0}, 0xffff0000u},
|
{ -1.0f, -1.0f, 1.0f, 1.0f },
|
||||||
// {{cos(M_PI * 2 / 3), sin(M_PI * 2 / 3)}, 0xff00ff00u},
|
{ 3.0f, -1.0f, 1.0f, 1.0f },
|
||||||
// {{cos(M_PI * 4 / 3), sin(M_PI * 4 / 3)}, 0xff0000ffu},
|
{ -1.0f, 3.0f, 1.0f, 1.0f } };
|
||||||
// };
|
|
||||||
|
|
||||||
// static constexpr uint16_t TRIANGLE_INDICES[3] = { 0, 1, 2 };
|
|
||||||
|
|
||||||
|
static const uint16_t sFullScreenTriangleIndices[3] = {0, 1, 2};
|
||||||
|
|
||||||
FilamentViewer::FilamentViewer(void* context, LoadResource loadResource,
|
FilamentViewer::FilamentViewer(void* context, LoadResource loadResource,
|
||||||
FreeResource freeResource)
|
FreeResource freeResource)
|
||||||
@@ -196,34 +194,85 @@ FilamentViewer::FilamentViewer(void* context, LoadResource loadResource,
|
|||||||
_unlitProvider = new UnlitMaterialProvider(_engine);
|
_unlitProvider = new UnlitMaterialProvider(_engine);
|
||||||
_ubershaderProvider = gltfio::createUbershaderProvider(
|
_ubershaderProvider = gltfio::createUbershaderProvider(
|
||||||
_engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
|
_engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
|
||||||
Log("Created material provider");
|
|
||||||
|
|
||||||
EntityManager &em = EntityManager::get();
|
EntityManager &em = EntityManager::get();
|
||||||
_ncm = new NameComponentManager(em);
|
_ncm = new NameComponentManager(em);
|
||||||
_assetLoader = AssetLoader::create({_engine, _ubershaderProvider, _ncm, &em});
|
|
||||||
|
|
||||||
_resourceLoader = new ResourceLoader({.engine = _engine,
|
_resourceLoader = new ResourceLoader({.engine = _engine,
|
||||||
.normalizeSkinningWeights = true });
|
.normalizeSkinningWeights = true });
|
||||||
_stbDecoder = createStbProvider(_engine);
|
_stbDecoder = createStbProvider(_engine);
|
||||||
_resourceLoader->addTextureProvider("image/png", _stbDecoder);
|
_resourceLoader->addTextureProvider("image/png", _stbDecoder);
|
||||||
_resourceLoader->addTextureProvider("image/jpeg", _stbDecoder);
|
_resourceLoader->addTextureProvider("image/jpeg", _stbDecoder);
|
||||||
_sceneAssetLoader = new SceneAssetLoader(_loadResource,
|
_ubershaderAssetLoader = new SceneAssetLoader(_loadResource,
|
||||||
_freeResource,
|
_freeResource,
|
||||||
_assetLoader,
|
_ubershaderProvider,
|
||||||
|
&em,
|
||||||
_resourceLoader,
|
_resourceLoader,
|
||||||
_ncm,
|
_ncm,
|
||||||
_engine,
|
_engine,
|
||||||
_scene);
|
_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) {
|
void FilamentViewer::setFrameInterval(float frameInterval) {
|
||||||
Renderer::FrameRateOptions fro;
|
Renderer::FrameRateOptions fro;
|
||||||
fro.interval = frameInterval;
|
fro.interval = frameInterval;
|
||||||
@@ -260,52 +309,6 @@ void FilamentViewer::clearLights() {
|
|||||||
_lights.clear();
|
_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) {
|
static bool endsWith(string path, string ending) {
|
||||||
return path.compare(path.length() - ending.length(), ending.length(), ending) == 0;
|
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()
|
_imageTexture = Texture::Builder()
|
||||||
.width(_imageWidth)
|
.width(_imageWidth)
|
||||||
.height(_imageHeight)
|
.height(_imageHeight)
|
||||||
.levels(0xff)
|
.levels(0x01)
|
||||||
.format(channels == 3 ? Texture::InternalFormat::RGB16F
|
.format(channels == 3 ? Texture::InternalFormat::RGB16F
|
||||||
: Texture::InternalFormat::RGBA16F)
|
: Texture::InternalFormat::RGBA16F)
|
||||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
.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("showImage", 0);
|
||||||
|
_imageMaterial->setDefaultParameter("backgroundColor", RgbaType::sRGB, float4(r, g, b, a));
|
||||||
_imageMaterial->setDefaultParameter("backgroundColor", RgbType::sRGB, float3(color[0], color[1], color[2]));
|
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) {
|
void FilamentViewer::setBackgroundImage(const char *resourcePath) {
|
||||||
|
|
||||||
string resourcePathString(resourcePath);
|
string resourcePathString(resourcePath);
|
||||||
|
|
||||||
Log("Setting background image to %s", resourcePath);
|
Log("Setting background image to %s", resourcePath);
|
||||||
|
|
||||||
createImageRenderable();
|
clearBackgroundImage();
|
||||||
|
|
||||||
if (_imageTexture) {
|
|
||||||
Log("Destroying existing texture");
|
|
||||||
_engine->destroy(_imageTexture);
|
|
||||||
Log("Destroyed.");
|
|
||||||
_imageTexture = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
loadTextureFromPath(resourcePathString);
|
loadTextureFromPath(resourcePathString);
|
||||||
|
|
||||||
@@ -442,11 +451,8 @@ void FilamentViewer::setBackgroundImage(const char *resourcePath) {
|
|||||||
|
|
||||||
_imageMaterial->setDefaultParameter("transform", _imageScale);
|
_imageMaterial->setDefaultParameter("transform", _imageScale);
|
||||||
_imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler);
|
_imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler);
|
||||||
|
|
||||||
_imageMaterial->setDefaultParameter("showImage", 1);
|
_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() {
|
FilamentViewer::~FilamentViewer() {
|
||||||
clearAssets();
|
clearAssets();
|
||||||
delete _sceneAssetLoader;
|
delete _ubershaderAssetLoader;
|
||||||
|
delete _unlitAssetLoader;
|
||||||
_resourceLoader->asyncCancelLoad();
|
_resourceLoader->asyncCancelLoad();
|
||||||
_ubershaderProvider->destroyMaterials();
|
_ubershaderProvider->destroyMaterials();
|
||||||
_unlitProvider->destroyMaterials();
|
_unlitProvider->destroyMaterials();
|
||||||
AssetLoader::destroy(&_assetLoader);
|
|
||||||
for(auto it : _lights) {
|
for(auto it : _lights) {
|
||||||
_engine->destroy(it);
|
_engine->destroy(it);
|
||||||
}
|
}
|
||||||
@@ -609,14 +616,20 @@ void FilamentViewer::destroySwapChain() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneAsset *FilamentViewer::loadGlb(const char *const uri) {
|
SceneAsset *FilamentViewer::loadGlb(const char *const uri, bool unlit) {
|
||||||
SceneAsset *asset = _sceneAssetLoader->fromGlb(uri);
|
SceneAsset *asset;
|
||||||
|
if(unlit) {
|
||||||
|
asset = _unlitAssetLoader->fromGlb(uri);
|
||||||
|
} else {
|
||||||
|
asset = _ubershaderAssetLoader->fromGlb(uri);
|
||||||
|
}
|
||||||
if (!asset) {
|
if (!asset) {
|
||||||
Log("Unknown error loading asset.");
|
Log("Unknown error loading asset.");
|
||||||
} else {
|
} else {
|
||||||
_assets.push_back(asset);
|
_assets.push_back(asset);
|
||||||
Log("GLB loaded, asset at index %d", _assets.size() - 1);
|
Log("GLB loaded, asset at index %d", _assets.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,7 +637,7 @@ SceneAsset *FilamentViewer::loadGltf(const char *const uri,
|
|||||||
const char *const relativeResourcePath) {
|
const char *const relativeResourcePath) {
|
||||||
Log("Loading GLTF at URI %s with relativeResourcePath %s", uri,
|
Log("Loading GLTF at URI %s with relativeResourcePath %s", uri,
|
||||||
relativeResourcePath);
|
relativeResourcePath);
|
||||||
SceneAsset *asset = _sceneAssetLoader->fromGltf(uri, relativeResourcePath);
|
SceneAsset *asset = _ubershaderAssetLoader->fromGltf(uri, relativeResourcePath);
|
||||||
if (!asset) {
|
if (!asset) {
|
||||||
Log("Unknown error loading asset.");
|
Log("Unknown error loading asset.");
|
||||||
} else {
|
} else {
|
||||||
@@ -633,7 +646,6 @@ SceneAsset *FilamentViewer::loadGltf(const char *const uri,
|
|||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FilamentViewer::clearAssets() {
|
void FilamentViewer::clearAssets() {
|
||||||
Log("Clearing all assets");
|
Log("Clearing all assets");
|
||||||
if(_mainCamera) {
|
if(_mainCamera) {
|
||||||
@@ -645,12 +657,9 @@ void FilamentViewer::clearAssets() {
|
|||||||
_manipulator = nullptr;
|
_manipulator = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
_ubershaderAssetLoader->destroyAll();
|
||||||
for (auto asset : _assets) {
|
_unlitAssetLoader->destroyAll();
|
||||||
_sceneAssetLoader->remove(asset);
|
|
||||||
Log("Cleared asset %d", i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
_assets.clear();
|
_assets.clear();
|
||||||
Log("Cleared all assets");
|
Log("Cleared all assets");
|
||||||
}
|
}
|
||||||
@@ -661,19 +670,8 @@ void FilamentViewer::removeAsset(SceneAsset *asset) {
|
|||||||
mtx.lock();
|
mtx.lock();
|
||||||
// todo - what if we are using a camera from this asset?
|
// todo - what if we are using a camera from this asset?
|
||||||
_view->setCamera(_mainCamera);
|
_view->setCamera(_mainCamera);
|
||||||
_sceneAssetLoader->remove(asset);
|
_ubershaderAssetLoader->remove(asset);
|
||||||
|
_unlitAssetLoader->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");
|
|
||||||
}
|
|
||||||
mtx.unlock();
|
mtx.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,12 @@ extern "C" {
|
|||||||
delete((FilamentViewer*)viewer);
|
delete((FilamentViewer*)viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_background_color(void* viewer, const float* color) {
|
void set_background_color(void* viewer, const float r, const float g, const float b, const float a) {
|
||||||
((FilamentViewer*)viewer)->setBackgroundColor(color);
|
((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) {
|
void set_background_image(void* viewer, const char* path) {
|
||||||
@@ -63,8 +67,8 @@ extern "C" {
|
|||||||
((FilamentViewer*)viewer)->clearLights();
|
((FilamentViewer*)viewer)->clearLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* load_glb(void* viewer, const char* assetPath) {
|
void* load_glb(void* viewer, const char* assetPath, bool unlit) {
|
||||||
return ((FilamentViewer*)viewer)->loadGlb(assetPath);
|
return ((FilamentViewer*)viewer)->loadGlb(assetPath, unlit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath) {
|
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath) {
|
||||||
|
|||||||
@@ -10,14 +10,22 @@ using namespace filament::gltfio;
|
|||||||
|
|
||||||
SceneAssetLoader::SceneAssetLoader(LoadResource loadResource,
|
SceneAssetLoader::SceneAssetLoader(LoadResource loadResource,
|
||||||
FreeResource freeResource,
|
FreeResource freeResource,
|
||||||
AssetLoader *assetLoader,
|
MaterialProvider* materialProvider,
|
||||||
|
EntityManager* entityManager,
|
||||||
ResourceLoader *resourceLoader,
|
ResourceLoader *resourceLoader,
|
||||||
NameComponentManager *ncm,
|
NameComponentManager *ncm,
|
||||||
Engine *engine,
|
Engine *engine,
|
||||||
Scene *scene)
|
Scene *scene)
|
||||||
: _loadResource(loadResource), _freeResource(freeResource),
|
: _loadResource(loadResource), _freeResource(freeResource), _materialProvider(materialProvider), _entityManager(entityManager),
|
||||||
_assetLoader(assetLoader), _resourceLoader(resourceLoader), _ncm(ncm),
|
_resourceLoader(resourceLoader), _ncm(ncm),
|
||||||
_engine(engine), _scene(scene) {}
|
_engine(engine), _scene(scene) {
|
||||||
|
_assetLoader = AssetLoader::create({_engine, materialProvider, _ncm, entityManager});
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneAssetLoader::~SceneAssetLoader() {
|
||||||
|
destroyAll();
|
||||||
|
AssetLoader::destroy(&_assetLoader);
|
||||||
|
}
|
||||||
|
|
||||||
SceneAsset *SceneAssetLoader::fromGltf(const char *uri,
|
SceneAsset *SceneAssetLoader::fromGltf(const char *uri,
|
||||||
const char *relativeResourcePath) {
|
const char *relativeResourcePath) {
|
||||||
@@ -87,6 +95,7 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
|
|||||||
FilamentAsset *asset = _assetLoader->createAsset(
|
FilamentAsset *asset = _assetLoader->createAsset(
|
||||||
(const uint8_t *)rbuf.data, rbuf.size);
|
(const uint8_t *)rbuf.data, rbuf.size);
|
||||||
|
|
||||||
|
|
||||||
if (!asset) {
|
if (!asset) {
|
||||||
Log("Unknown error loading GLB asset.");
|
Log("Unknown error loading GLB asset.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -106,10 +115,16 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
|
|||||||
|
|
||||||
RenderableManager &rm = _engine->getRenderableManager();
|
RenderableManager &rm = _engine->getRenderableManager();
|
||||||
|
|
||||||
|
MaterialKey config;
|
||||||
|
auto mi_new = _materialProvider->createMaterialInstance(&config, nullptr);
|
||||||
|
|
||||||
// why did I need to explicitly enable culling?
|
// why did I need to explicitly enable culling?
|
||||||
for (int i = 0; i < asset->getEntityCount(); i++) {
|
for (int i = 0; i < asset->getEntityCount(); i++) {
|
||||||
auto entityInstance = rm.getInstance(entities[i]);
|
auto entityInstance = rm.getInstance(entities[i]);
|
||||||
rm.setCulling(entityInstance, true);
|
auto mi = rm.getMaterialInstanceAt(entityInstance, 0);
|
||||||
|
// auto m = mi->getMaterial();
|
||||||
|
// auto shading = m->getShading();
|
||||||
|
// Log("Shading %d", shading);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lights = asset->getLightEntities();
|
auto lights = asset->getLightEntities();
|
||||||
@@ -118,6 +133,8 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
|
|||||||
Log("Added %d lights to scene from asset", asset->getLightEntityCount());
|
Log("Added %d lights to scene from asset", asset->getLightEntityCount());
|
||||||
|
|
||||||
FilamentInstance* inst = asset->getInstance();
|
FilamentInstance* inst = asset->getInstance();
|
||||||
|
|
||||||
|
|
||||||
inst->getAnimator()->updateBoneMatrices();
|
inst->getAnimator()->updateBoneMatrices();
|
||||||
|
|
||||||
inst->recomputeBoundingBoxes();
|
inst->recomputeBoundingBoxes();
|
||||||
@@ -128,10 +145,43 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
|
|||||||
_freeResource(rbuf.id);
|
_freeResource(rbuf.id);
|
||||||
|
|
||||||
Log("Successfully loaded GLB.");
|
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) {
|
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.");
|
Log("Removing asset and all associated entities/lights.");
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'animations/animation_builder.dart';
|
import 'animations/animation_builder.dart';
|
||||||
import 'animations/animations.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.
|
// this is confusing - "FilamentAsset" actually defines a pointer to a SceneAsset, whereas FilamentLight is an Entity ID.
|
||||||
// should make this consistent
|
// should make this consistent
|
||||||
typedef FilamentAsset = int;
|
typedef FilamentAsset = int;
|
||||||
@@ -26,11 +26,12 @@ abstract class FilamentController {
|
|||||||
void setPixelRatio(double ratio);
|
void setPixelRatio(double ratio);
|
||||||
Future resize(int width, int height, {double contentScaleFactor = 1});
|
Future resize(int width, int height, {double contentScaleFactor = 1});
|
||||||
Future setBackgroundColor(Color color);
|
Future setBackgroundColor(Color color);
|
||||||
|
Future clearBackgroundImage();
|
||||||
Future setBackgroundImage(String path);
|
Future setBackgroundImage(String path);
|
||||||
Future setBackgroundImagePosition(double x, double y, {bool clamp = false});
|
Future setBackgroundImagePosition(double x, double y, {bool clamp = false});
|
||||||
Future loadSkybox(String skyboxPath);
|
Future loadSkybox(String skyboxPath);
|
||||||
Future removeSkybox();
|
Future removeSkybox();
|
||||||
Future loadIbl(String path);
|
Future loadIbl(String path, {double intensity = 30000});
|
||||||
Future removeIbl();
|
Future removeIbl();
|
||||||
|
|
||||||
// copied from LightManager.h
|
// copied from LightManager.h
|
||||||
@@ -54,7 +55,7 @@ abstract class FilamentController {
|
|||||||
bool castShadows);
|
bool castShadows);
|
||||||
Future removeLight(FilamentLight light);
|
Future removeLight(FilamentLight light);
|
||||||
Future clearLights();
|
Future clearLights();
|
||||||
Future<FilamentAsset> loadGlb(String path);
|
Future<FilamentAsset> loadGlb(String path, {bool unlit = false});
|
||||||
Future<FilamentAsset> loadGltf(String path, String relativeResourcePath);
|
Future<FilamentAsset> loadGltf(String path, String relativeResourcePath);
|
||||||
Future zoomBegin();
|
Future zoomBegin();
|
||||||
Future zoomUpdate(double z);
|
Future zoomUpdate(double z);
|
||||||
@@ -172,6 +173,11 @@ class PolyvoxFilamentController extends FilamentController {
|
|||||||
_textureIdController.add(_textureId);
|
_textureIdController.add(_textureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future clearBackgroundImage() async {
|
||||||
|
await _channel.invokeMethod("clearBackgroundImage");
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setBackgroundImage(String path) async {
|
Future setBackgroundImage(String path) async {
|
||||||
await _channel.invokeMethod("setBackgroundImage", path);
|
await _channel.invokeMethod("setBackgroundImage", path);
|
||||||
@@ -179,15 +185,12 @@ class PolyvoxFilamentController extends FilamentController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setBackgroundColor(Color color) async {
|
Future setBackgroundColor(Color color) async {
|
||||||
print(
|
await _channel.invokeMethod("setBackgroundColor", [
|
||||||
"setting to ${color.red.toDouble() / 255.0} ${color.blue.toDouble() / 255.0} ${color.red.toDouble() / 255.0}");
|
color.red.toDouble() / 255.0,
|
||||||
await _channel.invokeMethod(
|
color.green.toDouble() / 255.0,
|
||||||
"setBackgroundColor",
|
color.blue.toDouble() / 255.0,
|
||||||
Float32List.fromList([
|
color.alpha.toDouble() / 255.0
|
||||||
color.red.toDouble() / 255.0,
|
]);
|
||||||
color.green.toDouble() / 255.0,
|
|
||||||
color.blue.toDouble() / 255.0
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -253,9 +256,9 @@ class PolyvoxFilamentController extends FilamentController {
|
|||||||
return _channel.invokeMethod("clearLights");
|
return _channel.invokeMethod("clearLights");
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<FilamentAsset> loadGlb(String path) async {
|
Future<FilamentAsset> loadGlb(String path, {bool unlit = false}) async {
|
||||||
print("Loading GLB at $path ");
|
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) {
|
if (asset == FILAMENT_ASSET_ERROR) {
|
||||||
throw Exception("An error occurred loading the asset at $path");
|
throw Exception("An error occurred loading the asset at $path");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -35,6 +36,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool _rotating = false;
|
bool _rotating = false;
|
||||||
|
bool _scaling = false;
|
||||||
|
|
||||||
// to avoid duplicating code for pan/rotate (panStart, panUpdate, panEnd, rotateStart, rotateUpdate etc)
|
// to avoid duplicating code for pan/rotate (panStart, panUpdate, panEnd, rotateStart, rotateUpdate etc)
|
||||||
// we have only a single function for start/update/end.
|
// we have only a single function for start/update/end.
|
||||||
@@ -100,6 +102,8 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
|||||||
onScaleStart: !widget.enableControls
|
onScaleStart: !widget.enableControls
|
||||||
? null
|
? null
|
||||||
: (d) async {
|
: (d) async {
|
||||||
|
_scaling = true;
|
||||||
|
print("SCALE START");
|
||||||
if (d.pointerCount == 2) {
|
if (d.pointerCount == 2) {
|
||||||
await widget.controller.zoomEnd();
|
await widget.controller.zoomEnd();
|
||||||
await widget.controller.zoomBegin();
|
await widget.controller.zoomBegin();
|
||||||
@@ -108,6 +112,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
|||||||
onScaleEnd: !widget.enableControls
|
onScaleEnd: !widget.enableControls
|
||||||
? null
|
? null
|
||||||
: (d) async {
|
: (d) async {
|
||||||
|
_scaling = false;
|
||||||
if (d.pointerCount == 2) {
|
if (d.pointerCount == 2) {
|
||||||
_lastScale = 0;
|
_lastScale = 0;
|
||||||
await widget.controller.zoomEnd();
|
await widget.controller.zoomEnd();
|
||||||
@@ -118,8 +123,9 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
|||||||
: (d) async {
|
: (d) async {
|
||||||
if (d.pointerCount == 2) {
|
if (d.pointerCount == 2) {
|
||||||
if (_lastScale != 0) {
|
if (_lastScale != 0) {
|
||||||
await widget.controller
|
await widget.controller.zoomUpdate(Platform.isIOS
|
||||||
.zoomUpdate(100 * (_lastScale - d.scale));
|
? 1000 * (_lastScale - d.scale)
|
||||||
|
: 100 * (_lastScale - d.scale));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_lastScale = d.scale;
|
_lastScale = d.scale;
|
||||||
@@ -128,6 +134,8 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
|||||||
onPointerSignal: !widget.enableControls
|
onPointerSignal: !widget.enableControls
|
||||||
? null
|
? null
|
||||||
: (pointerSignal) async {
|
: (pointerSignal) async {
|
||||||
|
print("ponter signal");
|
||||||
|
|
||||||
// scroll-wheel zoom on desktop
|
// scroll-wheel zoom on desktop
|
||||||
if (pointerSignal is PointerScrollEvent) {
|
if (pointerSignal is PointerScrollEvent) {
|
||||||
_scrollTimer?.cancel();
|
_scrollTimer?.cancel();
|
||||||
@@ -146,6 +154,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
|||||||
onPointerDown: !widget.enableControls
|
onPointerDown: !widget.enableControls
|
||||||
? null
|
? null
|
||||||
: (d) async {
|
: (d) async {
|
||||||
|
print("piinterodoiwn");
|
||||||
if (d.buttons == kTertiaryButton || _rotating) {
|
if (d.buttons == kTertiaryButton || _rotating) {
|
||||||
await widget.controller.rotateStart(
|
await widget.controller.rotateStart(
|
||||||
d.localPosition.dx, d.localPosition.dy);
|
d.localPosition.dx, d.localPosition.dy);
|
||||||
@@ -157,6 +166,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
|||||||
onPointerMove: !widget.enableControls
|
onPointerMove: !widget.enableControls
|
||||||
? null
|
? null
|
||||||
: (d) async {
|
: (d) async {
|
||||||
|
print("pointermove");
|
||||||
if (d.buttons == kTertiaryButton || _rotating) {
|
if (d.buttons == kTertiaryButton || _rotating) {
|
||||||
await widget.controller.rotateUpdate(
|
await widget.controller.rotateUpdate(
|
||||||
d.localPosition.dx, d.localPosition.dy);
|
d.localPosition.dx, d.localPosition.dy);
|
||||||
@@ -168,6 +178,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
|||||||
onPointerUp: !widget.enableControls
|
onPointerUp: !widget.enableControls
|
||||||
? null
|
? null
|
||||||
: (d) async {
|
: (d) async {
|
||||||
|
print("pointerup");
|
||||||
if (d.buttons == kTertiaryButton || _rotating) {
|
if (d.buttons == kTertiaryButton || _rotating) {
|
||||||
await widget.controller.rotateEnd();
|
await widget.controller.rotateEnd();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ set(PLUGIN_NAME "polyvox_filament_plugin")
|
|||||||
link_directories("${CMAKE_CURRENT_SOURCE_DIR}/lib")
|
link_directories("${CMAKE_CURRENT_SOURCE_DIR}/lib")
|
||||||
|
|
||||||
add_library(FILAMENT_SHADERS SHARED
|
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"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/include/material/unlit_opaque.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,178 @@
|
|||||||
material {
|
material {
|
||||||
name : BakedColor,
|
name : unlit_opaque,
|
||||||
requires : [
|
requires : [ uv0, uv1, color ],
|
||||||
color
|
|
||||||
],
|
|
||||||
shadingModel : unlit,
|
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 {
|
fragment {
|
||||||
void material(inout MaterialInputs material) {
|
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);
|
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}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user