HUAWEI Scene Kit

Kadirtas
Huawei Developers - Türkiye
10 min readOct 14, 2020

Merhabalar…

Bu yazımda size HUAWEI Scene Kit’ten bahsedeceğim ve ardından bir demo uygulama geliştirerek detaylı bir şekilde anlatmaya çalışacağım. HUAWEI Scene Kit, yüksek performans ve düşük tüketime sahip lightweight bir render motorudur. 3D malzemeleri düzenlememiz, çalıştırmamız ve işlememiz için gelişmiş açıklayıcı API’ler sağlar. Scene Kit, gerçekçi renderlama efektleri elde etmek için fiziksel tabanlı renderlama(PBR) pipeline’ı kullanır. Bu Kit ile, Android telefonlarda karmaşık 3D nesneleri kolayca yüklemek ve görüntülemek için yalnızca bazı API’leri çağırmamız yeterli oluyor.

Scene Kit daha önce sadece SceneView özelliği ile duyurulmuştu. Ancak Scene Kit SDK 5.0.2.300 sürümüyle birlikte, FaceView ve ARView gibi yeni özellikleri de geliştiriciler tarafından eklenmiş. Scene Kit bu yeniliklerle Plane Detection ve Face Tracking özelliklerinin entegrasyonunu çok daha kolay bir hale getirmiş görünüyor.

Bu aşamada aklınıza “madem ML Kit ve AR Engine var, neden Scene Kit kullanacağız?” sorusu gelebilir. Hemen bir örnekle bu sorunun cevabını verelim.

Scene Kit ile AR Engine veya ML Kit Arasındaki Farklar

Örneğin bir Alışveriş uygulamamız var. Ve uygulamamızın gözlük satın alma bölümünde, gözlüklerin gerçekte nasıl göründüğünü görmek için kullanıcının AR kullanarak gözlükleri test edebilme özelliğine sahip olduğunu varsayalım. Burada AR Engine’in sağladığı Facial expression tracking özelliğini kullanarak yüz mimiklerini takip etmemize gerek yoktur. Tek yapmamız gereken bir 3D objeyi ekrandaki yüzün göz hizasında renderlamaktır. Bunun için de Face Tracking yeterlidir. Bu yüzden AR Engine kullanmış olsak OpenGL gibi grafik kütüphaneleriyle uğraşmak zorunda kalacaktık. Ama Scene Kit FaceView kullanarak çok basit bir şekilde herhangi bir grafik kütüphanesiyle uğraşmadan bu özelliği uygulamamıza ekleyebiliyoruz. Çünkü buradaki özellik temel bir özelliktir ve Scene Kit bize bunu sağlamaktadır.

Yani AR Engine yada ML Kit’i birbirinden ayıran şey, AR Engine ve ML Kit daha detaylı kontroller sağlamaktadır. Ancak Scene Kit sadece temel özellikleri(Bu özelliklerden ileride bahsedeceğim) sağlamaktadır. Bu sebeple, entegrasyonu çok daha basite indirgenmiştir.

Şimdi bu özelliklerin bize sağladıklarını inceleyelim.

SceneView

SceneView ile, temel düzeyde 3D malzemeleri yükleyebiliyor ve renderlayabiliyoruz.

SceneView ile:

  • 3D modelleri yükleyebilir ve renderlayabiliriz.
  • Scene’in gerçekte olduğundan daha büyük ve etkileyici görünmesini sağlamak için skybox’ın cubemap texture’ını yükleyebiliriz.
  • PBR pipeline aracılığıyla gerçek dünyadaki aydınlatma koşullarını taklit etmek için aydınlatma haritalarını yükleyebiliriz.
  • Ekranı kaydırarak modeli farklı açılardan görebiliriz.

ARView

ARView, AR sahnelerinde 3D malzemeleri yükleme ve işleme yeteneği sağlamak için AR Engine’in Plane Detection özelliğini Scene Kit‘in grafik renderlama özelliği ile birlikte kullanır.

ARView ile :

  • AR sahnelerinde 3D malzemeleri yükleyebilir ve renderlayabiliriz.
  • Gerçek dünya görünümünde bir düzlem seçmeye yardımcı olmak için kafes düzleminin (beyaz kafes noktalarından oluşan) görüntülenip görüntülenmeyeceğini ayarlayabiliriz.
  • Kafes düzlemine yerleştirilmiş bir nesneyi seçmek için dokunabiliriz. Seçildikten sonra nesne kırmızıya dönecektir. Sonra onu taşıyabilir, yeniden boyutlandırabilir veya döndürebiliriz.

FaceView

FaceView, yüzleri dinamik olarak algılamak için ML Kit veya AR Engine tarafından sağlanan yüz algılama özelliğini kullanabilir. Scene Kit’in grafik renderlama özelliğinin yanı sıra FaceView, bize yüzler için ayrılmış AR sahne renderlama sağlıyor.

FaceView ile:

  • Yüzleri dinamik olarak algılayabilir ve algılanan yüzlere 3D malzemeler uygulayabiliriz.

Yukarıda bahsettiğim gibi ARView, AR Engine’in düzlem algılama özelliğini kullanır ve FaceView, ML Kit veya AR Engine tarafından sağlanan yüz algılama özelliğini kullanır. FaceView özelliğini kullanırken hangi SDK’yi kullanacağımızı layout içinde belirterek istediğimiz SDK’den faydalanabiliyoruz.

Burada SDK seçimi yaparken desteklenecek cihazları dikkate almalıyız. Desteklenen cihazları aşağıdaki tabloda görebilirsiniz. Ayrıca daha detaylı bilgi için bu sayfayı ziyaret edebilirsiniz. page. (Bu sayfadaki tabloya ek olarak, Scene Kit’in SceneView özelliği P40 Lite cihazları da destekliyor.)

Ayrıca, Scene Kit’in bazı önemli çalışma prensiplerinden bahsetmekte de fayda olduğunu düşünüyorum:

Scene Kit

  • Uygulamamız, HMS Core olmadan telefonlarda çalışsa bile 3D grafik oluşturma yeteneklerine erişmek için uygulamamıza entegre edebileceğimiz bir Full SDK sağlar.
  • Coupling’i azaltmak ve multi-threaded parallel rendering uygulamak için Entity Component System (ECS) kullanır.
  • İşlenmiş görüntülerin gerçek bir dünyadaki gibi görünmesini sağlamak için gerçek zamanlı PBR ardışık düzenlerini benimser.
  • Güç tüketimini önemli ölçüde azaltmak için genel amaçlı GPU Turbo’yu destekler.

Demo Uygulama

Bu bölümde geliştireceğimiz bir demo uygulamayla Scene Kit’in sunduğu bu 3 özelliği entegre ederek daha detaylı öğrenelim.

HMS Core SDK için Maven repo adresini yapılandırmak üzere aşağıdaki kodu proje seviyesindeki build.gradle’a ekleyin.

project level build.gradle > buildscript > repositories

project level build.gradle > allprojects > repositories

maven { url 'https://developer.huawei.com/repo/' }

Sonra şuraya gidin:

module level build.gradle > dependencies

then add build dependencies for the Full-SDK of Scene Kit in the dependencies block.

daha sonra dependencies bloğundaki Scene Kit’in Full-SDKsı için bağımlılıkları ekleyin.

implementation 'com.huawei.scenekit:full-sdk:5.0.2.302'

Note: When adding build dependencies, replace the version here “full-sdk: 5.0.2.302” with the latest Full-SDK version. You can find all the SDK and Full-SDK version numbers in Version Change History.

Not: Derleme bağımlılıkları eklerken, buradaki “full-sdk: 5.0.2.302” sürümünü en son Full-SDK sürümüyle değiştirin. Full-SDK ve Full-SDK sürüm numaralarını Sürüm Değişikliği Geçmişinde bulabilirsiniz.

Ardından aşağıda gösterildiği gibi Sync Now’a tıklayın

Derleme başarıyla tamamlandıktan sonra, Kamera izni için aşağıdaki satırı AndroidManifest.xml dosyasına ekleyin.

<uses-permission android:name="android.permission.CAMERA" />

Artık projemiz geliştirilmeye hazır. Scene Kit’in tüm işlevlerini kullanabiliriz.

Bu demo uygulamasının bir alışveriş uygulaması olduğunu varsayalım. Ve bu uygulamada Scene Kit özelliklerini kullanmak istiyoruz. Seçtiğimiz bir bitkinin ve akvaryumun çalışma masamızın üzerinde nasıl göründüğünü test etmek için uygulamamızın “office” bölümünde Scene Kit’in ARView özelliğini kullanacağız.

Güneş gözlüğü bölümünde, güneş gözlüklerinin yüzümüzde nasıl göründüğünü test etmek için FaceView özelliğini kullanacağız.

Son olarak uygulamamızın ayakkabılar bölümünde SceneView özelliğini kullanacağız. Nasıl göründüğünü görmek için bir ayakkabıyı test edeceğiz.

Bu özellikleri test etmek için materyallere ihtiyacımız olacak öncelikle bu materyalleri elde edelim. Ben aşağıdaki linklerden indirebileceğiniz 3D modelleri kullanacağım. Siz de isterseniz aynılarını veya farklı materyalleri kullanabilirsiniz.

Özellik: ARView, Kullanılan Modeller: Plant , Aquarium

Özellik: FaceView, Kullanılan Model: Sunglasses

Özellik: SceneView, Kullanılan Model: Shoe

Not: Ben ARView ve FaceView özelliklerinde asset olarak “.glb” formatındaki 3D modeller kullandım. Ancak bu belirttiğim bağlantılar “.gltf” biçiminde 3D modeller içermektedir. Ben “.gltf” formatındaki dosyaları “.glb” formatına çevirdim. Dolayısıyla, bu linklerden indirdiğiniz 3D modellerin tüm dosyalarını (textures, scene.bin ve scene.gltf) bir online dönüştürücü websitesine uploadlayarak “.glb” formatında bir 3D model elde edebilirsiniz. Dönüştürme işlemi için herhangi bir online dönüştürme websitesini kullanabilirsiniz.

Tüm materyaller assets klasörünün altında olmalı. Bu nedenle, materyalleri projemizde app>src>main>assets dosyasının altına yerleştiriyoruz. Yerleştirdikten sonra dosya yapımız aşağıdaki gibi olacak.

Materyalleri de ekledikten sonra ilk olarak ARView özelliğini ekleyerek başlayacağız. ARView özelliğini kullanacağımız activity’de ofis malzemeleri olduğunu varsaydığım için OfficeActivity adında bir activity oluşturalım ve öncelikle bunun layout’unu düzenleyelim.

Not: Activity’ler Activity sınıfını extend etmeli. AppCompatActivity’i extend eden activityleri Activity ile güncelleyin.

Örnek: “OfficeActivity extends Activity” olmalı.

ARView

Scene Kit’in ARView özelliğini kullanabilmek için aşağıdaki ARView kodunu layout’a (activity_office.xml dosyasına) ekliyoruz.

activity_office.xml dosyasının genel görünümü:

Biri akvaryum ve diğeri bir bitkiyi yüklemek için 2 buton ekledik. Şimdi OfficeActivity’den başlatma işlemlerini yapalım ve ARView özelliğini uygulamamızda aktifleştirelim. Önce onCreate() fonksiyonunu override ederek burada ARView’i ve objeyi yükleyeceğimiz kodu tetikleyecek butonu elde edelim.

Sonra buton tıklandığında tetiklenecek metodu ekleyelim. Burada, objenin yüklenme durumunu kontrol edeceğiz. Duruma göre objeyi temizleyeceğiz veya yükleyeceğiz.

Plant butonu için:

Aquarium butonu için:

Şimdi satır satır buradaki kodlarda ne yaptığımızdan bahsedelim. Öncelikle ARView.enablePlaneDisplay() fonksiyonunu true’ya set ederek, eğer gerçek dünyada bir plane tanımlandıysa burada bir kafes düzlemi oluşturuyoruz.

mARView.enablePlaneDisplay(true);

Sonrasında objenin yüklenip yüklenmediğini kontrol ediyoruz. Eğer yüklenmemişse, mARView.loadAsset() fonksiyonuyla seçtiğimiz 3D modelin yolunu belirtiyor ve yüklüyoruz. (assets>ARView>flower.glb)

mARView.loadAsset("ARView/flower.glb");

Sonrasında başlangıç pozisyonu için scale ve rotation dizilerini oluşturuyoruz ve başlatıyoruz. Şimdilik buralara manuel değerler giriyoruz. İleride ekrana basılı tutarak vs. bir başlangıç pozisyonu belirleyebiliriz.

Not: Scene Kit ARView özelliği şu anda, oluşturduğumuz objeyi ekranda hareket ettirmemizi, boyutunu ayarlamamızı ve yönünü çevirmemizi sağlıyor. Bunun için oluşturduğumuz objeyi seçip, parmaklarımızı ekranda hareket ettirerek objenin yerini, boyutunu veya yönünü değiştirebiliriz.

Burada rotation ve scale değerlerini set ederek de objenin yönünü veya boyutunu ayarlayabiliriz.

float[] scale = new float[] { 0.15f, 0.15f, 0.15f };
float[] rotation = new float[] { 0.707f, 0.0f, -0.500f, 0.0f };

Sonra oluşturduğumuz scale ve rotation değerlerini başlangıç pozisyonu olarak ayarlıyoruz.

mARView.setInitialPose(scale, rotation);

Bu işlemden sonra objenin oluşturulduğunu belirtmek için boolean değeri ayarlıyoruz ve butonun yazısını güncelliyoruz.

isLoadResource = true;
mButton.setText(R.string.btn_text_clear_resource);

Eğer obje zaten yüklenmişse, kaynağı temizleyip boş obje yüklüyoruz ki objeyi ekrandan kaldıralım.

mARView.clearResource();
mARView.loadAsset("");

Sonrasında yine boolean değeri ayarlayıp buton yazısını güncelleyerek bitiriyoruz.

isLoadResource = false;
mButton.setText(R.string.btn_text_load);

Son olarak senkronizasyonu sağlamak için aşağıdaki metodları koddaki gibi override etmeyi unutmamalıyız.

OfficeActivity’nin son hali aşağıdaki gibidir.

Bu şekilde, ARView’i uygulamamıza eklemiş oluyoruz. Artık ARView özelliğini kullanabiliriz. Şimdi ARView kısmını Scene Kit ARView özelliğini destekleyen bir cihazda test edelim.

Aşağıdaki gibi masamıza bitki ve akvaryum yerleştirelim ve nasıl göründüğünü test edelim.

Burada önce ARView’in zemini tanıması için fotoğrafta gördüğünüz plane noktaları ekranda çıkana kadar kamerayı yavaşça çevirmeniz gerekli. Plane noktaları zemin üzerinde göründükten sonra load flower butonuna tıklayıp plant ekleyeceğimizi belirtiyoruz. Sonra ekranın bitkiyi eklemek istediğimiz noktasına tıklayarak bitkiyi ekliyoruz. Aynı işlemi akvaryum butonunu tıklayarak yapınca da akvaryum ekleyebiliyoruz.

Ben masama akvaryum ve bitki yerleştirdim. Siz de masanıza veya herhangi bir yere bitki veya akvaryum yerleştirerek nasıl göründüğünü test edebilirsiniz. Aşağıdaki fotoğrafta nasıl göründüğünü görebilirsiniz. Burada Clear Flower ve Clear Aquarium butonları ekranda yerleştirmiş olduğumuz objeleri kaldıracaktır.

Objeleri oluşturduktan sonra aşağıdaki resimde gördüğünüz gibi hareket ettirmek, boyutunu veya yönünü değiştirmek istediğimiz objeyi seçiyoruz. Normal şartlarda seçilen objenin rengi kırmızıya dönüşecektir.(Bazı modellerde renk değişikliği olmuyor. Örneğin burada akvaryum modeli seçildiğinde, modelin rengi kırmızı renge dönüşmüyor.)

Objeyi seçtikten sonra boyutunu değiştirmek istiyorsak zoom in ve zoom out yapabiliriz. Yada sürükleyerek bu objenin yerini değiştirebiliriz. Yönünü değiştirmek için ise iki parmağımızı dairesel hareket ettirebiliriz.

FaceView

Yazımın bu bölümünde FaceView özelliğini uygulamamıza ekleyeceğiz. FaceView özelliğini güneş gözlüğü test bölümünde kullanacağımız için SunglassesActivity isminde bir activity oluşturacağız. Yine önce layout düzenleyerek başlıyoruz.

Layout’u oluştururken FaceView’de hangi SDK’yi kullanacağımızı belirtiyoruz:

activity_sunglasses layout dosyasının son hali aşağıdaki gibidir:

Ben burada sdk type’ı “AR_ENGINE”’ olarak belirterek AR Engine Face Tracking SDK’sını kullanacağımı belirtiyorum. Şimdi SunglassesActivity’nin onCreate() fonksiyonunu override edip, layout’a eklediğimiz FaceView’ı elde edelim ve init() fonksiyonunu çağırarak listener’ı başlatalım.

Şimdi sırada init() fonksiyonunu ekliyoruz. Bu fonksiyonu satır satır anlatacağım:

Bu fonksiyonda öncelikle başlangıç pozu için kullanacağımız position, rotation ve scale değerlerini oluşturuyoruz.(Bu değerler setInitialPose() fonksiyonunun parametresi olarak kullanılacaktır)

Not: Bu değerler kullanılan modele göre değiştirilebilir. Eğer bu örnektekinden farklı bir model kullanacaksanız, uygun değerleri bulmak için kendiniz denemelisiniz. Bu değerlerin ayrıntıları için FaceView setInitialPose() fonksiyonunun dokümantasyonuna bakabilirsiniz.

Sonrasında FaceView’a click listener ayarlıyoruz. Çünkü gözlüğün yüzde gösterilmesi kodunu ekrana uzun basma ile tetikleyeceğiz.

onClick fonksiyonunun içinde öncelikle güneş gözlüğünün oluşturulup oluşturulmadığını kontrol ediyoruz. Eğer güneş gözlüğü oluşturulmamışsa FaceView.loadAsset() fonksiyonu ile renderlanacak materyalin yolunu belirterek yüklüyoruz (Burada assets>FaceView altına eklediğimiz güneş gözlüğünün yolunu belirtiyoruz.) ve referans noktasını ayarlıyoruz. Örneğin burada işaretleyici konumunu LandmarkType.TIP_OF_NOSE olarak belirledik. Bu sayede FaceView modeli yükleyince merkez olarak test eden kişinin burnunu referans alacaktır.

Bu fonksiyon bize geriye integer bir değer dönüyor. Bu değer eğer negatif bir değerse yükleme başarısız olur. Dönüş değeri negatif olmayan bir sayı ise, sayı yüklenen malzemenin indeks değeridir. Bu yüzden bir hata olma olasılığına karşılık bunu kontrol ediyoruz. Eğer yüklenirken hata oluştuysa, Toast mesaj bastırıp çıkıyoruz.

Hata yoksa eğer modelin başlangıç pozunu ve boolean değeri ayarlayıp modeli başarıyla yüklediğimizi belirtiyoruz.

Ekrana tıkladığımızda güneş gözlüğü zaten yüklenmişse, bu defa clearResource ile kaynağı temizliyoruz ardından boş asset yükleyerek güneş gözlüğünü kaldırıyoruz.

Son olarak senkronizasyonu sağlayabilmek için aşağıdaki fonksiyonları override ediyoruz:

SunglassesActivity’nin son hali aşağıdaki gibidir:

Ve FaceView’i de uygulamamıza ekledik. Artık FaceView özelliğini kullanarak gözlük testine başlayabiliriz. Bu bölümü Scene Kit FaceView özelliğini destekleyen bir cihazda derleyip çalıştıralım.

Kamera açıldıktan sonra ekrana dokunduğunuzda gözlük oluşturulacaktır.

SceneView

Yazımın bu bölümünde uygulamamızın ayakkabı satın alma bölümünde kullanacağımız Scene Kit’in SceneView özelliğini uygulayacağız.

SceneView özelliğini ayakkabı satın alma senaryosunda kullanacağımız için, ShoesActivity adında bir activity oluşturuyoruz. Bu activity’nin layout’unda SceneView’i extend eden bir özel view kullanacağız. Bunun için öncelikle CustomSceneView sınıfımızı oluşturalım. Bu sınıfı Activity’den başlatmak için constructor’larını oluşturalım.

Constructor’ları ekledikten sonra, surfaceCreated() fonksiyonunu override etmemiz ve malzemeleri yüklemek ve başlatmak için SceneView API’lerini çağırmamız gerekir.

Not: Her iki constructor’ı da eklemeliyiz.

SceneView’a ait olan surfaceCreated() fonksiyonunu override ediyoruz.

super() fonksiyonu, başlatma logic’ini içerir. surfaceCreated() fonksiyonunu override etmek için ilk satırda super() fonksiyonunu çağırmalıyız.

Ardında loadScene() fonksiyonu ile ayakkabı modelini yüklüyoruz. loadSkyBox() fonksiyonu ile arkaplan ekleyebiliriz. loadSpecularEnvTexture() fonksiyonu sayesinde yansıma efektini yüklüyoruz ve son olarak loadDiffuseEnvTexture() fonksiyonunu çağırarak diffuse map’i yüklüyoruz.

Ayrıca bu view üzerinde ekstra dokunma kontrolleri yapmak istersek, onTouchEvent() fonksiyonunu override edebiliriz.

Şimdi oluşturduğumuz özel view olan CustomSceneView’i ShoesActivity’nin layoutuna ekleyelim.

Artık tek yapmamız gereken layout’u Activity’e ayarlamak. Şimdi ShoesActivity’nin onCreate() fonksiyonunu override ederek, layout’u ayarlıyoruz.

İşte bu kadar!

Artık ayakkabı satın alım kısmında kullanacağımız SceneView özelliğini de eklediğimize göre şimdi sırada MainActivity’den bunları çağırmak kaldı.

Şimdi de navigation yönetimini yapacağımız MainActivity’nin layout’unu düzenleyelim ve aşağıdaki gibi mükemmel kötü bir UI tasarlayalım :)

Şimdi MainActivity’den gerekli başlatmaları yapalım. Önce onCreate metodunu override ederek layout’u ayarlayalım.

Sonra aşağıdaki kodları MainActivity sınıfının içine ekleyerek buton click’leri handle ediyoruz. Tabi burada ARView özelliği ve FaceView özelliklerini kullanırken kamerayı kullanacağımızı unutmamalıyız. Bu sebeple, bahsini ettiğim fonksiyonların içerisinde Kamera iznini de kontrol etmeliyiz.

Kamera izninin kontrolünden sonra akışın devam edeceği yer olan onPermissionResult() fonksiyonunu override ederek buradan verdiğimiz istek kodlarına göre tıklanan activity’e yönlendirme yapacağız. Bunun için aşağıdaki kodu MainActivity’e ekliyoruz.

Kodlama kısmını bitirdiğimize göre bazı notları ekleyebiliriz.

NOT: Beklenen ARView ve FaceView deneyimlerini elde etmek için, uygulamamız daha iyi bir görüntü efekti elde etmek için ekran yönü değişikliğini veya bölünmüş ekran modunu desteklememelidir; bu nedenle aşağıdaki yapılandırmaları AndroidManifest.xml dosyasındaki ilgili activity etiketlerinin içine ekleyin:

android:configChanges="screenSize|orientation|uiMode|density"
android:screenOrientation="portrait"
android:resizeableActivity="false"

Not: Daha iyi görüntü efektleri elde etmek için SceneView, ARView veya FaceView uygulamak için kullandığımız Activity’ler için Full-screen görüntülemeyi de etkinleştirebiliriz.

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

Bu konfigürasyonları yaptıktan sonra uygulamamızın AndroidManifest.xml dosyasının genel görünümü aşağıdaki gibi olacaktır:

Ve bitti :) Şimdi uygulamamızı, özellikleri destekleyen bir cihazda test edelim.

SceneView:

MainActivity :

Özet

Scene Kit ile uygulamamıza, çok zor eklenecek özellikleri herhangi bir grafik kütüphanesiyle uğraşmadan nasıl kolay bir şekilde ekleyebileceğimizi bir senaryo eşliğinde anlatmaya çalıştım. Umarım buraya kadar okuduysanız size bir faydası olmuştur. Okuduğunuz için teşekkür ederim.

Bir sonraki yazılarımda görüşmek üzere…

Full kod:

Kaynak:

3D Modeller:

--

--