fix camera manipulator/gesture detector, add explicit functions to set camera pos/rot, add unlitshader material provider

This commit is contained in:
Nick Fisher
2022-09-01 13:03:15 +10:00
parent 91038bc0d7
commit 26d916fc40
13 changed files with 2085 additions and 118 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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();
}; };
} }

View 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

View 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

Binary file not shown.

File diff suppressed because it is too large Load Diff

View 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

View File

@@ -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]);

View File

@@ -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();
// },