From a2fe9f745cd23739ec0a915ba4599f172981b441 Mon Sep 17 00:00:00 2001
From: Tibor Hencz <39774620+mentholyspirit@users.noreply.github.com>
Date: Thu, 27 Jun 2024 03:05:14 +0300
Subject: [PATCH 1/3] Add ability to disable panning in the OrbitManipulator
(#7928)
---
.../src/main/cpp/Manipulator.cpp | 5 +++++
.../google/android/filament/utils/Manipulator.java | 12 ++++++++++++
libs/camutils/include/camutils/Manipulator.h | 3 +++
libs/camutils/src/Manipulator.cpp | 8 ++++++++
libs/camutils/src/OrbitManipulator.h | 2 +-
5 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/android/filament-utils-android/src/main/cpp/Manipulator.cpp b/android/filament-utils-android/src/main/cpp/Manipulator.cpp
index 22d471def2..84ac111e75 100644
--- a/android/filament-utils-android/src/main/cpp/Manipulator.cpp
+++ b/android/filament-utils-android/src/main/cpp/Manipulator.cpp
@@ -125,6 +125,11 @@ extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBu
builder->groundPlane(a, b, c, d);
}
+extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderPanning(JNIEnv*, jclass, jlong nativeBuilder, jboolean enabled) {
+ Builder* builder = (Builder*) nativeBuilder;
+ builder->panning(enabled);
+}
+
extern "C" JNIEXPORT long Java_com_google_android_filament_utils_Manipulator_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder, jint mode) {
Builder* builder = (Builder*) nativeBuilder;
return (jlong) builder->build((Mode) mode);
diff --git a/android/filament-utils-android/src/main/java/com/google/android/filament/utils/Manipulator.java b/android/filament-utils-android/src/main/java/com/google/android/filament/utils/Manipulator.java
index 2c0ab85a14..548a6e6f8c 100644
--- a/android/filament-utils-android/src/main/java/com/google/android/filament/utils/Manipulator.java
+++ b/android/filament-utils-android/src/main/java/com/google/android/filament/utils/Manipulator.java
@@ -274,6 +274,17 @@ public class Manipulator {
return this;
}
+ /**
+ * Sets whether panning is enabled in the manipulator.
+ *
+ * @return this Builder object for chaining calls
+ */
+ @NonNull
+ public Builder panning(Boolean enabled) {
+ nBuilderPanning(mNativeBuilder, enabled);
+ return this;
+ }
+
/**
* Creates and returns the Manipulator object.
*
@@ -483,6 +494,7 @@ public class Manipulator {
private static native void nBuilderFlightPanSpeed(long nativeBuilder, float x, float y);
private static native void nBuilderFlightMoveDamping(long nativeBuilder, float damping);
private static native void nBuilderGroundPlane(long nativeBuilder, float a, float b, float c, float d);
+ private static native void nBuilderPanning(long nativeBuilder, Boolean enabled);
private static native long nBuilderBuild(long nativeBuilder, int mode);
private static native void nDestroyManipulator(long nativeManip);
diff --git a/libs/camutils/include/camutils/Manipulator.h b/libs/camutils/include/camutils/Manipulator.h
index 2cc8a4da03..5ea49eaf5a 100644
--- a/libs/camutils/include/camutils/Manipulator.h
+++ b/libs/camutils/include/camutils/Manipulator.h
@@ -109,6 +109,7 @@ public:
vec4 groundPlane;
RayCallback raycastCallback;
void* raycastUserdata;
+ bool panning = true;
};
struct Builder {
@@ -143,6 +144,8 @@ public:
Builder& groundPlane(FLOAT a, FLOAT b, FLOAT c, FLOAT d); //! Plane equation used as a raycast fallback
Builder& raycastCallback(RayCallback cb, void* userdata); //! Raycast function for accurate grab-and-pan
+ Builder& panning(bool enabled); //! Sets whether panning is enabled
+
/**
* Creates a new camera manipulator, either ORBIT, MAP, or FREE_FLIGHT.
*
diff --git a/libs/camutils/src/Manipulator.cpp b/libs/camutils/src/Manipulator.cpp
index d44528cd50..897d75c6d1 100644
--- a/libs/camutils/src/Manipulator.cpp
+++ b/libs/camutils/src/Manipulator.cpp
@@ -144,6 +144,14 @@ Manipulator::Builder& Manipulator::Builder::raycastCallback(RayCal
return *this;
}
+
+
+template typename
+Manipulator::Builder& Manipulator::Builder::panning(bool enabled) {
+ details.panning = enabled;
+ return *this;
+}
+
template
Manipulator* Manipulator::Builder::build(Mode mode) {
switch (mode) {
diff --git a/libs/camutils/src/OrbitManipulator.h b/libs/camutils/src/OrbitManipulator.h
index 54e325cc3b..f89b7ada03 100644
--- a/libs/camutils/src/OrbitManipulator.h
+++ b/libs/camutils/src/OrbitManipulator.h
@@ -69,7 +69,7 @@ public:
}
void grabBegin(int x, int y, bool strafe) override {
- mGrabState = strafe ? PANNING : ORBITING;
+ mGrabState = strafe && Base::mProps.panning ? PANNING : ORBITING;
mGrabPivot = mPivot;
mGrabEye = Base::mEye;
mGrabTarget = Base::mTarget;
From 44b4de904e71e2ee70be451eeb3f0ad3e656e287 Mon Sep 17 00:00:00 2001
From: Ben Doherty
Date: Thu, 27 Jun 2024 14:36:03 -0700
Subject: [PATCH 2/3] Add saveRawVariants flag to matc (#7949)
---
filament/docs/SpirvDebugging.md | 9 +++---
.../filamat/include/filamat/MaterialBuilder.h | 9 ++++++
libs/filamat/src/MaterialBuilder.cpp | 31 ++++++++++++++++++-
tools/matc/src/matc/CommandlineConfig.cpp | 7 ++++-
tools/matc/src/matc/Config.h | 5 +++
tools/matc/src/matc/MaterialCompiler.cpp | 1 +
6 files changed, 56 insertions(+), 6 deletions(-)
diff --git a/filament/docs/SpirvDebugging.md b/filament/docs/SpirvDebugging.md
index 42aad3aa9b..047fe3bc2a 100644
--- a/filament/docs/SpirvDebugging.md
+++ b/filament/docs/SpirvDebugging.md
@@ -64,14 +64,15 @@ First determine the Filament material and variant that causes the problem.
What we want is the "raw" GLSL version of the shader, before any optimizations / cross-compilation
happens.
-The easiest way I've found to do this is by adding a `std::cout` statement inside `MaterialBuilder`,
-right after `sg.createFragmentProgram` or `sg.createVertexProgram` is called. For example,
+We can use the `--save-raw-variants` debug flag in matc to export each GLSL
+shader to a file. For example:
```
-if (v.variant.key == 8u) { std::cout << shader << std::endl; }
+matc --save-raw-variants --optimize-size --variant-filter fog,ssr,vsm,stereo \
+ -a all -p all -o mymaterial.filamat mymaterial.mat
```
-Then, I invoke `matc` and redirect stdout to a .frag or .vert file.
+Files will be named like `mymaterial_0x05.frag` or `mymaterial_0x05.vert`.
Note that gltfio material "templates" first go through a build step. After building gltfio, the
gltfio Filament materials are output to:
diff --git a/libs/filamat/include/filamat/MaterialBuilder.h b/libs/filamat/include/filamat/MaterialBuilder.h
index c3045b942b..2587adba65 100644
--- a/libs/filamat/include/filamat/MaterialBuilder.h
+++ b/libs/filamat/include/filamat/MaterialBuilder.h
@@ -134,6 +134,7 @@ protected:
TargetApi mTargetApi = (TargetApi) 0;
Optimization mOptimization = Optimization::PERFORMANCE;
bool mPrintShaders = false;
+ bool mSaveRawVariants = false;
bool mGenerateDebugInfo = false;
bool mIncludeEssl1 = true;
utils::bitset32 mShaderModels;
@@ -586,6 +587,14 @@ public:
//! If true, will output the generated GLSL shader code to stdout.
MaterialBuilder& printShaders(bool printShaders) noexcept;
+ /**
+ * If true, this will write the raw generated GLSL for each variant to a text file in the
+ * current directory. The file will be named after the material name and the variant name. Its
+ * extension will be derived from the shader stage. For example, mymaterial_0x0e.frag,
+ * mymaterial_0x18.vert, etc.
+ */
+ MaterialBuilder& saveRawVariants(bool saveVariants) noexcept;
+
//! If true, will include debugging information in generated SPIRV.
MaterialBuilder& generateDebugInfo(bool generateDebugInfo) noexcept;
diff --git a/libs/filamat/src/MaterialBuilder.cpp b/libs/filamat/src/MaterialBuilder.cpp
index 11d539870a..590fac7f25 100644
--- a/libs/filamat/src/MaterialBuilder.cpp
+++ b/libs/filamat/src/MaterialBuilder.cpp
@@ -57,7 +57,7 @@
#include
#include
#include
-
+#include
namespace filamat {
@@ -547,6 +547,11 @@ MaterialBuilder& MaterialBuilder::printShaders(bool printShaders) noexcept {
return *this;
}
+MaterialBuilder& MaterialBuilder::saveRawVariants(bool saveRawVariants) noexcept {
+ mSaveRawVariants = saveRawVariants;
+ return *this;
+}
+
MaterialBuilder& MaterialBuilder::generateDebugInfo(bool generateDebugInfo) noexcept {
mGenerateDebugInfo = generateDebugInfo;
return *this;
@@ -918,6 +923,30 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector
Date: Thu, 27 Jun 2024 23:14:13 +0000
Subject: [PATCH 3/3] IBL drag & drop support for desktop gltf_viewer (#7947)
Users now can drag and drop IBL files for desktop gltf_viewer.
It attempts to load gltf files first then tries to load IBL files.
---
NEW_RELEASE_NOTES.md | 2 +
.../include/filamentapp/FilamentApp.h | 2 +
libs/filamentapp/src/FilamentApp.cpp | 55 ++++++++--------
samples/gltf_viewer.cpp | 62 ++++++++++++++-----
4 files changed, 82 insertions(+), 39 deletions(-)
diff --git a/NEW_RELEASE_NOTES.md b/NEW_RELEASE_NOTES.md
index 4a1a9c7fa7..228c34804a 100644
--- a/NEW_RELEASE_NOTES.md
+++ b/NEW_RELEASE_NOTES.md
@@ -7,3 +7,5 @@ for next branch cut* header.
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut
+
+- Add drag and drop support for IBL files for desktop gltf_viewer.
diff --git a/libs/filamentapp/include/filamentapp/FilamentApp.h b/libs/filamentapp/include/filamentapp/FilamentApp.h
index 186d146d08..d7087d0f0b 100644
--- a/libs/filamentapp/include/filamentapp/FilamentApp.h
+++ b/libs/filamentapp/include/filamentapp/FilamentApp.h
@@ -104,6 +104,8 @@ public:
size_t getSkippedFrameCount() const { return mSkippedFrames; }
+ void loadIBL(std::string_view path);
+
FilamentApp(const FilamentApp& rhs) = delete;
FilamentApp(FilamentApp&& rhs) = delete;
FilamentApp& operator=(const FilamentApp& rhs) = delete;
diff --git a/libs/filamentapp/src/FilamentApp.cpp b/libs/filamentapp/src/FilamentApp.cpp
index 980f3bdcfc..4a28396793 100644
--- a/libs/filamentapp/src/FilamentApp.cpp
+++ b/libs/filamentapp/src/FilamentApp.cpp
@@ -174,11 +174,6 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback,
loadDirt(config);
loadIBL(config);
- if (mIBL != nullptr) {
- mIBL->getSkybox()->setLayerMask(0x7, 0x4);
- mScene->setSkybox(mIBL->getSkybox());
- mScene->setIndirectLight(mIBL->getIndirectLight());
- }
for (auto& view : window->mViews) {
if (view.get() != window->mUiView) {
@@ -519,31 +514,41 @@ const utils::Path& FilamentApp::getRootAssetsPath() {
return root;
}
-void FilamentApp::loadIBL(const Config& config) {
- if (!config.iblDirectory.empty()) {
- Path iblPath(config.iblDirectory);
+void FilamentApp::loadIBL(std::string_view path) {
+ Path iblPath(path);
+ if (!iblPath.exists()) {
+ std::cerr << "The specified IBL path does not exist: " << iblPath << std::endl;
+ return;
+ }
- if (!iblPath.exists()) {
- std::cerr << "The specified IBL path does not exist: " << iblPath << std::endl;
+ mIBL = std::make_unique(*mEngine);
+
+ if (!iblPath.isDirectory()) {
+ if (!mIBL->loadFromEquirect(iblPath)) {
+ std::cerr << "Could not load the specified IBL: " << iblPath << std::endl;
+ mIBL.reset(nullptr);
return;
}
-
- mIBL = std::make_unique(*mEngine);
-
- if (!iblPath.isDirectory()) {
- if (!mIBL->loadFromEquirect(iblPath)) {
- std::cerr << "Could not load the specified IBL: " << iblPath << std::endl;
- mIBL.reset(nullptr);
- return;
- }
- } else {
- if (!mIBL->loadFromDirectory(iblPath)) {
- std::cerr << "Could not load the specified IBL: " << iblPath << std::endl;
- mIBL.reset(nullptr);
- return;
- }
+ } else {
+ if (!mIBL->loadFromDirectory(iblPath)) {
+ std::cerr << "Could not load the specified IBL: " << iblPath << std::endl;
+ mIBL.reset(nullptr);
+ return;
}
}
+
+ if (mIBL != nullptr) {
+ mIBL->getSkybox()->setLayerMask(0x7, 0x4);
+ mScene->setSkybox(mIBL->getSkybox());
+ mScene->setIndirectLight(mIBL->getIndirectLight());
+ }
+}
+
+void FilamentApp::loadIBL(const Config& config) {
+ if (config.iblDirectory.empty()) {
+ return;
+ }
+ loadIBL(config.iblDirectory);
}
void FilamentApp::loadDirt(const Config& config) {
diff --git a/samples/gltf_viewer.cpp b/samples/gltf_viewer.cpp
index 340391ec26..d3481c485d 100644
--- a/samples/gltf_viewer.cpp
+++ b/samples/gltf_viewer.cpp
@@ -58,6 +58,7 @@
#include
+#include
#include
#include
#include
@@ -508,30 +509,55 @@ static void onClick(App& app, View* view, ImVec2 pos) {
});
}
-static utils::Path getPathForAsset(std::string_view string) {
+static utils::Path getPathForIBLAsset(std::string_view string) {
+ auto isIBL = [] (utils::Path file) -> bool {
+ return file.getExtension() == "ktx" || file.getExtension() == "hdr";
+ };
+
utils::Path filename{ string };
if (!filename.exists()) {
std::cerr << "file " << filename << " not found!" << std::endl;
return {};
}
+
if (filename.isDirectory()) {
- auto files = filename.listContents();
- for (const auto& file: files) {
- if (file.getExtension() == "gltf" || file.getExtension() == "glb") {
- filename = file;
- break;
- }
- }
- if (filename.isDirectory()) {
- std::cerr << "no glTF file found in " << filename << std::endl;
+ std::vector files = filename.listContents();
+ if (std::none_of(files.cbegin(), files.cend(), isIBL)) {
return {};
}
+ } else if (!isIBL(filename)) {
+ return {};
}
+
return filename;
}
+static utils::Path getPathForGLTFAsset(std::string_view string) {
+ auto isGLTF = [] (utils::Path file) -> bool {
+ return file.getExtension() == "gltf" || file.getExtension() == "glb";
+ };
-static bool checkAsset(const utils::Path& filename) {
+ utils::Path filename{ string };
+ if (!filename.exists()) {
+ std::cerr << "file " << filename << " not found!" << std::endl;
+ return {};
+ }
+
+ if (filename.isDirectory()) {
+ std::vector files = filename.listContents();
+ auto it = std::find_if(files.cbegin(), files.cend(), isGLTF);
+ if (it == files.end()) {
+ return {};
+ }
+ filename = *it;
+ } else if (!isGLTF(filename)) {
+ return {};
+ }
+
+ return filename;
+}
+
+static bool checkGLTFAsset(const utils::Path& filename) {
// Peek at the file size to allow pre-allocation.
long const contentSize = static_cast(getFileSize(filename.c_str()));
if (contentSize <= 0) {
@@ -571,8 +597,9 @@ int main(int argc, char** argv) {
utils::Path filename;
int const num_args = argc - optionIndex;
if (num_args >= 1) {
- filename = getPathForAsset(argv[optionIndex]);
+ filename = getPathForGLTFAsset(argv[optionIndex]);
if (filename.isEmpty()) {
+ std::cerr << "no glTF file found in " << filename << std::endl;
return 1;
}
}
@@ -1125,9 +1152,9 @@ int main(int argc, char** argv) {
filamentApp.resize(resize);
filamentApp.setDropHandler([&](std::string_view path) {
- utils::Path const filename = getPathForAsset(path);
+ utils::Path filename = getPathForGLTFAsset(path);
if (!filename.isEmpty()) {
- if (checkAsset(filename)) {
+ if (checkGLTFAsset(filename)) {
app.resourceLoader->asyncCancelLoad();
app.resourceLoader->evictResourceData();
app.viewer->removeAsset();
@@ -1136,6 +1163,13 @@ int main(int argc, char** argv) {
loadResources(filename);
app.viewer->setAsset(app.asset, app.instance);
}
+ return;
+ }
+
+ filename = getPathForIBLAsset(path);
+ if (!filename.isEmpty()) {
+ FilamentApp::get().loadIBL(path);
+ return;
}
});