Compare commits
261 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a66f85b67 | ||
|
|
3bba92f813 | ||
|
|
93c9674e2a | ||
|
|
a4b879227d | ||
|
|
485dfa6cde | ||
|
|
3105a8330e | ||
|
|
88e8661bf3 | ||
|
|
3a9629d93c | ||
|
|
29c14b1053 | ||
|
|
bd5aeb6b69 | ||
|
|
3674361f20 | ||
|
|
4a29456a7a | ||
|
|
3179a83cfb | ||
|
|
5fe1fe73c4 | ||
|
|
5025d8eb6e | ||
|
|
71697b59a3 | ||
|
|
518ae9658f | ||
|
|
41ad8b5c18 | ||
|
|
51cef3b5ca | ||
|
|
491d16a4e5 | ||
|
|
e752b6fb6f | ||
|
|
46bf6fbfdd | ||
|
|
fd5fe3d18d | ||
|
|
ca2da39614 | ||
|
|
067dad2d38 | ||
|
|
f91a8890a6 | ||
|
|
dd9b84f06e | ||
|
|
9ac17a88b3 | ||
|
|
9ea8148d84 | ||
|
|
16c65550bb | ||
|
|
961860adee | ||
|
|
6146b4d2d9 | ||
|
|
274cd3a1f3 | ||
|
|
762e8b8b6a | ||
|
|
a5a6e9be8a | ||
|
|
4ab65975f4 | ||
|
|
041f26a7c5 | ||
|
|
b351e709c1 | ||
|
|
fbad683810 | ||
|
|
2854c0627d | ||
|
|
c5fa6fe7f2 | ||
|
|
40c7232bb2 | ||
|
|
59e3465b6b | ||
|
|
2c591d2dca | ||
|
|
4673545f45 | ||
|
|
4703a45ff5 | ||
|
|
35aabd5e44 | ||
|
|
118944be9a | ||
|
|
8e1ecbb0ea | ||
|
|
00ba8c09f8 | ||
|
|
15b071acaa | ||
|
|
aa3dfb9a4b | ||
|
|
95e22d878a | ||
|
|
4f8c495563 | ||
|
|
1d6ea1db0f | ||
|
|
393cc5c634 | ||
|
|
34c2772a60 | ||
|
|
4d258ab5e8 | ||
|
|
a306f9074a | ||
|
|
6e30566363 | ||
|
|
2908224c95 | ||
|
|
e011853e7e | ||
|
|
104105c937 | ||
|
|
3fa98419a6 | ||
|
|
44d08ce41e | ||
|
|
0a1c1be00e | ||
|
|
7efd7abffe | ||
|
|
e27158507e | ||
|
|
d9ee2fa10d | ||
|
|
b30a7aa5a2 | ||
|
|
34c1aaac18 | ||
|
|
8dbb4c6b7e | ||
|
|
f5d5afba74 | ||
|
|
e09f0bb99f | ||
|
|
fddf51dc74 | ||
|
|
b8d4b981e0 | ||
|
|
892302442f | ||
|
|
39046ddfe1 | ||
|
|
ac14074bc4 | ||
|
|
7d548151d7 | ||
|
|
898ed70aa0 | ||
|
|
78842b59c9 | ||
|
|
f4f4f9ccd5 | ||
|
|
2ef9d72dbd | ||
|
|
b030f67eb7 | ||
|
|
8380a87a6e | ||
|
|
06b9bb0c34 | ||
|
|
17893ecefd | ||
|
|
efc1b01901 | ||
|
|
88fa93f1de | ||
|
|
36385a2432 | ||
|
|
1e05327c5d | ||
|
|
0b7a08a2d8 | ||
|
|
237e0ee367 | ||
|
|
f9230856af | ||
|
|
9bf9c3a439 | ||
|
|
25c4efd2db | ||
|
|
8f6f0ef511 | ||
|
|
a924fbb490 | ||
|
|
4c01dfc9fd | ||
|
|
5ee15239fd | ||
|
|
69d36b0226 | ||
|
|
87db1aaa57 | ||
|
|
5e096de534 | ||
|
|
97d53bf7e9 | ||
|
|
6fbc690097 | ||
|
|
311f6eacd7 | ||
|
|
0dee8c5f34 | ||
|
|
ddf85bae72 | ||
|
|
695d61f87c | ||
|
|
9584371f89 | ||
|
|
509bfb5b5e | ||
|
|
f853b7dc40 | ||
|
|
0693a97577 | ||
|
|
8e00df1de5 | ||
|
|
28f0536b31 | ||
|
|
639bfbfc9a | ||
|
|
0c734d6db0 | ||
|
|
e0f5b5125c | ||
|
|
28065e36e8 | ||
|
|
8088f0cd6f | ||
|
|
36cdadd238 | ||
|
|
1061d5c5fa | ||
|
|
c1bd438d89 | ||
|
|
dd8c0a759f | ||
|
|
0f16f3177e | ||
|
|
acc2fd9c94 | ||
|
|
8feb842717 | ||
|
|
f19eaaa557 | ||
|
|
3fa0c2d18b | ||
|
|
9393e1369b | ||
|
|
8342b0ecec | ||
|
|
9a291b6543 | ||
|
|
ec403f8940 | ||
|
|
047dab769d | ||
|
|
5d8cd288d3 | ||
|
|
8a63682382 | ||
|
|
036f151a42 | ||
|
|
5bc1356192 | ||
|
|
c04a111d10 | ||
|
|
da5eabc91f | ||
|
|
79f8947bfa | ||
|
|
160a22519e | ||
|
|
cc9a1d446c | ||
|
|
b78ea90c27 | ||
|
|
cbb5d2b423 | ||
|
|
c759743e40 | ||
|
|
3b2ecc6003 | ||
|
|
4790cb5009 | ||
|
|
ee0080487a | ||
|
|
f70b820cbe | ||
|
|
1ccae61d40 | ||
|
|
f670472e55 | ||
|
|
f94aa731ed | ||
|
|
5c80bfe430 | ||
|
|
8d7866b58d | ||
|
|
179bf03caf | ||
|
|
0371a805ed | ||
|
|
57b48e0719 | ||
|
|
eb767abc55 | ||
|
|
dbda77b091 | ||
|
|
2c1454270e | ||
|
|
1ec72e606b | ||
|
|
24bfdd741a | ||
|
|
f0ce4094dd | ||
|
|
9cbcd88d4e | ||
|
|
8ea6e6ce59 | ||
|
|
6d0f8c9ead | ||
|
|
43d91a5c40 | ||
|
|
564e527ac7 | ||
|
|
6d3b733cb1 | ||
|
|
0e967726de | ||
|
|
001a4c46db | ||
|
|
1a9d0926ee | ||
|
|
05a756beaa | ||
|
|
1014847e9d | ||
|
|
d3309c2e84 | ||
|
|
565002a918 | ||
|
|
08b83e7ed1 | ||
|
|
b4c2f523fe | ||
|
|
4ba5d6b9a8 | ||
|
|
59ceb05f99 | ||
|
|
929c8e96c6 | ||
|
|
1b5a730358 | ||
|
|
79255e8e7d | ||
|
|
50845261fe | ||
|
|
da090f0ff6 | ||
|
|
60ead8c5f3 | ||
|
|
6942569409 | ||
|
|
498a608941 | ||
|
|
eee7154c33 | ||
|
|
a735660af8 | ||
|
|
c5ed7172b3 | ||
|
|
4b28362920 | ||
|
|
dfeaa416c0 | ||
|
|
3ce4dd94f7 | ||
|
|
0ee1d406e0 | ||
|
|
dad814e046 | ||
|
|
6246f20e63 | ||
|
|
f4ad55f6d7 | ||
|
|
027c4b42f7 | ||
|
|
fb6c9f8b7d | ||
|
|
33d2eaee5b | ||
|
|
ae3ccd7fb6 | ||
|
|
72dbea256a | ||
|
|
ea0ff1bc01 | ||
|
|
2bca33f535 | ||
|
|
75c5bb846b | ||
|
|
0da551c7fd | ||
|
|
5583dc26f9 | ||
|
|
339fa3bd60 | ||
|
|
dbaaa977e7 | ||
|
|
b10e99d374 | ||
|
|
a7d572f060 | ||
|
|
127234f655 | ||
|
|
2c13c8fe6e | ||
|
|
c0b9900cdc | ||
|
|
44e8d57935 | ||
|
|
d85f8164c0 | ||
|
|
32407c2ba5 | ||
|
|
51e82a5561 | ||
|
|
3fb75ca904 | ||
|
|
64a70c7c18 | ||
|
|
b9a68090b1 | ||
|
|
5344854056 | ||
|
|
abad894fd5 | ||
|
|
8872227af5 | ||
|
|
30a07a49d0 | ||
|
|
0a37cce5fe | ||
|
|
fc76ed9949 | ||
|
|
d55d042a14 | ||
|
|
d7e07f4d51 | ||
|
|
22a6ecadbb | ||
|
|
53ff133b03 | ||
|
|
d1ab68ebfa | ||
|
|
655b7dc13c | ||
|
|
48bfe0453b | ||
|
|
87a05f057a | ||
|
|
4f540fe7fd | ||
|
|
1fd675fd09 | ||
|
|
bf72adbb57 | ||
|
|
dd45703d73 | ||
|
|
7c0d3cdb10 | ||
|
|
5462cc0fcf | ||
|
|
8fe9f15b3b | ||
|
|
c49c6e5d19 | ||
|
|
636c54ec6f | ||
|
|
52ee07f2fd | ||
|
|
02ef4a99b7 | ||
|
|
73a4431a34 | ||
|
|
e252558ef6 | ||
|
|
5680b5d9a6 | ||
|
|
86c0a68ccd | ||
|
|
9379e7ce45 | ||
|
|
04d2234169 | ||
|
|
66f4419518 | ||
|
|
be4ad2ec07 | ||
|
|
853b2205dd | ||
|
|
80f104c522 | ||
|
|
1fa2fd9b7f | ||
|
|
fa108d6a65 |
37
.github/workflows/android-continuous.yml
vendored
Normal file
37
.github/workflows/android-continuous.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: Android
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-android
|
||||
path: out/filament-android-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filamat-android-full
|
||||
path: out/filamat-android-full-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filamat-android-lite
|
||||
path: out/filamat-android-lite-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: gltfio-android-release
|
||||
path: out/gltfio-android-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-utils-android-release
|
||||
path: out/filament-utils-android-release.aar
|
||||
21
.github/workflows/ios-continuous.yml
vendored
Normal file
21
.github/workflows/ios-continuous.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: iOS
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/ios && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-ios
|
||||
path: out/filament-release-ios.tgz
|
||||
21
.github/workflows/linux-continuous.yml
vendored
Normal file
21
.github/workflows/linux-continuous.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Linux
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
name: build-linux
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/linux && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-linux
|
||||
path: out/filament-release-linux.tgz
|
||||
21
.github/workflows/mac-continuous.yml
vendored
Normal file
21
.github/workflows/mac-continuous.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: macOS
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-mac:
|
||||
name: build-mac
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/mac && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-mac
|
||||
path: out/filament-release-darwin.tgz
|
||||
54
.github/workflows/presubmit.yml
vendored
54
.github/workflows/presubmit.yml
vendored
@@ -12,15 +12,7 @@ jobs:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout Filament
|
||||
run: |
|
||||
git version
|
||||
git init $GITHUB_WORKSPACE
|
||||
cd $GITHUB_WORKSPACE
|
||||
git remote add origin https://github.com/google/filament
|
||||
git config gc.auto 0
|
||||
git fetch --tags --prune --progress --no-recurse-submodules origin +${GITHUB_REF}:${GITHUB_REF/refs\//refs\/remote\/}
|
||||
git checkout --progress --force ${GITHUB_REF/refs\//refs\/remote\/}
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
|
||||
@@ -33,34 +25,18 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Filament
|
||||
run: |
|
||||
git version
|
||||
git init %GITHUB_WORKSPACE%
|
||||
cd %GITHUB_WORKSPACE%
|
||||
git remote add origin https://github.com/google/filament
|
||||
git config gc.auto 0
|
||||
git fetch --tags --prune --progress --no-recurse-submodules origin +%GITHUB_REF%:%GITHUB_REF:refs/=refs/remote/%
|
||||
git checkout --progress --force %GITHUB_REF:refs/=refs/remote/%
|
||||
shell: cmd
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
build\windows\build-github.bat
|
||||
build\windows\build-github.bat presubmit
|
||||
shell: cmd
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Filament
|
||||
run: |
|
||||
git version
|
||||
git init $GITHUB_WORKSPACE
|
||||
cd $GITHUB_WORKSPACE
|
||||
git remote add origin https://github.com/google/filament
|
||||
git config gc.auto 0
|
||||
git fetch --tags --prune --progress --no-recurse-submodules origin +${GITHUB_REF}:${GITHUB_REF/refs\//refs\/remote\/}
|
||||
git checkout --progress --force ${GITHUB_REF/refs\//refs\/remote\/}
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && ./build.sh ${TARGET}
|
||||
@@ -72,15 +48,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Filament
|
||||
run: |
|
||||
git version
|
||||
git init $GITHUB_WORKSPACE
|
||||
cd $GITHUB_WORKSPACE
|
||||
git remote add origin https://github.com/google/filament
|
||||
git config gc.auto 0
|
||||
git fetch --tags --prune --progress --no-recurse-submodules origin +${GITHUB_REF}:${GITHUB_REF/refs\//refs\/remote\/}
|
||||
git checkout --progress --force ${GITHUB_REF/refs\//refs\/remote\/}
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/ios && ./build.sh ${TARGET}
|
||||
@@ -92,15 +60,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Filament
|
||||
run: |
|
||||
git version
|
||||
git init $GITHUB_WORKSPACE
|
||||
cd $GITHUB_WORKSPACE
|
||||
git remote add origin https://github.com/google/filament
|
||||
git config gc.auto 0
|
||||
git fetch --tags --prune --progress --no-recurse-submodules origin +${GITHUB_REF}:${GITHUB_REF/refs\//refs\/remote\/}
|
||||
git checkout --progress --force ${GITHUB_REF/refs\//refs\/remote\/}
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && ./build.sh ${TARGET}
|
||||
|
||||
176
.github/workflows/release.yml
vendored
Normal file
176
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
name: Release
|
||||
|
||||
# This Workflow can be triggered two ways:
|
||||
# 1. A GitHub release is created (using the GitHub web UI). This triggers all of the platforms to build and upload assets.
|
||||
# 2. A repository_dispatch API event is sent. This triggers a build for only the platform specified in the dispatch event.
|
||||
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.event.client_payload.release_tag }}
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
build-desktop:
|
||||
name: build-desktop
|
||||
runs-on: ${{ matrix.os }}
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'desktop'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
- uses: actions/checkout@v1.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
|
||||
cd build/$WORKFLOW_OS && ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
if [ -f out/filament-release-darwin.tgz ]; then mv out/filament-release-darwin.tgz out/filament-${DATE}-mac.tgz; fi;
|
||||
if [ -f out/filament-release-linux.tgz ]; then mv out/filament-release-linux.tgz out/filament-${DATE}-linux.tgz; fi;
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'web'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
- uses: actions/checkout@v1.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
mv out/filament-release-web.tgz out/filament-${DATE}-web.tgz
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'android'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
- uses: actions/checkout@v1.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
mv out/filament-android-release.aar out/filament-${DATE}-android.aar
|
||||
mv out/filamat-android-full-release.aar out/filamat-${DATE}-full-android.aar
|
||||
mv out/filamat-android-lite-release.aar out/filamat-${DATE}-lite-android.aar
|
||||
mv out/gltfio-android-release.aar out/gltfio-${DATE}-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${DATE}-android.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'ios'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
- uses: actions/checkout@v1.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/ios && ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
mv out/filament-release-ios.tgz out/filament-${DATE}-ios.tgz
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'windows'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
shell: bash
|
||||
- uses: actions/checkout@v1.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
build\windows\build-github.bat release
|
||||
shell: cmd
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
mv out/filament-windows.tgz out/filament-${DATE}-windows.tgz
|
||||
python build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
shell: bash
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
21
.github/workflows/web-continuous.yml
vendored
Normal file
21
.github/workflows/web-continuous.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Web
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-web
|
||||
path: out/filament-release-web.tgz
|
||||
22
.github/workflows/windows-continuous.yml
vendored
Normal file
22
.github/workflows/windows-continuous.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Windows
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
build\windows\build-github.bat continuous
|
||||
shell: cmd
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-windows
|
||||
path: out/filament-windows.tgz
|
||||
449
BUILDING.md
Normal file
449
BUILDING.md
Normal file
@@ -0,0 +1,449 @@
|
||||
## Building Filament
|
||||
|
||||
### Prerequisites
|
||||
|
||||
To build Filament, you must first install the following tools:
|
||||
|
||||
- CMake 3.10 (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)
|
||||
|
||||
Additional dependencies may be required for your operating system. Please refer to the appropriate
|
||||
section below.
|
||||
|
||||
Building the `rays` library (used for light baking) is optional and requires the following packages:
|
||||
|
||||
- embree 3.0+
|
||||
- libtbb-dev
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio 3.6
|
||||
- Android SDK
|
||||
- Android NDK "side-by-side" 20 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.
|
||||
|
||||
When building for WebGL, you'll also need to set `EMSDK`. See [WebAssembly](#webassembly).
|
||||
|
||||
### IDE
|
||||
|
||||
We recommend using CLion to develop for Filament. Simply open the root directory's CMakeLists.txt
|
||||
in CLion to obtain a usable project.
|
||||
|
||||
### Easy build
|
||||
|
||||
Once the required OS specific dependencies listed below are installed, you can use the script
|
||||
located in `build.sh` to build Filament easily on macOS and Linux.
|
||||
|
||||
This script can be invoked from anywhere and will produce build artifacts in the `out/` directory
|
||||
inside the Filament source tree.
|
||||
|
||||
To trigger an incremental debug build:
|
||||
|
||||
```
|
||||
$ ./build.sh debug
|
||||
```
|
||||
|
||||
To trigger an incremental release build:
|
||||
|
||||
```
|
||||
$ ./build.sh release
|
||||
```
|
||||
|
||||
To trigger both incremental debug and release builds:
|
||||
|
||||
```
|
||||
$ ./build.sh debug release
|
||||
```
|
||||
|
||||
To install the libraries and executables in `out/debug/` and `out/release/`, add the `-i` flag.
|
||||
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 `-DENABLE_JAVA=OFF` to CMake instead.
|
||||
|
||||
### Filament-specific CMake Options
|
||||
|
||||
The following CMake options are boolean options specific to Filament:
|
||||
|
||||
- `ENABLE_JAVA`: Compile Java projects: requires a JDK and the JAVA_HOME env var
|
||||
- `ENABLE_LTO`: Enable link-time optimizations if supported by the compiler
|
||||
- `FILAMENT_BUILD_FILAMAT`: Build filamat and JNI buildings
|
||||
- `FILAMENT_SUPPORTS_METAL`: Include the Metal backend
|
||||
- `FILAMENT_SUPPORTS_VULKAN`: Include the Vulkan backend
|
||||
- `GENERATE_JS_DOCS`: Build WebGL documentation and tutorials
|
||||
- `INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
|
||||
- `USE_EXTERNAL_GLES3`: Experimental: Compile Filament against OpenGL ES 3
|
||||
|
||||
To turn an option on or off:
|
||||
|
||||
```
|
||||
$ cd <cmake-build-directory>
|
||||
$ cmake . -DOPTION=ON # Relace OPTION with the option name, set to ON / OFF
|
||||
```
|
||||
|
||||
Options can also be set with the CMake GUI.
|
||||
|
||||
### Linux
|
||||
|
||||
Make sure you've installed the following dependencies:
|
||||
|
||||
- `clang-7` or higher
|
||||
- `libglu1-mesa-dev`
|
||||
- `libc++-7-dev` (`libcxx-devel` and `libcxx-static` on Fedora) or higher
|
||||
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora) or higher
|
||||
- `ninja-build`
|
||||
- `libxi-dev`
|
||||
|
||||
After dependencies have been installed, we highly recommend using the [easy build](#easy-build)
|
||||
script.
|
||||
|
||||
If you'd like to run `cmake` directly rather than using the build script, it can be invoked as
|
||||
follows, with some caveats that are explained further down.
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
Your Linux distribution might default to `gcc` instead of `clang`, if that's the case invoke
|
||||
`cmake` with the following command:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
# Or use a specific version of clang, for instance /usr/bin/clang-7
|
||||
$ CC=/usr/bin/clang CXX=/usr/bin/clang++ CXXFLAGS=-stdlib=libc++ \
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
You can also export the `CC` and `CXX` environment variables to always point to `clang`. Another
|
||||
solution is to use `update-alternatives` to both change the default compiler, and point to a
|
||||
specific version of clang:
|
||||
|
||||
```
|
||||
$ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100
|
||||
$ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100
|
||||
$ update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100
|
||||
$ update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
|
||||
```
|
||||
|
||||
Finally, invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja
|
||||
```
|
||||
|
||||
This will build Filament, its tests and samples, and various host tools.
|
||||
|
||||
### macOS
|
||||
|
||||
To compile Filament you must have the most recent version of Xcode installed and you need to
|
||||
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:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
$ ninja
|
||||
```
|
||||
|
||||
### iOS
|
||||
|
||||
The easiest way to build Filament for iOS is to use `build.sh` and the
|
||||
`-p ios` flag. For instance to build the debug target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p ios debug
|
||||
```
|
||||
|
||||
See [ios/samples/README.md](./ios/samples/README.md) for more information.
|
||||
|
||||
### Windows
|
||||
|
||||
#### Building on Windows with Visual Studio 2019
|
||||
|
||||
Install the following components:
|
||||
|
||||
- [Visual Studio 2019](https://www.visualstudio.com/downloads)
|
||||
- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
|
||||
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
|
||||
- [CMake 3.14 or later](https://github.com/Kitware/CMake/releases/download/v3.14.7/cmake-3.14.7-win64-x64.msi)
|
||||
|
||||
The latest Windows SDK can also by installed by opening Visual Studio and selecting _Get Tools and
|
||||
Features..._ under the _Tools_ menu.
|
||||
|
||||
Open the `x64 Native Tools Command Prompt for VS 2019`.
|
||||
|
||||
Create a working directory, and run cmake in it:
|
||||
|
||||
```
|
||||
> mkdir out
|
||||
> cd out
|
||||
> cmake ..
|
||||
```
|
||||
|
||||
Open the generated solution file `TNT.sln` in Visual Studio.
|
||||
|
||||
To build all targets, run _Build Solution_ from the _Build_ menu. Alternatively, right click on a
|
||||
target in the _Solution Explorer_ and choose _Build_ to build a specific target.
|
||||
|
||||
For example, build the `material_sandbox` sample and run it from the `out` directory with:
|
||||
|
||||
```
|
||||
> samples\Debug\material_sandbox.exe ..\assets\models\monkey\monkey.obj
|
||||
```
|
||||
|
||||
### Android
|
||||
|
||||
Before building Filament for Android, make sure to build Filament for your host. Some of the
|
||||
host tools are required to successfully build for Android.
|
||||
|
||||
Filament can be built for the following architectures:
|
||||
|
||||
- ARM 64-bit (`arm64-v8a`)
|
||||
- ARM 32-bit (`armeabi-v7a`)
|
||||
- Intel 64-bit (`x86_64`)
|
||||
- Intel 32-bit (`x86`)
|
||||
|
||||
Note that the main target is the ARM 64-bit target. Our implementation is optimized first and
|
||||
foremost for `arm64-v8a`.
|
||||
|
||||
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
|
||||
|
||||
#### Easy Android build
|
||||
|
||||
The easiest way to build Filament for Android is to use `build.sh` and the
|
||||
`-p android` flag. For instance to build the release target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p android release
|
||||
```
|
||||
|
||||
Run `build.sh -h` for more information.
|
||||
|
||||
#### Manual builds
|
||||
|
||||
Invoke CMake in a build directory of your choice, inside of filament's directory. The commands
|
||||
below show how to build Filament for ARM 64-bit (`aarch64`).
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-aarch64
|
||||
$ cd out/android-build-release-aarch64
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-aarch64-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
|
||||
|
||||
#### AAR
|
||||
|
||||
Before you attempt to build the AAR, make sure you've compiled and installed the native libraries
|
||||
as explained in the sections above. You must have the following ABIs built in
|
||||
`out/android-release/filament/lib/`:
|
||||
|
||||
- `arm64-v8a`
|
||||
- `armeabi-v7a`
|
||||
- `x86_64`
|
||||
- `x86`
|
||||
|
||||
To build Filament's AAR simply open the Android Studio project in `android/`. The
|
||||
AAR is a universal AAR that contains all supported build targets:
|
||||
|
||||
- `arm64-v8a`
|
||||
- `armeabi-v7a`
|
||||
- `x86_64`
|
||||
- `x86`
|
||||
|
||||
To filter out unneeded ABIs, rely on the `abiFilters` of the project that links against Filament's
|
||||
AAR.
|
||||
|
||||
Alternatively you can build the AAR from the command line by executing the following in the
|
||||
`android/` directory:
|
||||
|
||||
```
|
||||
$ ./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease
|
||||
```
|
||||
|
||||
The `-Pfilament_dist_dir` can be used to specify a different installation directory (it must match
|
||||
the CMake install prefix used in the previous steps).
|
||||
|
||||
#### Using Filament's AAR
|
||||
|
||||
Create a new module in your project and select _Import .JAR or .AAR Package_ when prompted. Make
|
||||
sure to add the newly created module as a dependency to your application.
|
||||
|
||||
If you do not wish to include all supported ABIs, make sure to create the appropriate flavors in
|
||||
your Gradle build file. For example:
|
||||
|
||||
```
|
||||
flavorDimensions 'cpuArch'
|
||||
productFlavors {
|
||||
arm8 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'arm64-v8a'
|
||||
}
|
||||
}
|
||||
arm7 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a'
|
||||
}
|
||||
}
|
||||
x86_64 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86_64'.
|
||||
}
|
||||
}
|
||||
x86 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86'
|
||||
}
|
||||
}
|
||||
universal {
|
||||
dimension 'cpuArch'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### WebAssembly
|
||||
|
||||
The core Filament library can be cross-compiled to WebAssembly from either macOS or Linux. To get
|
||||
started, follow the instructions for building Filament on your platform ([macOS](#macos) or
|
||||
[linux](#linux)), which will ensure you have the proper dependencies installed.
|
||||
|
||||
Next, you need to install the Emscripten SDK. The following instructions show how to install the
|
||||
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/1b1f08f.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
python ./emsdk.py install latest
|
||||
python ./emsdk.py activate latest
|
||||
source ./emsdk_env.sh
|
||||
```
|
||||
|
||||
After this you can invoke the [easy build](#easy-build) script as follows:
|
||||
|
||||
```
|
||||
export EMSDK=<your chosen home for the emscripten SDK>
|
||||
./build.sh -p webgl release
|
||||
```
|
||||
|
||||
The EMSDK variable is required so that the build script can find the Emscripten SDK. The build
|
||||
creates a `samples` folder that can be used as the root of a simple static web server. Note that you
|
||||
cannot open the HTML directly from the filesystem due to CORS. One way to deal with this is to
|
||||
use Python to create a quick localhost server:
|
||||
|
||||
```
|
||||
cd out/cmake-webgl-release/web/samples
|
||||
python3 -m http.server # Python 3
|
||||
python -m SimpleHTTPServer # Python 2.7
|
||||
```
|
||||
|
||||
You can then open http://localhost:8000/suzanne.html in your web browser.
|
||||
|
||||
Alternatively, if you have node installed you can use the
|
||||
[live-server](https://www.npmjs.com/package/live-server) package, which automatically refreshes the
|
||||
web page when it detects a change.
|
||||
|
||||
Each sample app has its own handwritten html file. Additionally the server folder contains assets
|
||||
such as meshes, textures, and materials.
|
||||
|
||||
## Running the native samples
|
||||
|
||||
The `samples/` directory contains several examples of how to use Filament with SDL2.
|
||||
|
||||
Some of the samples accept FBX/OBJ meshes while others rely on the `filamesh` file format. To
|
||||
generate a `filamesh ` file from an FBX/OBJ asset, run the `filamesh` tool
|
||||
(`./tools/filamesh/filamesh` in your build directory):
|
||||
|
||||
```
|
||||
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:
|
||||
|
||||
```
|
||||
cmgen -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
|
||||
file. The environment map can be an equirectangular projection, a horizontal cross, a vertical
|
||||
cross, or a list of cubemap faces (horizontal or vertical).
|
||||
|
||||
`cmgen` will automatically create a directory based on the name of the source environment map. In
|
||||
the example above, the final directory will be `./ibls/my_ibl/`. This directory should contain the
|
||||
pre-filtered environment map (one file per cubemap face and per mip level), the environment map
|
||||
texture for the skybox and a text file containing the level harmonics for indirect diffuse
|
||||
lighting.
|
||||
|
||||
If you prefer a blurred background, run `cmgen` with this flag: `--extract-blur=0.1`. The numerical
|
||||
value is the desired roughness between 0 and 1.
|
||||
|
||||
## Generating C++ documentation
|
||||
|
||||
To generate the documentation you must first install `doxygen` and `graphviz`, then run the
|
||||
following commands:
|
||||
|
||||
```
|
||||
$ cd filament/filament
|
||||
$ doxygen docs/doxygen/filament.doxygen
|
||||
```
|
||||
|
||||
Finally simply open `docs/html/index.html` in your web browser.
|
||||
@@ -50,22 +50,19 @@ if (WIN32)
|
||||
set(CRT_FLAGS_DEBUG "/MDd")
|
||||
endif()
|
||||
|
||||
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# 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")
|
||||
|
||||
# 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")
|
||||
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")
|
||||
|
||||
# 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")
|
||||
|
||||
# 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")
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
@@ -211,6 +208,13 @@ if (ANDROID OR WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
|
||||
endif()
|
||||
|
||||
# With WebGL, we disable RTTI even for debug builds because we pass emscripten::val back and forth
|
||||
# between C++ and JavaScript in order to efficiently access typed arrays, which are unbound.
|
||||
# NOTE: This is not documented in emscripten so we should consider a different approach.
|
||||
if (WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-rtti")
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Debug compiler flags
|
||||
# ==================================================================================================
|
||||
@@ -219,16 +223,24 @@ endif()
|
||||
# -fsanitize=address causes a crash with assimp, which we can't explain for now
|
||||
#set(EXTRA_SANITIZE_OPTIONS "-fsanitize=undefined -fsanitize=address")
|
||||
# clang-cl.exe on Windows does not support -fstack-protector.
|
||||
if (NOT CLANG_CL AND NOT MSVC)
|
||||
if (NOT CLANG_CL AND NOT MSVC AND NOT WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
|
||||
|
||||
# Disable the stack check for macOS to workaround a known issue in clang 11.0.0.
|
||||
# See: https://forums.developer.apple.com/thread/121887
|
||||
if (APPLE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-stack-check")
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Linker flags
|
||||
# ==================================================================================================
|
||||
# Strip unused sections
|
||||
set(GC_SECTIONS "-Wl,--gc-sections")
|
||||
if (NOT WEBGL)
|
||||
set(GC_SECTIONS "-Wl,--gc-sections")
|
||||
endif()
|
||||
set(B_SYMBOLIC_FUNCTIONS "-Wl,-Bsymbolic-functions")
|
||||
|
||||
if (APPLE)
|
||||
@@ -443,6 +455,7 @@ endfunction()
|
||||
|
||||
# Common to all platforms
|
||||
add_subdirectory(${EXTERNAL}/libgtest/tnt)
|
||||
add_subdirectory(${LIBRARIES}/camutils)
|
||||
add_subdirectory(${LIBRARIES}/filabridge)
|
||||
add_subdirectory(${LIBRARIES}/filaflat)
|
||||
add_subdirectory(${LIBRARIES}/filameshio)
|
||||
|
||||
@@ -40,3 +40,18 @@ information on using pull requests.
|
||||
|
||||
This project follows
|
||||
[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/).
|
||||
|
||||
## Dependencies
|
||||
|
||||
One of our design goals is that Filament itself should have no dependencies or as few dependencies
|
||||
as possible. The current external dependencies of the runtime library include:
|
||||
|
||||
- STL
|
||||
- robin-map (header only library)
|
||||
|
||||
When building with Vulkan enabled, we have a few additional small dependencies:
|
||||
|
||||
- vkmemalloc
|
||||
- smol-v
|
||||
|
||||
Host tools (such as `matc` or `cmgen`) can use external dependencies freely.
|
||||
|
||||
839
README.md
839
README.md
@@ -1,28 +1,59 @@
|
||||
# Filament
|
||||
|
||||
<img alt="Android" src="build/img/android.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_android.html)
|
||||
<img alt="iOS" src="build/img/macos.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_ios.html)
|
||||
<img alt="Linux" src="build/img/linux.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_linux.html)
|
||||
<img alt="macOS" src="build/img/macos.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_mac.html)
|
||||
<img alt="Windows" src="build/img/windows.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_windows.html)
|
||||
<img alt="Web" src="build/img/web.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_web.html)
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows,
|
||||
and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
|
||||
|
||||
Filament is currently used in the
|
||||
[Sceneform](https://developers.google.com/ar/develop/java/sceneform/) library both at runtime on
|
||||
Android devices and as the renderer inside the Android Studio plugin.
|
||||
|
||||
## Download
|
||||
|
||||
[Download Filament releases](https://github.com/google/filament/releases) to access stable builds.
|
||||
Filament release archives contains host-side tools that are required to generate assets.
|
||||
|
||||
Make sure you always use tools from the same release as the runtime library. This is particularly
|
||||
important for `matc` (material compiler).
|
||||
|
||||
If you prefer to live on the edge, you can download a continuous build by clicking one of the build
|
||||
badges above.
|
||||
If you'd rather build Filament yourself, please refer to our [build manual](BUILDING.md).
|
||||
|
||||
### Android
|
||||
|
||||
Android projects can simply declare Filament libraries as Maven dependencies:
|
||||
|
||||
```gradle
|
||||
repositories {
|
||||
// ...
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.4.4'
|
||||
}
|
||||
```
|
||||
|
||||
Here are all the libraries available in the group `com.google.android.filament`:
|
||||
|
||||
- `filament-android`: the Filament rendering engine itself
|
||||
- `gltfio-android`: a glTF 2.0 loader for Filament, depends on `filament-android`
|
||||
- `filament-utils-android`: KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`
|
||||
- `filamat-android-full`: a runtime material builder/compiler. This library is large but contains
|
||||
a full shader compiler/validator/optimizer
|
||||
- `filamat-android-lite`: a much smaller alternative to `filamat-android-full` that can only
|
||||
generate OpenGL shaders. It does not provide validation or optimizations
|
||||
|
||||
### Snapshots
|
||||
|
||||
If you prefer to live on the edge, you can download a continuous build by following the following
|
||||
steps:
|
||||
|
||||
1. Find the [commit](https://github.com/google/filament/commits/master) you're interested in.
|
||||
2. Click the green check mark under the commit message.
|
||||
3. Click on the _Details_ link for the platform you're interested in.
|
||||
4. On the top right, click on the _Artifacts_ dropdown and choose an artifact.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -36,7 +67,9 @@ badges above.
|
||||
- [Material Properties](https://google.github.io/filament/Material%20Properties.pdf), a reference
|
||||
sheet for the standard material model.
|
||||
|
||||
## Samples
|
||||
## Examples
|
||||
|
||||
### Materials
|
||||
|
||||
Here are a few sample materials rendered with Filament:
|
||||
|
||||
@@ -48,15 +81,15 @@ Here are a few sample materials rendered with Filament:
|
||||

|
||||

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

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

|
||||
|
||||
@@ -73,7 +106,7 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- OpenGL 4.1+ for Linux, macOS and Windows
|
||||
- OpenGL ES 3.0+ for Android and iOS
|
||||
- Metal for macOS and iOS
|
||||
- Vulkan 1.0 for Android, Linux, macOS and iOS (with MoltenVk), and Windows
|
||||
- Vulkan 1.0 for Android, Linux, macOS, and Windows
|
||||
- WebGL 2.0 for all platforms
|
||||
|
||||
### Rendering
|
||||
@@ -98,695 +131,6 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- FXAA, MSAA and specular anti-aliasing
|
||||
- Dynamic resolution (on Android and iOS)
|
||||
|
||||
### Future
|
||||
|
||||
Many other features have been either prototyped or planned:
|
||||
|
||||
- IES light profiles/cookies
|
||||
- Area lights
|
||||
- Fog
|
||||
- Color grading
|
||||
- Bloom
|
||||
- TAA
|
||||
- etc.
|
||||
|
||||
## Directory structure
|
||||
|
||||
This repository not only contains the core Filament engine, but also its supporting libraries
|
||||
and tools.
|
||||
|
||||
- `android`: Android libraries and projects
|
||||
- `build`: Custom Gradle tasks for Android builds
|
||||
- `filamat-android`: Filament material generation library (AAR) for Android
|
||||
- `filament-android`: Filament library (AAR) for Android
|
||||
- `samples`: Android-specific Filament samples
|
||||
- `art`: Source for various artworks (logos, PDF manuals, etc.)
|
||||
- `assets`: 3D assets to use with sample applications
|
||||
- `build`: CMake build scripts
|
||||
- `docs`: Documentation
|
||||
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
|
||||
- `filament`: Filament rendering engine (minimal dependencies)
|
||||
- `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
|
||||
- `filabridge`: Library shared by the Filament engine and host tools
|
||||
- `filaflat`: Serialization/deserialization library used for materials
|
||||
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
|
||||
- `filamat`: Material generation library
|
||||
- `filameshio`: Tiny filamesh parsing library (see also `tools/filamesh`)
|
||||
- `geometry`: Mesh-related utilities
|
||||
- `gltfio`: Loader and optional pipeline for glTF 2.0
|
||||
- `ibl`: IBL generation tools
|
||||
- `image`: Image filtering and simple transforms
|
||||
- `imageio`: Image file reading / writing, only intended for internal use
|
||||
- `matdbg`: DebugServer for inspecting shaders at run-time (debug builds only)
|
||||
- `math`: Math library
|
||||
- `rays`: Simple path tracer used for baking ambient occlusion, etc.
|
||||
- `utils`: Utility library (threads, memory, data structures, etc.)
|
||||
- `samples`: Sample desktop applications
|
||||
- `shaders`: Shaders used by `filamat` and `matc`
|
||||
- `third_party`: External libraries and assets
|
||||
- `environments`: Environment maps under CC0 license that can be used with `cmgen`
|
||||
- `models`: Models under permissive licenses
|
||||
- `textures`: Textures under CC0 license
|
||||
- `tools`: Host tools
|
||||
- `cmgen`: Image-based lighting asset generator
|
||||
- `filamesh`: Mesh converter
|
||||
- `glslminifier`: Minifies GLSL source code
|
||||
- `matc`: Material compiler
|
||||
- `matinfo` Displays information about materials compiled with `matc`
|
||||
- `mipgen` Generates a series of miplevels from a source image
|
||||
- `normal-blending`: Tool to blend normal maps
|
||||
- `resgen` Aggregates binary blobs into embeddable resources
|
||||
- `roughness-prefilter`: Pre-filters a roughness map from a normal map to reduce aliasing
|
||||
- `skygen`: Physically-based sky environment texture generator
|
||||
- `specular-color`: Computes the specular color of conductors based on spectral data
|
||||
- `web`: JavaScript bindings, documentation, and samples
|
||||
|
||||
## Building Filament
|
||||
|
||||
### Prerequisites
|
||||
|
||||
To build Filament, you must first install the following tools:
|
||||
|
||||
- CMake 3.10 (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)
|
||||
|
||||
Additional dependencies may be required for your operating system. Please refer to the appropriate
|
||||
section below.
|
||||
|
||||
Building the `rays` library (used for light baking) is optional and requires the following packages:
|
||||
|
||||
- embree 3.0+
|
||||
- libtbb-dev
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio 3.5
|
||||
- Android SDK
|
||||
- Android NDK "side-by-side" 20 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.
|
||||
|
||||
When building for WebGL, you'll also need to set `EMSDK`. See [WebAssembly](#webassembly).
|
||||
|
||||
### IDE
|
||||
|
||||
We recommend using CLion to develop for Filament. Simply open the root directory's CMakeLists.txt
|
||||
in CLion to obtain a usable project.
|
||||
|
||||
### Easy build
|
||||
|
||||
Once the required OS specific dependencies listed below are installed, you can use the script
|
||||
located in `build.sh` to build Filament easily on macOS and Linux.
|
||||
|
||||
This script can be invoked from anywhere and will produce build artifacts in the `out/` directory
|
||||
inside the Filament source tree.
|
||||
|
||||
To trigger an incremental debug build:
|
||||
|
||||
```
|
||||
$ ./build.sh debug
|
||||
```
|
||||
|
||||
To trigger an incremental release build:
|
||||
|
||||
```
|
||||
$ ./build.sh release
|
||||
```
|
||||
|
||||
To trigger both incremental debug and release builds:
|
||||
|
||||
```
|
||||
$ ./build.sh debug release
|
||||
```
|
||||
|
||||
To install the libraries and executables in `out/debug/` and `out/release/`, add the `-i` flag.
|
||||
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 `-DENABLE_JAVA=OFF` to CMake instead.
|
||||
|
||||
### Filament-specific CMake Options
|
||||
|
||||
The following CMake options are boolean options specific to Filament:
|
||||
|
||||
- `ENABLE_JAVA`: Compile Java projects: requires a JDK and the JAVA_HOME env var
|
||||
- `ENABLE_LTO`: Enable link-time optimizations if supported by the compiler
|
||||
- `FILAMENT_BUILD_FILAMAT`: Build filamat and JNI buildings
|
||||
- `FILAMENT_SUPPORTS_METAL`: Include the Metal backend
|
||||
- `FILAMENT_SUPPORTS_VULKAN`: Include the Vulkan backend
|
||||
- `GENERATE_JS_DOCS`: Build WebGL documentation and tutorials
|
||||
- `INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
|
||||
- `USE_EXTERNAL_GLES3`: Experimental: Compile Filament against OpenGL ES 3
|
||||
|
||||
To turn an option on or off:
|
||||
|
||||
```
|
||||
$ cd <cmake-build-directory>
|
||||
$ cmake . -DOPTION=ON # Relace OPTION with the option name, set to ON / OFF
|
||||
```
|
||||
|
||||
Options can also be set with the CMake GUI.
|
||||
|
||||
### Linux
|
||||
|
||||
Make sure you've installed the following dependencies:
|
||||
|
||||
- `clang-7` or higher
|
||||
- `libglu1-mesa-dev`
|
||||
- `libc++-7-dev` (`libcxx-devel` and `libcxx-static` on Fedora) or higher
|
||||
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora) or higher
|
||||
- `ninja-build`
|
||||
- `libxi-dev`
|
||||
|
||||
After dependencies have been installed, we highly recommend using the [easy build](#easy-build)
|
||||
script.
|
||||
|
||||
If you'd like to run `cmake` directly rather than using the build script, it can be invoked as
|
||||
follows, with some caveats that are explained further down.
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
Your Linux distribution might default to `gcc` instead of `clang`, if that's the case invoke
|
||||
`cmake` with the following command:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
# Or use a specific version of clang, for instance /usr/bin/clang-7
|
||||
$ CC=/usr/bin/clang CXX=/usr/bin/clang++ CXXFLAGS=-stdlib=libc++ \
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
You can also export the `CC` and `CXX` environment variables to always point to `clang`. Another
|
||||
solution is to use `update-alternatives` to both change the default compiler, and point to a
|
||||
specific version of clang:
|
||||
|
||||
```
|
||||
$ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100
|
||||
$ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100
|
||||
$ update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100
|
||||
$ update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
|
||||
```
|
||||
|
||||
Finally, invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja
|
||||
```
|
||||
|
||||
This will build Filament, its tests and samples, and various host tools.
|
||||
|
||||
### macOS
|
||||
|
||||
To compile Filament you must have the most recent version of Xcode installed and you need to
|
||||
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:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
$ ninja
|
||||
```
|
||||
|
||||
### iOS
|
||||
|
||||
The easiest way to build Filament for iOS is to use `build.sh` and the
|
||||
`-p ios` flag. For instance to build the debug target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p ios debug
|
||||
```
|
||||
|
||||
See [ios/samples/README.md](./ios/samples/README.md) for more information.
|
||||
|
||||
### Windows
|
||||
|
||||
#### Building on Windows with the Visual Studio 2019 compiler
|
||||
|
||||
Install the following components:
|
||||
|
||||
- [Visual Studio 2019](https://www.visualstudio.com/downloads)
|
||||
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
|
||||
- [CMake 3.14 or later](https://github.com/Kitware/CMake/releases/download/v3.14.7/cmake-3.14.7-win64-x64.msi)
|
||||
|
||||
Open the `x64 Native Tools Command Prompt for VS 2019`.
|
||||
|
||||
Create a working directory, and run cmake in it:
|
||||
|
||||
```
|
||||
> mkdir out
|
||||
> cd out
|
||||
> cmake ..
|
||||
```
|
||||
|
||||
Then, you should be able to load the generated solution file `TNT.sln` in Visual Studio and build the `material_sandbox` project.
|
||||
|
||||
Run it from the `out` directory with:
|
||||
```
|
||||
> samples\Debug\material_sandbox.exe ..\assets\models\monkey\monkey.obj
|
||||
```
|
||||
|
||||
#### Building on Windows with the Clang compiler
|
||||
|
||||
The following instructions have been tested on a machine running Windows 10. They should take you
|
||||
from a machine with only the operating system to a machine able to build and run Filament.
|
||||
|
||||
Google employees require additional steps which can be found here [go/filawin](http://go/filawin).
|
||||
|
||||
Install the following components:
|
||||
|
||||
- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
|
||||
- [Visual Studio 2015 or 2017](https://www.visualstudio.com/downloads)
|
||||
- [Clang 7](http://releases.llvm.org/download.html)
|
||||
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
|
||||
- [Cmake 3.13 or later](https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-win64-x64.msi)
|
||||
|
||||
If you're using Visual Studio 2017, you'll also need to install the [LLVM Compiler
|
||||
Toolchain](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.llvm-toolchain)
|
||||
extension.
|
||||
|
||||
Open an appropriate Native Tools terminal for the version of Visual Studio you are using:
|
||||
- VS 2015: VS2015 x64 Native Tools Command Prompt
|
||||
- VS 2017: x64 Native Tools Command Prompt for VS 2017
|
||||
|
||||
You can find these by clicking the start button and typing "x64 native tools".
|
||||
|
||||
Create a working directory:
|
||||
```
|
||||
> mkdir out/cmake-release
|
||||
> cd out/cmake-release
|
||||
```
|
||||
|
||||
Create the msBuild project:
|
||||
```
|
||||
# Visual Studio 2015:
|
||||
> cmake -T"LLVM-vs2014" -G "Visual Studio 14 2015 Win64" ../..
|
||||
|
||||
# Visual Studio 2017
|
||||
> cmake ..\.. -T"LLVM" -G "Visual Studio 15 2017 Win64" ^
|
||||
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe"
|
||||
```
|
||||
|
||||
Check out the output and make sure Clang for Windows frontend was found. You should see a line
|
||||
showing the following output. Note that for Visual Studio 2017 this line may list Microsoft's
|
||||
compiler, but the build will still in fact use Clang and you can proceed.
|
||||
|
||||
```
|
||||
Clang:C:/Program Files/LLVM/msbuild-bin/cl.exe
|
||||
```
|
||||
|
||||
You are now ready to build:
|
||||
```
|
||||
> msbuild TNT.sln /t:material_sandbox /m /p:configuration=Release
|
||||
```
|
||||
|
||||
Run it:
|
||||
```
|
||||
> samples\Release\material_sandbox.exe ..\..\assets\models\monkey\monkey.obj
|
||||
```
|
||||
|
||||
#### Tips
|
||||
|
||||
- To troubleshoot an issue, use verbose mode via `/v:d` flag.
|
||||
- To build a specific project, use `/t:NAME` flag (e.g: `/t:material_sandbox`).
|
||||
- To build using more than one core, use parallel build flag: `/m`.
|
||||
- To build a specific profile, use `/p:configuration=` (e.g: `/p:configuration=Debug`,
|
||||
`/p:configuration=Release`, and `/p:configuration=RelWithDebInfo`).
|
||||
- The msBuild project is what is used by Visual Studio behind the scene to build. Building from VS
|
||||
or from the command-line is the same thing.
|
||||
|
||||
#### Building with Ninja on Windows
|
||||
|
||||
Alternatively, you can use [Ninja](https://ninja-build.org/) to build for Windows. An MSVC
|
||||
installation is still necessary.
|
||||
|
||||
First, install the dependencies listed under [Windows](#Windows) as well as Ninja. Then open up a
|
||||
Native Tools terminal as before. Create a build directory inside Filament and run the
|
||||
following CMake command:
|
||||
|
||||
```
|
||||
> cmake .. -G Ninja ^
|
||||
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe" ^
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
```
|
||||
|
||||
You should then be able to build by invoking Ninja:
|
||||
|
||||
```
|
||||
> ninja
|
||||
```
|
||||
|
||||
#### Development tips
|
||||
|
||||
- Before shipping a binary, make sure you used Release profile and make sure you have no libc/libc++
|
||||
dependencies with [Dependency Walker](http://www.dependencywalker.com).
|
||||
- Application Verifier and gflags.exe can be of great help to trackdown heap corruption. Application
|
||||
Verifier is easy to setup with a GUI. For gflags, use: `gflags /p /enable pheap-buggy.exe`.
|
||||
|
||||
#### Running a simple test
|
||||
|
||||
To confirm Filament was properly built, run the following command from the build directory:
|
||||
|
||||
```
|
||||
> samples\material_sandbox.exe --ibl=..\..\samples\envs\pillars ..\..\assets\models\sphere\sphere.obj
|
||||
```
|
||||
|
||||
### Android
|
||||
|
||||
Before building Filament for Android, make sure to build Filament for your host. Some of the
|
||||
host tools are required to successfully build for Android.
|
||||
|
||||
Filament can be built for the following architectures:
|
||||
|
||||
- ARM 64-bit (`arm64-v8a`)
|
||||
- ARM 32-bit (`armeabi-v7a`)
|
||||
- Intel 64-bit (`x86_64`)
|
||||
- Intel 32-bit (`x86`)
|
||||
|
||||
Note that the main target is the ARM 64-bit target. Our implementation is optimized first and
|
||||
foremost for `arm64-v8a`.
|
||||
|
||||
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
|
||||
|
||||
#### Easy Android build
|
||||
|
||||
The easiest way to build Filament for Android is to use `build.sh` and the
|
||||
`-p android` flag. For instance to build the release target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p android release
|
||||
```
|
||||
|
||||
Run `build.sh -h` for more information.
|
||||
|
||||
#### ARM 64-bit target (arm64-v8a)
|
||||
|
||||
Then invoke CMake in a build directory of your choice, inside of filament's directory:
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-aarch64
|
||||
$ cd out/android-build-release-aarch64
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-aarch64-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
|
||||
|
||||
#### ARM 32-bit target (armeabi-v7a)
|
||||
|
||||
Then invoke CMake in a build directory of your choice, inside of filament's directory:
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-arm
|
||||
$ cd out/android-build-release-arm
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-arm7-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/armeabi-v7a`.
|
||||
|
||||
#### Intel 64-bit target (x86_64)
|
||||
|
||||
Then invoke CMake in a build directory of your choice, sibling of filament's directory:
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-x86_64
|
||||
$ cd out/android-build-release-x86_64
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../filament/build/toolchain-x86_64-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../out/android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/x86_64`.
|
||||
|
||||
#### Intel 32-bit target (x86)
|
||||
|
||||
Then invoke CMake in a build directory of your choice, sibling of filament's directory:
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-x86
|
||||
$ cd out/android-build-release-x86
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../filament/build/toolchain-x86-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../out/android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/x86`.
|
||||
|
||||
### AAR
|
||||
|
||||
Before you attempt to build the AAR, make sure you've compiled and installed the native libraries
|
||||
as explained in the sections above. You must have the following ABIs built in
|
||||
`out/android-release/filament/lib/`:
|
||||
|
||||
- `arm64-v8a`
|
||||
- `armeabi-v7a`
|
||||
- `x86_64`
|
||||
- `x86`
|
||||
|
||||
To build Filament's AAR simply open the Android Studio project in `android/filament-android`. The
|
||||
AAR is a universal AAR that contains all supported build targets:
|
||||
|
||||
- `arm64-v8a`
|
||||
- `armeabi-v7a`
|
||||
- `x86_64`
|
||||
- `x86`
|
||||
|
||||
To filter out unneeded ABIs, rely on the `abiFilters` of the project that links against Filament's
|
||||
AAR.
|
||||
|
||||
Alternatively you can build the AAR from the command line by executing the following the
|
||||
`android/filament-android` directory:
|
||||
|
||||
```
|
||||
$ ./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease
|
||||
```
|
||||
|
||||
The `-Pfilament_dist_dir` can be used to specify a different installation directory (it must match
|
||||
the CMake install prefix used in the previous steps).
|
||||
|
||||
### Using Filament's AAR
|
||||
|
||||
Create a new module in your project and select _Import .JAR or .AAR Package_ when prompted. Make
|
||||
sure to add the newly created module as a dependency to your application.
|
||||
|
||||
If you do not wish to include all supported ABIs, make sure to create the appropriate flavors in
|
||||
your Gradle build file. For example:
|
||||
|
||||
```
|
||||
flavorDimensions 'cpuArch'
|
||||
productFlavors {
|
||||
arm8 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'arm64-v8a'
|
||||
}
|
||||
}
|
||||
arm7 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a'
|
||||
}
|
||||
}
|
||||
x86_64 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86_64'
|
||||
}
|
||||
}
|
||||
x86 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86'
|
||||
}
|
||||
}
|
||||
universal {
|
||||
dimension 'cpuArch'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### WebAssembly
|
||||
|
||||
The core Filament library can be cross-compiled to WebAssembly from either macOS or Linux. To get
|
||||
started, follow the instructions for building Filament on your platform ([macOS](#macos) or
|
||||
[linux](#linux)), which will ensure you have the proper dependencies installed.
|
||||
|
||||
Next, you need to install the Emscripten SDK. The following instructions show how to install the
|
||||
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/a77638d.zip > emsdk.zip
|
||||
unzip emsdk.zip
|
||||
mv emsdk-* emsdk
|
||||
cd emsdk
|
||||
./emsdk update
|
||||
./emsdk install sdk-1.38.28-64bit
|
||||
./emsdk activate sdk-1.38.28-64bit
|
||||
```
|
||||
|
||||
After this you can invoke the [easy build](#easy-build) script as follows:
|
||||
|
||||
```
|
||||
export EMSDK=<your chosen home for the emscripten SDK>
|
||||
./build.sh -p webgl release
|
||||
```
|
||||
|
||||
The EMSDK variable is required so that the build script can find the Emscripten SDK. The build
|
||||
creates a `samples` folder that can be used as the root of a simple static web server. Note that you
|
||||
cannot open the HTML directly from the filesystem due to CORS. One way to deal with this is to
|
||||
use Python to create a quick localhost server:
|
||||
|
||||
```
|
||||
cd out/cmake-webgl-release/web/samples
|
||||
python3 -m http.server # Python 3
|
||||
python -m SimpleHTTPServer # Python 2.7
|
||||
```
|
||||
|
||||
You can then open http://localhost:8000/suzanne.html in your web browser.
|
||||
|
||||
Alternatively, if you have node installed you can use the
|
||||
[live-server](https://www.npmjs.com/package/live-server) package, which automatically refreshes the
|
||||
web page when it detects a change.
|
||||
|
||||
Each sample app has its own handwritten html file. Additionally the server folder contains assets
|
||||
such as meshes, textures, and materials.
|
||||
|
||||
## Running the native samples
|
||||
|
||||
The `samples/` directory contains several examples of how to use Filament with SDL2.
|
||||
|
||||
Some of the samples accept FBX/OBJ meshes while others rely on the `filamesh` file format. To
|
||||
generate a `filamesh ` file from an FBX/OBJ asset, run the `filamesh` tool
|
||||
(`./tools/filamesh/filamesh` in your build directory):
|
||||
|
||||
```
|
||||
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:
|
||||
|
||||
```
|
||||
cmgen -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
|
||||
file. The environment map can be an equirectangular projection, a horizontal cross, a vertical
|
||||
cross, or a list of cubemap faces (horizontal or vertical).
|
||||
|
||||
`cmgen` will automatically create a directory based on the name of the source environment map. In
|
||||
the example above, the final directory will be `./ibls/my_ibl/`. This directory should contain the
|
||||
pre-filtered environment map (one file per cubemap face and per mip level), the environment map
|
||||
texture for the skybox and a text file containing the spherical harmonics for indirect diffuse
|
||||
lighting.
|
||||
|
||||
If you prefer a blurred background, run `cmgen` with this flag: `--extract-blur=0.1`. The numerical
|
||||
value is the desired roughness between 0 and 1.
|
||||
|
||||
## Rendering with Filament
|
||||
|
||||
### Native Linux, macOS and Windows
|
||||
@@ -889,44 +233,73 @@ Filament on iOS is largely the same as native rendering with C++. A `CAEAGLLayer
|
||||
is passed to the `createSwapChain` method. Filament for iOS supports both OpenGL ES and Vulkan via
|
||||
MoltenVK.
|
||||
|
||||
## Generating C++ documentation
|
||||
|
||||
To generate the documentation you must first install `doxygen` and `graphviz`, then run the
|
||||
following commands:
|
||||
|
||||
```
|
||||
$ cd filament/filament
|
||||
$ doxygen docs/doxygen/filament.doxygen
|
||||
```
|
||||
|
||||
Finally simply open `docs/html/index.html` in your web browser.
|
||||
|
||||
## Assets
|
||||
|
||||
To get started you can use the textures and environment maps found respectively in
|
||||
`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.
|
||||
|
||||
## Dependencies
|
||||
|
||||
One of our design goals is that Filament itself should have no dependencies or as few dependencies
|
||||
as possible. The current external dependencies of the runtime library include:
|
||||
|
||||
- STL
|
||||
- robin-map (header only library)
|
||||
|
||||
When building with Vulkan enabled, we have a few additional small dependencies:
|
||||
|
||||
- vkmemalloc
|
||||
- smol-v
|
||||
|
||||
Host tools (such as `matc` or `cmgen`) can use external dependencies freely.
|
||||
|
||||
## How to make contributions
|
||||
|
||||
Please read and follow the steps in [CONTRIBUTING.md](/CONTRIBUTING.md). Make sure you are
|
||||
familiar with the [code style](/CODE_STYLE.md).
|
||||
|
||||
## Directory structure
|
||||
|
||||
This repository not only contains the core Filament engine, but also its supporting libraries
|
||||
and tools.
|
||||
|
||||
- `android`: Android libraries and projects
|
||||
- `filamat-android`: Filament material generation library (AAR) for Android
|
||||
- `filament-android`: Filament library (AAR) for Android
|
||||
- `gltfio-android`: Filament glTF loading library (AAR) for Android
|
||||
- `samples`: Android-specific Filament samples
|
||||
- `art`: Source for various artworks (logos, PDF manuals, etc.)
|
||||
- `assets`: 3D assets to use with sample applications
|
||||
- `build`: CMake build scripts
|
||||
- `docs`: Documentation
|
||||
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
|
||||
- `filament`: Filament rendering engine (minimal dependencies)
|
||||
- `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
|
||||
- `filabridge`: Library shared by the Filament engine and host tools
|
||||
- `filaflat`: Serialization/deserialization library used for materials
|
||||
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
|
||||
- `filamat`: Material generation library
|
||||
- `filameshio`: Tiny filamesh parsing library (see also `tools/filamesh`)
|
||||
- `geometry`: Mesh-related utilities
|
||||
- `gltfio`: Loader and optional pipeline for glTF 2.0
|
||||
- `ibl`: IBL generation tools
|
||||
- `image`: Image filtering and simple transforms
|
||||
- `imageio`: Image file reading / writing, only intended for internal use
|
||||
- `matdbg`: DebugServer for inspecting shaders at run-time (debug builds only)
|
||||
- `math`: Math library
|
||||
- `rays`: Simple path tracer used for baking ambient occlusion, etc.
|
||||
- `utils`: Utility library (threads, memory, data structures, etc.)
|
||||
- `samples`: Sample desktop applications
|
||||
- `shaders`: Shaders used by `filamat` and `matc`
|
||||
- `third_party`: External libraries and assets
|
||||
- `environments`: Environment maps under CC0 license that can be used with `cmgen`
|
||||
- `models`: Models under permissive licenses
|
||||
- `textures`: Textures under CC0 license
|
||||
- `tools`: Host tools
|
||||
- `cmgen`: Image-based lighting asset generator
|
||||
- `filamesh`: Mesh converter
|
||||
- `glslminifier`: Minifies GLSL source code
|
||||
- `matc`: Material compiler
|
||||
- `matinfo` Displays information about materials compiled with `matc`
|
||||
- `mipgen` Generates a series of miplevels from a source image
|
||||
- `normal-blending`: Tool to blend normal maps
|
||||
- `resgen` Aggregates binary blobs into embeddable resources
|
||||
- `roughness-prefilter`: Pre-filters a roughness map from a normal map to reduce aliasing
|
||||
- `skygen`: Physically-based sky environment texture generator
|
||||
- `specular-color`: Computes the specular color of conductors based on spectral data
|
||||
- `web`: JavaScript bindings, documentation, and samples
|
||||
|
||||
## License
|
||||
|
||||
Please see [LICENSE](/LICENSE).
|
||||
|
||||
@@ -3,6 +3,49 @@
|
||||
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
|
||||
|
||||
## v1.4.5
|
||||
|
||||
- The depth prepass setting in View is now ignored and deprecated.
|
||||
- Fixed a threading bug with the NOOP backend.
|
||||
- Improved memory management for gltfio on Android.
|
||||
- Introduced `filament-utils` library with `TextureLoader`, `ModelViewer`, and Java bindings for `camutils`.
|
||||
- Fix out-of-bounds bug when glTF has many UV sets.
|
||||
- Added new `setMediaOverlay` API to `UiHelper` for controlling surface ordering.
|
||||
- Implemented sRGB support for DXT encoded textures.
|
||||
- Fix bug with incorrect world transforms computed in `TransformManager`.
|
||||
- gltfio: support external resources on Android.
|
||||
|
||||
|
||||
## v1.4.4
|
||||
|
||||
- Added support for solid and thin layer cubemap and screen-space refraction.
|
||||
- Improved high roughness material rendering by default when regenerating environments maps.
|
||||
- Fix bad instruction exception with macOS Catalina.
|
||||
- Fixed bad state after removing an IBL from the Scene.
|
||||
- Fixed incorrect punctual light binning (affected Metal and Vulkan backends).
|
||||
- Fixed crash when using a Metal headless SwapChain with an Intel integrated GPU.
|
||||
- Added support for ASTC textures on iOS with Metal backend.
|
||||
- Added new heightfield sample.
|
||||
- Removed `<iostream>` from math headers.
|
||||
- cmgen now places KTX files directly in the specified deployment folder.
|
||||
|
||||
## v1.4.3
|
||||
|
||||
- Fixed an assertion when a parameter array occurs last in a material definition.
|
||||
- Fixed morph shapes not rendering in WebGL.
|
||||
- Added support for the latest version of emscripten.
|
||||
- gltfio: fixed blackness seen with default material.
|
||||
- Added ETC2 and BC compressed texture support to Metal backend.
|
||||
- Rendering a `SAMPLER_EXTERNAL` texture before setting an external image no longer results in GPU errors.
|
||||
- Fixed a normals issue when skinning without a normal map or anisotropy.
|
||||
- Fixed an issue where transparent views couldn't be used with post-processing.
|
||||
- Always use higher quality 3-bands SH for indirect lighting, even on mobile.
|
||||
- The Metal backend can now handle binding individual planes of YUV external images.
|
||||
- Added support for depth buffer when post-processing is turned off
|
||||
- Improved performance on GPUs that use tile-based rendering
|
||||
|
||||
## v1.4.2
|
||||
|
||||
- Cleaned up the validation strategy in Engine (checks for use-after-destroy etc).
|
||||
@@ -11,6 +54,7 @@ A new header is inserted each time a *tag* is created.
|
||||
- gltfio: Added Java / Kotlin bindings for Animator.
|
||||
- gltfio: Fixed panic with the Android gltf-bloom demo.
|
||||
- gltfio: Java clients should no longer call Filament#init.
|
||||
- Improved IBL diffuse by allowing to use the specular cubemap at `roughness` = 1 instead of Spherical Harmonics
|
||||
|
||||
## v1.4.1
|
||||
|
||||
|
||||
9
android/.gitignore
vendored
Normal file
9
android/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/.idea/caches
|
||||
/.idea/gradle.xml
|
||||
.DS_Store
|
||||
/build/
|
||||
58
android/build.gradle
Normal file
58
android/build.gradle
Normal file
@@ -0,0 +1,58 @@
|
||||
// This script accepts the following parameters:
|
||||
//
|
||||
// filament_dist_dir
|
||||
// Path to the Filament distribution/install directory for Android
|
||||
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_dist_dir=../dist-android-release assembleRelease
|
||||
|
||||
buildscript {
|
||||
def filamentPath = file("../out/android-release/filament").absolutePath
|
||||
if (project.hasProperty("filament_dist_dir")) {
|
||||
filamentPath = file("$filament_dist_dir").absolutePath
|
||||
}
|
||||
|
||||
ext.filamentPath = filamentPath
|
||||
|
||||
// Our minSdkVersion is actually 19, we lie and say 14 here so apps don't have
|
||||
// to increase their minSdkVersion unnecessarily. It is however up to them to
|
||||
// ensure they do not initialize Filament on API levels < 19.
|
||||
ext.versions = [
|
||||
'minSdk': 14,
|
||||
'targetSdk': 29,
|
||||
'compileSdk': 29,
|
||||
'kotlin': '1.3.61',
|
||||
'buildTools': '29.0.2',
|
||||
]
|
||||
|
||||
ext.deps = [
|
||||
'androidx': [
|
||||
'annotations': "androidx.annotation:annotation:1.1.0",
|
||||
'core': "androidx.core:core:1.1.0",
|
||||
],
|
||||
'kotlin': "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"
|
||||
]
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.0-rc01'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
}
|
||||
|
||||
subprojects { project ->
|
||||
group = GROUP
|
||||
version = VERSION_NAME
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
9
android/buildSrc/.gitignore
vendored
Normal file
9
android/buildSrc/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/.idea/caches
|
||||
/.idea/gradle.xml
|
||||
.DS_Store
|
||||
/build/
|
||||
@@ -9,61 +9,63 @@
|
||||
|
||||
import java.nio.file.Paths
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import org.gradle.api.logging.Logger;
|
||||
import org.gradle.api.logging.LogLevel;
|
||||
import org.gradle.api.*
|
||||
import org.gradle.api.logging.*
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.incremental.*
|
||||
|
||||
def filamentToolsPath = file("../../../../out/release/filament")
|
||||
if (project.hasProperty("filament_tools_dir")) {
|
||||
filamentToolsPath = file("$filament_tools_dir")
|
||||
}
|
||||
class TaskWithBinary extends DefaultTask {
|
||||
private final String binaryName
|
||||
private File binaryPath = null
|
||||
|
||||
List<File> getBinaries(String name, File toolsPath) {
|
||||
def tool = ["/bin/${name}.exe", "/bin/${name}"]
|
||||
def toolFullPath = tool.collect { path -> Paths.get(toolsPath.absolutePath, path).toFile() }
|
||||
|
||||
// Ensure that at least one matc binary and Filament library is present
|
||||
if (!toolFullPath.any { path -> file(path).exists() }) {
|
||||
throw new StopActionException("No ${name} binary could be found in " + toolsPath +
|
||||
"/bin. Ensure Filament has been built/installed before building this app.")
|
||||
TaskWithBinary(String name) {
|
||||
binaryName = name
|
||||
}
|
||||
|
||||
return toolFullPath
|
||||
}
|
||||
String getBinaryName() {
|
||||
return binaryName
|
||||
}
|
||||
|
||||
ext.matcFullPath = getBinaries('matc', filamentToolsPath)
|
||||
ext.cmgenFullPath = getBinaries('cmgen', filamentToolsPath)
|
||||
ext.filameshFullPath = getBinaries('filamesh', filamentToolsPath)
|
||||
ext.resgenFullPath = getBinaries('resgen', filamentToolsPath)
|
||||
File 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]
|
||||
}
|
||||
return binaryPath
|
||||
}
|
||||
}
|
||||
|
||||
class LogOutputStream extends ByteArrayOutputStream {
|
||||
private final Logger logger;
|
||||
private final LogLevel level;
|
||||
private final Logger logger
|
||||
private final LogLevel level
|
||||
|
||||
public LogOutputStream(Logger logger, LogLevel level) {
|
||||
this.logger = logger;
|
||||
this.level = level;
|
||||
LogOutputStream(Logger logger, LogLevel level) {
|
||||
this.logger = logger
|
||||
this.level = level
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
Logger getLogger() {
|
||||
return logger
|
||||
}
|
||||
|
||||
public LogLevel getLevel() {
|
||||
return level;
|
||||
LogLevel getLevel() {
|
||||
return level
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
logger.log(level, toString());
|
||||
reset();
|
||||
void flush() {
|
||||
logger.log(level, toString())
|
||||
reset()
|
||||
}
|
||||
}
|
||||
|
||||
// Custom task to compile material files using matc
|
||||
// This task handles incremental builds
|
||||
class MaterialCompiler extends DefaultTask {
|
||||
File matcPath
|
||||
|
||||
class MaterialCompiler extends TaskWithBinary {
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@InputDirectory
|
||||
File inputDir
|
||||
@@ -72,8 +74,7 @@ class MaterialCompiler extends DefaultTask {
|
||||
File outputDir
|
||||
|
||||
MaterialCompiler() {
|
||||
matcPath = OperatingSystem.current().isWindows() ?
|
||||
project.ext.matcFullPath[0] : project.ext.matcFullPath[1]
|
||||
super("matc")
|
||||
}
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@@ -94,10 +95,15 @@ class MaterialCompiler extends DefaultTask {
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${matcPath}"
|
||||
executable "${getBinary()}"
|
||||
args('-a', 'all', '-p', 'mobile', '-o', getOutputFile(file), file)
|
||||
}
|
||||
}
|
||||
@@ -114,9 +120,8 @@ class MaterialCompiler extends DefaultTask {
|
||||
|
||||
// Custom task to process IBLs using cmgen
|
||||
// This task handles incremental builds
|
||||
class IblGenerator extends DefaultTask {
|
||||
File cmgenPath
|
||||
String cmgenArgs = null;
|
||||
class IblGenerator extends TaskWithBinary {
|
||||
String cmgenArgs = null
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@InputFile
|
||||
@@ -126,8 +131,7 @@ class IblGenerator extends DefaultTask {
|
||||
File outputDir
|
||||
|
||||
IblGenerator() {
|
||||
cmgenPath = OperatingSystem.current().isWindows() ?
|
||||
project.ext.cmgenFullPath[0] : project.ext.cmgenFullPath[1]
|
||||
super("cmgen")
|
||||
}
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@@ -147,21 +151,20 @@ class IblGenerator extends DefaultTask {
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${cmgenPath}"
|
||||
args('-x', outputDir, file)
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
if (!cmgenArgs) {
|
||||
cmgenArgs = '--format=rgb32f --extract-blur=0.08 --extract=' + outputDir.absolutePath
|
||||
cmgenArgs = '-q -x ' + outputDir +
|
||||
' --format=rgb32f --extract-blur=0.08 --extract=' + outputDir.absolutePath
|
||||
}
|
||||
cmgenArgs = cmgenArgs + " " + file
|
||||
errorOutput err
|
||||
executable "${cmgenPath}"
|
||||
executable "${getBinary()}"
|
||||
args(cmgenArgs.split())
|
||||
}
|
||||
}
|
||||
@@ -178,9 +181,7 @@ class IblGenerator extends DefaultTask {
|
||||
|
||||
// Custom task to compile mesh files using filamesh
|
||||
// This task handles incremental builds
|
||||
class MeshCompiler extends DefaultTask {
|
||||
File filameshPath
|
||||
|
||||
class MeshCompiler extends TaskWithBinary {
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@InputFile
|
||||
File inputFile
|
||||
@@ -189,8 +190,7 @@ class MeshCompiler extends DefaultTask {
|
||||
File outputDir
|
||||
|
||||
MeshCompiler() {
|
||||
filameshPath = OperatingSystem.current().isWindows() ?
|
||||
project.ext.filameshFullPath[0] : project.ext.filameshFullPath[1]
|
||||
super("filamesh")
|
||||
}
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@@ -210,10 +210,15 @@ class MeshCompiler extends DefaultTask {
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${filameshPath}"
|
||||
executable "${getBinary()}"
|
||||
args(file, getOutputFile(file))
|
||||
}
|
||||
}
|
||||
@@ -228,8 +233,50 @@ class MeshCompiler extends DefaultTask {
|
||||
}
|
||||
}
|
||||
|
||||
task compileMaterials(type: MaterialCompiler)
|
||||
class FilamentToolsPluginExtension {
|
||||
File materialInputDir
|
||||
File materialOutputDir
|
||||
|
||||
task generateIbl(type: IblGenerator)
|
||||
String cmgenArgs
|
||||
File iblInputFile
|
||||
File iblOutputDir
|
||||
|
||||
task compileMesh(type: MeshCompiler)
|
||||
File meshInputFile
|
||||
File meshOutputDir
|
||||
}
|
||||
|
||||
class FilamentToolsPlugin implements Plugin<Project> {
|
||||
void apply(Project project) {
|
||||
def extension = project.extensions.create('filamentTools', FilamentToolsPluginExtension)
|
||||
|
||||
project.ext.filamentToolsPath = project.file("../../../out/release/filament")
|
||||
if (project.hasProperty("filament_tools_dir")) {
|
||||
project.ext.filamentToolsPath = project.file("$filament_tools_dir")
|
||||
}
|
||||
|
||||
project.tasks.register("filamentCompileMaterials", MaterialCompiler) {
|
||||
enabled = extension.materialInputDir != null && extension.materialOutputDir != null
|
||||
inputDir = extension.materialInputDir
|
||||
outputDir = extension.materialOutputDir
|
||||
}
|
||||
|
||||
project.preBuild.dependsOn "filamentCompileMaterials"
|
||||
|
||||
project.tasks.register("filamentGenerateIbl", IblGenerator) {
|
||||
enabled = extension.iblInputFile != null && extension.iblOutputDir != null
|
||||
cmgenArgs = extension.cmgenArgs
|
||||
inputFile = extension.iblInputFile
|
||||
outputDir = extension.iblOutputDir
|
||||
}
|
||||
|
||||
project.preBuild.dependsOn "filamentGenerateIbl"
|
||||
|
||||
project.tasks.register("filamentCompileMesh", MeshCompiler) {
|
||||
enabled = extension.meshInputFile != null && extension.meshOutputDir != null
|
||||
inputFile = extension.meshInputFile
|
||||
outputDir = extension.meshOutputDir
|
||||
}
|
||||
|
||||
project.preBuild.dependsOn "filamentCompileMesh"
|
||||
}
|
||||
}
|
||||
@@ -27,39 +27,6 @@ struct {
|
||||
jmethodID execute;
|
||||
} gCallbackUtils;
|
||||
|
||||
JniCallback* JniCallback::make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback) {
|
||||
void* that = engine->streamAlloc(sizeof(JniCallback), alignof(JniCallback));
|
||||
return new (that) JniCallback(env, handler, callback);
|
||||
}
|
||||
|
||||
JniCallback::JniCallback(JNIEnv* env, jobject handler, jobject callback)
|
||||
: mEnv(env)
|
||||
, mHandler(env->NewGlobalRef(handler))
|
||||
, mCallback(env->NewGlobalRef(callback)) {
|
||||
}
|
||||
|
||||
JniCallback::~JniCallback() {
|
||||
if (mHandler && mCallback) {
|
||||
#ifdef ANDROID
|
||||
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.handlerClass)) {
|
||||
mEnv->CallBooleanMethod(mHandler, gCallbackUtils.post, mCallback);
|
||||
}
|
||||
#endif
|
||||
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.executorClass)) {
|
||||
mEnv->CallVoidMethod(mHandler, gCallbackUtils.execute, mCallback);
|
||||
}
|
||||
}
|
||||
mEnv->DeleteGlobalRef(mHandler);
|
||||
mEnv->DeleteGlobalRef(mCallback);
|
||||
}
|
||||
|
||||
void JniCallback::invoke(void*, size_t, void* user) {
|
||||
JniCallback* data = reinterpret_cast<JniCallback*>(user);
|
||||
// don't call delete here, because we don't own the storage
|
||||
data->~JniCallback();
|
||||
}
|
||||
|
||||
JniBufferCallback* JniBufferCallback::make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer) {
|
||||
void* that = engine->streamAlloc(sizeof(JniBufferCallback), alignof(JniBufferCallback));
|
||||
@@ -95,6 +62,37 @@ void JniBufferCallback::invoke(void*, size_t, void* user) {
|
||||
data->~JniBufferCallback();
|
||||
}
|
||||
|
||||
JniImageCallback* JniImageCallback::make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback, long image) {
|
||||
void* that = engine->streamAlloc(sizeof(JniImageCallback), alignof(JniImageCallback));
|
||||
return new (that) JniImageCallback(env, handler, callback, image);
|
||||
}
|
||||
|
||||
JniImageCallback::JniImageCallback(JNIEnv* env, jobject handler, jobject callback, long image)
|
||||
: mEnv(env)
|
||||
, mHandler(env->NewGlobalRef(handler))
|
||||
, mCallback(env->NewGlobalRef(callback))
|
||||
, mImage(image) { }
|
||||
|
||||
JniImageCallback::~JniImageCallback() {
|
||||
if (mHandler && mCallback) {
|
||||
#ifdef ANDROID
|
||||
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.handlerClass)) {
|
||||
mEnv->CallBooleanMethod(mHandler, gCallbackUtils.post, mCallback);
|
||||
}
|
||||
#endif
|
||||
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.executorClass)) {
|
||||
mEnv->CallVoidMethod(mHandler, gCallbackUtils.execute, mCallback);
|
||||
}
|
||||
}
|
||||
mEnv->DeleteGlobalRef(mHandler);
|
||||
mEnv->DeleteGlobalRef(mCallback);
|
||||
}
|
||||
|
||||
void JniImageCallback::invoke(void* image, void* user) {
|
||||
reinterpret_cast<JniImageCallback*>(user)->~JniImageCallback();
|
||||
}
|
||||
|
||||
void registerCallbackUtils(JNIEnv *env) {
|
||||
#ifdef ANDROID
|
||||
gCallbackUtils.handlerClass = env->FindClass("android/os/Handler");
|
||||
|
||||
@@ -23,21 +23,6 @@
|
||||
|
||||
#include <filament/Engine.h>
|
||||
|
||||
struct JniCallback {
|
||||
static JniCallback* make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback);
|
||||
|
||||
static void invoke(void* buffer, size_t n, void* user);
|
||||
|
||||
private:
|
||||
JniCallback(JNIEnv* env, jobject handler, jobject callback);
|
||||
~JniCallback();
|
||||
|
||||
JNIEnv* mEnv;
|
||||
jobject mHandler;
|
||||
jobject mCallback;
|
||||
};
|
||||
|
||||
struct JniBufferCallback {
|
||||
static JniBufferCallback* make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer);
|
||||
@@ -53,3 +38,19 @@ private:
|
||||
jobject mCallback;
|
||||
AutoBuffer mBuffer;
|
||||
};
|
||||
|
||||
struct JniImageCallback {
|
||||
static JniImageCallback* make(filament::Engine* engine, JNIEnv* env, jobject handler,
|
||||
jobject runnable, long image);
|
||||
|
||||
static void invoke(void* image, void* user);
|
||||
|
||||
private:
|
||||
JniImageCallback(JNIEnv* env, jobject handler, jobject runnable, long image);
|
||||
~JniImageCallback();
|
||||
|
||||
JNIEnv* mEnv;
|
||||
jobject mHandler;
|
||||
jobject mCallback;
|
||||
long mImage;
|
||||
};
|
||||
|
||||
@@ -1,55 +1,18 @@
|
||||
// This script accepts the following parameters:
|
||||
//
|
||||
// filament_dist_dir
|
||||
// Path to the Filament distribution/install directory for Android
|
||||
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_dist_dir=../../dist-android-release assembleRelease
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
group = "com.google.android.filament"
|
||||
version = "1.3"
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
def filament_path = file("../../out/android-release/filament").absolutePath
|
||||
if (project.hasProperty("filament_dist_dir")) {
|
||||
filament_path = file("$filament_dist_dir").absolutePath
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion versions.buildTools
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
minSdkVersion versions.minSdk
|
||||
targetSdkVersion versions.targetSdk
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DANDROID_PIE=ON")
|
||||
arguments.add("-DANDROID_PLATFORM=android-19")
|
||||
arguments.add("-DANDROID_PLATFORM=android-${versions.targetSdk}".toString())
|
||||
arguments.add("-DANDROID_STL=c++_static")
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filamentPath}".toString())
|
||||
cppFlags.add("-std=c++14")
|
||||
if (project.hasProperty('extra_cmake_args')) {
|
||||
arguments.add(extra_cmake_args)
|
||||
@@ -58,13 +21,6 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "functionality"
|
||||
productFlavors {
|
||||
full {
|
||||
@@ -101,6 +57,23 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.android.support:support-annotations:28.0.0'
|
||||
implementation deps.androidx.annotations
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
|
||||
afterEvaluate { project ->
|
||||
publishing {
|
||||
publications {
|
||||
fullRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_FULL
|
||||
from components.fullRelease
|
||||
}
|
||||
|
||||
liteRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_LITE
|
||||
from components.liteRelease
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
android/filamat-android/gradle.properties
Normal file
4
android/filamat-android/gradle.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
POM_NAME=Filament Material Builder
|
||||
POM_ARTIFACT_ID_FULL=filamat-android-full
|
||||
POM_ARTIFACT_ID_LITE=filamat-android-lite
|
||||
POM_PACKAGING=aar
|
||||
@@ -1,5 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* The settings file is used to specify which projects to include in your build.
|
||||
*
|
||||
* Detailed information about configuring a multi-project build in Gradle can be found
|
||||
* in the user guide at https://docs.gradle.org/4.6/userguide/multi_project_builds.html
|
||||
*/
|
||||
|
||||
rootProject.name = 'filamat-android'
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament.filamat;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MaterialBuilder {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament.filamat;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MaterialPackage {
|
||||
|
||||
113
android/filament-android/.idea/codeStyles/Project.xml
generated
113
android/filament-android/.idea/codeStyles/Project.xml
generated
@@ -1,113 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<codeStyleSettings language="XML">
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
@@ -1,5 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
||||
15
android/filament-android/.idea/compiler.xml
generated
15
android/filament-android/.idea/compiler.xml
generated
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
</wildcardResourcePatterns>
|
||||
</component>
|
||||
</project>
|
||||
6
android/filament-android/.idea/encodings.xml
generated
6
android/filament-android/.idea/encodings.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
34
android/filament-android/.idea/misc.xml
generated
34
android/filament-android/.idea/misc.xml
generated
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="5">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="4">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
8
android/filament-android/.idea/modules.xml
generated
8
android/filament-android/.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/filament-android.iml" filepath="$PROJECT_DIR$/filament-android.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
12
android/filament-android/.idea/runConfigurations.xml
generated
12
android/filament-android/.idea/runConfigurations.xml
generated
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
6
android/filament-android/.idea/vcs.xml
generated
6
android/filament-android/.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,58 +1,18 @@
|
||||
// This script accepts the following parameters:
|
||||
//
|
||||
// filament_dist_dir
|
||||
// Path to the Filament distribution/install directory for Android
|
||||
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_dist_dir=../../dist-android-release assembleRelease
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
group = "com.google.android.filament"
|
||||
version = "1.3"
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
def filament_path = file("../../out/android-release/filament").absolutePath
|
||||
if (project.hasProperty("filament_dist_dir")) {
|
||||
filament_path = file("$filament_dist_dir").absolutePath
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion versions.buildTools
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
// Our minSdkVersion is actually 19, we lie and say 14 here so apps don't have
|
||||
// to increase their minSdkVersion unnecessarily. It is however up to them to
|
||||
// ensure they do not initialize Filament on API levels < 19.
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
minSdkVersion versions.minSdk
|
||||
targetSdkVersion versions.targetSdk
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DANDROID_PIE=ON")
|
||||
arguments.add("-DANDROID_PLATFORM=android-19")
|
||||
arguments.add("-DANDROID_PLATFORM=android-${versions.targetSdk}".toString())
|
||||
arguments.add("-DANDROID_STL=c++_static")
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filamentPath}".toString())
|
||||
cppFlags.add("-std=c++14")
|
||||
if (project.hasProperty('extra_cmake_args')) {
|
||||
arguments.add(extra_cmake_args)
|
||||
@@ -61,13 +21,6 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "CMakeLists.txt"
|
||||
@@ -93,6 +46,18 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.android.support:support-annotations:28.0.0'
|
||||
implementation deps.androidx.annotations
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
|
||||
afterEvaluate { project ->
|
||||
publishing {
|
||||
publications {
|
||||
release(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID
|
||||
from components.release
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3
android/filament-android/gradle.properties
Normal file
3
android/filament-android/gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
POM_NAME=Filament
|
||||
POM_ARTIFACT_ID=filament-android
|
||||
POM_PACKAGING=aar
|
||||
Binary file not shown.
172
android/filament-android/gradlew
vendored
172
android/filament-android/gradlew
vendored
@@ -1,172 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
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"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
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
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
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
|
||||
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
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((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" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
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" "$@"
|
||||
84
android/filament-android/gradlew.bat
vendored
84
android/filament-android/gradlew.bat
vendored
@@ -1,84 +0,0 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@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"
|
||||
|
||||
@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
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
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%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
22
android/filament-android/proguard-rules.pro
vendored
22
android/filament-android/proguard-rules.pro
vendored
@@ -1,22 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# JNI is an entry point that's hard to keep track of, so there's
|
||||
# an annotation to mark fields and methods used by native code.
|
||||
|
||||
# Keep the annotations that proguard needs to process.
|
||||
-keep class com.google.android.filament.proguard.UsedBy*
|
||||
|
||||
# Just because native code accesses members of a class, does not mean that the
|
||||
# class itself needs to be annotated - only annotate classes that are
|
||||
# referenced themselves in native code.
|
||||
-keep @com.google.android.filament.proguard.UsedBy* class * {
|
||||
<init>();
|
||||
}
|
||||
-keepclassmembers class * {
|
||||
@com.google.android.filament.proguard.UsedBy* *;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
rootProject.name = 'filament-android'
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
#include <filament/Engine.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
#include <utils/EntityManager.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
@@ -59,6 +62,13 @@ Java_com_google_android_filament_Engine_nCreateSwapChain(JNIEnv* env,
|
||||
return (jlong) engine->createSwapChain(win, (uint64_t) flags);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateSwapChainHeadless(JNIEnv* env,
|
||||
jclass klass, jlong nativeEngine, jint width, jint height, jlong flags) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) engine->createSwapChain(width, height, (uint64_t) flags);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateSwapChainFromRawPointer(JNIEnv*,
|
||||
jclass, jlong nativeEngine, jlong pointer, jlong flags) {
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include <filament/IndexBuffer.h>
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
|
||||
#include "common/CallbackUtils.h"
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
|
||||
@@ -135,10 +135,31 @@ Java_com_google_android_filament_IndirectLight_nGetDirectionEstimate(JNIEnv* env
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_IndirectLight_nGetColorEstimate(JNIEnv* env, jclass,
|
||||
jlong nativeIndirectLight, jfloatArray outColor_, float x, float y, float z) {
|
||||
jlong nativeIndirectLight, jfloatArray outColor_, jfloat x, jfloat y, jfloat z) {
|
||||
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
|
||||
jfloat *outColor = env->GetFloatArrayElements(outColor_, NULL);
|
||||
*reinterpret_cast<filament::math::float4*>(outColor) =
|
||||
indirectLight->getColorEstimate(math::float3{x, y, z});
|
||||
env->ReleaseFloatArrayElements(outColor_, outColor, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_IndirectLight_nGetDirectionEstimateStatic(JNIEnv *env, jclass,
|
||||
jfloatArray sh_, jfloatArray outDirection_) {
|
||||
jfloat* sh = env->GetFloatArrayElements(sh_, NULL);
|
||||
jfloat *outDirection = env->GetFloatArrayElements(outDirection_, NULL);
|
||||
*reinterpret_cast<filament::math::float3*>(outDirection) = IndirectLight::getDirectionEstimate((filament::math::float3*)sh);
|
||||
env->ReleaseFloatArrayElements(outDirection_, outDirection, 0);
|
||||
env->ReleaseFloatArrayElements(sh_, sh, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_IndirectLight_nGetColorEstimateStatic(JNIEnv *env, jclass,
|
||||
jfloatArray outColor_, jfloatArray sh_, jfloat x, jfloat y, jfloat z) {
|
||||
jfloat* sh = env->GetFloatArrayElements(sh_, NULL);
|
||||
jfloat *outColor = env->GetFloatArrayElements(outColor_, NULL);
|
||||
*reinterpret_cast<filament::math::float4*>(outColor) =
|
||||
IndirectLight::getColorEstimate((filament::math::float3*)sh, math::float3{x, y, z});
|
||||
env->ReleaseFloatArrayElements(outColor_, outColor, 0);
|
||||
env->ReleaseFloatArrayElements(sh_, sh, JNI_ABORT);
|
||||
}
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <filament/LightManager.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
|
||||
@@ -84,6 +84,23 @@ Java_com_google_android_filament_Material_nGetBlendingMode(JNIEnv*, jclass,
|
||||
return (jint) material->getBlendingMode();
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Material_nGetRefraction(JNIEnv*, jclass,
|
||||
jlong nativeMaterial) {
|
||||
Material* material = (Material*) nativeMaterial;
|
||||
return (jint)material->getRefractionMode();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Material_nGetRefractionType(JNIEnv*, jclass,
|
||||
jlong nativeMaterial) {
|
||||
Material* material = (Material*) nativeMaterial;
|
||||
return (jint) material->getRefractionType();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Material_nGetVertexDomain(JNIEnv*, jclass,
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/MaterialInstance.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
|
||||
@@ -97,6 +97,42 @@ Java_com_google_android_filament_Renderer_nReadPixels(JNIEnv *env, jclass,
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Renderer_nReadPixelsEx(JNIEnv *env, jclass,
|
||||
jlong nativeRenderer, jlong nativeEngine, jlong nativeRenderTarget,
|
||||
jint xoffset, jint yoffset, jint width, jint height,
|
||||
jobject storage, jint remaining,
|
||||
jint left, jint top, jint type, jint alignment, jint stride, jint format,
|
||||
jobject handler, jobject runnable) {
|
||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
RenderTarget *renderTarget = (RenderTarget *) nativeRenderTarget;
|
||||
|
||||
stride = stride ? stride : width;
|
||||
size_t sizeInBytes = PixelBufferDescriptor::computeDataSize(
|
||||
(PixelDataFormat) format, (PixelDataType) type,
|
||||
(size_t) stride, (size_t) (height + top), (size_t) alignment);
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *buffer = nioBuffer.getData();
|
||||
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
|
||||
renderer->readPixels(renderTarget,
|
||||
uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
|
||||
std::move(desc));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jdouble JNICALL
|
||||
Java_com_google_android_filament_Renderer_nGetUserTime(JNIEnv*, jclass, jlong nativeRenderer) {
|
||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <filament/Scene.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
|
||||
@@ -24,6 +24,25 @@
|
||||
#include "common/NioUtils.h"
|
||||
#include "common/CallbackUtils.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
#if __has_include(<android/hardware_buffer_jni.h>)
|
||||
#include <android/hardware_buffer_jni.h>
|
||||
#else
|
||||
struct AHardwareBuffer;
|
||||
typedef struct AHardwareBuffer AHardwareBuffer;
|
||||
#endif
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
using PFN_FROMHARDWAREBUFFER = AHardwareBuffer* (*)(JNIEnv*, jobject);
|
||||
static PFN_FROMHARDWAREBUFFER AHardwareBuffer_fromHardwareBuffer_fn = nullptr;
|
||||
static bool sHardwareBufferSupported = true;
|
||||
|
||||
#endif
|
||||
|
||||
using namespace filament;
|
||||
using namespace backend;
|
||||
|
||||
@@ -108,10 +127,10 @@ Java_com_google_android_filament_Stream_nBuilderBuild(JNIEnv*, jclass,
|
||||
return (jlong) builder->builder()->build(*engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Stream_nIsNative(JNIEnv*, jclass, jlong nativeStream) {
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Stream_nGetStreamType(JNIEnv*, jclass, jlong nativeStream) {
|
||||
Stream* stream = (Stream*) nativeStream;
|
||||
return (jboolean) stream->isNativeStream();
|
||||
return (jint) stream->getStreamType();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -160,3 +179,44 @@ Java_com_google_android_filament_Stream_nGetTimestamp(JNIEnv*, jclass, jlong nat
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
return stream->getTimestamp();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nSetAcquiredImage(JNIEnv* env, jclass, jlong nativeStream,
|
||||
jlong nativeEngine, jobject hwbuffer, jobject handler, jobject runnable) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Stream* stream = (Stream*) nativeStream;
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
// This function is not available before NDK 15 or before Android 8.
|
||||
if (UTILS_UNLIKELY(!AHardwareBuffer_fromHardwareBuffer_fn)) {
|
||||
if (!sHardwareBufferSupported) {
|
||||
return;
|
||||
}
|
||||
AHardwareBuffer_fromHardwareBuffer_fn = (PFN_FROMHARDWAREBUFFER) dlsym(RTLD_DEFAULT, "AHardwareBuffer_fromHardwareBuffer");
|
||||
if (!AHardwareBuffer_fromHardwareBuffer_fn) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "Filament", "AHardwareBuffer_fromHardwareBuffer is not available.");
|
||||
sHardwareBufferSupported = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
AHardwareBuffer* nativeBuffer = AHardwareBuffer_fromHardwareBuffer_fn(env, hwbuffer);
|
||||
if (!nativeBuffer) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "Filament", "Unable to obtain native HardwareBuffer.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* callback = JniImageCallback::make(engine, env, handler, runnable, (long) nativeBuffer);
|
||||
|
||||
#else
|
||||
|
||||
// TODO: for non-Android platforms, it is unclear how to go from "jobject" to "void*"
|
||||
// For now this code is reserved for future use.
|
||||
auto* callback = JniImageCallback::make(engine, env, handler, runnable, 0);
|
||||
void* nativeBuffer = nullptr;
|
||||
|
||||
#endif
|
||||
|
||||
stream->setAcquiredImage((void*) nativeBuffer, &JniImageCallback::invoke, callback);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/View.h>
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
@@ -241,8 +242,14 @@ 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) {
|
||||
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity) {
|
||||
View* view = (View*) nativeView;
|
||||
View::AmbientOcclusionOptions options = { .radius = radius, .bias = bias, .power = power, .resolution = resolution};
|
||||
View::AmbientOcclusionOptions options = {
|
||||
.radius = radius,
|
||||
.bias = bias,
|
||||
.power = power,
|
||||
.resolution = resolution,
|
||||
.intensity = intensity
|
||||
};
|
||||
view->setAmbientOcclusionOptions(options);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,16 @@
|
||||
#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"
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
final class Asserts {
|
||||
private Asserts() {
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
/**
|
||||
* An axis-aligned 3D box represented by its center and half-extent.
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
/**
|
||||
* Camera represents the eye through which the scene is viewed.
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
@@ -119,13 +119,17 @@ public class Engine {
|
||||
*/
|
||||
DEFAULT,
|
||||
/**
|
||||
* Selects the OpenGL ES driver.
|
||||
* Selects the OpenGL driver (which supports OpenGL ES as well).
|
||||
*/
|
||||
OPENGL,
|
||||
/**
|
||||
* Selects the experimental Vulkan driver.
|
||||
* Selects the Vulkan driver if the platform supports it.
|
||||
*/
|
||||
VULKAN,
|
||||
/**
|
||||
* Selects the Metal driver if the platform supports it.
|
||||
*/
|
||||
METAL,
|
||||
/**
|
||||
* Selects the no-op driver for testing purposes.
|
||||
*/
|
||||
@@ -290,6 +294,32 @@ public class Engine {
|
||||
throw new IllegalArgumentException("Invalid surface " + surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a headless {@link SwapChain}
|
||||
*
|
||||
* @param width width of the rendering buffer
|
||||
* @param height height of the rendering buffer
|
||||
* @param flags configuration flags, see {@link SwapChain}
|
||||
*
|
||||
* @return a newly created {@link SwapChain} object
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if the SwapChain couldn't be created
|
||||
*
|
||||
* @see SwapChain#CONFIG_DEFAULT
|
||||
* @see SwapChain#CONFIG_TRANSPARENT
|
||||
* @see SwapChain#CONFIG_READABLE
|
||||
*
|
||||
*/
|
||||
@NonNull
|
||||
public SwapChain createSwapChain(int width, int height, long flags) {
|
||||
if (width >= 0 && height >= 0) {
|
||||
long nativeSwapChain = nCreateSwapChainHeadless(getNativeObject(), width, height, flags);
|
||||
if (nativeSwapChain == 0) throw new IllegalStateException("Couldn't create SwapChain");
|
||||
return new SwapChain(nativeSwapChain, null);
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid parameters");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SwapChain} from a {@link NativeSurface}.
|
||||
*
|
||||
@@ -608,6 +638,7 @@ public class Engine {
|
||||
private static native void nDestroyEngine(long nativeEngine);
|
||||
private static native long nGetBackend(long nativeEngine);
|
||||
private static native long nCreateSwapChain(long nativeEngine, Object nativeWindow, long flags);
|
||||
private static native long nCreateSwapChainHeadless(long nativeEngine, int width, int height, long flags);
|
||||
private static native long nCreateSwapChainFromRawPointer(long nativeEngine, long pointer, long flags);
|
||||
private static native void nDestroySwapChain(long nativeEngine, long nativeSwapChain);
|
||||
private static native long nCreateView(long nativeEngine);
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ package com.google.android.filament;
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class Fence {
|
||||
private long mNativeObject;
|
||||
@@ -37,6 +37,9 @@ public class Fence {
|
||||
TIMEOUT_EXPIRED
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks the current thread until the Fence signals.
|
||||
*/
|
||||
public FenceStatus wait(@NonNull Mode mode, long timeoutNanoSeconds) {
|
||||
int nativeResult = nWait(getNativeObject(), mode.ordinal(), timeoutNanoSeconds);
|
||||
switch (nativeResult) {
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
@@ -63,7 +63,10 @@ import com.google.android.filament.proguard.UsedByReflection;
|
||||
* <h1>Irradiance</h1>
|
||||
*
|
||||
* <p>The irradiance represents the light that comes from the environment and shines an
|
||||
* object's surface. It is represented as
|
||||
* object's surface.
|
||||
* The irradiance is calculated automatically from the Reflections (see below), and generally
|
||||
* doesn't need to be provided explicitly. However, it can be provided separately from the
|
||||
* Reflections as
|
||||
* <a href="https://en.wikipedia.org/wiki/Spherical_harmonics">Spherical Harmonics</a> (SH) of 1, 2 or
|
||||
* 3 bands, respectively 1, 4 or 9 coefficients.</p>
|
||||
*
|
||||
@@ -83,8 +86,7 @@ import com.google.android.filament.proguard.UsedByReflection;
|
||||
public class IndirectLight {
|
||||
long mNativeObject;
|
||||
|
||||
@UsedByReflection("KtxLoader.java")
|
||||
IndirectLight(long indirectLight) {
|
||||
public IndirectLight(long indirectLight) {
|
||||
mNativeObject = indirectLight;
|
||||
}
|
||||
|
||||
@@ -402,6 +404,7 @@ public class IndirectLight {
|
||||
* <p>The dominant light direction can be used to set a directional light's direction,
|
||||
* for instance to produce shadows that match the environment.</p>
|
||||
*
|
||||
* @param sh pre-scaled 3-bands spherical harmonics
|
||||
* @param direction an array of 3 floats to receive a unit vector representing the direction of
|
||||
* the dominant light or <code>null</code>
|
||||
* @return the <code>direction</code> paramter if it was provided, or a newly allocated float
|
||||
@@ -410,6 +413,19 @@ public class IndirectLight {
|
||||
* @see LightManager.Builder#direction
|
||||
* @see #getColorEstimate
|
||||
*/
|
||||
|
||||
@NonNull @Size(min = 3)
|
||||
public static float[] getDirectionEstimate(@NonNull float[] sh, @Nullable @Size(min = 3) float[] direction) {
|
||||
if (sh.length < 9 * 3) {
|
||||
throw new ArrayIndexOutOfBoundsException(
|
||||
"3 bands SH required, array must be at least 9 x float3");
|
||||
}
|
||||
direction = Asserts.assertFloat3(direction);
|
||||
nGetDirectionEstimateStatic(sh, direction);
|
||||
return direction;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] getDirectionEstimate(@Nullable @Size(min = 3) float[] direction) {
|
||||
direction = Asserts.assertFloat3(direction);
|
||||
@@ -417,6 +433,7 @@ public class IndirectLight {
|
||||
return direction;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to estimate the color and relative intensity of the environment in a given direction.
|
||||
*
|
||||
@@ -424,6 +441,7 @@ public class IndirectLight {
|
||||
* make sure to multiply this relative intensity by the the intensity of this indirect light.</p>
|
||||
*
|
||||
* @param colorIntensity an array of 4 floats to receive the result or <code>null</code>
|
||||
* @param sh pre-scaled 3-bands spherical harmonics
|
||||
* @param x the x coordinate of a unit vector representing the direction of the light
|
||||
* @param y the x coordinate of a unit vector representing the direction of the light
|
||||
* @param z the x coordinate of a unit vector representing the direction of the light
|
||||
@@ -438,6 +456,19 @@ public class IndirectLight {
|
||||
* @see #setIntensity
|
||||
*/
|
||||
@NonNull @Size(min = 4)
|
||||
public static float[] getColorEstimate(@Nullable @Size(min = 4) float[] colorIntensity, @NonNull float[] sh, float x, float y, float z) {
|
||||
if (sh.length < 9 * 3) {
|
||||
throw new ArrayIndexOutOfBoundsException(
|
||||
"3 bands SH required, array must be at least 9 x float3");
|
||||
}
|
||||
colorIntensity = Asserts.assertFloat4(colorIntensity);
|
||||
nGetColorEstimateStatic(colorIntensity, sh, x, y, z);
|
||||
return colorIntensity;
|
||||
}
|
||||
|
||||
|
||||
/** @deprecated */
|
||||
@NonNull @Size(min = 4)
|
||||
public float[] getColorEstimate(@Nullable @Size(min = 4) float[] colorIntensity, float x, float y, float z) {
|
||||
colorIntensity = Asserts.assertFloat4(colorIntensity);
|
||||
nGetColorEstimate(getNativeObject(), colorIntensity, x, y, z);
|
||||
@@ -472,4 +503,7 @@ public class IndirectLight {
|
||||
private static native void nGetRotation(long nativeIndirectLight, float[] outRotation);
|
||||
private static native void nGetDirectionEstimate(long nativeIndirectLight, float[] outDirection);
|
||||
private static native void nGetColorEstimate(long nativeIndirectLight, float[] outColor, float x, float y, float z);
|
||||
|
||||
private static native void nGetDirectionEstimateStatic(float[] sh, float[] direction);
|
||||
private static native void nGetColorEstimateStatic(float[] colorIntensity, float[] sh, float x, float y, float z);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
public class LightManager {
|
||||
private long mNativeObject;
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByNative;
|
||||
|
||||
@@ -141,6 +141,31 @@ public class Material {
|
||||
SCREEN,
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported refraction modes
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:refraction">
|
||||
* Blending and transparency: refractionMode</a>
|
||||
*/
|
||||
public enum RefractionMode {
|
||||
NONE,
|
||||
CUBEMAP,
|
||||
SCREEN_SPACE
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported refraction types
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:refractiontype">
|
||||
* Blending and transparency: refractionType</a>
|
||||
*/
|
||||
public enum RefractionType {
|
||||
SOLID,
|
||||
THIN
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported types of vertex domains
|
||||
*
|
||||
@@ -351,13 +376,35 @@ public class Material {
|
||||
return BlendingMode.values()[nGetBlendingMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the refraction mode of this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:refraction">
|
||||
* Blending and transparency: refraction</a>
|
||||
*/
|
||||
public RefractionMode getRefractionMode() {
|
||||
return RefractionMode.values()[nGetRefractionMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the refraction type of this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:refractiontype">
|
||||
* Blending and transparency: refractionType</a>
|
||||
*/
|
||||
public RefractionType getRefractionType() {
|
||||
return RefractionType.values()[nGetRefractionType(getNativeObject())];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the vertex domain of this material.
|
||||
*
|
||||
* @se
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/vertexandattributes:vertexdomain">
|
||||
* Vertex and attributes: vertexDomain</a>
|
||||
* @return
|
||||
*/
|
||||
public VertexDomain getVertexDomain() {
|
||||
return VertexDomain.values()[nGetVertexDomain(getNativeObject())];
|
||||
@@ -847,6 +894,9 @@ public class Material {
|
||||
private static native float nGetMaskThreshold(long nativeMaterial);
|
||||
private static native float nGetSpecularAntiAliasingVariance(long nativeMaterial);
|
||||
private static native float nGetSpecularAntiAliasingThreshold(long nativeMaterial);
|
||||
private static native int nGetRefractionMode(long nativeMaterial);
|
||||
private static native int nGetRefractionType(long nativeMaterial);
|
||||
|
||||
|
||||
private static native int nGetParameterCount(long nativeMaterial);
|
||||
private static native void nGetParameters(long nativeMaterial,
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
public class MaterialInstance {
|
||||
private Material mMaterial;
|
||||
@@ -356,7 +356,7 @@ public class MaterialInstance {
|
||||
* to produce a resolvable offset for a given implementation. This offset is added before the
|
||||
* depth test.
|
||||
*
|
||||
* @warning using a polygon offset other than zero has a significant negative performance
|
||||
* Warning: using a polygon offset other than zero has a significant negative performance
|
||||
* impact, as most implementations have to disable early depth culling. DO NOT USE unless
|
||||
* absolutely necessary.
|
||||
*
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
public final class MathUtils {
|
||||
private MathUtils() { }
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByNative;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
abstract class Platform {
|
||||
private static Platform mCurrentPlatform = null;
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An offscreen render target that can be associated with a {@link View} and contains
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
@@ -299,6 +299,94 @@ public class Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads back the content of a specified {@link RenderTarget}.
|
||||
*
|
||||
*<pre>
|
||||
*
|
||||
* Framebuffer as seen on User buffer (PixelBufferDescriptor)
|
||||
* screen
|
||||
* +--------------------+
|
||||
* | | .stride .alignment
|
||||
* | | ----------------------->-->
|
||||
* | | O----------------------+--+ low addresses
|
||||
* | | | | | |
|
||||
* | w | | | .top | |
|
||||
* | <---------> | | V | |
|
||||
* | +---------+ | | +---------+ | |
|
||||
* | | ^ | | ======> | | | | |
|
||||
* | x | h| | | |.left| | | |
|
||||
* +------>| v | | +---->| | | |
|
||||
* | +.........+ | | +.........+ | |
|
||||
* | ^ | | | |
|
||||
* | y | | +----------------------+--+ high addresses
|
||||
* O------------+-------+
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
*
|
||||
* <p>Typically <code>readPixels</code> will be called after {@link #render} and before
|
||||
* {@link #endFrame}.</p>
|
||||
* <br>
|
||||
* <p>After calling this method, the callback associated with <code>buffer</code>
|
||||
* will be invoked on the main thread, indicating that the read-back has completed.
|
||||
* Typically, this will happen after multiple calls to {@link #beginFrame},
|
||||
* {@link #render}, {@link #endFrame}.</p>
|
||||
* <br>
|
||||
* <p><code>readPixels</code> is intended for debugging and testing.
|
||||
* It will impact performance significantly.</p>
|
||||
*
|
||||
* @param renderTarget {@link RenderTarget} to read back from
|
||||
* @param xoffset left offset of the sub-region to read back
|
||||
* @param yoffset bottom offset of the sub-region to read back
|
||||
* @param width width of the sub-region to read back
|
||||
* @param height height of the sub-region to read back
|
||||
* @param buffer client-side buffer where the read-back will be written
|
||||
*
|
||||
* <p>
|
||||
* The following format are always supported:
|
||||
* <li>{@link Texture.Format#RGBA}</li>
|
||||
* <li>{@link Texture.Format#RGBA_INTEGER}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The following types are always supported:
|
||||
* <li>{@link Texture.Type#UBYTE}</li>
|
||||
* <li>{@link Texture.Type#UINT}</li>
|
||||
* <li>{@link Texture.Type#INT}</li>
|
||||
* <li>{@link Texture.Type#FLOAT}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>Other combination of format/type may be supported. If a combination is
|
||||
* not supported, this operation may fail silently. Use a DEBUG build
|
||||
* to get some logs about the failure.</p>
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*/
|
||||
public void readPixels(
|
||||
@NonNull RenderTarget renderTarget,
|
||||
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
|
||||
@IntRange(from = 0) int width, @IntRange(from = 0) int height,
|
||||
@NonNull Texture.PixelBufferDescriptor buffer) {
|
||||
|
||||
if (buffer.storage.isReadOnly()) {
|
||||
throw new ReadOnlyBufferException();
|
||||
}
|
||||
|
||||
int result = nReadPixelsEx(getNativeObject(), mEngine.getNativeObject(),
|
||||
renderTarget.getNativeObject(),
|
||||
xoffset, yoffset, width, height,
|
||||
buffer.storage, buffer.storage.remaining(),
|
||||
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
|
||||
buffer.stride, buffer.format.ordinal(),
|
||||
buffer.handler, buffer.callback);
|
||||
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a timestamp (in seconds) for the last call to {@link #beginFrame}. This value is
|
||||
* constant for all {@link View views} rendered during a frame. The epoch is set with
|
||||
@@ -355,7 +443,7 @@ public class Renderer {
|
||||
* <br>
|
||||
* <p>Use this method used to keep the precision of time high in materials, in practice it should
|
||||
* be called at least when the application is paused, e.g.
|
||||
* {@link android.app.Activity#onPause() Activity.onPause} in Android.</p>
|
||||
* <code>Activity.onPause</code> in Android.</p>
|
||||
*
|
||||
* @see #getUserTime
|
||||
*/
|
||||
@@ -386,6 +474,12 @@ public class Renderer {
|
||||
Buffer storage, int remaining,
|
||||
int left, int top, int type, int alignment, int stride, int format,
|
||||
Object handler, Runnable callback);
|
||||
private static native int nReadPixelsEx(long nativeRenderer, long nativeEngine,
|
||||
long nativeRenderTarget,
|
||||
int xoffset, int yoffset, int width, int height,
|
||||
Buffer storage, int remaining,
|
||||
int left, int top, int type, int alignment, int stride, int format,
|
||||
Object handler, Runnable callback);
|
||||
private static native double nGetUserTime(long nativeRenderer);
|
||||
private static native void nResetUserTime(long nativeRenderer);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A <code>Scene</code> is a flat container of {@link RenderableManager} and {@link LightManager}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
@@ -49,8 +49,7 @@ import com.google.android.filament.proguard.UsedByReflection;
|
||||
public class Skybox {
|
||||
private long mNativeObject;
|
||||
|
||||
@UsedByReflection("KtxLoader.java")
|
||||
Skybox(long nativeSkybox) {
|
||||
public Skybox(long nativeSkybox) {
|
||||
mNativeObject = nativeSkybox;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
@@ -33,6 +33,20 @@ public class Stream {
|
||||
private long mNativeObject;
|
||||
private long mNativeEngine;
|
||||
|
||||
/**
|
||||
* Represents the immutable stream type.
|
||||
*/
|
||||
public enum StreamType {
|
||||
/** Not synchronized but copy-free. Good for video. */
|
||||
NATIVE,
|
||||
|
||||
/** Synchronized, but GL-only and incurs copies. Good for AR on devices before API 26. */
|
||||
TEXTURE_ID,
|
||||
|
||||
/** Synchronized, copy-free, and take a release callback. Good for AR but requires API 26+. */
|
||||
ACQUIRED,
|
||||
};
|
||||
|
||||
Stream(long nativeStream, Engine engine) {
|
||||
mNativeObject = nativeStream;
|
||||
mNativeEngine = engine.getNativeObject();
|
||||
@@ -40,6 +54,12 @@ public class Stream {
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct an Stream object instance.
|
||||
*
|
||||
* By default, Stream objects are {@link StreamType#ACQUIRED ACQUIRED} and must have external images pushed to them via
|
||||
* {@link #setAcquiredImage}.
|
||||
*
|
||||
* To create a {@link StreamType#NATIVE NATIVE} or {@link StreamType#TEXTURE_ID TEXTURE_ID} stream, call one of the <pre>stream</pre> methods
|
||||
* on the builder.
|
||||
*/
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
@@ -55,8 +75,8 @@ public class Stream {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a native stream. Native streams can sample data directly from an
|
||||
* opaque platform object such as a {@link android.graphics.SurfaceTexture SurfaceTexture}
|
||||
* Creates a {@link StreamType#NATIVE NATIVE} stream. Native streams can sample data
|
||||
* directly from an opaque platform object such as a {@link android.graphics.SurfaceTexture SurfaceTexture}
|
||||
* on Android.
|
||||
*
|
||||
* @param streamSource an opaque native stream handle, e.g.: on Android this must be a
|
||||
@@ -74,7 +94,7 @@ public class Stream {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy stream. A copy stream will sample data from the supplied
|
||||
* Creates a {@link StreamType#TEXTURE_ID TEXTURE_ID} stream. A copy stream will sample data from the supplied
|
||||
* external texture and copy it into an internal private texture.
|
||||
*
|
||||
* <p>Currently only OpenGL external texture ids are supported.</p>
|
||||
@@ -150,12 +170,24 @@ public class Stream {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this <code>Stream</code> is a native stream or a copy stream.
|
||||
*
|
||||
* @return true if this is a native <code>Stream</code>, false otherwise.
|
||||
* Indicates whether this <code>Stream</code> is NATIVE, TEXTURE_ID, or ACQUIRED.
|
||||
*/
|
||||
public boolean isNative() {
|
||||
return nIsNative(getNativeObject());
|
||||
public StreamType getStreamType() {
|
||||
return StreamType.values()[nGetStreamType(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an <pre>ACQUIRED</pre> stream with an image that is guaranteed to be used in the next frame.
|
||||
*
|
||||
* This method should be called on the same thread that calls {#link Renderer#beginFrame}, which is
|
||||
* also where the callback is invoked.
|
||||
*
|
||||
* @param hwbuffer {@link android.hardware.HardwareBuffer HardwareBuffer} (requires API level 26)
|
||||
* @param handler {@link java.util.concurrent.Executor Executor} or {@link android.os.Handler Handler}.
|
||||
* @param callback a callback invoked by <code>handler</code> when the <code>hwbuffer</code> can be released.
|
||||
*/
|
||||
public void setAcquiredImage(Object hwbuffer, Object handler, Runnable callback) {
|
||||
nSetAcquiredImage(getNativeObject(), mNativeEngine, hwbuffer, handler, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +206,7 @@ public class Stream {
|
||||
* Reads back the content of the last frame of a <code>Stream</code> since the last call to
|
||||
* {@link Renderer#beginFrame}.
|
||||
*
|
||||
* <p>The Stream must be a copy stream, which can be checked with {@link #isNative()}.
|
||||
* <p>The Stream must be a copy stream, which can be checked with {@link #getStreamType()}.
|
||||
* This function is a no-op otherwise.</p>
|
||||
*
|
||||
* <pre>
|
||||
@@ -286,6 +318,7 @@ public class Stream {
|
||||
private static native void nBuilderHeight(long nativeStreamBuilder, int height);
|
||||
private static native long nBuilderBuild(long nativeStreamBuilder, long nativeEngine);
|
||||
|
||||
private static native int nGetStreamType(long nativeStream);
|
||||
private static native void nSetDimensions(long nativeStream, int width, int height);
|
||||
private static native int nReadPixels(long nativeStream, long nativeEngine,
|
||||
int xoffset, int yoffset, int width, int height,
|
||||
@@ -293,6 +326,6 @@ public class Stream {
|
||||
int left, int top, int type, int alignment, int stride, int format,
|
||||
Object handler, Runnable callback);
|
||||
private static native long nGetTimestamp(long nativeStream);
|
||||
|
||||
private static native boolean nIsNative(long nativeStream);
|
||||
private static native void nSetAcquiredImage(long nativeStream, long nativeEngine,
|
||||
Object hwbuffer, Object handler, Runnable callback);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* A <code>SwapChain</code> represents an Operating System's <b>native</b> renderable surface.
|
||||
@@ -85,15 +85,15 @@ public class SwapChain {
|
||||
*/
|
||||
public static final long CONFIG_READABLE = 0x2;
|
||||
|
||||
SwapChain(long nativeSwapChain, @NonNull Object surface) {
|
||||
SwapChain(long nativeSwapChain, Object surface) {
|
||||
mNativeObject = nativeSwapChain;
|
||||
mSurface = surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the native <code>Object</code> this <code>SwapChain</code> was created from.
|
||||
* @return the native <code>Object</code> this <code>SwapChain</code> was created from or null
|
||||
* for a headless SwapChain.
|
||||
*/
|
||||
@NonNull
|
||||
public Object getNativeWindow() {
|
||||
return mSurface;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
@@ -73,8 +73,7 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
|
||||
public class Texture {
|
||||
private long mNativeObject;
|
||||
|
||||
@UsedByReflection("KtxLoader.java")
|
||||
Texture(long nativeTexture) {
|
||||
public Texture(long nativeTexture) {
|
||||
mNativeObject = nativeTexture;
|
||||
}
|
||||
|
||||
@@ -322,13 +321,26 @@ public class Texture {
|
||||
public CompressedFormat compressedFormat;
|
||||
|
||||
@Nullable public Object handler;
|
||||
@Nullable public Runnable callback;
|
||||
|
||||
/**
|
||||
* Valid handler types:
|
||||
* - Android: Handler, Executor
|
||||
* - Other: Executor
|
||||
* Callback used to destroy the buffer data.
|
||||
* <p>
|
||||
* Guarantees:
|
||||
* <ul>
|
||||
* <li>Called on the main filament thread.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Limitations:
|
||||
* <ul>
|
||||
* <li>Must be lightweight.</li>
|
||||
* <li>Must not call filament APIs.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
@Nullable public Runnable callback;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a <code>PixelBufferDescriptor</code>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* <code>TextureSampler</code> defines how a texture is accessed.
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
/**
|
||||
* <code>TransformManager</code> is used to add transform components to entities.
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import static com.google.android.filament.Colors.LinearColor;
|
||||
|
||||
@@ -149,6 +149,11 @@ public class View {
|
||||
* How each dimension of the AO buffer is scaled. Must be positive and <= 1.
|
||||
*/
|
||||
public float resolution = 0.5f;
|
||||
|
||||
/**
|
||||
* Strength of the Ambient Occlusion effect. Must be positive.
|
||||
*/
|
||||
public float intensity = 1.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -620,6 +625,8 @@ public class View {
|
||||
/**
|
||||
* Sets whether this view is rendered with or without a depth pre-pass.
|
||||
*
|
||||
* <p><b>This setting is ignored and will be removed in future versions of Filament.</b></p>
|
||||
*
|
||||
* <p>
|
||||
* By default, the system picks the most appropriate strategy for your platform; this method
|
||||
* lets you override that strategy.
|
||||
@@ -642,6 +649,7 @@ public class View {
|
||||
* <li>DepthPrepass::ENABLE enables the depth pre-pass</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Deprecated
|
||||
public void setDepthPrepass(@NonNull DepthPrepass depthPrepass) {
|
||||
mDepthPrepass = depthPrepass;
|
||||
nSetDepthPrepass(getNativeObject(), depthPrepass.value);
|
||||
@@ -761,7 +769,8 @@ public class View {
|
||||
*/
|
||||
public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) {
|
||||
mAmbientOcclusionOptions = options;
|
||||
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power, options.resolution);
|
||||
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power,
|
||||
options.resolution, options.intensity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -819,5 +828,5 @@ 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);
|
||||
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import androidx.annotation.IntRange;
|
||||
|
||||
/**
|
||||
* Specifies a rectangular region within a render target in terms of pixel coordinates.
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.google.android.filament.android;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Texture;
|
||||
|
||||
@@ -19,8 +19,8 @@ package com.google.android.filament.android;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
@@ -131,6 +131,7 @@ public class UiHelper {
|
||||
private RenderSurface mRenderSurface;
|
||||
|
||||
private boolean mOpaque = true;
|
||||
private boolean mOverlay = false;
|
||||
|
||||
/**
|
||||
* Enum used to decide whether UiHelper should perform extra error checking.
|
||||
@@ -173,7 +174,7 @@ public class UiHelper {
|
||||
void detach();
|
||||
}
|
||||
|
||||
private class SurfaceViewHandler implements RenderSurface {
|
||||
private static class SurfaceViewHandler implements RenderSurface {
|
||||
private SurfaceView mSurfaceView;
|
||||
|
||||
SurfaceViewHandler(SurfaceView surface) {
|
||||
@@ -323,6 +324,30 @@ public class UiHelper {
|
||||
mOpaque = opaque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the SurfaceView used as a render target should be positioned above
|
||||
* other surfaces but below the activity's surface. False by default.
|
||||
*/
|
||||
public boolean isMediaOverlay() {
|
||||
return mOverlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether the surface of the SurfaceView used as a render target should be
|
||||
* positioned above other surfaces but below the activity's surface. This property
|
||||
* only has an effect when used in combination with {@link #setOpaque(boolean) setOpaque(false)}
|
||||
* and does not affect TextureView targets.
|
||||
*
|
||||
* Must be called before calling {@link #attachTo(SurfaceView)}
|
||||
* or {@link #attachTo(TextureView)}.
|
||||
*
|
||||
* @param overlay Indicates whether the render target should be rendered below the activity's
|
||||
* surface when transparent.
|
||||
*/
|
||||
public void setMediaOverlay(boolean overlay) {
|
||||
mOverlay = overlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flags to pass to
|
||||
* {@link com.google.android.filament.Engine#createSwapChain(Object, long)} to honor all
|
||||
@@ -340,11 +365,18 @@ public class UiHelper {
|
||||
*/
|
||||
public void attachTo(@NonNull SurfaceView view) {
|
||||
if (attach(view)) {
|
||||
if (!isOpaque()) {
|
||||
view.setZOrderOnTop(true);
|
||||
view.getHolder().setFormat(PixelFormat.TRANSLUCENT);
|
||||
boolean translucent = !isOpaque();
|
||||
// setZOrderOnTop() and setZOrderMediaOverlay() override each other,
|
||||
// we must only call one of them
|
||||
if (isMediaOverlay()) {
|
||||
view.setZOrderMediaOverlay(translucent);
|
||||
} else {
|
||||
view.setZOrderOnTop(translucent);
|
||||
}
|
||||
|
||||
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
|
||||
view.getHolder().setFormat(format);
|
||||
|
||||
mRenderSurface = new SurfaceViewHandler(view);
|
||||
|
||||
final SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
|
||||
@@ -377,7 +409,6 @@ public class UiHelper {
|
||||
final Surface surface = holder.getSurface();
|
||||
if (surface != null && surface.isValid()) {
|
||||
callback.surfaceCreated(holder);
|
||||
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
|
||||
callback.surfaceChanged(holder, format,
|
||||
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
/app/src/main/assets
|
||||
.externalNativeBuild
|
||||
/.cxx
|
||||
104
android/filament-utils-android/CMakeLists.txt
Normal file
104
android/filament-utils-android/CMakeLists.txt
Normal file
@@ -0,0 +1,104 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
|
||||
set(DISABLE_GLTFIO_JNI TRUE)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../gltfio-android ${CMAKE_CURRENT_BINARY_DIR}/gltfio-android)
|
||||
|
||||
add_library(filament STATIC IMPORTED)
|
||||
set_target_properties(filament PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament.a)
|
||||
|
||||
add_library(backend STATIC IMPORTED)
|
||||
set_target_properties(backend PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbackend.a)
|
||||
|
||||
add_library(camutils STATIC IMPORTED)
|
||||
set_target_properties(camutils PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libcamutils.a)
|
||||
|
||||
add_library(utils STATIC IMPORTED)
|
||||
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
|
||||
|
||||
add_library(filaflat STATIC IMPORTED)
|
||||
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
|
||||
|
||||
add_library(image STATIC IMPORTED)
|
||||
set_target_properties(image PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
|
||||
|
||||
add_library(ibl STATIC IMPORTED)
|
||||
set_target_properties(ibl PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libibl.a)
|
||||
|
||||
add_library(geometry STATIC IMPORTED)
|
||||
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
|
||||
|
||||
add_library(filabridge STATIC IMPORTED)
|
||||
set_target_properties(filabridge PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilabridge.a)
|
||||
|
||||
add_library(gltfio STATIC IMPORTED)
|
||||
set_target_properties(gltfio PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_core.a)
|
||||
|
||||
add_library(gltfio_resources STATIC IMPORTED)
|
||||
set_target_properties(gltfio_resources PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_resources.a)
|
||||
|
||||
add_library(bluevk STATIC IMPORTED)
|
||||
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbluevk.a)
|
||||
|
||||
add_library(smol-v STATIC IMPORTED)
|
||||
set_target_properties(smol-v PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libsmol-v.a)
|
||||
|
||||
include_directories(${FILAMENT_DIR}/include
|
||||
..
|
||||
../../libs/utils/include)
|
||||
|
||||
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/Bookmark.cpp
|
||||
src/main/cpp/Utils.cpp
|
||||
src/main/cpp/Manipulator.cpp
|
||||
|
||||
../common/CallbackUtils.cpp
|
||||
../common/NioUtils.cpp
|
||||
|
||||
$<TARGET_OBJECTS:gltfio-jni-obj>
|
||||
$<TARGET_OBJECTS:filament-jni-obj>
|
||||
)
|
||||
|
||||
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.symbols)
|
||||
|
||||
# The ordering in the following list is important because CMake does not have dependency information.
|
||||
target_link_libraries(filament-utils-jni
|
||||
gltfio
|
||||
filament
|
||||
backend
|
||||
filaflat
|
||||
filabridge
|
||||
camutils
|
||||
geometry
|
||||
image
|
||||
ibl
|
||||
utils
|
||||
log
|
||||
GLESv3
|
||||
EGL
|
||||
android
|
||||
jnigraphics
|
||||
gltfio_resources
|
||||
m
|
||||
)
|
||||
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
target_link_libraries(filament-utils-jni bluevk smol-v)
|
||||
endif()
|
||||
63
android/filament-utils-android/build.gradle
Normal file
63
android/filament-utils-android/build.gradle
Normal file
@@ -0,0 +1,63 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
android {
|
||||
buildToolsVersion versions.buildTools
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
minSdkVersion versions.minSdk
|
||||
targetSdkVersion versions.targetSdk
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DANDROID_PIE=ON")
|
||||
arguments.add("-DANDROID_PLATFORM=android-${versions.targetSdk}".toString())
|
||||
arguments.add("-DANDROID_STL=c++_static")
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filamentPath}".toString())
|
||||
cppFlags.add("-std=c++14")
|
||||
if (project.hasProperty('extra_cmake_args')) {
|
||||
arguments.add(extra_cmake_args)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
jni.srcDirs "src/main/cpp"
|
||||
kotlin.srcDirs += "src/main/java"
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation deps.kotlin
|
||||
implementation deps.androidx.annotations
|
||||
implementation project(':filament-android')
|
||||
implementation project(':gltfio-android')
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
|
||||
afterEvaluate { project ->
|
||||
publishing {
|
||||
publications {
|
||||
release(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID
|
||||
from components.release
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
android/filament-utils-android/gradle.properties
Normal file
3
android/filament-utils-android/gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
POM_NAME=Filament Android Utilities
|
||||
POM_ARTIFACT_ID=filament-utils-android
|
||||
POM_PACKAGING=aar
|
||||
4
android/filament-utils-android/libfilament-utils-jni.map
Normal file
4
android/filament-utils-android/libfilament-utils-jni.map
Normal file
@@ -0,0 +1,4 @@
|
||||
LIBFILAMENT_UTILS {
|
||||
global: Java_com_google_android_filament_*; JNI*;
|
||||
local: *;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
_Java_com_google_android_filament_*
|
||||
18
android/filament-utils-android/src/main/AndroidManifest.xml
Normal file
18
android/filament-utils-android/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.google.android.filament.utils" />
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
* Copyright (C) 2020 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.
|
||||
@@ -14,15 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_METALDEFINES_H
|
||||
#define TNT_METALDEFINES_H
|
||||
#include <jni.h>
|
||||
|
||||
// Filament fences are implemented with MTLSharedEvent, which are only available on
|
||||
// OSX 10.14+ and iOS 12.0+
|
||||
#if defined(IOS)
|
||||
#define METAL_FENCES_SUPPORTED (__IPHONE_OS_VERSION_MAX_ALLOWED > 120000)
|
||||
#else
|
||||
#define METAL_FENCES_SUPPORTED (MAC_OS_X_VERSION_MAX_ALLOWED > 101400)
|
||||
#endif
|
||||
#include <camutils/Bookmark.h>
|
||||
|
||||
#endif //TNT_METALDEFINES_H
|
||||
using namespace filament::camutils;
|
||||
using namespace filament::math;
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Bookmark_nDestroyBookmark(JNIEnv*, jclass, jlong nativeBookmark) {
|
||||
Bookmark<float>* bookmark = (Bookmark<float>*) nativeBookmark;
|
||||
delete bookmark;
|
||||
}
|
||||
193
android/filament-utils-android/src/main/cpp/Manipulator.cpp
Normal file
193
android/filament-utils-android/src/main/cpp/Manipulator.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 <math/mat3.h>
|
||||
#include <math/vec3.h>
|
||||
|
||||
#include <camutils/Manipulator.h>
|
||||
|
||||
using namespace filament::camutils;
|
||||
using namespace filament::math;
|
||||
|
||||
using Builder = Manipulator<float>::Builder;
|
||||
|
||||
extern "C" JNIEXPORT jlong Java_com_google_android_filament_utils_Manipulator_nCreateBuilder(JNIEnv*, jclass) {
|
||||
return (jlong) new Builder {};
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nDestroyBuilder(JNIEnv*, jclass, jlong nativeBuilder) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderViewport(JNIEnv*, jclass, jlong nativeBuilder, jint width, jint height) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->viewport(width, height);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderTargetPosition(JNIEnv*, jclass, jlong nativeBuilder, jfloat x, jfloat y, jfloat z) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->targetPosition(x, y, z);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderUpVector(JNIEnv*, jclass, jlong nativeBuilder, jfloat x, jfloat y, jfloat z) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->upVector(x, y, z);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderZoomSpeed(JNIEnv*, jclass, jlong nativeBuilder, jfloat arg) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->zoomSpeed(arg);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderOrbitHomePosition(JNIEnv*, jclass, jlong nativeBuilder, jfloat x, jfloat y, jfloat z) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->orbitHomePosition(x, y, z);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderOrbitSpeed(JNIEnv*, jclass, jlong nativeBuilder, jfloat x, jfloat y) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->orbitSpeed(x, y);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderFovDirection(JNIEnv*, jclass, jlong nativeBuilder, jint arg) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->fovDirection((Fov) arg);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderFovDegrees(JNIEnv*, jclass, jlong nativeBuilder, jfloat arg) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->fovDegrees(arg);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderFarPlane(JNIEnv*, jclass, jlong nativeBuilder, jfloat distance) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->farPlane(distance);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderMapExtent(JNIEnv*, jclass, jlong nativeBuilder, jfloat width, jfloat height) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->mapExtent(width, height);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderMapMinDistance(JNIEnv*, jclass, jlong nativeBuilder, jfloat arg) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->mapMinDistance(arg);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderGroundPlane(JNIEnv*, jclass, jlong nativeBuilder, jfloat a, jfloat b, jfloat c, jfloat d) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->groundPlane(a, b, c, d);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long Java_com_google_android_filament_utils_Manipulator_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder, jint mode) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
return (jlong) builder->build((Mode) mode);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_Manipulator_nDestroyManipulator(JNIEnv*, jclass, jlong nativeManip) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
delete manip;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL Java_com_google_android_filament_utils_Manipulator_nGetMode(JNIEnv*, jclass, jlong nativeManip) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
return (int) manip->getMode();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nSetViewport(JNIEnv*, jclass, jlong nativeManip, jint width, jint height) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
manip->setViewport(width, height);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nGetLookAtFloat(JNIEnv* env, jclass, jlong nativeManip, jfloatArray eyePosition, jfloatArray targetPosition, jfloatArray upward) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
|
||||
jfloat *eye = env->GetFloatArrayElements(eyePosition, NULL);
|
||||
jfloat *target = env->GetFloatArrayElements(targetPosition, NULL);
|
||||
jfloat *up = env->GetFloatArrayElements(upward, NULL);
|
||||
|
||||
manip->getLookAt((float3*) eye, (float3*) target, (float3*) up);
|
||||
|
||||
env->ReleaseFloatArrayElements(eyePosition, eye, 0);
|
||||
env->ReleaseFloatArrayElements(targetPosition, target, 0);
|
||||
env->ReleaseFloatArrayElements(upward, up, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nGetLookAtDouble(JNIEnv* env, jclass, jlong nativeManip, jdoubleArray eyePosition, jdoubleArray targetPosition, jdoubleArray upward) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
float3 eyef, targetf, upf;
|
||||
manip->getLookAt(&eyef, &targetf, &upf);
|
||||
|
||||
jdouble *eye = env->GetDoubleArrayElements(eyePosition, NULL);
|
||||
jdouble *target = env->GetDoubleArrayElements(targetPosition, NULL);
|
||||
jdouble *up = env->GetDoubleArrayElements(upward, NULL);
|
||||
|
||||
*((double3*) eye) = eyef;
|
||||
*((double3*) target) = targetf;
|
||||
*((double3*) up) = upf;
|
||||
|
||||
env->ReleaseDoubleArrayElements(eyePosition, eye, 0);
|
||||
env->ReleaseDoubleArrayElements(targetPosition, target, 0);
|
||||
env->ReleaseDoubleArrayElements(upward, up, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nRaycast(JNIEnv* env, jclass, jlong nativeManip, jint x, jint y, jfloatArray result) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
jfloat *presult = env->GetFloatArrayElements(result, NULL);
|
||||
manip->raycast(x, y, (float3*) presult);
|
||||
env->ReleaseFloatArrayElements(result, presult, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nGrabBegin(JNIEnv*, jclass, jlong nativeManip, jint x, jint y, jboolean strafe) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
manip->grabBegin(x, y, (bool) strafe);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nGrabUpdate(JNIEnv*, jclass, jlong nativeManip, jint x, jint y) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
manip->grabUpdate(x, y);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nGrabEnd(JNIEnv*, jclass, jlong nativeManip) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
manip->grabEnd();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nZoom(JNIEnv*, jclass, jlong nativeManip, jint x, jint y, jfloat scrolldelta) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
manip->zoom(x, y, scrolldelta);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL Java_com_google_android_filament_utils_Manipulator_nGetCurrentBookmark(JNIEnv*, jclass, jlong nativeManip) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
return (jlong) new Bookmark<float>(manip->getCurrentBookmark());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL Java_com_google_android_filament_utils_Manipulator_nGetHomeBookmark(JNIEnv*, jclass, jlong nativeManip) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
return (jlong) new Bookmark<float>(manip->getHomeBookmark());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nJumpToBookmark(JNIEnv*, jclass, jlong nativeManip, jlong nativeBookmark) {
|
||||
auto manip = (Manipulator<float>*) nativeManip;
|
||||
auto bookmark = (Bookmark<float>*) nativeBookmark;
|
||||
manip->jumpToBookmark(*bookmark);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
* Copyright (C) 2020 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.
|
||||
@@ -28,8 +28,23 @@ using namespace filament;
|
||||
using namespace filament::math;
|
||||
using namespace image;
|
||||
|
||||
extern void registerCallbackUtils(JNIEnv*);
|
||||
extern void registerNioUtils(JNIEnv*);
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||
JNIEnv* env;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
registerCallbackUtils(env);
|
||||
registerNioUtils(env);
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_KtxLoader_nCreateTexture(JNIEnv* env, jclass,
|
||||
Java_com_google_android_filament_utils_KtxLoader_nCreateTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
@@ -41,7 +56,7 @@ Java_com_google_android_filament_gltfio_KtxLoader_nCreateTexture(JNIEnv* env, jc
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_KtxLoader_nCreateIndirectLight(JNIEnv* env, jclass,
|
||||
Java_com_google_android_filament_utils_KtxLoader_nCreateIndirectLight(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
@@ -64,7 +79,7 @@ Java_com_google_android_filament_gltfio_KtxLoader_nCreateIndirectLight(JNIEnv* e
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_KtxLoader_nCreateSkybox(JNIEnv* env, jclass,
|
||||
Java_com_google_android_filament_utils_KtxLoader_nCreateSkybox(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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;
|
||||
|
||||
public class Bookmark {
|
||||
private long mNativeObject;
|
||||
|
||||
Bookmark(long nativeObject) {
|
||||
mNativeObject = nativeObject;
|
||||
}
|
||||
|
||||
long getNativeObject() {
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
nDestroyBookmark(mNativeObject);
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
private static native void nDestroyBookmark(long nativeObject);
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 android.view.MotionEvent
|
||||
import android.view.View
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Responds to Android touch events and manages a camera manipulator.
|
||||
* Supports one-touch orbit, two-touch pan, and pinch-to-zoom.
|
||||
*/
|
||||
class GestureDetector(private val view: View, private val manipulator: Manipulator) {
|
||||
private enum class Gesture { NONE, ORBIT, PAN, ZOOM }
|
||||
|
||||
// Simplified memento of MotionEvent, minimal but sufficient for our purposes.
|
||||
private data class TouchPair(var pt0: Float2, var pt1: Float2, var count: Int) {
|
||||
constructor() : this(Float2(0f), Float2(0f), 0)
|
||||
constructor(me: MotionEvent, height: Int) : this() {
|
||||
if (me.pointerCount >= 1) {
|
||||
this.pt0 = Float2(me.getX(0), height - me.getY(0))
|
||||
this.pt1 = this.pt0
|
||||
this.count++
|
||||
}
|
||||
if (me.pointerCount >= 2) {
|
||||
this.pt1 = Float2(me.getX(1), height - me.getY(1))
|
||||
this.count++
|
||||
}
|
||||
}
|
||||
val separation get() = distance(pt0, pt1)
|
||||
val midpoint get() = mix(pt0, pt1, 0.5f)
|
||||
val x: Int get() = midpoint.x.toInt()
|
||||
val y: Int get() = midpoint.y.toInt()
|
||||
}
|
||||
|
||||
private var currentGesture = Gesture.NONE
|
||||
private var previousTouch = TouchPair()
|
||||
private val tentativePanEvents = ArrayList<TouchPair>()
|
||||
private val tentativeOrbitEvents = ArrayList<TouchPair>()
|
||||
private val tentativeZoomEvents = ArrayList<TouchPair>()
|
||||
|
||||
private val kGestureConfidenceCount = 2
|
||||
private val kPanConfidenceDistance = 4
|
||||
private val kZoomConfidenceDistance = 10
|
||||
private val kZoomSpeed = 1f / 10f
|
||||
|
||||
fun onTouchEvent(event: MotionEvent) {
|
||||
val touch = TouchPair(event, view.height)
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
|
||||
// CANCEL GESTURE DUE TO UNEXPECTED POINTER COUNT
|
||||
|
||||
if ((event.pointerCount != 1 && currentGesture == Gesture.ORBIT) ||
|
||||
(event.pointerCount != 2 && currentGesture == Gesture.PAN) ||
|
||||
(event.pointerCount != 2 && currentGesture == Gesture.ZOOM)) {
|
||||
endGesture()
|
||||
return
|
||||
}
|
||||
|
||||
// UPDATE EXISTING GESTURE
|
||||
|
||||
if (currentGesture == Gesture.ZOOM) {
|
||||
val d0 = previousTouch.separation
|
||||
val d1 = touch.separation
|
||||
manipulator.zoom(touch.x, touch.y, (d0 - d1) * kZoomSpeed)
|
||||
previousTouch = touch
|
||||
return
|
||||
}
|
||||
|
||||
if (currentGesture != Gesture.NONE) {
|
||||
manipulator.grabUpdate(touch.x, touch.y)
|
||||
return
|
||||
}
|
||||
|
||||
// DETECT NEW GESTURE
|
||||
|
||||
if (event.pointerCount == 1) {
|
||||
tentativeOrbitEvents.add(touch)
|
||||
}
|
||||
|
||||
if (event.pointerCount == 2) {
|
||||
tentativePanEvents.add(touch)
|
||||
tentativeZoomEvents.add(touch)
|
||||
}
|
||||
|
||||
if (isOrbitGesture()) {
|
||||
manipulator.grabBegin(touch.x, touch.y, false)
|
||||
currentGesture = Gesture.ORBIT
|
||||
return
|
||||
}
|
||||
|
||||
if (isZoomGesture()) {
|
||||
currentGesture = Gesture.ZOOM
|
||||
previousTouch = touch
|
||||
return
|
||||
}
|
||||
|
||||
if (isPanGesture()) {
|
||||
manipulator.grabBegin(touch.x, touch.y, true)
|
||||
currentGesture = Gesture.PAN
|
||||
return
|
||||
}
|
||||
}
|
||||
MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
|
||||
endGesture()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun endGesture() {
|
||||
tentativePanEvents.clear()
|
||||
tentativeOrbitEvents.clear()
|
||||
tentativeZoomEvents.clear()
|
||||
currentGesture = Gesture.NONE
|
||||
manipulator.grabEnd()
|
||||
}
|
||||
|
||||
private fun isOrbitGesture(): Boolean {
|
||||
return tentativeOrbitEvents.size > kGestureConfidenceCount
|
||||
}
|
||||
|
||||
private fun isPanGesture(): Boolean {
|
||||
if (tentativePanEvents.size <= kGestureConfidenceCount) {
|
||||
return false
|
||||
}
|
||||
val oldest = tentativePanEvents.first().midpoint
|
||||
val newest = tentativePanEvents.last().midpoint
|
||||
return distance(oldest, newest) > kPanConfidenceDistance
|
||||
}
|
||||
|
||||
private fun isZoomGesture(): Boolean {
|
||||
if (tentativeZoomEvents.size <= kGestureConfidenceCount) {
|
||||
return false
|
||||
}
|
||||
val oldest = tentativeZoomEvents.first().separation
|
||||
val newest = tentativeZoomEvents.last().separation
|
||||
return kotlin.math.abs(newest - oldest) > kZoomConfidenceDistance
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.IndirectLight
|
||||
import com.google.android.filament.Skybox
|
||||
import com.google.android.filament.Texture
|
||||
|
||||
import java.nio.Buffer
|
||||
|
||||
/**
|
||||
* Utilities for consuming KTX files and producing Filament textures, IBLs, and sky boxes.
|
||||
*
|
||||
* KTX is a simple container format that makes it easy to bundle miplevels and cubemap faces
|
||||
* into a single file.
|
||||
*/
|
||||
object KtxLoader {
|
||||
class Options {
|
||||
var srgb = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes the content of a KTX file and produces a [Texture] object.
|
||||
*
|
||||
* @param engine Gets passed to the builder.
|
||||
* @param buffer The content of the KTX File.
|
||||
* @param options Loader options.
|
||||
* @return The resulting Filament texture, or null on failure.
|
||||
*/
|
||||
fun createTexture(engine: Engine, buffer: Buffer, options: Options): Texture {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeTexture = nCreateTexture(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return Texture(nativeTexture)
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes the content of a KTX file and produces an [IndirectLight] object.
|
||||
*
|
||||
* @param engine Gets passed to the builder.
|
||||
* @param buffer The content of the KTX File.
|
||||
* @param options Loader options.
|
||||
* @return The resulting Filament texture, or null on failure.
|
||||
*/
|
||||
fun createIndirectLight(engine: Engine, buffer: Buffer, options: Options): IndirectLight {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeIndirectLight = nCreateIndirectLight(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return IndirectLight(nativeIndirectLight)
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes the content of a KTX file and produces a [Skybox] object.
|
||||
*
|
||||
* @param engine Gets passed to the builder.
|
||||
* @param buffer The content of the KTX File.
|
||||
* @param options Loader options.
|
||||
* @return The resulting Filament texture, or null on failure.
|
||||
*/
|
||||
fun createSkybox(engine: Engine, buffer: Buffer, options: Options): Skybox {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeSkybox = nCreateSkybox(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return Skybox(nativeSkybox)
|
||||
}
|
||||
|
||||
private external fun nCreateTexture(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 nCreateSkybox(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
/**
|
||||
* Helper that enables camera interaction similar to sketchfab or Google Maps.
|
||||
*
|
||||
* Clients notify the camera manipulator of various mouse or touch events, then periodically call
|
||||
* its getLookAt() method so that they can adjust their camera(s). Two modes are supported: ORBIT
|
||||
* and MAP. To construct a manipulator instance, the desired mode is passed into the create method.
|
||||
*
|
||||
* @see Bookmark
|
||||
*/
|
||||
public class Manipulator {
|
||||
private long mNativeObject;
|
||||
|
||||
private Manipulator(long nativeIndexBuffer) {
|
||||
mNativeObject = nativeIndexBuffer;
|
||||
}
|
||||
|
||||
public enum Mode { ORBIT, MAP };
|
||||
|
||||
public enum Fov { VERTICAL, HORIZONTAL };
|
||||
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
// Keep to finalize native resources
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Width and height of the viewing area.
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder viewport(@IntRange(from = 1) int width, @IntRange(from = 1) int height) {
|
||||
nBuilderViewport(mNativeBuilder, width, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets world-space position of interest, which defaults to (0,0,0).
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder targetPosition(float x, float y, float z) {
|
||||
nBuilderTargetPosition(mNativeBuilder, x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets orientation for the home position, which defaults to (0,1,0).
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder upVector(float x, float y, float z) {
|
||||
nBuilderUpVector(mNativeBuilder, x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scroll delta multiplier, which defaults to 0.01.
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder zoomSpeed(float arg) {
|
||||
nBuilderZoomSpeed(mNativeBuilder, arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets initial eye position in world space for ORBIT mode.
|
||||
* This defaults to (0,0,1).
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder orbitHomePosition(float x, float y, float z) {
|
||||
nBuilderOrbitHomePosition(mNativeBuilder, x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the multiplier with viewport delta for ORBIT mode.
|
||||
* This defaults to 0.01
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder orbitSpeed(float x, float y) {
|
||||
nBuilderOrbitSpeed(mNativeBuilder, x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the FOV axis that's held constant when the viewport changes.
|
||||
* This defaults to Vertical.
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder fovDirection(Fov fov) {
|
||||
nBuilderFovDirection(mNativeBuilder, fov.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the full FOV (not the half-angle) in the degrees.
|
||||
* This defaults to 33.
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder fovDegrees(float arg) {
|
||||
nBuilderFovDegrees(mNativeBuilder, arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the distance to the far plane, which defaults to 5000.
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder farPlane(float arg) {
|
||||
nBuilderFarPlane(mNativeBuilder, arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ground plane size used to compute the home position for MAP mode.
|
||||
* This defaults to 512 x 512
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder mapExtent(float width, float height) {
|
||||
nBuilderMapExtent(mNativeBuilder, width, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constrains the zoom-in level. Defaults to 0.
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder mapMinDistance(float arg) {
|
||||
nBuilderMapMinDistance(mNativeBuilder, arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ground plane equation used for ray casts.
|
||||
* This is a plane equation as in Ax + By + Cz + D = 0.
|
||||
* Defaults to (0, 0, 1, 0).
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder groundPlane(float a, float b, float c, float d) {
|
||||
nBuilderGroundPlane(mNativeBuilder, a, b, c, d);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the <code>Manipulator</code> object.
|
||||
*
|
||||
* @return the newly created <code>Manipulator</code> object
|
||||
*
|
||||
* @exception IllegalStateException if the Manipulator could not be created
|
||||
*
|
||||
*/
|
||||
@NonNull
|
||||
public Manipulator build(Mode mode) {
|
||||
long nativeManipulator = nBuilderBuild(mNativeBuilder, mode.ordinal());
|
||||
if (nativeManipulator == 0)
|
||||
throw new IllegalStateException("Couldn't create Manipulator");
|
||||
return new Manipulator(nativeManipulator);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroyManipulator(mNativeObject);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the immutable mode of the manipulator.
|
||||
*/
|
||||
public Mode getMode() { return Mode.values()[nGetMode(mNativeObject)]; }
|
||||
|
||||
/**
|
||||
* Sets the viewport dimensions in terms of pixels.
|
||||
*
|
||||
* The manipulator uses this only in the grab and raycast methods, since
|
||||
* those methods consume coordinates in viewport space.
|
||||
*/
|
||||
public void setViewport(int width, int height) {
|
||||
nSetViewport(mNativeObject, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current orthonormal basis. This is usually called once per frame.
|
||||
*/
|
||||
public void getLookAt(
|
||||
@NonNull @Size(min = 3) float[] eyePosition,
|
||||
@NonNull @Size(min = 3) float[] targetPosition,
|
||||
@NonNull @Size(min = 3) float[] upward) {
|
||||
nGetLookAtFloat(mNativeObject, eyePosition, targetPosition, upward);
|
||||
}
|
||||
|
||||
public void getLookAt(
|
||||
@NonNull @Size(min = 3) double[] eyePosition,
|
||||
@NonNull @Size(min = 3) double[] targetPosition,
|
||||
@NonNull @Size(min = 3) double[] upward) {
|
||||
nGetLookAtDouble(mNativeObject, eyePosition, targetPosition, upward);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a viewport coordinate, picks a point in the ground plane.
|
||||
*/
|
||||
@Nullable @Size(min = 3)
|
||||
public float[] raycast(int x, int y) {
|
||||
float[] result = new float[3];
|
||||
nRaycast(mNativeObject, x, y, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a grabbing session (i.e. the user is dragging around in the viewport).
|
||||
*
|
||||
* This starts a panning session in MAP mode, and start either rotating or strafing in ORBIT.
|
||||
*
|
||||
* @param x X-coordinate for point of interest in viewport space
|
||||
* @param y Y-coordinate for point of interest in viewport space
|
||||
* @param strafe ORBIT mode only; if true, starts a translation rather than a rotation.
|
||||
*/
|
||||
public void grabBegin(int x, int y, boolean strafe) {
|
||||
nGrabBegin(mNativeObject, x, y, strafe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a grabbing session.
|
||||
*
|
||||
* This must be called at least once between grabBegin / grabEnd to dirty the camera.
|
||||
*/
|
||||
public void grabUpdate(int x, int y) {
|
||||
nGrabUpdate(mNativeObject, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a grabbing session.
|
||||
*/
|
||||
public void grabEnd() {
|
||||
nGrabEnd(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dollys the camera along the viewing direction.
|
||||
*
|
||||
* @param x X-coordinate for point of interest in viewport space
|
||||
* @param y Y-coordinate for point of interest in viewport space
|
||||
* @param scrolldelta Positive means "zoom in", negative means "zoom out"
|
||||
*/
|
||||
public void zoom(int x, int y, float scrolldelta) {
|
||||
nZoom(mNativeObject, x, y, scrolldelta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a handle that can be used to reset the manipulator back to its current position.
|
||||
*
|
||||
* @see #jumpToBookmark(Bookmark)
|
||||
*/
|
||||
public Bookmark getCurrentBookmark() {
|
||||
return new Bookmark(nGetCurrentBookmark(mNativeObject));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a handle that can be used to reset the manipulator back to its home position.
|
||||
*
|
||||
* see jumpToBookmark
|
||||
*/
|
||||
public Bookmark getHomeBookmark() {
|
||||
return new Bookmark(nGetHomeBookmark(mNativeObject));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the manipulator position and orientation back to a stashed state.
|
||||
*
|
||||
* @see #getCurrentBookmark()
|
||||
* @see #getHomeBookmark()
|
||||
*/
|
||||
public void jumpToBookmark(Bookmark bookmark) {
|
||||
nJumpToBookmark(mNativeObject, bookmark.getNativeObject());
|
||||
}
|
||||
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
private static native void nBuilderViewport(long nativeBuilder, int width, int height);
|
||||
private static native void nBuilderTargetPosition(long nativeBuilder, float x, float y, float z);
|
||||
private static native void nBuilderUpVector(long nativeBuilder, float x, float y, float z);
|
||||
private static native void nBuilderZoomSpeed(long nativeBuilder, float arg);
|
||||
private static native void nBuilderOrbitHomePosition(long nativeBuilder, float x, float y, float z);
|
||||
private static native void nBuilderOrbitSpeed(long nativeBuilder, float x, float y);
|
||||
private static native void nBuilderFovDirection(long nativeBuilder, int arg);
|
||||
private static native void nBuilderFovDegrees(long nativeBuilder, float arg);
|
||||
private static native void nBuilderFarPlane(long nativeBuilder, float distance);
|
||||
private static native void nBuilderMapExtent(long nativeBuilder, float width, float height);
|
||||
private static native void nBuilderMapMinDistance(long nativeBuilder, float arg);
|
||||
private static native void nBuilderGroundPlane(long nativeBuilder, float a, float b, float c, float d);
|
||||
private static native long nBuilderBuild(long nativeBuilder, int mode);
|
||||
|
||||
private static native void nDestroyManipulator(long nativeManip);
|
||||
private static native int nGetMode(long nativeManip);
|
||||
private static native void nSetViewport(long nativeManip, int width, int height);
|
||||
private static native void nGetLookAtFloat(long nativeManip, float[] eyePosition, float[] targetPosition, float[] upward);
|
||||
private static native void nGetLookAtDouble(long nativeManip, double[] eyePosition, double[] targetPosition, double[] upward);
|
||||
private static native void nRaycast(long nativeManip, int x, int y, float[] result);
|
||||
private static native void nGrabBegin(long nativeManip, int x, int y, boolean strafe);
|
||||
private static native void nGrabUpdate(long nativeManip, int x, int y);
|
||||
private static native void nGrabEnd(long nativeManip);
|
||||
private static native void nZoom(long nativeManip, int x, int y, float scrolldelta);
|
||||
private static native long nGetCurrentBookmark(long nativeManip);
|
||||
private static native long nGetHomeBookmark(long nativeManip);
|
||||
private static native void nJumpToBookmark(long nativeManip, long nativeBookmark);
|
||||
}
|
||||
@@ -0,0 +1,520 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Romain Guy
|
||||
*
|
||||
* 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 kotlin.math.*
|
||||
|
||||
enum class MatrixColumn {
|
||||
X, Y, Z, W
|
||||
}
|
||||
|
||||
data class Mat2(
|
||||
var x: Float2 = Float2(x = 1.0f),
|
||||
var y: Float2 = Float2(y = 1.0f)) {
|
||||
constructor(m: Mat2) : this(m.x.copy(), m.y.copy())
|
||||
|
||||
companion object {
|
||||
fun of(vararg a: Float): Mat2 {
|
||||
require(a.size >= 4)
|
||||
return Mat2(
|
||||
Float2(a[0], a[2]),
|
||||
Float2(a[1], a[3])
|
||||
)
|
||||
}
|
||||
|
||||
fun identity() = Mat2()
|
||||
}
|
||||
|
||||
operator fun get(column: Int) = when(column) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
else -> throw IllegalArgumentException("column must be in 0..1")
|
||||
}
|
||||
operator fun get(column: Int, row: Int) = get(column)[row]
|
||||
|
||||
operator fun get(column: MatrixColumn) = when(column) {
|
||||
MatrixColumn.X -> x
|
||||
MatrixColumn.Y -> y
|
||||
else -> throw IllegalArgumentException("column must be X or Y")
|
||||
}
|
||||
operator fun get(column: MatrixColumn, row: Int) = get(column)[row]
|
||||
|
||||
operator fun invoke(row: Int, column: Int) = get(column - 1)[row - 1]
|
||||
operator fun invoke(row: Int, column: Int, v: Float) = set(column - 1, row - 1, v)
|
||||
|
||||
operator fun set(column: Int, v: Float2) {
|
||||
this[column].xy = v
|
||||
}
|
||||
operator fun set(column: Int, row: Int, v: Float) {
|
||||
this[column][row] = v
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Mat2(-x, -y)
|
||||
operator fun inc(): Mat2 {
|
||||
x++
|
||||
y++
|
||||
return this
|
||||
}
|
||||
operator fun dec(): Mat2 {
|
||||
x--
|
||||
y--
|
||||
return this
|
||||
}
|
||||
|
||||
operator fun plus(v: Float) = Mat2(x + v, y + v)
|
||||
operator fun minus(v: Float) = Mat2(x - v, y - v)
|
||||
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(v: Float2): Float2 {
|
||||
val t = transpose(this)
|
||||
return Float2(dot(t.x, v), dot(t.y, v))
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x,
|
||||
x.y, y.y
|
||||
)
|
||||
|
||||
override fun toString(): String {
|
||||
return """
|
||||
|${x.x} ${y.x}|
|
||||
|${x.y} ${y.y}|
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data class Mat3(
|
||||
var x: Float3 = Float3(x = 1.0f),
|
||||
var y: Float3 = Float3(y = 1.0f),
|
||||
var z: Float3 = Float3(z = 1.0f)) {
|
||||
constructor(m: Mat3) : this(m.x.copy(), m.y.copy(), m.z.copy())
|
||||
|
||||
companion object {
|
||||
fun of(vararg a: Float): Mat3 {
|
||||
require(a.size >= 9)
|
||||
return Mat3(
|
||||
Float3(a[0], a[3], a[6]),
|
||||
Float3(a[1], a[4], a[7]),
|
||||
Float3(a[2], a[5], a[8])
|
||||
)
|
||||
}
|
||||
|
||||
fun identity() = Mat3()
|
||||
}
|
||||
|
||||
operator fun get(column: Int) = when(column) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
else -> throw IllegalArgumentException("column must be in 0..2")
|
||||
}
|
||||
operator fun get(column: Int, row: Int) = get(column)[row]
|
||||
|
||||
operator fun get(column: MatrixColumn) = when(column) {
|
||||
MatrixColumn.X -> x
|
||||
MatrixColumn.Y -> y
|
||||
MatrixColumn.Z -> z
|
||||
else -> throw IllegalArgumentException("column must be X, Y or Z")
|
||||
}
|
||||
operator fun get(column: MatrixColumn, row: Int) = get(column)[row]
|
||||
|
||||
operator fun invoke(row: Int, column: Int) = get(column - 1)[row - 1]
|
||||
operator fun invoke(row: Int, column: Int, v: Float) = set(column - 1, row - 1, v)
|
||||
|
||||
operator fun set(column: Int, v: Float3) {
|
||||
this[column].xyz = v
|
||||
}
|
||||
operator fun set(column: Int, row: Int, v: Float) {
|
||||
this[column][row] = v
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Mat3(-x, -y, -z)
|
||||
operator fun inc(): Mat3 {
|
||||
x++
|
||||
y++
|
||||
z++
|
||||
return this
|
||||
}
|
||||
operator fun dec(): Mat3 {
|
||||
x--
|
||||
y--
|
||||
z--
|
||||
return this
|
||||
}
|
||||
|
||||
operator fun plus(v: Float) = Mat3(x + v, y + v, z + v)
|
||||
operator fun minus(v: Float) = Mat3(x - v, y - v, z - v)
|
||||
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(v: Float3): Float3 {
|
||||
val t = transpose(this)
|
||||
return Float3(dot(t.x, v), dot(t.y, v), dot(t.z, v))
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x, z.x,
|
||||
x.y, y.y, z.y,
|
||||
x.z, y.z, z.z
|
||||
)
|
||||
|
||||
override fun toString(): String {
|
||||
return """
|
||||
|${x.x} ${y.x} ${z.x}|
|
||||
|${x.y} ${y.y} ${z.y}|
|
||||
|${x.z} ${y.z} ${z.z}|
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
data class Mat4(
|
||||
var x: Float4 = Float4(x = 1.0f),
|
||||
var y: Float4 = Float4(y = 1.0f),
|
||||
var z: Float4 = Float4(z = 1.0f),
|
||||
var w: Float4 = Float4(w = 1.0f)) {
|
||||
constructor(right: Float3, up: Float3, forward: Float3, position: Float3 = Float3()) :
|
||||
this(Float4(right), Float4(up), Float4(forward), Float4(position, 1.0f))
|
||||
constructor(m: Mat4) : this(m.x.copy(), m.y.copy(), m.z.copy(), m.w.copy())
|
||||
|
||||
companion object {
|
||||
fun of(vararg a: Float): Mat4 {
|
||||
require(a.size >= 16)
|
||||
return Mat4(
|
||||
Float4(a[0], a[4], a[8], a[12]),
|
||||
Float4(a[1], a[5], a[9], a[13]),
|
||||
Float4(a[2], a[6], a[10], a[14]),
|
||||
Float4(a[3], a[7], a[11], a[15])
|
||||
)
|
||||
}
|
||||
|
||||
fun identity() = Mat4()
|
||||
}
|
||||
|
||||
inline var right: Float3
|
||||
get() = x.xyz
|
||||
set(value) {
|
||||
x.xyz = value
|
||||
}
|
||||
inline var up: Float3
|
||||
get() = y.xyz
|
||||
set(value) {
|
||||
y.xyz = value
|
||||
}
|
||||
inline var forward: Float3
|
||||
get() = z.xyz
|
||||
set(value) {
|
||||
z.xyz = value
|
||||
}
|
||||
inline var position: Float3
|
||||
get() = w.xyz
|
||||
set(value) {
|
||||
w.xyz = value
|
||||
}
|
||||
|
||||
inline val scale: Float3
|
||||
get() = Float3(length(x.xyz), length(y.xyz), length(z.xyz))
|
||||
inline val translation: Float3
|
||||
get() = w.xyz
|
||||
val rotation: Float3
|
||||
get() {
|
||||
val x = normalize(right)
|
||||
val y = normalize(up)
|
||||
val z = normalize(forward)
|
||||
|
||||
return when {
|
||||
z.y <= -1.0f -> Float3(degrees(-HALF_PI), 0.0f, degrees(atan2( x.z, y.z)))
|
||||
z.y >= 1.0f -> Float3(degrees( HALF_PI), 0.0f, degrees(atan2(-x.z, -y.z)))
|
||||
else -> Float3(
|
||||
degrees(-asin(z.y)), degrees(-atan2(z.x, z.z)), degrees(atan2( x.y, y.y)))
|
||||
}
|
||||
}
|
||||
|
||||
inline val upperLeft: Mat3
|
||||
get() = Mat3(x.xyz, y.xyz, z.xyz)
|
||||
|
||||
operator fun get(column: Int) = when(column) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
3 -> w
|
||||
else -> throw IllegalArgumentException("column must be in 0..3")
|
||||
}
|
||||
operator fun get(column: Int, row: Int) = get(column)[row]
|
||||
|
||||
operator fun get(column: MatrixColumn) = when(column) {
|
||||
MatrixColumn.X -> x
|
||||
MatrixColumn.Y -> y
|
||||
MatrixColumn.Z -> z
|
||||
MatrixColumn.W -> w
|
||||
}
|
||||
operator fun get(column: MatrixColumn, row: Int) = get(column)[row]
|
||||
|
||||
operator fun invoke(row: Int, column: Int) = get(column - 1)[row - 1]
|
||||
operator fun invoke(row: Int, column: Int, v: Float) = set(column - 1, row - 1, v)
|
||||
|
||||
operator fun set(column: Int, v: Float4) {
|
||||
this[column].xyzw = v
|
||||
}
|
||||
operator fun set(column: Int, row: Int, v: Float) {
|
||||
this[column][row] = v
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Mat4(-x, -y, -z, -w)
|
||||
operator fun inc(): Mat4 {
|
||||
x++
|
||||
y++
|
||||
z++
|
||||
w++
|
||||
return this
|
||||
}
|
||||
operator fun dec(): Mat4 {
|
||||
x--
|
||||
y--
|
||||
z--
|
||||
w--
|
||||
return this
|
||||
}
|
||||
|
||||
operator fun plus(v: Float) = Mat4(x + v, y + v, z + v, w + v)
|
||||
operator fun minus(v: Float) = Mat4(x - v, y - v, z - v, w - v)
|
||||
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(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))
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x, z.x, w.x,
|
||||
x.y, y.y, z.y, w.y,
|
||||
x.z, y.z, z.z, w.z,
|
||||
x.w, y.w, z.w, w.w
|
||||
)
|
||||
|
||||
override fun toString(): String {
|
||||
return """
|
||||
|${x.x} ${y.x} ${z.x} ${w.x}|
|
||||
|${x.y} ${y.y} ${z.y} ${w.y}|
|
||||
|${x.z} ${y.z} ${z.z} ${w.z}|
|
||||
|${x.w} ${y.w} ${z.w} ${w.w}|
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
fun transpose(m: Mat2) = Mat2(
|
||||
Float2(m.x.x, m.y.x),
|
||||
Float2(m.x.y, m.y.y)
|
||||
)
|
||||
|
||||
fun transpose(m: Mat3) = Mat3(
|
||||
Float3(m.x.x, m.y.x, m.z.x),
|
||||
Float3(m.x.y, m.y.y, m.z.y),
|
||||
Float3(m.x.z, m.y.z, m.z.z)
|
||||
)
|
||||
fun inverse(m: Mat3): Mat3 {
|
||||
val a = m.x.x
|
||||
val b = m.x.y
|
||||
val c = m.x.z
|
||||
val d = m.y.x
|
||||
val e = m.y.y
|
||||
val f = m.y.z
|
||||
val g = m.z.x
|
||||
val h = m.z.y
|
||||
val i = m.z.z
|
||||
|
||||
val A = e * i - f * h
|
||||
val B = f * g - d * i
|
||||
val C = d * h - e * g
|
||||
|
||||
val det = a * A + b * B + c * C
|
||||
|
||||
return Mat3.of(
|
||||
A / det, B / det, C / det,
|
||||
(c * h - b * i) / det, (a * i - c * g) / det, (b * g - a * h) / det,
|
||||
(b * f - c * e) / det, (c * d - a * f) / det, (a * e - b * d) / det
|
||||
)
|
||||
}
|
||||
|
||||
fun transpose(m: Mat4) = Mat4(
|
||||
Float4(m.x.x, m.y.x, m.z.x, m.w.x),
|
||||
Float4(m.x.y, m.y.y, m.z.y, m.w.y),
|
||||
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()
|
||||
|
||||
var pair0 = m.z.z * m.w.w
|
||||
var pair1 = m.w.z * m.z.w
|
||||
var pair2 = m.y.z * m.w.w
|
||||
var pair3 = m.w.z * m.y.w
|
||||
var pair4 = m.y.z * m.z.w
|
||||
var pair5 = m.z.z * m.y.w
|
||||
var pair6 = m.x.z * m.w.w
|
||||
var pair7 = m.w.z * m.x.w
|
||||
var pair8 = m.x.z * m.z.w
|
||||
var pair9 = m.z.z * m.x.w
|
||||
var pair10 = m.x.z * m.y.w
|
||||
var pair11 = m.y.z * m.x.w
|
||||
|
||||
result.x.x = pair0 * m.y.y + pair3 * m.z.y + pair4 * m.w.y
|
||||
result.x.x -= pair1 * m.y.y + pair2 * m.z.y + pair5 * m.w.y
|
||||
result.x.y = pair1 * m.x.y + pair6 * m.z.y + pair9 * m.w.y
|
||||
result.x.y -= pair0 * m.x.y + pair7 * m.z.y + pair8 * m.w.y
|
||||
result.x.z = pair2 * m.x.y + pair7 * m.y.y + pair10 * m.w.y
|
||||
result.x.z -= pair3 * m.x.y + pair6 * m.y.y + pair11 * m.w.y
|
||||
result.x.w = pair5 * m.x.y + pair8 * m.y.y + pair11 * m.z.y
|
||||
result.x.w -= pair4 * m.x.y + pair9 * m.y.y + pair10 * m.z.y
|
||||
result.y.x = pair1 * m.y.x + pair2 * m.z.x + pair5 * m.w.x
|
||||
result.y.x -= pair0 * m.y.x + pair3 * m.z.x + pair4 * m.w.x
|
||||
result.y.y = pair0 * m.x.x + pair7 * m.z.x + pair8 * m.w.x
|
||||
result.y.y -= pair1 * m.x.x + pair6 * m.z.x + pair9 * m.w.x
|
||||
result.y.z = pair3 * m.x.x + pair6 * m.y.x + pair11 * m.w.x
|
||||
result.y.z -= pair2 * m.x.x + pair7 * m.y.x + pair10 * m.w.x
|
||||
result.y.w = pair4 * m.x.x + pair9 * m.y.x + pair10 * m.z.x
|
||||
result.y.w -= pair5 * m.x.x + pair8 * m.y.x + pair11 * m.z.x
|
||||
|
||||
pair0 = m.z.x * m.w.y
|
||||
pair1 = m.w.x * m.z.y
|
||||
pair2 = m.y.x * m.w.y
|
||||
pair3 = m.w.x * m.y.y
|
||||
pair4 = m.y.x * m.z.y
|
||||
pair5 = m.z.x * m.y.y
|
||||
pair6 = m.x.x * m.w.y
|
||||
pair7 = m.w.x * m.x.y
|
||||
pair8 = m.x.x * m.z.y
|
||||
pair9 = m.z.x * m.x.y
|
||||
pair10 = m.x.x * m.y.y
|
||||
pair11 = m.y.x * m.x.y
|
||||
|
||||
result.z.x = pair0 * m.y.w + pair3 * m.z.w + pair4 * m.w.w
|
||||
result.z.x -= pair1 * m.y.w + pair2 * m.z.w + pair5 * m.w.w
|
||||
result.z.y = pair1 * m.x.w + pair6 * m.z.w + pair9 * m.w.w
|
||||
result.z.y -= pair0 * m.x.w + pair7 * m.z.w + pair8 * m.w.w
|
||||
result.z.z = pair2 * m.x.w + pair7 * m.y.w + pair10 * m.w.w
|
||||
result.z.z -= pair3 * m.x.w + pair6 * m.y.w + pair11 * m.w.w
|
||||
result.z.w = pair5 * m.x.w + pair8 * m.y.w + pair11 * m.z.w
|
||||
result.z.w -= pair4 * m.x.w + pair9 * m.y.w + pair10 * m.z.w
|
||||
result.w.x = pair2 * m.z.z + pair5 * m.w.z + pair1 * m.y.z
|
||||
result.w.x -= pair4 * m.w.z + pair0 * m.y.z + pair3 * m.z.z
|
||||
result.w.y = pair8 * m.w.z + pair0 * m.x.z + pair7 * m.z.z
|
||||
result.w.y -= pair6 * m.z.z + pair9 * m.w.z + pair1 * m.x.z
|
||||
result.w.z = pair6 * m.y.z + pair11 * m.w.z + pair3 * m.x.z
|
||||
result.w.z -= pair10 * m.w.z + pair2 * m.x.z + pair7 * m.y.z
|
||||
result.w.w = pair10 * m.z.z + pair4 * m.x.z + pair9 * m.y.z
|
||||
result.w.w -= pair8 * m.y.z + pair11 * m.z.z + pair5 * m.x.z
|
||||
|
||||
val determinant = m.x.x * result.x.x + m.y.x * result.x.y + m.z.x * result.x.z + m.w.x * result.x.w
|
||||
|
||||
return result / determinant
|
||||
}
|
||||
|
||||
fun scale(s: Float3) = Mat4(Float4(x = s.x), Float4(y = s.y), Float4(z = s.z))
|
||||
fun scale(m: Mat4) = scale(m.scale)
|
||||
|
||||
fun translation(t: Float3) = Mat4(w = Float4(t, 1.0f))
|
||||
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) })
|
||||
|
||||
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,
|
||||
c.y * s.z, c.x * c.z + s.x * s.y * s.z, -s.x * c.z + c.x * s.y * s.z, 0.0f,
|
||||
-s.y , s.x * c.y , c.x * c.y , 0.0f,
|
||||
0.0f , 0.0f , 0.0f , 1.0f
|
||||
)
|
||||
}
|
||||
fun rotation(axis: Float3, angle: Float): Mat4 {
|
||||
val x = axis.x
|
||||
val y = axis.y
|
||||
val z = axis.z
|
||||
|
||||
val r = radians(angle)
|
||||
val c = cos(r)
|
||||
val s = sin(r)
|
||||
val d = 1.0f - c
|
||||
|
||||
return Mat4.of(
|
||||
x * x * d + c , x * y * d - z * s, x * z * d + y * s, 0.0f,
|
||||
y * x * d + z * s, y * y * d + c , y * z * d - x * s, 0.0f,
|
||||
z * x * d - y * s, z * y * d + x * s, z * z * d + c , 0.0f,
|
||||
0.0f , 0.0f , 0.0f , 1.0f
|
||||
)
|
||||
}
|
||||
|
||||
fun normal(m: Mat4) = scale(1.0f / Float3(length2(m.right), length2(m.up), length2(m.forward))) * m
|
||||
|
||||
fun lookAt(eye: Float3, target: Float3, up: Float3 = Float3(z = 1.0f)): Mat4 {
|
||||
return lookTowards(eye, target - eye, up)
|
||||
}
|
||||
|
||||
fun lookTowards(eye: Float3, forward: Float3, up: Float3 = Float3(z = 1.0f)): Mat4 {
|
||||
val f = normalize(forward)
|
||||
val r = normalize(f x up)
|
||||
val u = normalize(r x f)
|
||||
return Mat4(Float4(r), Float4(u), Float4(f), Float4(eye, 1.0f))
|
||||
}
|
||||
|
||||
fun perspective(fov: Float, ratio: Float, near: Float, far: Float): Mat4 {
|
||||
val t = 1.0f / tan(radians(fov) * 0.5f)
|
||||
val a = (far + near) / (far - near)
|
||||
val b = (2.0f * far * near) / (far - near)
|
||||
val c = t / ratio
|
||||
return Mat4(Float4(x = c), Float4(y = t), Float4(z = a, w = 1.0f), Float4(z = -b))
|
||||
}
|
||||
|
||||
fun ortho(l: Float, r: Float, b: Float, t: Float, n: Float, f: Float) = Mat4(
|
||||
Float4(x = 2.0f / (r - 1.0f)),
|
||||
Float4(y = 2.0f / (t - b)),
|
||||
Float4(z = -2.0f / (f - n)),
|
||||
Float4(-(r + l) / (r - l), -(t + b) / (t - b), -(f + n) / (f - n), 1.0f)
|
||||
)
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 android.view.MotionEvent
|
||||
import android.view.Surface
|
||||
import android.view.SurfaceView
|
||||
import android.view.TextureView
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.UiHelper
|
||||
import com.google.android.filament.gltfio.*
|
||||
import java.nio.Buffer
|
||||
|
||||
/**
|
||||
* Helps render glTF models into a [SurfaceView] or [TextureView] with an orbit controller.
|
||||
*
|
||||
* `ModelViewer` owns a Filament engine, renderer, swapchain, view, and scene. It allows clients
|
||||
* to access these objects via read-only properties. The viewer can display only one glTF scene
|
||||
* at a time, which can be scaled and translated into the viewing frustum by calling
|
||||
* [transformToUnitCube]. All ECS entities can be accessed and modified via the [asset] property.
|
||||
*
|
||||
* For GLB files, clients can call [loadModelGlb] and pass in a [Buffer] with the contents of the
|
||||
* GLB file. For glTF files, clients can call [loadModelGltf] and pass in a [Buffer] with the JSON
|
||||
* contents, as well as a callback for loading external resources.
|
||||
*
|
||||
* `ModelViewer` reduces much of the boilerplate required for simple Filament applications, but
|
||||
* clients still have the responsibility of adding an [IndirectLight] and [Skybox] to the scene.
|
||||
* Additionally, clients should:
|
||||
*
|
||||
* 1. Call [onTouchEvent] from a touch handler.
|
||||
* 2. Call [render] and [Animator.applyAnimation] from a `Choreographer` frame callback.
|
||||
*
|
||||
* NOTE: if its associated SurfaceView or TextureView has become detached from its window, the
|
||||
* ModelViewer becomes invalid and must be recreated.
|
||||
*
|
||||
* See `sample-gltf-viewer` for a usage example.
|
||||
*/
|
||||
class ModelViewer {
|
||||
|
||||
var asset: FilamentAsset? = null
|
||||
private set
|
||||
|
||||
var animator: Animator? = null
|
||||
private set
|
||||
|
||||
val engine: Engine
|
||||
val scene: Scene
|
||||
val view: View
|
||||
val camera: Camera
|
||||
@Entity val light: Int
|
||||
|
||||
private val uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
|
||||
private val cameraManipulator: Manipulator
|
||||
private val gestureDetector: GestureDetector
|
||||
private val renderer: Renderer
|
||||
private var swapChain: SwapChain? = null
|
||||
private var assetLoader: AssetLoader
|
||||
|
||||
private val eyePos = DoubleArray(3)
|
||||
private val target = DoubleArray(3)
|
||||
private val upward = DoubleArray(3)
|
||||
|
||||
private val kNearPlane = 0.5
|
||||
private val kFarPlane = 10000.0
|
||||
private val kFovDegrees = 45.0
|
||||
private val kAperture = 16f
|
||||
private val kShutterSpeed = 1f / 125f
|
||||
private val kSensitivity = 100f
|
||||
|
||||
init {
|
||||
engine = Engine.create()
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
camera = engine.createCamera().apply { setExposure(kAperture, kShutterSpeed, kSensitivity) }
|
||||
view = engine.createView()
|
||||
view.scene = scene
|
||||
view.camera = camera
|
||||
|
||||
assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
|
||||
|
||||
// Always add a direct light source since it is required for shadowing.
|
||||
// We highly recommend adding an indirect light as well.
|
||||
|
||||
light = EntityManager.get().create()
|
||||
|
||||
val (r, g, b) = Colors.cct(6_500.0f)
|
||||
LightManager.Builder(LightManager.Type.DIRECTIONAL)
|
||||
.color(r, g, b)
|
||||
.intensity(300_000.0f)
|
||||
.direction(0.0f, -1.0f, 0.0f)
|
||||
.castShadows(true)
|
||||
.build(engine, light)
|
||||
|
||||
scene.addEntity(light)
|
||||
}
|
||||
|
||||
constructor(surfaceView: SurfaceView) {
|
||||
cameraManipulator = Manipulator.Builder()
|
||||
.targetPosition(0.0f, 0.0f, -4.0f)
|
||||
.viewport(surfaceView.width, surfaceView.height)
|
||||
.build(Manipulator.Mode.ORBIT)
|
||||
|
||||
gestureDetector = GestureDetector(surfaceView, cameraManipulator)
|
||||
uiHelper.renderCallback = SurfaceCallback()
|
||||
uiHelper.attachTo(surfaceView)
|
||||
addDetachListener(surfaceView)
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(textureView: TextureView) {
|
||||
cameraManipulator = Manipulator.Builder()
|
||||
.targetPosition(0.0f, 0.0f, -4.0f)
|
||||
.viewport(textureView.width, textureView.height)
|
||||
.build(Manipulator.Mode.ORBIT)
|
||||
|
||||
gestureDetector = GestureDetector(textureView, cameraManipulator)
|
||||
uiHelper.renderCallback = SurfaceCallback()
|
||||
uiHelper.attachTo(textureView)
|
||||
addDetachListener(textureView)
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a monolithic binary glTF and populates the Filament scene.
|
||||
*/
|
||||
fun loadModelGlb(buffer: Buffer) {
|
||||
destroyModel()
|
||||
asset = assetLoader.createAssetFromJson(buffer)
|
||||
asset?.let { asset ->
|
||||
val resourceLoader = ResourceLoader(engine)
|
||||
resourceLoader.loadResources(asset)
|
||||
resourceLoader.destroy()
|
||||
animator = asset.animator
|
||||
asset.releaseSourceData()
|
||||
scene.addEntities(asset.entities)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a JSON-style glTF file and populates the Filament scene.
|
||||
*/
|
||||
fun loadModelGltf(buffer: Buffer, callback: (String) -> Buffer) {
|
||||
destroyModel()
|
||||
asset = assetLoader.createAssetFromJson(buffer)
|
||||
asset?.let { asset ->
|
||||
val resourceLoader = ResourceLoader(engine)
|
||||
for (uri in asset.resourceUris) {
|
||||
resourceLoader.addResourceData(uri, callback(uri))
|
||||
}
|
||||
resourceLoader.loadResources(asset)
|
||||
resourceLoader.destroy()
|
||||
animator = asset.animator
|
||||
asset.releaseSourceData()
|
||||
scene.addEntities(asset.entities)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a root transform on the current model to make it fit into the viewing frustum.
|
||||
*/
|
||||
fun transformToUnitCube() {
|
||||
asset?.let { asset ->
|
||||
val tm = engine.transformManager
|
||||
val center = asset.boundingBox.center.let { v-> Float3(v[0], v[1], v[2]) }
|
||||
val halfExtent = asset.boundingBox.halfExtent.let { v-> Float3(v[0], v[1], v[2]) }
|
||||
val maxExtent = 2.0f * max(halfExtent)
|
||||
val scaleFactor = 2.0f / maxExtent
|
||||
center.z = center.z + 4.0f / scaleFactor
|
||||
val transform = scale(Float3(scaleFactor)) * translation(Float3(-center))
|
||||
tm.setTransform(tm.getInstance(asset.root), transpose(transform).toFloatArray())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all entities associated with the most recently-loaded model.
|
||||
*/
|
||||
fun destroyModel() {
|
||||
asset?.let { asset ->
|
||||
assetLoader.destroyAsset(asset)
|
||||
this.asset = null
|
||||
this.animator = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the model and updates the Filament camera.
|
||||
*/
|
||||
fun render() {
|
||||
if (!uiHelper.isReadyToRender) {
|
||||
return
|
||||
}
|
||||
|
||||
cameraManipulator.getLookAt(eyePos, target, upward)
|
||||
camera.lookAt(
|
||||
eyePos[0], eyePos[1], eyePos[2],
|
||||
target[0], target[1], target[2],
|
||||
upward[0], upward[1], upward[2])
|
||||
|
||||
if (renderer.beginFrame(swapChain!!)) {
|
||||
renderer.render(view)
|
||||
renderer.endFrame()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addDetachListener(view: android.view.View) {
|
||||
view.addOnAttachStateChangeListener(object : android.view.View.OnAttachStateChangeListener {
|
||||
override fun onViewAttachedToWindow(v: android.view.View?) {}
|
||||
override fun onViewDetachedFromWindow(v: android.view.View?) {
|
||||
uiHelper.detach()
|
||||
|
||||
destroyModel()
|
||||
assetLoader.destroy()
|
||||
|
||||
engine.destroyEntity(light)
|
||||
engine.destroyRenderer(renderer)
|
||||
engine.destroyView(this@ModelViewer.view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
|
||||
EntityManager.get().destroy(light)
|
||||
|
||||
engine.destroy()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a [MotionEvent] to enable one-finger orbit, two-finger pan, and pinch-to-zoom.
|
||||
*/
|
||||
fun onTouchEvent(event: MotionEvent) {
|
||||
gestureDetector.onTouchEvent(event)
|
||||
}
|
||||
|
||||
inner class SurfaceCallback : UiHelper.RendererCallback {
|
||||
override fun onNativeWindowChanged(surface: Surface) {
|
||||
swapChain?.let { engine.destroySwapChain(it) }
|
||||
swapChain = engine.createSwapChain(surface)
|
||||
}
|
||||
|
||||
override fun onDetachedFromSurface() {
|
||||
swapChain?.let {
|
||||
engine.destroySwapChain(it)
|
||||
engine.flushAndWait()
|
||||
swapChain = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResized(width: Int, height: Int) {
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
val aspect = width.toDouble() / height.toDouble()
|
||||
camera.setProjection(kFovDegrees, aspect, kNearPlane, kFarPlane, Camera.Fov.VERTICAL)
|
||||
cameraManipulator.setViewport(width, height)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
* Copyright (C) 2017 Romain Guy
|
||||
*
|
||||
* 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
|
||||
* 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,
|
||||
@@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Empty symbol used to suppress warnings on Darwin
|
||||
#if __has_attribute(visibility)
|
||||
__attribute__((visibility("hidden")))
|
||||
#endif
|
||||
void e() {
|
||||
}
|
||||
package com.google.android.filament.utils
|
||||
|
||||
data class Ray(var origin: Float3 = Float3(), var direction: Float3)
|
||||
|
||||
fun pointAt(r: Ray, t: Float) = r.origin + r.direction * t
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Romain Guy
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
const val FPI = 3.1415926536f
|
||||
const val HALF_PI = FPI * 0.5f
|
||||
const val TWO_PI = FPI * 2.0f
|
||||
const val FOUR_PI = FPI * 4.0f
|
||||
const val INV_PI = 1.0f / FPI
|
||||
const val INV_TWO_PI = INV_PI * 0.5f
|
||||
const val INV_FOUR_PI = INV_PI * 0.25f
|
||||
|
||||
inline fun clamp(x: Float, min: Float, max: Float)= if (x < min) min else (if (x > max) max else x)
|
||||
|
||||
inline fun saturate(x: Float) = clamp(x, 0.0f, 1.0f)
|
||||
|
||||
inline fun mix(a: Float, b: Float, x: Float) = a * (1.0f - x) + b * x
|
||||
|
||||
inline fun degrees(v: Float) = v * (180.0f * INV_PI)
|
||||
|
||||
inline fun radians(v: Float) = v * (FPI / 180.0f)
|
||||
|
||||
inline fun fract(v: Float) = v % 1
|
||||
|
||||
inline fun sqr(v: Float) = v * v
|
||||
|
||||
inline fun pow(x: Float, y: Float) = StrictMath.pow(x.toDouble(), y.toDouble()).toFloat()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user