API Poly: Mendapatkan aset 3D untuk aplikasi Android VR dan AR anda

Pengarang: Peter Berry
Tarikh Penciptaan: 14 Ogos 2021
Tarikh Kemas Kini: 8 Mungkin 2024
Anonim
3D scan real objects using your phone and display.land for Blender asset, VR and AR!
Video.: 3D scan real objects using your phone and display.land for Blender asset, VR and AR!

Kandungan


Adakah anda mempunyai idea yang bagus untuk apl mudah alih Virtual Reality (VR) atau aplikasinya Reality (AR), tetapi tidak mempunyai idea bagaimana untuk membawa visi anda ke kehidupan?

Kecuali anda pemaju Android yang juga menjadi artis 3D yang berpengalaman, maka mencipta semua aset yang diperlukan untuk menyampaikan pengalaman immersive 360 ​​degree, boleh menjadi proses yang menakutkan.

Hanya kerana anda tidak mempunyai masa, sumber atau pengalaman yang diperlukan untuk mencipta model 3D, tidak maksudnya anda tidak boleh membina aplikasi mudah alih VR atau AR yang hebat! Terdapat banyak sumber 3D yang tersedia secara percuma di World Wide Web, ditambah dengan semua API, kerangka kerja dan perpustakaan yang anda perlukan untuk memuat turun dan menjadikan aset ini dalam aplikasi Android anda.

Baca seterusnya: Anda kini boleh melawat mana-mana laman web menggunakan Daydream VR. Malah itu.

Dalam artikel ini, kami akan melihat Poly, sebuah repositori dalam talian dan API yang meletakkan beribu-ribu aset 3D di hujung jari anda. Menjelang akhir artikel ini, anda akan membuat aplikasi yang mengambil aset Poli 3D pada masa runtime, dan kemudian menjadikannya menggunakan pemprosesan Perpustakaan Pemproses yang popular.


Memaparkan aset 3D dengan Poli

Sekiranya anda pernah terburu-buru dalam pembangunan Perpaduan, maka repositori Poly adalah sama dengan Unity Asset Store - kecuali segala-galanya dalam Poly adalah percuma!

Banyak model 3D Polis diterbitkan di bawah lesen Creative Commons, jadi anda bebas untuk menggunakan, mengubah suai dan remix aset-aset ini, selagi anda memberi pencipta kredit yang sesuai.

Semua model 3D Poli direka untuk bersesuaian dengan platform VR dan AR Google, seperti Daydream dan ARCore, tetapi anda boleh menggunakannya di mana sahaja dan bagaimanapun anda mahu - berpotensi, anda juga boleh menggunakannya dengan ARKit Apple!

Apabila mendapat semula dan memaparkan aset Poly, anda mempunyai dua pilihan. Pertama, anda boleh memuat turun aset ke komputer anda dan kemudian mengimportnya ke Android Studio, jadi mereka menghantar dengan aplikasi anda dan menyumbang ke arah saiz APKnya, atau anda boleh mengambil aset ini pada masa runtime menggunakan API Poly.


Platform berasaskan REST, REST Poly API menyediakan capaian programatik dan baca-baca kepada model 3D koleksi Poly yang besar. Ini lebih rumit daripada menggabungkan aset dengan APK anda, tetapi terdapat beberapa faedah untuk mendapatkan aset Poly saat runtime, terutamanya yang membantu untuk memastikan saiz APK anda terkendali, yang dapat mempengaruhi berapa banyak orang yang memuat turun aplikasi anda.

Anda juga boleh menggunakan API Poly untuk memberi pilihan kepada pengguna anda, contohnya jika anda membangunkan permainan mudah alih maka anda boleh membiarkan pengguna memilih dari pelbagai model karakter.

Oleh kerana anda bebas memodifikasi model Poli, anda juga boleh membiarkan pengguna mengubah taraf pilihan mereka, contohnya dengan mengubah warna rambut atau mata, atau dengan menggabungkannya dengan aset Poli lain, seperti senjata dan perisai yang berlainan. Dengan cara ini, API Poly boleh membantu anda menyampaikan pelbagai aset 3D yang mengagumkan, dengan banyak skop untuk mempersonalisasikan pengalaman itu - dan semua untuk kerja yang relatif sedikit. Pengguna anda akan yakin bahawa anda telah menghabiskan banyak masa, dengan teliti membuat semua model 3D ini!

Mewujudkan projek pemodelan 3D

Kami akan membuat aplikasi yang mengambil aset Poli tertentu apabila aplikasi dilancarkan terlebih dahulu, dan kemudian memaparkan aset tersebut dalam mod skrin penuh, atas permintaan pengguna.

Untuk membantu kami mendapatkan aset ini, saya akan menggunakan Bahan Api, iaitu perpustakaan rangkaian HTTP untuk Kotlin dan Android. Mulakan dengan membuat projek baru dengan tetapan pilihan anda, tetapi apabila digesa memilih untuk "Sertakan sokongan Kotlin."

Semua panggilan yang anda buat kepada API Poly mesti memasukkan kunci API, yang digunakan untuk mengenal pasti apl anda dan menguatkan had penggunaan. Semasa pembangunan dan ujian, anda akan sering menggunakan kunci API tanpa had, tetapi jika anda mempunyai rancangan untuk melepaskan aplikasi ini, maka anda mesti menggunakan kunci API yang dibolehkan Android.

Untuk membuat kunci yang terhad, anda perlu mengetahui sijil menandatangani SHA-1 projek anda, jadi mari dapatkan maklumat ini sekarang:

  • Pilih tab "Gradle" Android Studio (tempat kursor diletakkan di tangkapan skrin berikut). Ini membuka panel "Projek Gradle".

  • Di panel "Gradle projects", klik dua kali untuk mengembangkan 'root' projek anda, kemudian pilih "Tugas> Android> Laporan Tandatangan." Ini membuka panel baru di bahagian bawah tetingkap Android Studio.
  • Pilih 'Tugasan tugas pelaksanaan / mod teks "butang (di mana kursor diletakkan di tangkapan skrin berikut).

Panel "Run" kini akan dikemas kini untuk memaparkan banyak maklumat tentang projek anda, termasuk cap jari SHA-1.

Buat akaun Platform Awan Google

Untuk memperoleh kunci API yang diperlukan, anda memerlukan akaun Google Cloud Platform (GPC).

Jika anda tidak mempunyai akaun, maka anda boleh mendaftar untuk percubaan percuma 12 bulan dengan menuju ke Platform Coba Awan untuk halaman percuma, dan mengikuti arahan. Perhatikan bahawa kad kredit atau kad debit diperlukan, tetapi mengikut halaman Soalan Lazim, ini hanya digunakan untuk mengesahkan identiti anda dan "anda tidak akan dicaj atau dibilkan semasa percubaan percuma anda."

Dapatkan kunci API Poly anda

Sebaik sahaja anda semua mendaftar, anda boleh mengaktifkan API Poli dan buat kekunci anda:

  • Kepala ke Konsol GCP.
  • Pilih ikon berbaris di penjuru kiri sebelah atas, dan pilih "API & Perkhidmatan> Papan Pemuka."
  • Pilih "Dayakan API dan perkhidmatan."
  • Di menu sebelah kiri, pilih "Lain-lain."
  • Pilih "API Poly" kad.
  • Klik butang "Dayakan".
  • Selepas beberapa saat, anda akan dibawa ke skrin baru; buka menu sampingan dan pilih "API & Perkhidmatan> Bukti Kredensial."

  • Dalam pop timbul berikutnya, pilih "Hadkan kekunci."
  • Berikan kunci anda sebagai nama tersendiri.
  • Di bawah "Sekatan aplikasi," pilih "Apl Android".
  • Pilih "Tambah nama pakej dan cap jari."
  • Salin / tampal cap jari SHA-1 projek anda ke dalam medan "Sidang cap jari penandatangan".
  • Masukkan nama pakej projek anda (ia muncul dalam Manifes anda dan di bahagian atas setiap fail kelas).
  • Klik "Simpan."

Anda kini akan dibawa ke skrin "Bukti Kredensial" projek anda, yang mengandungi senarai semua kunci API anda - termasuk kunci API yang diaktifkan Poli yang baru anda buat.

Kebergantungan projek: Sambutan Bahan Api, P3D dan Kotlin

Untuk mendapatkan dan memaparkan aset Poly, kami memerlukan bantuan daripada beberapa perpustakaan tambahan:

  • Bahan api. Polinya pada masa ini tidak mempunyai alatan Android rasmi, jadi anda perlu bekerjasama dengan API terus menggunakan antara muka RESTnya. Untuk menjadikan proses ini lebih mudah, saya akan menggunakan perpustakaan rangkaian HTTP Bahan Api.
  • Pemprosesan untuk Android. Saya akan menggunakan penyajian P3D perpustakaan untuk memaparkan aset Poly.

Buka fail build.gradle projek anda, dan tambahkan dua perpustakaan ini sebagai dependensi projek:

kebergantungan {implementasi fileTree (termasuk:, dir: libs) pelaksanaan "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" pelaksanaan com.android.support:appcompat-v7:27.1.1 // Tambah perpustakaan Bahan Api / / pelaksanaan com.github.kittinunf.fuel: android-fuel: 1.13.0 // Tambah pemprosesan untuk enjin Android // implementasi org.p5android: pemproses-inti: 4.0.1}

Untuk membuat kod kami lebih ringkas, saya juga akan menggunakan sambungan Kotlin Android, jadi mari tambahkan plugin ini semasa kami mempunyai file build.gradle terbuka:

memohon plugin: kotlin-android-extensions

Akhirnya, sejak kita mengambil aset dari Internet, aplikasi kami memerlukan kebenaran Internet. Buka Manifes anda dan tambah yang berikut:

Menambah kunci API anda

Setiap kali aplikasi kami meminta aset dari Poli, ia perlu memasukkan kunci API yang sah. Saya menggunakan teks pemegang tempat, tetapi anda mestilah ganti pemegang tempat ini dengan kunci API anda sendiri jika permohonan itu akan berfungsi.

Saya juga menambah cek, supaya aplikasi itu akan memaparkan amaran jika anda lupa untuk menggantikan teks "INSERT-YOUR-API-KEY":

import android.os.Bundle import android.support.v7.app.AppCompatActivity class MainActivity: AppCompatActivity () {object companion {const val APIKey = "INSERT-YOUR-API-KEY"} override fun onCreate (savedInstanceState: Bundle?) { super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) // Jika kunci API bermula dengan "INSERT" ... // if (APIKey.startsWith ("INSERT")) {// kemudian memaparkan toast berikut ... .// Toast.makeText (ini, "Anda tidak mengemas kini kunci API anda", Toast.LENGTH_SHORT) .show ()} else {... ... ...

Mendapatkan aset itu

Anda boleh memilih apa-apa aset di tapak Poli Google, tetapi saya akan menggunakan model planet Bumi ini.

Anda mengambil aset menggunakan IDnya, yang muncul pada akhir slug URL (disorot dalam tangkapan sebelumnya). Kami menggabungkan ID aset ini, dengan tuan rumah API Poly, iaitu "https://poly.googleapis.com/v1."

import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {object companion {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} override fun onCreate (savedInstanceState: Bundle?) {Super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (ini, "Anda telah mengemas kini kunci API anda", Toast.LENGTH_SHORT) .show ()} else {

Seterusnya, kami perlu membuat permintaan GET ke URL aset, menggunakan kaedah httpGet (). Saya juga menyatakan bahawa jenis tindak balas mesti JSON:

import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {object companion {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} override fun onCreate (savedInstanceState: Bundle?) {Super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) if ( (Toast.makeText (ini, "Anda tidak mengemas kini kunci API anda", Toast.LENGTH_SHORT) .show ()} else {// Buat panggilan server, kemudian lulus data menggunakan "ListOf" method // assetURL.httpGet (listOf ("key" to APIKey)). ResponseJson {request, response, result -> // Do something with the response // result.fold ({val as set = it.obj ()

Aset mungkin mempunyai beberapa format, seperti OBJ, GLTF, dan FBX. Kita perlu menentukan aset itu dalam format OBJ.

Dalam langkah ini, saya juga mengambil nama dan URL semua fail yang perlu kita muat turun,
termasuk fail utama aset ("root"), ditambah sebarang bahan dan tekstur yang berkaitan ("sumber").

Jika permohonan kami tidak dapat memperoleh aset dengan betul, maka ia akan memaparkan toast yang memaklumkan kepada pengguna.

import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {object companion {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} override fun onCreate (savedInstanceState: Bundle?) {Super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (ini, "Anda telah mengemas kini kunci API anda", Toast.LENGTH_SHORT) .show ()} else {// Membuat permintaan GET ke URL aset // asetURL. httpGet (listOf ("kunci" untuk APIKey)). responsJson {permintaan, tindak balas, hasil -> // Lakukan sesuatu dengan respon // result.fold ({val asset = it.obj () var objectURL: String? = null var materialLibraryName: String? = null var materialLibraryURL: String? = null // Semak format aset, menggunakan array "format" // val assetFormats = asset.getJSONArray ("format") // Loop melalui semua format // untuk (i dalam 0 hingga assetFormats.length ()) { val currentFormat = assetFormats.getJSONObject (i) // Gunakan formatType untuk mengenal pasti jenis format sumber ini. Jika formatnya adalah OBJ ... .// if (currentFormat.getString ("formatType") == "OBJ") {// ... setelah mengambil fail 'root' ini, iaitu fail OBJ // objectURL = currentFormat. getJSONObject ("root") .getString ("url") // Ambil semua ketergantungan fail akar // // MaterialLibraryName = currentFormat.getJSONArray ("resources") .getJSONObject (0) .getString ("relativePath") materialLibraryURL = currentFormat.getJSONArray ("resources") .getJSONObject (0) .getString ("url") break}} objectURL !! httpDownload (). destination {_, _-> File (filesDir, "globeAsset.obj" , _, hasil -> result.fold ({}, {// Jika anda tidak dapat mencari atau memuat turun fail OBJ, kemudian tunjukkan ralat // Toast.makeText (ini, "Tidak dapat memuat turun sumber", Toast.LENGTH_SHORT ) .show ()})} materialLibraryURL !! httpDownload (). destination {_, _ -> File (filesDir, materialLibraryName)} .response {_, _, result -> result.fold ({}, {Toast. makeText (ini, "Tidak dapat memuat turun sumber", Toast.LENGTH_SHORT) .show ()})}}, { Toast.makeText (ini, "Tidak dapat memuat turun sumber", Toast.LENGTH_SHORT) .show ()})}}}

Pada ketika ini, jika anda memasang projek pada telefon pintar Android anda atau tablet, atau Peranti Maya Maya (AVD), maka aset tersebut akan dimuatkan dengan jayanya, tetapi aplikasinya tidak akan memaparkannya. Mari selesaikan ini sekarang!

Membuat skrin kedua: Menambah navigasi

Kami akan memaparkan aset dalam mod skrin penuh, jadi mari kita mengemas kini fail main_activity.xml kami untuk menyertakan butang yang, apabila ditoreh, akan melancarkan Aktiviti skrin penuh.

Sekarang mari kita tambahkan onClickListener ke akhir fail MainActivity.kt:

import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {object companion {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} override fun onCreate (savedInstanceState: Bundle?) {Super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (ini, "Anda telah mengemas kini kunci API anda", Toast.LENGTH_SHORT) .show ()} lain {assetURL.httpGet (listOf ("kunci" kepada APIKey)). response.fold ({val asset = it.obj () var objectURL: String? = null var materialLibraryName: String? = null var materialLibraryURL: Str ing? = null val assetFormats = asset.getJSONArray ("format") untuk (i in 0 hingga assetFormats.length ()) {val currentFormat = assetFormats.getJSONObject (i) if (currentFormat.getString ("formatType") == " . {objectURL = currentFormat.getJSONObject ("root") .getString ("url") materialLibraryName = currentFormat.getJSONArray ("resources") .getJSONObject (0) .getString ("relativePath") materialLibraryURL = currentFormat.getJSONArray (" ) .getJSONObject (0) .getString ("url") break}} objectURL !! httpDownload (). destination {_, _ -> File (filesDir, "globeAsset.obj")} .response {_, _, -> result.fold ({}, {Toast.makeText (ini, "Tidak dapat memuat turun sumber", Toast.LENGTH_SHORT) .show ()})} materialLibraryURL !! httpDownload (). destination {_, _ -> File (failDir, materialLibraryName)} .response {_, _, result -> result.fold ({}, {Toast.makeText (ini, "Tidak dapat memuat turun sumber", Toast.LENGTH_SHORT) .show ()}) {Toast.makeText (ini, "Tidak boleh memuat turun sumber", Toast.LENGTH_SHORT) .sh ow ()})} // Melaksanakan butang // displayButton.setOnClickListener {val intent = Niat (ini, SecondActivity :: class.java) startActivity (niat); }}}

Membina kanvas 3D

Sekarang, mari buat Aktiviti di mana kami akan memaparkan aset kami dalam mod skrin penuh:

  • Kawalan-klik fail MainActivity.kt projek anda, dan pilih "New> Kotlin / Class Kotlin."
  • Buka dropdown "Jenis", dan pilih "Kelas."
  • Berikan kelas ini nama "SecondActivity," dan kemudian klik "OK."

Untuk menarik objek 3D, kita memerlukan kanvas 3D! Saya akan menggunakan pemproses P3D Pemprosesan untuk Android, yang bermaksud melanjutkan kelas PApplet, mengatasi kaedah tetapan () dan kemudian lulus P3D sebagai hujah kepada kaedah fullScreen (). Kami juga perlu membuat harta yang mewakili aset Poly sebagai objek PShape.

paparan seronok persendirianSimpan () {val canvas3D = object: PApplet () {var polyAsset: PShape? = null tetapan override yang menyeronokkan () {fullScreen (PConstants.P3D)}

Seterusnya, kita perlu memulakan objek PShape, dengan mengatasi kaedah persediaan (), memanggil kaedah loadShape (), dan kemudian lulus laluan absolut fail .obj:

mengatasi persediaan menyeronokkan () {polyAsset = loadShape (Fail (filesDir, "globeAsset.obj"). absolutePath)}

Melukis pada kanvas P3D

Untuk menarik kanvas 3D ini, kita perlu mengatasi kaedah cabutan ():

mengatasi cabutan menyeronokkan () {background (0) bentuk (polyAsset)}}

Secara lalai, banyak aset yang diambil dari API Poly berada di sisi yang lebih kecil, jadi jika anda menjalankan kod ini sekarang, maka anda mungkin tidak melihat aset itu, bergantung kepada konfigurasi skrin anda. Apabila membuat adegan 3D, anda biasanya akan membuat kamera tersuai supaya pengguna dapat meneroka tempat kejadian dan melihat aset 3D anda dari 360 darjah penuh. Walau bagaimanapun, ini adalah di luar skop artikel ini supaya saya akan mengubah saiz dan kedudukan aset secara manual, untuk memastikan ia sesuai dengan skrin.

Anda boleh meningkatkan saiz aset, dengan lulus nilai negatif kepada kaedah skala ():

skala (-10f)

Anda boleh menyesuaikan kedudukan aset dalam ruang 3D maya menggunakan kaedah menterjemah () dan koordinat berikut:

  • X. Posisi aset di sepanjang paksi mendatar.
  • Y. Posisi aset di sepanjang paksi menegak.
  • Z. Ini adalah paksi "kedalaman / ketinggian", yang mengubah objek 2D menjadi objek 3D. Nilai positif membuat tanggapan bahawa objek itu datang ke arah anda, dan nilai negatif membuat kesan bahawa objek itu bergerak dari anda.

Perhatikan bahawa transformasi adalah kumulatif, jadi semua yang berlaku selepas fungsi itu berkumpul kesannya.

Saya menggunakan yang berikut:

menterjemah (-50f, -100f, 10f)

Inilah kod yang lengkap:

menggambar menarik () {latar belakang (0) skala (-10f) menterjemah (-50f, -100f) // Lukis aset dengan memanggil bentuk () method // shape (polyAsset)}}

Seterusnya, kami perlu membuat fail susun atur yang sepadan, di mana kami akan menambah kanvas 3D sebagai widget FrameLayout:

  • Control-click folder "res> layout" projek anda.
  • Pilih "Fail sumber peletakan."
  • Beri file ini nama "activity_second," dan kemudian klik "OK."

Kini kami mempunyai "asset_view" FrameLayout kami, kami perlu membiarkan SecondActivity kami tahu mengenainya! Flip kembali ke file SecondActivity.kt, buat contoh PFragment baru, dan arahkan ke arah widget "asset_view" kami:

import android.os.Bundle import android.support.v7.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_second. * import processing.android.PFragment import processing.core.PApplet import processing.core.PConstants import processing.core . Import import java.io.File class SecondActivity: AppCompatActivity () {override fun onCreate (savedInstanceState: Bundle?) {Super.onCreate (savedInstanceState) setContentView (R.layout.activity_second) displayAsetset () canvas3D = object: PApplet () {var polyAsset: PShape? = null {fullScreen (PConstants.P3D)} menimpa persediaan yang menyenangkan () {polyAsset = loadShape (fail (filesDir, "globeAsset.obj"). absolutePath) (-10f) menterjemahkan (-50f, -100f) bentuk (polyAsset)}} // Tambah asset // asetViewView = PFragment (kanvas3D) berikut (asset_view, this)}}

Langkah terakhir, adalah menambah SecondActivity ke Manifest anda:

// Tambah berikut //

Menguji projek anda

Kami kini bersedia untuk menguji projek siap! Pasangnya pada peranti Android anda atau AVD, dan pastikan anda mempunyai sambungan Internet yang aktif. Sebaik sahaja aplikasinya dilancarkan, ia akan memuat turun aset itu, dan anda boleh melihatnya dengan memberikan butang "Paparkan Asset" satu ketuk.

Anda boleh memuat turun projek lengkap ini dari GitHub.

Mengakhiri

Dalam artikel ini, kami melihat bagaimana menggunakan API Poly untuk mengambil aset 3D pada masa runtime, dan bagaimana untuk mempamerkan aset itu menggunakan pemprosesan untuk pustaka Android. Adakah anda berfikir bahawa API Poly mempunyai potensi untuk membuat pembangunan VR dan AR diakses oleh lebih banyak orang? Beritahu kami dalam komen di bawah!

Berkaitan

  • Google akan membawa aplikasi AR kepada "beratus-ratus juta" peranti Android pada 2018
  • Google akan mengajar anda tentang pembelajaran AI dan mesin secara percuma
  • 15 permainan VR terbaik untuk Google Cardboard
  • 10 aplikasi VR terbaik untuk Google Cardboard
  • Apa itu Google Fuchsia? Adakah ini Android baru?
  • Apakah itu Google Duplex? - ciri, tarikh pelepasan, dan banyak lagi
  • Bagaimana untuk mencipta aplikasi VR untuk Android dalam masa 7 minit sahaja
  • Alat dengar VR mudah alih - apakah pilihan terbaik anda?

alah atu permainan RPG paling bear dalam beberapa tahun kebelakangan ini akhirnya membuat jalan Barat. Blade Akhir - fantai bergaya oriental yang dibangunkan oleh tudio Korea elatan kyPeople - telah d...

Kebanyakan orang menikmati wang, tetapi tidak ramai yang tahu elok belok kewangan dan perakaunan. ekiranya anda berfikir tentang melompat ke dunia kewangan, inilah peluang anda untuk bermula. Awak bol...

Artikel Terkini.