Guida rapida per Google Cardboard per iOS

Questa guida mostra come utilizzare l'SDK Cardboard per iOS per creare esperienze di realtà virtuale (VR).

Puoi usare l'SDK di Cardboard per trasformare uno smartphone in una piattaforma VR. Uno smartphone può mostrare scene 3D con rendering stereoscopico, seguire e reagire ai movimenti della testa e interagire con le app rilevando quando l'utente preme il pulsante del visore.

Per iniziare, utilizzerai HelloCardboard, un gioco demo che dimostra le caratteristiche principali dell'SDK Cardboard. Nel gioco gli utenti esplorano il mondo virtuale per trovare e raccogliere oggetti. Ti mostra come:

  • Configurazione dell'ambiente di sviluppo
  • Scarica e crea l'app demo
  • Scansiona il codice QR di un visore Cardboard per salvarne i parametri
  • Monitorare i movimenti della testa dell'utente
  • Visualizza le immagini stereoscopiche impostando la distorsione corretta per ogni occhio

Configurazione dell'ambiente di sviluppo

Requisiti hardware:

Requisiti software:

Scarica e crea l'app demo

L'SDK di Cardboard è realizzato utilizzando file di origine C++ precompilati di buffer di protocollo. I passaggi per creare i file di origine da zero sono disponibili qui.

  1. Clona l'SDK Cardboard e l'app demo Hello Cardboard da GitHub eseguendo questo comando:

    git clone https://github.com/googlevr/cardboard.git
  2. Installa la dipendenza Protocol Buffers nel progetto Xcode eseguendo questo comando nella directory radice del repository:

    pod install
  3. Apri l'area di lavoro di Cardboard (Cardboard.xcworkspace) in Xcode.

  4. Modifica l'ID gruppo dell'app in modo da poter firmare l'app con il tuo team.

  5. Vai a SDK > Fasi di creazione > Collega file binario a librerie.

    1. Rimuovi libPods-sdk.a dall'elenco selezionandolo e facendo clic sul pulsante "-".
    2. Aggiungi libProtobuf-C++.a all'elenco facendo clic sul pulsante "+" e selezionandolo. Se visualizzi un messaggio che suggerisce di utilizzare un XCFramework, fai clic su "Aggiungi comunque".
  6. Fai clic su Esegui.

Scansiona il codice QR

Per salvare i parametri del dispositivo, scansiona il codice QR sul visore Cardboard:

Prova la demo

In HelloCardboard cercare e raccogliere sfere geodetiche nello spazio 3D.

Per trovare e raccogliere una sfera:

  1. Muovi la testa in qualsiasi direzione finché non vedi una sfera mobile.

  2. Guardare direttamente la sfera. Questo causa la modifica dei colori.

  3. Premi il pulsante del visore Cardboard per "raccogliere" la sfera.

Configura il dispositivo

Quando l'utente tocca l'icona a forma di ingranaggio per cambiare i visori Cardboard, il metodo didTapSwitchButton viene richiamato in HelloCardboardOverlayView.

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

Viene chiamata CardboardQrCode_scanQrCodeAndSaveDeviceParams, che apre la finestra per la scansione del codice QR del visualizzatore. Quando l'utente scansiona il codice QR, i parametri di distorsione del dispositivo vengono aggiornati.

- (void)switchViewer {
  CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}

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

Rilevamento dei movimenti della testa

Crea tracker della testa

Il tracker della testa viene creato una volta nel metodo viewDidLoad di HelloCardboardViewController:

_cardboardHeadTracker = CardboardHeadTracker_create();

Metti in pausa e riprendi il tracker della testa

I metodi pauseCardboard e resumeCardboard nella lezione HelloCardboardViewController mettono in pausa e riprendono rispettivamente il tracker della testa. resumeCardboard imposta anche il flag _updateParams, che determina l'aggiornamento dei parametri del dispositivo nella prossima chiamata al disegno.

- (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;
}

Distorsione obiettivo

Ogni volta che Cardboard scansiona un nuovo codice QR, il seguente codice legge i parametri salvati e li utilizza per creare l'oggetto di distorsione dell'obiettivo, che applica la corretta distorsione dell'obiettivo al contenuto visualizzato:

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));

Rendering

Il rendering dei contenuti in Cardboard prevede quanto segue:

  • Creazione di texture
  • Come ottenere le matrici di visualizzazione e di proiezione per l'occhio sinistro e destro
  • Creazione del renderer e impostazione del mesh di distorsione
  • Rendering di ogni frame

Crea texture

Il contenuto viene disegnato su una texture, suddivisa in sezioni per l'occhio destro e sinistro. Queste sezioni sono inizializzate rispettivamente in _leftEyeTexture e _rightEyeTexture. L'app di esempio utilizza un'unica texture per entrambi gli occhi, ma è anche possibile creare una trama distinta per ogni occhio.

// 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");

Queste texture vengono passate come parametri a CardboardDistortionRenderer_renderEyeToDisplay.

Visualizza le matrici di visualizzazione e proiezione per l'occhio sinistro e destro

Per prima cosa, recupera le matrici dell'occhio sinistro e destro:

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]);

Quindi ottieni i mesh di distorsione per ciascuno degli occhi e passali al renderer di distorsione:

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

Crea il renderer e imposta il mesh di distorsione corretto

Il renderer deve essere inizializzato una sola volta. Dopo aver creato il renderer, imposta il nuovo mesh di distorsione per gli occhi sinistro e destro in base ai valori mesh restituiti dalla funzione CardboardLensDistortion_getDistortionMesh.

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

Rendering dei contenuti

Recupera l'orientamento attuale della testa da CardboardHeadTracker_getPose:

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

Utilizza l'orientamento attuale della testa con le matrici di vista e proiezione per comporre una matrice di proiezione e usale per eseguire il rendering dei contenuti del mondo per ciascuno degli occhi:

// 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]));

Usa CardboardDistortionRenderer_renderEyeToDisplay per applicare la correzione della distorsione ai contenuti e visualizzarli sullo schermo.

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