Compare commits
490 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6960b1148a | ||
|
|
3cc23aac25 | ||
|
|
11dc8740f2 | ||
|
|
4b797cff88 | ||
|
|
fe1c1736cd | ||
|
|
4058ef5f09 | ||
|
|
d25ca01624 | ||
|
|
e7bebcdea9 | ||
|
|
5ef234153d | ||
|
|
d96f87dbbf | ||
|
|
bbee5599f1 | ||
|
|
a4212d5ace | ||
|
|
6d0e719e06 | ||
|
|
3fa9b08a52 | ||
|
|
4b1a451804 | ||
|
|
f9d7d60f7d | ||
|
|
aaf9d95411 | ||
|
|
90d1ebefae | ||
|
|
a7e4a759e9 | ||
|
|
283992088f | ||
|
|
75c9ee5982 | ||
|
|
4d88ff116c | ||
|
|
cf3cc37392 | ||
|
|
f804c9e346 | ||
|
|
8a2e31023f | ||
|
|
4e33e9c3d1 | ||
|
|
18ac9fd0cc | ||
|
|
d0f28a48a8 | ||
|
|
706780e3a6 | ||
|
|
b5f9c66503 | ||
|
|
41f34b8d55 | ||
|
|
04731b937a | ||
|
|
7278e5b5ba | ||
|
|
891184bc77 | ||
|
|
3d51f9ab23 | ||
|
|
1ea8e171d9 | ||
|
|
e2be3dd0ac | ||
|
|
35c0092b84 | ||
|
|
d249f70750 | ||
|
|
0dc25cd2a8 | ||
|
|
1c51164e7b | ||
|
|
91b5cc4bea | ||
|
|
f190f03530 | ||
|
|
af6f19e390 | ||
|
|
47446e6cfd | ||
|
|
8fada7d6c7 | ||
|
|
8a81486f5d | ||
|
|
e483699fba | ||
|
|
ae40a12f54 | ||
|
|
73d4279f00 | ||
|
|
a0e2f722f6 | ||
|
|
5c0da86e04 | ||
|
|
055fc7cbc1 | ||
|
|
37d8f96927 | ||
|
|
e9e3ce78ca | ||
|
|
2dadad1e87 | ||
|
|
9073fc3dc3 | ||
|
|
8c36e6d95f | ||
|
|
2b6d99f5e7 | ||
|
|
6f29358cb6 | ||
|
|
4e9dcb45ea | ||
|
|
282b6f72c1 | ||
|
|
cd48be5265 | ||
|
|
3cba26a4c5 | ||
|
|
dd2119268b | ||
|
|
5e51ff78d9 | ||
|
|
6bf27c7356 | ||
|
|
3abd4fdf09 | ||
|
|
2409dc9bc4 | ||
|
|
432434e7e9 | ||
|
|
6586c8d70b | ||
|
|
ac0c94da69 | ||
|
|
ba68ea89cd | ||
|
|
26661375ae | ||
|
|
d19d6a72b0 | ||
|
|
c81b5d98ef | ||
|
|
f45b7626eb | ||
|
|
2aa21e2a43 | ||
|
|
ad876b91e7 | ||
|
|
73514f6c91 | ||
|
|
385a05d197 | ||
|
|
306f6e1ca3 | ||
|
|
756866675f | ||
|
|
41baa7bcf0 | ||
|
|
694204d54a | ||
|
|
85bc1c1758 | ||
|
|
0c9cb72e53 | ||
|
|
d113c0f01f | ||
|
|
98b8871f34 | ||
|
|
7cb16afcb5 | ||
|
|
1a79e5463f | ||
|
|
fd444b2fd0 | ||
|
|
15db005dc6 | ||
|
|
a26b05bbbb | ||
|
|
12b9ee46b9 | ||
|
|
ce1eb83a0e | ||
|
|
27529730ca | ||
|
|
7b398c01f6 | ||
|
|
cdb0bb9490 | ||
|
|
ee82f76846 | ||
|
|
b77a23ff9d | ||
|
|
0d8cdab4e4 | ||
|
|
67b53d0115 | ||
|
|
c3291d0137 | ||
|
|
7f2ebd25bc | ||
|
|
fc32fa3a78 | ||
|
|
a3cf2ee61a | ||
|
|
cc287386aa | ||
|
|
9ea1dbad93 | ||
|
|
4a849c7caf | ||
|
|
a77a9ade29 | ||
|
|
090d23434c | ||
|
|
83850c8201 | ||
|
|
ebcd4925f7 | ||
|
|
13bed4fdf9 | ||
|
|
d306bfe147 | ||
|
|
adfc4a5b0c | ||
|
|
1dae5c6b6c | ||
|
|
6b249bde4b | ||
|
|
1036759f39 | ||
|
|
302c07048c | ||
|
|
2686b0bbac | ||
|
|
cece128bb9 | ||
|
|
3e5471d32a | ||
|
|
272f786f35 | ||
|
|
0dd04f6e73 | ||
|
|
a5221fc816 | ||
|
|
29f6616cee | ||
|
|
0d08402004 | ||
|
|
64c2ab7048 | ||
|
|
26a54ba86a | ||
|
|
32b3f16573 | ||
|
|
4080a0a5d5 | ||
|
|
17d67f2a39 | ||
|
|
9c20efd235 | ||
|
|
b46833680d | ||
|
|
4bcd862c0e | ||
|
|
c414ba9b2f | ||
|
|
27a070c8f9 | ||
|
|
c8aea02d7d | ||
|
|
46ff9a433c | ||
|
|
c135b4aa19 | ||
|
|
89d5f4a418 | ||
|
|
003fe86ffb | ||
|
|
94c250a241 | ||
|
|
f1a69c8c36 | ||
|
|
2bd8faaef5 | ||
|
|
94a25452e8 | ||
|
|
505cb39e1c | ||
|
|
127dd8f675 | ||
|
|
fc5837b1b6 | ||
|
|
46e3d10e62 | ||
|
|
64c5dc63ab | ||
|
|
31adb1213e | ||
|
|
8e6663e4b0 | ||
|
|
ba804444b8 | ||
|
|
0344de57e9 | ||
|
|
750252b297 | ||
|
|
58cfb85004 | ||
|
|
ab46481b45 | ||
|
|
4296782399 | ||
|
|
4f28734042 | ||
|
|
4289c03ce5 | ||
|
|
bdbc85773c | ||
|
|
0a2fa36d5a | ||
|
|
0c244bc2ac | ||
|
|
67a49e5770 | ||
|
|
a98395bee7 | ||
|
|
26c9732b4e | ||
|
|
62787de97b | ||
|
|
830c379958 | ||
|
|
1a24de8735 | ||
|
|
121489f2af | ||
|
|
0e7295a469 | ||
|
|
602b3d0796 | ||
|
|
fda06fe8a0 | ||
|
|
92628ade8e | ||
|
|
b399d64024 | ||
|
|
a8e8c04c7b | ||
|
|
313b9944fd | ||
|
|
5a61d28eee | ||
|
|
4eb0937d21 | ||
|
|
a082e94235 | ||
|
|
9bd3684893 | ||
|
|
0cd9fd9ad9 | ||
|
|
efcc690f42 | ||
|
|
1ed1a5efb6 | ||
|
|
2d7de6ecc0 | ||
|
|
4a1edc4281 | ||
|
|
d6b32e5923 | ||
|
|
105ae8abb6 | ||
|
|
1f33dad675 | ||
|
|
90ee59512b | ||
|
|
7f2a189641 | ||
|
|
1ab59ca35a | ||
|
|
5c0826963e | ||
|
|
7555fe6196 | ||
|
|
1dbb9c7ded | ||
|
|
ac798c1350 | ||
|
|
00682bd911 | ||
|
|
ef375a7103 | ||
|
|
fd258b7765 | ||
|
|
ceced43e93 | ||
|
|
55fdc47e66 | ||
|
|
147de8d372 | ||
|
|
eb2a1928b6 | ||
|
|
53a92451e6 | ||
|
|
77016f34a5 | ||
|
|
19db911d46 | ||
|
|
46a88c7ed8 | ||
|
|
ca3b841974 | ||
|
|
e9ff2157bc | ||
|
|
d270c42109 | ||
|
|
f4558fee1d | ||
|
|
86461663d8 | ||
|
|
fcca62ec6a | ||
|
|
f6dde81a16 | ||
|
|
d77e66d1e8 | ||
|
|
702f906d49 | ||
|
|
2f257b54e7 | ||
|
|
c1b9e47a90 | ||
|
|
a93e10308c | ||
|
|
204fc0359c | ||
|
|
eb483281dc | ||
|
|
b841709729 | ||
|
|
35b033102f | ||
|
|
7bc65421a9 | ||
|
|
736514cf37 | ||
|
|
6307fb3563 | ||
|
|
35b3542b2e | ||
|
|
db0158dae8 | ||
|
|
0fa5ca9a6a | ||
|
|
36285f2ca5 | ||
|
|
9e19a1aca4 | ||
|
|
19c7949cc4 | ||
|
|
36d7f6ff94 | ||
|
|
e7b90f9c12 | ||
|
|
8bd499c60c | ||
|
|
0d61d47f28 | ||
|
|
4b5dc5b3af | ||
|
|
61bf472426 | ||
|
|
ef6199a792 | ||
|
|
7bd0b45a2b | ||
|
|
eb0c346969 | ||
|
|
bf2938f345 | ||
|
|
c7e4116154 | ||
|
|
db521e0e5e | ||
|
|
a219629ead | ||
|
|
ba10393f48 | ||
|
|
091e399d0f | ||
|
|
5de6779d72 | ||
|
|
4b3a983b23 | ||
|
|
1b53e78ea7 | ||
|
|
ef08323b25 | ||
|
|
24c6917267 | ||
|
|
9ab25fa19e | ||
|
|
d5f785ff41 | ||
|
|
f2a8e2aef7 | ||
|
|
7bdd1fe096 | ||
|
|
f677eef422 | ||
|
|
70f3824b14 | ||
|
|
11b980832c | ||
|
|
e706695ed1 | ||
|
|
e8877ffe2d | ||
|
|
300e853646 | ||
|
|
a403279fa6 | ||
|
|
1fd5d9dae6 | ||
|
|
8f6f831d5b | ||
|
|
599077b54c | ||
|
|
9b7414b60c | ||
|
|
78430858fe | ||
|
|
fe8528a963 | ||
|
|
f365cb965b | ||
|
|
2b38cf4c65 | ||
|
|
2e9080a179 | ||
|
|
0a50ee989e | ||
|
|
c9c9103ede | ||
|
|
1ce9e96490 | ||
|
|
1f9c802e10 | ||
|
|
c6fda8385a | ||
|
|
d0664bc119 | ||
|
|
e7ed85ec94 | ||
|
|
5d1d4ff4d6 | ||
|
|
57040ebb22 | ||
|
|
03b018e7f3 | ||
|
|
04ada346b0 | ||
|
|
f53c7723fb | ||
|
|
cd48089318 | ||
|
|
0a6a74c78c | ||
|
|
b40982d579 | ||
|
|
2605633e1e | ||
|
|
6379ab22c9 | ||
|
|
0bf02b75d5 | ||
|
|
2f7e873137 | ||
|
|
bb9e23519d | ||
|
|
c4259b5598 | ||
|
|
acfae2882d | ||
|
|
180eb61620 | ||
|
|
a92bb87cd8 | ||
|
|
2c967b821b | ||
|
|
abe9a9731d | ||
|
|
2837a48001 | ||
|
|
4aef84342d | ||
|
|
9be6153875 | ||
|
|
444640afb7 | ||
|
|
122908587b | ||
|
|
c1654537e2 | ||
|
|
984a172cec | ||
|
|
ee2767875c | ||
|
|
fa0a41e62e | ||
|
|
edaf718281 | ||
|
|
7cd5963d3a | ||
|
|
60f5512c5f | ||
|
|
6b3c1179bc | ||
|
|
d1b9a1b996 | ||
|
|
1bd91e7e94 | ||
|
|
5e2f73c74e | ||
|
|
4a269e37c5 | ||
|
|
3eceaf20a2 | ||
|
|
bbc4f4f21d | ||
|
|
c5ef1d6252 | ||
|
|
a4280881d5 | ||
|
|
8ef4c54712 | ||
|
|
5ebc8c3e1a | ||
|
|
c1a0e61e8e | ||
|
|
cbcb3e95c6 | ||
|
|
fc06298ed4 | ||
|
|
4ca87b188c | ||
|
|
f1f60c3e0d | ||
|
|
76d21b56af | ||
|
|
02a8cffb18 | ||
|
|
d53f7ecd6a | ||
|
|
e297f65d8c | ||
|
|
5356f65040 | ||
|
|
5056abc357 | ||
|
|
46029acd14 | ||
|
|
28e414c9a5 | ||
|
|
29c036d826 | ||
|
|
831a6d9480 | ||
|
|
fb2a95470a | ||
|
|
4d73583f86 | ||
|
|
9a24c4001f | ||
|
|
4c9ae9dd91 | ||
|
|
384d6921f6 | ||
|
|
0ab0e50a4f | ||
|
|
e0a8284fcf | ||
|
|
eafbf699a2 | ||
|
|
4d3f10477a | ||
|
|
9a83805f19 | ||
|
|
6fcc2b579d | ||
|
|
e04a3d7d3a | ||
|
|
34f4c06a5c | ||
|
|
6de36f1e53 | ||
|
|
be61ea2dc8 | ||
|
|
c594d6a07e | ||
|
|
2a9a3b1ac2 | ||
|
|
ee7feff9cc | ||
|
|
02ce911405 | ||
|
|
f12ee8f54c | ||
|
|
81a98c6769 | ||
|
|
e3f626934f | ||
|
|
94ff2ea6b1 | ||
|
|
cc6201b0db | ||
|
|
d079df9ce5 | ||
|
|
6a2c944bbd | ||
|
|
266fea5e6c | ||
|
|
6da3f85362 | ||
|
|
1d58892fed | ||
|
|
ff1b6d28a8 | ||
|
|
ff935e05f2 | ||
|
|
d378f5e4bb | ||
|
|
44eee6550c | ||
|
|
260b8fb672 | ||
|
|
2f240acc43 | ||
|
|
189b528b3d | ||
|
|
2b265d54a1 | ||
|
|
c61d67301f | ||
|
|
5f3d8096f3 | ||
|
|
6e5b05d0b5 | ||
|
|
6bbae681ef | ||
|
|
097fac4cca | ||
|
|
97515b0d7d | ||
|
|
3500101816 | ||
|
|
1cebf51672 | ||
|
|
3b59dff577 | ||
|
|
cd01ad06fd | ||
|
|
84b73a3770 | ||
|
|
662a10e273 | ||
|
|
331332fab0 | ||
|
|
f3572876a1 | ||
|
|
ecce02502e | ||
|
|
c827004821 | ||
|
|
786eee4eb9 | ||
|
|
92d2de5279 | ||
|
|
f4070f3fb5 | ||
|
|
856a6567a1 | ||
|
|
363edb1427 | ||
|
|
c209232950 | ||
|
|
3f9120b129 | ||
|
|
d17875aea1 | ||
|
|
b1f0f905e5 | ||
|
|
c71c7c70d4 | ||
|
|
613ae56cc1 | ||
|
|
6607002939 | ||
|
|
2e40bb46e7 | ||
|
|
b8897a68f9 | ||
|
|
720288c420 | ||
|
|
97651a0ff4 | ||
|
|
84efd4871e | ||
|
|
3125c44ce1 | ||
|
|
d909b38d57 | ||
|
|
5572ef8574 | ||
|
|
3c4192bd0e | ||
|
|
3fc9dc3684 | ||
|
|
85ea5a6b70 | ||
|
|
77891acb92 | ||
|
|
a06e01a196 | ||
|
|
034b6892f4 | ||
|
|
74fe102035 | ||
|
|
25cc554925 | ||
|
|
bd8ea711fd | ||
|
|
c1347e55cb | ||
|
|
afbd6e6606 | ||
|
|
d6c5cb7778 | ||
|
|
43d47745dd | ||
|
|
f0d99070e4 | ||
|
|
6a49d67c6c | ||
|
|
6b7c1b21cb | ||
|
|
b7d1b4ca1a | ||
|
|
8a04d5761b | ||
|
|
8d8729be8e | ||
|
|
d4325de47d | ||
|
|
e29c76465b | ||
|
|
a220407aef | ||
|
|
4df214003e | ||
|
|
182250b9c0 | ||
|
|
59a6758fce | ||
|
|
73aa996444 | ||
|
|
d787a521b5 | ||
|
|
08769ec35e | ||
|
|
3aa18eafb3 | ||
|
|
8d4a0e5aa9 | ||
|
|
e8183d09c2 | ||
|
|
5f1da1dfc0 | ||
|
|
1dad27a172 | ||
|
|
c1c5776439 | ||
|
|
da418fc7f2 | ||
|
|
fcaae825b7 | ||
|
|
f5ee074674 | ||
|
|
0c787b94b8 | ||
|
|
02f5f07db0 | ||
|
|
a97591a193 | ||
|
|
60d230b380 | ||
|
|
80485bf520 | ||
|
|
401bd8ce73 | ||
|
|
c23a7343d4 | ||
|
|
75a24ee41f | ||
|
|
7e9a69df64 | ||
|
|
12bf8d9659 | ||
|
|
d1c8d42bd2 | ||
|
|
c0fe2d1c09 | ||
|
|
812f0d577b | ||
|
|
4a25ba1111 | ||
|
|
0b4f3f76fc | ||
|
|
e7e19a88e6 | ||
|
|
4295eaa311 | ||
|
|
43e78f7a93 | ||
|
|
0a305a710a | ||
|
|
ef45d695d0 | ||
|
|
ac50cb69f7 | ||
|
|
9fc6e398c6 | ||
|
|
e06b948343 | ||
|
|
28ca9df5a0 | ||
|
|
c66915209e | ||
|
|
cb4ffe39f4 | ||
|
|
e07f91ce8b | ||
|
|
03fcbfea62 | ||
|
|
f9d05a879a | ||
|
|
7a8dd52c4c | ||
|
|
ef48cad322 | ||
|
|
c39d692757 | ||
|
|
4c1d8f310a | ||
|
|
1e1542fe16 | ||
|
|
647ac34c8c | ||
|
|
ea34691625 | ||
|
|
4557255ce1 | ||
|
|
4cb951461b | ||
|
|
750dcbb9d8 | ||
|
|
459f70f7b4 | ||
|
|
61748fa7dc |
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -17,6 +17,10 @@ A clear and concise description of what you expected to happen.
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Logs**
|
||||
If applicable, copy logs from your console here. Please *do not*
|
||||
use screenshots of logs, copy them as text.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- GPU: [e.g. NVIDIA GTX 1080]
|
||||
|
||||
16
.github/workflows/release.yml
vendored
16
.github/workflows/release.yml
vendored
@@ -96,6 +96,20 @@ jobs:
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh release
|
||||
- name: Sign sample-gltf-viewer
|
||||
run: |
|
||||
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
|
||||
base64 --decode filament.jks.base64 > filament.jks
|
||||
BUILD_TOOLS_VERSION=$(ls ${ANDROID_HOME}/build-tools | sort -V | tail -n 1)
|
||||
APKSIGNER=${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner
|
||||
IN_FILE="out/sample-gltf-viewer-release.apk"
|
||||
OUT_FILE="out/filament-gltf-viewer-${TAG}-android.apk"
|
||||
${APKSIGNER} sign --ks filament.jks --key-pass=pass:${APK_KEYSTORE_PASS} --ks-pass=pass:${APK_KEYSTORE_PASS} --in ${IN_FILE} --out ${OUT_FILE}
|
||||
rm "${IN_FILE}"
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
APK_KEYSTORE_BASE64: ${{ secrets.APK_KEYSTORE_BASE64 }}
|
||||
APK_KEYSTORE_PASS: ${{ secrets.APK_KEYSTORE_PASS }}
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
@@ -107,7 +121,7 @@ jobs:
|
||||
mv out/gltfio-android-lite-release.aar out/gltfio-${TAG}-lite-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||
mv out/filament-utils-android-lite-release.aar out/filament-utils-${TAG}-lite-android.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar out/*.apk
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
51
BUILDING.md
51
BUILDING.md
@@ -4,29 +4,23 @@
|
||||
|
||||
To build Filament, you must first install the following tools:
|
||||
|
||||
- CMake 3.10 (or more recent)
|
||||
- CMake 3.19 (or more recent)
|
||||
- clang 7.0 (or more recent)
|
||||
- [ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
|
||||
|
||||
To build the Java based components of the project you can optionally install (recommended):
|
||||
|
||||
- OpenJDK 1.8 (or more recent)
|
||||
- [ninja 1.10](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
|
||||
|
||||
Additional dependencies may be required for your operating system. Please refer to the appropriate
|
||||
section below.
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio 4.1.0 or more recent
|
||||
- Android Studio Arctic Fox or more recent
|
||||
- Android SDK
|
||||
- Android NDK "side-by-side" 22.0 or higher
|
||||
- Android NDK "side-by-side" 22.1 or higher
|
||||
|
||||
### Environment variables
|
||||
|
||||
Make sure the environment variable `ANDROID_HOME` points to the location of your Android SDK.
|
||||
|
||||
By default our build system will attempt to compile the Java bindings. To do so, the environment
|
||||
variable `JAVA_HOME` should point to the location of your JDK.
|
||||
To build Filament for Android, make sure the environment variable `ANDROID_HOME` points to the
|
||||
location of your Android SDK.
|
||||
|
||||
When building for WebGL, you'll also need to set `EMSDK`. See [WebAssembly](#webassembly).
|
||||
|
||||
@@ -65,25 +59,13 @@ To install the libraries and executables in `out/debug/` and `out/release/`, add
|
||||
You can force a clean build by adding the `-c` flag. The script offers more features described
|
||||
by executing `build.sh -h`.
|
||||
|
||||
### Disabling Java builds
|
||||
|
||||
By default our build system will attempt to compile the Java bindings. If you wish to skip this
|
||||
compilation step simply pass the `-j` flag to `build.sh`:
|
||||
|
||||
```
|
||||
$ ./build.sh -j release
|
||||
```
|
||||
|
||||
If you use CMake directly instead of the build script, pass `-DFILAMENT_ENABLE_JAVA=OFF`
|
||||
to CMake instead.
|
||||
|
||||
### Filament-specific CMake Options
|
||||
|
||||
The following CMake options are boolean options specific to Filament:
|
||||
|
||||
- `FILAMENT_ENABLE_JAVA`: Compile Java projects: requires a JDK and the JAVA_HOME env var
|
||||
- `FILAMENT_ENABLE_LTO`: Enable link-time optimizations if supported by the compiler
|
||||
- `FILAMENT_BUILD_FILAMAT`: Build filamat and JNI buildings
|
||||
- `FILAMENT_SUPPORTS_OPENGL`: Include the OpenGL backend
|
||||
- `FILAMENT_SUPPORTS_METAL`: Include the Metal backend
|
||||
- `FILAMENT_SUPPORTS_VULKAN`: Include the Vulkan backend
|
||||
- `FILAMENT_INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
|
||||
@@ -162,14 +144,6 @@ make sure the command line tools are setup by running:
|
||||
$ xcode-select --install
|
||||
```
|
||||
|
||||
After installing Java 1.8 you must also ensure that your `JAVA_HOME` environment variable is
|
||||
properly set. If it doesn't already point to the appropriate JDK, you can simply add the following
|
||||
to your `.profile`:
|
||||
|
||||
```
|
||||
export JAVA_HOME="$(/usr/libexec/java_home)"
|
||||
```
|
||||
|
||||
Then run `cmake` and `ninja` to trigger a build:
|
||||
|
||||
```
|
||||
@@ -375,7 +349,7 @@ same version that our continuous builds use.
|
||||
|
||||
```
|
||||
cd <your chosen parent folder for the emscripten SDK>
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.17.zip > emsdk.zip
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.23.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
python ./emsdk.py install latest
|
||||
python ./emsdk.py activate latest
|
||||
@@ -422,12 +396,13 @@ filamesh ./assets/models/monkey/monkey.obj monkey.filamesh
|
||||
```
|
||||
|
||||
Most samples accept an IBL that must be generated using the `cmgen` tool (`./tools/filamesh/cmgen`
|
||||
in your build directory). These sample apps expect a path to a directory containing the '.rgb32f'
|
||||
files for the IBL (which are PNGs containing `R11F_G11F_B10F` data). To generate an IBL simply use
|
||||
this command:
|
||||
in your build directory). These sample apps expect a path to a directory containing the `.rgb32f`
|
||||
files for the IBL (which are PNGs containing `R11F_G11F_B10F` data) or a path to a directory
|
||||
containing two `.ktx` files (one for the IBL itself, one for the skybox). To generate an IBL
|
||||
simply use this command:
|
||||
|
||||
```
|
||||
cmgen -x ./ibls/ my_ibl.exr
|
||||
cmgen -f ktx -x ./ibls/ my_ibl.exr
|
||||
```
|
||||
|
||||
The source environment map can be a PNG (8 or 16 bit), a PSD (16 or 32 bit), an HDR or an OpenEXR
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ==================================================================================================
|
||||
# CMake
|
||||
# ==================================================================================================
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
# ==================================================================================================
|
||||
# Project declaration
|
||||
@@ -11,8 +11,6 @@ project(TNT)
|
||||
# ==================================================================================================
|
||||
# Options
|
||||
# ==================================================================================================
|
||||
option(FILAMENT_ENABLE_JAVA "Compile Java projects, requires a JDK and the JAVA_HOME env var" ON)
|
||||
|
||||
option(FILAMENT_USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
|
||||
|
||||
option(FILAMENT_USE_SWIFTSHADER "Compile Filament against SwiftShader" OFF)
|
||||
@@ -25,6 +23,10 @@ option(FILAMENT_SUPPORTS_XCB "Include XCB support in Linux builds" ON)
|
||||
|
||||
option(FILAMENT_SUPPORTS_XLIB "Include XLIB support in Linux builds" ON)
|
||||
|
||||
set(FILAMENT_NDK_VERSION "" CACHE STRING
|
||||
"Android NDK version or version prefix to be used when building for Android."
|
||||
)
|
||||
|
||||
set(FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB "2" CACHE STRING
|
||||
"Per render pass arena size. Must be roughly 1 MB larger than FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, default 2."
|
||||
)
|
||||
@@ -37,8 +39,12 @@ set(FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB "1" CACHE STRING
|
||||
"Size of the command-stream buffer. As a rule of thumb use the same value as FILAMENT_PER_FRRAME_COMMANDS_SIZE_IN_MB, default 1."
|
||||
)
|
||||
|
||||
set(FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB "2" CACHE STRING
|
||||
"Size of the OpenGL handle arena, default 2."
|
||||
set(FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB "4" CACHE STRING
|
||||
"Size of the OpenGL handle arena, default 4."
|
||||
)
|
||||
|
||||
set(FILAMENT_METAL_HANDLE_ARENA_SIZE_IN_MB "8" CACHE STRING
|
||||
"Size of the Metal handle arena, default 8."
|
||||
)
|
||||
|
||||
# ==================================================================================================
|
||||
@@ -125,27 +131,35 @@ if (WIN32)
|
||||
# __declspec(dllexport) in front of each functions).
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
# The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
|
||||
# global method here:
|
||||
if (${USE_STATIC_CRT})
|
||||
set(CRT_FLAGS_RELEASE "/MT")
|
||||
set(CRT_FLAGS_DEBUG "/MTd")
|
||||
add_compile_options(
|
||||
$<$<CONFIG:>:/MT>
|
||||
$<$<CONFIG:Debug>:/MTd>
|
||||
$<$<CONFIG:Release>:/MT>
|
||||
)
|
||||
else()
|
||||
set(CRT_FLAGS_RELEASE "/MD")
|
||||
set(CRT_FLAGS_DEBUG "/MDd")
|
||||
add_compile_options(
|
||||
$<$<CONFIG:>:/MD>
|
||||
$<$<CONFIG:Debug>:/MDd>
|
||||
$<$<CONFIG:Release>:/MD>
|
||||
)
|
||||
endif()
|
||||
|
||||
# TODO: Figure out why pdb generation messes with incremental compilaton.
|
||||
# IN RELEASE_WITH_DEBUG_INFO, generate debug info in .obj, no in pdb.
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Z7")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /Z7")
|
||||
|
||||
# In RELEASE, also generate PDBs.
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CRT_FLAGS_RELEASE} /Zi")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${CRT_FLAGS_RELEASE} /Zi")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi")
|
||||
|
||||
# In DEBUG, avoid generating a PDB file which seems to mess with incremental compilation.
|
||||
# Instead generate debug info directly inside obj files.
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Z7")
|
||||
|
||||
# Special settings when building on CI.
|
||||
if (${FILAMENT_WINDOWS_CI_BUILD})
|
||||
@@ -285,6 +299,12 @@ if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
|
||||
endif()
|
||||
|
||||
# Use hidden by default and expose what we need.
|
||||
if (NOT WIN32)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Release compiler flags
|
||||
# ==================================================================================================
|
||||
@@ -365,6 +385,12 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebIn
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTNT_DEV")
|
||||
endif()
|
||||
|
||||
# By default, build with support for OpenGL on all platforms.
|
||||
option(FILAMENT_SUPPORTS_OPENGL "Include the OpenGL backend" ON)
|
||||
if (FILAMENT_SUPPORTS_OPENGL)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_OPENGL)
|
||||
endif()
|
||||
|
||||
# By default, build with Vulkan support on desktop platforms, although clients must request to use
|
||||
# it at run time.
|
||||
if (WIN32 OR WEBGL OR IOS)
|
||||
@@ -420,9 +446,9 @@ endif()
|
||||
|
||||
set(MATC_API_FLAGS )
|
||||
|
||||
# TODO: Add a flag to build Filament without support for OpenGL.
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a opengl)
|
||||
|
||||
if (FILAMENT_SUPPORTS_OPENGL)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a opengl)
|
||||
endif()
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a vulkan)
|
||||
endif()
|
||||
@@ -430,8 +456,9 @@ if (FILAMENT_SUPPORTS_METAL)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a metal)
|
||||
endif()
|
||||
|
||||
# Disable optimizations and enable debug info (preserves names in SPIR-V)
|
||||
if (FILAMENT_DISABLE_MATOPT)
|
||||
set(MATC_OPT_FLAGS -g)
|
||||
set(MATC_OPT_FLAGS -gd)
|
||||
endif()
|
||||
|
||||
set(MATC_BASE_FLAGS ${MATC_API_FLAGS} -p ${MATC_TARGET} ${MATC_OPT_FLAGS})
|
||||
@@ -639,14 +666,12 @@ if (WEBGL)
|
||||
endif()
|
||||
|
||||
if (IS_HOST_PLATFORM)
|
||||
add_subdirectory(${LIBRARIES}/bluegl)
|
||||
if (FILAMENT_SUPPORTS_OPENGL)
|
||||
add_subdirectory(${LIBRARIES}/bluegl)
|
||||
endif()
|
||||
add_subdirectory(${LIBRARIES}/filamentapp)
|
||||
add_subdirectory(${LIBRARIES}/imageio)
|
||||
|
||||
add_subdirectory(${FILAMENT}/java/filamat)
|
||||
add_subdirectory(${FILAMENT}/java/filament)
|
||||
add_subdirectory(${FILAMENT}/java/gltfio)
|
||||
|
||||
add_subdirectory(${FILAMENT}/samples)
|
||||
|
||||
add_subdirectory(${EXTERNAL}/astcenc/tnt)
|
||||
|
||||
89
README.md
89
README.md
@@ -31,39 +31,28 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.9.24'
|
||||
implementation 'com.google.android.filament:filament-android:1.12.1'
|
||||
}
|
||||
```
|
||||
|
||||
Here are all the libraries available in the group `com.google.android.filament`:
|
||||
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android)
|
||||
The Filament rendering engine itself.
|
||||
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android)
|
||||
A glTF 2.0 loader for Filament, depends on `filament-android` .
|
||||
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite)
|
||||
Trimmed version of `gltfio` that does not support some glTF features.
|
||||
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android)
|
||||
KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`.
|
||||
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android-lite)
|
||||
Trimmed version of `filament-utils` that does not support some glTF features.
|
||||
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android)
|
||||
A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer.
|
||||
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite)
|
||||
A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations.
|
||||
| Artifact | Description |
|
||||
| ------------- | ------------- |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite) | Trimmed version of `gltfio` that does not support some glTF extensions. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android-lite) | Trimmed version of `filament-utils` that does not support some glTF features. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
|
||||
|
||||
### iOS
|
||||
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.9.24'
|
||||
pod 'Filament', '~> 1.12.1'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
@@ -97,25 +86,12 @@ steps:
|
||||

|
||||

|
||||
|
||||
|
||||
### Applications
|
||||
|
||||
Here are a few screenshots of applications that use Filament in production:
|
||||
|
||||
#### Google Maps AR Navigation
|
||||
|
||||

|
||||
|
||||
#### Google Search 3D/AR Viewer on Android
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
### APIs
|
||||
|
||||
- Native C++ API for Android, iOS, Linux, macOS and Windows
|
||||
- Java/JNI API for Android, Linux, macOS and Windows
|
||||
- Java/JNI API for Android
|
||||
- JavaScript API
|
||||
|
||||
### Backends
|
||||
@@ -131,6 +107,7 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- Clustered forward renderer
|
||||
- Cook-Torrance microfacet specular BRDF
|
||||
- Lambertian diffuse BRDF
|
||||
- Custom lighting/surface shading
|
||||
- HDR/linear lighting
|
||||
- Metallic workflow
|
||||
- Clear coat
|
||||
@@ -142,20 +119,26 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- Physically-based camera (shutter speed, sensitivity and aperture)
|
||||
- Physical light units
|
||||
- Point lights, spot lights and directional light
|
||||
- Specular anti-aliasing
|
||||
- Spot and directional light shadows
|
||||
- Cascaded shadows
|
||||
- VSM or PCF shadows
|
||||
- EVSM or PCF shadows
|
||||
- Transparent shadows
|
||||
- Contact shadows
|
||||
- Screen-space ambient occlusion
|
||||
- Screen-space refraction
|
||||
- Global fog
|
||||
- Dynamic resolution
|
||||
|
||||
### Post processing
|
||||
|
||||
- HDR bloom
|
||||
- Depth of field bokeh
|
||||
- Multiple tone mappers: ACES, filmic, etc.
|
||||
- Color grading: white balance, channel mixer, shadows/mid-tones/highlights, ASC CDL,
|
||||
contrast, saturation, etc.
|
||||
- TAA, FXAA, MSAA and specular anti-aliasing
|
||||
- Dynamic resolution
|
||||
- TAA, FXAA, MSAA
|
||||
- Screen-space lens flares
|
||||
|
||||
### glTF 2.0
|
||||
|
||||
@@ -184,10 +167,12 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- [x] KHR_draco_mesh_compression
|
||||
- [x] KHR_lights_punctual
|
||||
- [x] KHR_materials_clearcoat
|
||||
- [x] KHR_materials_ior
|
||||
- [x] KHR_materials_pbrSpecularGlossiness
|
||||
- [x] KHR_materials_sheen
|
||||
- [x] KHR_materials_transmission
|
||||
- [x] KHR_materials_unlit
|
||||
- [x] KHR_materials_volume
|
||||
- [x] KHR_mesh_quantization
|
||||
- [x] KHR_texture_transform
|
||||
|
||||
@@ -255,22 +240,11 @@ if (renderer->beginFrame(swapChain)) {
|
||||
```
|
||||
|
||||
For complete examples of Linux, macOS and Windows Filament applications, look at the source files
|
||||
in the `samples/` directory. These samples are all based on `samples/app/` which contains the code
|
||||
that creates a native window with SDL2 and initializes the Filament engine, renderer and views.
|
||||
in the `samples/` directory. These samples are all based on `libs/filamentapp/` which contains the
|
||||
code that creates a native window with SDL2 and initializes the Filament engine, renderer and views.
|
||||
|
||||
### Java on Linux, macOS and Windows
|
||||
|
||||
After building Filament, you can use `filament-java.jar` and its companion `filament-jni` native
|
||||
library to use Filament in desktop Java applications.
|
||||
|
||||
You must always first initialize Filament by calling `Filament.init()`.
|
||||
|
||||
You can use Filament either with AWT or Swing, using respectively a `FilamentCanvas` or a
|
||||
`FilamentPanel`.
|
||||
|
||||
Following the steps above (how to use Filament from native code), create an `Engine` and a
|
||||
`Renderer`, but instead of calling `beginFrame` and `endFrame` on the renderer itself, call
|
||||
these methods on `FilamentCanvas` or `FilamentPanel`.
|
||||
For more information on how to prepare environment maps for image-based lighting please refer to
|
||||
[BUILDING.md](https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples).
|
||||
|
||||
### Android
|
||||
|
||||
@@ -301,6 +275,10 @@ To get started you can use the textures and environment maps found respectively
|
||||
`third_party/textures` and `third_party/environments`. These assets are under CC0 license. Please
|
||||
refer to their respective `URL.txt` files to know more about the original authors.
|
||||
|
||||
Environments must be pre-processed using
|
||||
[`cmgen`](https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples) or
|
||||
using the `libiblprefilter` library.
|
||||
|
||||
## How to make contributions
|
||||
|
||||
Please read and follow the steps in [CONTRIBUTING.md](/CONTRIBUTING.md). Make sure you are
|
||||
@@ -323,9 +301,9 @@ and tools.
|
||||
- `docs`: Documentation
|
||||
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
|
||||
- `filament`: Filament rendering engine (minimal dependencies)
|
||||
- `backend`: Rendering backends/drivers (Vulkan, Metal, OpenGL/ES)
|
||||
- `ide`: Configuration files for IDEs (CLion, etc.)
|
||||
- `ios`: Sample projects for iOS
|
||||
- `java`: Java bindings for Filament libraries
|
||||
- `libs`: Libraries
|
||||
- `bluegl`: OpenGL bindings for macOS, Linux and Windows
|
||||
- `bluevk`: Vulkan bindings for macOS, Linux, Windows and Android
|
||||
@@ -345,6 +323,7 @@ and tools.
|
||||
- `math`: Math library
|
||||
- `mathio`: Math types support for output streams
|
||||
- `utils`: Utility library (threads, memory, data structures, etc.)
|
||||
- `viewer`: glTF viewer library (requires gltfio)
|
||||
- `samples`: Sample desktop applications
|
||||
- `shaders`: Shaders used by `filamat` and `matc`
|
||||
- `third_party`: External libraries and assets
|
||||
|
||||
149
RELEASE_NOTES.md
149
RELEASE_NOTES.md
@@ -3,7 +3,154 @@
|
||||
This file contains one line summaries of commits that are worthy of mentioning in release notes.
|
||||
A new header is inserted each time a *tag* is created.
|
||||
|
||||
## Next release (main branch)
|
||||
## v1.12.2 (currently main branch)
|
||||
|
||||
## v1.12.1
|
||||
|
||||
- engine: `double` precision translation support in TransformManager. Disabled by default.
|
||||
Augment model (and view) matrix on `Camera` to accept double precision matrices. When enabled,
|
||||
double precision translations allow filament to handle a very large world space.
|
||||
[**New API**].
|
||||
- engine: Fix, Views with custom render targets are now blendable.
|
||||
|
||||
## v1.12.0
|
||||
|
||||
- engine: Option to automatically compute bent normals from SSAO & apply to specular AO
|
||||
[⚠️ **Material breakage**].
|
||||
- engine: New APIs: Light channels. Geometry and lights now have a channel associated to them, at
|
||||
least one channel must match for lighting to occur [⚠️ **Material breakage**].
|
||||
- engine: Fix potential GPU crash with punctual lights near the far clipping plane.
|
||||
- materials: The `inverseTonemap` API is now an exact inverse of the Filmic tonemapper.
|
||||
- Metal: Better support for texture formats on M1 Macs.
|
||||
|
||||
## v1.11.2
|
||||
|
||||
- engine: New API: `ColorGrading::Builder::toneMapper(const ToneMapper*)`.
|
||||
- engine: New tone mapper: `GenericToneMapper`, a configurable tone mapper.
|
||||
- engine: `ColorGrading::Builder::toneMapping(ColorGrading::ToneMapping)` is now deprecated.
|
||||
- engine: Removed `REINHARD` tonemap operator[⚠️ **API Change**].
|
||||
- engine: Improve s3tc_srgb detection on desktop.
|
||||
- engine: Add bilateral threshold in SSAO options.
|
||||
- gltfio: Fix AssetLoader leak, remove unwanted destructor.
|
||||
- Metal/Vulkan: Fix uploading texture data with padding or offset.
|
||||
- Metal: fix GPU crash seen with large amounts of geometry.
|
||||
|
||||
## v1.11.1
|
||||
|
||||
- engine: Luminance scaling can now be used with any tone mapping operator. It was previously tied
|
||||
to the "EVILS" tone mapping operator.
|
||||
- engine: Removed the "EVILS" tone mapping operator [⚠️ **API Change**].
|
||||
- engine: Improvements to Skinning. A new `SkinningBuffer` API allows bone sharing between
|
||||
renderables.
|
||||
- engine: Improvements to internal memory allocation for Metal and Vulkan backends.
|
||||
- engine: Default to OpenGL backend when Windows does not support Vulkan.
|
||||
- samples: Add new sample app: image_viewer.
|
||||
|
||||
## v1.11.0
|
||||
|
||||
- engine: Added support for transparent shadows. Add `transparentShadow : true` in the material file.
|
||||
- engine: honor user-defined precision in material files for non-samplers, rename `SamplerPrecision`
|
||||
to `ParameterPrecicion`. [⚠️ **API Change**]
|
||||
- engine: Work around Qualcomm issue with point lights.
|
||||
- engine: Allow MSAA when post-processing is disabled.
|
||||
- engine: enable up to 6 spot-light shadows.
|
||||
- gltfio: Added support for `KHR_materials_volume`.
|
||||
- gltfio: fix precision in KHR_texture_transform.
|
||||
- java: Removed support for Java desktop targets (macOS, Linux, and Windows) [⚠️ **API Change**].
|
||||
|
||||
## v1.10.7
|
||||
|
||||
- engine: Spot-light position calculation moved to fragment shader.
|
||||
- engine: Small shadow mapping fixes and improvements.
|
||||
- gltfio: Add fast path for native material providers.
|
||||
- gltfio: Allow Java / Kotlin clients to customize MaterialProvider.
|
||||
- engine: Fix out of bounds access with `RenderTarget` java bindings.
|
||||
- Metal: `TextureFormat::DEPTH24_STENCIL8` now maps to a 32 bit depth format on iOS.
|
||||
|
||||
## v1.10.6
|
||||
|
||||
- engine: Use exponential VSM and improve VSM user settings [⚠️ **Recompile Materials for VSM**].
|
||||
- engine: Optional blurring of VSM shadowmaps.
|
||||
- engine: Fix a crash when using lens flares.
|
||||
- engine: Fix backend crashes when using an unsupported sample count.
|
||||
- gltfio: Add new `getAsset`API to `FilamentInstance`.
|
||||
- gltfio: Introduce support for extras strings.
|
||||
- OpenGL: Increase OpenGL backend handle arena from 2 to 4 MiB.
|
||||
- Vulkan: Fix Texture swizzle support.
|
||||
|
||||
## v1.10.5
|
||||
|
||||
- android: AAR libraries now properly include their ProGuard rules.
|
||||
- engine: User materials can now provide custom lighting/surface shading, please consult
|
||||
the [materials documentation](https://google.github.io/filament/Materials.html) for details.
|
||||
- engine: `Backend::DEFAULT` now selects the most appropriate backend for the platform, rather than
|
||||
always `OPENGL`. On Android the default is `OPENGL`, on Apple platforms the default is `METAL` and
|
||||
on all other platforms that default is `VULKAN`.
|
||||
- engine: Fix a potential memory corruption when using more than 4 render targets.
|
||||
- engine: Fix a possible crash when bloom is enabled.
|
||||
- engine: Fix and refactor support for S3TC + SRGB with OpenGL.
|
||||
- engine: Fix automatic clearing of rendertargets.
|
||||
- engine: Fix imported render target discard and clear flags.
|
||||
- engine: Fix opaque blit with imported render targets.
|
||||
|
||||
## v1.10.4
|
||||
|
||||
- engine: improvements to internal job system.
|
||||
- Vulkan: performance improvements on Mali.
|
||||
- gltfio: improvements to load time for large models.
|
||||
- WebGL: remove bogus stride argument, fix `BindingType` TypeScript definition.
|
||||
|
||||
## v1.10.3
|
||||
|
||||
- android: use `debug.filament.backend` system property to select the desired backend.
|
||||
- engine: fix `LightManager::getFalloff`.
|
||||
- gltfio: fix crash with non-triangles.
|
||||
- macOS: fix main thread checker warnings with OpenGL.
|
||||
- vulkan: fix crash on Windows machines with NVIDIA GPUs.
|
||||
|
||||
## v1.10.2
|
||||
|
||||
- Vulkan: validation and diagnostic improvements
|
||||
- engine: improvements for scenes with many renderables.
|
||||
- gltfio: added support for `KHR_materials_ior`.
|
||||
- java: Add bindings for `IBLPrefilterContext`.
|
||||
- java: add `KTXLoader.getSphericalHarmonics` JNI binding
|
||||
- libimage: fix, respect sRGB option for compressed formats.
|
||||
- sample-gltf-viewer: fix lifetime cycle for RemoteServer.
|
||||
|
||||
## v1.10.1
|
||||
|
||||
- engine: Add `getPlatform` API to Engine.
|
||||
- engine: Add a new cone angles API to `LightManager`.
|
||||
- engine: Attachments of custom RendereTargets are not systematically discarded.
|
||||
- engine: Fix a crash when using custom rendertargets.
|
||||
- engine: New API to duplicate a `MaterialInstance`.
|
||||
- filagui: fix support for custom images in ImGuiHelper.
|
||||
- java: Add bindings for HDRLoader.
|
||||
|
||||
## v1.10.0
|
||||
|
||||
- engine: User materials can now use 9 samplers instead of 8 [⚠️ **Material breakage**].
|
||||
- engine: Remove `populateTangentQuaternions` [⚠️ **API change**].
|
||||
- engine: Deprecate `Stream::Builder::stream(intptr_t)` [⚠️ **API Change**].
|
||||
- engine: Remove deprecated APIs: `Camera::setScaling`, `Engine::destroy(Camera*)`,
|
||||
`Engine::createCamera`, `Renderer::beginFrame(SwapChain*, uint64_t,
|
||||
backend::FrameScheduledCallback, void*)`, and `View::setShadowsEnabled` [⚠️ **API Change**].
|
||||
- engine: Remove `focusDistance` from `View::BloomOptions` [⚠️ **API Change**].
|
||||
- engine: Add a `FILAMENT_SUPPORTS_OPENGL` CMake option to enable/disable OpenGL support.
|
||||
- Vulkan: fixes and improvements for large scenes.
|
||||
- gltfio: fix morphing bugs uncovered by MorphStressTest.
|
||||
- Java: add API for `Texture::Builder::import()`.
|
||||
- WebGL: Fix a potential INVALID_OPERATION.
|
||||
|
||||
## v1.9.25
|
||||
|
||||
- NEW API: Screen-space lens flare effect.
|
||||
- engine: Fix several memory leaks in the GL backend.
|
||||
- Vulkan: General bug fixes and improvements.
|
||||
- Vulkan: Fix some problems seen on Mali devices.
|
||||
- ios: Fix VSM shadows not working.
|
||||
- webgl: Fix black screen seen with some samples.
|
||||
|
||||
## v1.9.24
|
||||
|
||||
|
||||
@@ -59,14 +59,13 @@ buildscript {
|
||||
}
|
||||
}
|
||||
|
||||
// Our minSdkVersion is 19.
|
||||
ext.versions = [
|
||||
'minSdk': 19,
|
||||
'targetSdk': 30,
|
||||
'compileSdk': 30,
|
||||
'kotlin': '1.4.31',
|
||||
'kotlin': '1.5.21',
|
||||
'buildTools': '30.0.3',
|
||||
'ndk': '22.0.7026061'
|
||||
'ndk': '22.1.7171670'
|
||||
]
|
||||
|
||||
ext.deps = [
|
||||
@@ -78,7 +77,7 @@ buildscript {
|
||||
]
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
classpath 'com.android.tools.build:gradle:7.0.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
|
||||
@@ -93,8 +92,7 @@ buildscript {
|
||||
ext.cppFlags = [
|
||||
"-std=c++17",
|
||||
"-Wno-unused-command-line-argument",
|
||||
// Required to support API levels below 23
|
||||
"-Wl,--hash-style=both",
|
||||
"-Wl,--hash-style=both", // Required to support API levels below 23
|
||||
"-fno-stack-protector",
|
||||
"-fno-exceptions",
|
||||
"-fno-unwind-tables",
|
||||
@@ -116,7 +114,6 @@ buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +135,6 @@ subprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
if (!name.startsWith("sample")) {
|
||||
@@ -163,11 +159,13 @@ subprojects {
|
||||
ndk {
|
||||
abiFilters(*rootProject.ext.abis)
|
||||
}
|
||||
}
|
||||
|
||||
consumerProguardFiles '../proguard-rules.pro'
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version "3.19.0+"
|
||||
path "CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,11 @@ import org.gradle.api.file.FileType
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputDirectory
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.api.tasks.incremental.InputFileDetails
|
||||
@@ -33,24 +36,23 @@ import java.nio.file.Paths
|
||||
|
||||
class TaskWithBinary extends DefaultTask {
|
||||
private final String binaryName
|
||||
private File binaryPath = null
|
||||
private Property<String> binaryPath = null
|
||||
|
||||
TaskWithBinary(String name) {
|
||||
binaryName = name
|
||||
}
|
||||
|
||||
String getBinaryName() {
|
||||
return binaryName
|
||||
}
|
||||
|
||||
File getBinary() {
|
||||
@Input
|
||||
Property<String> getBinary() {
|
||||
if (binaryPath == null) {
|
||||
def tool = ["/bin/${binaryName}.exe", "/bin/${binaryName}"]
|
||||
def fullPath = tool.collect { path ->
|
||||
Paths.get(project.ext.filamentToolsPath.absolutePath, path).toFile()
|
||||
}
|
||||
|
||||
binaryPath = OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]
|
||||
binaryPath = project.objects.property(String.class)
|
||||
binaryPath.set(
|
||||
(OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]).toString())
|
||||
}
|
||||
return binaryPath
|
||||
}
|
||||
@@ -65,14 +67,6 @@ class LogOutputStream extends ByteArrayOutputStream {
|
||||
this.level = level
|
||||
}
|
||||
|
||||
Logger getLogger() {
|
||||
return logger
|
||||
}
|
||||
|
||||
LogLevel getLevel() {
|
||||
return level
|
||||
}
|
||||
|
||||
@Override
|
||||
void flush() {
|
||||
logger.log(level, toString())
|
||||
@@ -85,10 +79,10 @@ class LogOutputStream extends ByteArrayOutputStream {
|
||||
abstract class MaterialCompiler extends TaskWithBinary {
|
||||
@Incremental
|
||||
@InputDirectory
|
||||
final DirectoryProperty inputDir = project.objects.directoryProperty()
|
||||
abstract DirectoryProperty getInputDir()
|
||||
|
||||
@OutputDirectory
|
||||
final DirectoryProperty outputDir = project.objects.directoryProperty()
|
||||
abstract DirectoryProperty getOutputDir()
|
||||
|
||||
MaterialCompiler() {
|
||||
super("matc")
|
||||
@@ -115,8 +109,8 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
if (!new File(binary.get()).exists()) {
|
||||
throw new GradleException("Could not find ${binary.get()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
@@ -129,7 +123,7 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${getBinary()}"
|
||||
executable "${binary.get()}"
|
||||
args matcArgs
|
||||
}
|
||||
}
|
||||
@@ -143,15 +137,17 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
|
||||
// Custom task to process IBLs using cmgen
|
||||
// This task handles incremental builds
|
||||
class IblGenerator extends TaskWithBinary {
|
||||
String cmgenArgs = null
|
||||
abstract class IblGenerator extends TaskWithBinary {
|
||||
@Input
|
||||
@Optional
|
||||
abstract Property<String> getCmgenArgs()
|
||||
|
||||
@Incremental
|
||||
@InputFile
|
||||
final RegularFileProperty inputFile = project.objects.fileProperty()
|
||||
abstract RegularFileProperty getInputFile()
|
||||
|
||||
@OutputDirectory
|
||||
final DirectoryProperty outputDir = project.objects.directoryProperty()
|
||||
abstract DirectoryProperty getOutputDir()
|
||||
|
||||
IblGenerator() {
|
||||
super("cmgen")
|
||||
@@ -178,23 +174,25 @@ class IblGenerator extends TaskWithBinary {
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
if (!new File(binary.get()).exists()) {
|
||||
throw new GradleException("Could not find ${binary.get()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
def outputPath = outputDir.get().asFile
|
||||
def commandArgs = cmgenArgs.getOrNull()
|
||||
if (commandArgs == null) {
|
||||
commandArgs =
|
||||
'-q -x ' + outputPath + ' --format=rgb32f ' +
|
||||
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
|
||||
}
|
||||
commandArgs = commandArgs + " " + file
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
if (!cmgenArgs) {
|
||||
cmgenArgs =
|
||||
'-q -x ' + outputPath + ' --format=rgb32f ' +
|
||||
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
|
||||
}
|
||||
cmgenArgs = cmgenArgs + " " + file
|
||||
errorOutput err
|
||||
executable "${getBinary()}"
|
||||
args(cmgenArgs.split())
|
||||
executable "${binary.get()}"
|
||||
args(commandArgs.split())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,13 +205,13 @@ class IblGenerator extends TaskWithBinary {
|
||||
|
||||
// Custom task to compile mesh files using filamesh
|
||||
// This task handles incremental builds
|
||||
class MeshCompiler extends TaskWithBinary {
|
||||
abstract class MeshCompiler extends TaskWithBinary {
|
||||
@Incremental
|
||||
@InputFile
|
||||
final RegularFileProperty inputFile = project.objects.fileProperty()
|
||||
abstract RegularFileProperty getInputFile()
|
||||
|
||||
@OutputDirectory
|
||||
final DirectoryProperty outputDir = project.objects.directoryProperty()
|
||||
abstract DirectoryProperty getOutputDir()
|
||||
|
||||
MeshCompiler() {
|
||||
super("filamesh")
|
||||
@@ -240,15 +238,15 @@ class MeshCompiler extends TaskWithBinary {
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
if (!new File(binary.get()).exists()) {
|
||||
throw new GradleException("Could not find ${binary.get()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${getBinary()}"
|
||||
executable "${binary.get()}"
|
||||
args(file, getOutputFile(file))
|
||||
}
|
||||
}
|
||||
@@ -291,8 +289,8 @@ class FilamentToolsPlugin implements Plugin<Project> {
|
||||
enabled =
|
||||
extension.materialInputDir.isPresent() &&
|
||||
extension.materialOutputDir.isPresent()
|
||||
inputDir = extension.materialInputDir.getOrNull()
|
||||
outputDir = extension.materialOutputDir.getOrNull()
|
||||
inputDir.set(extension.materialInputDir.getOrNull())
|
||||
outputDir.set(extension.materialOutputDir.getOrNull())
|
||||
}
|
||||
|
||||
project.preBuild.dependsOn "filamentCompileMaterials"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(filamat-android)
|
||||
|
||||
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||
|
||||
|
||||
@@ -123,19 +123,22 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderInterpo
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameter(
|
||||
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jstring name_) {
|
||||
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint precision, jstring name_) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
const char* name = env->GetStringUTFChars(name_, nullptr);
|
||||
builder->parameter((MaterialBuilder::UniformType) uniformType, name);
|
||||
builder->parameter((MaterialBuilder::UniformType) uniformType,
|
||||
(MaterialBuilder::ParameterPrecision) precision, name);
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameterArray(
|
||||
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint size, jstring name_) {
|
||||
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint size, jint precision,
|
||||
jstring name_) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
const char* name = env->GetStringUTFChars(name_, nullptr);
|
||||
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size, name);
|
||||
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size,
|
||||
(MaterialBuilder::ParameterPrecision) precision, name);
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
}
|
||||
|
||||
@@ -146,7 +149,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSampler
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
const char* name = env->GetStringUTFChars(name_, nullptr);
|
||||
builder->parameter((MaterialBuilder::SamplerType) samplerType,
|
||||
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::SamplerPrecision) precision,
|
||||
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::ParameterPrecision) precision,
|
||||
name);
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
}
|
||||
@@ -255,6 +258,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShadowM
|
||||
builder->shadowMultiplier(shadowMultiplier);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderTransparentShadow(
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jboolean transparentShadow) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->transparentShadow(transparentShadow);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSpecularAntiAliasing(
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jboolean specularAntiAliasing) {
|
||||
@@ -291,6 +301,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderFlipUV(
|
||||
builder->flipUV(flipUV);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderCustomSurfaceShading(JNIEnv*,
|
||||
jclass, jlong nativeBuilder, jboolean customSurfaceShading) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->customSurfaceShading(customSurfaceShading);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMultiBounceAmbientOcclusion(
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jboolean multiBounceAO) {
|
||||
|
||||
@@ -91,7 +91,7 @@ public class MaterialBuilder {
|
||||
SHADOW
|
||||
}
|
||||
|
||||
public enum SamplerPrecision {
|
||||
public enum ParameterPrecision {
|
||||
LOW,
|
||||
MEDIUM,
|
||||
HIGH,
|
||||
@@ -247,19 +247,36 @@ public class MaterialBuilder {
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder uniformParameter(@NonNull UniformType type, String name) {
|
||||
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), name);
|
||||
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(),
|
||||
ParameterPrecision.DEFAULT.ordinal(), name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder uniformParameter(@NonNull UniformType type,
|
||||
ParameterPrecision precision, String name) {
|
||||
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), precision.ordinal(), name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size, String name) {
|
||||
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size, name);
|
||||
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size,
|
||||
ParameterPrecision.DEFAULT.ordinal(), name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size,
|
||||
ParameterPrecision precision, String name) {
|
||||
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size,
|
||||
precision.ordinal(), name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder samplerParameter(@NonNull SamplerType type, SamplerFormat format,
|
||||
SamplerPrecision precision, String name) {
|
||||
ParameterPrecision precision, String name) {
|
||||
nMaterialBuilderSamplerParameter(
|
||||
mNativeObject, type.ordinal(), format.ordinal(), precision.ordinal(), name);
|
||||
return this;
|
||||
@@ -349,6 +366,12 @@ public class MaterialBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder transparentShadow(boolean transparentShadow) {
|
||||
nMaterialBuilderTransparentShadow(mNativeObject, transparentShadow);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder specularAntiAliasing(boolean specularAntiAliasing) {
|
||||
nMaterialBuilderSpecularAntiAliasing(mNativeObject, specularAntiAliasing);
|
||||
@@ -391,6 +414,12 @@ public class MaterialBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder customSurfaceShading(boolean customSurfaceShading) {
|
||||
nMaterialBuilderCustomSurfaceShading(mNativeObject, customSurfaceShading);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder multiBounceAmbientOcclusion(boolean multiBounceAO) {
|
||||
nMaterialBuilderMultiBounceAmbientOcclusion(mNativeObject, multiBounceAO);
|
||||
@@ -523,9 +552,9 @@ public class MaterialBuilder {
|
||||
private static native void nMaterialBuilderShading(long nativeBuilder, int shading);
|
||||
private static native void nMaterialBuilderInterpolation(long nativeBuilder, int interpolation);
|
||||
private static native void nMaterialBuilderUniformParameter(long nativeBuilder, int type,
|
||||
String name);
|
||||
int precision, String name);
|
||||
private static native void nMaterialBuilderUniformParameterArray(long nativeBuilder, int type,
|
||||
int size, String name);
|
||||
int size, int precision, String name);
|
||||
private static native void nMaterialBuilderSamplerParameter(long nativeBuilder, int type,
|
||||
int format, int precision, String name);
|
||||
private static native void nMaterialBuilderVariable(long nativeBuilder, int variable,
|
||||
@@ -545,6 +574,8 @@ public class MaterialBuilder {
|
||||
|
||||
private static native void nMaterialBuilderShadowMultiplier(long mNativeObject,
|
||||
boolean shadowMultiplier);
|
||||
private static native void nMaterialBuilderTransparentShadow(long mNativeObject,
|
||||
boolean transparentShadow);
|
||||
private static native void nMaterialBuilderSpecularAntiAliasing(long mNativeObject,
|
||||
boolean specularAntiAliasing);
|
||||
private static native void nMaterialBuilderSpecularAntiAliasingVariance(long mNativeObject,
|
||||
@@ -556,6 +587,8 @@ public class MaterialBuilder {
|
||||
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
|
||||
boolean clearCoatIorChange);
|
||||
private static native void nMaterialBuilderFlipUV(long nativeBuilder, boolean flipUV);
|
||||
private static native void nMaterialBuilderCustomSurfaceShading(long nativeBuilder,
|
||||
boolean customSurfaceShading);
|
||||
private static native void nMaterialBuilderMultiBounceAmbientOcclusion(long nativeBuilder,
|
||||
boolean multiBounceAO);
|
||||
private static native void nMaterialBuilderSpecularAmbientOcclusion(long nativeBuilder,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(filament-android)
|
||||
|
||||
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
|
||||
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||
@@ -26,6 +27,10 @@ add_library(filaflat STATIC IMPORTED)
|
||||
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
|
||||
|
||||
add_library(filamat STATIC IMPORTED)
|
||||
set_target_properties(filamat PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilamat.a)
|
||||
|
||||
add_library(geometry STATIC IMPORTED)
|
||||
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
|
||||
@@ -74,11 +79,13 @@ add_library(filament-jni SHARED
|
||||
src/main/cpp/RenderTarget.cpp
|
||||
src/main/cpp/Scene.cpp
|
||||
src/main/cpp/SkyBox.cpp
|
||||
src/main/cpp/SkinningBuffer.cpp
|
||||
src/main/cpp/Stream.cpp
|
||||
src/main/cpp/SurfaceOrientation.cpp
|
||||
src/main/cpp/SwapChain.cpp
|
||||
src/main/cpp/Texture.cpp
|
||||
src/main/cpp/TextureSampler.cpp
|
||||
src/main/cpp/ToneMapper.cpp
|
||||
src/main/cpp/TransformManager.cpp
|
||||
src/main/cpp/VertexBuffer.cpp
|
||||
src/main/cpp/View.cpp
|
||||
@@ -109,6 +116,7 @@ target_link_libraries(filament-jni
|
||||
PUBLIC geometry
|
||||
|
||||
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
|
||||
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
|
||||
|
||||
@@ -13,7 +13,9 @@ LIBFILAMENT {
|
||||
*filament*IndirectLight*;
|
||||
*filament*LightManager*;
|
||||
*filament*Renderer*;
|
||||
*filament*RenderTarget*;
|
||||
*filament*Scene*;
|
||||
*filament*ToneMapper*;
|
||||
*filament*Transform*;
|
||||
*filament*Material*;
|
||||
*filament*IndexBuffer*;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <filament/Camera.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
|
||||
using namespace filament;
|
||||
@@ -100,10 +102,19 @@ Java_com_google_android_filament_Camera_nSetModelMatrix(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jfloatArray in_) {
|
||||
Camera* camera = (Camera *) nativeCamera;
|
||||
jfloat *in = env->GetFloatArrayElements(in_, NULL);
|
||||
camera->setModelMatrix(*reinterpret_cast<const filament::math::mat4f*>(in));
|
||||
camera->setModelMatrix((math::mat4)*reinterpret_cast<const filament::math::mat4f*>(in));
|
||||
env->ReleaseFloatArrayElements(in_, in, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nSetModelMatrixFp64(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jdoubleArray in_) {
|
||||
Camera* camera = (Camera *) nativeCamera;
|
||||
jdouble *in = env->GetDoubleArrayElements(in_, NULL);
|
||||
camera->setModelMatrix(*reinterpret_cast<const filament::math::mat4*>(in));
|
||||
env->ReleaseDoubleArrayElements(in_, in, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetProjectionMatrix(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jdoubleArray out_) {
|
||||
@@ -139,21 +150,41 @@ Java_com_google_android_filament_Camera_nGetModelMatrix(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jfloatArray out_) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jfloat *out = env->GetFloatArrayElements(out_, NULL);
|
||||
const filament::math::mat4f& m = camera->getModelMatrix();
|
||||
const filament::math::mat4f& m = (math::mat4f)camera->getModelMatrix();
|
||||
std::copy_n(&m[0][0], 16, out);
|
||||
env->ReleaseFloatArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetModelMatrixFp64(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jdoubleArray out_) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
|
||||
const filament::math::mat4& m = camera->getModelMatrix();
|
||||
std::copy_n(&m[0][0], 16, out);
|
||||
env->ReleaseDoubleArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetViewMatrix(JNIEnv *env, jclass, jlong nativeCamera,
|
||||
jfloatArray out_) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jfloat *out = env->GetFloatArrayElements(out_, NULL);
|
||||
const filament::math::mat4f& m = camera->getViewMatrix();
|
||||
const filament::math::mat4f& m = (math::mat4f)camera->getViewMatrix();
|
||||
std::copy_n(&m[0][0], 16, out);
|
||||
env->ReleaseFloatArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetViewMatrixFp64(JNIEnv *env, jclass, jlong nativeCamera,
|
||||
jdoubleArray out_) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
|
||||
const filament::math::mat4& m = camera->getViewMatrix();
|
||||
std::copy_n(&m[0][0], 16, out);
|
||||
env->ReleaseDoubleArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetPosition(JNIEnv *env, jclass, jlong nativeCamera,
|
||||
jfloatArray out_) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/ColorGrading.h>
|
||||
#include <filament/ToneMapper.h>
|
||||
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
@@ -30,28 +31,35 @@ Java_com_google_android_filament_ColorGrading_nCreateBuilder(JNIEnv*, jclass) {
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nDestroyBuilder(JNIEnv*, jclass,
|
||||
jlong nativeBuilder) {
|
||||
Java_com_google_android_filament_ColorGrading_nDestroyBuilder(JNIEnv*, jclass, jlong nativeBuilder) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder, jlong nativeEngine) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return (jlong) builder->build(*engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderQuality(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint quality_) {
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderQuality(JNIEnv*, jclass, jlong nativeBuilder, jint quality_) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
ColorGrading::QualityLevel quality = (ColorGrading::QualityLevel) quality_;
|
||||
builder->quality(quality);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderToneMapper(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong toneMapper_) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
const ToneMapper* toneMapper = (const ToneMapper*) toneMapper_;
|
||||
builder->toneMapper(toneMapper);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderToneMapping(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint toneMapping_) {
|
||||
@@ -59,6 +67,21 @@ Java_com_google_android_filament_ColorGrading_nBuilderToneMapping(JNIEnv*, jclas
|
||||
ColorGrading::ToneMapping toneMapping = (ColorGrading::ToneMapping) toneMapping_;
|
||||
builder->toneMapping(toneMapping);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderLuminanceScaling(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean luminanceScaling) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
builder->luminanceScaling(luminanceScaling);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderExposure(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jfloat exposure) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
builder->exposure(exposure);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderWhiteBalance(JNIEnv*, jclass,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/Camera.h>
|
||||
#include <filament/Engine.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
@@ -120,15 +121,8 @@ Java_com_google_android_filament_Engine_nDestroyRenderer(JNIEnv*, jclass,
|
||||
|
||||
// Camera
|
||||
|
||||
extern "C" [[deprecated]] JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateCamera(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) engine->createCamera();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateCameraWithEntity(JNIEnv*, jclass,
|
||||
Java_com_google_android_filament_Engine_nCreateCamera(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jint entity_) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
|
||||
@@ -143,12 +137,12 @@ Java_com_google_android_filament_Engine_nGetCameraComponent(JNIEnv*, jclass,
|
||||
return (jlong) engine->getCameraComponent(entity);
|
||||
}
|
||||
|
||||
extern "C" [[deprecated]] JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyCamera(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeCamera) {
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyCameraComponent(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jint entity_) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
engine->destroy(camera);
|
||||
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
|
||||
engine->destroyCameraComponent(entity);
|
||||
}
|
||||
|
||||
// Scene
|
||||
|
||||
@@ -77,7 +77,7 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
|
||||
jlong nativeBuilder, jint mapSize, jint cascades, jfloatArray splitPositions,
|
||||
jfloat constantBias, jfloat normalBias, jfloat shadowFar, jfloat shadowNearHint,
|
||||
jfloat shadowFarHint, jboolean stable, jboolean screenSpaceContactShadows, jint stepCount,
|
||||
jfloat maxShadowDistance, jint vsmMsaaSamples) {
|
||||
jfloat maxShadowDistance, jint vsmMsaaSamples, jfloat blurWidth) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
LightManager::ShadowOptions shadowOptions {
|
||||
.mapSize = (uint32_t)mapSize,
|
||||
@@ -92,7 +92,8 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
|
||||
.stepCount = uint8_t(stepCount),
|
||||
.maxShadowDistance = maxShadowDistance,
|
||||
.vsm = {
|
||||
.msaaSamples = (uint8_t) vsmMsaaSamples
|
||||
.msaaSamples = (uint8_t) vsmMsaaSamples,
|
||||
.blurWidth = blurWidth
|
||||
}
|
||||
};
|
||||
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
|
||||
@@ -188,6 +189,23 @@ Java_com_google_android_filament_LightManager_nBuilderHaloFalloff(JNIEnv*, jclas
|
||||
builder->sunHaloFalloff(haloFalloff);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_LightManager_nBuilderLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint channel, jboolean enable) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
builder->lightChannel(channel, (bool)enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine, jint entity) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return jboolean(builder->build(*engine, (Entity &) entity) == LightManager::Builder::Success);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_LightManager_nComputeUniformSplits(JNIEnv* env, jclass,
|
||||
jfloatArray splitPositions, jint cascades) {
|
||||
@@ -212,13 +230,7 @@ Java_com_google_android_filament_LightManager_nComputePracticalSplits(JNIEnv* en
|
||||
env->ReleaseFloatArrayElements(splitPositions, nativeSplits, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine, jint entity) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return jboolean(builder->build(*engine, (Entity &) entity) == LightManager::Builder::Success);
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_LightManager_nGetType(JNIEnv* env,
|
||||
@@ -379,3 +391,31 @@ Java_com_google_android_filament_LightManager_nIsShadowCaster(JNIEnv*, jclass,
|
||||
LightManager *lm = (LightManager *) nativeLightManager;
|
||||
return (jboolean)lm->isShadowCaster((LightManager::Instance) i);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_LightManager_nGetOuterConeAngle(JNIEnv*, jclass,
|
||||
jlong nativeLightManager, jint i) {
|
||||
LightManager *lm = (LightManager *) nativeLightManager;
|
||||
return (jfloat)lm->getSpotLightOuterCone((LightManager::Instance) i);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_LightManager_nGetInnerConeAngle(JNIEnv*, jclass,
|
||||
jlong nativeLightManager, jint i) {
|
||||
LightManager *lm = (LightManager *) nativeLightManager;
|
||||
return (jfloat)lm->getSpotLightInnerCone((LightManager::Instance) i);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_LightManager_nSetLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeLightManager, jint i, jint channel, jboolean enable) {
|
||||
LightManager *lm = (LightManager *) nativeLightManager;
|
||||
lm->setLightChannel((LightManager::Instance) i, channel, (bool)enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_LightManager_nGetLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeLightManager, jint i, jint channel) {
|
||||
LightManager const *lm = (LightManager const *) nativeLightManager;
|
||||
return lm->getLightChannel((LightManager::Instance) i, channel);
|
||||
}
|
||||
|
||||
@@ -364,3 +364,19 @@ Java_com_google_android_filament_MaterialInstance_nGetMaterial(JNIEnv* env, jcla
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
return (jlong) instance->getMaterial();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nDuplicate(JNIEnv* env, jclass clazz,
|
||||
jlong otherNativeMaterialInstance, jstring name) {
|
||||
MaterialInstance* other = (MaterialInstance*) otherNativeMaterialInstance;
|
||||
const char *cstr = nullptr;
|
||||
if (name != nullptr) {
|
||||
cstr = env->GetStringUTFChars(name, nullptr);
|
||||
}
|
||||
MaterialInstance* mi = MaterialInstance::duplicate(other, cstr);
|
||||
if (name != nullptr) {
|
||||
env->ReleaseStringUTFChars(name, cstr);
|
||||
}
|
||||
return (jlong)mi;
|
||||
}
|
||||
|
||||
@@ -170,6 +170,14 @@ Java_com_google_android_filament_RenderableManager_nBuilderScreenSpaceContactSha
|
||||
builder->screenSpaceContactShadows(enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderSkinningBuffer(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeSkinningBuffer, jint boneCount, jint offset) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
SkinningBuffer *skinningBuffer = (SkinningBuffer *) nativeSkinningBuffer;
|
||||
builder->skinning(skinningBuffer, boneCount, offset);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderSkinning(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint boneCount) {
|
||||
@@ -177,6 +185,13 @@ Java_com_google_android_filament_RenderableManager_nBuilderSkinning(JNIEnv*, jcl
|
||||
builder->skinning((size_t)boneCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nEnableSkinningBuffers(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean enabled) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->enableSkinningBuffers(enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderSkinningBones(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, jint boneCount, jobject bones, jint remaining) {
|
||||
@@ -199,6 +214,22 @@ Java_com_google_android_filament_RenderableManager_nBuilderMorphing(JNIEnv*, jcl
|
||||
builder->morphing(enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint channel, jboolean enable) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->lightChannel(channel, (bool)enable);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetSkinningBuffer(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jlong nativeSkinningBuffer, jint count, jint offset) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
SkinningBuffer *sb = (SkinningBuffer *) nativeSkinningBuffer;
|
||||
rm->setSkinningBuffer(i, sb, count, offset);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetBonesAsMatrices(JNIEnv* env, jclass,
|
||||
@@ -339,21 +370,13 @@ Java_com_google_android_filament_RenderableManager_nSetMaterialInstanceAt(JNIEnv
|
||||
materialInstance);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nGetMaterialInstanceAt(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
return (long) rm->getMaterialInstanceAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nGetMaterialAt(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
MaterialInstance *mi = rm->getMaterialInstanceAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
|
||||
return (long) mi->getMaterial();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetGeometryAt__JIIIJJII(JNIEnv*,
|
||||
jclass, jlong nativeRenderableManager, jint i, jint primitiveIndex, jint primitiveType,
|
||||
@@ -390,3 +413,17 @@ Java_com_google_android_filament_RenderableManager_nGetEnabledAttributesAt(JNIEn
|
||||
AttributeBitset enabled = rm->getEnabledAttributesAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
|
||||
return enabled.getValue();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint channel, jboolean enable) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
rm->setLightChannel((RenderableManager::Instance) i, channel, (bool)enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nGetLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint channel) {
|
||||
RenderableManager const *rm = (RenderableManager const *) nativeRenderableManager;
|
||||
return rm->getLightChannel((RenderableManager::Instance) i, channel);
|
||||
}
|
||||
|
||||
116
android/filament-android/src/main/cpp/SkinningBuffer.cpp
Normal file
116
android/filament-android/src/main/cpp/SkinningBuffer.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <functional>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <filament/SkinningBuffer.h>
|
||||
|
||||
#include "common/CallbackUtils.h"
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace backend;
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_SkinningBuffer_nCreateBuilder(JNIEnv*, jclass) {
|
||||
return (jlong) new SkinningBuffer::Builder();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SkinningBuffer_nDestroyBuilder(JNIEnv*, jclass,
|
||||
jlong nativeBuilder) {
|
||||
SkinningBuffer::Builder* builder = (SkinningBuffer::Builder *) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SkinningBuffer_nBuilderBoneCount(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint boneCount) {
|
||||
SkinningBuffer::Builder* builder = (SkinningBuffer::Builder *) nativeBuilder;
|
||||
builder->boneCount((uint32_t)boneCount);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SkinningBuffer_nBuilderInitialize(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean initialize) {
|
||||
SkinningBuffer::Builder* builder = (SkinningBuffer::Builder *) nativeBuilder;
|
||||
builder->initialize((bool)initialize);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_SkinningBuffer_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
SkinningBuffer::Builder* builder = (SkinningBuffer::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return (jlong) builder->build(*engine);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_SkinningBuffer_nSetBonesAsMatrices(JNIEnv* env, jclass,
|
||||
jlong nativeSkinningBuffer, jlong nativeEngine, jobject matrices, jint remaining, jint boneCount,
|
||||
jint offset) {
|
||||
SkinningBuffer *skinningBuffer = (SkinningBuffer *) nativeSkinningBuffer;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
AutoBuffer nioBuffer(env, matrices, boneCount * 16);
|
||||
void* data = nioBuffer.getData();
|
||||
size_t sizeInBytes = nioBuffer.getSize();
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
skinningBuffer->setBones(*engine,
|
||||
static_cast<filament::math::mat4f const *>(data), (size_t)boneCount, (size_t)offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_SkinningBuffer_nSetBonesAsQuaternions(JNIEnv* env, jclass,
|
||||
jlong nativeSkinningBuffer, jlong nativeEngine, jobject quaternions, jint remaining,
|
||||
jint boneCount, jint offset) {
|
||||
SkinningBuffer *skinningBuffer = (SkinningBuffer *) nativeSkinningBuffer;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
AutoBuffer nioBuffer(env, quaternions, boneCount * 8);
|
||||
void* data = nioBuffer.getData();
|
||||
size_t sizeInBytes = nioBuffer.getSize();
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
skinningBuffer->setBones(*engine,
|
||||
static_cast<RenderableManager::Bone const *>(data), (size_t)boneCount, (size_t)offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_SkinningBuffer_nGetBoneCount(JNIEnv*, jclass,
|
||||
jlong nativeSkinningBuffer) {
|
||||
SkinningBuffer *skinningBuffer = (SkinningBuffer *) nativeSkinningBuffer;
|
||||
return (jint)skinningBuffer->getBoneCount();
|
||||
}
|
||||
@@ -102,7 +102,10 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nBuilderStream(JNIEnv*, jclass,
|
||||
jlong nativeStreamBuilder, jlong externalTextureId) {
|
||||
StreamBuilder* builder = (StreamBuilder*) nativeStreamBuilder;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
builder->builder()->stream(externalTextureId);
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
||||
@@ -129,6 +129,13 @@ Java_com_google_android_filament_Texture_nBuilderSwizzle(JNIEnv *, jclass ,
|
||||
(Texture::Swizzle)r, (Texture::Swizzle)g, (Texture::Swizzle)b, (Texture::Swizzle)a);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderImportTexture(JNIEnv*, jclass, jlong nativeBuilder, jlong id) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
builder->import((intptr_t)id);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
|
||||
109
android/filament-android/src/main/cpp/ToneMapper.cpp
Normal file
109
android/filament-android/src/main/cpp/ToneMapper.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/ToneMapper.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nDestroyToneMapper(JNIEnv *env, jclass clazz,
|
||||
jlong toneMapper_) {
|
||||
ToneMapper* toneMapper = (ToneMapper*) toneMapper_;
|
||||
delete toneMapper;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateLinearToneMapper(JNIEnv*, jclass) {
|
||||
return (jlong) new LinearToneMapper();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateACESToneMapper(JNIEnv*, jclass) {
|
||||
return (jlong) new ACESToneMapper();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateACESLegacyToneMapper(JNIEnv*, jclass) {
|
||||
return (jlong) new ACESLegacyToneMapper();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateFilmicToneMapper(JNIEnv*, jclass) {
|
||||
return (jlong) new FilmicToneMapper();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateGenericToneMapper(JNIEnv*, jclass,
|
||||
jfloat contrast, jfloat shoulder, jfloat midGrayIn, jfloat midGrayOut, jfloat hdrMax) {
|
||||
return (jlong) new GenericToneMapper(contrast, shoulder, midGrayIn, midGrayOut, hdrMax);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetContrast(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getContrast();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetShoulder(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getShoulder();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayIn(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getMidGrayIn();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayOut(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getMidGrayOut();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetHdrMax(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getHdrMax();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetContrast(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat contrast) {
|
||||
((GenericToneMapper*) nativeObject)->setContrast(contrast);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetShoulder(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat shoulder) {
|
||||
((GenericToneMapper*) nativeObject)->setShoulder(shoulder);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayIn(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat midGrayIn) {
|
||||
((GenericToneMapper*) nativeObject)->setMidGrayIn(midGrayIn);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayOut(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat midGrayOut) {
|
||||
((GenericToneMapper*) nativeObject)->setMidGrayOut(midGrayOut);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetHdrMax(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat hdrMax) {
|
||||
((GenericToneMapper*) nativeObject)->setHdrMax(hdrMax);
|
||||
}
|
||||
@@ -70,6 +70,23 @@ Java_com_google_android_filament_TransformManager_nCreateArray(JNIEnv* env,
|
||||
return tm->getInstance(entity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nCreateArrayFp64(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint entity_, jint parent,
|
||||
jdoubleArray localTransform_) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
|
||||
if (localTransform_) {
|
||||
jdouble *localTransform = env->GetDoubleArrayElements(localTransform_, NULL);
|
||||
tm->create(entity, (TransformManager::Instance) parent,
|
||||
*reinterpret_cast<const filament::math::mat4 *>(localTransform));
|
||||
env->ReleaseDoubleArrayElements(localTransform_, localTransform, JNI_ABORT);
|
||||
} else {
|
||||
tm->create(entity, (TransformManager::Instance) parent);
|
||||
}
|
||||
return tm->getInstance(entity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nDestroy(JNIEnv*, jclass,
|
||||
jlong nativeTransformManager, jint entity_) {
|
||||
@@ -104,6 +121,17 @@ Java_com_google_android_filament_TransformManager_nSetTransform(JNIEnv* env,
|
||||
env->ReleaseFloatArrayElements(localTransform_, localTransform, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nSetTransformFp64(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
jdoubleArray localTransform_) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
jdouble *localTransform = env->GetDoubleArrayElements(localTransform_, NULL);
|
||||
tm->setTransform((TransformManager::Instance) i,
|
||||
*reinterpret_cast<const filament::math::mat4 *>(localTransform));
|
||||
env->ReleaseDoubleArrayElements(localTransform_, localTransform, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nGetTransform(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
@@ -115,6 +143,17 @@ Java_com_google_android_filament_TransformManager_nGetTransform(JNIEnv* env,
|
||||
env->ReleaseFloatArrayElements(outLocalTransform_, outLocalTransform, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nGetTransformFp64(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
jdoubleArray outLocalTransform_) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
jdouble *outLocalTransform = env->GetDoubleArrayElements(outLocalTransform_, NULL);
|
||||
*reinterpret_cast<filament::math::mat4 *>(outLocalTransform) = tm->getTransformAccurate(
|
||||
(TransformManager::Instance) i);
|
||||
env->ReleaseDoubleArrayElements(outLocalTransform_, outLocalTransform, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nGetWorldTransform(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
@@ -126,6 +165,17 @@ Java_com_google_android_filament_TransformManager_nGetWorldTransform(JNIEnv* env
|
||||
env->ReleaseFloatArrayElements(outWorldTransform_, outWorldTransform, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nGetWorldTransformFp64(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
jdoubleArray outWorldTransform_) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
jdouble *outWorldTransform = env->GetDoubleArrayElements(outWorldTransform_, NULL);
|
||||
*reinterpret_cast<filament::math::mat4 *>(outWorldTransform) = tm->getWorldTransformAccurate(
|
||||
(TransformManager::Instance) i);
|
||||
env->ReleaseDoubleArrayElements(outWorldTransform_, outWorldTransform, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nOpenLocalTransformTransaction(
|
||||
JNIEnv*, jclass, jlong nativeTransformManager) {
|
||||
@@ -139,3 +189,19 @@ Java_com_google_android_filament_TransformManager_nCommitLocalTransformTransacti
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
tm->commitLocalTransformTransaction();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nSetAccurateTranslationsEnabled(JNIEnv*,
|
||||
jclass, jlong nativeTransformManager, jboolean enable) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
tm->setAccurateTranslationsEnabled((bool)enable);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nIsAccurateTranslationsEnabled(JNIEnv*,
|
||||
jclass, jlong nativeTransformManager) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
return (jboolean)tm->isAccurateTranslationsEnabled();
|
||||
}
|
||||
|
||||
@@ -130,43 +130,3 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferObjectAt(JNIEnv *env, jc
|
||||
BufferObject *bufferObject = (BufferObject *) nativeBufferObject;
|
||||
vertexBuffer->setBufferObjectAt(*engine, (uint8_t) bufferIndex, bufferObject);
|
||||
}
|
||||
|
||||
extern "C" [[deprecated]] JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nPopulateTangentQuaternions(JNIEnv *env,
|
||||
jclass type, jint quatType, jint quatCount, jobject outBuffer, jint outRemaining,
|
||||
jint outStride, jobject normals, jint normalsRemaining, jint normalsStride,
|
||||
jobject tangents, jint tangentsRemaining, jint tangentsStride) {
|
||||
|
||||
AutoBuffer outNioBuffer(env, outBuffer, outRemaining, true);
|
||||
void* outData = outNioBuffer.getData();
|
||||
|
||||
AutoBuffer normalsNioBuffer(env, normals, normalsRemaining);
|
||||
auto normalsData = (const float3*) normalsNioBuffer.getData();
|
||||
|
||||
if (tangents) {
|
||||
AutoBuffer tangentsNioBuffer(env, tangents, tangentsRemaining);
|
||||
auto tangentsData = (const float4*) tangentsNioBuffer.getData();
|
||||
VertexBuffer::populateTangentQuaternions({
|
||||
.quatType = (VertexBuffer::QuatType) quatType,
|
||||
.quatCount = (size_t) quatCount,
|
||||
.outBuffer = outData,
|
||||
.outStride = (size_t) outStride,
|
||||
.normals = normalsData,
|
||||
.normalsStride = (size_t) normalsStride,
|
||||
.tangents = tangentsData,
|
||||
.tangentsStride = (size_t) tangentsStride
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
VertexBuffer::populateTangentQuaternions({
|
||||
.quatType = (VertexBuffer::QuatType) quatType,
|
||||
.quatCount = (size_t) quatCount,
|
||||
.outBuffer = outData,
|
||||
.outStride = (size_t) outStride,
|
||||
.normals = normalsData,
|
||||
.normalsStride = (size_t) normalsStride,
|
||||
.tangents = nullptr,
|
||||
.tangentsStride = 0
|
||||
});
|
||||
}
|
||||
|
||||
@@ -138,10 +138,15 @@ Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nati
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetVsmShadowOptions(JNIEnv*, jclass, jlong nativeView,
|
||||
jint anisotropy) {
|
||||
jint anisotropy, jboolean mipmapping, jfloat exponent, jfloat minVarianceScale,
|
||||
jfloat lightBleedReduction) {
|
||||
View* view = (View*) nativeView;
|
||||
View::VsmShadowOptions options;
|
||||
options.anisotropy = (uint8_t) anisotropy;
|
||||
options.anisotropy = (uint8_t)anisotropy;
|
||||
options.mipmapping = (bool)mipmapping;
|
||||
options.exponent = exponent;
|
||||
options.minVarianceScale = minVarianceScale;
|
||||
options.lightBleedReduction = lightBleedReduction;
|
||||
view->setVsmShadowOptions(options);
|
||||
}
|
||||
|
||||
@@ -211,7 +216,9 @@ Java_com_google_android_filament_View_nGetAmbientOcclusion(JNIEnv*, jclass, jlon
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity,
|
||||
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jfloat minHorizonAngleRad) {
|
||||
jfloat bilateralThreshold,
|
||||
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jboolean bentNormals,
|
||||
jfloat minHorizonAngleRad) {
|
||||
View* view = (View*) nativeView;
|
||||
View::AmbientOcclusionOptions options = view->getAmbientOcclusionOptions();
|
||||
options.radius = radius;
|
||||
@@ -219,10 +226,12 @@ Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclas
|
||||
options.bias = bias;
|
||||
options.resolution = resolution;
|
||||
options.intensity = intensity;
|
||||
options.bilateralThreshold = bilateralThreshold;
|
||||
options.quality = (View::QualityLevel)quality;
|
||||
options.lowPassFilter = (View::QualityLevel)lowPassFilter;
|
||||
options.upsampling = (View::QualityLevel)upsampling;
|
||||
options.enabled = (bool)enabled;
|
||||
options.bentNormals = (bool)bentNormals;
|
||||
options.minHorizonAngleRad = minHorizonAngleRad;
|
||||
view->setAmbientOcclusionOptions(options);
|
||||
}
|
||||
@@ -253,7 +262,10 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jlong nativeTexture,
|
||||
jfloat dirtStrength, jfloat strength, jint resolution, jfloat anamorphism, jint levels,
|
||||
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight) {
|
||||
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight,
|
||||
jboolean lensFlare, jboolean starburst, jfloat chromaticAberration, jint ghostCount,
|
||||
jfloat ghostSpacing, jfloat ghostThreshold, jfloat haloThickness, jfloat haloRadius,
|
||||
jfloat haloThreshold) {
|
||||
View* view = (View*) nativeView;
|
||||
Texture* dirt = (Texture*) nativeTexture;
|
||||
View::BloomOptions options = {
|
||||
@@ -266,7 +278,16 @@ Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
.blendMode = (View::BloomOptions::BlendMode)blendMode,
|
||||
.threshold = (bool)threshold,
|
||||
.enabled = (bool)enabled,
|
||||
.highlight = highlight
|
||||
.highlight = highlight,
|
||||
.lensFlare = (bool)lensFlare,
|
||||
.starburst = (bool)starburst,
|
||||
.chromaticAberration = chromaticAberration,
|
||||
.ghostCount = (uint8_t)ghostCount,
|
||||
.ghostSpacing = ghostSpacing,
|
||||
.ghostThreshold = ghostThreshold,
|
||||
.haloThickness = haloThickness,
|
||||
.haloRadius = haloRadius,
|
||||
.haloThreshold = haloThreshold
|
||||
};
|
||||
view->setBloomOptions(options);
|
||||
}
|
||||
@@ -309,7 +330,7 @@ Java_com_google_android_filament_View_nSetDepthOfFieldOptions(JNIEnv *, jclass ,
|
||||
// View::DepthOfFieldOptions::Filter::MEDIAN value is actually 2
|
||||
eFilter = View::DepthOfFieldOptions::Filter::MEDIAN;
|
||||
}
|
||||
view->setDepthOfFieldOptions({.focusDistance = focusDistance, .cocScale = cocScale,
|
||||
view->setDepthOfFieldOptions({.cocScale = cocScale,
|
||||
.maxApertureDiameter = maxApertureDiameter, .enabled = (bool)enabled, .filter = eFilter,
|
||||
.nativeResolution = (bool)nativeResolution,
|
||||
.foregroundRingCount = (uint8_t)foregroundRingCount,
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <jawt.h>
|
||||
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<darwin/jawt_md.h>)
|
||||
#include <darwin/jawt_md.h>
|
||||
#else
|
||||
#include <jawt_md.h>
|
||||
#endif
|
||||
#else
|
||||
#include <darwin/jawt_md.h>
|
||||
#endif
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include "JAWTUtils.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma ide diagnostic ignored "NotReleasedValue"
|
||||
extern "C" {
|
||||
void *getNativeWindow(JNIEnv *env, jclass klass, jobject surface) {
|
||||
void *win = nullptr;
|
||||
JAWT_DrawingSurface *ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo *dsi = nullptr;
|
||||
|
||||
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
|
||||
return win;
|
||||
}
|
||||
NSObject<JAWT_SurfaceLayers>* jawldsip = (NSObject<JAWT_SurfaceLayers>*)dsi->platformInfo;
|
||||
// Use jawt_DrawingSurfaceInfo.bounds for frame dimension.
|
||||
NSView *view = [[NSView alloc] initWithFrame:
|
||||
NSMakeRect(dsi->bounds.x, dsi->bounds.y, dsi->bounds.width, dsi->bounds.height)];
|
||||
view.wantsLayer = true;
|
||||
[jawldsip setLayer:view.layer];
|
||||
|
||||
win = (void*) view;
|
||||
releaseDrawingSurface(ds, dsi);
|
||||
return win;
|
||||
}
|
||||
|
||||
jlong createNativeSurface(jint width, jint height) {
|
||||
NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, width, height)];
|
||||
view.wantsLayer = true;
|
||||
return (jlong) view;
|
||||
}
|
||||
|
||||
void destroyNativeSurface(jlong surface) {
|
||||
NSView *view = reinterpret_cast<NSView*>(surface);
|
||||
[view release];
|
||||
}
|
||||
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "JAWTUtils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
static std::vector<int> jawtVersions = {
|
||||
0x00010003,
|
||||
0x00010004,
|
||||
0x00010007,
|
||||
0x00010009,
|
||||
};
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wuninitialized"
|
||||
bool acquireDrawingSurface(JNIEnv* env, jobject surface,
|
||||
JAWT_DrawingSurface** ods, JAWT_DrawingSurfaceInfo** odsi) {
|
||||
|
||||
JAWT awt;
|
||||
JAWT_DrawingSurface* ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo* dsi = nullptr;
|
||||
|
||||
// Search for a valid AWT
|
||||
jboolean foundJawt = JNI_FALSE;
|
||||
for (int jawtVersion : jawtVersions) {
|
||||
awt.version = jawtVersion;
|
||||
#if defined(__APPLE__) && defined(__aarch64__)
|
||||
// FIXME: enable Apple Silicon build. The problem here is that we attempt to link an x86 jdk and that fails
|
||||
// so JAWT_GetAWT doesn't exist at link time.
|
||||
#warning "FIXME: JAWT_GetAWT() not supported"
|
||||
foundJawt = {};
|
||||
#else
|
||||
foundJawt = JAWT_GetAWT(env, &awt);
|
||||
#endif
|
||||
if (foundJawt == JNI_TRUE) {
|
||||
#ifndef NDEBUG
|
||||
printf("Found valid AWT v%08x.\n", jawtVersion);
|
||||
#endif
|
||||
break;
|
||||
} else {
|
||||
#ifndef NDEBUG
|
||||
printf("AWT v%08x not present.\n", jawtVersion);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
if (foundJawt == JNI_FALSE) {
|
||||
printf("AWT Not found\n");
|
||||
fflush(stdout);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the drawing surface
|
||||
ds = awt.GetDrawingSurface(env, surface);
|
||||
if (ds == nullptr) {
|
||||
#ifndef NDEBUG
|
||||
printf("NULL drawing surface\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lock the drawing
|
||||
jint lock = ds->Lock(ds);
|
||||
if ((lock & JAWT_LOCK_ERROR) != 0) {
|
||||
#ifndef NDEBUG
|
||||
printf("Error locking surface\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
awt.FreeDrawingSurface(ds);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the drawing surface info
|
||||
dsi = ds->GetDrawingSurfaceInfo(ds);
|
||||
if (dsi == nullptr) {
|
||||
#ifndef NDEBUG
|
||||
printf("Error getting surface info\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
ds->Unlock(ds);
|
||||
awt.FreeDrawingSurface(ds);
|
||||
return false;
|
||||
}
|
||||
|
||||
*odsi = dsi;
|
||||
*ods = ds;
|
||||
|
||||
return true;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
void releaseDrawingSurface(JAWT_DrawingSurface* ds, JAWT_DrawingSurfaceInfo* dsi) {
|
||||
// Free the drawing surface info
|
||||
ds->FreeDrawingSurfaceInfo(dsi);
|
||||
// Unlock the drawing surface
|
||||
ds->Unlock(ds);
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jawt.h>
|
||||
|
||||
extern "C" {
|
||||
bool acquireDrawingSurface(JNIEnv* env, jobject surface, JAWT_DrawingSurface** ods,
|
||||
JAWT_DrawingSurfaceInfo** odsi);
|
||||
void releaseDrawingSurface(JAWT_DrawingSurface* ds, JAWT_DrawingSurfaceInfo* dsi);
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <jawt.h>
|
||||
#include <linux/jawt_md.h>
|
||||
|
||||
#include "JAWTUtils.h"
|
||||
#include<GL/glx.h>
|
||||
|
||||
extern "C" {
|
||||
void *getNativeWindow(JNIEnv* env, jclass, jobject surface) {
|
||||
void* win = nullptr;
|
||||
JAWT_DrawingSurface* ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo* dsi = nullptr;
|
||||
|
||||
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
|
||||
return win;
|
||||
}
|
||||
JAWT_X11DrawingSurfaceInfo* dsi_x11 = (JAWT_X11DrawingSurfaceInfo*) dsi->platformInfo;
|
||||
|
||||
win = (void*) dsi_x11->drawable;
|
||||
releaseDrawingSurface(ds, dsi);
|
||||
return win;
|
||||
}
|
||||
|
||||
jlong createNativeSurface(jint width, jint height) {
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
int screen = DefaultScreen(display);
|
||||
Window window = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
int major, minor;
|
||||
glXQueryVersion(display, &major, &minor);
|
||||
printf("Using GLX v%d.%d\n", major, minor); fflush(stdout);
|
||||
#endif
|
||||
|
||||
static int visualAttributess[] = {
|
||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DOUBLEBUFFER, True,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 24,
|
||||
None
|
||||
};
|
||||
int numConfigs = 0;
|
||||
GLXFBConfig* configs = glXChooseFBConfig( display, screen, visualAttributess, &numConfigs);
|
||||
if (numConfigs == 0) {
|
||||
printf("Unable to find a suitable Framebuffer Configuration.\n"); fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pbufferAttributes[] = {
|
||||
GLX_PBUFFER_WIDTH, width,
|
||||
GLX_PBUFFER_HEIGHT, height,
|
||||
None
|
||||
};
|
||||
window = glXCreatePbuffer( display, configs[0], pbufferAttributes );
|
||||
XFree(configs);
|
||||
// Make sure pbuffer creation has not been buffered in the event queue (we need it NOW).
|
||||
XFlush(display);
|
||||
|
||||
// Camouflage the pbuffer as a window which are both XID anyway.
|
||||
return (jlong) window;
|
||||
}
|
||||
|
||||
void destroyNativeSurface(jlong surface) {
|
||||
const char* displayName = nullptr;
|
||||
Display* display = XOpenDisplay(displayName);
|
||||
GLXPbuffer pBuffer = (GLXPbuffer)surface;
|
||||
glXDestroyPbuffer(display, pBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <jawt.h>
|
||||
#include <win32/jawt_md.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <utils/unwindows.h>
|
||||
|
||||
#include "JAWTUtils.h"
|
||||
#include <filament/Engine.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
void* getNativeWindow(JNIEnv* env, jclass, jobject surface) {
|
||||
JAWT_DrawingSurface* ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo* dsi = nullptr;
|
||||
|
||||
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JAWT_Win32DrawingSurfaceInfo* dsi_win32 = (JAWT_Win32DrawingSurfaceInfo*) dsi->platformInfo;
|
||||
HWND hWnd = dsi_win32->hwnd;
|
||||
|
||||
releaseDrawingSurface(ds, dsi);
|
||||
|
||||
return (void*) hWnd;
|
||||
}
|
||||
|
||||
|
||||
jlong createNativeSurface(jint width, jint height) {
|
||||
// We need to adjust the window size so the "client area" matches width and height requested.
|
||||
// Otherwise, the window itself will be of dimension width-height but the "client area" and the
|
||||
// resulting surface will be smaller than requested.
|
||||
RECT dimension = {0, 0, width, height};
|
||||
AdjustWindowRect(&dimension, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
width = dimension.right - dimension.left;
|
||||
height = dimension.bottom - dimension.top;
|
||||
|
||||
HWND window = CreateWindowA("STATIC", "dummy", 0, 0, 0, width, height, NULL, NULL, NULL, NULL);
|
||||
SetWindowLong(window, GWL_STYLE, 0); //remove all window styles
|
||||
|
||||
return (jlong) window;
|
||||
}
|
||||
|
||||
void destroyNativeSurface(jlong surface) {
|
||||
HWND window = (HWND) surface;
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,12 +63,27 @@ final class Asserts {
|
||||
return out;
|
||||
}
|
||||
|
||||
@NonNull @Size(min = 16)
|
||||
static double[] assertMat4(@Nullable double[] out) {
|
||||
if (out == null) out = new double[16];
|
||||
else if (out.length < 16) {
|
||||
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void assertMat4fIn(@NonNull @Size(min = 16) float[] in) {
|
||||
if (in.length < 16) {
|
||||
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
|
||||
}
|
||||
}
|
||||
|
||||
static void assertMat4In(@NonNull @Size(min = 16) double[] in) {
|
||||
if (in.length < 16) {
|
||||
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull @Size(min = 3)
|
||||
static float[] assertFloat3(@Nullable float[] out) {
|
||||
if (out == null) out = new float[3];
|
||||
|
||||
@@ -29,7 +29,7 @@ import androidx.annotation.Size;
|
||||
*
|
||||
* In Filament, Camera is a component that must be associated with an entity. To do so,
|
||||
* use {@link Engine#createCamera(int)}. A Camera component is destroyed using
|
||||
* {@link Engine#destroyCamera(Camera)}.
|
||||
* {@link Engine#destroyCameraComponent(int Entity)} ()}.
|
||||
*
|
||||
* <pre>
|
||||
* Camera myCamera = engine.createCamera(myCameraEntity);
|
||||
@@ -37,7 +37,7 @@ import androidx.annotation.Size;
|
||||
* myCamera.lookAt(0, 1.60, 1,
|
||||
* 0, 0, 0,
|
||||
* 0, 1, 0);
|
||||
* engine.destroyCamera(myCamera);
|
||||
* engine.destroyCameraComponent(myCameraEntity);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
@@ -121,6 +121,9 @@ import androidx.annotation.Size;
|
||||
public class Camera {
|
||||
private long mNativeObject;
|
||||
|
||||
@Entity
|
||||
private final int mEntity;
|
||||
|
||||
/**
|
||||
* Denotes the projection type used by this camera.
|
||||
* @see #setProjection
|
||||
@@ -143,8 +146,9 @@ public class Camera {
|
||||
HORIZONTAL
|
||||
}
|
||||
|
||||
Camera(long nativeCamera) {
|
||||
Camera(long nativeCamera, @Entity int entity) {
|
||||
mNativeObject = nativeCamera;
|
||||
mEntity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,6 +254,9 @@ public class Camera {
|
||||
/**
|
||||
* Sets a custom projection matrix.
|
||||
*
|
||||
* <p>The projection matrix must define an NDC system that must match the OpenGL convention,
|
||||
* that is all 3 axis are mapped to [-1, 1].</p>
|
||||
*
|
||||
* @param inProjection custom projection matrix for rendering and culling
|
||||
*
|
||||
* @param near distance in world units from the camera to the near plane.
|
||||
@@ -275,6 +282,9 @@ public class Camera {
|
||||
/**
|
||||
* Sets a custom projection matrix.
|
||||
*
|
||||
* <p>The projection matrices must define an NDC system that must match the OpenGL convention,
|
||||
* that is all 3 axis are mapped to [-1, 1].</p>
|
||||
*
|
||||
* @param inProjection custom projection matrix for rendering.
|
||||
*
|
||||
* @param inProjectionForCulling custom projection matrix for culling.
|
||||
@@ -409,6 +419,20 @@ public class Camera {
|
||||
nSetModelMatrix(getNativeObject(), viewMatrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera's view matrix.
|
||||
* <p>
|
||||
* Helper method to set the camera's entity transform component.
|
||||
* Remember that the Camera "looks" towards its -z axis.
|
||||
* <p>
|
||||
*
|
||||
* @param viewMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
|
||||
*/
|
||||
public void setModelMatrix(@NonNull @Size(min = 16) double[] viewMatrix) {
|
||||
Asserts.assertMat4In(viewMatrix);
|
||||
nSetModelMatrixFp64(getNativeObject(), viewMatrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera's view matrix.
|
||||
*
|
||||
@@ -506,6 +530,22 @@ public class Camera {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the camera's model matrix. The model matrix encodes the camera position and
|
||||
* orientation, or pose.
|
||||
*
|
||||
* @param out A 16-double array where the model matrix will be stored, or null in which
|
||||
* case a new array is allocated.
|
||||
*
|
||||
* @return A 16-double array containing the camera's pose as a column-major matrix.
|
||||
*/
|
||||
@NonNull @Size(min = 16)
|
||||
public double[] getModelMatrix(@Nullable @Size(min = 16) double[] out) {
|
||||
out = Asserts.assertMat4(out);
|
||||
nGetModelMatrixFp64(getNativeObject(), out);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the camera's view matrix. The view matrix is the inverse of the model matrix.
|
||||
*
|
||||
@@ -521,6 +561,21 @@ public class Camera {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the camera's view matrix. The view matrix is the inverse of the model matrix.
|
||||
*
|
||||
* @param out A 16-double array where the model view will be stored, or null in which
|
||||
* case a new array is allocated.
|
||||
*
|
||||
* @return A 16-double array containing the camera's view as a column-major matrix.
|
||||
*/
|
||||
@NonNull @Size(min = 16)
|
||||
public double[] getViewMatrix(@Nullable @Size(min = 16) double[] out) {
|
||||
out = Asserts.assertMat4(out);
|
||||
nGetViewMatrixFp64(getNativeObject(), out);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the camera position in world space.
|
||||
*
|
||||
@@ -681,6 +736,15 @@ public class Camera {
|
||||
return nGetSensitivity(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entity representing this Camera
|
||||
* @return the entity this Camera component is attached to
|
||||
*/
|
||||
@Entity
|
||||
public int getEntity() {
|
||||
return mEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to compute the effective focal length taking into account the focus distance
|
||||
*
|
||||
@@ -721,6 +785,7 @@ public class Camera {
|
||||
private static native void nSetScaling(long nativeCamera, double x, double y);
|
||||
private static native void nSetShift(long nativeCamera, double x, double y);
|
||||
private static native void nSetModelMatrix(long nativeCamera, float[] in);
|
||||
private static native void nSetModelMatrixFp64(long nativeCamera, double[] in);
|
||||
private static native void nLookAt(long nativeCamera, double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
|
||||
private static native float nGetNear(long nativeCamera);
|
||||
private static native float nGetCullingFar(long nativeCamera);
|
||||
@@ -728,7 +793,9 @@ public class Camera {
|
||||
private static native void nGetCullingProjectionMatrix(long nativeCamera, double[] out);
|
||||
private static native void nGetScaling(long nativeCamera, double[] out);
|
||||
private static native void nGetModelMatrix(long nativeCamera, float[] out);
|
||||
private static native void nGetModelMatrixFp64(long nativeCamera, double[] out);
|
||||
private static native void nGetViewMatrix(long nativeCamera, float[] out);
|
||||
private static native void nGetViewMatrixFp64(long nativeCamera, double[] out);
|
||||
private static native void nGetPosition(long nativeCamera, float[] out);
|
||||
private static native void nGetLeftVector(long nativeCamera, float[] out);
|
||||
private static native void nGetUpVector(long nativeCamera, float[] out);
|
||||
|
||||
@@ -54,6 +54,7 @@ import static com.google.android.filament.Asserts.assertFloat4In;
|
||||
*
|
||||
* The various transforms held by ColorGrading are applied in the following order:
|
||||
* <ul>
|
||||
* <li>Exposure</li>
|
||||
* <li>White balance</li>
|
||||
* <li>Channel mixer</li>
|
||||
* <li>Shadows/mid-tones/highlights</li>
|
||||
@@ -63,12 +64,14 @@ import static com.google.android.filament.Asserts.assertFloat4In;
|
||||
* <li>Saturation</li>
|
||||
* <li>Curves</li>
|
||||
* <li>Tone mapping</li>
|
||||
* <li>Luminance scaling</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h1>Defaults</h1>
|
||||
*
|
||||
* Here are the default color grading options:
|
||||
* <ul>
|
||||
* <li>Exposure: 0.0</li>
|
||||
* <li>White balance: temperature <code>0.0</code>, and tint <code>0.0</code></li>
|
||||
* <li>Channel mixer: red <code>{1,0,0}</code>, green <code>{0,1,0}</code>, blue <code>{0,0,1}</code></li>
|
||||
* <li>Shadows/mid-tones/highlights: shadows <code>{1,1,1,0}</code>, mid-tones <code>{1,1,1,0}</code>,
|
||||
@@ -78,11 +81,12 @@ import static com.google.android.filament.Asserts.assertFloat4In;
|
||||
* <li>Vibrance: <code>1.0</code></li>
|
||||
* <li>Saturation: <code>1.0</code></li>
|
||||
* <li>Curves: gamma <code>{1,1,1}</code>, midPoint <code>{1,1,1}</code>, and scale <code>{1,1,1}</code></li>
|
||||
* <li>Tone mapping: {@link ToneMapping#ACES_LEGACY}</li>
|
||||
* <li>Tone mapping: {@link ToneMapper.ACESLegacy}</li>
|
||||
* <li>Luminance scaling: false</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see View
|
||||
* @see ToneMapping
|
||||
* @see ToneMapper
|
||||
*/
|
||||
public class ColorGrading {
|
||||
long mNativeObject;
|
||||
@@ -99,6 +103,8 @@ public class ColorGrading {
|
||||
|
||||
/**
|
||||
* List of available tone-mapping operators.
|
||||
*
|
||||
* @deprecated Use {@link ColorGrading.Builder#toneMapper(ToneMapper)}
|
||||
*/
|
||||
public enum ToneMapping {
|
||||
/** Linear tone mapping (i.e. no tone mapping). */
|
||||
@@ -109,10 +115,6 @@ public class ColorGrading {
|
||||
ACES,
|
||||
/** Filmic tone mapping, modelled after ACES but applied in sRGB space. */
|
||||
FILMIC,
|
||||
/** Exposure value invariant luminance scaling tone mapping, offers the best behaviors in high intensity areas. */
|
||||
EVILS,
|
||||
/** Reinhard luma-based tone mapping. */
|
||||
REINHARD,
|
||||
/** Tone mapping used to validate/debug scene exposure. */
|
||||
DISPLAY_RANGE,
|
||||
}
|
||||
@@ -156,6 +158,25 @@ public class ColorGrading {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the tone mapping operator to apply to the HDR color buffer as the last
|
||||
* operation of the color grading post-processing step.
|
||||
*
|
||||
* The default tone mapping operator is {@link ToneMapper.ACESLegacy}.
|
||||
*
|
||||
* The specified tone mapper must have a lifecycle that exceeds the lifetime of
|
||||
* this builder. Since the build(Engine&) method is synchronous, it is safe to
|
||||
* delete the tone mapper object after that finishes executing.
|
||||
*
|
||||
* @param toneMapper The tone mapping operator to apply to the HDR color buffer
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder toneMapper(ToneMapper toneMapper) {
|
||||
nBuilderToneMapper(mNativeBuilder, toneMapper.getNativeObject());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the tone mapping operator to apply to the HDR color buffer as the last
|
||||
* operation of the color grading post-processing step.
|
||||
@@ -165,12 +186,49 @@ public class ColorGrading {
|
||||
* @param toneMapping The tone mapping operator to apply to the HDR color buffer
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*
|
||||
* @deprecated Use {@link #toneMapper(ToneMapper)}
|
||||
*/
|
||||
public Builder toneMapping(ToneMapping toneMapping) {
|
||||
nBuilderToneMapping(mNativeBuilder, toneMapping.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables the luminance scaling component (LICH) from the exposure value
|
||||
* invariant luminance system (EVILS). When this setting is enabled, pixels with high
|
||||
* chromatic values will roll-off to white to offer a more natural rendering. This step
|
||||
* also helps avoid undesirable hue skews caused by out of gamut colors clipped
|
||||
* to the destination color gamut.
|
||||
*
|
||||
* When luminance scaling is enabled, tone mapping is performed on the luminance of each
|
||||
* pixel instead of per-channel.
|
||||
*
|
||||
* @param luminanceScaling Enables or disables EVILS post-tone mapping
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder luminanceScaling(boolean luminanceScaling) {
|
||||
nBuilderLuminanceScaling(mNativeBuilder, luminanceScaling);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the exposure of this image. The exposure is specified in stops:
|
||||
* each stop brightens (positive values) or darkens (negative values) the image by
|
||||
* a factor of 2. This means that an exposure of 3 will brighten the image 8 times
|
||||
* more than an exposure of 0 (2^3 = 8 and 2^0 = 1). Contrary to the camera's exposure,
|
||||
* this setting is applied after all post-processing (bloom, etc.) are applied.
|
||||
*
|
||||
* @param exposure Value in EV stops. Can be negative, 0, or positive.
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder exposure(float exposure) {
|
||||
nBuilderExposure(mNativeBuilder, exposure);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the while balance of the image. This can be used to remove color casts
|
||||
* and correct the appearance of the white point in the scene, or to alter the
|
||||
@@ -463,7 +521,10 @@ public class ColorGrading {
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
|
||||
private static native void nBuilderQuality(long nativeBuilder, int quality);
|
||||
private static native void nBuilderToneMapping(long nativeBuilder, int toneMapper);
|
||||
private static native void nBuilderToneMapper(long nativeBuilder, long toneMapper);
|
||||
private static native void nBuilderToneMapping(long nativeBuilder, int toneMapping);
|
||||
private static native void nBuilderLuminanceScaling(long nativeBuilder, boolean luminanceScaling);
|
||||
private static native void nBuilderExposure(long nativeBuilder, float exposure);
|
||||
private static native void nBuilderWhiteBalance(long nativeBuilder, float temperature, float tint);
|
||||
private static native void nBuilderChannelMixer(long nativeBuilder, float[] outRed, float[] outGreen, float[] outBlue);
|
||||
private static native void nBuilderShadowsMidtonesHighlights(long nativeBuilder, float[] shadows, float[] midtones, float[] highlights, float[] ranges);
|
||||
|
||||
@@ -399,19 +399,6 @@ public class Engine {
|
||||
|
||||
// Camera
|
||||
|
||||
/**
|
||||
* Creates a new <code>entity</code> and adds a {@link Camera} component to it.
|
||||
*
|
||||
* @return A newly created {@link Camera}
|
||||
* @exception IllegalStateException can be thrown if the {@link Camera} couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public Camera createCamera() {
|
||||
long nativeCamera = nCreateCamera(getNativeObject());
|
||||
if (nativeCamera == 0) throw new IllegalStateException("Couldn't create Camera");
|
||||
return new Camera(nativeCamera);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and adds a {@link Camera} component to a given <code>entity</code>.
|
||||
*
|
||||
@@ -421,9 +408,9 @@ public class Engine {
|
||||
*/
|
||||
@NonNull
|
||||
public Camera createCamera(@Entity int entity) {
|
||||
long nativeCamera = nCreateCameraWithEntity(getNativeObject(), entity);
|
||||
long nativeCamera = nCreateCamera(getNativeObject(), entity);
|
||||
if (nativeCamera == 0) throw new IllegalStateException("Couldn't create Camera");
|
||||
return new Camera(nativeCamera);
|
||||
return new Camera(nativeCamera, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -437,16 +424,16 @@ public class Engine {
|
||||
public Camera getCameraComponent(@Entity int entity) {
|
||||
long nativeCamera = nGetCameraComponent(getNativeObject(), entity);
|
||||
if (nativeCamera == 0) return null;
|
||||
return new Camera(nativeCamera);
|
||||
return new Camera(nativeCamera, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link Camera} component and frees all its associated resources.
|
||||
* @param camera the {@link Camera} to destroy
|
||||
* Destroys the {@link Camera} component associated with the given entity.
|
||||
*
|
||||
* @param entity an entity
|
||||
*/
|
||||
public void destroyCamera(@NonNull Camera camera) {
|
||||
nDestroyCamera(getNativeObject(), camera.getNativeObject());
|
||||
camera.clearNativeObject();
|
||||
public void destroyCameraComponent(@Entity int entity) {
|
||||
nDestroyCameraComponent(getNativeObject(), entity);
|
||||
}
|
||||
|
||||
// Scene
|
||||
@@ -634,6 +621,14 @@ public class Engine {
|
||||
return mRenderableManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link EntityManager} used by this {@link Engine}
|
||||
*/
|
||||
@NonNull
|
||||
public EntityManager getEntityManager() {
|
||||
return mEntityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks the hardware thread (e.g.: the OpenGL, Vulkan or Metal thread) and blocks until
|
||||
* all commands to this point are executed. Note that this doesn't guarantee that the
|
||||
@@ -685,10 +680,9 @@ public class Engine {
|
||||
private static native boolean nDestroyView(long nativeEngine, long nativeView);
|
||||
private static native long nCreateRenderer(long nativeEngine);
|
||||
private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer);
|
||||
private static native long nCreateCamera(long nativeEngine);
|
||||
private static native long nCreateCameraWithEntity(long nativeEngine, int entity);
|
||||
private static native long nCreateCamera(long nativeEngine, int entity);
|
||||
private static native long nGetCameraComponent(long nativeEngine, int entity);
|
||||
private static native void nDestroyCamera(long nativeEngine, long nativeCamera);
|
||||
private static native void nDestroyCameraComponent(long nativeEngine, int entity);
|
||||
private static native long nCreateScene(long nativeEngine);
|
||||
private static native boolean nDestroyScene(long nativeEngine, long nativeScene);
|
||||
private static native long nCreateFence(long nativeEngine);
|
||||
|
||||
@@ -84,11 +84,7 @@ import androidx.annotation.Size;
|
||||
public class IndirectLight {
|
||||
long mNativeObject;
|
||||
|
||||
public IndirectLight(Engine engine, long indirectLight) {
|
||||
mNativeObject = indirectLight;
|
||||
}
|
||||
|
||||
IndirectLight(long indirectLight) {
|
||||
public IndirectLight(long indirectLight) {
|
||||
mNativeObject = indirectLight;
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ public class LightManager {
|
||||
* Control the quality / performance of the shadow map associated to this light
|
||||
*/
|
||||
public static class ShadowOptions {
|
||||
/** Size of the shadow map in texels. Must be a power-of-two. */
|
||||
/** Size of the shadow map in texels. Must be a power-of-two and larger or equal to 8. */
|
||||
public int mapSize = 1024;
|
||||
|
||||
/**
|
||||
@@ -242,15 +242,17 @@ public class LightManager {
|
||||
|
||||
/** Constant bias in world units (e.g. meters) by which shadows are moved away from the
|
||||
* light. 1mm by default.
|
||||
* This is ignored when the View's ShadowType is set to VSM.
|
||||
*/
|
||||
public float constantBias = 0.05f;
|
||||
|
||||
/** Amount by which the maximum sampling error is scaled. The resulting value is used
|
||||
* to move the shadow away from the fragment normal. Should be 1.0.
|
||||
* This is ignored when the View's ShadowType is set to VSM.
|
||||
*/
|
||||
public float normalBias = 0.4f;
|
||||
|
||||
/** Distance from the camera after which shadows are clipped. this is used to clip
|
||||
/** Distance from the camera after which shadows are clipped. This is used to clip
|
||||
* shadows that are too far and wouldn't contribute to the scene much, improving
|
||||
* performance and quality. This value is always positive.
|
||||
* Use 0.0f to use the camera far distance.
|
||||
@@ -324,6 +326,12 @@ public class LightManager {
|
||||
*/
|
||||
@IntRange(from = 1)
|
||||
public int vsmMsaaSamples = 1;
|
||||
|
||||
/**
|
||||
* Blur width for the VSM blur. Zero do disable.
|
||||
* The maximum value is 125.
|
||||
*/
|
||||
public float blurWidth = 0.0f;
|
||||
}
|
||||
|
||||
public static class ShadowCascades {
|
||||
@@ -422,6 +430,18 @@ public class LightManager {
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a light channel. Light channel 0 is enabled by default.
|
||||
*
|
||||
* @param channel Light channel to enable or disable, between 0 and 7.
|
||||
* @param enable Whether to enable or disable the light channel.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder lightChannel(@IntRange(from = 0, to = 7) int channel, boolean enable) {
|
||||
nBuilderLightChannel(mNativeBuilder, channel, enable);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this Light casts shadows (disabled by default)
|
||||
*
|
||||
@@ -452,7 +472,8 @@ public class LightManager {
|
||||
options.mapSize, options.shadowCascades, options.cascadeSplitPositions,
|
||||
options.constantBias, options.normalBias, options.shadowFar, options.shadowNearHint,
|
||||
options.shadowFarHint, options.stable, options.screenSpaceContactShadows,
|
||||
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples);
|
||||
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples,
|
||||
options.blurWidth);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -776,6 +797,30 @@ public class LightManager {
|
||||
return type == Type.SPOT || type == Type.FOCUSED_SPOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a light channel.
|
||||
* Light channel 0 is enabled by default.
|
||||
*
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param channel Light channel to set
|
||||
* @param enable true to enable, false to disable
|
||||
*
|
||||
* @see Builder#lightChannel
|
||||
*/
|
||||
public void setLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel, boolean enable) {
|
||||
nSetLightChannel(mNativeObject, i, channel, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a light channel is enabled on a specified renderable.
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param channel Light channel to query
|
||||
* @return true if the light channel is enabled, false otherwise
|
||||
*/
|
||||
public boolean getLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel) {
|
||||
return nGetLightChannel(mNativeObject, i, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically updates the light's position.
|
||||
*
|
||||
@@ -1065,6 +1110,14 @@ public class LightManager {
|
||||
return nIsShadowCaster(mNativeObject, i);
|
||||
}
|
||||
|
||||
public float getOuterConeAngle(@EntityInstance int i) {
|
||||
return nGetOuterConeAngle(mNativeObject, i);
|
||||
}
|
||||
|
||||
public float getInnerConeAngle(@EntityInstance int i) {
|
||||
return nGetInnerConeAngle(mNativeObject, i);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
return mNativeObject;
|
||||
}
|
||||
@@ -1078,7 +1131,7 @@ public class LightManager {
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
private static native boolean nBuilderBuild(long nativeBuilder, long nativeEngine, int entity);
|
||||
private static native void nBuilderCastShadows(long nativeBuilder, boolean enable);
|
||||
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples);
|
||||
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples, float blurWidth);
|
||||
private static native void nBuilderCastLight(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderPosition(long nativeBuilder, float x, float y, float z);
|
||||
private static native void nBuilderDirection(long nativeBuilder, float x, float y, float z);
|
||||
@@ -1091,6 +1144,7 @@ public class LightManager {
|
||||
private static native void nBuilderAngularRadius(long nativeBuilder, float angularRadius);
|
||||
private static native void nBuilderHaloSize(long nativeBuilder, float haloSize);
|
||||
private static native void nBuilderHaloFalloff(long nativeBuilder, float haloFalloff);
|
||||
private static native void nBuilderLightChannel(long nativeBuilder, int channel, boolean enable);
|
||||
|
||||
private static native void nComputeUniformSplits(float[] splitPositions, int cascades);
|
||||
private static native void nComputeLogSplits(float[] splitPositions, int cascades, float near, float far);
|
||||
@@ -1118,4 +1172,8 @@ public class LightManager {
|
||||
private static native float nGetSunHaloFalloff(long nativeLightManager, int i);
|
||||
private static native void nSetShadowCaster(long nativeLightManager, int i, boolean shadowCaster);
|
||||
private static native boolean nIsShadowCaster(long nativeLightManager, int i);
|
||||
private static native float nGetOuterConeAngle(long nativeLightManager, int i);
|
||||
private static native float nGetInnerConeAngle(long nativeLightManager, int i);
|
||||
private static native void nSetLightChannel(long nativeLightManager, int i, int channel, boolean enable);
|
||||
private static native boolean nGetLightChannel(long nativeLightManager, int i, int channel);
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ public class Material {
|
||||
}
|
||||
}
|
||||
|
||||
Material(long nativeMaterial) {
|
||||
public Material(long nativeMaterial) {
|
||||
mNativeObject = nativeMaterial;
|
||||
long nativeDefaultInstance = nGetDefaultInstance(nativeMaterial);
|
||||
mDefaultInstance = new MaterialInstance(this, nativeDefaultInstance);
|
||||
|
||||
@@ -64,6 +64,22 @@ public class MaterialInstance {
|
||||
mNativeMaterial = nGetMaterial(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link #MaterialInstance} using another {@link #MaterialInstance} as a template for initialization.
|
||||
* The new {@link #MaterialInstance} is an instance of the same {@link Material} of the template instance and
|
||||
* must be destroyed just like any other {@link #MaterialInstance}.
|
||||
*
|
||||
* @param other A {@link #MaterialInstance} to use as a template for initializing a new instance
|
||||
* @param name A name for the new {@link #MaterialInstance} or nullptr to use the template's name
|
||||
* @return A new {@link #MaterialInstance}
|
||||
*/
|
||||
@NonNull
|
||||
public static MaterialInstance duplicate(@NonNull MaterialInstance other, String name) {
|
||||
long nativeInstance = nDuplicate(other.mNativeObject, name);
|
||||
if (nativeInstance == 0) throw new IllegalStateException("Couldn't duplicate MaterialInstance");
|
||||
return new MaterialInstance(other.mMaterial, nativeInstance);
|
||||
}
|
||||
|
||||
/** @return the {@link Material} associated with this instance */
|
||||
@NonNull
|
||||
public Material getMaterial() {
|
||||
@@ -539,4 +555,6 @@ public class MaterialInstance {
|
||||
|
||||
private static native String nGetName(long nativeMaterialInstance);
|
||||
private static native long nGetMaterial(long nativeMaterialInstance);
|
||||
|
||||
private static native long nDuplicate(long otherNativeMaterialInstance, String name);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import androidx.annotation.Nullable;
|
||||
*/
|
||||
public class RenderTarget {
|
||||
private long mNativeObject;
|
||||
private static final int ATTACHMENT_COUNT = 5;
|
||||
private static final int ATTACHMENT_COUNT = AttachmentPoint.values().length;
|
||||
private final Texture[] mTextures = new Texture[ATTACHMENT_COUNT];
|
||||
|
||||
private RenderTarget(long nativeRenderTarget, Builder builder) {
|
||||
@@ -55,6 +55,10 @@ public class RenderTarget {
|
||||
COLOR1,
|
||||
COLOR2,
|
||||
COLOR3,
|
||||
COLOR4,
|
||||
COLOR5,
|
||||
COLOR6,
|
||||
COLOR7,
|
||||
DEPTH
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ public class RenderableManager {
|
||||
* @param count the number of primitives that will be supplied to the builder
|
||||
*
|
||||
* Note that builders typically do not have a long lifetime since clients should discard
|
||||
* them after calling build(). For a usage example, see {@link RenderableManager}.
|
||||
* them after calling {@link #build}. For a usage example, see {@link RenderableManager}.
|
||||
*/
|
||||
public Builder(@IntRange(from = 1) int count) {
|
||||
mNativeBuilder = nCreateBuilder(count);
|
||||
@@ -128,7 +128,7 @@ public class RenderableManager {
|
||||
* <code>geometry()</code> and <code>material()</code>.
|
||||
*
|
||||
* @param index zero-based index of the primitive, must be less than the count passed to Builder constructor
|
||||
* @param type specifies the topology of the primitive (e.g., PrimitiveType.TRIANGLES)
|
||||
* @param type specifies the topology of the primitive (e.g., {@link PrimitiveType#TRIANGLES})
|
||||
* @param vertices specifies the vertex buffer, which in turn specifies a set of attributes
|
||||
* @param indices specifies the index buffer (either u16 or u32)
|
||||
* @param offset specifies where in the index buffer to start reading (expressed as a number of indices)
|
||||
@@ -147,7 +147,7 @@ public class RenderableManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* For details, see the {@link RenderableManager.Builder#geometry primary overload}.
|
||||
* For details, see the {@link RenderableManager.Builder#geometry} primary overload.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder geometry(@IntRange(from = 0) int index, @NonNull PrimitiveType type,
|
||||
@@ -159,7 +159,7 @@ public class RenderableManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* For details, see the {@link RenderableManager.Builder#geometry primary overload}.
|
||||
* For details, see the {@link RenderableManager.Builder#geometry} primary overload.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder geometry(@IntRange(from = 0) int index, @NonNull PrimitiveType type,
|
||||
@@ -266,6 +266,18 @@ public class RenderableManager {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a light channel. Light channel 0 is enabled by default.
|
||||
*
|
||||
* @param channel Light channel to enable or disable, between 0 and 7.
|
||||
* @param enable Whether to enable or disable the light channel.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder lightChannel(@IntRange(from = 0, to = 7) int channel, boolean enable) {
|
||||
nBuilderLightChannel(mNativeBuilder, channel, enable);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls if this renderable casts shadows, false by default.
|
||||
*
|
||||
@@ -303,6 +315,50 @@ public class RenderableManager {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows bones to be swapped out and shared using SkinningBuffer.
|
||||
*
|
||||
* If skinning buffer mode is enabled, clients must call #setSkinningBuffer() rather than
|
||||
* #setBonesAsQuaternions(). This allows sharing of data between renderables.
|
||||
*
|
||||
* @param enabled If true, enables buffer object mode. False by default.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder enableSkinningBuffers(boolean enabled) {
|
||||
nEnableSkinningBuffers(mNativeBuilder, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables GPU vertex skinning for up to 255 bones, 0 by default.
|
||||
*
|
||||
*<p>Skinning Buffer mode must be enabled.</p>
|
||||
*
|
||||
*<p>Each vertex can be affected by up to 4 bones simultaneously. The attached
|
||||
* VertexBuffer must provide data in the BONE_INDICES slot (uvec4) and the
|
||||
* BONE_WEIGHTS slot (float4).</p>
|
||||
*
|
||||
*<p>See also {@link #setSkinningBuffer}, {@link SkinningBuffer#setBonesAsMatrices}
|
||||
* or {@link SkinningBuffer#setBonesAsQuaternions},
|
||||
* which can be called on a per-frame basis to advance the animation.</p>
|
||||
*
|
||||
* @see #setSkinningBuffer
|
||||
* @see SkinningBuffer#setBonesAsMatrices
|
||||
* @see SkinningBuffer#setBonesAsQuaternions
|
||||
*
|
||||
* @param skinningBuffer null to disable, otherwise the {@link SkinningBuffer} to use
|
||||
* @param boneCount 0 to disable, otherwise the number of bone transforms (up to 255)
|
||||
* @param offset offset in the {@link SkinningBuffer}
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder skinning(SkinningBuffer skinningBuffer,
|
||||
@IntRange(from = 0, to = 255) int boneCount, int offset) {
|
||||
nBuilderSkinningBuffer(mNativeBuilder,
|
||||
skinningBuffer != null ? skinningBuffer.getNativeObject() : 0, boneCount, offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder skinning(@IntRange(from = 0, to = 255) int boneCount) {
|
||||
nBuilderSkinning(mNativeBuilder, boneCount);
|
||||
@@ -312,6 +368,8 @@ public class RenderableManager {
|
||||
/**
|
||||
* Enables GPU vertex skinning for up to 255 bones, 0 by default.
|
||||
*
|
||||
* <p>Skinning Buffer mode must be disabled.</p>
|
||||
*
|
||||
* <p>Each vertex can be affected by up to 4 bones simultaneously. The attached
|
||||
* VertexBuffer must provide data in the <code>BONE_INDICES</code> slot (uvec4) and the
|
||||
* <code>BONE_WEIGHTS</code> slot (float4).</p>
|
||||
@@ -319,6 +377,8 @@ public class RenderableManager {
|
||||
* <p>See also {@link RenderableManager#setBonesAsMatrices}, which can be called on a per-frame basis
|
||||
* to advance the animation.</p>
|
||||
*
|
||||
* @see SkinningBuffer#setBonesAsMatrices
|
||||
*
|
||||
* @param boneCount Number of bones associated with this component
|
||||
* @param bones A FloatBuffer containing boneCount transforms. Each transform consists of 8 float.
|
||||
* float 0 to 3 encode a unit quaternion w+ix+jy+kz stored as x,y,z,w.
|
||||
@@ -379,9 +439,22 @@ public class RenderableManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Associates a {@link SkinningBuffer} to a renderable instance
|
||||
* @param i Instance of the Renderable
|
||||
* @param skinningBuffer {@link SkinningBuffer} to use
|
||||
* @param count Numbers of bones to set
|
||||
* @param offset Offset in the {@link SkinningBuffer}
|
||||
*/
|
||||
public void setSkinningBuffer(@EntityInstance int i, @NonNull SkinningBuffer skinningBuffer,
|
||||
int count, int offset) {
|
||||
nSetSkinningBuffer(mNativeObject, i, skinningBuffer.getNativeObject(), count, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the transforms associated with each bone of a Renderable.
|
||||
*
|
||||
*
|
||||
* @param i Instance of the Renderable
|
||||
* @param matrices A FloatBuffer containing boneCount 4x4 packed matrices (i.e. 16 floats each matrix and no gap between matrices)
|
||||
* @param boneCount Number of bones to set
|
||||
@@ -470,6 +543,30 @@ public class RenderableManager {
|
||||
nSetCulling(mNativeObject, i, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a light channel.
|
||||
* Light channel 0 is enabled by default.
|
||||
*
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param channel Light channel to set
|
||||
* @param enable true to enable, false to disable
|
||||
*
|
||||
* @see Builder#lightChannel
|
||||
*/
|
||||
public void setLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel, boolean enable) {
|
||||
nSetLightChannel(mNativeObject, i, channel, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a light channel is enabled on a specified renderable.
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param channel Light channel to query
|
||||
* @return true if the light channel is enabled, false otherwise
|
||||
*/
|
||||
public boolean getLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel) {
|
||||
return nGetLightChannel(mNativeObject, i, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes whether or not the renderable casts shadows.
|
||||
*
|
||||
@@ -654,8 +751,12 @@ public class RenderableManager {
|
||||
private static native void nBuilderScreenSpaceContactShadows(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderSkinning(long nativeBuilder, int boneCount);
|
||||
private static native int nBuilderSkinningBones(long nativeBuilder, int boneCount, Buffer bones, int remaining);
|
||||
private static native void nBuilderSkinningBuffer(long nativeBuilder, long nativeSkinningBuffer, int boneCount, int offset);
|
||||
private static native void nBuilderMorphing(long nativeBuilder, boolean enabled);
|
||||
private static native void nEnableSkinningBuffers(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderLightChannel(long nativeRenderableManager, int channel, boolean enable);
|
||||
|
||||
private static native void nSetSkinningBuffer(long nativeObject, int i, long nativeSkinningBuffer, int count, int offset);
|
||||
private static native int nSetBonesAsMatrices(long nativeObject, int i, Buffer matrices, int remaining, int boneCount, int offset);
|
||||
private static native int nSetBonesAsQuaternions(long nativeObject, int i, Buffer quaternions, int remaining, int boneCount, int offset);
|
||||
private static native void nSetMorphWeights(long nativeObject, int instance, float[] weights);
|
||||
@@ -663,6 +764,8 @@ public class RenderableManager {
|
||||
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
|
||||
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
|
||||
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
|
||||
private static native void nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
|
||||
private static native boolean nGetLightChannel(long nativeRenderableManager, int i, int channel);
|
||||
private static native void nSetCastShadows(long nativeRenderableManager, int i, boolean enabled);
|
||||
private static native void nSetReceiveShadows(long nativeRenderableManager, int i, boolean enabled);
|
||||
private static native void nSetScreenSpaceContactShadows(long nativeRenderableManager, int i, boolean enabled);
|
||||
@@ -672,7 +775,6 @@ public class RenderableManager {
|
||||
private static native int nGetPrimitiveCount(long nativeRenderableManager, int i);
|
||||
private static native void nSetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex, long nativeMaterialInstance);
|
||||
private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
|
||||
private static native long nGetMaterialAt(long nativeRenderableManager, int i, int primitiveIndex);
|
||||
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count);
|
||||
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, int offset, int count);
|
||||
private static native void nSetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex, int blendOrder);
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
public class SkinningBuffer {
|
||||
private long mNativeObject;
|
||||
private SkinningBuffer(long nativeSkinningBuffer) {
|
||||
mNativeObject = nativeSkinningBuffer;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
// Keep to finalize native resources
|
||||
private final SkinningBuffer.Builder.BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new SkinningBuffer.Builder.BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the skinning buffer in bones.
|
||||
*
|
||||
* <p>Due to limitation in the GLSL, the SkinningBuffer must always by a multiple of
|
||||
* 256, this adjustment is done automatically, but can cause
|
||||
* some memory overhead. This memory overhead can be mitigated by using the same
|
||||
* {@link SkinningBuffer} to store the bone information for multiple RenderPrimitives.</p>
|
||||
*
|
||||
* @param boneCount Number of bones the skinning buffer can hold.
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder boneCount(@IntRange(from = 1) int boneCount) {
|
||||
nBuilderBoneCount(mNativeBuilder, boneCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The new buffer is created with identity bones
|
||||
*
|
||||
* @param initialize true to initializing the buffer, false to not.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder initialize(boolean initialize) {
|
||||
nBuilderInitialize(mNativeBuilder, initialize);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the <code>SkinningBuffer</code> object.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this <code>SkinningBuffer</code>
|
||||
* with.
|
||||
*
|
||||
* @return the newly created <code>SkinningBuffer</code> object
|
||||
*
|
||||
* @exception IllegalStateException if the SkinningBuffer could not be created
|
||||
*
|
||||
* @see #setBonesAsMatrices
|
||||
* @see #setBonesAsQuaternions
|
||||
*/
|
||||
@NonNull
|
||||
public SkinningBuffer build(@NonNull Engine engine) {
|
||||
long nativeSkinningBuffer = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
if (nativeSkinningBuffer == 0)
|
||||
throw new IllegalStateException("Couldn't create SkinningBuffer");
|
||||
return new SkinningBuffer(nativeSkinningBuffer);
|
||||
}
|
||||
|
||||
private static class BuilderFinalizer {
|
||||
private final long mNativeObject;
|
||||
|
||||
BuilderFinalizer(long nativeObject) {
|
||||
mNativeObject = nativeObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroyBuilder(mNativeObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the bone transforms in the range [offset, offset + boneCount).
|
||||
*
|
||||
* @param engine {@link Engine} instance
|
||||
* @param matrices A {@link FloatBuffer} containing boneCount 4x4 packed matrices (i.e. 16 floats each matrix and no gap between matrices)
|
||||
* @param boneCount Number of bones to set
|
||||
* @param offset Index of the first bone to set
|
||||
*/
|
||||
public void setBonesAsMatrices(@NonNull Engine engine,
|
||||
@NonNull Buffer matrices, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
int result = nSetBonesAsMatrices(mNativeObject, engine.getNativeObject(),
|
||||
matrices, matrices.remaining(), boneCount, offset);
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the bone transforms in the range [offset, offset + boneCount).
|
||||
*
|
||||
* @param engine {@link Engine} instance
|
||||
* @param quaternions A {@link FloatBuffer} containing boneCount transforms. Each transform consists of 8 float.
|
||||
* float 0 to 3 encode a unit quaternion <code>w+ix+jy+kz</code> stored as <code>x,y,z,w</code>.
|
||||
* float 4 to 7 encode a translation stored as <code>x,y,z,1</code>.
|
||||
* @param boneCount Number of bones to set
|
||||
* @param offset Index of the first bone to set
|
||||
*/
|
||||
public void setBonesAsQuaternions(@NonNull Engine engine,
|
||||
@NonNull Buffer quaternions, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
int result = nSetBonesAsQuaternions(mNativeObject, engine.getNativeObject(),
|
||||
quaternions, quaternions.remaining(), boneCount, offset);
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of bones in this {@link SkinningBuffer}
|
||||
*/
|
||||
public int getBoneCount() {
|
||||
return nGetBoneCount(mNativeObject);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed IndexBuffer");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
void clearNativeObject() {
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
private static native void nBuilderBoneCount(long nativeBuilder, int boneCount);
|
||||
private static native void nBuilderInitialize(long nativeBuilder, boolean initialize);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||
|
||||
private static native int nSetBonesAsMatrices(long nativeObject, long nativeEngine, Buffer matrices, int remaining, int boneCount, int offset);
|
||||
private static native int nSetBonesAsQuaternions(long nativeObject, long nativeEngine, Buffer quaternions, int remaining, int boneCount, int offset);
|
||||
private static native int nGetBoneCount(long nativeObject);
|
||||
}
|
||||
@@ -51,11 +51,7 @@ import static com.google.android.filament.Colors.LinearColor;
|
||||
public class Skybox {
|
||||
private long mNativeObject;
|
||||
|
||||
public Skybox(Engine engine, long nativeSkybox) {
|
||||
mNativeObject = nativeSkybox;
|
||||
}
|
||||
|
||||
Skybox(long nativeSkybox) {
|
||||
public Skybox(long nativeSkybox) {
|
||||
mNativeObject = nativeSkybox;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,7 +166,9 @@ public class Stream {
|
||||
* <code>GL_TEXTURE_EXTERNAL_OES.</code>
|
||||
* @return This Builder, for chaining calls.
|
||||
* @see Texture#setExternalStream
|
||||
* @deprecated this method existed only for ARCore which doesn't need this anymore, use {@link Texture.Builder#importTexture(long)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public Builder stream(long externalTextureId) {
|
||||
nBuilderStream(mNativeBuilder, externalTextureId);
|
||||
|
||||
@@ -73,11 +73,7 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
|
||||
public class Texture {
|
||||
private long mNativeObject;
|
||||
|
||||
Texture(long nativeTexture) {
|
||||
mNativeObject = nativeTexture;
|
||||
}
|
||||
|
||||
public Texture(Engine engine, long nativeTexture) {
|
||||
public Texture(long nativeTexture) {
|
||||
mNativeObject = nativeTexture;
|
||||
}
|
||||
|
||||
@@ -695,6 +691,26 @@ public class Texture {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a native texture to import as a Filament texture.
|
||||
* <p>
|
||||
* The texture id is backend-specific:
|
||||
* <ul>
|
||||
* <li> OpenGL: GLuint texture ID </li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param id a backend specific texture identifier
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder importTexture(long id) {
|
||||
nBuilderImportTexture(mNativeBuilder, id);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>Texture</code> instance.
|
||||
* @param engine The {@link Engine} to associate this <code>Texture</code> with.
|
||||
@@ -1167,6 +1183,7 @@ public class Texture {
|
||||
private static native void nBuilderFormat(long nativeBuilder, int format);
|
||||
private static native void nBuilderUsage(long nativeBuilder, int flags);
|
||||
private static native void nBuilderSwizzle(long nativeBuilder, int r, int g, int b, int a);
|
||||
private static native void nBuilderImportTexture(long nativeBuilder, long id);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||
|
||||
private static native int nGetWidth(long nativeTexture, int level);
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
package com.google.android.filament;
|
||||
|
||||
/**
|
||||
* Interface for tone mapping operators. A tone mapping operator, or tone mapper,
|
||||
* is responsible for compressing the dynamic range of the rendered scene to a
|
||||
* dynamic range suitable for display.
|
||||
*
|
||||
* In Filament, tone mapping is a color grading step. ToneMapper instances are
|
||||
* created and passed to the ColorGrading::Builder to produce a 3D LUT that will
|
||||
* be used during post-processing to prepare the final color buffer for display.
|
||||
*
|
||||
* Filament provides several default tone mapping operators that fall into three
|
||||
* categories:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Configurable tone mapping operators</li>
|
||||
* <ul>
|
||||
* <li>GenericToneMapper</li>
|
||||
* </ul>
|
||||
* <li>Fixed-aesthetic tone mapping operators</li>
|
||||
* <ul>
|
||||
* <li>ACESToneMapper</li>
|
||||
* <li>ACESLegacyToneMapper</li>
|
||||
* <li>FilmicToneMapper</li>
|
||||
* </ul>
|
||||
* <li>Debug/validation tone mapping operators</li>
|
||||
* <ul>
|
||||
* <li>LinearToneMapper</li>
|
||||
* <li>DisplayRangeToneMapper</li>
|
||||
* </ul>
|
||||
* </ul>
|
||||
*
|
||||
* You can create custom tone mapping operators by subclassing ToneMapper.
|
||||
*/
|
||||
public class ToneMapper {
|
||||
private final long mNativeObject;
|
||||
|
||||
private ToneMapper(long nativeObject) {
|
||||
mNativeObject = nativeObject;
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed ToneMapper");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
super.finalize();
|
||||
} finally {
|
||||
nDestroyToneMapper(mNativeObject);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Linear tone mapping operator that returns the input color but clamped to
|
||||
* the 0..1 range. This operator is mostly useful for debugging.
|
||||
*/
|
||||
public static class Linear extends ToneMapper {
|
||||
public Linear() {
|
||||
super(nCreateLinearToneMapper());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ACES tone mapping operator. This operator is an implementation of the
|
||||
* ACES Reference Rendering Transform (RRT) combined with the Output Device
|
||||
* Transform (ODT) for sRGB monitors (dim surround, 100 nits).
|
||||
*/
|
||||
public static class ACES extends ToneMapper {
|
||||
public ACES() {
|
||||
super(nCreateACESToneMapper());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ACES tone mapping operator, modified to match the perceived brightness
|
||||
* of FilmicToneMapper. This operator is the same as ACESToneMapper but
|
||||
* applies a brightness multiplier of ~1.6 to the input color value to
|
||||
* target brighter viewing environments.
|
||||
*/
|
||||
public static class ACESLegacy extends ToneMapper {
|
||||
public ACESLegacy() {
|
||||
super(nCreateACESLegacyToneMapper());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "Filmic" tone mapping operator. This tone mapper was designed to
|
||||
* approximate the aesthetics of the ACES RRT + ODT for Rec.709
|
||||
* and historically Filament's default tone mapping operator. It exists
|
||||
* only for backward compatibility purposes and is not otherwise recommended.
|
||||
*/
|
||||
public static class Filmic extends ToneMapper {
|
||||
public Filmic() {
|
||||
super(nCreateFilmicToneMapper());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic tone mapping operator that gives control over the tone mapping
|
||||
* curve. This operator can be used to control the aesthetics of the final
|
||||
* image. This operator also allows to control the dynamic range of the
|
||||
* scene referred values.
|
||||
*
|
||||
* The tone mapping curve is defined by 5 parameters:
|
||||
* <ul>
|
||||
* <li>contrast: controls the contrast of the curve</li>
|
||||
* <li>shoulder: controls the shoulder of the curve, i.e. how quickly scene
|
||||
* referred values map to output white</li>
|
||||
* <li>midGrayIn: sets the input middle gray</li>
|
||||
* <li>midGrayOut: sets the output middle gray</li>
|
||||
* <li>hdrMax: defines the maximum input value that will be mapped to
|
||||
* output white</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static class Generic extends ToneMapper {
|
||||
/**
|
||||
* Builds a new generic tone mapper parameterized to closely approximate
|
||||
* the {@link ACESLegacy} tone mapper. The default values are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>contrast = 1.585f</li>
|
||||
* <li>shoulder = 0.5f</li>
|
||||
* <li>midGrayIn = 0.18f</li>
|
||||
* <li>midGrayOut = 0.268f</li>
|
||||
* <li>hdrMax = 10.0f</li>
|
||||
* </ul>
|
||||
*/
|
||||
public Generic() {
|
||||
this(1.585f, 0.5f, 0.18f, 0.268f, 10.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new generic tone mapper.
|
||||
*
|
||||
* @param contrast: controls the contrast of the curve, must be > 0.0, values
|
||||
* in the range 0.5..2.0 are recommended.
|
||||
* @param shoulder: controls the shoulder of the curve, i.e. how quickly scene
|
||||
* referred values map to output white, between 0.0 and 1.0.
|
||||
* @param midGrayIn: sets the input middle gray, between 0.0 and 1.0.
|
||||
* @param midGrayOut: sets the output middle gray, between 0.0 and 1.0.
|
||||
* @param hdrMax: defines the maximum input value that will be mapped to
|
||||
* output white. Must be >= 1.0.
|
||||
*/
|
||||
public Generic(
|
||||
float contrast, float shoulder, float midGrayIn, float midGrayOut, float hdrMax) {
|
||||
super(nCreateGenericToneMapper(contrast, shoulder, midGrayIn, midGrayOut, hdrMax));
|
||||
}
|
||||
|
||||
/** Returns the contrast of the curve as a strictly positive value. */
|
||||
public float getContrast() {
|
||||
return nGenericGetContrast(getNativeObject());
|
||||
}
|
||||
|
||||
/** Sets the contrast of the curve, must be > 0.0, values in the range 0.5..2.0 are recommended. */
|
||||
public void setContrast(float contrast) {
|
||||
nGenericSetContrast(getNativeObject(), contrast);
|
||||
}
|
||||
|
||||
/** Returns how fast scene referred values map to output white as a value between 0.0 and 1.0. */
|
||||
public float getShoulder() {
|
||||
return nGenericGetShoulder(getNativeObject());
|
||||
}
|
||||
|
||||
/** Sets how quickly scene referred values map to output white, between 0.0 and 1.0. */
|
||||
public void setShoulder(float shoulder) {
|
||||
nGenericSetShoulder(getNativeObject(), shoulder);
|
||||
}
|
||||
|
||||
/** Returns the middle gray point for input values as a value between 0.0 and 1.0. */
|
||||
public float getMidGrayIn() {
|
||||
return nGenericGetMidGrayIn(getNativeObject());
|
||||
}
|
||||
|
||||
/** Sets the input middle gray, between 0.0 and 1.0. */
|
||||
public void setMidGrayIn(float midGrayIn) {
|
||||
nGenericSetMidGrayIn(getNativeObject(), midGrayIn);
|
||||
}
|
||||
|
||||
/** Returns the middle gray point for output values as a value between 0.0 and 1.0. */
|
||||
public float getMidGrayOut() {
|
||||
return nGenericGetMidGrayOut(getNativeObject());
|
||||
}
|
||||
|
||||
/** Sets the output middle gray, between 0.0 and 1.0. */
|
||||
public void setMidGrayOut(float midGrayOut) {
|
||||
nGenericSetMidGrayOut(getNativeObject(), midGrayOut);
|
||||
}
|
||||
|
||||
/** Returns the maximum input value that will map to output white, as a value >= 1.0. */
|
||||
public float getHdrMax() {
|
||||
return nGenericGetHdrMax(getNativeObject());
|
||||
}
|
||||
|
||||
/** Defines the maximum input value that will be mapped to output white. Must be >= 1.0. */
|
||||
public void setHdrMax(float hdrMax) {
|
||||
nGenericSetHdrMax(getNativeObject(), hdrMax);
|
||||
}
|
||||
}
|
||||
|
||||
private static native void nDestroyToneMapper(long nativeObject);
|
||||
|
||||
private static native long nCreateLinearToneMapper();
|
||||
private static native long nCreateACESToneMapper();
|
||||
private static native long nCreateACESLegacyToneMapper();
|
||||
private static native long nCreateFilmicToneMapper();
|
||||
private static native long nCreateGenericToneMapper(
|
||||
float contrast, float shoulder, float midGrayIn, float midGrayOut, float hdrMax);
|
||||
|
||||
// Generic tone mappper
|
||||
private static native float nGenericGetContrast(long nativeObject);
|
||||
private static native float nGenericGetShoulder(long nativeObject);
|
||||
private static native float nGenericGetMidGrayIn(long nativeObject);
|
||||
private static native float nGenericGetMidGrayOut(long nativeObject);
|
||||
private static native float nGenericGetHdrMax(long nativeObject);
|
||||
|
||||
private static native void nGenericSetContrast(long nativeObject, float contrast);
|
||||
private static native void nGenericSetShoulder(long nativeObject, float shoulder);
|
||||
private static native void nGenericSetMidGrayIn(long nativeObject, float midGrayIn);
|
||||
private static native void nGenericSetMidGrayOut(long nativeObject, float midGrayOut);
|
||||
private static native void nGenericSetHdrMax(long nativeObject, float hdrMax);
|
||||
}
|
||||
@@ -83,6 +83,35 @@ import androidx.annotation.Size;
|
||||
return nGetInstance(mNativeObject, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disable the accurate translation mode. Disabled by default.
|
||||
*
|
||||
* When accurate translation mode is active, the translation component of all transforms is
|
||||
* maintained at double precision. This is only useful if the mat4 version of setTransform()
|
||||
* is used, as well as getTransformAccurate().
|
||||
*
|
||||
* @param enable true to enable the accurate translation mode, false to disable.
|
||||
*
|
||||
* @see #isAccurateTranslationsEnabled
|
||||
* @see #create(int, int, double[])
|
||||
* @see #setTransform(int, double[])
|
||||
* @see #getTransform(int, double[])
|
||||
* @see #getWorldTransform(int, double[])
|
||||
*/
|
||||
public void setAccurateTranslationsEnabled(boolean enable) {
|
||||
nSetAccurateTranslationsEnabled(mNativeObject, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the high precision translation mode is active.
|
||||
*
|
||||
* @return true if accurate translations mode is active, false otherwise
|
||||
* @see #setAccurateTranslationsEnabled
|
||||
*/
|
||||
public boolean isAccurateTranslationsEnabled() {
|
||||
return nIsAccurateTranslationsEnabled(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a transform component and associates it with the given entity. The component is
|
||||
* initialized with the identity transform.
|
||||
@@ -114,6 +143,23 @@ import androidx.annotation.Size;
|
||||
return nCreateArray(mNativeObject, entity, parent, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a transform component with a parent and associates it with the given entity.
|
||||
* If this component already exists on the given entity, it is first
|
||||
* destroyed as if {@link #destroy} was called.
|
||||
*
|
||||
* @param entity an {@link Entity} to associate a transform component to.
|
||||
* @param parent the {@link EntityInstance} of the parent transform
|
||||
* @param localTransform the transform, relative to the parent, to initialize the transform
|
||||
* component with.
|
||||
* @see #destroy
|
||||
*/
|
||||
@EntityInstance
|
||||
public int create(@Entity int entity, @EntityInstance int parent,
|
||||
@Nullable @Size(min = 16) double[] localTransform) {
|
||||
return nCreateArrayFp64(mNativeObject, entity, parent, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys this component from the given entity, children are orphaned.
|
||||
*
|
||||
@@ -170,6 +216,24 @@ import androidx.annotation.Size;
|
||||
nSetTransform(mNativeObject, i, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a local transform of a transform component.
|
||||
* <p>This operation can be slow if the hierarchy of transform is too deep, and this
|
||||
* will be particularly bad when updating a lot of transforms. In that case,
|
||||
* consider using {@link #openLocalTransformTransaction} / {@link #commitLocalTransformTransaction}.</p>
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to set the local
|
||||
* transform to.
|
||||
* @param localTransform the local transform (i.e. relative to the parent).
|
||||
* @see #getTransform(int, double[])
|
||||
* @see #getWorldTransform(int, double[])
|
||||
*/
|
||||
public void setTransform(@EntityInstance int i,
|
||||
@NonNull @Size(min = 16) double[] localTransform) {
|
||||
Asserts.assertMat4In(localTransform);
|
||||
nSetTransformFp64(mNativeObject, i, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local transform of a transform component.
|
||||
*
|
||||
@@ -190,6 +254,26 @@ import androidx.annotation.Size;
|
||||
return outLocalTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local transform of a transform component.
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to query the
|
||||
* local transform from.
|
||||
* @param outLocalTransform a 16 <code>float</code> array to receive the result.
|
||||
* If <code>null</code> is given, a new suitable array is allocated.
|
||||
* @return the local transform of the component (i.e. relative to the parent). This always
|
||||
* returns the value set by setTransform().
|
||||
* @see #setTransform
|
||||
*/
|
||||
@NonNull
|
||||
@Size(min = 16)
|
||||
public double[] getTransform(@EntityInstance int i,
|
||||
@Nullable @Size(min = 16) double[] outLocalTransform) {
|
||||
outLocalTransform = Asserts.assertMat4(outLocalTransform);
|
||||
nGetTransformFp64(mNativeObject, i, outLocalTransform);
|
||||
return outLocalTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the world transform of a transform component.
|
||||
*
|
||||
@@ -210,6 +294,26 @@ import androidx.annotation.Size;
|
||||
return outWorldTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the world transform of a transform component.
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to query the
|
||||
* world transform from.
|
||||
* @param outWorldTransform a 16 <code>float</code> array to receive the result.
|
||||
* If <code>null</code> is given, a new suitable array is allocated
|
||||
* @return The world transform of the component (i.e. relative to the root). This is the
|
||||
* composition of this component's local transform with its parent's world transform.
|
||||
* @see #setTransform
|
||||
*/
|
||||
@NonNull
|
||||
@Size(min = 16)
|
||||
public double[] getWorldTransform(@EntityInstance int i,
|
||||
@Nullable @Size(min = 16) double[] outWorldTransform) {
|
||||
outWorldTransform = Asserts.assertMat4(outWorldTransform);
|
||||
nGetWorldTransformFp64(mNativeObject, i, outWorldTransform);
|
||||
return outWorldTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a local transform transaction. During a transaction, {@link #getWorldTransform} can
|
||||
* return an invalid transform until {@link #commitLocalTransformTransaction} is called.
|
||||
@@ -252,12 +356,18 @@ import androidx.annotation.Size;
|
||||
private static native int nGetInstance(long nativeTransformManager, int entity);
|
||||
private static native int nCreate(long nativeTransformManager, int entity);
|
||||
private static native int nCreateArray(long mNativeObject, int entity, int parent, float[] localTransform);
|
||||
private static native int nCreateArrayFp64(long mNativeObject, int entity, int parent, double[] localTransform);
|
||||
private static native void nDestroy(long nativeTransformManager, int entity);
|
||||
private static native void nSetParent(long nativeTransformManager, int i, int newParent);
|
||||
private static native int nGetParent(long nativeTransformManager, int i);
|
||||
private static native void nSetTransform(long nativeTransformManager, int i, float[] localTransform);
|
||||
private static native void nSetTransformFp64(long nativeTransformManager, int i, double[] localTransform);
|
||||
private static native void nGetTransform(long nativeTransformManager, int i, float[] outLocalTransform);
|
||||
private static native void nGetTransformFp64(long nativeTransformManager, int i, double[] outLocalTransform);
|
||||
private static native void nGetWorldTransform(long nativeTransformManager, int i, float[] outWorldTransform);
|
||||
private static native void nGetWorldTransformFp64(long nativeTransformManager, int i, double[] outWorldTransform);
|
||||
private static native void nOpenLocalTransformTransaction(long nativeTransformManager);
|
||||
private static native void nCommitLocalTransformTransaction(long nativeTransformManager);
|
||||
private static native void nSetAccurateTranslationsEnabled(long nativeTransformManager, boolean enable);
|
||||
private static native boolean nIsAccurateTranslationsEnabled(long nativeTransformManager);
|
||||
}
|
||||
|
||||
@@ -104,48 +104,6 @@ public class VertexBuffer {
|
||||
HALF3,
|
||||
HALF4,
|
||||
}
|
||||
/**
|
||||
* Specifies the quaternion type for the {@link #populateTangentQuaternions} utility.
|
||||
*/
|
||||
public enum QuatType {
|
||||
/** 2 bytes per component as half-floats (8 bytes per quat) */
|
||||
HALF4,
|
||||
|
||||
/** 2 bytes per component as normalized integers (8 bytes per quat) */
|
||||
SHORT4,
|
||||
|
||||
/** 4 bytes per component as floats (16 bytes per quat) */
|
||||
FLOAT4,
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the parameters for the {@link #populateTangentQuaternions} utility.
|
||||
*/
|
||||
public static class QuatTangentContext {
|
||||
/** desired quaternion type (required) */
|
||||
public QuatType quatType;
|
||||
|
||||
/** number of quaternions (required) */
|
||||
public int quatCount;
|
||||
|
||||
/** pre-allocated output buffer (required) */
|
||||
public Buffer outBuffer;
|
||||
|
||||
/** desired stride in bytes (optional) */
|
||||
public int outStride;
|
||||
|
||||
/** source normals (required) */
|
||||
public Buffer normals;
|
||||
|
||||
/** normals stride in bytes (optional) */
|
||||
public int normalsStride;
|
||||
|
||||
/** source tangents (optional) */
|
||||
public Buffer tangents;
|
||||
|
||||
/** tangents stride in bytes (optional) */
|
||||
public int tangentsStride;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
@@ -429,38 +387,6 @@ public class VertexBuffer {
|
||||
bufferObject.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function that consumes normal vectors (and, optionally, tangent vectors) and
|
||||
* produces quaternions that can be passed into a TANGENTS buffer.
|
||||
*
|
||||
* <p>
|
||||
* The given output buffer must be preallocated with at least quatCount * outStride bytes.
|
||||
* <p>
|
||||
*
|
||||
* <p>
|
||||
* Normals are required but tangents are optional, in which case this function tries to generate
|
||||
* reasonable tangents. The given normals should be unit length.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If supplied, the tangent vectors should be unit length and should be orthogonal to the
|
||||
* normals. The w component of the tangent is a sign (-1 or +1) indicating handedness of the
|
||||
* basis.
|
||||
* </p>
|
||||
*
|
||||
* @deprecated Instead please use SurfaceOrientation since it has additional capabilities and a
|
||||
* builder-style API.
|
||||
*
|
||||
* @param context an initialized QuatTangentContext object
|
||||
*/
|
||||
public static void populateTangentQuaternions(@NonNull QuatTangentContext context) {
|
||||
nPopulateTangentQuaternions(context.quatType.ordinal(), context.quatCount,
|
||||
context.outBuffer, context.outBuffer.remaining(), context.outStride,
|
||||
context.normals, context.normals.remaining(), context.normalsStride,
|
||||
context.tangents, context.tangents != null ? context.tangents.remaining() : 0,
|
||||
context.tangentsStride);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed VertexBuffer");
|
||||
@@ -490,8 +416,4 @@ public class VertexBuffer {
|
||||
|
||||
private static native void nSetBufferObjectAt(long nativeVertexBuffer, long nativeEngine,
|
||||
int bufferIndex, long nativeBufferObject);
|
||||
|
||||
private static native void nPopulateTangentQuaternions(int quatType, int quatCount,
|
||||
Buffer outBuffer, int outRemaining, int outStride, Buffer normals, int normalsRemaining,
|
||||
int normalsStride, Buffer tangents, int tangentsRemaining, int tangentsStride);
|
||||
}
|
||||
|
||||
@@ -169,6 +169,16 @@ public class View {
|
||||
*/
|
||||
public float intensity = 1.0f;
|
||||
|
||||
/**
|
||||
* Depth distance that constitute an edge for filtering. Must be positive.
|
||||
* Default is 5cm.
|
||||
* This must be adjusted with the scene's scale and/or units.
|
||||
* A value too low will result in high frequency noise, while a value too high will
|
||||
* result in the loss of geometry edges. For AO, it is generally better to be too
|
||||
* blurry than not enough.
|
||||
*/
|
||||
public float bilateralThreshold = 0.05f;
|
||||
|
||||
/**
|
||||
* The quality setting controls the number of samples used for evaluating Ambient
|
||||
* occlusion. The default is QualityLevel.LOW which is sufficient for most mobile
|
||||
@@ -198,6 +208,11 @@ public class View {
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
|
||||
/**
|
||||
* enables bent normals computation from AO, and specular AO
|
||||
*/
|
||||
public boolean bentNormals = false;
|
||||
|
||||
/**
|
||||
* Minimal angle to consider in radian. This is used to reduce the creases that can
|
||||
* appear due to insufficiently tessellated geometry.
|
||||
@@ -284,11 +299,11 @@ public class View {
|
||||
*
|
||||
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
|
||||
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
|
||||
* maximum is 12. This value together with resolution influences the spread of the
|
||||
* maximum is 11. This value together with resolution influences the spread of the
|
||||
* blur effect. This value can be silently reduced to accommodate the original
|
||||
* image size.
|
||||
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
|
||||
* the maximum is lower of the original resolution and 4096. This parameter is
|
||||
* resolution: Resolution of bloom's vertical axis. The minimum value is 2^levels and the
|
||||
* the maximum is lower of the original resolution and 2048. This parameter is
|
||||
* silently clamped to the minimum and maximum.
|
||||
* It is highly recommended that this value be smaller than the target resolution
|
||||
* after dynamic resolution is applied (horizontally and vertically).
|
||||
@@ -329,7 +344,7 @@ public class View {
|
||||
public float strength = 0.10f;
|
||||
|
||||
/**
|
||||
* Resolution of minor axis (2^levels to 4096)
|
||||
* Resolution of minor axis (2^levels to 2048)
|
||||
*/
|
||||
public int resolution = 360;
|
||||
|
||||
@@ -339,7 +354,7 @@ public class View {
|
||||
public float anamorphism = 1.0f;
|
||||
|
||||
/**
|
||||
* Number of blur levels (3 to 12)
|
||||
* Number of blur levels (3 to 11)
|
||||
*/
|
||||
public int levels = 6;
|
||||
|
||||
@@ -363,6 +378,52 @@ public class View {
|
||||
* minimum value is 10.0.
|
||||
*/
|
||||
public float highlight = 1000.0f;
|
||||
|
||||
|
||||
/**
|
||||
* enable screen-space lens flare
|
||||
*/
|
||||
public boolean lensFlare = false;
|
||||
|
||||
/**
|
||||
* enable starburst effect on lens flare
|
||||
*/
|
||||
public boolean starburst = true;
|
||||
|
||||
/**
|
||||
* amount of chromatic aberration
|
||||
*/
|
||||
public float chromaticAberration = 0.005f;
|
||||
|
||||
/**
|
||||
* number of flare "ghosts"
|
||||
*/
|
||||
public int ghostCount = 4;
|
||||
|
||||
/**
|
||||
* spacing of the ghost in screen units [0, 1[
|
||||
*/
|
||||
public float ghostSpacing = 0.6f;
|
||||
|
||||
/**
|
||||
* hdr threshold for the ghosts
|
||||
*/
|
||||
public float ghostThreshold = 10.0f;
|
||||
|
||||
/**
|
||||
* thickness of halo in vertical screen units, 0 to disable
|
||||
*/
|
||||
public float haloThickness = 0.1f;
|
||||
|
||||
/**
|
||||
* radius of halo in vertical screen units [0, 0.5]
|
||||
*/
|
||||
public float haloRadius = 0.4f;
|
||||
|
||||
/**
|
||||
* hdr threshold for the halo
|
||||
*/
|
||||
public float haloThreshold = 10.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,14 +497,6 @@ public class View {
|
||||
MEDIAN
|
||||
}
|
||||
|
||||
/**
|
||||
* focus distance in world units
|
||||
*
|
||||
* @deprecated use {@link Camera#setFocusDistance(float)}
|
||||
*/
|
||||
@Deprecated
|
||||
public float focusDistance = 10.0f;
|
||||
|
||||
/**
|
||||
* circle of confusion scale factor (amount of blur)
|
||||
*
|
||||
@@ -649,20 +702,44 @@ public class View {
|
||||
/**
|
||||
* View-level options for VSM shadowing.
|
||||
*
|
||||
* <strong>Warning: This API is still experimental and subject to change.</strong>
|
||||
*
|
||||
* @see View#setVsmShadowOptions
|
||||
*/
|
||||
public static class VsmShadowOptions {
|
||||
/**
|
||||
* Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater
|
||||
* than 0, mipmaps will automatically be generated each frame for all lights.
|
||||
* This implies mipmapping below.
|
||||
*
|
||||
* <p>
|
||||
* The number of anisotropic samples = 2 ^ vsmAnisotropy.
|
||||
* </p>
|
||||
*
|
||||
* <strong>Warning: This API is still experimental and subject to change.</strong>
|
||||
*/
|
||||
public int anisotropy = 0;
|
||||
|
||||
/**
|
||||
* Whether to generate mipmaps for all VSM shadow maps.
|
||||
*/
|
||||
public boolean mipmapping = false;
|
||||
|
||||
/**
|
||||
* EVSM exponent
|
||||
* The maximum value permissible is 5.54 for a shadow map in fp16, or 42.0 for a
|
||||
* shadow map in fp32. Currently the shadow map bit depth is always fp16.
|
||||
*/
|
||||
public float exponent = 5.54f;
|
||||
|
||||
/**
|
||||
* VSM minimum variance scale, must be positive.
|
||||
*/
|
||||
public float minVarianceScale = 1.0f;
|
||||
|
||||
/**
|
||||
* VSM light bleeding reduction amount, between 0 and 1.
|
||||
*/
|
||||
public float lightBleedReduction = 0.2f;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -893,16 +970,6 @@ public class View {
|
||||
nSetShadowingEnabled(getNativeObject(), enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables shadow mapping. Enabled by default.
|
||||
*
|
||||
* @deprecated Use {@link #setShadowingEnabled}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setShadowsEnabled(boolean enabled) {
|
||||
setShadowingEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether shadowing is enabled
|
||||
*/
|
||||
@@ -1280,7 +1347,8 @@ public class View {
|
||||
*/
|
||||
public void setVsmShadowOptions(@NonNull VsmShadowOptions options) {
|
||||
mVsmShadowOptions = options;
|
||||
nSetVsmShadowOptions(getNativeObject(), options.anisotropy);
|
||||
nSetVsmShadowOptions(getNativeObject(), options.anisotropy, options.mipmapping,
|
||||
options.exponent, options.minVarianceScale, options.lightBleedReduction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1325,9 +1393,11 @@ public class View {
|
||||
public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) {
|
||||
mAmbientOcclusionOptions = options;
|
||||
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power,
|
||||
options.resolution, options.intensity, options.quality.ordinal(), options.lowPassFilter.ordinal(), options.upsampling.ordinal(),
|
||||
options.enabled, options.minHorizonAngleRad);
|
||||
nSetSSCTOptions(getNativeObject(), options.ssctLightConeRad, options.ssctStartTraceDistance, options.ssctContactDistanceMax, options.ssctIntensity,
|
||||
options.resolution, options.intensity, options.bilateralThreshold,
|
||||
options.quality.ordinal(), options.lowPassFilter.ordinal(), options.upsampling.ordinal(),
|
||||
options.enabled, options.bentNormals, options.minHorizonAngleRad);
|
||||
nSetSSCTOptions(getNativeObject(), options.ssctLightConeRad, options.ssctStartTraceDistance,
|
||||
options.ssctContactDistanceMax, options.ssctIntensity,
|
||||
options.ssctLightDirection[0], options.ssctLightDirection[1], options.ssctLightDirection[2],
|
||||
options.ssctDepthBias, options.ssctDepthSlopeBias, options.ssctSampleCount,
|
||||
options.ssctRayCount, options.ssctEnabled);
|
||||
@@ -1357,7 +1427,10 @@ public class View {
|
||||
nSetBloomOptions(getNativeObject(), options.dirt != null ? options.dirt.getNativeObject() : 0,
|
||||
options.dirtStrength, options.strength, options.resolution,
|
||||
options.anamorphism, options.levels, options.blendingMode.ordinal(),
|
||||
options.threshold, options.enabled, options.highlight);
|
||||
options.threshold, options.enabled, options.highlight,
|
||||
options.lensFlare, options.starburst, options.chromaticAberration,
|
||||
options.ghostCount, options.ghostSpacing, options.ghostThreshold,
|
||||
options.haloThickness, options.haloRadius, options.haloThreshold);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1442,7 +1515,7 @@ public class View {
|
||||
*/
|
||||
public void setDepthOfFieldOptions(@NonNull DepthOfFieldOptions options) {
|
||||
mDepthOfFieldOptions = options;
|
||||
nSetDepthOfFieldOptions(getNativeObject(), options.focusDistance, options.cocScale,
|
||||
nSetDepthOfFieldOptions(getNativeObject(), options.cocScale,
|
||||
options.maxApertureDiameter, options.enabled, options.filter.ordinal(),
|
||||
options.nativeResolution, options.foregroundRingCount, options.backgroundRingCount,
|
||||
options.fastGatherRingCount, options.maxForegroundCOC, options.maxBackgroundCOC);
|
||||
@@ -1491,7 +1564,7 @@ public class View {
|
||||
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
|
||||
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
|
||||
private static native void nSetShadowType(long nativeView, int type);
|
||||
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy);
|
||||
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy, boolean mipmapping, float exponent, float minVarianceScale, float lightBleedReduction);
|
||||
private static native void nSetColorGrading(long nativeView, long nativeColorGrading);
|
||||
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
|
||||
private static native boolean nIsPostProcessingEnabled(long nativeView);
|
||||
@@ -1499,12 +1572,13 @@ public class View {
|
||||
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
|
||||
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
|
||||
private static native int nGetAmbientOcclusion(long nativeView);
|
||||
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, int quality, int lowPassFilter, int upsampling, boolean enabled, float minHorizonAngleRad);
|
||||
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, float bilateralThreshold, int quality, int lowPassFilter, int upsampling, boolean enabled, boolean bentNormals, float minHorizonAngleRad);
|
||||
private static native void nSetSSCTOptions(long nativeView, float ssctLightConeRad, float ssctStartTraceDistance, float ssctContactDistanceMax, float ssctIntensity, float v, float v1, float v2, float ssctDepthBias, float ssctDepthSlopeBias, int ssctSampleCount, int ssctRayCount, boolean ssctEnabled);
|
||||
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight);
|
||||
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight,
|
||||
boolean lensFlare, boolean starburst, float chromaticAberration, int ghostCount, float ghostSpacing, float ghostThreshold, float haloThickness, float haloRadius, float haloThreshold);
|
||||
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
|
||||
private static native void nSetBlendMode(long nativeView, int blendMode);
|
||||
private static native void nSetDepthOfFieldOptions(long nativeView, float focusDistance, float cocScale, float maxApertureDiameter, boolean enabled, int filter,
|
||||
private static native void nSetDepthOfFieldOptions(long nativeView, float cocScale, float maxApertureDiameter, boolean enabled, int filter,
|
||||
boolean nativeResolution, int foregroundRingCount, int backgroundRingCount, int fastGatherRingCount, int maxForegroundCOC, int maxBackgroundCOC);
|
||||
private static native void nSetVignetteOptions(long nativeView, float midPoint, float roundness, float feather, float r, float g, float b, float a, boolean enabled);
|
||||
private static native void nSetTemporalAntiAliasingOptions(long nativeView, float feedback, float filterWidth, boolean enabled);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(filament-utils-android)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
set(IMAGEIO_DIR ../../libs/imageio)
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../gltfio-android ${CMAKE_CURRENT_BINARY_DIR}/gltfio-android)
|
||||
|
||||
@@ -20,23 +22,37 @@ add_library(civetweb STATIC IMPORTED)
|
||||
set_target_properties(civetweb PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libcivetweb.a)
|
||||
|
||||
include_directories(${FILAMENT_DIR}/include
|
||||
..
|
||||
../../libs/utils/include)
|
||||
add_library(iblprefilter STATIC IMPORTED)
|
||||
set_target_properties(iblprefilter PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament-iblprefilter.a)
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.map")
|
||||
|
||||
add_library(filament-utils-jni SHARED
|
||||
src/main/cpp/AutomationEngine.cpp
|
||||
src/main/cpp/Bookmark.cpp
|
||||
src/main/cpp/HDRLoader.cpp
|
||||
src/main/cpp/IBLPrefilterContext.cpp
|
||||
src/main/cpp/Utils.cpp
|
||||
src/main/cpp/Manipulator.cpp
|
||||
src/main/cpp/RemoteServer.cpp
|
||||
|
||||
${IMAGEIO_DIR}/include/imageio/ImageDecoder.h
|
||||
${IMAGEIO_DIR}/include/imageio/HDRDecoder.h
|
||||
${IMAGEIO_DIR}/src/HDRDecoder.cpp
|
||||
|
||||
../common/CallbackUtils.cpp
|
||||
../common/NioUtils.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(filament-utils-jni PUBLIC IMAGEIO_LITE=1)
|
||||
|
||||
target_include_directories(filament-utils-jni PRIVATE
|
||||
${FILAMENT_DIR}/include
|
||||
..
|
||||
${IMAGEIO_DIR}/include
|
||||
../../libs/utils/include)
|
||||
|
||||
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.symbols)
|
||||
|
||||
@@ -45,6 +61,7 @@ target_link_libraries(filament-utils-jni
|
||||
gltfio-jni
|
||||
civetweb
|
||||
camutils
|
||||
iblprefilter
|
||||
image
|
||||
viewer
|
||||
)
|
||||
|
||||
@@ -84,7 +84,13 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
|
||||
}
|
||||
}
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||
automation->tick((View*) view, ptrMaterials, materialCount, (Renderer*) renderer, deltaTime);
|
||||
AutomationEngine::ViewerContent content = {
|
||||
.view = (View*) view,
|
||||
.renderer = (Renderer*) renderer,
|
||||
.materials = ptrMaterials,
|
||||
.materialCount = (size_t) materialCount,
|
||||
};
|
||||
automation->tick(content, deltaTime);
|
||||
if (longMaterials) {
|
||||
env->ReleaseLongArrayElements(materials, longMaterials, 0);
|
||||
delete[] ptrMaterials;
|
||||
@@ -94,8 +100,9 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nApplySettings(JNIEnv* env, jclass klass,
|
||||
jlong nativeAutomation, jstring json, jlong view, jlongArray materials, jlong nativeIbl,
|
||||
jint lightEntity, jlong nativeLm, jlong scene, jlong renderer) {
|
||||
jint sunlightEntity, jintArray assetLights, jlong nativeLm, jlong scene, jlong renderer) {
|
||||
using MaterialPointer = MaterialInstance*;
|
||||
|
||||
jsize materialCount = 0;
|
||||
jlong* longMaterials = nullptr;
|
||||
MaterialPointer* ptrMaterials = nullptr;
|
||||
@@ -107,17 +114,42 @@ Java_com_google_android_filament_utils_AutomationEngine_nApplySettings(JNIEnv* e
|
||||
ptrMaterials[i] = (MaterialPointer) longMaterials[i];
|
||||
}
|
||||
}
|
||||
|
||||
jsize lightCount = 0;
|
||||
jint* intLights = nullptr;
|
||||
if (assetLights) {
|
||||
lightCount = env->GetArrayLength(assetLights);
|
||||
intLights = env->GetIntArrayElements(assetLights, nullptr);
|
||||
}
|
||||
|
||||
static_assert(sizeof(jint) == sizeof(Entity));
|
||||
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||
const char* nativeJson = env->GetStringUTFChars(json, 0);
|
||||
size_t jsonLength = env->GetStringUTFLength(json);
|
||||
automation->applySettings(nativeJson, jsonLength, (View*) view, ptrMaterials, materialCount,
|
||||
(IndirectLight*) nativeIbl, (Entity&) lightEntity, (LightManager*) nativeLm,
|
||||
(Scene*) scene, (Renderer*) renderer);
|
||||
|
||||
AutomationEngine::ViewerContent content = {
|
||||
.view = (View*) view,
|
||||
.renderer = (Renderer*) renderer,
|
||||
.materials = ptrMaterials,
|
||||
.materialCount = (size_t) materialCount,
|
||||
.lightManager = (LightManager*) nativeLm,
|
||||
.scene = (Scene*) scene,
|
||||
.indirectLight = (IndirectLight*) nativeIbl,
|
||||
.sunlight = (Entity&) sunlightEntity,
|
||||
.assetLights = (Entity*) intLights,
|
||||
.assetLightCount = (size_t) lightCount,
|
||||
};
|
||||
|
||||
automation->applySettings(nativeJson, jsonLength, content);
|
||||
env->ReleaseStringUTFChars(json, nativeJson);
|
||||
if (longMaterials) {
|
||||
env->ReleaseLongArrayElements(materials, longMaterials, 0);
|
||||
delete[] ptrMaterials;
|
||||
}
|
||||
if (intLights) {
|
||||
env->ReleaseIntArrayElements(assetLights, intLights, 0);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -136,6 +168,7 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
|
||||
const jfieldID skyboxEnabled = env->GetFieldID(klass, "skyboxEnabled", "Z");
|
||||
const jfieldID cameraFocalLength = env->GetFieldID(klass, "cameraFocalLength", "F");
|
||||
const jfieldID cameraFocusDistance = env->GetFieldID(klass, "cameraFocusDistance", "F");
|
||||
const jfieldID autoScaleEnabled = env->GetFieldID(klass, "autoScaleEnabled", "Z");
|
||||
|
||||
env->SetFloatField(result, cameraAperture, options.cameraAperture);
|
||||
env->SetFloatField(result, cameraSpeed, options.cameraSpeed);
|
||||
@@ -145,6 +178,7 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
|
||||
env->SetBooleanField(result, skyboxEnabled, options.skyboxEnabled);
|
||||
env->SetFloatField(result, cameraFocalLength, options.cameraFocalLength);
|
||||
env->SetFloatField(result, cameraFocusDistance, options.cameraFocusDistance);
|
||||
env->SetBooleanField(result, autoScaleEnabled, options.autoScaleEnabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
|
||||
91
android/filament-utils-android/src/main/cpp/HDRLoader.cpp
Normal file
91
android/filament-utils-android/src/main/cpp/HDRLoader.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Texture.h>
|
||||
|
||||
#include <imageio/HDRDecoder.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace image;
|
||||
using namespace utils;
|
||||
|
||||
using PixelBufferDescriptor = Texture::PixelBufferDescriptor;
|
||||
|
||||
jlong nCreateHDRTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat) {
|
||||
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
Texture::InternalFormat textureFormat = (Texture::InternalFormat) internalFormat;
|
||||
|
||||
auto dataPtr = (char const*) buffer.getData();
|
||||
const size_t byteCount = buffer.getSize();
|
||||
|
||||
// This creates a copy but it's the easest way to create a memory stream.
|
||||
std::string ins(dataPtr, byteCount);
|
||||
std::istringstream in(ins);
|
||||
|
||||
LinearImage* image = new LinearImage(ImageDecoder::decode(in, "memory.hdr"));
|
||||
|
||||
// This can happen if a decoding error occurs.
|
||||
if (image->getChannels() != 3) {
|
||||
delete image;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Texture* texture = Texture::Builder()
|
||||
.width(image->getWidth())
|
||||
.height(image->getHeight())
|
||||
.levels(0xff)
|
||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
||||
.format(textureFormat)
|
||||
.build(*engine);
|
||||
|
||||
if (texture == nullptr) {
|
||||
slog.e << "Unable to create Filament Texture from HDR image." << io::endl;
|
||||
delete image;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PixelBufferDescriptor::Callback freeCallback = [](void* buf, size_t, void* userdata) {
|
||||
delete (LinearImage*) userdata;
|
||||
};
|
||||
|
||||
PixelBufferDescriptor pbd(
|
||||
(void const* ) image->getPixelRef(),
|
||||
image->getWidth() * image->getHeight() * 3 * sizeof(float),
|
||||
PixelBufferDescriptor::PixelDataFormat::RGB,
|
||||
PixelBufferDescriptor::PixelDataType::FLOAT,
|
||||
freeCallback,
|
||||
image);
|
||||
|
||||
// Note that the setImage call could fail (e.g. due to an invalid combination of internal format
|
||||
// and PixelDataFormat) but there is no way of detecting such a failure.
|
||||
texture->setImage(*engine, 0, std::move(pbd));
|
||||
|
||||
texture->generateMipmaps(*engine);
|
||||
|
||||
return (jlong) texture;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament-iblprefilter/IBLPrefilterContext.h>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Texture.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nCreate(JNIEnv* env, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) new IBLPrefilterContext(*engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nDestroy(JNIEnv*, jclass, jlong native) {
|
||||
IBLPrefilterContext* context = (IBLPrefilterContext*) native;
|
||||
delete context;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nCreateEquirectHelper(JNIEnv* env, jclass, jlong nativeContext) {
|
||||
IBLPrefilterContext* context = (IBLPrefilterContext*) nativeContext;
|
||||
return (long) new IBLPrefilterContext::EquirectangularToCubemap(*context);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nEquirectHelperRun(JNIEnv* env, jclass, jlong nativeHelper, long nativeEquirect) {
|
||||
auto helper = (IBLPrefilterContext::EquirectangularToCubemap*) nativeHelper;
|
||||
auto texture = (filament::Texture*) nativeEquirect;
|
||||
auto result = (*helper)(texture);
|
||||
return (long) result;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nDestroyEquirectHelper(JNIEnv* env, jclass, jlong nativeObject) {
|
||||
delete (IBLPrefilterContext::EquirectangularToCubemap*) nativeObject;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nCreateSpecularFilter(JNIEnv* env, jclass, jlong nativeContext) {
|
||||
IBLPrefilterContext* context = (IBLPrefilterContext*) nativeContext;
|
||||
return (long) new IBLPrefilterContext::SpecularFilter(*context);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nSpecularFilterRun(JNIEnv* env, jclass, jlong nativeHelper, long nativeSkybox) {
|
||||
auto helper = (IBLPrefilterContext::SpecularFilter*) nativeHelper;
|
||||
auto texture = (filament::Texture*) nativeSkybox;
|
||||
auto result = (*helper)(texture);
|
||||
return (long) result;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nDestroySpecularFilter(JNIEnv* env, jclass, jlong nativeObject) {
|
||||
delete (IBLPrefilterContext::SpecularFilter*) nativeObject;
|
||||
}
|
||||
@@ -28,7 +28,10 @@ using namespace filament;
|
||||
using namespace filament::math;
|
||||
using namespace image;
|
||||
|
||||
static jlong nCreateTexture(JNIEnv* env, jclass,
|
||||
jlong nCreateHDRTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat);
|
||||
|
||||
static jlong nCreateKTXTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
@@ -73,6 +76,19 @@ static jlong nCreateSkybox(JNIEnv* env, jclass,
|
||||
return (jlong) Skybox::Builder().environment(cubemap).showSun(true).build(*engine);
|
||||
}
|
||||
|
||||
static jboolean nGetSphericalHarmonics(JNIEnv* env, jclass, jobject javaBuffer, jint remaining,
|
||||
jfloatArray outSphericalHarmonics_) {
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
|
||||
jfloat* outSphericalHarmonics = env->GetFloatArrayElements(outSphericalHarmonics_, nullptr);
|
||||
const auto success = bundle.getSphericalHarmonics(
|
||||
reinterpret_cast<filament::math::float3*>(outSphericalHarmonics)
|
||||
);
|
||||
env->ReleaseFloatArrayElements(outSphericalHarmonics_, outSphericalHarmonics, JNI_ABORT);
|
||||
|
||||
return success ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||
JNIEnv* env;
|
||||
@@ -80,15 +96,27 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
jclass c = env->FindClass("com/google/android/filament/utils/KtxLoader");
|
||||
if (c == nullptr) return JNI_ERR;
|
||||
int rc;
|
||||
|
||||
static const JNINativeMethod methods[] = {
|
||||
{"nCreateTexture", "(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateTexture)},
|
||||
{"nCreateIndirectLight", "(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateIndirectLight)},
|
||||
{"nCreateSkybox", "(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateSkybox)},
|
||||
// KTXLoader
|
||||
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTXLoader");
|
||||
if (ktxloaderClass == nullptr) return JNI_ERR;
|
||||
static const JNINativeMethod ktxMethods[] = {
|
||||
{(char*)"nCreateKTXTexture", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateKTXTexture)},
|
||||
{(char*)"nCreateIndirectLight", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateIndirectLight)},
|
||||
{(char*)"nCreateSkybox", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateSkybox)},
|
||||
{(char*)"nGetSphericalHarmonics", (char*)"(Ljava/nio/Buffer;I[F)Z", reinterpret_cast<void*>(nGetSphericalHarmonics)},
|
||||
};
|
||||
int rc = env->RegisterNatives(c, methods, sizeof(methods) / sizeof(JNINativeMethod));
|
||||
rc = env->RegisterNatives(ktxloaderClass, ktxMethods, sizeof(ktxMethods) / sizeof(JNINativeMethod));
|
||||
if (rc != JNI_OK) return rc;
|
||||
|
||||
// HDRLoader
|
||||
jclass hdrloaderClass = env->FindClass("com/google/android/filament/utils/HDRLoader");
|
||||
if (hdrloaderClass == nullptr) return JNI_ERR;
|
||||
static const JNINativeMethod hdrMethods[] = {
|
||||
{(char*)"nCreateHDRTexture", (char*)"(JLjava/nio/Buffer;II)J", reinterpret_cast<void*>(nCreateHDRTexture)},
|
||||
};
|
||||
rc = env->RegisterNatives(hdrloaderClass, hdrMethods, sizeof(hdrMethods) / sizeof(JNINativeMethod));
|
||||
if (rc != JNI_OK) return rc;
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
|
||||
@@ -51,7 +51,7 @@ import com.google.android.filament.Renderer;
|
||||
* (shouldClose) that is triggered after the last test has been invoked.
|
||||
*/
|
||||
public class AutomationEngine {
|
||||
private long mNativeObject;
|
||||
private final long mNativeObject;
|
||||
private ColorGrading mColorGrading;
|
||||
|
||||
/**
|
||||
@@ -76,6 +76,20 @@ public class AutomationEngine {
|
||||
public boolean verbose = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collection of Filament objects that can be modified by the automation engine.
|
||||
*/
|
||||
public static class ViewerContent {
|
||||
public View view;
|
||||
public Renderer renderer;
|
||||
public MaterialInstance[] materials;
|
||||
public LightManager lightManager;
|
||||
public Scene scene;
|
||||
public IndirectLight indirectLight;
|
||||
public @Entity int sunlight;
|
||||
public @Entity int[] assetLights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows remote control for the viewer.
|
||||
*/
|
||||
@@ -88,6 +102,7 @@ public class AutomationEngine {
|
||||
public boolean skyboxEnabled = true;
|
||||
public float cameraFocalLength = 28.0f;
|
||||
public float cameraFocusDistance = 0.0f;
|
||||
public boolean autoScaleEnabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,22 +155,22 @@ public class AutomationEngine {
|
||||
* This is when settings get applied, screenshots are (optionally) exported, and the internal
|
||||
* test counter is potentially incremented.
|
||||
*
|
||||
* @param view The Filament View that automation pushes changes to.
|
||||
* @param materials Optional set of of materials that can receive parameter tweaks.
|
||||
* @param renderer The Filament Renderer that can be used to take screenshots.
|
||||
* @param content Contains the Filament View, Materials, and Renderer that get modified.
|
||||
* @param deltaTime The amount of time that has passed since the previous tick in seconds.
|
||||
*/
|
||||
public void tick(@NonNull View view, @Nullable MaterialInstance[] materials,
|
||||
@NonNull Renderer renderer, float deltaTime) {
|
||||
public void tick(@NonNull ViewerContent content, float deltaTime) {
|
||||
if (content.view == null || content.renderer == null) {
|
||||
throw new IllegalStateException("Must provide a View and Renderer");
|
||||
}
|
||||
long[] nativeMaterialInstances = null;
|
||||
if (materials != null) {
|
||||
nativeMaterialInstances = new long[materials.length];
|
||||
if (content.materials != null) {
|
||||
nativeMaterialInstances = new long[content.materials.length];
|
||||
for (int i = 0; i < nativeMaterialInstances.length; i++) {
|
||||
nativeMaterialInstances[i] = materials[i].getNativeObject();
|
||||
nativeMaterialInstances[i] = content.materials[i].getNativeObject();
|
||||
}
|
||||
}
|
||||
long nativeView = view.getNativeObject();
|
||||
long nativeRenderer = renderer.getNativeObject();
|
||||
long nativeView = content.view.getNativeObject();
|
||||
long nativeRenderer = content.renderer.getNativeObject();
|
||||
nTick(mNativeObject, nativeView, nativeMaterialInstances, nativeRenderer, deltaTime);
|
||||
}
|
||||
|
||||
@@ -167,24 +182,32 @@ public class AutomationEngine {
|
||||
*
|
||||
* This updates the stashed Settings object, then pushes those settings to the given
|
||||
* Filament objects. Clients can optionally call getColorGrading() after calling this method.
|
||||
*
|
||||
* @param settingsJson Contains the JSON string with a set of changes that need to be pushed.
|
||||
* @param content Contains a set of Filament objects that you want to mutate.
|
||||
*/
|
||||
public void applySettings(@NonNull String settingsJson, @NonNull View view,
|
||||
@Nullable MaterialInstance[] materials, @Nullable IndirectLight ibl, @Entity int light,
|
||||
@NonNull LightManager lm, @NonNull Scene scene, @NonNull Renderer renderer) {
|
||||
public void applySettings(@NonNull String settingsJson, @NonNull ViewerContent content) {
|
||||
if (content.view == null || content.renderer == null) {
|
||||
throw new IllegalStateException("Must provide a View and Renderer");
|
||||
}
|
||||
long[] nativeMaterialInstances = null;
|
||||
if (materials != null) {
|
||||
nativeMaterialInstances = new long[materials.length];
|
||||
if (content.lightManager == null || content.scene == null) {
|
||||
throw new IllegalStateException("Must provide a LightManager and Scene");
|
||||
}
|
||||
if (content.materials != null) {
|
||||
nativeMaterialInstances = new long[content.materials.length];
|
||||
for (int i = 0; i < nativeMaterialInstances.length; i++) {
|
||||
nativeMaterialInstances[i] = materials[i].getNativeObject();
|
||||
nativeMaterialInstances[i] = content.materials[i].getNativeObject();
|
||||
}
|
||||
}
|
||||
long nativeView = view.getNativeObject();
|
||||
long nativeIbl = ibl == null ? 0 : ibl.getNativeObject();
|
||||
long nativeLm = lm.getNativeObject();
|
||||
long nativeScene = scene.getNativeObject();
|
||||
long nativeRenderer = renderer.getNativeObject();
|
||||
long nativeView = content.view.getNativeObject();
|
||||
long nativeIbl = content.indirectLight == null ? 0 : content.indirectLight.getNativeObject();
|
||||
long nativeLm = content.lightManager.getNativeObject();
|
||||
long nativeScene = content.scene.getNativeObject();
|
||||
long nativeRenderer = content.renderer.getNativeObject();
|
||||
nApplySettings(mNativeObject, settingsJson, nativeView, nativeMaterialInstances,
|
||||
nativeIbl, light, nativeLm, nativeScene, nativeRenderer);
|
||||
nativeIbl, content.sunlight, content.assetLights, nativeLm, nativeScene,
|
||||
nativeRenderer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,7 +269,8 @@ public class AutomationEngine {
|
||||
private static native void nTick(long nativeObject, long view, long[] materials, long renderer,
|
||||
float deltaTime);
|
||||
private static native void nApplySettings(long nativeObject, String jsonSettings, long view,
|
||||
long[] materials, long ibl, int light, long lightManager, long scene, long renderer);
|
||||
long[] materials, long ibl, int sunlight, int[] assetLights, long lightManager,
|
||||
long scene, long renderer);
|
||||
private static native void nGetViewerOptions(long nativeObject, Object result);
|
||||
private static native long nGetColorGrading(long nativeObject, long nativeEngine);
|
||||
private static native void nSignalBatchMode(long nativeObject);
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
import com.google.android.filament.Engine
|
||||
import com.google.android.filament.Texture
|
||||
|
||||
import java.nio.Buffer
|
||||
|
||||
/**
|
||||
* Utility for decoding an HDR file and producing a Filament texture.
|
||||
*/
|
||||
object HDRLoader {
|
||||
class Options {
|
||||
var desiredFormat = Texture.InternalFormat.RGB16F
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes the content of an HDR file and produces a [Texture] object.
|
||||
*
|
||||
* @param engine Gets passed to the builder.
|
||||
* @param buffer The content of the HDR File.
|
||||
* @param options Loader options.
|
||||
* @return The resulting Filament texture, or null on failure.
|
||||
*/
|
||||
fun createTexture(engine: Engine, buffer: Buffer, options: Options = Options()): Texture? {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeTexture = nCreateHDRTexture(nativeEngine, buffer, buffer.remaining(), options.desiredFormat.ordinal)
|
||||
if (nativeTexture == 0L) {
|
||||
return null;
|
||||
}
|
||||
return Texture(nativeTexture)
|
||||
}
|
||||
|
||||
private external fun nCreateHDRTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, format: Int): Long
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.utils;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Texture;
|
||||
|
||||
/**
|
||||
* IBLPrefilterContext creates and initializes GPU state common to all environment map filters
|
||||
* supported. Typically, only one instance per filament Engine of this object needs to exist.
|
||||
*
|
||||
* Java usage example:
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* context = new IBLPrefilterContext(engine);
|
||||
* equirectangularToCubemap = new IBLPrefilterContext.EquirectangularToCubemap(context);
|
||||
*
|
||||
* Texture equirect = HDRLoader.createTexture("foo.hdr");
|
||||
* Texture skyboxTexture = equirectangularToCubemap.run(equirect);
|
||||
* engine.destroy(equirect);
|
||||
*
|
||||
* specularFilter = new IBLPrefilterContext.SpecularFilter(context);
|
||||
* Texture reflections = specularFilter.run(skyboxTexture);
|
||||
*
|
||||
* IndirectLight ibl = IndirectLight.Builder()
|
||||
* .reflections(reflections)
|
||||
* .intensity(30000.0f)
|
||||
* .build(engine);
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
public class IBLPrefilterContext {
|
||||
private final long mNativeObject;
|
||||
|
||||
public IBLPrefilterContext(Engine engine) {
|
||||
mNativeObject = nCreate(engine.getNativeObject());
|
||||
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create IBLPrefilterContext");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
nDestroy(mNativeObject);
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public static class EquirectangularToCubemap {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
private final HelperFinalizer mFinalizer;
|
||||
private final long mNativeHelper;
|
||||
|
||||
public EquirectangularToCubemap(IBLPrefilterContext context) {
|
||||
mNativeHelper = nCreateEquirectHelper(context.mNativeObject);
|
||||
mFinalizer = new HelperFinalizer(mNativeHelper);
|
||||
}
|
||||
|
||||
public Texture run(Texture equirect) {
|
||||
long nativeTexture = nEquirectHelperRun(mNativeHelper, equirect.getNativeObject());
|
||||
return new Texture(nativeTexture);
|
||||
}
|
||||
|
||||
private static class HelperFinalizer {
|
||||
private final long mNativeObject;
|
||||
|
||||
HelperFinalizer(long nativeObject) { mNativeObject = nativeObject; }
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroyEquirectHelper(mNativeObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpecularFilter {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
private final HelperFinalizer mFinalizer;
|
||||
private final long mNativeHelper;
|
||||
|
||||
public SpecularFilter(IBLPrefilterContext context) {
|
||||
mNativeHelper = nCreateSpecularFilter(context.mNativeObject);
|
||||
mFinalizer = new HelperFinalizer(mNativeHelper);
|
||||
}
|
||||
|
||||
public Texture run(Texture skybox) {
|
||||
long nativeTexture = nSpecularFilterRun(mNativeHelper, skybox.getNativeObject());
|
||||
return new Texture(nativeTexture);
|
||||
}
|
||||
|
||||
private static class HelperFinalizer {
|
||||
private final long mNativeObject;
|
||||
|
||||
HelperFinalizer(long nativeObject) { mNativeObject = nativeObject; }
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroySpecularFilter(mNativeObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static native long nCreate(long nativeEngine);
|
||||
private static native void nDestroy(long nativeObject);
|
||||
|
||||
private static native long nCreateEquirectHelper(long nativeContext);
|
||||
private static native long nEquirectHelperRun(long nativeHelper, long nativeEquirect);
|
||||
private static native void nDestroyEquirectHelper(long nativeObject);
|
||||
|
||||
private static native long nCreateSpecularFilter(long nativeContext);
|
||||
private static native long nSpecularFilterRun(long nativeHelper, long nativeSkybox);
|
||||
private static native void nDestroySpecularFilter(long nativeObject);
|
||||
}
|
||||
@@ -29,7 +29,7 @@ import java.nio.Buffer
|
||||
* KTX is a simple container format that makes it easy to bundle miplevels and cubemap faces
|
||||
* into a single file.
|
||||
*/
|
||||
object KtxLoader {
|
||||
object KTXLoader {
|
||||
class Options {
|
||||
var srgb = false
|
||||
}
|
||||
@@ -44,8 +44,8 @@ object KtxLoader {
|
||||
*/
|
||||
fun createTexture(engine: Engine, buffer: Buffer, options: Options = Options()): Texture {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeTexture = nCreateTexture(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return Texture(engine, nativeTexture)
|
||||
val nativeTexture = nCreateKTXTexture(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return Texture(nativeTexture)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +59,7 @@ object KtxLoader {
|
||||
fun createIndirectLight(engine: Engine, buffer: Buffer, options: Options = Options()): IndirectLight {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeIndirectLight = nCreateIndirectLight(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return IndirectLight(engine, nativeIndirectLight)
|
||||
return IndirectLight(nativeIndirectLight)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,10 +73,23 @@ object KtxLoader {
|
||||
fun createSkybox(engine: Engine, buffer: Buffer, options: Options = Options()): Skybox {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeSkybox = nCreateSkybox(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return Skybox(engine, nativeSkybox)
|
||||
return Skybox(nativeSkybox)
|
||||
}
|
||||
|
||||
private external fun nCreateTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
|
||||
/**
|
||||
* Retrieves spherical harmonics from the content of a KTX file.
|
||||
*
|
||||
* @param buffer The content of the KTX File.
|
||||
* @return The resulting array of 9 * 3 floats, or null on failure.
|
||||
*/
|
||||
fun getSphericalHarmonics(buffer: Buffer): FloatArray? {
|
||||
val sphericalHarmonics = FloatArray(9 * 3)
|
||||
val success = nGetSphericalHarmonics(buffer, buffer.remaining(), sphericalHarmonics)
|
||||
return if (success) sphericalHarmonics else null
|
||||
}
|
||||
|
||||
private external fun nCreateKTXTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
|
||||
private external fun nCreateIndirectLight(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
|
||||
private external fun nGetSphericalHarmonics(buffer: Buffer, remaining: Int, outSphericalHarmonics: FloatArray): Boolean
|
||||
private external fun nCreateSkybox(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
|
||||
}
|
||||
@@ -80,18 +80,22 @@ data class Mat2(
|
||||
operator fun times(v: Float) = Mat2(x * v, y * v)
|
||||
operator fun div(v: Float) = Mat2(x / v, y / v)
|
||||
|
||||
operator fun times(m: Mat2): Mat2 {
|
||||
val t = transpose(this)
|
||||
return Mat2(
|
||||
Float2(dot(t.x, m.x), dot(t.y, m.x)),
|
||||
Float2(dot(t.x, m.y), dot(t.y, m.y))
|
||||
)
|
||||
}
|
||||
operator fun times(m: Mat2) = Mat2(
|
||||
Float2(
|
||||
x.x * m.x.x + y.x * m.x.y,
|
||||
x.y * m.x.x + y.y * m.x.y,
|
||||
),
|
||||
Float2(
|
||||
x.x * m.y.x + y.x * m.y.y,
|
||||
x.y * m.y.x + y.y * m.y.y,
|
||||
)
|
||||
)
|
||||
|
||||
operator fun times(v: Float2) = Float2(
|
||||
x.x * v.x + y.x * v.y,
|
||||
x.y * v.x + y.y * v.y,
|
||||
)
|
||||
|
||||
operator fun times(v: Float2): Float2 {
|
||||
val t = transpose(this)
|
||||
return Float2(dot(t.x, v), dot(t.y, v))
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x,
|
||||
@@ -171,19 +175,29 @@ data class Mat3(
|
||||
operator fun times(v: Float) = Mat3(x * v, y * v, z * v)
|
||||
operator fun div(v: Float) = Mat3(x / v, y / v, z / v)
|
||||
|
||||
operator fun times(m: Mat3): Mat3 {
|
||||
val t = transpose(this)
|
||||
return Mat3(
|
||||
Float3(dot(t.x, m.x), dot(t.y, m.x), dot(t.z, m.x)),
|
||||
Float3(dot(t.x, m.y), dot(t.y, m.y), dot(t.z, m.y)),
|
||||
Float3(dot(t.x, m.z), dot(t.y, m.z), dot(t.z, m.z))
|
||||
)
|
||||
}
|
||||
operator fun times(m: Mat3) = Mat3(
|
||||
Float3(
|
||||
x.x * m.x.x + y.x * m.x.y + z.x * m.x.z,
|
||||
x.y * m.x.x + y.y * m.x.y + z.y * m.x.z,
|
||||
x.z * m.x.x + y.z * m.x.y + z.z * m.x.z,
|
||||
),
|
||||
Float3(
|
||||
x.x * m.y.x + y.x * m.y.y + z.x * m.y.z,
|
||||
x.y * m.y.x + y.y * m.y.y + z.y * m.y.z,
|
||||
x.z * m.y.x + y.z * m.y.y + z.z * m.y.z,
|
||||
),
|
||||
Float3(
|
||||
x.x * m.z.x + y.x * m.z.y + z.x * m.z.z,
|
||||
x.y * m.z.x + y.y * m.z.y + z.y * m.z.z,
|
||||
x.z * m.z.x + y.z * m.z.y + z.z * m.z.z,
|
||||
)
|
||||
)
|
||||
|
||||
operator fun times(v: Float3): Float3 {
|
||||
val t = transpose(this)
|
||||
return Float3(dot(t.x, v), dot(t.y, v), dot(t.z, v))
|
||||
}
|
||||
operator fun times(v: Float3) = Float3(
|
||||
x.x * v.x + y.x * v.y + z.x * v.z,
|
||||
x.y * v.x + y.y * v.y + z.y * v.z,
|
||||
x.z * v.x + y.z * v.y + z.z * v.z,
|
||||
)
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x, z.x,
|
||||
@@ -313,20 +327,39 @@ data class Mat4(
|
||||
operator fun times(v: Float) = Mat4(x * v, y * v, z * v, w * v)
|
||||
operator fun div(v: Float) = Mat4(x / v, y / v, z / v, w / v)
|
||||
|
||||
operator fun times(m: Mat4): Mat4 {
|
||||
val t = transpose(this)
|
||||
return Mat4(
|
||||
Float4(dot(t.x, m.x), dot(t.y, m.x), dot(t.z, m.x), dot(t.w, m.x)),
|
||||
Float4(dot(t.x, m.y), dot(t.y, m.y), dot(t.z, m.y), dot(t.w, m.y)),
|
||||
Float4(dot(t.x, m.z), dot(t.y, m.z), dot(t.z, m.z), dot(t.w, m.z)),
|
||||
Float4(dot(t.x, m.w), dot(t.y, m.w), dot(t.z, m.w), dot(t.w, m.w))
|
||||
)
|
||||
}
|
||||
operator fun times(m: Mat4) = Mat4(
|
||||
Float4(
|
||||
x.x * m.x.x + y.x * m.x.y + z.x * m.x.z + w.x * m.x.w,
|
||||
x.y * m.x.x + y.y * m.x.y + z.y * m.x.z + w.y * m.x.w,
|
||||
x.z * m.x.x + y.z * m.x.y + z.z * m.x.z + w.z * m.x.w,
|
||||
x.w * m.x.x + y.w * m.x.y + z.w * m.x.z + w.w * m.x.w,
|
||||
),
|
||||
Float4(
|
||||
x.x * m.y.x + y.x * m.y.y + z.x * m.y.z + w.x * m.y.w,
|
||||
x.y * m.y.x + y.y * m.y.y + z.y * m.y.z + w.y * m.y.w,
|
||||
x.z * m.y.x + y.z * m.y.y + z.z * m.y.z + w.z * m.y.w,
|
||||
x.w * m.y.x + y.w * m.y.y + z.w * m.y.z + w.w * m.y.w,
|
||||
),
|
||||
Float4(
|
||||
x.x * m.z.x + y.x * m.z.y + z.x * m.z.z + w.x * m.z.w,
|
||||
x.y * m.z.x + y.y * m.z.y + z.y * m.z.z + w.y * m.z.w,
|
||||
x.z * m.z.x + y.z * m.z.y + z.z * m.z.z + w.z * m.z.w,
|
||||
x.w * m.z.x + y.w * m.z.y + z.w * m.z.z + w.w * m.z.w,
|
||||
),
|
||||
Float4(
|
||||
x.x * m.w.x + y.x * m.w.y + z.x * m.w.z + w.x * m.w.w,
|
||||
x.y * m.w.x + y.y * m.w.y + z.y * m.w.z + w.y * m.w.w,
|
||||
x.z * m.w.x + y.z * m.w.y + z.z * m.w.z + w.z * m.w.w,
|
||||
x.w * m.w.x + y.w * m.w.y + z.w * m.w.z + w.w * m.w.w,
|
||||
)
|
||||
)
|
||||
|
||||
operator fun times(v: Float4): Float4 {
|
||||
val t = transpose(this)
|
||||
return Float4(dot(t.x, v), dot(t.y, v), dot(t.z, v), dot(t.w, v))
|
||||
}
|
||||
operator fun times(v: Float4) = Float4(
|
||||
x.x * v.x + y.x * v.y + z.x * v.z+ w.x * v.w,
|
||||
x.y * v.x + y.y * v.y + z.y * v.z+ w.y * v.w,
|
||||
x.z * v.x + y.z * v.y + z.z * v.z+ w.z * v.w,
|
||||
x.w * v.x + y.w * v.y + z.w * v.z+ w.w * v.w
|
||||
)
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x, z.x, w.x,
|
||||
@@ -355,6 +388,8 @@ fun transpose(m: Mat3) = Mat3(
|
||||
Float3(m.x.y, m.y.y, m.z.y),
|
||||
Float3(m.x.z, m.y.z, m.z.z)
|
||||
)
|
||||
|
||||
@Suppress("LocalVariableName")
|
||||
fun inverse(m: Mat3): Mat3 {
|
||||
val a = m.x.x
|
||||
val b = m.x.y
|
||||
@@ -385,6 +420,7 @@ fun transpose(m: Mat4) = Mat4(
|
||||
Float4(m.x.z, m.y.z, m.z.z, m.w.z),
|
||||
Float4(m.x.w, m.y.w, m.z.w, m.w.w)
|
||||
)
|
||||
|
||||
fun inverse(m: Mat4): Mat4 {
|
||||
val result = Mat4()
|
||||
|
||||
@@ -462,8 +498,8 @@ fun translation(m: Mat4) = translation(m.translation)
|
||||
fun rotation(m: Mat4) = Mat4(normalize(m.right), normalize(m.up), normalize(m.forward))
|
||||
fun rotation(d: Float3): Mat4 {
|
||||
val r = transform(d, ::radians)
|
||||
val c = transform(r, { x -> cos(x) })
|
||||
val s = transform(r, { x -> sin(x) })
|
||||
val c = transform(r) { x -> cos(x) }
|
||||
val s = transform(r) { x -> sin(x) }
|
||||
|
||||
return Mat4.of(
|
||||
c.y * c.z, -c.x * s.z + s.x * s.y * c.z, s.x * s.z + c.x * s.y * c.z, 0.0f,
|
||||
|
||||
@@ -105,12 +105,12 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
init {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
camera = engine.createCamera().apply { setExposure(kAperture, kShutterSpeed, kSensitivity) }
|
||||
camera = engine.createCamera(engine.entityManager.create()).apply { setExposure(kAperture, kShutterSpeed, kSensitivity) }
|
||||
view = engine.createView()
|
||||
view.scene = scene
|
||||
view.camera = camera
|
||||
|
||||
assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
|
||||
assetLoader = AssetLoader(engine, UbershaderLoader(engine), EntityManager.get())
|
||||
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes)
|
||||
|
||||
// Always add a direct light source since it is required for shadowing.
|
||||
@@ -225,6 +225,16 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the transformation that was set up via transformToUnitCube.
|
||||
*/
|
||||
fun clearRootTransform() {
|
||||
asset?.let {
|
||||
val tm = engine.transformManager
|
||||
tm.setTransform(tm.getInstance(it.root), Mat4().toFloatArray())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all entities associated with the most recently-loaded model.
|
||||
*/
|
||||
@@ -299,7 +309,8 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
engine.destroyRenderer(renderer)
|
||||
engine.destroyView(this@ModelViewer.view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
EntityManager.get().destroy(camera.entity)
|
||||
|
||||
EntityManager.get().destroy(light)
|
||||
|
||||
|
||||
@@ -81,6 +81,16 @@ public class RemoteServer {
|
||||
return message;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys the native WebSocket server and frees up the port.
|
||||
*
|
||||
* This might need to be done explicitly (as opposed to waiting for gc) to free up the port.
|
||||
*/
|
||||
public void close() {
|
||||
nDestroy(mNativeObject);
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
nDestroy(mNativeObject);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(gltfio-android)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
set(GLTFIO_DIR ../../libs/gltfio)
|
||||
@@ -60,7 +61,9 @@ set(GLTFIO_SRCS
|
||||
src/main/cpp/AssetLoader.cpp
|
||||
src/main/cpp/FilamentAsset.cpp
|
||||
src/main/cpp/FilamentInstance.cpp
|
||||
src/main/cpp/MaterialProvider.cpp
|
||||
src/main/cpp/MaterialKey.cpp
|
||||
src/main/cpp/MaterialKey.h
|
||||
src/main/cpp/UbershaderLoader.cpp
|
||||
src/main/cpp/ResourceLoader.cpp
|
||||
|
||||
${FILAMENT_DIR}/include/gltfio/resources/gltfresources_lite.h
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,27 +23,178 @@
|
||||
|
||||
#include <gltfio/AssetLoader.h>
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
#include "MaterialKey.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace gltfio;
|
||||
using namespace utils;
|
||||
|
||||
class JavaMaterialProvider : public MaterialProvider {
|
||||
JNIEnv* const mEnv;
|
||||
const jobject mJavaProvider;
|
||||
mutable Material** mPreviousMaterials = nullptr;
|
||||
|
||||
jclass mMaterialKeyClass;
|
||||
|
||||
jmethodID mMaterialKeyConstructor;
|
||||
jmethodID mCreateMaterialInstance;
|
||||
jmethodID mGetMaterials;
|
||||
jmethodID mNeedsDummyData;
|
||||
jmethodID mDestroyMaterials;
|
||||
jmethodID mMaterialInstanceGetNativeObject;
|
||||
jmethodID mMaterialGetNativeObject;
|
||||
|
||||
public:
|
||||
JavaMaterialProvider(JNIEnv* env, jobject provider) : mEnv(env),
|
||||
mJavaProvider(env->NewGlobalRef(provider)) {
|
||||
mMaterialKeyClass = env->FindClass(JAVA_MATERIAL_KEY);
|
||||
mMaterialKeyClass = (jclass) env->NewGlobalRef(mMaterialKeyClass);
|
||||
assert_invariant(mMaterialKeyClass);
|
||||
|
||||
mMaterialKeyConstructor = env->GetMethodID(mMaterialKeyClass, "<init>", "()V");
|
||||
assert_invariant(mMaterialKeyConstructor);
|
||||
|
||||
jclass materialInstanceClass = env->FindClass("com/google/android/filament/MaterialInstance");
|
||||
mMaterialInstanceGetNativeObject = env->GetMethodID(materialInstanceClass, "getNativeObject", "()J");
|
||||
assert_invariant(mMaterialInstanceGetNativeObject);
|
||||
|
||||
jclass materialClass = env->FindClass("com/google/android/filament/Material");
|
||||
mMaterialGetNativeObject = env->GetMethodID(materialClass, "getNativeObject", "()J");
|
||||
assert_invariant(mMaterialGetNativeObject);
|
||||
|
||||
jclass providerClass = env->GetObjectClass(provider);
|
||||
|
||||
mCreateMaterialInstance = env->GetMethodID(providerClass, "createMaterialInstance",
|
||||
"(L" JAVA_MATERIAL_KEY ";[ILjava/lang/String;)Lcom/google/android/filament/MaterialInstance;");
|
||||
assert_invariant(mCreateMaterialInstance);
|
||||
|
||||
mGetMaterials = env->GetMethodID(providerClass, "getMaterials",
|
||||
"()[Lcom/google/android/filament/Material;");
|
||||
assert_invariant(mGetMaterials);
|
||||
|
||||
mNeedsDummyData = env->GetMethodID(providerClass, "needsDummyData","(I)Z");
|
||||
assert_invariant(mNeedsDummyData);
|
||||
|
||||
mDestroyMaterials = env->GetMethodID(providerClass, "destroyMaterials", "()V");
|
||||
assert_invariant(mDestroyMaterials);
|
||||
}
|
||||
|
||||
~JavaMaterialProvider() override {
|
||||
mEnv->DeleteGlobalRef(mMaterialKeyClass);
|
||||
mEnv->DeleteGlobalRef(mJavaProvider);
|
||||
delete mPreviousMaterials;
|
||||
}
|
||||
|
||||
MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap, const char* label) override {
|
||||
// Create a Java object for the material key and copy the native fields into it.
|
||||
jobject javaKey = mEnv->NewObject(mMaterialKeyClass, mMaterialKeyConstructor);
|
||||
|
||||
auto& helper = MaterialKeyHelper::get();
|
||||
helper.copy(mEnv, javaKey, *config);
|
||||
|
||||
// Convert the optional label into a Java string.
|
||||
jstring stringLabel = label ? mEnv->NewStringUTF(label) : nullptr;
|
||||
|
||||
// Allocate space for the output argument.
|
||||
jintArray uvMapArray = mEnv->NewIntArray(8);
|
||||
|
||||
// Call the Java-based material provider.
|
||||
jobject materialInstance = mEnv->CallObjectMethod(mJavaProvider, mCreateMaterialInstance,
|
||||
javaKey, uvMapArray, stringLabel);
|
||||
|
||||
// Copy the UvMap results from the JVM array into the native array.
|
||||
if (uvmap) {
|
||||
jint* elements = mEnv->GetIntArrayElements(uvMapArray, nullptr);
|
||||
for (size_t i = 0; i < uvmap->size(); i++) {
|
||||
(*uvmap)[i] = (UvSet) elements[i];
|
||||
}
|
||||
mEnv->ReleaseIntArrayElements(uvMapArray, elements, JNI_ABORT);
|
||||
}
|
||||
|
||||
// The config parameter is an in-out parameter so we need to copy the results from Java.
|
||||
helper.copy(mEnv, *config, javaKey);
|
||||
|
||||
mEnv->DeleteLocalRef(javaKey);
|
||||
mEnv->DeleteLocalRef(uvMapArray);
|
||||
|
||||
if (stringLabel) {
|
||||
mEnv->DeleteLocalRef(stringLabel);
|
||||
}
|
||||
|
||||
if (materialInstance == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return (MaterialInstance*) mEnv->CallLongMethod(materialInstance, mMaterialInstanceGetNativeObject);
|
||||
}
|
||||
|
||||
const Material* const* getMaterials() const noexcept override {
|
||||
jobjectArray javaMaterials = (jobjectArray) mEnv->CallObjectMethod(mJavaProvider, mGetMaterials);
|
||||
|
||||
const size_t count = mEnv->GetArrayLength(javaMaterials);
|
||||
|
||||
delete mPreviousMaterials;
|
||||
using MaterialPointer = Material*;
|
||||
mPreviousMaterials = new MaterialPointer[count];
|
||||
|
||||
// Call "getNativeObject" on each material in order to pass them up into the native layer.
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
jobject javaMaterial = mEnv->GetObjectArrayElement(javaMaterials, i);
|
||||
jlong matPointer = mEnv->CallLongMethod(javaMaterial, mMaterialGetNativeObject);
|
||||
mPreviousMaterials[i] = (Material*) matPointer;
|
||||
}
|
||||
|
||||
return mPreviousMaterials;
|
||||
}
|
||||
|
||||
size_t getMaterialsCount() const noexcept override {
|
||||
jobjectArray javaMaterials = (jobjectArray) mEnv->CallObjectMethod(mJavaProvider, mGetMaterials);
|
||||
return mEnv->GetArrayLength(javaMaterials);
|
||||
}
|
||||
|
||||
void destroyMaterials() override {
|
||||
mEnv->CallObjectMethod(mJavaProvider, mDestroyMaterials);
|
||||
}
|
||||
|
||||
bool needsDummyData(VertexAttribute attrib) const noexcept override {
|
||||
return mEnv->CallBooleanMethod(mJavaProvider, mNeedsDummyData, (int) attrib);
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetLoader(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeProvider, jlong nativeEntities) {
|
||||
Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetLoader(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject provider, jlong nativeEntities) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
MaterialProvider* materials = (MaterialProvider*) nativeProvider;
|
||||
MaterialProvider* materialProvider = nullptr;
|
||||
|
||||
// First check for a fast path that passes a native MaterialProvider into the loader.
|
||||
// This drastically reduces the number of JNI calls while the asset is being loaded.
|
||||
jclass klass = env->GetObjectClass(provider);
|
||||
jmethodID getNativeObject = env->GetMethodID(klass, "getNativeObject", "()J");
|
||||
if (getNativeObject) {
|
||||
materialProvider = (MaterialProvider*) env->CallLongMethod(provider, getNativeObject);
|
||||
} else {
|
||||
env->ExceptionClear();
|
||||
}
|
||||
|
||||
if (materialProvider == nullptr) {
|
||||
materialProvider = new JavaMaterialProvider(env, provider);
|
||||
}
|
||||
|
||||
EntityManager* entities = (EntityManager*) nativeEntities;
|
||||
NameComponentManager* names = new NameComponentManager(*entities);
|
||||
return (jlong) AssetLoader::create({engine, materials, names, entities});
|
||||
return (jlong) AssetLoader::create({engine, materialProvider, names, entities});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_AssetLoader_nDestroyAssetLoader(JNIEnv*, jclass,
|
||||
jlong nativeLoader) {
|
||||
AssetLoader* loader = (AssetLoader*) nativeLoader;
|
||||
delete loader->getMaterialProvider();
|
||||
NameComponentManager* names = loader->getNames();
|
||||
AssetLoader::destroy(&loader);
|
||||
delete names;
|
||||
|
||||
@@ -192,6 +192,15 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetName(JNIEnv* env, jcla
|
||||
return val ? env->NewStringUTF(val) : nullptr;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetExtras(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint entityId) {
|
||||
Entity entity = Entity::import(entityId);
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
const auto val = asset->getExtras(entity);
|
||||
return val ? env->NewStringUTF(val) : nullptr;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetAnimator(JNIEnv* , jclass,
|
||||
jlong nativeAsset) {
|
||||
|
||||
177
android/gltfio-android/src/main/cpp/MaterialKey.cpp
Normal file
177
android/gltfio-android/src/main/cpp/MaterialKey.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
|
||||
#include "MaterialKey.h"
|
||||
|
||||
using namespace gltfio;
|
||||
|
||||
MaterialKeyHelper& MaterialKeyHelper::get() {
|
||||
static MaterialKeyHelper helper;
|
||||
return helper;
|
||||
}
|
||||
|
||||
void MaterialKeyHelper::init(JNIEnv* env) {
|
||||
const jclass materialKeyClass = env->FindClass(JAVA_MATERIAL_KEY);
|
||||
auto field = [materialKeyClass, env](const char* fieldName, const char* signature) {
|
||||
return env->GetFieldID(materialKeyClass, fieldName, signature);
|
||||
};
|
||||
doubleSided = field("doubleSided", "Z");
|
||||
unlit = field("unlit", "Z");
|
||||
hasVertexColors = field("hasVertexColors", "Z");
|
||||
hasBaseColorTexture = field("hasBaseColorTexture", "Z");
|
||||
hasNormalTexture = field("hasNormalTexture", "Z");
|
||||
hasOcclusionTexture = field("hasOcclusionTexture", "Z");
|
||||
hasEmissiveTexture = field("hasEmissiveTexture", "Z");
|
||||
useSpecularGlossiness = field("useSpecularGlossiness", "Z");
|
||||
alphaMode = field("alphaMode", "I");
|
||||
enableDiagnostics = field("enableDiagnostics", "Z");
|
||||
hasMetallicRoughnessTexture = field("hasMetallicRoughnessTexture", "Z");
|
||||
metallicRoughnessUV = field("metallicRoughnessUV", "I");
|
||||
baseColorUV = field("baseColorUV", "I");
|
||||
hasClearCoatTexture = field("hasClearCoatTexture", "Z");
|
||||
clearCoatUV = field("clearCoatUV", "I");
|
||||
hasClearCoatRoughnessTexture = field("hasClearCoatRoughnessTexture", "Z");
|
||||
clearCoatRoughnessUV = field("clearCoatRoughnessUV", "I");
|
||||
hasClearCoatNormalTexture = field("hasClearCoatNormalTexture", "Z");
|
||||
clearCoatNormalUV = field("clearCoatNormalUV", "I");
|
||||
hasClearCoat = field("hasClearCoat", "Z");
|
||||
hasTransmission = field("hasTransmission", "Z");
|
||||
hasTextureTransforms = field("hasTextureTransforms", "Z");
|
||||
emissiveUV = field("emissiveUV", "I");
|
||||
aoUV = field("aoUV", "I");
|
||||
normalUV = field("normalUV", "I");
|
||||
hasTransmissionTexture = field("hasTransmissionTexture", "Z");
|
||||
transmissionUV = field("transmissionUV", "I");
|
||||
hasSheenColorTexture = field("hasSheenColorTexture", "Z");
|
||||
sheenColorUV = field("sheenColorUV", "I");
|
||||
hasSheenRoughnessTexture = field("hasSheenRoughnessTexture", "Z");
|
||||
sheenRoughnessUV = field("sheenRoughnessUV", "I");
|
||||
hasVolumeThicknessTexture = field("hasVolumeThicknessTexture", "Z");
|
||||
volumeThicknessUV = field("volumeThicknessUV", "I");
|
||||
hasSheen = field("hasSheen", "Z");
|
||||
hasIOR = field("hasIOR", "Z");
|
||||
}
|
||||
|
||||
void MaterialKeyHelper::copy(JNIEnv* env, MaterialKey& dst, jobject src) {
|
||||
dst.doubleSided = env->GetBooleanField(src, doubleSided);
|
||||
dst.unlit = env->GetBooleanField(src, unlit);
|
||||
dst.hasVertexColors = env->GetBooleanField(src, hasVertexColors);
|
||||
dst.hasBaseColorTexture = env->GetBooleanField(src, hasBaseColorTexture);
|
||||
dst.hasNormalTexture = env->GetBooleanField(src, hasNormalTexture);
|
||||
dst.hasOcclusionTexture = env->GetBooleanField(src, hasOcclusionTexture);
|
||||
dst.hasEmissiveTexture = env->GetBooleanField(src, hasEmissiveTexture);
|
||||
dst.useSpecularGlossiness = env->GetBooleanField(src, useSpecularGlossiness);
|
||||
dst.alphaMode = (AlphaMode) env->GetIntField(src, alphaMode);
|
||||
dst.enableDiagnostics = env->GetBooleanField(src, enableDiagnostics);
|
||||
dst.hasMetallicRoughnessTexture = env->GetBooleanField(src, hasMetallicRoughnessTexture);
|
||||
dst.metallicRoughnessUV = env->GetIntField(src, metallicRoughnessUV);
|
||||
dst.baseColorUV = env->GetIntField(src, baseColorUV);
|
||||
dst.hasClearCoatTexture = env->GetBooleanField(src, hasClearCoatTexture);
|
||||
dst.clearCoatUV = env->GetIntField(src, clearCoatUV);
|
||||
dst.hasClearCoatRoughnessTexture = env->GetBooleanField(src, hasClearCoatRoughnessTexture);
|
||||
dst.clearCoatRoughnessUV = env->GetIntField(src, clearCoatRoughnessUV);
|
||||
dst.hasClearCoatNormalTexture = env->GetBooleanField(src, hasClearCoatNormalTexture);
|
||||
dst.clearCoatNormalUV = env->GetIntField(src, clearCoatNormalUV);
|
||||
dst.hasClearCoat = env->GetBooleanField(src, hasClearCoat);
|
||||
dst.hasTransmission = env->GetBooleanField(src, hasTransmission);
|
||||
dst.hasTextureTransforms = env->GetBooleanField(src, hasTextureTransforms);
|
||||
dst.emissiveUV = env->GetIntField(src, emissiveUV);
|
||||
dst.aoUV = env->GetIntField(src, aoUV);
|
||||
dst.normalUV = env->GetIntField(src, normalUV);
|
||||
dst.hasTransmissionTexture = env->GetBooleanField(src, hasTransmissionTexture);
|
||||
dst.transmissionUV = env->GetIntField(src, transmissionUV);
|
||||
dst.hasSheenColorTexture = env->GetBooleanField(src, hasSheenColorTexture);
|
||||
dst.sheenColorUV = env->GetIntField(src, sheenColorUV);
|
||||
dst.hasSheenRoughnessTexture = env->GetBooleanField(src, hasSheenRoughnessTexture);
|
||||
dst.sheenRoughnessUV = env->GetIntField(src, sheenRoughnessUV);
|
||||
dst.hasVolumeThicknessTexture = env->GetBooleanField(src, hasVolumeThicknessTexture);
|
||||
dst.volumeThicknessUV = env->GetIntField(src, volumeThicknessUV);
|
||||
dst.hasSheen = env->GetBooleanField(src, hasSheen);
|
||||
dst.hasIOR = env->GetBooleanField(src, hasIOR);
|
||||
}
|
||||
|
||||
void MaterialKeyHelper::copy(JNIEnv* env, jobject dst, const MaterialKey& src) {
|
||||
env->SetBooleanField(dst, doubleSided, src.doubleSided);
|
||||
env->SetBooleanField(dst, unlit, src.unlit);
|
||||
env->SetBooleanField(dst, hasVertexColors, src.hasVertexColors);
|
||||
env->SetBooleanField(dst, hasBaseColorTexture, src.hasBaseColorTexture);
|
||||
env->SetBooleanField(dst, hasNormalTexture, src.hasNormalTexture);
|
||||
env->SetBooleanField(dst, hasOcclusionTexture, src.hasOcclusionTexture);
|
||||
env->SetBooleanField(dst, hasEmissiveTexture, src.hasEmissiveTexture);
|
||||
env->SetBooleanField(dst, useSpecularGlossiness, src.useSpecularGlossiness);
|
||||
env->SetIntField(dst, alphaMode, (int) src.alphaMode);
|
||||
env->SetBooleanField(dst, enableDiagnostics, src.enableDiagnostics);
|
||||
env->SetBooleanField(dst, hasMetallicRoughnessTexture, src.hasMetallicRoughnessTexture);
|
||||
env->SetIntField(dst, metallicRoughnessUV, src.metallicRoughnessUV);
|
||||
env->SetIntField(dst, baseColorUV, src.baseColorUV);
|
||||
env->SetBooleanField(dst, hasClearCoatTexture, src.hasClearCoatTexture);
|
||||
env->SetIntField(dst, clearCoatUV, src.clearCoatUV);
|
||||
env->SetBooleanField(dst, hasClearCoatRoughnessTexture, src.hasClearCoatRoughnessTexture);
|
||||
env->SetIntField(dst, clearCoatRoughnessUV, src.clearCoatRoughnessUV);
|
||||
env->SetBooleanField(dst, hasClearCoatNormalTexture, src.hasClearCoatNormalTexture);
|
||||
env->SetIntField(dst, clearCoatNormalUV, src.clearCoatNormalUV);
|
||||
env->SetBooleanField(dst, hasClearCoat, src.hasClearCoat);
|
||||
env->SetBooleanField(dst, hasTransmission, src.hasTransmission);
|
||||
env->SetBooleanField(dst, hasTextureTransforms, src.hasTextureTransforms);
|
||||
env->SetIntField(dst, emissiveUV, src.emissiveUV);
|
||||
env->SetIntField(dst, aoUV, src.aoUV);
|
||||
env->SetIntField(dst, normalUV, src.normalUV);
|
||||
env->SetBooleanField(dst, hasTransmissionTexture, src.hasTransmissionTexture);
|
||||
env->SetIntField(dst, transmissionUV, src.transmissionUV);
|
||||
env->SetBooleanField(dst, hasSheenColorTexture, src.hasSheenColorTexture);
|
||||
env->SetIntField(dst, sheenColorUV, src.sheenColorUV);
|
||||
env->SetBooleanField(dst, hasSheenRoughnessTexture, src.hasSheenRoughnessTexture);
|
||||
env->SetIntField(dst, sheenRoughnessUV, src.sheenRoughnessUV);
|
||||
env->SetBooleanField(dst, hasVolumeThicknessTexture, src.hasVolumeThicknessTexture);
|
||||
env->SetIntField(dst, volumeThicknessUV, src.volumeThicknessUV);
|
||||
env->SetBooleanField(dst, hasSheen, src.hasSheen);
|
||||
env->SetBooleanField(dst, hasIOR, src.hasIOR);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nGlobalInit(JNIEnv* env, jclass) {
|
||||
MaterialKeyHelper::get().init(env);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nConstrainMaterial(JNIEnv* env, jclass,
|
||||
jobject materialKey, jintArray uvMap) {
|
||||
MaterialKey nativeMaterialKey = {};
|
||||
|
||||
auto& helper = MaterialKeyHelper::get();
|
||||
helper.copy(env, nativeMaterialKey, materialKey);
|
||||
|
||||
UvMap nativeUvMap = {};
|
||||
constrainMaterial(&nativeMaterialKey, &nativeUvMap);
|
||||
|
||||
// Copy the UvMap results from the native array into the JVM array.
|
||||
jint* elements = env->GetIntArrayElements(uvMap, nullptr);
|
||||
if (elements) {
|
||||
const size_t javaSize = env->GetArrayLength(uvMap);
|
||||
for (int i = 0, n = std::min(javaSize, nativeUvMap.size()); i < n; ++i) {
|
||||
elements[i] = nativeUvMap[i];
|
||||
}
|
||||
env->ReleaseIntArrayElements(uvMap, elements, 0);
|
||||
}
|
||||
|
||||
// The config parameter is an in-out parameter so we need to copy the results back to Java.
|
||||
helper.copy(env, materialKey, nativeMaterialKey);
|
||||
}
|
||||
68
android/gltfio-android/src/main/cpp/MaterialKey.h
Normal file
68
android/gltfio-android/src/main/cpp/MaterialKey.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
|
||||
#define JAVA_MATERIAL_KEY "com/google/android/filament/gltfio/MaterialProvider$MaterialKey"
|
||||
|
||||
class MaterialKeyHelper {
|
||||
public:
|
||||
static MaterialKeyHelper& get();
|
||||
|
||||
void copy(JNIEnv* env, gltfio::MaterialKey& dst, jobject src);
|
||||
void copy(JNIEnv* env, jobject dst, const gltfio::MaterialKey& src);
|
||||
|
||||
void init(JNIEnv* env); // called only from the Java static class constructor
|
||||
|
||||
private:
|
||||
jfieldID doubleSided;
|
||||
jfieldID unlit;
|
||||
jfieldID hasVertexColors;
|
||||
jfieldID hasBaseColorTexture;
|
||||
jfieldID hasNormalTexture;
|
||||
jfieldID hasOcclusionTexture;
|
||||
jfieldID hasEmissiveTexture;
|
||||
jfieldID useSpecularGlossiness;
|
||||
jfieldID alphaMode;
|
||||
jfieldID enableDiagnostics;
|
||||
jfieldID hasMetallicRoughnessTexture;
|
||||
jfieldID metallicRoughnessUV;
|
||||
jfieldID baseColorUV;
|
||||
jfieldID hasClearCoatTexture;
|
||||
jfieldID clearCoatUV;
|
||||
jfieldID hasClearCoatRoughnessTexture;
|
||||
jfieldID clearCoatRoughnessUV;
|
||||
jfieldID hasClearCoatNormalTexture;
|
||||
jfieldID clearCoatNormalUV;
|
||||
jfieldID hasClearCoat;
|
||||
jfieldID hasTransmission;
|
||||
jfieldID hasTextureTransforms;
|
||||
jfieldID emissiveUV;
|
||||
jfieldID aoUV;
|
||||
jfieldID normalUV;
|
||||
jfieldID hasTransmissionTexture;
|
||||
jfieldID transmissionUV;
|
||||
jfieldID hasSheenColorTexture;
|
||||
jfieldID sheenColorUV;
|
||||
jfieldID hasSheenRoughnessTexture;
|
||||
jfieldID sheenRoughnessUV;
|
||||
jfieldID hasVolumeThicknessTexture;
|
||||
jfieldID volumeThicknessUV;
|
||||
jfieldID hasSheen;
|
||||
jfieldID hasIOR;
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace gltfio;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_MaterialProvider_nCreateMaterialProvider(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) createUbershaderLoader(engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterialProvider(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
delete provider;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterials(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
provider->destroyMaterials();
|
||||
}
|
||||
102
android/gltfio-android/src/main/cpp/UbershaderLoader.cpp
Normal file
102
android/gltfio-android/src/main/cpp/UbershaderLoader.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include "MaterialKey.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace gltfio;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateUbershaderLoader(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) createUbershaderLoader(engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nDestroyUbershaderLoader(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
delete provider;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nDestroyMaterials(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
provider->destroyMaterials();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateMaterialInstance(JNIEnv* env, jclass,
|
||||
jlong nativeProvider, jobject materialKey, jintArray uvmap, jstring label) {
|
||||
MaterialKey nativeKey = {};
|
||||
|
||||
auto& helper = MaterialKeyHelper::get();
|
||||
helper.copy(env, nativeKey, materialKey);
|
||||
|
||||
const char* nativeLabel = label ? env->GetStringUTFChars(label, nullptr) : nullptr;
|
||||
UvMap nativeUvMap = {};
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
MaterialInstance* instance = provider->createMaterialInstance(&nativeKey, &nativeUvMap, nativeLabel);
|
||||
|
||||
// Copy the UvMap results from the native array into the JVM array.
|
||||
jint* elements = env->GetIntArrayElements(uvmap, nullptr);
|
||||
if (elements) {
|
||||
const size_t javaSize = env->GetArrayLength(uvmap);
|
||||
for (int i = 0, n = std::min(javaSize, nativeUvMap.size()); i < n; ++i) {
|
||||
elements[i] = nativeUvMap[i];
|
||||
}
|
||||
env->ReleaseIntArrayElements(uvmap, elements, 0);
|
||||
}
|
||||
|
||||
// The config parameter is an in-out parameter so we need to copy the results back to Java.
|
||||
helper.copy(env, materialKey, nativeKey);
|
||||
|
||||
if (label) {
|
||||
env->ReleaseStringUTFChars(label, nativeLabel);
|
||||
}
|
||||
|
||||
return (long) instance;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nGetMaterialCount(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
return provider->getMaterialsCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nGetMaterials(JNIEnv* env, jclass,
|
||||
jlong nativeProvider, jlongArray result) {
|
||||
auto provider = (MaterialProvider *) nativeProvider;
|
||||
auto materials = provider->getMaterials();
|
||||
jlong *resultElements = env->GetLongArrayElements(result, nullptr);
|
||||
if (resultElements) {
|
||||
const size_t javaSize = env->GetArrayLength(result);
|
||||
for (int i = 0, n = std::min(javaSize, provider->getMaterialsCount()); i < n; ++i) {
|
||||
resultElements[i] = (jlong) materials[i];
|
||||
}
|
||||
env->ReleaseLongArrayElements(result, resultElements, JNI_ABORT);
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ import java.nio.Buffer;
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
|
||||
* assetLoader = AssetLoader(engine, UbershaderLoader(engine), EntityManager.get())
|
||||
*
|
||||
* filamentAsset = assets.open("models/lucy.gltf").use { input ->
|
||||
* val bytes = ByteArray(input.available())
|
||||
@@ -85,23 +85,22 @@ public class AssetLoader {
|
||||
* {@link FilamentAsset}.
|
||||
*
|
||||
* @param engine the engine that the loader should pass to builder objects
|
||||
* @param generator specifies if materials should be generated or loaded from a pre-built set
|
||||
* @param provider an object that provides Filament materials corresponding to glTF materials
|
||||
* @param entities the EntityManager that should be used to create entities
|
||||
*/
|
||||
public AssetLoader(@NonNull Engine engine, @NonNull MaterialProvider generator,
|
||||
public AssetLoader(@NonNull Engine engine, @NonNull MaterialProvider provider,
|
||||
@NonNull EntityManager entities) {
|
||||
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
long nativeMaterials = generator.getNativeObject();
|
||||
long nativeEntities = entities.getNativeObject();
|
||||
mNativeObject = nCreateAssetLoader(nativeEngine, nativeMaterials, nativeEntities);
|
||||
mNativeObject = nCreateAssetLoader(nativeEngine, provider, nativeEntities);
|
||||
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Unable to parse glTF asset.");
|
||||
}
|
||||
|
||||
mEngine = engine;
|
||||
mMaterialCache = generator;
|
||||
mMaterialCache = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,10 +148,11 @@ public class AssetLoader {
|
||||
if (nativeAsset == 0) {
|
||||
return null;
|
||||
}
|
||||
FilamentAsset asset = new FilamentAsset(mEngine, nativeAsset);
|
||||
for (int i = 0; i < nativeInstances.length; i++) {
|
||||
instances[i] = new FilamentInstance(nativeInstances[i]);
|
||||
instances[i] = new FilamentInstance(asset, nativeInstances[i]);
|
||||
}
|
||||
return new FilamentAsset(mEngine, nativeAsset);
|
||||
return asset;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +178,7 @@ public class AssetLoader {
|
||||
if (nativeInstance == 0) {
|
||||
return null;
|
||||
}
|
||||
return new FilamentInstance(nativeInstance);
|
||||
return new FilamentInstance(asset, nativeInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,7 +197,7 @@ public class AssetLoader {
|
||||
asset.clearNativeObject();
|
||||
}
|
||||
|
||||
private static native long nCreateAssetLoader(long nativeEngine, long nativeGenerator,
|
||||
private static native long nCreateAssetLoader(long nativeEngine, Object provider,
|
||||
long nativeEntities);
|
||||
private static native void nDestroyAssetLoader(long nativeLoader);
|
||||
private static native long nCreateAssetFromBinary(long nativeLoader, Buffer buffer, int remaining);
|
||||
|
||||
@@ -186,6 +186,16 @@ public class FilamentAsset {
|
||||
return nGetName(getNativeObject(), entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the glTF extras string for the asset or a specific node.
|
||||
*
|
||||
* @param entity the entity corresponding to the glTF node, or 0 to get the asset-level string.
|
||||
* @return the requested extras string, or null if it does not exist.
|
||||
*/
|
||||
public @Nullable String getExtras(@Entity int entity) {
|
||||
return nGetExtras(mNativeObject, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or retrieves the <code>Animator</code> interface for this asset.
|
||||
*
|
||||
@@ -252,6 +262,7 @@ public class FilamentAsset {
|
||||
|
||||
private static native void nGetBoundingBox(long nativeAsset, float[] box);
|
||||
private static native String nGetName(long nativeAsset, int entity);
|
||||
private static native String nGetExtras(long nativeAsset, int entity);
|
||||
private static native long nGetAnimator(long nativeAsset);
|
||||
private static native int nGetResourceUriCount(long nativeAsset);
|
||||
private static native void nGetResourceUris(long nativeAsset, String[] result);
|
||||
|
||||
@@ -28,10 +28,12 @@ import com.google.android.filament.Entity;
|
||||
* @see AssetLoader
|
||||
*/
|
||||
public class FilamentInstance {
|
||||
private FilamentAsset mAsset;
|
||||
private long mNativeObject;
|
||||
private Animator mAnimator;
|
||||
|
||||
FilamentInstance(long nativeObject) {
|
||||
FilamentInstance(FilamentAsset asset, long nativeObject) {
|
||||
mAsset = asset;
|
||||
mNativeObject = nativeObject;
|
||||
mAnimator = null;
|
||||
}
|
||||
@@ -46,6 +48,11 @@ public class FilamentInstance {
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public @NonNull FilamentAsset getAsset() {
|
||||
return mAsset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transform root for the asset, which has no matching glTF node.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,36 +16,108 @@
|
||||
|
||||
package com.google.android.filament.gltfio;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.MaterialInstance;
|
||||
import com.google.android.filament.Material;
|
||||
import com.google.android.filament.VertexBuffer;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
/**
|
||||
* Loads pre-generated ubershader materials that fulfill glTF requirements.
|
||||
*
|
||||
* <p>This class is used by {@link AssetLoader} to create Filament materials.
|
||||
* Client applications do not need to call methods on it.</p>
|
||||
*/
|
||||
public class MaterialProvider {
|
||||
private long mNativeObject;
|
||||
public interface MaterialProvider {
|
||||
|
||||
/**
|
||||
* Constructs an ubershader loader using the supplied {@link Engine}.
|
||||
*
|
||||
* @param engine the engine used to create materials
|
||||
* MaterialKey specifies the requirements for a requested glTF material.
|
||||
* The provider creates Filament materials that fulfill these requirements.
|
||||
*/
|
||||
public MaterialProvider(Engine engine) {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateMaterialProvider(nativeEngine);
|
||||
}
|
||||
public static class MaterialKey {
|
||||
public boolean doubleSided;
|
||||
public boolean unlit;
|
||||
public boolean hasVertexColors;
|
||||
public boolean hasBaseColorTexture;
|
||||
public boolean hasNormalTexture;
|
||||
public boolean hasOcclusionTexture;
|
||||
public boolean hasEmissiveTexture;
|
||||
public boolean useSpecularGlossiness;
|
||||
public int alphaMode; // 0 = OPAQUE, 1 = MASK, 2 = BLEND
|
||||
public boolean enableDiagnostics;
|
||||
public boolean hasMetallicRoughnessTexture; // piggybacks with specularRoughness
|
||||
public int metallicRoughnessUV; // piggybacks with specularRoughness
|
||||
public int baseColorUV;
|
||||
public boolean hasClearCoatTexture;
|
||||
public int clearCoatUV;
|
||||
public boolean hasClearCoatRoughnessTexture;
|
||||
public int clearCoatRoughnessUV;
|
||||
public boolean hasClearCoatNormalTexture;
|
||||
public int clearCoatNormalUV;
|
||||
public boolean hasClearCoat;
|
||||
public boolean hasTransmission;
|
||||
public boolean hasTextureTransforms;
|
||||
public int emissiveUV;
|
||||
public int aoUV;
|
||||
public int normalUV;
|
||||
public boolean hasTransmissionTexture;
|
||||
public int transmissionUV;
|
||||
public boolean hasSheenColorTexture;
|
||||
public int sheenColorUV;
|
||||
public boolean hasSheenRoughnessTexture;
|
||||
public int sheenRoughnessUV;
|
||||
public boolean hasVolumeThicknessTexture;
|
||||
public int volumeThicknessUV;
|
||||
public boolean hasSheen;
|
||||
public boolean hasIOR;
|
||||
|
||||
public MaterialKey() {}
|
||||
static {
|
||||
nGlobalInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate UV map according to the material key, altering latter if required.
|
||||
*
|
||||
* Filament supports up to 2 UV sets. glTF has arbitrary texcoord set indices, but it
|
||||
* allows implementations to support only 2 simultaneous sets. Here we build a mapping
|
||||
* table with 1-based indices where 0 means unused. Note that the order in which we drop
|
||||
* textures can affect the look of certain assets. This "order of degradation" is
|
||||
* stipulated by the glTF 2.0 specification.
|
||||
*
|
||||
* @param uvmap Output argument that gets populated with a small table that maps from a
|
||||
* glTF uv index to a Filament uv index (0 = UNUSED, 1 = UV0, 2 = UV1).
|
||||
*/
|
||||
public void constrainMaterial(@NonNull @Size(min = 8) int[] uvmap) {
|
||||
nConstrainMaterial(this, uvmap);
|
||||
}
|
||||
|
||||
private static native void nGlobalInit();
|
||||
private static native void nConstrainMaterial(MaterialKey materialKey, int[] uvmap);
|
||||
};
|
||||
|
||||
/**
|
||||
* Frees memory associated with the native material provider.
|
||||
* */
|
||||
public void destroy() {
|
||||
nDestroyMaterialProvider(mNativeObject);
|
||||
mNativeObject = 0;
|
||||
}
|
||||
* Creates or fetches a compiled Filament material, then creates an instance from it.
|
||||
*
|
||||
* @param config Specifies requirements; might be mutated due to resource constraints.
|
||||
* @param uvmap Output argument that gets populated with a small table that maps from a glTF uv
|
||||
* index to a Filament uv index (0 = UNUSED, 1 = UV0, 2 = UV1).
|
||||
* @param label Optional tag that is not a part of the cache key.
|
||||
*/
|
||||
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label);
|
||||
|
||||
/**
|
||||
* Creates and returns an array containing all cached materials.
|
||||
*/
|
||||
public @NonNull Material[] getMaterials();
|
||||
|
||||
/**
|
||||
* Returns true if the presence of the given vertex attribute is required.
|
||||
*
|
||||
* Some types of providers (e.g. ubershader) require dummy attribute values
|
||||
* if the glTF model does not provide them.
|
||||
*
|
||||
* NOTE: The given attribute is the VertexAttribute enum casted to an integer.
|
||||
* This is done to streamline the JNI work between Java and Native layers.
|
||||
*/
|
||||
public boolean needsDummyData(int attrib);
|
||||
|
||||
/**
|
||||
* Destroys all cached materials.
|
||||
@@ -53,15 +125,5 @@ public class MaterialProvider {
|
||||
* This is not called automatically when MaterialProvider is destroyed, which allows
|
||||
* clients to take ownership of the cache if desired.
|
||||
*/
|
||||
public void destroyMaterials() {
|
||||
nDestroyMaterials(mNativeObject);
|
||||
}
|
||||
|
||||
long getNativeObject() {
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
private static native long nCreateMaterialProvider(long nativeEngine);
|
||||
private static native void nDestroyMaterialProvider(long nativeProvider);
|
||||
private static native void nDestroyMaterials(long nativeProvider);
|
||||
public void destroyMaterials();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.gltfio;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.MaterialInstance;
|
||||
import com.google.android.filament.Material;
|
||||
import com.google.android.filament.VertexBuffer;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
/**
|
||||
* Loads pre-generated ubershader materials that fulfill glTF requirements.
|
||||
*
|
||||
* <p>This class is used by {@link AssetLoader} to create Filament materials.
|
||||
* Client applications do not need to call methods on it.</p>
|
||||
*/
|
||||
public class UbershaderLoader implements MaterialProvider {
|
||||
private long mNativeObject;
|
||||
|
||||
/**
|
||||
* Constructs an ubershader loader using the supplied {@link Engine}.
|
||||
*
|
||||
* @param engine the engine used to create materials
|
||||
*/
|
||||
public UbershaderLoader(Engine engine) {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateUbershaderLoader(nativeEngine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees memory associated with the native material provider.
|
||||
* */
|
||||
public void destroy() {
|
||||
nDestroyUbershaderLoader(mNativeObject);
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label) {
|
||||
long nativeMaterialInstance = nCreateMaterialInstance(mNativeObject, config, uvmap, label);
|
||||
return nativeMaterialInstance == 0 ? null : new MaterialInstance(null, nativeMaterialInstance);
|
||||
}
|
||||
|
||||
public @NonNull Material[] getMaterials() {
|
||||
final int count = nGetMaterialCount(mNativeObject);
|
||||
Material[] result = new Material[count];
|
||||
long[] natives = new long[count];
|
||||
nGetMaterials(mNativeObject, natives);
|
||||
for (int i = 0; i < count; i++) {
|
||||
result[i] = new Material(natives[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean needsDummyData(int attrib) {
|
||||
VertexBuffer.VertexAttribute vattrib = VertexBuffer.VertexAttribute.values()[attrib];
|
||||
switch (vattrib) {
|
||||
case UV0:
|
||||
case UV1:
|
||||
case COLOR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void destroyMaterials() {
|
||||
nDestroyMaterials(mNativeObject);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
private static native long nCreateUbershaderLoader(long nativeEngine);
|
||||
private static native void nDestroyUbershaderLoader(long nativeProvider);
|
||||
private static native void nDestroyMaterials(long nativeProvider);
|
||||
private static native long nCreateMaterialInstance(long nativeProvider, MaterialKey config, int[] uvmap, String label);
|
||||
private static native int nGetMaterialCount(long nativeProvider);
|
||||
private static native void nGetMaterials(long nativeProvider, long[] result);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.9.24
|
||||
VERSION_NAME=1.12.1
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@@ -1,6 +1,5 @@
|
||||
#Thu Nov 05 09:33:02 PST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
||||
|
||||
53
android/gradlew
vendored
53
android/gradlew
vendored
@@ -1,5 +1,21 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m"'
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
@@ -66,6 +82,7 @@ esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
@@ -109,10 +126,11 @@ if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
@@ -138,19 +156,19 @@ if $cygwin ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -159,14 +177,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
43
android/gradlew.bat
vendored
43
android/gradlew.bat
vendored
@@ -1,3 +1,19 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m"
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -35,7 +54,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@@ -45,28 +64,14 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
@@ -24,6 +24,9 @@ import android.view.*
|
||||
import android.view.GestureDetector
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import com.google.android.filament.Fence
|
||||
import com.google.android.filament.IndirectLight
|
||||
import com.google.android.filament.Skybox
|
||||
import com.google.android.filament.utils.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -57,6 +60,9 @@ class MainActivity : Activity() {
|
||||
private var statusText: String? = null
|
||||
private var latestDownload: String? = null
|
||||
private val automation = AutomationEngine()
|
||||
private var loadStartTime = 0L
|
||||
private var loadStartFence: Fence? = null
|
||||
private val viewerContent = AutomationEngine.ViewerContent()
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -71,6 +77,11 @@ class MainActivity : Activity() {
|
||||
doubleTapDetector = GestureDetector(applicationContext, doubleTapListener)
|
||||
|
||||
modelViewer = ModelViewer(surfaceView)
|
||||
viewerContent.view = modelViewer.view
|
||||
viewerContent.sunlight = modelViewer.light
|
||||
viewerContent.lightManager = modelViewer.engine.lightManager
|
||||
viewerContent.scene = modelViewer.scene
|
||||
viewerContent.renderer = modelViewer.renderer
|
||||
|
||||
surfaceView.setOnTouchListener { _, event ->
|
||||
modelViewer.onTouchEvent(event)
|
||||
@@ -78,27 +89,28 @@ class MainActivity : Activity() {
|
||||
true
|
||||
}
|
||||
|
||||
createRenderables()
|
||||
createDefaultRenderables()
|
||||
createIndirectLight()
|
||||
|
||||
setStatusText("To load a new model, go to the above URL on your host machine.")
|
||||
|
||||
val dynamicResolutionOptions = modelViewer.view.dynamicResolutionOptions
|
||||
dynamicResolutionOptions.enabled = true
|
||||
modelViewer.view.dynamicResolutionOptions = dynamicResolutionOptions
|
||||
val view = modelViewer.view
|
||||
view.dynamicResolutionOptions = view.dynamicResolutionOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
val ssaoOptions = modelViewer.view.ambientOcclusionOptions
|
||||
ssaoOptions.enabled = true
|
||||
modelViewer.view.ambientOcclusionOptions = ssaoOptions
|
||||
view.ambientOcclusionOptions = view.ambientOcclusionOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
val bloomOptions = modelViewer.view.bloomOptions
|
||||
bloomOptions.enabled = true
|
||||
modelViewer.view.bloomOptions = bloomOptions
|
||||
view.bloomOptions = view.bloomOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
remoteServer = RemoteServer(8082)
|
||||
}
|
||||
|
||||
private fun createRenderables() {
|
||||
private fun createDefaultRenderables() {
|
||||
val buffer = assets.open("models/scene.gltf").use { input ->
|
||||
val bytes = ByteArray(input.available())
|
||||
input.read(bytes)
|
||||
@@ -106,7 +118,7 @@ class MainActivity : Activity() {
|
||||
}
|
||||
|
||||
modelViewer.loadModelGltfAsync(buffer) { uri -> readCompressedAsset("models/$uri") }
|
||||
modelViewer.transformToUnitCube()
|
||||
updateRootTransform()
|
||||
}
|
||||
|
||||
private fun createIndirectLight() {
|
||||
@@ -114,11 +126,12 @@ class MainActivity : Activity() {
|
||||
val scene = modelViewer.scene
|
||||
val ibl = "default_env"
|
||||
readCompressedAsset("envs/$ibl/${ibl}_ibl.ktx").let {
|
||||
scene.indirectLight = KtxLoader.createIndirectLight(engine, it)
|
||||
scene.indirectLight = KTXLoader.createIndirectLight(engine, it)
|
||||
scene.indirectLight!!.intensity = 30_000.0f
|
||||
viewerContent.indirectLight = modelViewer.scene.indirectLight
|
||||
}
|
||||
readCompressedAsset("envs/$ibl/${ibl}_skybox.ktx").let {
|
||||
scene.skybox = KtxLoader.createSkybox(engine, it)
|
||||
scene.skybox = KTXLoader.createSkybox(engine, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +164,39 @@ class MainActivity : Activity() {
|
||||
withContext(Dispatchers.Main) {
|
||||
modelViewer.destroyModel()
|
||||
modelViewer.loadModelGlb(message.buffer)
|
||||
modelViewer.transformToUnitCube()
|
||||
updateRootTransform()
|
||||
loadStartTime = System.nanoTime()
|
||||
loadStartFence = modelViewer.engine.createFence()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadHdr(message: RemoteServer.ReceivedMessage) {
|
||||
withContext(Dispatchers.Main) {
|
||||
val engine = modelViewer.engine
|
||||
val equirect = HDRLoader.createTexture(engine, message.buffer)
|
||||
if (equirect == null) {
|
||||
setStatusText("Could not decode HDR file.")
|
||||
} else {
|
||||
setStatusText("Successfully decoded HDR file.")
|
||||
|
||||
val context = IBLPrefilterContext(engine)
|
||||
val equirectToCubemap = IBLPrefilterContext.EquirectangularToCubemap(context)
|
||||
val skyboxTexture = equirectToCubemap.run(equirect)!!
|
||||
engine.destroyTexture(equirect)
|
||||
|
||||
val specularFilter = IBLPrefilterContext.SpecularFilter(context)
|
||||
val reflections = specularFilter.run(skyboxTexture)
|
||||
|
||||
val ibl = IndirectLight.Builder()
|
||||
.reflections(reflections)
|
||||
.intensity(30000.0f)
|
||||
.build(engine)
|
||||
|
||||
val sky = Skybox.Builder().environment(skyboxTexture).build(engine)
|
||||
|
||||
modelViewer.scene.skybox = sky
|
||||
modelViewer.scene.indirectLight = ibl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +284,9 @@ class MainActivity : Activity() {
|
||||
pathToBufferMapping[path]
|
||||
}
|
||||
}
|
||||
modelViewer.transformToUnitCube()
|
||||
updateRootTransform()
|
||||
loadStartTime = System.nanoTime()
|
||||
loadStartFence = modelViewer.engine.createFence()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +303,7 @@ class MainActivity : Activity() {
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
remoteServer?.close()
|
||||
}
|
||||
|
||||
fun loadModelData(message: RemoteServer.ReceivedMessage) {
|
||||
@@ -265,6 +313,8 @@ class MainActivity : Activity() {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (message.label.endsWith(".zip")) {
|
||||
loadZip(message)
|
||||
} else if (message.label.endsWith(".hdr")) {
|
||||
loadHdr(message)
|
||||
} else {
|
||||
loadGlb(message)
|
||||
}
|
||||
@@ -273,11 +323,19 @@ class MainActivity : Activity() {
|
||||
|
||||
fun loadSettings(message: RemoteServer.ReceivedMessage) {
|
||||
val json = StandardCharsets.UTF_8.decode(message.buffer).toString()
|
||||
automation.applySettings(json, modelViewer.view, null,
|
||||
modelViewer.scene.indirectLight, modelViewer.light, modelViewer.engine.lightManager,
|
||||
modelViewer.scene, modelViewer.renderer)
|
||||
modelViewer.view.colorGrading = automation.getColorGrading((modelViewer.engine))
|
||||
viewerContent.assetLights = modelViewer.asset?.lightEntities
|
||||
automation.applySettings(json, viewerContent)
|
||||
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
|
||||
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
|
||||
updateRootTransform()
|
||||
}
|
||||
|
||||
private fun updateRootTransform() {
|
||||
if (automation.viewerOptions.autoScaleEnabled) {
|
||||
modelViewer.transformToUnitCube()
|
||||
} else {
|
||||
modelViewer.clearRootTransform()
|
||||
}
|
||||
}
|
||||
|
||||
inner class FrameCallback : Choreographer.FrameCallback {
|
||||
@@ -285,6 +343,16 @@ class MainActivity : Activity() {
|
||||
override fun doFrame(frameTimeNanos: Long) {
|
||||
choreographer.postFrameCallback(this)
|
||||
|
||||
loadStartFence?.let {
|
||||
if (it.wait(Fence.Mode.FLUSH, 0) == Fence.FenceStatus.CONDITION_SATISFIED) {
|
||||
val end = System.nanoTime()
|
||||
val total = (end - loadStartTime) / 1_000_000
|
||||
Log.i(TAG, "The Filament backend took $total ms to load the model geometry.")
|
||||
modelViewer.engine.destroyFence(it)
|
||||
loadStartFence = null
|
||||
}
|
||||
}
|
||||
|
||||
modelViewer.animator?.apply {
|
||||
if (animationCount > 0) {
|
||||
val elapsedTimeSeconds = (frameTimeNanos - startTime).toDouble() / 1_000_000_000
|
||||
@@ -318,11 +386,11 @@ class MainActivity : Activity() {
|
||||
}
|
||||
}
|
||||
|
||||
// Just for testing purposes, this releases the model and reloads it.
|
||||
// Just for testing purposes, this releases the current model and reloads the default model.
|
||||
inner class DoubleTapListener : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onDoubleTap(e: MotionEvent?): Boolean {
|
||||
modelViewer.destroyModel()
|
||||
createRenderables()
|
||||
createDefaultRenderables()
|
||||
return super.onDoubleTap(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,8 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -342,13 +343,14 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -113,7 +113,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -271,12 +271,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -113,7 +113,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -249,12 +249,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -114,7 +114,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -358,13 +358,14 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -101,7 +101,7 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -167,7 +167,8 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
engine.destroyRenderer(renderer)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
EntityManager.get().destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
@@ -221,4 +222,4 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -289,12 +289,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -65,6 +65,7 @@ class MainActivity : Activity() {
|
||||
private lateinit var view1: View
|
||||
private lateinit var view2: View
|
||||
private lateinit var view3: View
|
||||
private lateinit var view4: View
|
||||
// We need skybox to set the background color
|
||||
private lateinit var skybox: Skybox
|
||||
// Should be pretty obvious :)
|
||||
@@ -119,16 +120,20 @@ class MainActivity : Activity() {
|
||||
view1 = engine.createView()
|
||||
view2 = engine.createView()
|
||||
view3 = engine.createView()
|
||||
view4 = engine.createView()
|
||||
|
||||
view0.setName("view0");
|
||||
view1.setName("view1");
|
||||
view2.setName("view2");
|
||||
view3.setName("view3");
|
||||
view4.setName("view4");
|
||||
|
||||
view4.blendMode = View.BlendMode.TRANSLUCENT;
|
||||
|
||||
skybox = Skybox.Builder().build(engine);
|
||||
scene.skybox = skybox
|
||||
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
@@ -136,11 +141,13 @@ class MainActivity : Activity() {
|
||||
view1.camera = camera
|
||||
view2.camera = camera
|
||||
view3.camera = camera
|
||||
view4.camera = camera
|
||||
|
||||
view0.scene = scene
|
||||
view1.scene = scene
|
||||
view2.scene = scene
|
||||
view3.scene = scene
|
||||
view4.scene = scene
|
||||
}
|
||||
|
||||
private fun setupScene() {
|
||||
@@ -373,15 +380,17 @@ class MainActivity : Activity() {
|
||||
engine.destroyView(view1)
|
||||
engine.destroyView(view2)
|
||||
engine.destroyView(view3)
|
||||
engine.destroyView(view4)
|
||||
engine.destroySkybox(skybox)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
@@ -410,6 +419,9 @@ class MainActivity : Activity() {
|
||||
skybox.setColor(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
renderer.render(view3)
|
||||
|
||||
skybox.setColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
renderer.render(view4)
|
||||
|
||||
renderer.endFrame()
|
||||
}
|
||||
}
|
||||
@@ -442,6 +454,7 @@ class MainActivity : Activity() {
|
||||
view1.viewport = Viewport(width / 2, 0, width / 2, height / 2)
|
||||
view2.viewport = Viewport(0, height / 2, width / 2, height / 2)
|
||||
view3.viewport = Viewport(width / 2, height / 2, width / 2, height / 2)
|
||||
view4.viewport = Viewport(width / 4, height / 4, width / 2, height / 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ public class MainActivity extends Activity
|
||||
mRenderer = mEngine.createRenderer();
|
||||
mScene = mEngine.createScene();
|
||||
mView = mEngine.createView();
|
||||
mCamera = mEngine.createCamera();
|
||||
mCamera = mEngine.createCamera(mEngine.getEntityManager().create());
|
||||
|
||||
mCamera.lookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
|
||||
|
||||
@@ -223,9 +223,10 @@ public class MainActivity extends Activity
|
||||
|
||||
mEngine.destroyView(mView);
|
||||
mEngine.destroyScene(mScene);
|
||||
mEngine.destroyCamera(mCamera);
|
||||
mEngine.destroyCameraComponent(mCamera.getEntity());
|
||||
|
||||
EntityManager.get().destroy(mPage.renderable);
|
||||
EntityManager.get().destroy(mCamera.getEntity());
|
||||
|
||||
mEngine.destroy();
|
||||
}
|
||||
@@ -298,4 +299,4 @@ public class MainActivity extends Activity
|
||||
canvas.drawBitmap(bmp, borderSize, borderSize, null);
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -328,13 +328,14 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -113,7 +113,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -271,12 +271,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -39,5 +39,5 @@ dependencies {
|
||||
implementation deps.kotlin
|
||||
implementation project(':filament-android')
|
||||
implementation project(':gltfio-android')
|
||||
implementation project(':filament-utils-android') // required for KtxLoader
|
||||
implementation project(':filament-utils-android') // required for KTXLoader
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -269,12 +269,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -136,7 +136,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
|
||||
// clear the swapchain with transparent pixels
|
||||
val options = renderer.clearOptions
|
||||
@@ -294,12 +294,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
119
build.sh
119
build.sh
@@ -17,14 +17,16 @@ function print_help {
|
||||
echo " Generate .tgz build archives, implies -i."
|
||||
echo " -c"
|
||||
echo " Clean build directories."
|
||||
echo " -C"
|
||||
echo " Clean build directories and revert android/ to a freshly sync'ed state."
|
||||
echo " All (and only) git-ignored files under android/ are deleted."
|
||||
echo " This is sometimes needed instead of -c (which still misses some clean steps)."
|
||||
echo " -d"
|
||||
echo " Enable matdbg and disable material optimization."
|
||||
echo " -f"
|
||||
echo " Always invoke CMake before incremental builds."
|
||||
echo " -i"
|
||||
echo " Install build output"
|
||||
echo " -j"
|
||||
echo " Do not compile desktop Java projects"
|
||||
echo " -m"
|
||||
echo " Compile with make instead of ninja."
|
||||
echo " -p platform1,platform2,..."
|
||||
@@ -48,6 +50,10 @@ function print_help {
|
||||
echo " For macOS, this builds universal binaries for both Apple silicon and Intel-based Macs."
|
||||
echo " -w"
|
||||
echo " Build Web documents (compiles .md.html files to .html)."
|
||||
echo " -k sample1,sample2,..."
|
||||
echo " When building for Android, also build select sample APKs."
|
||||
echo " sampleN is an Android sample, e.g., sample-gltf-viewer."
|
||||
echo " This automatically performs a partial desktop build and install."
|
||||
echo ""
|
||||
echo "Build types:"
|
||||
echo " release"
|
||||
@@ -103,13 +109,16 @@ function print_matdbg_help {
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/build/android/ndk.version | cut -f 1 -d ".")}
|
||||
|
||||
# Requirements
|
||||
CMAKE_MAJOR=3
|
||||
CMAKE_MINOR=10
|
||||
ANDROID_NDK_VERSION=21
|
||||
CMAKE_MINOR=19
|
||||
|
||||
# Internal variables
|
||||
ISSUE_CLEAN=false
|
||||
ISSUE_CLEAN_AGGRESSIVE=false
|
||||
|
||||
ISSUE_DEBUG_BUILD=false
|
||||
ISSUE_RELEASE_BUILD=false
|
||||
@@ -134,9 +143,10 @@ ISSUE_CMAKE_ALWAYS=false
|
||||
|
||||
ISSUE_WEB_DOCS=false
|
||||
|
||||
RUN_TESTS=false
|
||||
ANDROID_SAMPLES=()
|
||||
BUILD_ANDROID_SAMPLES=false
|
||||
|
||||
FILAMENT_ENABLE_JAVA=ON
|
||||
RUN_TESTS=false
|
||||
|
||||
INSTALL_COMMAND=
|
||||
|
||||
@@ -168,6 +178,12 @@ function build_clean {
|
||||
rm -Rf android/filament-utils-android/build android/filament-utils-android/.externalNativeBuild android/filament-utils-android/.cxx
|
||||
}
|
||||
|
||||
function build_clean_aggressive {
|
||||
echo "Cleaning build directories..."
|
||||
rm -Rf out
|
||||
git clean -qfX android
|
||||
}
|
||||
|
||||
function build_desktop_target {
|
||||
local lc_target=$(echo "$1" | tr '[:upper:]' '[:lower:]')
|
||||
local build_targets=$2
|
||||
@@ -197,7 +213,6 @@ function build_desktop_target {
|
||||
-DIMPORT_EXECUTABLES_DIR=out \
|
||||
-DCMAKE_BUILD_TYPE="$1" \
|
||||
-DCMAKE_INSTALL_PREFIX="../${lc_target}/filament" \
|
||||
-DFILAMENT_ENABLE_JAVA="${FILAMENT_ENABLE_JAVA}" \
|
||||
${SWIFTSHADER_OPTION} \
|
||||
${MATDBG_OPTION} \
|
||||
${deployment_target} \
|
||||
@@ -322,6 +337,7 @@ function build_android_target {
|
||||
-G "${BUILD_GENERATOR}" \
|
||||
-DIMPORT_EXECUTABLES_DIR=out \
|
||||
-DCMAKE_BUILD_TYPE="$1" \
|
||||
-DFILAMENT_NDK_VERSION="${FILAMENT_NDK_VERSION}" \
|
||||
-DCMAKE_INSTALL_PREFIX="../android-${lc_target}/filament" \
|
||||
-DCMAKE_TOOLCHAIN_FILE="../../build/toolchain-${arch}-linux-android.cmake" \
|
||||
${MATDBG_OPTION} \
|
||||
@@ -366,16 +382,9 @@ function ensure_android_build {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local ndk_side_by_side="${ANDROID_HOME}/ndk/"
|
||||
if [[ -d ${ndk_side_by_side} ]]; then
|
||||
# shellcheck disable=SC2012
|
||||
local ndk_version=$(ls "${ndk_side_by_side}" | sort -V | tail -n 1 | cut -f 1 -d ".")
|
||||
if [[ ${ndk_version} -lt ${ANDROID_NDK_VERSION} ]]; then
|
||||
echo "Error: Android NDK side-by-side version ${ANDROID_NDK_VERSION} or higher must be installed, exiting"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Error: Android NDK side-by-side version ${ANDROID_NDK_VERSION} or higher must be installed, exiting"
|
||||
# shellcheck disable=SC2012
|
||||
if [[ -z $(ls "${ANDROID_HOME}/ndk/" | sort -V | grep "^${FILAMENT_NDK_VERSION}") ]]; then
|
||||
echo "Error: Android NDK side-by-side version ${FILAMENT_NDK_VERSION} or compatible must be installed, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -399,6 +408,24 @@ function build_android {
|
||||
|
||||
build_desktop "${MOBILE_HOST_TOOLS}"
|
||||
|
||||
# When building the samples, we need to partially "install" the host tools so Gradle can see
|
||||
# them.
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
if [[ "${ISSUE_DEBUG_BUILD}" == "true" ]]; then
|
||||
mkdir -p out/debug/filament/bin
|
||||
for tool in ${MOBILE_HOST_TOOLS}; do
|
||||
cp out/cmake-debug/tools/${tool}/${tool} out/debug/filament/bin/
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_RELEASE_BUILD}" == "true" ]]; then
|
||||
mkdir -p out/release/filament/bin
|
||||
for tool in ${MOBILE_HOST_TOOLS}; do
|
||||
cp out/cmake-release/tools/${tool}/${tool} out/release/filament/bin/
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
INSTALL_COMMAND=${old_install_command}
|
||||
|
||||
if [[ "${ABI_ARM64_V8A}" == "true" ]]; then
|
||||
@@ -438,6 +465,15 @@ function build_android {
|
||||
-Pfilament_abis=${ABI_GRADLE_OPTION} \
|
||||
:filamat-android:assembleDebug
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
./gradlew \
|
||||
-Pfilament_dist_dir=../out/android-debug/filament \
|
||||
-Pfilament_abis=${ABI_GRADLE_OPTION} \
|
||||
:samples:${sample}:assembleDebug
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${INSTALL_COMMAND}" ]]; then
|
||||
echo "Installing out/filamat-android-debug.aar..."
|
||||
cp filamat-android/build/outputs/aar/filamat-android-lite-debug.aar ../out/
|
||||
@@ -453,6 +489,14 @@ function build_android {
|
||||
echo "Installing out/filament-utils-android-debug.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-debug.aar ../out/
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-debug.aar ../out/filament-utils-android-debug.aar
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
echo "Installing out/${sample}-debug.apk"
|
||||
cp samples/${sample}/build/outputs/apk/debug/${sample}-debug-unsigned.apk \
|
||||
../out/${sample}-debug.apk
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -470,6 +514,15 @@ function build_android {
|
||||
-Pfilament_abis=${ABI_GRADLE_OPTION} \
|
||||
:filamat-android:assembleRelease
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
./gradlew \
|
||||
-Pfilament_dist_dir=../out/android-release/filament \
|
||||
-Pfilament_abis=${ABI_GRADLE_OPTION} \
|
||||
:samples:${sample}:assembleRelease
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${INSTALL_COMMAND}" ]]; then
|
||||
echo "Installing out/filamat-android-release.aar..."
|
||||
cp filamat-android/build/outputs/aar/filamat-android-lite-release.aar ../out/
|
||||
@@ -485,6 +538,14 @@ function build_android {
|
||||
echo "Installing out/filament-utils-android-release.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-release.aar ../out/
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-release.aar ../out/filament-utils-android-release.aar
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
echo "Installing out/${sample}-release.apk"
|
||||
cp samples/${sample}/build/outputs/apk/release/${sample}-release-unsigned.apk \
|
||||
../out/${sample}-release.apk
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -628,12 +689,6 @@ function validate_build_command {
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# Make sure we have Java
|
||||
local javac_binary=$(command -v javac)
|
||||
if [[ "${JAVA_HOME}" == "" ]] || [[ ! "${javac_binary}" ]]; then
|
||||
echo "Warning: JAVA_HOME is not set, skipping Java projects"
|
||||
FILAMENT_ENABLE_JAVA=OFF
|
||||
fi
|
||||
# If building a WebAssembly module, ensure we know where Emscripten lives.
|
||||
if [[ "${EMSDK}" == "" ]] && [[ "${ISSUE_WEBGL_BUILD}" == "true" ]]; then
|
||||
echo "Error: EMSDK is not set, exiting"
|
||||
@@ -682,7 +737,7 @@ function run_tests {
|
||||
|
||||
pushd "$(dirname "$0")" > /dev/null
|
||||
|
||||
while getopts ":hacfijmp:q:uvslwtd" opt; do
|
||||
while getopts ":hacCfijmp:q:uvslwtdk:" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
@@ -695,9 +750,12 @@ while getopts ":hacfijmp:q:uvslwtd" opt; do
|
||||
c)
|
||||
ISSUE_CLEAN=true
|
||||
;;
|
||||
C)
|
||||
ISSUE_CLEAN_AGGRESSIVE=true
|
||||
;;
|
||||
d)
|
||||
PRINT_MATDBG_HELP=true
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON"
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON, -DFILAMENT_BUILD_FILAMAT=ON"
|
||||
;;
|
||||
f)
|
||||
ISSUE_CMAKE_ALWAYS=true
|
||||
@@ -705,9 +763,6 @@ while getopts ":hacfijmp:q:uvslwtd" opt; do
|
||||
i)
|
||||
INSTALL_COMMAND=install
|
||||
;;
|
||||
j)
|
||||
FILAMENT_ENABLE_JAVA=OFF
|
||||
;;
|
||||
m)
|
||||
BUILD_GENERATOR="Unix Makefiles"
|
||||
BUILD_COMMAND="make"
|
||||
@@ -796,6 +851,10 @@ while getopts ":hacfijmp:q:uvslwtd" opt; do
|
||||
w)
|
||||
ISSUE_WEB_DOCS=true
|
||||
;;
|
||||
k)
|
||||
BUILD_ANDROID_SAMPLES=true
|
||||
ANDROID_SAMPLES=$(echo "${OPTARG}" | tr ',' '\n')
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -${OPTARG}" >&2
|
||||
echo ""
|
||||
@@ -834,6 +893,10 @@ if [[ "${ISSUE_CLEAN}" == "true" ]]; then
|
||||
build_clean
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_CLEAN_AGGRESSIVE}" == "true" ]]; then
|
||||
build_clean_aggressive
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_DESKTOP_BUILD}" == "true" ]]; then
|
||||
build_desktop
|
||||
fi
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
#
|
||||
# The default is release
|
||||
|
||||
NDK_VERSION="ndk;22.0.7026061"
|
||||
ANDROID_NDK_VERSION=22
|
||||
|
||||
echo "This script is intended to run in a CI environment and may modify your current environment."
|
||||
echo "Please refer to BUILDING.md for more information."
|
||||
|
||||
@@ -47,15 +44,12 @@ elif [[ "$LC_UNAME" == "darwin" ]]; then
|
||||
fi
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
# Only update and install the NDK if necessary, as this can be slow
|
||||
ndk_side_by_side="${ANDROID_HOME}/ndk/"
|
||||
if [[ -d $ndk_side_by_side ]]; then
|
||||
ndk_version=`ls ${ndk_side_by_side} | sort -V | tail -n 1 | cut -f 1 -d "."`
|
||||
if [[ ${ndk_version} -lt ${ANDROID_NDK_VERSION} ]]; then
|
||||
${ANDROID_HOME}/tools/bin/sdkmanager "${NDK_VERSION}" > /dev/null
|
||||
fi
|
||||
else
|
||||
${ANDROID_HOME}/tools/bin/sdkmanager "${NDK_VERSION}" > /dev/null
|
||||
# Unless explicitly specified, NDK version will be set to match exactly the required one
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/ndk.version)}
|
||||
|
||||
# Install the required NDK version specifically (if not present)
|
||||
if [[ ! -d "${ANDROID_HOME}/ndk/$FILAMENT_NDK_VERSION" ]]; then
|
||||
${ANDROID_HOME}/tools/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
|
||||
fi
|
||||
|
||||
# Only build 1 32 bit and 1 64 bit target during presubmit to cut down build times
|
||||
@@ -65,5 +59,11 @@ if [[ "$TARGET" == "presubmit" ]]; then
|
||||
ANDROID_ABIS="-q arm64-v8a,x86"
|
||||
fi
|
||||
|
||||
# Build the Android sample-gltf-viewer APK during release.
|
||||
BUILD_SAMPLES=
|
||||
if [[ "$TARGET" == "release" ]]; then
|
||||
BUILD_SAMPLES="-k sample-gltf-viewer"
|
||||
fi
|
||||
|
||||
pushd `dirname $0`/../.. > /dev/null
|
||||
./build.sh -p android $ANDROID_ABIS -c $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION} ./build.sh -p android $ANDROID_ABIS -c $BUILD_SAMPLES $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
|
||||
1
build/android/ndk.version
Normal file
1
build/android/ndk.version
Normal file
@@ -0,0 +1 @@
|
||||
22.1.7171670
|
||||
@@ -3,4 +3,12 @@
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
echo "Running workflow $GITHUB_WORKFLOW (event: $GITHUB_EVENT_NAME, action: $GITHUB_ACTION)"
|
||||
CONTINUOUS_INTEGRATION=true
|
||||
|
||||
# Force Java to be Java 11 minimum, it defaults to 8 in GitHub runners for some platforms
|
||||
export JAVA_HOME=${JAVA_HOME_11_X64}
|
||||
java_version=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
|
||||
if [[ "$java_version" < 11 ]]; then
|
||||
echo "Android builds require Java 11, found version ${java_version} instead"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-mac.zip
|
||||
unzip -q ninja-mac.zip
|
||||
chmod +x ninja
|
||||
export PATH="$PWD:$PATH"
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
# version of clang we want to use
|
||||
GITHUB_CLANG_VERSION=8
|
||||
# version of CMake to use instead of the default one
|
||||
CMAKE_VERSION=3.13.4
|
||||
CMAKE_VERSION=3.19.5
|
||||
# version of ninja to use
|
||||
NINJA_VERSION=1.8.2
|
||||
NINJA_VERSION=1.10.2
|
||||
|
||||
# Steps for GitHub Workflows
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-mac.zip
|
||||
unzip -q ninja-mac.zip
|
||||
chmod +x ninja
|
||||
export PATH="$PWD:$PATH"
|
||||
|
||||
@@ -31,7 +31,11 @@ set(DIST_ARCH arm64-v8a)
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
|
||||
file(TO_CMAKE_PATH $ENV{ANDROID_HOME} ANDROID_HOME_UNIX)
|
||||
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/*)
|
||||
if (NOT FILAMENT_NDK_VERSION)
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/android/ndk.version" FILAMENT_NDK_VERSION)
|
||||
string(REGEX MATCH "^\\d+" FILAMENT_NDK_VERSION ${FILAMENT_NDK_VERSION})
|
||||
endif()
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/${FILAMENT_NDK_VERSION}*)
|
||||
list(SORT NDK_VERSIONS)
|
||||
list(GET NDK_VERSIONS -1 NDK_VERSION)
|
||||
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user