1. खास जानकारी
ARCore, Android पर ऑगमेंटेड रिएलिटी (एआर) ऐप्लिकेशन बनाने का प्लैटफ़ॉर्म है. ऑगमेंटेड इमेज की मदद से, ऐसे एआर ऐप्लिकेशन बनाए जा सकते हैं जो असल दुनिया में पहले से रजिस्टर की गई 2D इमेज की पहचान कर सकते हैं और उनके ऊपर वर्चुअल कॉन्टेंट को ऐंकर कर सकते हैं.
यह कोडलैब आपको मौजूदा ARCore सैंपल ऐप्लिकेशन में बदलाव करने का तरीका बताता है, ताकि आप ऐसी ऑगमेंटेड इमेज को शामिल कर सकें जो एक जगह से दूसरी जगह ले जा रही हैं या सही जगह पर मौजूद हैं.
आपको क्या बनाना होगा
इस कोडलैब में, पहले से मौजूद ARCore सैंपल ऐप्लिकेशन को बनाया जा रहा है. कोडलैब के खत्म होने तक, आपका ऐप्लिकेशन ये काम कर पाएगा:
- इमेज के टारगेट का पता लगाएं और टारगेट पर वर्चुअल भूलभुलैया को अटैच करें
- ऑब्जेक्ट के कैमरे के व्यू में होने पर, मूविंग टारगेट को ट्रैक करते रहें
क्या आप पहली बार ARCore ऐप्लिकेशन बना रहे हैं?
क्या आपको इस कोडलैब में सैंपल कोड लिखना है या सिर्फ़ इन पेजों को पढ़ना है?
आप इन चीज़ों के बारे में जानेंगे
- Java में ARCore में ऑगमेंटेड इमेज को इस्तेमाल करने का तरीका
- ARCore से किसी इमेज की पहचान करने की क्षमता का पता लगाने का तरीका
- किसी इमेज पर वर्चुअल कॉन्टेंट अटैच करने और उसकी मूवमेंट को ट्रैक करने का तरीका
ज़रूरी शर्तें
इस कोडलैब को पूरा करने के लिए, आपको खास हार्डवेयर और सॉफ़्टवेयर की ज़रूरत होगी.
हार्डवेयर की आवश्यकताएं
- ARCore के साथ काम करने वाला डिवाइस, जिसे यूएसबी केबल के ज़रिए आपकी डेवलपमेंट मशीन से कनेक्ट किया गया हो
ज़रूरी सॉफ़्टवेयर
- ARCore APK 1.9.0 या इसके बाद का वर्शन. आम तौर पर, यह APK आपके डिवाइस पर Play Store से अपने-आप इंस्टॉल हो जाता है
- Android Studio वाली डेवलपमेंट मशीन (v3.1 या इसके बाद के वर्शन)
- इंटरनेट ऐक्सेस करें, क्योंकि डेवलपमेंट के दौरान आपको लाइब्रेरी डाउनलोड करनी होंगी
अब जब आपने सब कुछ तैयार कर लिया है, तो चलिए शुरू करते हैं!
2. डेवलपमेंट एनवायरमेंट सेट अप करना
SDK टूल डाउनलोड करें
सबसे पहले, हम GitHub से नया ARCore Android SDK डाउनलोड करेंगे. अपनी पसंदीदा जगह पर इसे अनज़िप करें. इस कोडलैब के लिए, SDK टूल का सबसे पुराना वर्शन 1.18.1 है. इस फ़ोल्डर को arcore-android-sdk-x.xx.x
के तौर पर दिखाया जाएगा. इसकी सटीक वैल्यू, आपके इस्तेमाल किए जा रहे SDK टूल का वर्शन होगी.
Android Studio लॉन्च करें और मौजूदा Android Studio प्रोजेक्ट खोलें पर क्लिक करें.
इस अनज़िप किए गए फ़ोल्डर पर जाएं:
arcore-android-sdk-x.xx.x/samples/augmented_image_java
खोलें पर क्लिक करें.
प्रोजेक्ट को सिंक करने के लिए, Android Studio का इंतज़ार करें. अगर आपके Android Studio में ज़रूरी कॉम्पोनेंट मौजूद नहीं हैं, तो हो सकता है कि यह Install missing platform and sync project
मैसेज के साथ काम न करे. समस्या को ठीक करने के लिए निर्देशों का पालन करें.
सैंपल ऐप्लिकेशन चलाएं
अब आपके पास एक चालू ARCore ऐप्लिकेशन प्रोजेक्ट है, तो आइए इसे टेस्ट करके देखें.
अपने ARCore डिवाइस को डेवलपमेंट मशीन से कनेक्ट करें और मेन्यू Run > डिवाइस पर डीबग वर्शन चलाने के लिए, ‘ऐप्लिकेशन' चलाएं. जिस डिवाइस से आपको चलाना है उसे चुनने के लिए कहने वाले डायलॉग बॉक्स में, कनेक्ट किया गया डिवाइस चुनें और ठीक है पर क्लिक करें.
यह सैंपल प्रोजेक्ट, targetSdkVersion 28
का इस्तेमाल करता है. अगर आपके डिवाइस में Failed to find Build Tools revision 28.0.3
जैसी कोई बिल्ड की गड़बड़ी है, तो Android Studio में बताए गए निर्देशों का पालन करके, Android बिल्ड टूल का ज़रूरी वर्शन डाउनलोड और इंस्टॉल करें.
अगर जांच पूरी हो जाती है, तो डिवाइस पर सैंपल ऐप्लिकेशन लॉन्च होगा. इसके बाद, आपको ऑगमेंटेड इमेज को फ़ोटो और वीडियो लेने की अनुमति देने का प्रॉम्प्ट मिलेगा. अनुमति देने के लिए, अनुमति दें पर टैप करें.
सैंपल इमेज की मदद से जांच करना
अब आपने अपना डेवलपमेंट एनवायरमेंट सेट अप कर लिया है, तो ऐप्लिकेशन को देखने के लिए उसकी इमेज देकर उसकी जांच की जा सकती है.
Android Studio में प्रोजेक्ट विंडो में जाकर, ऐप्लिकेशन > ऐसेट पर क्लिक करें और default.jpg
फ़ाइल को खोलने के लिए, उस पर दो बार क्लिक करें.
अपने डिवाइस के कैमरे को स्क्रीन पर मौजूद अर्थ की इमेज के सामने लाएं और स्कैन की जा रही इमेज को क्रॉसहेयर में फ़िट करने के लिए निर्देशों का पालन करें.
एक इमेज फ़्रेम, इमेज के ऊपर इस तरह से ओवरले करेगा:
इसके बाद, हम सैंपल ऐप्लिकेशन में कुछ सुधार करेंगे.
3. 2D इमेज पर भूलभुलैया मॉडल दिखाएं
ऑगमेंटेड इमेज की मदद से गेम खेलना शुरू किया जा सकता है. इसके लिए, आपको ऑगमेंटेड इमेज के ऊपर एक 3D मॉडल दिखाना होगा.
3D मॉडल डाउनलोड करें
इस कोडलैब के लिए, हम "Circle Maze - Green" इस्तेमाल करने जा रहे हैं और साथ ही, CC-BY 3.0 के तहत लाइसेंस मिला है. मैंने इस कोडलैब के GitHub रिपॉज़िटरी में इस 3D मॉडल की एक कॉपी सेव की है. आपको यहां पर जाकर यह जानकारी मिल सकती है.
मॉडल डाउनलोड करने और उसे Android Studio में शामिल करने के लिए, यह तरीका अपनाएं.
- इस कोडलैब (कोड बनाना सीखना) की GitHub रिपॉज़िटरी (तीसरे पक्ष की डायरेक्ट्री) पर जाएं.
- GreenMaze_obj.zip पर क्लिक करें और GreenMaze_obj.zip बटन पर क्लिक करें.
इससे GreenMaze_obj.zip
नाम की फ़ाइल डाउनलोड हो जाती है.
- Android Studio में, ऐप्लिकेशन > में जाकर
green-maze
डायरेक्ट्री बनाएं ऐसेट > मॉडल GreenMaze_obj.zip
को अनज़िप करें और कॉन्टेंट को इस जगह पर कॉपी करें:arcore-android-sdk-x.xx.x/samples/augmented_image_java/app/src/main/assets/models/green-maze
- Android Studio में, ऐप्लिकेशन > ऐसेट > मॉडल > हरी-भुलैया.
इस फ़ोल्डर में दो फ़ाइलें होनी चाहिए: GreenMaze.obj
और GreenMaze.mtl
.
भूलभुलैया मॉडल को रेंडर करें
GreenMaze.obj
3D मॉडल को मौजूदा 2D इमेज के ऊपर दिखाने के लिए, यह तरीका अपनाएं.
AugmentedImageRenderer.java
में, भूलभुलैया मॉडल को रेंडर करने के लिए mazeRenderer
नाम का सदस्य वैरिएबल जोड़ें. भूलभुलैया को इमेज से जोड़ना चाहिए, इसलिए mazeRenderer
को AugmentedImageRenderer
क्लास के अंदर रखना सही रहता है.
AugmentedImageRenderer.java
// Add a member variable to hold the maze model.
private final ObjectRenderer mazeRenderer = new ObjectRenderer();
createOnGlThread()
फ़ंक्शन में, GreenMaze.obj
को लोड करें. सरलता के लिए, उसी फ़्रेम टेक्स्चर का इस्तेमाल करें जो इसकी बनावट है.
AugmentedImageRenderer.java
// Replace the definition of the createOnGlThread() function with the
// following code, which loads GreenMaze.obj.
public void createOnGlThread(Context context) throws IOException {
mazeRenderer.createOnGlThread(
context, "models/green-maze/GreenMaze.obj", "models/frame_base.png");
mazeRenderer.setMaterialProperties(0.0f, 3.5f, 1.0f, 6.0f);
}
draw()
फ़ंक्शन की परिभाषा को नीचे दी गई परिभाषा से बदलें. यह भूलभुलैया के आकार को पता लगाई गई चित्र के आकार के अनुसार समायोजित करता है और उसे स्क्रीन पर रेंडर करता है.
AugmentedImageRenderer.java
// Adjust size of detected image and render it on-screen
public void draw(
float[] viewMatrix,
float[] projectionMatrix,
AugmentedImage augmentedImage,
Anchor centerAnchor,
float[] colorCorrectionRgba) {
float[] tintColor =
convertHexToColor(TINT_COLORS_HEX[augmentedImage.getIndex() % TINT_COLORS_HEX.length]);
final float mazeEdgeSize = 492.65f; // Magic number of maze size
final float maxImageEdgeSize = Math.max(augmentedImage.getExtentX(), augmentedImage.getExtentZ()); // Get largest detected image edge size
Pose anchorPose = centerAnchor.getPose();
float mazeScaleFactor = maxImageEdgeSize / mazeEdgeSize; // scale to set Maze to image size
float[] modelMatrix = new float[16];
// OpenGL Matrix operation is in the order: Scale, rotation and Translation
// So the manual adjustment is after scale
// The 251.3f and 129.0f is magic number from the maze obj file
// You mustWe need to do this adjustment because the maze obj file
// is not centered around origin. Normally when you
// work with your own model, you don't have this problem.
Pose mazeModelLocalOffset = Pose.makeTranslation(
-251.3f * mazeScaleFactor,
0.0f,
129.0f * mazeScaleFactor);
anchorPose.compose(mazeModelLocalOffset).toMatrix(modelMatrix, 0);
mazeRenderer.updateModelMatrix(modelMatrix, mazeScaleFactor, mazeScaleFactor/10.0f, mazeScaleFactor); // This line relies on a change in ObjectRenderer.updateModelMatrix later in this codelab.
mazeRenderer.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColor);
}
अब यह भूल-भुलैया, पृथ्वी की default.jpg
तस्वीर के ऊपर दिखनी चाहिए.
ध्यान दें: क्योंकि आपके पास इस सैंपल 3D मॉडल पर पूरा कंट्रोल नहीं है, इसलिए ऊपर दिया गया कोड कुछ "मैजिक" का इस्तेमाल करता है नंबर. भूलभुलैया मॉडल का आयाम 492.65 x 120 x 492.65 है, जिसके केंद्र का मान (251.3, 60, -129.0) है. इसके शीर्षों की सीमा X, Y, और Z कोऑर्डिनेट की वैल्यू [5.02, 497.67], [0, 120], और [-375.17, 117.25] हैं. इसलिए, भूलभुलैया मॉडल का स्केल image_size / 492.65
होना चाहिए. mazeModelLocalOffset
को इसलिए पेश किया गया है, क्योंकि भूल-भुलैया का 3D मॉडल, मूल (0, 0, 0) के केंद्र में नहीं है.
भूलभुलैया की दीवार अभी भी चित्र में ऊपर फ़िट होने के लिए बहुत ऊंची है. ऐसा हेल्पर फ़ंक्शन updateModelMatrix()
बनाएं जो X, Y, Z को असमान रूप से स्केल करके, मेज़ की ऊंचाई को 0.1 से स्केल कर सके. ध्यान दें, आपको मौजूदा updateModelMatrix(float[] modelMatrix, float scaleFactor)
को बनाए रखना होगा और फ़ंक्शन ओवरलोड updateModelMatrix(float[] modelMatrix, float scaleFactorX, float scaleFactorY, float scaleFactorZ)
को नए फ़ंक्शन के तौर पर जोड़ना होगा.
common/rendering/ObjectRenderer.java
// Scale X, Y, Z coordinates unevenly
public void updateModelMatrix(float[] modelMatrix, float scaleFactorX, float scaleFactorY, float scaleFactorZ) {
float[] scaleMatrix = new float[16];
Matrix.setIdentityM(scaleMatrix, 0);
scaleMatrix[0] = scaleFactorX;
scaleMatrix[5] = scaleFactorY;
scaleMatrix[10] = scaleFactorZ;
Matrix.multiplyMM(this.modelMatrix, 0, modelMatrix, 0, scaleMatrix, 0);
}
कोड चलाएं. भूलभुलैया को अब चित्र के ऊपर ठीक से फ़िट होना चाहिए.
4. भूल-भुलैया में एंडी को जोड़ें
अब आपके पास एक भूल-भुलैया है, तो उसमें चारों ओर घूमने के लिए एक वर्ण जोड़ें. ARCore Android SDK में शामिल andy.obj
फ़ाइल का इस्तेमाल करें. चित्र फ़्रेम की बनावट को उसकी बनावट के रूप में रखें, क्योंकि यह चित्र के शीर्ष पर रेंडर की गई हरी भूलभुलैया से अलग दिखती है.
AugmentedImageRenderer.java
में, एंडी को रेंडर करने के लिए निजी ObjectRenderer
जोड़ें.
AugmentedImageRenderer.java
// Render for Andy
private final ObjectRenderer andyRenderer = new ObjectRenderer();
इसके बाद, createOnGlThread()
के आखिर में andyRenderer
शुरू करें.
AugmentedImageRenderer.java
public void createOnGlThread(Context context) throws IOException {
// Initialize andyRenderer
andyRenderer.createOnGlThread(
context, "models/andy.obj", "models/andy.png");
andyRenderer.setMaterialProperties(0.0f, 3.5f, 1.0f, 6.0f);
}
आखिर में, draw()
फ़ंक्शन के आखिर में, एंडी को भूल-भुलैया पर खड़े होकर रेंडर करें.
AugmentedImageRenderer.java
public void draw(
float[] viewMatrix,
float[] projectionMatrix,
AugmentedImage augmentedImage,
Anchor centerAnchor,
float[] colorCorrectionRgba) {
// Render Andy, standing on top of the maze
Pose andyModelLocalOffset = Pose.makeTranslation(
0.0f,
0.1f,
0.0f);
anchorPose.compose(andyModelLocalOffset).toMatrix(modelMatrix, 0);
andyRenderer.updateModelMatrix(modelMatrix, 0.05f); // 0.05f is a Magic number to scale
andyRenderer.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColor);
}
अपना कोड चलाएं. आपको देखना होगा कि एंडी भूलभुलैया पर सबसे ऊपर खड़ा है.
टारगेट इमेज क्वालिटी तय करें
इमेज की पहचान करने के लिए ARCore विज़ुअल सुविधाओं का इस्तेमाल करता है. क्वालिटी में अंतर होने की वजह से, सभी इमेज की आसानी से पहचान नहीं की जा सकती.
arcoreimg
एक कमांड-लाइन टूल है, जिससे यह पता लगाया जा सकता है कि ARCore की मदद से, कोई इमेज कितनी आसानी से पहचानी जा सकेगी. यह 0 से 100 के बीच की कोई संख्या होती है और 100 की पहचान करना सबसे आसान होता है.
को अपनाएं. यहां एक उदाहरण दिया गया है:
arcore-android-sdk-x.xx.x/tools/arcoreimg/macos$
$ ./arcoreimg eval-img --input_image_path=/Users/username/maze.jpg
100
maze.jpg
की वैल्यू 100 है, इसलिए ARCore से इसे आसानी से पहचाना जा सकता है.
5. ज़रूरी नहीं: ऐंडी को भूल-भुलैया में घुमाएं
आखिर में, एंडी को भूल-भुलैया में ले जाने के लिए, उसमें कुछ कोड जोड़े जा सकते हैं. उदाहरण के लिए, फ़िज़िक्स सिम्युलेशन को हैंडल करने के लिए, ओपन सोर्स फ़िज़िक्स इंजन jBullet का इस्तेमाल करें. अगर आप इस हिस्से को छोड़ दें, तो कोई बात नहीं.
PhysicsController.java
को डाउनलोड करें और इसे डायरेक्ट्री में अपने प्रोजेक्ट में जोड़ें
arcore-android-sdk-x.xx.x/samples/augmented_image_java/app/src/main/java/com/google/ar/core/examples/java/augmentedimage/
Android Studio में, प्रोजेक्ट ऐसेट डायरेक्ट्री में GreenMaze.obj जोड़ें, ताकि इसे रनटाइम के दौरान लोड किया जा सके. GreenMaze.obj
को ऐप्लिकेशन से कॉपी करें > ऐसेट > मॉडल > green-maze से app के लिए > ऐसेट.
ऐप्लिकेशन की build.gradle
फ़ाइल में, ये डिपेंडेंसी जोड़ें.
app/build.gradle
// jbullet library
implementation 'cz.advel.jbullet:jbullet:20101010-1'
एंडी के मौजूदा पोज़ की जगह को सेव करने के लिए, वैरिएबल andyPose
तय करें.
AugmentedImageRenderer.java
// Create a new pose for the Andy
private Pose andyPose = Pose.IDENTITY;
नए andyPose
वैरिएबल का इस्तेमाल करके एंडी को रेंडर करने के लिए, AugmentedImageRenderer.java
में बदलाव करें.
AugmentedImageRenderer.java
public void draw(
float[] viewMatrix,
float[] projectionMatrix,
AugmentedImage augmentedImage,
Anchor centerAnchor,
float[] colorCorrectionRgba) {
// Use these code to replace previous code for rendering the Andy object
//
// Adjust the Andy's rendering position
// The Andy's pose is at the maze's vertex's coordinate
Pose andyPoseInImageSpace = Pose.makeTranslation(
andyPose.tx() * mazeScaleFactor,
andyPose.ty() * mazeScaleFactor,
andyPose.tz() * mazeScaleFactor);
anchorPose.compose(andyPoseInImageSpace).toMatrix(modelMatrix, 0);
andyRenderer.updateModelMatrix(modelMatrix, 0.05f);
andyRenderer.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColor);
}
एंडी पोज़ से जुड़े अपडेट पाने के लिए, एक नया यूटिलिटी फ़ंक्शन updateAndyPose()
जोड़ें.
AugmentedImageRenderer.java
// Receive Andy pose updates
public void updateAndyPose(Pose pose) {
andyPose = pose;
}
AugmentedImageActivity.java
में, एक ऐसा PhysicsController
ऑब्जेक्ट बनाएं जो भौतिकी से जुड़े सभी फ़ंक्शन को मैनेज करने के लिए, JBullet भौतिक इंजन का इस्तेमाल करता हो.
AugmentedImageActivity.java
import com.google.ar.core.Pose;
// Declare the PhysicsController object
private PhysicsController physicsController;
फ़िज़िक्स इंजन में, हम एंडी को दिखाने के लिए एक ठोस बॉल का इस्तेमाल करते हैं और बॉल के पोज़ का इस्तेमाल करके एंडी के पोज़ को अपडेट करते हैं. PhysicsController
को कॉल करें, ताकि ऐप्लिकेशन जब भी किसी इमेज की पहचान करे, तब फ़िज़िक्स को अपडेट करने में मदद मिले. बॉल को असली दुनिया की तरह मूव करने के लिए, रीयल-वर्ल्ड के गुरुत्वाकर्षण का इस्तेमाल करके उसे भूल-भुलैया में ले जाएं.
AugmentedImageActivity.java
// Update the case clause for TRACKING to call PhysicsController
// whenever the app recognizes an image
private void drawAugmentedImages(
...
case TRACKING:
// Switch to UI Thread to update View
this.runOnUiThread(
new Runnable() {
@Override
public void run() {
fitToScanView.setVisibility(View.GONE);
}
});
// Create a new anchor for newly found images
if (!augmentedImageMap.containsKey(augmentedImage.getIndex())) {
Anchor centerPoseAnchor = augmentedImage.createAnchor(augmentedImage.getCenterPose());
augmentedImageMap.put(
augmentedImage.getIndex(), Pair.create(augmentedImage, centerPoseAnchor));
physicsController = new PhysicsController(this);
} else {
Pose ballPose = physicsController.getBallPose();
augmentedImageRenderer.updateAndyPose(ballPose);
// Use real world gravity, (0, -10, 0), as gravity
// Convert to Physics world coordinate(maze mesh has to be static)
// Use the converted coordinate as a force to move the ball
Pose worldGravityPose = Pose.makeTranslation(0, -10f, 0);
Pose mazeGravityPose = augmentedImage.getCenterPose().inverse().compose(worldGravityPose);
float mazeGravity[] = mazeGravityPose.getTranslation();
physicsController.applyGravityToBall(mazeGravity);
physicsController.updatePhysics();
}
break;
ऐप्लिकेशन चलाएं. इमेज को झुकाने पर, एंडी को अब असल में आस-पास घूमना चाहिए.
नीचे दिए गए उदाहरण में, इमेज दिखाने के लिए किसी दूसरे फ़ोन का इस्तेमाल किया गया है. अपनी सुविधा के हिसाब से किसी भी चीज़ का इस्तेमाल किया जा सकता है. जैसे, टैबलेट, हार्डकॉपी बुक का कवर या किसी सपाट चीज़ पर अटैच किया गया पेपर.
हो गया! भूलभुलैया में एंडी को बाहर निकालने की कोशिश करें. संकेत: टारगेट इमेज को ऊपर की ओर रखने पर, बाहर निकलने का रास्ता ढूंढना आसान होता है.
6. बधाई हो
बधाई हो, आप इस कोडलैब के आखिर तक पहुंच गए हैं और आपने:
- ARCore AugmentedImage Java सैंपल बनाया गया और चलाया गया.
- सही स्केल पर, इमेज पर भूलभुलैया मॉडल दिखाने के लिए, सैंपल को अपडेट किया गया.
- कुछ मज़ेदार करने के लिए, इमेज की फ़ोटो का इस्तेमाल किया.
अगर आपको पूरा कोड देखना है, तो उसे यहां से डाउनलोड करें.