التشغيل السريع لـ Google Cardboard لنظام التشغيل iOS

يوضِّح لك هذا الدليل كيفية استخدام حزمة تطوير البرامج (SDK) في Cardboard لنظام التشغيل iOS لإنشاء تجاربك الخاصة في الواقع الافتراضي (VR).

يمكنك استخدام حزمة تطوير البرامج (SDK) في Cardboard لتحويل هاتف ذكي إلى نظام واقع افتراضي. يمكن للهاتف الذكي عرض مشاهد ثلاثية الأبعاد مع عرض مجسم، وتتبُّع حركات الرأس والتفاعل معها، والتفاعل مع التطبيقات من خلال رصد الحالات التي يضغط فيها المستخدم على زر العارض.

للبدء، ستستخدم HelloCardboard، وهي لعبة تجريبية توضح الميزات الأساسية لحزمة تطوير البرامج (SDK) من Cardboard. في اللعبة، يتجول المستخدمون في عالم افتراضي للعثور على الكائنات وجمعها. وتوضِّح لك كيفية:

  • إعداد بيئة التطوير
  • تنزيل التطبيق التجريبي وإنشاؤه
  • امسح ضوئيًا رمز الاستجابة السريعة لعارض Cardboard لحفظ معلماته.
  • تتبع حركات رأس المستخدم
  • يمكنك عرض صور مجسّمة من خلال ضبط التشوّه الصحيح لكل عين.

إعداد بيئة التطوير

متطلبات الأجهزة:

متطلّبات البرامج:

تنزيل التطبيق التجريبي وإنشاؤه

تم إنشاء حزمة تطوير البرامج (SDK) لـ Cardboard باستخدام ملفات مصدر Protocol Buffers C++ المجمّعة مسبقًا. يمكن الاطّلاع هنا على خطوات إنشاء ملفات المصدر من البداية.

  1. استنسِخ حزمة تطوير البرامج (SDK) لـ Cardboard وتطبيق العرض التوضيحي Hello Cardboard من GitHub من خلال تشغيل هذا الأمر:

    git clone https://github.com/googlevr/cardboard.git
  2. ثبِّت تبعية Protocol Buffers في مشروع Xcode من خلال تشغيل هذا الأمر في جذر المستودع:

    pod install
  3. افتح مساحة عمل Cardboard (Cardboard.xcworkspace) في Xcode.

  4. غيِّر معرِّف حزمة التطبيق حتى تتمكّن من توقيع التطبيق مع فريقك.

  5. انتقل إلى SDK > مراحل الإنشاء > ربط النظام الثنائي مع المكتبات.

    1. عليك إزالة "libPods-sdk.a" من القائمة من خلال اختياره والنقر على الزر "-".
    2. يمكنك إضافة libProtobuf-C++.a إلى القائمة من خلال النقر على الزر "+" واختياره. في حالة ظهور رسالة تقترح استخدام XCFramework، انقر على "إضافة على أي حال".
  6. انقر على تشغيل.

المسح الضوئي لرمز الاستجابة السريعة

لحفظ معلمات الجهاز، امسح رمز الاستجابة السريعة على نظّارة Cardboard:

تجربة العرض التوضيحي

في HelloCardboard، ستبحث عن المجالات الجيوديسية وتجمعها في مساحة ثلاثية الأبعاد.

للبحث عن كرة وجمعها:

  1. حرّك رأسك في أي اتجاه حتى ترى كرة عائمة.

  2. انظر مباشرة إلى الكرة. يؤدي هذا إلى تغيير ألوانها.

  3. اضغط على زر نظّارة Cardboard من أجل "جمع" الكرة.

إعداد الجهاز

عندما ينقر المستخدم على رمز الترس لتبديل عارضات Cardboard، يتم استدعاء الطريقة didTapSwitchButton في HelloCardboardOverlayView.

- (void)didTapSwitchButton:(id)sender {
  if ([self.delegate respondsToSelector:@selector(didTapBackButton)]) {
    [self.delegate didChangeViewerProfile];
  }
  self.settingsBackgroundView.hidden = YES;
}

يستدعي هذا الإجراء CardboardQrCode_scanQrCodeAndSaveDeviceParams، الذي يفتح نافذة لمسح رمز الاستجابة السريعة للمُشاهد. عندما يمسح المستخدم ضوئيًا رمز الاستجابة السريعة، يتم تحديث معلمات التشويه للجهاز.

- (void)switchViewer {
  CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}

- (void)didChangeViewerProfile {
  [self pauseCardboard];
  [self switchViewer];
  [self resumeCardboard];
}

تتبُّع حركة الرأس

إنشاء أداة تتبُّع للرأس

يتم إنشاء جهاز تتبُّع الرأس مرة واحدة بالطريقة viewDidLoad في HelloCardboardViewController:

_cardboardHeadTracker = CardboardHeadTracker_create();

إيقاف أداة تتبُّع الرأس مؤقتًا واستئنافها

على التوالي، يتم إيقاف طريقتَي pauseCardboard وresumeCardboard في الصف HelloCardboardViewController ويتم استئنافهما من جديد. يضبط resumeCardboard أيضًا العلامة _updateParams، والتي تؤدي إلى تعديل معلَمات الجهاز في استدعاء الرسم التالي.

- (void)pauseCardboard {
  self.paused = true;
  CardboardHeadTracker_pause(_cardboardHeadTracker);
}

- (void)resumeCardboard {
  // Parameters may have changed.
  _updateParams = YES;

  // Check for device parameters existence in app storage. If they're missing,
  // we must scan a Cardboard QR code and save the obtained parameters.
  uint8_t *buffer;
  int size;
  CardboardQrCode_getSavedDeviceParams(&buffer, &size);
  if (size == 0) {
    [self switchViewer];
  }
  CardboardQrCode_destroy(buffer);

  CardboardHeadTracker_resume(_cardboardHeadTracker);
  self.paused = false;
}

تشوّه العدسة

في كل مرة يمسح فيها Cardboard رمز استجابة سريعة جديدًا، يقرأ الرمز التالي المعلَمات المحفوظة ويستخدمها لإنشاء عنصر تشويه العدسة، والذي يطبّق التشوّه المناسب للعدسة على المحتوى المعروض:

CardboardQrCode_getSavedDeviceParams(&encodedDeviceParams, &size);

// Create CardboardLensDistortion.
CardboardLensDistortion_destroy(_cardboardLensDistortion);
_cardboardLensDistortion =
    CardboardLensDistortion_create(encodedDeviceParams, size, width, height);

// Initialize HelloCardboardRenderer.
_renderer.reset(new cardboard::hello_cardboard::HelloCardboardRenderer(
      _cardboardLensDistortion, _cardboardHeadTracker, width, height));

العرض

يتضمن عرض المحتوى في Cardboard ما يلي:

  • إنشاء الزخارف
  • الحصول على مصفوفات العرض والإسقاط للعينين اليسرى واليمنى
  • إنشاء جهاز العرض وضبط شبكة التشوّه
  • عرض كل إطار

إنشاء زخارف

يتم رسم المحتوى على زخرفة، مقسمة إلى أقسام للعين اليسرى واليمنى. تم إعداد هذه الأقسام في _leftEyeTexture و_rightEyeTexture، على التوالي. يستخدم نموذج التطبيق زخرفة واحدة لكلا العينين، ولكن من الممكن أيضًا إنشاء زخرفة منفصلة لكل عين.

// Generate texture to render left and right eyes.
glGenTextures(1, &_eyeTexture);
glBindTexture(GL_TEXTURE_2D, _eyeTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _width, _height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

_leftEyeTexture.texture = _eyeTexture;
_leftEyeTexture.left_u = 0;
_leftEyeTexture.right_u = 0.5;
_leftEyeTexture.top_v = 1;
_leftEyeTexture.bottom_v = 0;

_rightEyeTexture.texture = _eyeTexture;
_rightEyeTexture.left_u = 0.5;
_rightEyeTexture.right_u = 1;
_rightEyeTexture.top_v = 1;
_rightEyeTexture.bottom_v = 0;
CheckGLError("Create Eye textures");

يتم نقل هذه الزخارف كمعلَمات إلى CardboardDistortionRenderer_renderEyeToDisplay.

احصل على مصفوفات العرض والإسقاط للعين اليمنى واليسرى

أولاً، استرجع مصفوفات العين للعينين اليسرى واليمنى:

CardboardLensDistortion_getEyeFromHeadMatrix(_lensDistortion, kLeft, _eyeMatrices[kLeft]);
CardboardLensDistortion_getEyeFromHeadMatrix(_lensDistortion, kRight, _eyeMatrices[kRight]);
CardboardLensDistortion_getProjectionMatrix(_lensDistortion, kLeft, kZNear, kZFar,
                                            _projMatrices[kLeft]);
CardboardLensDistortion_getProjectionMatrix(_lensDistortion, kRight, kZNear, kZFar,
                                            _projMatrices[kRight]);

بعد ذلك، احصل على شبكات التشوّه لكل عين ومررها إلى عارض التشوه:

CardboardLensDistortion_getDistortionMesh(_lensDistortion, kLeft, &leftMesh);
CardboardLensDistortion_getDistortionMesh(_lensDistortion, kRight, &rightMesh);

إنشاء العارض وضبط شبكة التشوّه الصحيحة

يجب إعداد العارض مرة واحدة فقط. بعد إنشاء العارض، اضبط شبكة التشوّه الجديدة للعينين اليسرى واليمنى وفقًا لقيم الشبكة المتداخلة التي يتم عرضها من الدالة CardboardLensDistortion_getDistortionMesh.

_distortionRenderer = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(_distortionRenderer, &leftMesh, kLeft);
CardboardDistortionRenderer_setMesh(_distortionRenderer, &rightMesh, kRight);

عرض المحتوى

استرداد اتجاه الرأس الحالي من CardboardHeadTracker_getPose:

CardboardHeadTracker_getPose(_headTracker, targetTime, position, orientation);
_headView =
    GLKMatrix4Multiply(GLKMatrix4MakeTranslation(position[0], position[1], position[2]),
                       GLKMatrix4MakeWithQuaternion(GLKQuaternionMakeWithArray(orientation)));

استخدم اتجاه الرأس الحالي مع مصفوفات العرض والإسقاط لإنشاء مصفوفة إسقاط طريقة العرض، واستخدمها لعرض محتوى العالم لكل عين:

// Draw left eye.
glViewport(0, 0, _width / 2.0, _height);
glScissor(0, 0, _width / 2.0, _height);
DrawWorld(_leftEyeViewPose, GLKMatrix4MakeWithArray(_projMatrices[kLeft]));

// Draw right eye.
glViewport(_width / 2.0, 0, _width / 2.0, _height);
glScissor(_width / 2.0, 0, _width / 2.0, _height);
DrawWorld(_rightEyeViewPose, GLKMatrix4MakeWithArray(_projMatrices[kRight]));

استخدِم CardboardDistortionRenderer_renderEyeToDisplay لتطبيق تصحيح التشوّه على المحتوى وعرض المحتوى على الشاشة.

CardboardDistortionRenderer_renderEyeToDisplay(_distortionRenderer, renderTarget, /*x=*/0,
                                               /*y=*/0, _width, _height, &_leftEyeTexture,
                                               &_rightEyeTexture);