1. ข้อควรทราบก่อนที่จะเริ่มต้น
นามธรรม
Codelab นี้จะสอนวิธีใช้ข้อมูลจาก Google Maps Platform เพื่อแสดงสถานที่ใกล้เคียงใน Augmented Reality (AR) บน Android
สิ่งที่ต้องมีก่อน
- ความเข้าใจเบื้องต้นเกี่ยวกับการพัฒนา Android โดยใช้ Android Studio
- ทําความคุ้นเคยกับ Kotlin
สิ่งที่จะได้เรียนรู้
- ขออนุญาตจากผู้ใช้ให้เข้าถึงกล้องและตําแหน่งของอุปกรณ์
- ผสานรวมกับ Places API เพื่อดึงข้อมูลสถานที่ใกล้เคียงรอบๆ ตําแหน่งของอุปกรณ์
- ผสานรวมกับ ARCore เพื่อค้นหาพื้นผิวของระนาบแนวนอนเพื่อให้วัตถุเสมือนสามารถยึดติดและวางไว้ในพื้นที่ 3 มิติได้โดยใช้ Sceneform
- รวบรวมข้อมูลเกี่ยวกับตําแหน่งของอุปกรณ์ในพื้นที่โดยใช้ SensorManager และใช้ Maps SDK สําหรับไลบรารียูทิลิตีของ Android เพื่อวางออบเจ็กต์เสมือนในส่วนหัวที่ถูกต้อง
สิ่งที่ต้องมี
- Android Studio 2020.3.1 ขึ้นไป
- เครื่องสนับสนุนที่รองรับ OpenGL ES 3.0 ขึ้นไป
- อุปกรณ์ที่รองรับ ARCore หรือโปรแกรมจําลอง Android ที่เปิดใช้ ARCore (ดูวิธีการในขั้นตอนถัดไป)
2. ตั้งค่า
Android Studio
Codelab นี้ใช้ Android 10.0 (API ระดับ 29) และกําหนดให้คุณต้องติดตั้งบริการ Google Play ใน Android Studio หากต้องการติดตั้งทรัพยากร Dependency ทั้ง 2 รายการนี้ ให้ทําตามขั้นตอนต่อไปนี้
- ไปที่ SDK Manager ซึ่งเข้าถึงได้โดยคลิกเครื่องมือ > SDK SDK
- ตรวจสอบว่าติดตั้ง Android 10.0 หรือไม่ หากไม่ ให้ติดตั้งโดยเลือกช่องทําเครื่องหมายถัดจาก Android 10.0 (Q) แล้วคลิกตกลง และสุดท้าย ให้คลิกตกลงอีกครั้งในกล่องโต้ตอบที่ปรากฏ
- สุดท้าย ติดตั้งบริการ Google Play โดยไปที่แท็บเครื่องมือ SDK เลือกช่องทําเครื่องหมายถัดจากบริการ Google Play คลิกตกลง จากนั้นเลือกตกลงอีกครั้งในกล่องโต้ตอบที่ปรากฏ****
API ที่จําเป็น
ในขั้นตอนที่ 3 ของส่วนต่อไปนี้ ให้เปิดใช้ Maps SDK สําหรับ Android และ Places API สําหรับ Codelab นี้
เริ่มต้นใช้งาน Google Maps Platform
หากคุณไม่เคยใช้ Google Maps Platform มาก่อน ให้ทําตามคู่มือเริ่มต้นใช้งาน Google Maps Platform หรือดูเพลย์ลิสต์การเริ่มต้นใช้งาน Google Maps Platform เพื่อทําตามขั้นตอนต่อไปนี้
- สร้างบัญชีสําหรับการเรียกเก็บเงิน
- สร้างโปรเจ็กต์
- เปิดใช้ Google Maps Platform API และ SDK (แสดงอยู่ในส่วนก่อนหน้า)
- สร้างคีย์ API
ไม่บังคับ: โปรแกรมจําลองของ Android
หากคุณไม่มีอุปกรณ์ที่รองรับ ARCore อีกทางเลือกหนึ่งคือใช้โปรแกรมจําลอง Android เพื่อจําลองโหมด AR รวมถึงปลอมแปลงตําแหน่งของอุปกรณ์ก็ได้ เนื่องจากคุณจะใช้ Sceneform ในการออกกําลังกายนี้ด้วย จึงต้องทําตามขั้นตอนต่างๆ ใน " และกําหนดค่าโปรแกรมจําลองให้รองรับ Sceneform &&tt
3. การเริ่มใช้งานอย่างง่าย
ในการเริ่มต้น ให้ใช้โค้ดต่อไปนี้เป็นโค้ดเริ่มต้นเพื่อช่วยคุณติดตาม Codelab นี้ได้อย่างรวดเร็ว คุณข้ามไปที่โซลูชันนี้ได้ แต่หากต้องการดูทุกขั้นตอน โปรดอ่านต่อไป
คุณโคลนที่เก็บได้หากติดตั้ง git
ไว้
git clone https://github.com/googlecodelabs/display-nearby-places-ar-android.git
หรือคุณจะคลิกปุ่มด้านล่างเพื่อดาวน์โหลดซอร์สโค้ดก็ได้
เมื่อได้รับรหัสแล้ว ให้เปิดโปรเจ็กต์ที่พบในไดเรกทอรี starter
4. ภาพรวมโครงการ
สํารวจโค้ดที่คุณดาวน์โหลดจากขั้นตอนก่อนหน้า ในที่เก็บนี้ คุณจะเห็นโมดูลเดี่ยวที่ชื่อ app
ซึ่งมีแพ็กเกจ com.google.codelabs.findnearbyplacesar
AndroidManifest.xml
มีการประกาศแอตทริบิวต์ต่อไปนี้ในไฟล์ AndroidManifest.xml
เพื่อให้คุณใช้ฟีเจอร์ที่จําเป็นใน Codelab นี้ได้
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Sceneform requires OpenGL ES 3.0 or later. -->
<uses-feature
android:glEsVersion="0x00030000"
android:required="true" />
<!-- Indicates that app requires ARCore ("AR Required"). Ensures the app is visible only in the Google Play Store on devices that support ARCore. For "AR Optional" apps remove this line. -->
<uses-feature android:name="android.hardware.camera.ar" />
สําหรับ uses-permission
ซึ่งจะระบุว่าต้องให้สิทธิ์ใดแก่ผู้ใช้ก่อน ผู้ใช้ดังกล่าวจึงจะใช้สิทธิ์เหล่านี้ได้
android.permission.INTERNET
การกําหนดเป้าหมายนี้จะทําให้แอปสามารถดําเนินการเกี่ยวกับเครือข่ายและดึงข้อมูลผ่านอินเทอร์เน็ตได้ เช่น ข้อมูลสถานที่ผ่าน Places APIandroid.permission.CAMERA
- ต้องมีสิทธิ์เข้าถึงกล้องเพื่อให้คุณใช้กล้องของอุปกรณ์เพื่อแสดงวัตถุใน Augmented Reality ได้android.permission.ACCESS_FINE_LOCATION
- ต้องใช้การเข้าถึงตําแหน่ง คุณสามารถดึงข้อมูลสถานที่ใกล้เคียงซึ่งสัมพันธ์กับตําแหน่งของอุปกรณ์ได้
สําหรับ uses-feature
ซึ่งระบุฟีเจอร์ฮาร์ดแวร์ที่แอปนี้ต้องใช้ ระบบจะประกาศข้อมูลต่อไปนี้
- ต้องใช้ OpenGL ES เวอร์ชัน 3.0
- ต้องใช้อุปกรณ์ที่รองรับ ARCore
นอกจากนี้ ระบบจะเพิ่มแท็กข้อมูลเมตาต่อไปนี้ใต้ออบเจ็กต์แอปพลิเคชัน
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--
Indicates that this app requires Google Play Services for AR ("AR Required") and causes
the Google Play Store to download and install Google Play Services for AR along with
the app. For an "AR Optional" app, specify "optional" instead of "required".
-->
<meta-data
android:name="com.google.ar.core"
android:value="required" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<!-- Additional elements here -->
</application>
รายการข้อมูลเมตารายการแรกเป็นการระบุว่า ARCore เป็นข้อกําหนดเพื่อให้แอปนี้ทํางานได้ และรายการที่สองคือวิธีที่คุณระบุคีย์ API ของ Google Maps Platform แก่ Maps SDK สําหรับ Android
build.gradle
ใน build.gradle
จะมีการระบุทรัพยากร Dependency เพิ่มเติมต่อไปนี้
dependencies {
// Maps & Location
implementation 'com.google.android.gms:play-services-location:17.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.maps.android:maps-utils-ktx:1.7.0'
// ARCore
implementation "com.google.ar.sceneform.ux:sceneform-ux:1.15.0"
// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.7.1"
implementation "com.squareup.retrofit2:converter-gson:2.7.1"
}
ต่อไปนี้คือคําอธิบายโดยย่อของทรัพยากร Dependency แต่ละรายการ
- ไลบรารีที่ใช้รหัสกลุ่ม
com.google.android.gms
เช่นplay-services-location
และplay-services-maps
จะใช้เพื่อเข้าถึงข้อมูลตําแหน่งของอุปกรณ์และฟังก์ชันการเข้าถึงที่เกี่ยวข้องกับ Google Maps com.google.maps.android:maps-utils-ktx
คือไลบรารี Kootlin (KTX) สําหรับ Maps SDK สําหรับไลบรารี Utility Android ระบบจะใช้ฟังก์ชันนี้ในไลบรารีนี้เพื่อจัดตําแหน่งวัตถุเสมือนจริงในภายหลังแบบเรียลไทม์com.google.ar.sceneform.ux:sceneform-ux
เป็นไลบรารี Sceneform ซึ่งช่วยให้คุณแสดงผลฉาก 3 มิติสมจริงได้โดยไม่ต้องเรียนรู้ OpenGL- การขึ้นต่อกันในรหัสกลุ่ม
com.squareup.retrofit2
เป็นทรัพยากร Dependency การนํามาใช้ซ้ํา ซึ่งให้คุณเขียนไคลเอ็นต์ HTTP เพื่อโต้ตอบกับ Places API ได้อย่างรวดเร็ว
โครงสร้างโปรเจ็กต์
ที่นี่คุณจะพบแพ็กเกจและไฟล์ต่อไปนี้
- **api—**แพ็กเกจนี้มีคลาสที่ใช้โต้ตอบกับ Places API โดยใช้ Retrofit
- **ar—**แพ็กเกจนี้มีไฟล์ทั้งหมดที่เกี่ยวข้องกับ ARCore
- **model—**แพ็กเกจนี้มี Data
Place
คลาสเดียวซึ่งใช้เพื่อรวมสถานที่แห่งเดียวตามที่ Places API ส่งคืน - MainActivity.kt -
Activity
นี้จะอยู่ภายในแอป ซึ่งจะแสดงแผนที่และมุมมองกล้อง
5. การตั้งค่าฉาก
เจาะลึกองค์ประกอบสําคัญของแอปโดยเริ่มจากส่วน Augmented Reality
MainActivity
มี SupportMapFragment
ซึ่งจะจัดการการแสดงออบเจ็กต์แผนที่ และคลาสย่อยของ ArFragment
—PlacesArFragment
ซึ่งจะจัดการการแสดง Augmented Reality
การตั้งค่า Augmented Reality
นอกเหนือจากการแสดงฉาก Augmented Reality แล้ว PlacesArFragment
ยังจะดําเนินการขอสิทธิ์ในการใช้กล้องจากผู้ใช้หากยังไม่ได้ทํา คุณยังขอสิทธิ์เพิ่มเติมได้โดยลบล้างเมธอด getAdditionalPermissions
เนื่องจากคุณต้องขอสิทธิ์เข้าถึงตําแหน่งด้วย จากนั้นให้ระบุและลบล้างเมธอด getAdditionalPermissions
ดังนี้
class PlacesArFragment : ArFragment() {
override fun getAdditionalPermissions(): Array<String> =
listOf(Manifest.permission.ACCESS_FINE_LOCATION)
.toTypedArray()
}
เรียกใช้
ดําเนินการต่อและเปิดรหัสโครงกระดูกในไดเรกทอรี starter
ใน Android Studio ได้ หากคลิกเรียกใช้ > เรียกใช้ "แอป' จากแถบเครื่องมือและทําให้แอปใช้งานได้ในอุปกรณ์หรือโปรแกรมจําลอง คุณควรได้รับแจ้งให้เปิดใช้สิทธิ์เข้าถึงตําแหน่งและกล้องก่อน หลังจากนั้นให้คลิกอนุญาต และขณะเดียวกัน คุณจะเห็นมุมมองกล้องและมุมมองแผนที่เทียบกันดังนี้
การตรวจจับเครื่องบิน
เมื่อมองดูสภาพแวดล้อมรอบตัวคุณด้วยกล้อง คุณอาจสังเกตเห็นจุดสีขาว 2-3 จุดที่วางซ้อนบนพื้นผิวในแนวนอน เช่น จุดสีขาวบนพรมในรูปภาพนี้
จุดสีขาวเหล่านี้เป็นหลักเกณฑ์จาก ARCore ที่บ่งชี้ว่าระนาบแนวนอนที่ตรวจพบ เครื่องบินที่ตรวจพบเหล่านี้ช่วยให้คุณสร้างสิ่งที่เรียกว่า #quot;anchor" เพื่อที่คุณจะได้จัดตําแหน่งวัตถุเสมือนจริงในแบบเรียลไทม์ได้
โปรดอ่านแนวคิดพื้นฐานเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับ ARCore และทําความเข้าใจสภาพแวดล้อมรอบตัว
6. รับข้อมูลสถานที่ใกล้เคียง
จากนั้น คุณจะต้องเข้าถึงและแสดงตําแหน่งปัจจุบันของอุปกรณ์ตามด้วยการดึงข้อมูลสถานที่ใกล้เคียงโดยใช้ Places API
การตั้งค่า Maps
คีย์ API ของ Google Maps Platform
ก่อนหน้านี้คุณได้สร้างคีย์ Google Maps Platform API เพื่อเปิดใช้การค้นหา Places API และสามารถใช้ Maps SDK สําหรับ Android ได้ ดําเนินการต่อและเปิดไฟล์ gradle.properties
และแทนที่สตริง "YOUR API KEY HERE"
ด้วยคีย์ API ที่คุณสร้าง
แสดงตําแหน่งของอุปกรณ์บนแผนที่
เมื่อเพิ่มคีย์ API แล้ว ให้เพิ่มโปรแกรมช่วยเหลือบนแผนที่เพื่อช่วยจัดตําแหน่งผู้ใช้ให้สัมพันธ์กับแผนที่ หากต้องการทําเช่นนั้น ให้ไปที่เมธอด setUpMaps
และภายในการโทร mapFragment.getMapAsync
ให้ตั้งค่า googleMap.isMyLocationEnabled
เป็น true.
เพื่อแสดงจุดสีน้ําเงินบนแผนที่
private fun setUpMaps() {
mapFragment.getMapAsync { googleMap ->
googleMap.isMyLocationEnabled = true
// ...
}
}
ดูตําแหน่งปัจจุบัน
หากต้องการดูตําแหน่งของอุปกรณ์ คุณจะต้องใช้ประโยชน์จากชั้นเรียน FusedLocationProviderClient
การรับอินสแตนซ์นี้ทําได้แล้วในเมธอด onCreate
ของ MainActivity
หากต้องการใช้ออบเจ็กต์นี้ โปรดกรอกข้อมูลในเมธอด getCurrentLocation
ซึ่งยอมรับอาร์กิวเมนต์แลมบ์ดา เพื่อให้ระบบส่งตําแหน่งไปยังผู้โทรของเมธอดนี้ได้
ในการใช้วิธีนี้ คุณสามารถเข้าถึงพร็อพเพอร์ตี้ lastLocation
ของออบเจ็กต์ FusedLocationProviderClient
ได้ด้วยการเพิ่มใน addOnSuccessListener
ดังนี้
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
currentLocation = location
onSuccess(location)
}.addOnFailureListener {
Log.e(TAG, "Could not get location")
}
ระบบจะเรียกเมธอด getCurrentLocation
จากแลมบ์ดาที่ให้ไว้ใน getMapAsync
ในเมธอด setUpMaps
ที่ดึงข้อมูลสถานที่ใกล้เคียง
เริ่มต้นการโทรในเครือข่ายสถานที่
ในการเรียกใช้เมธอด getNearbyPlaces
โปรดทราบว่าพารามิเตอร์ต่อไปนี้จะส่งผ่านเมธอด placesServices.nearbyPlaces
เช่น คีย์ API, ตําแหน่งของอุปกรณ์, รัศมีเป็นเมตร (ซึ่งตั้งค่าเป็น 2 กม.) และประเภทสถานที่ (ขณะนี้ตั้งค่าเป็น park
)
val apiKey = "YOUR API KEY"
placesService.nearbyPlaces(
apiKey = apiKey,
location = "${location.latitude},${location.longitude}",
radiusInMeters = 2000,
placeType = "park"
)
หากต้องการเรียกใช้เครือข่ายให้เสร็จสิ้น โปรดส่งต่อคีย์ API ที่คุณกําหนดไว้ในไฟล์ gradle.properties
ระบบจะกําหนดข้อมูลโค้ดต่อไปนี้ในไฟล์ build.gradle
ภายใต้การกําหนดค่า android > defaultConfig
android {
defaultConfig {
resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
}
}
ซึ่งจะทําให้ค่าทรัพยากรสตริง google_maps_key
พร้อมใช้งานในเวลาบิลด์
หากต้องการเรียกเครือข่ายให้เสร็จสมบูรณ์ คุณเพียงแค่อ่านทรัพยากรสตริงนี้ผ่าน getString
ในออบเจ็กต์ Context
val apiKey = this.getString(R.string.google_maps_key)
7. สถานที่ใน AR
จนถึงตอนนี้ คุณทําสิ่งต่อไปนี้แล้ว
- ขอสิทธิ์เข้าถึงกล้องและตําแหน่งจากผู้ใช้เมื่อเรียกใช้แอปครั้งแรก
- ตั้งค่า ARCore เพื่อเริ่มติดตามเครื่องบินแนวนอน
- ตั้งค่า Maps SDK ด้วยคีย์ API
- รับตําแหน่งปัจจุบันของอุปกรณ์
- ดึงสถานที่ใกล้เคียง (โดยเฉพาะสวนสาธารณะ) โดยใช้ Places API
ที่เหลือให้ทําแบบฝึกหัดนี้ก็คือการวางตําแหน่งที่จะดึงข้อมูลผ่าน Augmented Reality
ทําความเข้าใจสถานการณ์
ARCore เข้าใจฉากในโลกแห่งความเป็นจริงผ่านกล้องของอุปกรณ์ได้โดยการตรวจจับจุดที่น่าสนใจและโดดเด่นที่เรียกว่า "ฟีเจอร์โฟน" ในแต่ละเฟรมรูปภาพ เมื่อมีการรวมจุดเด่นเหล่านี้เข้าด้วยกันและอยู่บนระนาบแนวนอนทั่วไป เช่น ตารางและพื้น ARCore จะทําให้ฟีเจอร์นี้พร้อมใช้งานเป็นแอปแนวนอน
ดังที่คุณเห็นก่อนหน้านี้ ARCore จะช่วยแนะนําผู้ใช้เมื่อตรวจพบเครื่องบินโดยแสดงจุดสีขาว
การเพิ่มโฆษณา Anchor
เมื่อระบบตรวจพบเครื่องบินแล้ว คุณจะแนบวัตถุที่เรียกว่าแท็ก Anchor ได้ คุณจะวางวัตถุเสมือนจริงไว้ได้ด้วย Anchor และรับประกันว่าวัตถุเหล่านั้นจะปรากฏในตําแหน่งเดียวกันในพื้นที่ทํางาน แล้วแก้ไขโค้ดเพื่อแนบรหัสเมื่อตรวจพบเครื่องบิน
ใน setUpAr
OnTapArPlaneListener
จะแนบกับ PlacesArFragment
Listener นี้จะถูกเรียกใช้ทุกครั้งที่แตะเครื่องบินในโหมด AR ภายในการเรียกนี้ คุณสามารถสร้าง Anchor
และ AnchorNode
จาก HitResult
ที่ระบุไว้ใน Listener ดังนี้
arFragment.setOnTapArPlaneListener { hitResult, _, _ ->
val anchor = hitResult.createAnchor()
anchorNode = AnchorNode(anchor)
anchorNode?.setParent(arFragment.arSceneView.scene)
addPlaces(anchorNode!!)
}
AnchorNode
คือที่ที่คุณจะแนบออบเจ็กต์โหนดย่อย (เช่น PlaceNode
) ในฉากที่จัดการในการเรียกใช้เมธอด addPlaces
เรียกใช้
หากคุณเรียกใช้แอปโดยแก้ไขตามข้างต้น ให้มองรอบตัวคุณจนกว่าจะตรวจพบเครื่องบิน ไปต่อที่จุดสีขาวซึ่งแสดงเครื่องบิน ซึ่งเมื่อทําเช่นนั้น คุณจะเห็นเครื่องหมายบนแผนที่แสดงสวนสาธารณะที่ใกล้ที่สุดรอบตัวคุณ อย่างไรก็ตาม หากสังเกตเห็นว่า วัตถุเสมือนติดอยู่บนตัวยึด โดยไม่ได้วางไว้ข้างที่ของสวนสาธารณะเหล่านั้น
สําหรับขั้นตอนสุดท้าย คุณจะแก้ไขได้โดยใช้ Maps SDK สําหรับไลบรารียูทิลิตีของ Android และ SensorManager ในอุปกรณ์
8. การกําหนดตําแหน่ง
หากต้องการจัดตําแหน่งไอคอนสถานที่เสมือนจริงใน Augmented Reality เป็นส่วนหัวที่ถูกต้อง คุณจะต้องมีข้อมูลต่อไปนี้ 2 ส่วน
- ทิศเหนือที่เป็นจริง
- มุมระหว่างทิศเหนือกับสถานที่แต่ละแห่ง
หันไปทางทิศเหนือ
ทิศเหนือกําหนดได้โดยใช้เซ็นเซอร์ตําแหน่ง (แม่เหล็กและตัวตรวจวัดความเร่ง) ที่มีในอุปกรณ์ การใช้เซ็นเซอร์ 2 ตัวนี้จะทําให้คุณรวบรวมข้อมูลแบบเรียลไทม์เกี่ยวกับตําแหน่งของอุปกรณ์ในอวกาศได้ สําหรับข้อมูลเพิ่มเติมเกี่ยวกับเซ็นเซอร์ตําแหน่ง โปรดอ่านคํานวณการวางแนวของอุปกรณ์
หากต้องการเข้าถึงเซ็นเซอร์เหล่านี้ คุณจะต้องได้รับ SensorManager
ตามด้วยการลงทะเบียน SensorEventListener
ในเซ็นเซอร์เหล่านั้น มีขั้นตอนเหล่านี้ให้คุณได้แล้วในวิธีวงจรของ MainActivity
'
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
sensorManager = getSystemService()!!
// ...
}
override fun onResume() {
super.onResume()
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)?.also {
sensorManager.registerListener(
this,
it,
SensorManager.SENSOR_DELAY_NORMAL
)
}
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)?.also {
sensorManager.registerListener(
this,
it,
SensorManager.SENSOR_DELAY_NORMAL
)
}
}
override fun onPause() {
super.onPause()
sensorManager.unregisterListener(this)
}
ในเมธอด onSensorChanged
จะมีการระบุออบเจ็กต์ SensorEvent
ซึ่งมีรายละเอียดเกี่ยวกับเซ็นเซอร์ที่ให้ไว้และมีการเปลี่ยนแปลงเมื่อมีการเปลี่ยนแปลงเมื่อเวลาผ่านไป เพิ่มโค้ดต่อไปนี้ลงในเมธอดนั้น
override fun onSensorChanged(event: SensorEvent?) {
if (event == null) {
return
}
if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
System.arraycopy(event.values, 0, accelerometerReading, 0, accelerometerReading.size)
} else if (event.sensor.type == Sensor.TYPE_MAGNETIC_FIELD) {
System.arraycopy(event.values, 0, magnetometerReading, 0, magnetometerReading.size)
}
// Update rotation matrix, which is needed to update orientation angles.
SensorManager.getRotationMatrix(
rotationMatrix,
null,
accelerometerReading,
magnetometerReading
)
SensorManager.getOrientation(rotationMatrix, orientationAngles)
}
โค้ดข้างต้นจะตรวจสอบประเภทของเซ็นเซอร์และจะอัปเดตการอ่านเซ็นเซอร์ที่เหมาะสม (ไม่ว่าจะเป็นตัวตรวจวัดความเร่งหรือเครื่องวัดค่าความเข้มข้นของสนามแม่เหล็ก) ทั้งนี้ขึ้นอยู่กับประเภท เมื่อใช้ค่าที่อ่านได้จากเซ็นเซอร์เหล่านี้ เราจะถือว่าค่ากี่องศาจากทิศเหนือที่สัมพันธ์กับอุปกรณ์ (เช่น ค่าของ orientationAngles[0]
)
ส่วนหัวแบบ 360 องศา
เมื่อระบุทิศเหนือแล้ว ขั้นตอนถัดไปคือการกําหนดมุมระหว่างทิศเหนือและแต่ละสถานที่ ตามด้วยข้อมูลนั้นเพื่อวางสถานที่ในส่วนหัวที่ถูกต้องใน Augmented Reality
ในการคํานวณส่วนหัว คุณจะต้องใช้ SDK ของ Maps สําหรับไลบรารียูทิลิตีของ Android ซึ่งมีฟังก์ชันช่วยมากมายสําหรับระยะทางในการประมวลผลและส่วนหัวผ่านเรขาคณิตทรงกลม โปรดอ่านข้อมูลเพิ่มเติมที่หัวข้อภาพรวมของไลบรารีนี้
ถัดไปคุณจะต้องใช้วิธีการของ sphericalHeading
ในไลบรารียูทิลิตี ซึ่งคํานวณส่วนหัว/ทิศทางระหว่างออบเจ็กต์ LatLng
ทั้ง 2 รายการ ต้องป้อนข้อมูลนี้ภายในเมธอด getPositionVector
ที่กําหนดไว้ใน Place.kt
ในที่สุดเมธอดนี้จะแสดงออบเจ็กต์ Vector3
ซึ่ง PlaceNode
แต่ละรายการจะใช้ตําแหน่งดังกล่าวเป็นตําแหน่งในพื้นที่ AR
ดําเนินการต่อและแทนที่การกําหนดส่วนหัวในวิธีการนั้นด้วยข้อมูลต่อไปนี้
val heading = latLng.sphericalHeading(placeLatLng)
ซึ่งควรส่งผลให้เกิดคําจํากัดความของวิธีการต่อไปนี้
fun Place.getPositionVector(azimuth: Float, latLng: LatLng): Vector3 {
val placeLatLng = this.geometry.location.latLng
val heading = latLng.sphericalHeading(placeLatLng)
val r = -2f
val x = r * sin(azimuth + heading).toFloat()
val y = 1f
val z = r * cos(azimuth + heading).toFloat()
return Vector3(x, y, z)
}
ตําแหน่งในเครื่อง
ขั้นตอนสุดท้ายในการดูแลสถานที่อย่างถูกต้องใน AR คือการใช้ผลลัพธ์ของ getPositionVector
เมื่อมีการเพิ่มออบเจ็กต์ PlaceNode
ลงในฉาก ดําเนินการต่อและไปที่ addPlaces
ใน MainActivity
ด้านขวาใต้บรรทัดที่กําหนดผู้ปกครองใน placeNode
แต่ละรายการ (ใต้ placeNode.setParent(anchorNode)
) ตั้งค่า localPosition
ของ placeNode
ตามผลลัพธ์ของการเรียกใช้ getPositionVector
ดังนี้
val placeNode = PlaceNode(this, place)
placeNode.setParent(anchorNode)
placeNode.localPosition = place.getPositionVector(orientationAngles[0], currentLocation.latLng)
โดยค่าเริ่มต้น เมธอด getPositionVector
จะตั้งค่าระยะทาง y ของโหนดเป็น 1 เมตรดังที่ระบุโดยค่า y
ในเมธอด getPositionVector
หากต้องการปรับระยะทางนี้ ให้พูดว่า 2 เมตร แล้วแก้ไขค่านั้นตามต้องการ
การเปลี่ยนแปลงนี้ทําให้ออบเจ็กต์ PlaceNode
ที่เพิ่มเข้ามาควรอยู่ในทิศทางที่ถูกต้อง เริ่มต้นใช้งานแล้วเรียกใช้แอปเพื่อดูผลลัพธ์
9. ยินดีด้วย
ขอแสดงความยินดีกับการก้าวไปอีกขั้น