fix camera manipulator/gesture detector, add explicit functions to set camera pos/rot, add unlitshader material provider
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:2735c0b6fef502c35f3d2c28d1e8da262108cd6a60bbeb2c27fa23bee3f49842
|
oid sha256:c26d06b2f1b12264ac0f6c5aa10c6ede5670ca5ca18d1aa4023835eee342d4f1
|
||||||
size 41236
|
size 41672
|
||||||
|
|||||||
@@ -69,6 +69,7 @@
|
|||||||
#include "image/imagematerials_ios.h"
|
#include "image/imagematerials_ios.h"
|
||||||
#else
|
#else
|
||||||
#include "image/imagematerial.h"
|
#include "image/imagematerial.h"
|
||||||
|
#include "shaders/unlitopaque.h"
|
||||||
#endif
|
#endif
|
||||||
#include "FilamentViewer.hpp"
|
#include "FilamentViewer.hpp"
|
||||||
#include "StreamBufferAdapter.hpp"
|
#include "StreamBufferAdapter.hpp"
|
||||||
@@ -86,6 +87,48 @@ class LightManager;
|
|||||||
|
|
||||||
namespace polyvox {
|
namespace polyvox {
|
||||||
|
|
||||||
|
class UnlitMaterialProvider : public MaterialProvider {
|
||||||
|
|
||||||
|
const Material* _m;
|
||||||
|
const Material* _ms[1];
|
||||||
|
|
||||||
|
public:
|
||||||
|
UnlitMaterialProvider(Engine* engine) {
|
||||||
|
_m = Material::Builder()
|
||||||
|
.package(UNLITOPAQUE_UNLIT_OPAQUE_DATA, UNLITOPAQUE_UNLIT_OPAQUE_SIZE)
|
||||||
|
.build(*engine);
|
||||||
|
_ms[0] = _m;
|
||||||
|
}
|
||||||
|
|
||||||
|
filament::MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap,
|
||||||
|
const char* label = "material", const char* extras = nullptr) {
|
||||||
|
MaterialInstance* d = (MaterialInstance*)_m->getDefaultInstance();
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a weak reference to the array of cached materials.
|
||||||
|
*/
|
||||||
|
const filament::Material* const* getMaterials() const noexcept {
|
||||||
|
return _ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of cached materials.
|
||||||
|
*/
|
||||||
|
size_t getMaterialsCount() const noexcept {
|
||||||
|
return (size_t)1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyMaterials() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool needsDummyData(filament::VertexAttribute attrib) const noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const double kNearPlane = 0.05; // 5 cm
|
const double kNearPlane = 0.05; // 5 cm
|
||||||
const double kFarPlane = 1000.0; // 1 km
|
const double kFarPlane = 1000.0; // 1 km
|
||||||
const float kScaleMultiplier = 100.0f;
|
const float kScaleMultiplier = 100.0f;
|
||||||
@@ -160,7 +203,9 @@ FilamentViewer::FilamentViewer(void *layer, LoadResource loadResource,
|
|||||||
|
|
||||||
_view->setMultiSampleAntiAliasingOptions(multiSampleAntiAliasingOptions);
|
_view->setMultiSampleAntiAliasingOptions(multiSampleAntiAliasingOptions);
|
||||||
|
|
||||||
_materialProvider = gltfio::createUbershaderProvider(
|
_materialProvider =
|
||||||
|
// new UnlitMaterialProvider(_engine);
|
||||||
|
gltfio::createUbershaderProvider(
|
||||||
_engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
|
_engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
|
||||||
|
|
||||||
EntityManager &em = EntityManager::get();
|
EntityManager &em = EntityManager::get();
|
||||||
@@ -172,10 +217,6 @@ FilamentViewer::FilamentViewer(void *layer, LoadResource loadResource,
|
|||||||
_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);
|
||||||
manipulator = Manipulator<float>::Builder()
|
|
||||||
.orbitHomePosition(0.0f, 0.0f, 1.0f)
|
|
||||||
.targetPosition(0.0f, 0.0f, 0.0f)
|
|
||||||
.build(Mode::ORBIT);
|
|
||||||
|
|
||||||
// Always add a direct light source since it is required for shadowing.
|
// Always add a direct light source since it is required for shadowing.
|
||||||
_sun = EntityManager::get().create();
|
_sun = EntityManager::get().create();
|
||||||
@@ -407,6 +448,11 @@ void FilamentViewer::clearAssets() {
|
|||||||
_view->setCamera(_mainCamera);
|
_view->setCamera(_mainCamera);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_manipulator) {
|
||||||
|
delete _manipulator;
|
||||||
|
_manipulator = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto asset : _assets) {
|
for (auto asset : _assets) {
|
||||||
_sceneAssetLoader->remove(asset);
|
_sceneAssetLoader->remove(asset);
|
||||||
@@ -579,21 +625,23 @@ void FilamentViewer::render() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mtx.lock();
|
|
||||||
for (auto &asset : _assets) {
|
for (auto &asset : _assets) {
|
||||||
asset->updateAnimations();
|
asset->updateAnimations();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_manipulator) {
|
||||||
math::float3 eye, target, upward;
|
math::float3 eye, target, upward;
|
||||||
manipulator->getLookAt(&eye, &target, &upward);
|
Camera& cam =_view->getCamera();
|
||||||
_mainCamera->lookAt(eye, target, upward);
|
_manipulator->getLookAt(&eye, &target, &upward);
|
||||||
|
cam.lookAt(eye, target, upward);
|
||||||
|
}
|
||||||
|
|
||||||
// Render the scene, unless the renderer wants to skip the frame.
|
// Render the scene, unless the renderer wants to skip the frame.
|
||||||
if (_renderer->beginFrame(_swapChain)) {
|
if (_renderer->beginFrame(_swapChain)) {
|
||||||
_renderer->render(_view);
|
_renderer->render(_view);
|
||||||
_renderer->endFrame();
|
_renderer->endFrame();
|
||||||
}
|
}
|
||||||
// mtx.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilamentViewer::updateViewportAndCameraProjection(
|
void FilamentViewer::updateViewportAndCameraProjection(
|
||||||
@@ -622,11 +670,57 @@ void FilamentViewer::updateViewportAndCameraProjection(
|
|||||||
void FilamentViewer::setCameraPosition(float x, float y, float z) {
|
void FilamentViewer::setCameraPosition(float x, float y, float z) {
|
||||||
Camera& cam =_view->getCamera();
|
Camera& cam =_view->getCamera();
|
||||||
auto &tm = _engine->getTransformManager();
|
auto &tm = _engine->getTransformManager();
|
||||||
// tm.setTransform(tm.getInstance(_asset->getRoot()), math::mat4f::translation(math::float3(x,y,z)) * _cameraRotation);
|
_cameraPosition = math::mat4f::translation(math::float3(x,y,z));
|
||||||
|
cam.setModelMatrix(_cameraPosition * _cameraRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilamentViewer::setCameraRotation(float rads, float x, float y, float z) {
|
void FilamentViewer::setCameraRotation(float rads, float x, float y, float z) {
|
||||||
Camera& cam =_view->getCamera();
|
Camera& cam =_view->getCamera();
|
||||||
|
auto &tm = _engine->getTransformManager();
|
||||||
|
_cameraRotation = math::mat4f::rotation(rads, math::float3(x,y,z));
|
||||||
|
cam.setModelMatrix(_cameraPosition * _cameraRotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilamentViewer::grabBegin(float x, float y, bool pan) {
|
||||||
|
if(!_manipulator) {
|
||||||
|
Camera& cam =_view->getCamera();
|
||||||
|
math::float3 home = cam.getPosition();
|
||||||
|
math::float3 fv = cam.getForwardVector();
|
||||||
|
Viewport const& vp = _view->getViewport();
|
||||||
|
_manipulator = Manipulator<float>::Builder()
|
||||||
|
.viewport(vp.width, vp.height)
|
||||||
|
.orbitHomePosition(home[0], home[1], home[2])
|
||||||
|
.targetPosition(fv[0], fv[1], fv[2])
|
||||||
|
.build(Mode::ORBIT);
|
||||||
|
Log("Created manipualtor for vp width %d height %d ", vp.width, vp.height);
|
||||||
|
} else {
|
||||||
|
// Log("Error - calling grabBegin while another grab session is active. This will probably cause weirdness");
|
||||||
|
}
|
||||||
|
_manipulator->grabBegin(x, y, pan);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilamentViewer::grabUpdate(float x, float y) {
|
||||||
|
if(_manipulator) {
|
||||||
|
Log("grab update %f %f", x, y);
|
||||||
|
_manipulator->grabUpdate(x, y);
|
||||||
|
} else {
|
||||||
|
Log("Error - trying to use a manipulator when one is not available. Ensure you call grabBegin before grabUpdate/grabEnd");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilamentViewer::grabEnd() {
|
||||||
|
if(_manipulator) {
|
||||||
|
_manipulator->grabEnd();
|
||||||
|
// delete _manipulator;
|
||||||
|
} else {
|
||||||
|
Log("Error - trying to use a manipulator when one is not available. Ensure you call grabBegin before grabUpdate/grabEnd");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilamentViewer::scroll(float x, float y, float delta) {
|
||||||
|
if(_manipulator) {
|
||||||
|
_manipulator->scroll(x, y, delta);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace polyvox
|
} // namespace polyvox
|
||||||
|
|||||||
@@ -63,8 +63,6 @@ namespace polyvox {
|
|||||||
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
|
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
Manipulator<float>* manipulator;
|
|
||||||
|
|
||||||
bool setFirstCamera(SceneAsset* asset);
|
bool setFirstCamera(SceneAsset* asset);
|
||||||
bool setCamera(SceneAsset* asset, const char* nodeName);
|
bool setCamera(SceneAsset* asset, const char* nodeName);
|
||||||
void destroySwapChain();
|
void destroySwapChain();
|
||||||
@@ -79,6 +77,11 @@ namespace polyvox {
|
|||||||
void setCameraFocalLength(float fl);
|
void setCameraFocalLength(float fl);
|
||||||
void setCameraFocusDistance(float focusDistance);
|
void setCameraFocusDistance(float focusDistance);
|
||||||
|
|
||||||
|
void grabBegin(float x, float y, bool pan);
|
||||||
|
void grabUpdate(float x, float y);
|
||||||
|
void grabEnd();
|
||||||
|
void scroll(float x, float y, float delta);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createImageRenderable();
|
void createImageRenderable();
|
||||||
void loadResources(std::string relativeResourcePath);
|
void loadResources(std::string relativeResourcePath);
|
||||||
@@ -87,6 +90,10 @@ namespace polyvox {
|
|||||||
|
|
||||||
void* _layer;
|
void* _layer;
|
||||||
|
|
||||||
|
Manipulator<float>* _manipulator;
|
||||||
|
math::mat4f _cameraPosition;
|
||||||
|
math::mat4f _cameraRotation;
|
||||||
|
|
||||||
LoadResource _loadResource;
|
LoadResource _loadResource;
|
||||||
FreeResource _freeResource;
|
FreeResource _freeResource;
|
||||||
|
|
||||||
|
|||||||
@@ -87,21 +87,21 @@ extern "C" {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll(void* viewer, float x, float y , float z) {
|
void scroll(void* viewer, float x, float y, float delta) {
|
||||||
return ((FilamentViewer*)viewer)->manipulator->scroll(x, y, z);
|
return ((FilamentViewer*)viewer)->scroll(x, y, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grab_begin(void* viewer, int x, int y, bool pan) {
|
void grab_begin(void* viewer, float x, float y, bool pan) {
|
||||||
((FilamentViewer*)viewer)->manipulator->grabBegin(x, y, pan);
|
|
||||||
|
|
||||||
|
((FilamentViewer*)viewer)->grabBegin(x, y, pan);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grab_update(void* viewer, int x, int y) {
|
void grab_update(void* viewer, float x, float y) {
|
||||||
((FilamentViewer*)viewer)->manipulator->grabUpdate(x, y);
|
((FilamentViewer*)viewer)->grabUpdate(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grab_end(void* viewer) {
|
void grab_end(void* viewer) {
|
||||||
((FilamentViewer*)viewer)->manipulator->grabEnd();
|
((FilamentViewer*)viewer)->grabEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply_weights(void* asset, float* const weights, int count) {
|
void apply_weights(void* asset, float* const weights, int count) {
|
||||||
@@ -166,6 +166,10 @@ extern "C" {
|
|||||||
((SceneAsset*)asset)->setRotation(rads, x, y, z);
|
((SceneAsset*)asset)->setRotation(rads, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_scale(void* asset, float scale) {
|
||||||
|
((SceneAsset*)asset)->setScale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
void stop_animation(void* asset, int index) {
|
void stop_animation(void* asset, int index) {
|
||||||
((SceneAsset*)asset)->stopAnimation(index);
|
((SceneAsset*)asset)->stopAnimation(index);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ void SceneAsset::loadTexture(const char* resourcePath, int renderableIndex) {
|
|||||||
|
|
||||||
Log("Loading texture at %s for renderableIndex %d", resourcePath, renderableIndex);
|
Log("Loading texture at %s for renderableIndex %d", resourcePath, renderableIndex);
|
||||||
|
|
||||||
string rp("flutter_assets/assets/background.png");
|
string rp(resourcePath);
|
||||||
|
|
||||||
if(_texture) {
|
if(_texture) {
|
||||||
_engine->destroy(_texture);
|
_engine->destroy(_texture);
|
||||||
@@ -161,8 +161,6 @@ void SceneAsset::loadTexture(const char* resourcePath, int renderableIndex) {
|
|||||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
.sampler(Texture::Sampler::SAMPLER_2D)
|
||||||
.build(*_engine);
|
.build(*_engine);
|
||||||
|
|
||||||
Log("build texture");
|
|
||||||
|
|
||||||
Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t,
|
Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t,
|
||||||
void *data) {
|
void *data) {
|
||||||
delete reinterpret_cast<LinearImage *>(data);
|
delete reinterpret_cast<LinearImage *>(data);
|
||||||
@@ -174,7 +172,6 @@ void SceneAsset::loadTexture(const char* resourcePath, int renderableIndex) {
|
|||||||
Texture::Type::FLOAT, freeCallback);
|
Texture::Type::FLOAT, freeCallback);
|
||||||
|
|
||||||
_texture->setImage(*_engine, 0, std::move(buffer));
|
_texture->setImage(*_engine, 0, std::move(buffer));
|
||||||
Log("set image");
|
|
||||||
setTexture();
|
setTexture();
|
||||||
delete inputStream;
|
delete inputStream;
|
||||||
|
|
||||||
@@ -290,32 +287,28 @@ void SceneAsset::transformToUnitCube() {
|
|||||||
tm.setTransform(tm.getInstance(_asset->getRoot()), transform);
|
tm.setTransform(tm.getInstance(_asset->getRoot()), transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneAsset::setPosition(float x, float y, float z) {
|
void SceneAsset::updateTransform() {
|
||||||
Log("Setting position to %f %f %f", x, y, z);
|
|
||||||
auto &tm = _engine->getTransformManager();
|
auto &tm = _engine->getTransformManager();
|
||||||
_position = math::mat4f::translation(math::float3(x,y,z));
|
|
||||||
auto aabb = _asset->getBoundingBox();
|
|
||||||
auto center = aabb.center();
|
|
||||||
auto halfExtent = aabb.extent();
|
|
||||||
auto maxExtent = max(halfExtent) * 2;
|
|
||||||
auto scaleFactor = 2.0f / maxExtent;
|
|
||||||
auto transform =
|
auto transform =
|
||||||
math::mat4f::scaling(scaleFactor) * math::mat4f::translation(-center) * _position * _rotation;
|
math::mat4f::scaling(_scale) * _position * _rotation;
|
||||||
tm.setTransform(tm.getInstance(_asset->getRoot()), transform);
|
tm.setTransform(tm.getInstance(_asset->getRoot()), transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneAsset::setScale(float scale) {
|
||||||
|
_scale = scale;
|
||||||
|
updateTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneAsset::setPosition(float x, float y, float z) {
|
||||||
|
Log("Setting position to %f %f %f", x, y, z);
|
||||||
|
_position = math::mat4f::translation(math::float3(x,y,z));
|
||||||
|
updateTransform();
|
||||||
|
}
|
||||||
|
|
||||||
void SceneAsset::setRotation(float rads, float x, float y, float z) {
|
void SceneAsset::setRotation(float rads, float x, float y, float z) {
|
||||||
Log("Rotating %f radians around axis %f %f %f", x, y, z);
|
Log("Rotating %f radians around axis %f %f %f", rads, x, y, z);
|
||||||
auto &tm = _engine->getTransformManager();
|
|
||||||
_rotation = math::mat4f::rotation(rads, math::float3(x,y,z));
|
_rotation = math::mat4f::rotation(rads, math::float3(x,y,z));
|
||||||
auto aabb = _asset->getBoundingBox();
|
updateTransform();
|
||||||
auto center = aabb.center();
|
|
||||||
auto halfExtent = aabb.extent();
|
|
||||||
auto maxExtent = max(halfExtent) * 2;
|
|
||||||
auto scaleFactor = 2.0f / maxExtent;
|
|
||||||
auto transform =
|
|
||||||
math::mat4f::scaling(scaleFactor) * math::mat4f::translation(-center) * _position * _rotation;
|
|
||||||
tm.setTransform(tm.getInstance(_asset->getRoot()), transform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ namespace polyvox {
|
|||||||
|
|
||||||
void transformToUnitCube();
|
void transformToUnitCube();
|
||||||
|
|
||||||
|
void setScale(float scale);
|
||||||
|
|
||||||
void setPosition(float x, float y, float z);
|
void setPosition(float x, float y, float z);
|
||||||
|
|
||||||
void setRotation(float rads, float x, float y, float z);
|
void setRotation(float rads, float x, float y, float z);
|
||||||
@@ -108,6 +110,9 @@ namespace polyvox {
|
|||||||
|
|
||||||
math::mat4f _position;
|
math::mat4f _position;
|
||||||
math::mat4f _rotation;
|
math::mat4f _rotation;
|
||||||
|
float _scale = 1;
|
||||||
|
|
||||||
|
void updateTransform();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
12
ios/src/shaders/unlitopaque.S
Normal file
12
ios/src/shaders/unlitopaque.S
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.global UNLITOPAQUE_UNLIT_OPAQUE_OFFSET;
|
||||||
|
.global UNLITOPAQUE_UNLIT_OPAQUE_SIZE;
|
||||||
|
|
||||||
|
.global UNLITOPAQUE_PACKAGE
|
||||||
|
.section .rodata
|
||||||
|
UNLITOPAQUE_PACKAGE:
|
||||||
|
.incbin "unlitopaque.bin"
|
||||||
|
UNLITOPAQUE_UNLIT_OPAQUE_OFFSET:
|
||||||
|
.int 0
|
||||||
|
UNLITOPAQUE_UNLIT_OPAQUE_SIZE:
|
||||||
|
.int 35615
|
||||||
|
|
||||||
12
ios/src/shaders/unlitopaque.apple.S
Normal file
12
ios/src/shaders/unlitopaque.apple.S
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.global _UNLITOPAQUE_UNLIT_OPAQUE_OFFSET;
|
||||||
|
.global _UNLITOPAQUE_UNLIT_OPAQUE_SIZE;
|
||||||
|
|
||||||
|
.global _UNLITOPAQUE_PACKAGE
|
||||||
|
.section __TEXT,__const
|
||||||
|
_UNLITOPAQUE_PACKAGE:
|
||||||
|
.incbin "unlitopaque.bin"
|
||||||
|
_UNLITOPAQUE_UNLIT_OPAQUE_OFFSET:
|
||||||
|
.int 0
|
||||||
|
_UNLITOPAQUE_UNLIT_OPAQUE_SIZE:
|
||||||
|
.int 35615
|
||||||
|
|
||||||
BIN
ios/src/shaders/unlitopaque.bin
Normal file
BIN
ios/src/shaders/unlitopaque.bin
Normal file
Binary file not shown.
1790
ios/src/shaders/unlitopaque.c
Normal file
1790
ios/src/shaders/unlitopaque.c
Normal file
File diff suppressed because it is too large
Load Diff
13
ios/src/shaders/unlitopaque.h
Normal file
13
ios/src/shaders/unlitopaque.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef UNLITOPAQUE_H_
|
||||||
|
#define UNLITOPAQUE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
extern const uint8_t UNLITOPAQUE_PACKAGE[];
|
||||||
|
extern int UNLITOPAQUE_UNLIT_OPAQUE_OFFSET;
|
||||||
|
extern int UNLITOPAQUE_UNLIT_OPAQUE_SIZE;
|
||||||
|
}
|
||||||
|
#define UNLITOPAQUE_UNLIT_OPAQUE_DATA (UNLITOPAQUE_PACKAGE + UNLITOPAQUE_UNLIT_OPAQUE_OFFSET)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -7,8 +7,8 @@ typedef FilamentAsset = int;
|
|||||||
abstract class FilamentController {
|
abstract class FilamentController {
|
||||||
late int textureId;
|
late int textureId;
|
||||||
Future get initialized;
|
Future get initialized;
|
||||||
Future initialize(int width, int height);
|
Future initialize(int width, int height, { double devicePixelRatio = 1});
|
||||||
Future resize(int width, int height, {double contentScaleFactor=1});
|
Future resize(int width, int height, { double devicePixelRatio = 1, double contentScaleFactor=1});
|
||||||
Future setBackgroundImage(String path);
|
Future setBackgroundImage(String path);
|
||||||
Future loadSkybox(String skyboxPath);
|
Future loadSkybox(String skyboxPath);
|
||||||
Future removeSkybox();
|
Future removeSkybox();
|
||||||
@@ -38,11 +38,16 @@ abstract class FilamentController {
|
|||||||
Future setPosition(FilamentAsset asset, double x, double y, double z);
|
Future setPosition(FilamentAsset asset, double x, double y, double z);
|
||||||
Future setRotation(
|
Future setRotation(
|
||||||
FilamentAsset asset, double rads, double x, double y, double z);
|
FilamentAsset asset, double rads, double x, double y, double z);
|
||||||
|
Future setScale(
|
||||||
|
FilamentAsset asset, double scale);
|
||||||
Future setCameraFocalLength(
|
Future setCameraFocalLength(
|
||||||
double focalLength);
|
double focalLength);
|
||||||
Future setCameraFocusDistance(
|
Future setCameraFocusDistance(
|
||||||
double focusDistance);
|
double focusDistance);
|
||||||
|
Future setCameraPosition(
|
||||||
|
double x, double y, double z);
|
||||||
|
Future setCameraRotation(
|
||||||
|
double rads, double x, double y, double z);
|
||||||
///
|
///
|
||||||
/// Set the weights of all morph targets in the mesh to the specified weights at successive frames (where each frame requires a duration of [frameLengthInMs].
|
/// Set the weights of all morph targets in the mesh to the specified weights at successive frames (where each frame requires a duration of [frameLengthInMs].
|
||||||
/// Accepts a list of doubles representing a sequence of "frames", stacked end-to-end.
|
/// Accepts a list of doubles representing a sequence of "frames", stacked end-to-end.
|
||||||
@@ -55,7 +60,9 @@ abstract class FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PolyvoxFilamentController extends FilamentController {
|
class PolyvoxFilamentController extends FilamentController {
|
||||||
|
|
||||||
late MethodChannel _channel = MethodChannel("app.polyvox.filament/event");
|
late MethodChannel _channel = MethodChannel("app.polyvox.filament/event");
|
||||||
|
late double _devicePixelRatio;
|
||||||
|
|
||||||
final _initialized = Completer();
|
final _initialized = Completer();
|
||||||
Future get initialized => _initialized.future;
|
Future get initialized => _initialized.future;
|
||||||
@@ -67,13 +74,15 @@ class PolyvoxFilamentController extends FilamentController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future initialize(int width, int height) async {
|
Future initialize(int width, int height, { double devicePixelRatio=1 }) async {
|
||||||
textureId = await _channel.invokeMethod("initialize", [width, height]);
|
_devicePixelRatio = devicePixelRatio;
|
||||||
|
textureId = await _channel.invokeMethod("initialize", [width*devicePixelRatio, height*devicePixelRatio]);
|
||||||
_initialized.complete(true);
|
_initialized.complete(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future resize(int width, int height, { double contentScaleFactor=1.0}) async {
|
Future resize(int width, int height, { double devicePixelRatio=1, double contentScaleFactor=1.0}) async {
|
||||||
await _channel.invokeMethod("resize", [width, height, contentScaleFactor]);
|
_devicePixelRatio = devicePixelRatio;
|
||||||
|
await _channel.invokeMethod("resize", [width*devicePixelRatio, height*devicePixelRatio, contentScaleFactor]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -118,11 +127,11 @@ class PolyvoxFilamentController extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future panStart(double x, double y) async {
|
Future panStart(double x, double y) async {
|
||||||
await _channel.invokeMethod("panStart", [x.toInt(), y.toInt()]);
|
await _channel.invokeMethod("panStart", [x * _devicePixelRatio, y * _devicePixelRatio]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future panUpdate(double x, double y) async {
|
Future panUpdate(double x, double y) async {
|
||||||
await _channel.invokeMethod("panUpdate", [x.toInt(), y.toInt()]);
|
await _channel.invokeMethod("panUpdate", [x * _devicePixelRatio, y * _devicePixelRatio]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future panEnd() async {
|
Future panEnd() async {
|
||||||
@@ -130,11 +139,11 @@ class PolyvoxFilamentController extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future rotateStart(double x, double y) async {
|
Future rotateStart(double x, double y) async {
|
||||||
await _channel.invokeMethod("rotateStart", [x.toInt(), y.toInt()]);
|
await _channel.invokeMethod("rotateStart", [x * _devicePixelRatio, y * _devicePixelRatio]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future rotateUpdate(double x, double y) async {
|
Future rotateUpdate(double x, double y) async {
|
||||||
await _channel.invokeMethod("rotateUpdate", [x.toInt(), y.toInt()]);
|
await _channel.invokeMethod("rotateUpdate", [x * _devicePixelRatio, y * _devicePixelRatio]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future rotateEnd() async {
|
Future rotateEnd() async {
|
||||||
@@ -174,7 +183,7 @@ class PolyvoxFilamentController extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future zoom(double z) async {
|
Future zoom(double z) async {
|
||||||
await _channel.invokeMethod("zoom", z);
|
await _channel.invokeMethod("zoom", [0.0,0.0,z]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future playAnimation(FilamentAsset asset, int index,
|
Future playAnimation(FilamentAsset asset, int index,
|
||||||
@@ -205,6 +214,16 @@ class PolyvoxFilamentController extends FilamentController {
|
|||||||
await _channel.invokeMethod("setCameraFocusDistance", focusDistance);
|
await _channel.invokeMethod("setCameraFocusDistance", focusDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future setCameraPosition(
|
||||||
|
double x, double y, double z) async {
|
||||||
|
await _channel.invokeMethod("setCameraPosition", [x,y,z]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future setCameraRotation(
|
||||||
|
double rads, double x, double y, double z) async {
|
||||||
|
await _channel.invokeMethod("setCameraRotation", [rads, x,y,z]);
|
||||||
|
}
|
||||||
|
|
||||||
Future setTexture(FilamentAsset asset, String assetPath,
|
Future setTexture(FilamentAsset asset, String assetPath,
|
||||||
{int renderableIndex = 0}) async {
|
{int renderableIndex = 0}) async {
|
||||||
await _channel
|
await _channel
|
||||||
@@ -219,6 +238,11 @@ class PolyvoxFilamentController extends FilamentController {
|
|||||||
await _channel.invokeMethod("setPosition", [asset, x, y, z]);
|
await _channel.invokeMethod("setPosition", [asset, x, y, z]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future setScale(
|
||||||
|
FilamentAsset asset, double scale) async {
|
||||||
|
await _channel.invokeMethod("setScale", [asset, scale]);
|
||||||
|
}
|
||||||
|
|
||||||
Future setRotation(
|
Future setRotation(
|
||||||
FilamentAsset asset, double rads, double x, double y, double z) async {
|
FilamentAsset asset, double rads, double x, double y, double z) async {
|
||||||
await _channel.invokeMethod("setRotation", [asset, rads, x, y, z]);
|
await _channel.invokeMethod("setRotation", [asset, rads, x, y, z]);
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
|
|
||||||
import 'filament_controller.dart';
|
import 'filament_controller.dart';
|
||||||
import 'filament_widget.dart';
|
import 'filament_widget.dart';
|
||||||
|
|
||||||
@@ -20,6 +18,29 @@ class GestureDetectingFilamentView extends StatefulWidget {
|
|||||||
class _GestureDetectingFilamentViewState
|
class _GestureDetectingFilamentViewState
|
||||||
extends State<GestureDetectingFilamentView> {
|
extends State<GestureDetectingFilamentView> {
|
||||||
bool _rotate = false;
|
bool _rotate = false;
|
||||||
|
late Future Function(double x, double y) _functionStart;
|
||||||
|
late Future Function(double x, double y) _functionUpdate;
|
||||||
|
late Future Function() _functionEnd;
|
||||||
|
|
||||||
|
double _lastScale = 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_setFunction();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setFunction() {
|
||||||
|
if (_rotate) {
|
||||||
|
_functionStart = widget.controller.rotateStart;
|
||||||
|
_functionUpdate = widget.controller.rotateUpdate;
|
||||||
|
_functionEnd = widget.controller.rotateEnd;
|
||||||
|
} else {
|
||||||
|
_functionStart = widget.controller.panStart;
|
||||||
|
_functionUpdate = widget.controller.panUpdate;
|
||||||
|
_functionEnd = widget.controller.panEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(Widget oldWidget) {
|
void didUpdateWidget(Widget oldWidget) {
|
||||||
@@ -27,6 +48,7 @@ class _GestureDetectingFilamentViewState
|
|||||||
(oldWidget as GestureDetectingFilamentView).showControls) {
|
(oldWidget as GestureDetectingFilamentView).showControls) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,67 +58,58 @@ class _GestureDetectingFilamentViewState
|
|||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
onPanDown: (details) async {
|
onScaleStart: (d) {
|
||||||
await widget.controller.panEnd();
|
if (d.pointerCount == 2) {
|
||||||
await widget.controller.rotateEnd();
|
// _lastScale = d.
|
||||||
_rotate
|
} else {
|
||||||
? widget.controller.rotateStart(
|
// print("start ${d.focalPoint}");
|
||||||
details.globalPosition.dx, details.globalPosition.dy)
|
_functionStart(d.focalPoint.dx, d.focalPoint.dy);
|
||||||
: widget.controller.panStart(
|
}
|
||||||
details.globalPosition.dx, details.globalPosition.dy);
|
|
||||||
},
|
},
|
||||||
onPanUpdate: (details) {
|
onScaleEnd: (d) {
|
||||||
_rotate
|
if (d.pointerCount == 2) {
|
||||||
? widget.controller.rotateUpdate(
|
_lastScale = 0;
|
||||||
details.globalPosition.dx, details.globalPosition.dy)
|
} else {
|
||||||
: widget.controller.panUpdate(
|
// print("end ${d.velocity}");
|
||||||
details.globalPosition.dx, details.globalPosition.dy);
|
_functionEnd();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onPanEnd: (d) {
|
onScaleUpdate: (d) {
|
||||||
_rotate
|
if (d.pointerCount == 2) {
|
||||||
? widget.controller.rotateEnd()
|
if (_lastScale == 0) {
|
||||||
: widget.controller.panEnd();
|
_lastScale = d.scale;
|
||||||
|
} else {
|
||||||
|
// var zoomFactor = ;
|
||||||
|
// if(zoomFactor < 0) {
|
||||||
|
// zoomFactor *= 10;
|
||||||
|
// }
|
||||||
|
// print(zoomFactor);
|
||||||
|
print(d.horizontalScale);
|
||||||
|
// print(d.focalPoint.dx);
|
||||||
|
widget.controller.zoom(d.scale > 1 ? 10 : -10);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// print("update ${d.focalPoint}");
|
||||||
|
_functionUpdate(d.focalPoint.dx, d.focalPoint.dy);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: FilamentWidget(controller: widget.controller))),
|
child: FilamentWidget(controller: widget.controller))),
|
||||||
widget.showControls
|
widget.showControls
|
||||||
? Padding(
|
? Align(alignment:Alignment.bottomRight, child:GestureDetector(
|
||||||
padding: const EdgeInsets.all(50),
|
onTap: () {
|
||||||
child: Row(children: [
|
|
||||||
Checkbox(
|
|
||||||
value: _rotate,
|
|
||||||
onChanged: (v) {
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_rotate = v == true;
|
_rotate = !_rotate;
|
||||||
|
_setFunction();
|
||||||
});
|
});
|
||||||
}),
|
},
|
||||||
ElevatedButton(
|
child: Container(
|
||||||
onPressed: () => widget.controller.zoom(30.0),
|
padding: const EdgeInsets.all(50),
|
||||||
child: const Text('-')),
|
child: Icon(Icons.rotate_90_degrees_ccw,
|
||||||
ElevatedButton(
|
color: _rotate
|
||||||
onPressed: () => widget.controller.zoom(-30.0),
|
? Colors.white
|
||||||
child: const Text('+'))
|
: Colors.white.withOpacity(0.5))),
|
||||||
]))
|
))
|
||||||
: Container()
|
: Container()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// behavior: HitTestBehavior.opaque,
|
|
||||||
// onPanDown: (details) {
|
|
||||||
// _rotate
|
|
||||||
// ? _filamentController.rotateStart(
|
|
||||||
// details.globalPosition.dx, details.globalPosition.dy)
|
|
||||||
// : _filamentController.panStart(
|
|
||||||
// details.globalPosition.dx, details.globalPosition.dy);
|
|
||||||
// },
|
|
||||||
// onPanUpdate: (details) {
|
|
||||||
// _rotate
|
|
||||||
// ? _filamentController.rotateUpdate(
|
|
||||||
// details.globalPosition.dx, details.globalPosition.dy)
|
|
||||||
// : _filamentController.panUpdate(
|
|
||||||
// details.globalPosition.dx, details.globalPosition.dy);
|
|
||||||
// },
|
|
||||||
// onPanEnd: (d) {
|
|
||||||
// _rotate
|
|
||||||
// ? _filamentController.rotateEnd()
|
|
||||||
// : _filamentController.panEnd();
|
|
||||||
// },
|
|
||||||
|
|||||||
Reference in New Issue
Block a user