APLICAȚIE ANDROID PENTRU REALITATE VIRTUALĂ COORDONATOR ȘTIINȚIFIC: Conf. univ. dr. Mironela Pîrnău Absolvent: Bogdan Andrei Roman SESIUNEA IUNIE… [305779]

UNIVERSITATEA “TITU MAIORESCU” DIN BUCUREȘTI

FACULTATEA DE INFORMATICĂ

LUCRARE DE LICENȚĂ

APLICAȚIE ANDROID PENTRU REALITATE VIRTUALĂ

COORDONATOR ȘTIINȚIFIC:

Conf. univ. dr. Mironela Pîrnău

Absolvent: [anonimizat]

2016

Abstract

În primii 5 ani ai secolului 21 realitatea virtuală a avut o [anonimizat], [anonimizat], [anonimizat]. [anonimizat], de procesare grafică 3D, au permis o generație de dispozitive ușoare și practice realității virtuale.

Obiectivul principal al temei de licență a [anonimizat], [anonimizat].

“[anonimizat], comunicarea se făcea față în față. Acum, majoritatea ei e digitală, [anonimizat]. [anonimizat]-am întoarce spre origini.”

[anonimizat].

Conținutul lucrării

Lucrarea de față este împărțită în 9 părți, după cum urmează:

Capitolul 1: [anonimizat] o scurtă istorie.

Capitolul 2: [anonimizat], [anonimizat].

Capitolul 3: Proiectarea generală a aplicației oferă o scurtă introducere și o descriere a aplicației Flyer.

Capitolul 4: [anonimizat], cu privire la principalele soluții similare existente pe piață la ora actuală. [anonimizat] o descriere a [anonimizat], bazată pe scenarii de utilizare.

Capitolul 5: [anonimizat], [anonimizat].

Capitolul 6: Posibilități de dezvoltare ulterioare oferă câteva posibilități de extindere.

Capitolul 7: [anonimizat], însoțit de concluzii.

Capitolul 8: Abrevieri

Capitolul 9: Bibliografie

1. Repere conceptuale în domeniul aplicațiilor android

1.1. [anonimizat]. Android a [anonimizat] 2010, în primul trimestru al anului 2016, raportând o cotă de 60,99% din piața mondială a smartphone-urilor, cu un total aproximat la 1,4 miliarde de dispozitive cu acest sistem de operare instalat.

Android a început de la o [anonimizat] 2005. [anonimizat], o [anonimizat]: [anonimizat], Inel, LG, Motorola, [anonimizat], Tmobile sau Texas Instruments.

[anonimizat] o [anonimizat] („apps”), care extind funcționalitatea dispozitivelor. [anonimizat]cipal, codul versiunii custom de Java. Applicațiile pot fi descărcate de pe magazine online, ca Google Play (fostul Android Market), magazinul condus de Google. În februarie 2016 erau mai mult de 2.000.000 aplicații disponibile pentru Android.

Până de curând, telefoanele mobile au fost medii închise, construite pe sisteme de operare proprietare foarte fragmentate, sisteme care aveau nevoie de tool-uri de dezvoltare specifice. Telefoanele, deseori prioritizau rularea aplicațiilor native, în detrimentul aplicațiilor scrise de diverși dezvoltatori. Acest lucru a introdus o barieră artificială pentru dezvoltatori, aceștia fiind nevoiți să aștepte după hardware-uri din ce în ce mai puternice, pentru dezvoltarea aplicațiilor. În android, aplicațiile native și cele create de terți dezvoltatori, sunt scrise folosind aceleași API-uri și sunt executate în același timp. Aceste API-uri oferă acces la hardware-ul telefonului, înregistrări video, comunicarea dintre aplicații și grafica 2D și 3D.

Android are niște API-uri puternice, excelent documentate, o comunitate de dezvoltatori în continuă expansiune și fără costuri, în ceea ce privește dezvoltarea și distribuția aplicațiilor. După cum dispozitivele mobile continuă să crească în popularitate, Android oferă o oportunitate interesantă, pentru crearea de aplicații inovative pentru telefoane, indiferent de experiența dezvoltatorului.

Dezvoltatorii, care programau utilizând cod C sau C++ de nivel jos, trebuiau să înțeleagă hardware-ul specific pentru care dezvoltau, în general un singur dispozitiv, sau o gamă de dispozitive asemănătoare ale aceluiași producător. După cum tehnologia hardware și accesul la internet mobil au evoluat, această abordare restrictivă a devenit depășită. Platforme, precum sistemul Symbian, au fost create pentru a asigura dezvoltatorilor un target hardware mai amplu. Aceste sisteme s-au dovedit a fi de succes, în încurajarea dezvoltatorilor de aplicații pentru mobile, să dezvolte aplicații, care profitau mai mult de hardware-ul disponibil.

Aceste platforme oferă acces la hardware-ul telefonului, dar tot au nevoie ca dezvoltatorul, să scrie cod C/C++ complex și să folosească API-uri proprietare, greu de folosit. Aceste dificultăți sunt amplificate pentru aplicațiile care funcționează pe diverse implementări hardware, în special cele care se folosesc de un anumit modul hardware, cum ar fi GPS-ul. Cel mai notabil progres, în dezvoltarea pe telefoane mobile, a fost introducerea de MID-leți Java. MID-leții sunt executați într-o mașină virtual Java, un proces care nu ține cont de hardware-ul aflat pe telefon și permite dezvoltatorilor să dezvolte aplicații pentru o gamă mai largă de telefoane. Din nefericire, acest lucru creează niște dificultăți în ceea ce privește accesul la hardware-ul dispozitivului.

În dezvoltarea aplicațiilor mobile, era considerat normal, ca aplicațiile terțe să primească acces diferit la hardware și grile de execuție, decât aplicațiile native scrise de către producătorul telefonului. Astfel, MID-leții Java aveau acces restricționat către hardware și către grilele de execuție. Introducerea de MID-leți Java a mărit rândurile dezvoltatorilor, dar lipsa accesului la hardware și execuția într-o mașină virtuală, a însemnat, ca marea majoritate a aplicațiilor mobile, să fie programe desktop normale sau website-uri și care nu se folosesc de avantajele oferite de către un dispozitiv mobil.

Android se situează în noul val de sisteme de operare mobile, create special pentru hardware, aflate in continuă ascensiune. Windows Mobile, Apple iPhone și Palm Pre, asigură un mediu de dezvoltare mai bogat și mai simplu, pentru aplicațiile mobile. Dar, spre deosebire de Android, sunt construite pe sisteme de operare proprietare care, în unele cazuri, prioritizează aplicațiile native în detrimental celor create de terți utilizatori, restricționează transferul de date între aplicații terțe și aplicațiile native ale telefonului și restricționează sau controlează distribuția aplicațiilor către platforme.

Fiecare utilizator – gestionar al unei console (format cel puțin dintr-o tastatură și un monitor) poate deschide sesiuni multiple – prin intermediul unor console virtuale, să lucreze, la un moment de timp dat, sub diferite nume (sau cu același nume, pe terminale virtuale diferite).

Android oferă noi posibilități pentru aplicațiile mobile, deoarece oferă un mediu de dezvoltare deschis, construit peste un kernel Linux open source. Accesul la hardware este disponibil tuturor aplicațiilor, prin intermediul unor librării de API-uri, iar interacțiunea dintre aplicații, deși este controlată cu grijă, este suportată în întregime.

În Android, aplicațiile au un statut egal. Aplicațiile terțe și cele native sunt scrise folosind aceleași API-uri și sunt executate în același mediu de execuție. Utilizatorii pot scoate și înlocui orice aplicație nativă, cu o alternativă oferită de către terți dezvoltatori; chiar și tastatura și ecranul de start pot fi înlocuite.

1.2. Arhitectura sistemului de operare Android

Android este alcătuit din mai multe straturi care comunică între ele. Există cinci straturi principale: Linux Kernel, Libraries, Android Runtime, Application Framework și Applications (Fig.1). Fiecare strat folosește serviciile aduse de stratul de sub el.

Fig.1

Primul strat este Linux Kernel. Android este construit pe o fundație destul de solidă: un kernel de Linux. Acest layer este rezervat sistemului, programatorul și utilizatorul nu vor utiliza direct serviciile sale.

Al doilea strat, Native Libraries, reprezintă bibliotecile native Android. Sunt scrise în C sau în C++ și sunt compilate pentru un anumit hardware. Aici sunt bibliotecile responsabile de gestiunea bazelor de date (SQLite), redarea filmelor (Media Framework) și afișarea fișierelor HTML (WebKit).

Android Runtime conține mașina virtuală Dalvik și bibliotecile Java. Aplicațiile Android rulează pe mașina virtuală Dalvik, programele sunt scrise în Java și compilate în bytecode. Fișierele .class sunt transformate în fișiere executabile Dalvik “.dex”. Toate acestea, pentru că aplicațiile rulează pe un sistem cu memorie destul de limitată și cu o putere de procesare mai mică.

Application Framework este partea cu care lucrează direct programatorul. Aceasta este preinstalată în Android, însă serviciile se pot extinde și se pot crea propriile componente. Cele mai importante componente sunt:

• Activity Manager: controlează ciclul de viață al aplicațiilor și stiva de navigare a utilizatorului;

• Content Providers: conține datele ce sunt împărțite între aplicații (ex: contactele din telefon);

• Location Manager: acces la GPS;

• Notification Manager: alerte trimise utilizatorului că ceva s-a întâmplat în background.

Applications reprezintă ceea ce vede utilizatorul și ceea ce el folosește: aplicațiile și widgeturile.

La baza tuturor aplicațiilor stă un set întreg de servicii și sisteme, printre care:

• un set bogat și extensibil de componente grafice de tip View, cum ar fi: liste, tabele, butoane sau câmpuri de text, cu ajutorul cărora se pot construi interfețe grafice bogate;

• furnizori de conținut (engleză: Content Providers) ce permit aplicațiilor să acceseze date ale altor aplicații (spre exemplu accesarea listei de contacte din aplicația Contacte), precum și publicarea propriilor date spre a fi accesate de către celelalte aplicații;

• un manager de resurse (engleză: Resource Manager) ce facilitează accesul la resurse de tip non-cod, cum ar fi fișiere ce definesc aspectul interfeței grafice sau șiruri de caractere localizate;

• un manager de notificări (engleză: Notification Manager) ce permite tuturor aplicațiilor să afișeze mesaje de atenționare sau de informare în bara de status (engleză: Status Bar), adresate utilizatorului;

• un manager al activităților (engleză: Activity Manager) ce gestionează durata de viață a aplicațiilor și facilitează o stivă de navigare comună.

Platforma Android include un set bogat de biblioteci C/C++, folosite de numeroase componente ale sistemului. Accesul către aceste biblioteci, pentru dezvoltatori, este facilitat de către framework-uri de aplicații.

Dintre bibliotecile de bază putem aminti:

• biblioteca de sistem C – o derivare BSD a bibliotecii standard C (libe), optimizată pentru dispozitivele încorporate bazate pe Linux;

• biblioteci media – bazate pe OpenCORE; aceste biblioteci oferă suport pentru redarea și înregistrarea a numeroase formate audio și video, dintre care putem aminti: MPEG4, H.264, MP3, AAC, AMR, JPG și PNG;

• managerul de suprafețe (engleză: Surface Manager) – gestionează accesul la subansamblele afișajului grafic și facilitează compunerea imaginilor prin suprapunerea de straturi compozite 2D sau 3D provenite din diferite aplicații;

• LibWebCore – pune la dispoziție un motor modem de randare a paginilor web, integrat atât în navigatorul web, cât și în componenta grafică, ce poate fi folosită în cadrul aplicațiilor pentru a afișa pagini web;

• SGL – motorul ce gestionează grafica 2D;

• biblioteci 3D – implementate pe baza API-ului OpenGL ES 1.0; aceste biblioteci utilizează fie accelerarea 3D în hardware, acolo unde aceasta este disponibilă, fie accelerarea 3D efectuată în software puternic optimizată.

• FreeType – folosită pentru a randa fonturi, bazate atât pe grafică vectorială cât și pe grafică de tip raster;

• SQLite – o bază de date flexibilă și puternic optimizată, din punct de vedere al consumului de resurse, disponibilă pentru toate aplicațiile.

Aplicațiile Android sunt scrise în limbajul de programare orientat obiect Java. Uneltele din cadrul SDK-ului Android sunt cele ce compilează codul Java (împreună cu alte fișiere tip resursă necesare) într-un pachet Android. Prin pachet Android înțelegându-se un fișier comprimat, având extensia .apk. Tot ceea ce se află într-un astfel de fișier .apk este considerat ca fiind o aplicație Android, iar acest fișier este cel ce este instalat pe dispozitive, pentru ca acestea să poată rula aplicația respectivă.

Odată instalată pe un terminal mobil, fiecare aplicație Android trăiește în propriul spațiu de memorie virtualizat – conceptul se numește sandboxing: sistemul de operare Android este un sistem multi-utilizator, bazat pe Linux, în care fiecare aplicație este reprezentată de un utilizator unic; în mod implicit, sistemul alocă fiecărei aplicații un identificator de utilizator Linux unic; acest identificator este cunoscut și utilizat doar de către sistemul de operare, nu și de către aplicație în sine; fiecare proces are propria sa mașină virtuală, astfel că, codul fiecărei aplicații este executat în mod izolat față de celelalte aplicații; în mod implicit, fiecare aplicație rulează în cadrul propriului ei proces Linux.

Sistemul de operare pornește acest proces în momentul în care, oricare dintre componentele aplicației trebuie să ruleze. Procesul este oprit în momentul când componenta respectivă își termină ciclul de viață sau, în momentul în care sistemul rămâne fără memorie RAM, în acest fel, sistemul Android implementează principiul celui mai mic privilegiu. Acest principiu forțează ca fiecare aplicație, în mod implicit, să aibă acces doar la componentele necesare funcționării ei corespunzătoare și nimic mai mult. Acest mecanism asigură un mediu sigur, în care o aplicație nu poate accesa părți ale sistemului, pentru care nu a primit permisiuni.

Totuși, pentru a mări gradul de flexibilitate, au fost implementate și mecanisme, prin care o aplicație poate partaja date cu alte aplicații, precum și prin care o aplicație, poate avea acces la serviciile sistemului:

• este posibil, ca două aplicații să poată împărți același identificator de utilizator Linux, în acest fel, cele două aplicații având posibilitatea de a-și accesa fișierele una alteia. Pentru a conserva resursele sistemului, aplicațiile având același identificator de utilizator, pot să ruleze în cadrul aceluiași proces Linux și pot partaja aceeași mașină virtuală. În acest caz însă, este necesar ca aplicațiile să fie semnate cu același certificat digital;

• o aplicație poate cere permisiunea de a accesa date stocate în sistem, precum contactele utilizatorului, mesajele scurte de tip SMS, cardul de memorie SD, camera foto, interfața Bluetooth, precum și multe altele.

Toate cererile de permisiuni ale unei aplicații, trebuie să fie aprobate de utilizator, în momentul în care aceasta este instalată.

1.3. Componentele aplicației Android

Cele mai importante componente ale unei aplicații Android sunt:

Activity (Activitate)

reprezintă o interfață cu utilizatorul, fereastră sau formular;

aplicația Android poate avea una sau mai multe activități; de exemplu, o aplicație de tip Agendă, poate avea o activitate pentru a gestiona contactele, o activitate pentru a gestiona întâlniri și una pentru a edita o intrare în agendă;

fiecare activitate are propriul său ciclu de viață, independent de ciclul de viață al procesului asociat aplicației;

fiecare activitate are propria stare și datele acesteia pot fi salvate sau restaurate;

activitățile pot fi pornite de aplicații diferite (dacă este permis);

are un ciclu de viață complex, deoarece aplicațiile pot avea activități multiple și doar una este în prim-plan; utilizând managerul de activități, sistemul Android gestionează o stivă de activități, care se găsesc în diferite stări (pornire, în execuție, întreruptă, oprită, distrusă);

în SDK, activitatea este implementată folosind o subclasă a clasei Activity, care extinde clasa Context;

Intent (Intenție)

reprezintă o entitate, folosită pentru a descrie o operațiune, care urmează să fie executată; este un mesaj transmis către o altă componentă pentru a anunța o operațiune;

oarecum similar cu conceptul de event-handler din .NET sau Java.;

un mesaj asincron, utilizat pentru a activa activități sau servicii;

gestionată de o instanță a clasei Intent;

Service (Serviciu)

un task care se execută în fundal, fără interacțiunea directă cu utilizatorul;

gestionată de o instanță a clasei Service;

Content provider (Furnizor sau manager de conținut)

un API folosit pentru a gestiona datele private ale aplicației;

un sistem de management de date ce descrie o alternativă la sistemul de fișiere, baze de date SQLite sau orice altă soluție de stocare persistentă;

implementată de o subclasă a clasei ContentProvider;

soluție pentru a partaja și controla (pe bază de permisiuni) transferul de date între aplicații (de exemplu, sistemul Android oferă un furnizor de conținut pentru datele de contact);

Broadcast receiver

componentă care răspunde la anunțuri difuzate (propagate) la nivel de sistem;

oarecum similar cu conceptul de handler global (sau evenimente de sistem);

implementată de o subclasă a clasei BroadcastReceiver .

1.4. Ciclul de viață al unei Activități

Activitatea este una dintre cele mai importante componente (alături de servicii și broadcast receivers) ale unei aplicații Android, deoarece este strâns legată de interfața cu utilizatorul. O activitate este utilizată pentru a gestiona interfața cu utilizatorul și este echivalentă cu fereastra sau formularul din aplicațiile desktop.

Înțelegerea modului în care se controlează activitatea vă permite să:

utilizați ciclul de viață al activității pentru a crea, vizualiza, utiliza și a opri activitățile;

salvați datele utilizatorului, înainte ca activitatea să fie oprită și să le restaurați atunci când activitatea este readusă în prim-plan;

creați aplicații cu mai multe formulare sau activități;

Ciclul de viață al unei Activități descrie starea în care o activitate poate fi la un moment dat (denumirile sunt lăsate intenționat în Engleză, deoarece fac parte din vocabularul programatorului):

Running – Activitatea a fost creată (onCreate()), pornită (onStart()) și este afișată pe ecranul aparatului; în cazul în care activitatea a mai fost utilizată și aplicația a salvat starea acesteia (onSaveInstanceState()), activitatea este reluată din acel punct (onRestoreInstanceState() și onResume()); în această stare utilizatorul interacționează cu activitatea prin intermediul interfeței dispozitivului (tastatură, touchscreen, display);

Paused – Activitatea pierde prim-planul (onPause()), deoarece o altă activitate este executată, cum ar fi o fereastră de dialog; de asemenea, în cazul în care aparatul intră în modul sleep, activitatea este oprită temporar; activitatea își poate relua execuția (onResume()) și este plasată înapoi în prim-plan;

Stopped – Activitatea nu mai este în uz și pentru că este oprită (onStop()) nu este vizibilă; pentru a fi reactivată (ea deja există), activitatea trebuie să fie repornită (onRestart() și onStart()) și reluată (onResume());

Destroyed – Activitatea este distrusă (onDestroy()) și memoria sa eliberată, deoarece nu mai este necesară sau sistemul are nevoie de memorie suplimentară pentru rutinele proprii sau pentru alte activități; deoarece managementul memoriei este un aspect important pentru sistemul de operare Linux al dispozitivului mobil, procesul care găzduiește o activitate întreruptă, oprită sau distrusă, poate fi terminat, pentru a elibera memoria pentru noi activități; doar procesele ce gestionează activități ce rulează sunt protejate;

Diagrama ciclului de viață pentru o activitate Android (Fig. 2) :

Fig. 2

După cum se poate observa în imaginea anterioară, Activitatea are mai multe stări, între care există tranziții clare. În ciuda faptului că lucrurile pot arata complicat, în realitate ele sunt mult mai simple, dacă ne concentrăm pe următoarele elemente:

singură Activitatea poate fi în prim-plan la un moment dat;

doar sistemul gestionează stările și tranzițiile unei Activități și NU programatorul (nu în mod direct, deoarece atunci când se lansează o activitate nouă se modifică, implicit, starea activității curente);

IMPORTANT ! Sistemul va anunța, atunci când activitatea își schimbă starea, prin intermediul handler-elor (metode de formă onXXX()), pentru evenimentele de tip tranziție; ca programator, puteți adăuga propriul cod prin supradefinirea acestor metode:

onCreate(Bundle) – apelată când activitatea este creată; folosind argumentul metodei de tip Bundle, există posibilitatea să restabiliți starea activității, care a fost salvată într-o sesiune anterioară;

onStart() – apelată în cazul în care activitatea urmează să fie afișată; din acest punct, activitatea poate veni în prim-plan (onResume()) sau rămâne ascunsă în fundal (onStop());

onRestoreInstanceState(Bundle) – apelată în cazul în care activitatea este inițializată, cu datele dintr-o stare anterioară, ce a fost salvată; în mod implicit, sistemul restaurează starea interfeței cu utilizatorul (starea controalelor vizuale, poziția cursorului, etc);

onResume() – apelată când activitatea este vizibilă, iar utilizatorul poate interacționa cu aceasta; din această stare, activitatea poate fi plasată în fundal, devenind întreruptă (onPause());

onRestart() – apelată în cazul în care activitatea revine în prim-plan dintr-o stare oprită (stopped); după aceasta, activitatea este pornită (onStart()) din nou;

onPause() – apelată atunci când sistemul aduce în prim-plan o altă activitate; activitatea curentă este mutată în fundal și mai târziu poate fi oprită (onStop()) sau repornită și afișată (onResume()); acesta este un moment bun pentru a salva datele aplicației într-un mediu de stocare persistent (fișiere, baze de date), deoarece după această fază, activitatea poate fi terminată și distrusă, fără a se anunța acest lucru.

onSaveInstanceState(Bundle) – apelată pentru a salva starea curentă a activității; în mod implicit, sistemul salvează starea interfeței cu utilizatorul;

onStop() – apelată, în cazul în care activitatea nu mai este utilizată și nu mai este vizibilă, deoarece o altă activitate interacționează cu utilizatorul; din acest punct, activitatea poate fi repornită (onRestart()) sau distrusă (onDestroy());

onDestroy() – apelată, în cazul în care activitatea este distrusă, iar memoria sa eliberată; acest lucru, se poate întâmpla, în cazul în care sistemul necesită mai multă memorie sau, dacă programatorul termină explicit activitatea, apelând metoda finish() din clasa Activity; .

2. Definirea și implementarea realității virtuale în aplicații android

2.1. Definirea conceptului de realitate virtuală

Realitatea virtuală este termenul utilizat pentru a descrie un mediu tridimensional, generat de calculator, care poate fi explorat de către o persoană. Acea persoană devine parte a acestei lumi virtuale și este capabilă de a manipula obiecte sau de a efectua o serie de acțiuni.

Noi cunoaștem lumea prin intermediul simțurile noastre și mecanismelor de percepție. În școală, am învățat cu toții, că avem cinci simțuri: gust, simț tactil (pipăit), miros, vedere (văz) și auz. Acestea sunt însă, doar cele mai importante percepții senzoriale. Adevărul este că, oamenii au mai multe simțuri decât acestea, cum ar fi simțul echilibrului, de exemplu. Aceste alte intrări senzoriale, plus unele speciale, de prelucrare a informațiilor senzoriale de către creierul nostru, ne asigură că avem un flux bogat de informații în mințile noastre.

O mare parte din cunoașterea realității noastre vine prin intermediul simțurilor noastre. Cu alte cuvinte, întreaga noastră experiență a realității, este pur și simplu o combinație de informații senzoriale și capacitatea creierului nostru de a atribui un sens acestor informații. Este de la sine înțeles că, dacă simțurile vor fi excitate de stimuli artificiali, atunci percepția asupra realității se va modifica în acord cu aceștia. Ți s-ar prezenta o versiune a realității, care nu este cu adevărat acolo, dar din perspectiva ta, ar fi percepută ca fiind reală și prezentă. Așa că, în rezumat, realitatea virtuală presupune excitarea simțurilor noastre, cu un mediu virtual, generat de calculator, pe care o putem explora într-un fel.

Mediile virtuale au numeroase funcționalități, printre care se numără: oferirea unor experiențe imersive utilizatorului, designul unor noi concepte sau produse, explorarea și analiza datelor într-o manieră intuitivă, antrenarea utilizatorilor pentru sarcini complexe și potențial periculoase, într-un mediu sigur și eficient, divertisment.

2.2. Istoricul realității virtuale

În această istorie detaliată, a realității virtuale, ne uităm la modul în care tehnologia a evoluat și modul în care pionierii cheie, au pavat calea pentru realitatea virtuală, așa cum o știm astăzi.

Dacă ne concentrăm, mai strict, asupra domeniului de aplicare al realității virtuale, ca la un mijloc de a crea iluzia că suntem prezenți undeva unde nu suntem de fapt, atunci cea mai veche încercare de realitate virtuală sunt, cu siguranță, picturile murale reprezentate în 360 ​​de grade (sau picturi panoramice) din secolul al XIX-lea (Fig. 3). Aceste picturi au fost destinate să umple întregul câmp vizual al privitorului, ceea ce îl face să se simtă prezent la un eveniment istoric sau la o scenă istorică.

Fig. 3

În 1930, o poveste a scriitorului science fiction, Stanley G. Weinbaum, (Pygmalion Spectacles) (Fig. 4), conține ideea unei perechi de ochelari, care permit purtătorului, să experimenteze o lume fictivă prin holografie, miros, gust și atingere.

Fig. 4

La mijlocul anilor 1950, cineastul Morton Heilig a dezvoltat Sensorama (Fig. 5) (patentat 1962), care a fost un cabinet de teatru, stil arcade, care ar stimula toate simțurile, nu doar vederea și auzul. Acesta conținea difuzoare stereo, un ecran 3D stereoscopic, ventilatoare, generatoare de miros și un scaun vibrator. Sensorama a fost destinat să dea impresia individului, că simte, în realitate, senzațiile din filmul respectiv. El a creat, de asemenea, șase scurtmetraje pentru invenția sa.

Fig. 5

În anul 1968, Ivan Sutherland și studentul Bob Sproull, au creat primul dispozitiv VR / AR (Sabia lui Damocles), care a fost conectat la un calculator. Acest dispozitiv a fost mare și înfricoșător, fiind prea greu pentru a fi purtat pe cap, confortabil, de către utilizator și a fost suspendat de tavan (de unde și numele). Utilizatorul ar trebui să fie legat în acest dispozitiv. Grafica pe calculator, era de tip wireframe și a fost generată de camere foarte primitive.

Chiar și după toată această dezvoltare în realitatea virtuală, încă nu a fost găsit un termen atotcuprinzător pentru a descrie câmpul. Acest lucru s-a schimbat, cu totul, în anul 1987, când Jaron Lanier, fondator al laboratorului de programare vizuală (VPL), a inventat (sau, după unii, popularizat) termenul "realitate virtuală". Aria de cercetare a avut, acum, un nume. Prin cercetările sale de companie, VPL Jaron a dezvoltat o gamă de unelte de realitate virtuală (Fig. 6), inclusiv Dataglove (împreună cu Tom Zimmerman) și afișajul de montat pe cap EyePhone. Ei au fost prima companie, care a vândut ochelari de realitate virtuală (EyePhone 1 $ 9.400; EyePhone HRX $ 49.000) și mănuși ($ 9.000).

Fig. 6

La începutul anilor ’90, au început să apară dispozitive de realitate virtuală, la care publicul larg a avut acces, cum ar fi, setul cu cască Sega VR, pentru consolă Sega Genesis sau Nintendo Virtual Boy. Deși prețul nu a fost unul mare ($ 200), ambele au fost sortite eșecului, datorită lipsei de suport software și de culoare în grafică (jocurile au fost în roșu și negru) (Fig. 7).

Fig. 7

În anul 1999, filmul fraților Wachowski, “The Matrix”, ajunge pe marile ecrane. Filmul prezintă personaje care trăiesc într-o lume complet simulată, mulți fiind complet conștienți că ei nu trăiesc în lumea reală, cu toate că, unele filme anterioare au cochetat, ilustrând realitatea virtuală, cum ar fi “Tron”, în 1982. Dar, “The Matrix” are un impact cultural major și a adus subiectul realității simulate, în cotidian.

În primii cinci ani ai secolului 21, realitatea virtuală a avut o creștere rapidă, în mare parte datorită progresului în industria tehnologiilor mobile, dar și prețurilor acestora, care sunt, în mod constant, împinse în jos. Creșterea numărului de smartphone-uri, cu ecrane de înaltă densitate și capacități grafice 3D, au permis o generație de dispozitive ușoare și practice realității virtuale.

Recent, companii precum Google au lansat produse intermediare, de realitate virtuală, cum ar fi Google carton, un set cu cască DIY, care utilizează un smartphone. Companii, precum Samsung, au preluat acest concept și l-au integrat cu alte produse, cum ar fi Galaxy Gear, care este produs în masă și conține caracteristici "inteligente", cum ar fi controlul prin gesturi.

Se pare că, 2016 va fi un an-cheie în industria de realitate virtuală. Mai multe dispozitive de consum par să răspundă, în cele din urmă, la promisiunile neonorate făcute de realitatea virtuală în 1990 și care, acum au intrat deja, pe piață. Acestea includ Oculus Rift (Fig. 8), care a fost achiziționată de gigantul social media Facebook, în 2014, pentru suma de $ 2 miliarde. Un vot incredibil de încredere, primit de industria realității virtuale, deși, la momentul lansării în 2016, Oculus Rift va fi în competiție cu produse de la Valve Corporation și HTC, Microsoft, precum și Sony Computer Entertainment.

Fig. 8

2.3. Implementarea realității virtuale cu google cardboard

Google Cardboard este o platformă (VR) de realitate virtuală, dezvoltată de Google, pentru a fi utilizat ca dispozitiv de montat pe cap, cu smartphone pe post de ecran. Platforma este concepută ca un sistem de low-cost, pentru a încuraja interesul și dezvoltarea în aplicații VR.

Utilizatorii pot construi propriul lor dispozitiv vizualizator, din componente simple, ieftine și accesibile, folosind specificații publicate de Google sau, pot achiziționa unul pre-fabricat. Dispozitivul vizualizator este utilizat, prin plasarea unui smartphone în partea din spate a acestuia, pentru a vizualiza conținutul dorit de realitate virtuală, prin lentilele din față.

Platforma a fost creată de David Coz și Damien Henry, ingineri Google de la Google Cultural Institute din Paris, în acel 20% timp destinat inovării. A fost introdusă la Google I / O 2014 Developers Conference, când au oferit participanților un dispozitiv de vizualizare din carton. Kit-ul de dezvoltare software (SDK) Cardboard este disponibil pentru Android și iOS; SDK VR View permite dezvoltatorilor de a încorpora conținutul VR pe web, precum și în aplicațiile lor mobile. Se estimează că, începând cu ianuarie 2016, peste cinci milioane de telespectatori dețin un dispozitiv din carton și peste 1.000 de aplicații compatibile au fost publicate.

Specificațiile setului cu cască au fost proiectate de către Google, care a făcut lista de piese, scheme și instrucțiuni de montaj, disponibile gratuit pe site-ul lor, permițând oamenilor să-și asambleze singuri Cardboard-ul, din piese ușor disponibile. Desigur, poate fi achiziționat de la diverși producători, începând cu prețul de $ 5 și urcând spre $ 30, pentru variante îmbunătățite.

Piesele care alcătuiesc un vizualizator de carton (Fig. 9) sunt: o bucată de carton tăiat într-o formă precisă (1), lentile cu distanță focală de 45 mm (2), magneți (3), bandă arici (de tip Velcro) (4), o bandă de cauciuc (5), precum și un opțional tag NFC (6).

Fig. 9

După ce setul este asamblat (Fig. 10), un smartphone este introdus în partea din spate a aparatului și fixat cu bandă arici. O aplicație Google Cardboard compatibilă, împarte imaginea afișată pe smartphone în două, câte una pentru fiecare ochi, în timp ce se aplică, imaginea este denaturată, pentru a contracara denaturarea cauzată de lentile. Rezultatul este unul stereoscopic ("3D"), formând o imagine cu un câmp larg de vedere (Fig. 11).

Fig. 10

Fig. 11

Google pune la dispoziție trei kit-uri de dezvoltare software pentru dezvoltarea de aplicații Cardboard: unul pentru Android, sistemul de operare folosind Java, unul pentru motorul grafic de joc Unity, folosind C# și unul pentru iOS.

În plus, față de aplicațiile native din Cardboard, există Experimente Google Chrome VR implementate, folosind WebGL. Telefoanele, inclusiv Apple, care suportă WebGL, pot rula experimente web Google .

În ianuarie 2016, Google a anunțat că, kiturile de dezvoltare de software oferă suport audio spațial, un efect de realitate virtuală, destinat să simuleze sunete care provin din afara dispozitivului de vizualizare, definind mai bine spațiul 3D.

În martie 2016, Google a lansat VR View, o extindere a SDK – Cardboard, care permite dezvoltatorilor de a încorpora conținutul VR 360 de grade, pe o pagină web sau într-o aplicație mobilă, pe desktop, Android și iOS. Codul Javascript și HTML pentru conținutul web de publicare VR este open source și disponibil pe GitHub, permițând dezvoltatorilor să auto-găzduiască conținutul lor.

La conferința din 18 mai 2016, Google a anunțat o nouă platformă pentru VR, numită Daydream (Fig. 12), care va fi lansată undeva prin toamnă, spre deosebire de google cardboard, care avea ca scop, să facă cât mai cunoscut mediul de realitate virtual, printr-un dispozitiv cât mai accesibil publicului larg.

Dispozitivul Daydream (Fig. 13) își propune să cucerească segmentul de mijloc al pieței VR și vine cu un design nou pentru dispozitivele de montat pe cap, cu un controller și o platformă nouă, superioară calitativ platformei Cardboard. Momentan, este speculat că Google dorește, prin această platformă, să ajungă la un acord cu cât mai mulți producători de smartphone-uri, privind specificațiile tehnice necesare ce trebuiesc implementate, cum ar fi o latență a afișării pe ecran de doar 20 ms, probabil un ecran cu o densitate mare de pixeli si cu o putere de procesare grafică marită. Noul sistem de operare android N vine optimizat, pentru platformele de realitate virtuală.

Fig. 12

Fig. 13

2.4. Dispozitive pe piață

2.5. Motorul grafic Unity

Unity este un motor grafic multi-platformă dezvoltat de Unity Technolgies și este folosit pentru a dezvolta jocuri video pentru PC, console, dispozitive mobile și site-uri web.

Cu un puternic accent pe portabilitate, motorul grafic vizează următoarele interfețe pentru programarea de aplicații (API-uri) Direct3D pe Windows și Xbox 360, OpenGL pe Mac și Windows, OpenGL ES pe Android și iOS; și API-uri proprietare de pe console de jocuri video.

Unity permite specificarea setărilor de compresie a texturii și rezoluția pentru fiecare platformă motor de joc acceptată; oferă suport pentru ecran de ocluzie spațiu ambiental (SSAO), umbre dinamice, folosind hărți umbră, randare la texturare și efecte de post-procesare pentru întregul ecran.

Motorul grafic Unity poate oferi un shader cu mai multe variante, ce permit detecția variantei cele mai bună pentru hardware-ul video curent; și în cazul în care nici unul nu este compatibil, revin înapoi la un shader alternativ, care poate sacrifica din caracteristici pentru performanță.

Unity este notabil pentru capacitatea sa de a viza jocuri pentru mai multe platforme. În cadrul unui proiect, dezvoltatorii au un control asupra livrării către dispozitive mobile, browsere web, desktop-uri și console.

Platformele acceptate includ Android, Apple TV, BlackBerry 10, iOS, Linux, Nintendo 3DS, OS X, Playstation 3, Playstation 4, Playstation Vita, Unity Web player, Wii, Wii U, Windows Phone 8, pentru Windows, Xbox 360 și Xbox One.

3. Proiectarea generală a aplicației

3.1. Tema aplicației

Obiectivul principal al temei de licență este constituit de dezvoltarea și elaborarea unui simulator de zbor într-un mediu cosmic, prin explorarea tehnologiilor și tehnicilor specifice mediilor realității virtuale, în scopul construirii jocului Flyer (Fig. 14), ce își are inspirația în cunoscutul Asteroids (Asteroizi), realizat de Atari, Inc. în 1979 (Fig. 15). Pentru îndeplinirea acestui obiectiv urmăresc studiul, conceperea, dezvoltarea, implementarea și calibrarea unui simulator de zbor în mediul realității virtuale.

Fig. 14

Fig. 15

Realitatea virtuală este un termen folosit tot mai des în ultimii ani, după boom-ul înregistrat în cercetare, la începutul anilor ‘90. Inițial, percepută ca o lume creată ca alternativă la lumea reală, aceasta nu mai constituie, în prezent, un subiect desprins din literatura SF. Mediile virtuale reprezintă o colecție de tehnologii care permit utilizatorilor să interacționeze eficient, în timp real, cu module 3D generate de calculator, folosind simțurile și abilitățile lor naturale.

Asteroizi este un shooter spațial arcade, lansat în noiembrie 1979 de către Atari, Inc. și proiectat de Lyle Rains, Ed Logg și Dominic Walsh. Jucătorul controlează o navă spațială într-un domeniu de asteroizi, care este traversat periodic de farfurii zburătoare. Obiectivul jocului este de a trage și de a distruge asteroizi și farfurioare, în timp ce trebuie să eviți a fi ciocnit. Jocul devine mai greu, pe măsură ce numărul de asteroizi crește.

În mod similar jocului Asteroizi, Flyer te transpune prin realitatea virtuală, în rolul pilotului de navă, într-un câmp de asteroizi ce trebuiesc distruși sau evitați, obiectivul final fiind acela de a înregistra un scor cât mai mare, într-un timp limitat.

3.2. Trăsăturile jocului

nu permite mai mulți utilizatori simultan;

conține o navă care se deplaseză în spațiu și trage cu laser;

asteroizii, cercurile, apar aleatoriu, în spațiul jocului;

sistem de scor, prin distrugerea asteroizilor și trecerea prin cercuri, într-un timp limitat;

afișaj permanent, cu: viața navei, timp rămas și scor;

meniu de început;

ecran de final de joc, cu scor;

fundal spațial generat la infinit, cu apariția de particule, în mod aleatoriu;

sistem de gestiune a coliziunilor între actori (asteroizi, navă, cercuri, proiectile);

transformări și animații ale actorilor;

sistem de reutilizare a obiectelor.

4. Prezentarea aplicației propriu-zise

4.1. Prezentarea aplicației

Aplicația Flyer este un joc de tip simulator / shooter spațial, implementat prin tehnici de realitate virtuală (Fig. 16). Obiectivul este de a supraviețui și atinge un scor cât mai mare într-un timp limitat. Acesta se atinge, prin distrugerea sau evitarea coliziunii cu asteroizii, care sunt generați aleatoriu, dar și prin pătrunderea cu nava în cercuri care, de asemenea, apar aleatoriu. Controlul navei este foarte intuitiv și se face prin mișcarea capului, în direcția în care se dorește deplasarea.

Fig. 16

Cerințele minime pentru utilizarea aplicației sunt: un smartphone cu Android (versiunea minimă 4.1 Jelly Bean) și dispozitivul google cardboard.

Pentru o experiență cât mai plăcută, recomand un smartphone cu un ecran de minim 5 inch și o densitate cât mai mare de pixeli, dispozitivul google cardboard și o pereche de căști.

4.2. Elementele componente utilizate

Aplicația Flyer a fost realizată în motorul grafic Unity v5.3, folosind Cardboard SDK for Unity v.0.7.2 și Android SDK. Componetele grafice și resursele jocului au fost descărcate din Unity Assets Store, ele sunt oferite gratuit ca mostre, pentru dezvoltarea pe platformele de realitate virtuale Oculus DK2 și GearVR.

Jocul Flyer a fost asamblat în versiunea Unity v5.3, pe sistemul de operare MacOSX și testat cu succes pe smartphone-ul Samsuns Galaxy S6, cu sistemul de operare Android 6.0.1.

4.3. Jocuri similare

Galaxy VR Cardboard Space FPS (Fig. 17) este un simulator spațial, implementat prin realitatea virtuală, care te așează în scaunul unei nave mici, de luptă. Jocul este compatibil cu majoritatea dispozitivelor de tip Google Cardboard, fără magnet și necesită un dispozitiv periferic sau o tastatură conectată prin Bluetooth sau USB, pentru a controla nava. În absența acestora, vă puteți bucura doar de un demo. Camera din joc poate fi mișcată, prin utilizarea giroscopului și busolei telefonului, într-un mod similar mișcării camerei și a direcției de zbor din aplicația Flyer.

Aplicația, pe lângă necesitatea conectării unui dispozitiv periferic de tip joystick, gamepad, în scopul obținerii datelor de intrare, necesare realizării deplasării, aduce, în plus, multiple moduri ale perspectivei camerei, un avatar al jucătorului, care îți imită mișcările la bordul navei, un meniu implementat chiar din interiorul navei.

Fig. 17

Deep Space Battle VR (Fig. 18) intră în aceeași categorie de simulator / shooter spațial, destinat tot dispozitivelor de tip cardboard. Tema jocului este de a distruge cât mai multe nave inamice, aparținând unui flote invadatoare.

Jocul, aduce în plus, posibilitatea alegerii de nave diferite dintr-o listă de șase, fiecare cu caracteristici diferite, cât și mai multe nivele, ce cresc, gradual, dificultatea duelurilor aeriene. Deplasarea și interacțiunea este foarte similară cu cea din jocul Flyer, adică, direcția de zbor a navei este ghidată de reticulul din centrul ecranului, prin mișcarea capului, dar cu o singură deosebire, privind modul în care se trage cu proiectile, fiind implementat un mod automat, odată ce nava inamică este în țintă, nemaifiind acționate de utilizator.

Fig. 18

4.4. Manual utilizare

Aplicația Flyer, momentan, este pur conceptuală și nu a fost distribuită pe platforma Google Play. Pentru a o instala pe un smartphone, trebuie să urmați pașii de mai jos.

Primul pas, este activarea modului de dezvoltator. Acesta se face, de regulă, prin accesarea setărilor din meniu, apoi se navighează la categoria <Despre Telefon> și se apasă de șapte ori pe categoria <Versiune>. După primele două apăsări consecutive, apare un dialog care contorizează pașii rămăși pentru a deveni un dezvoltator. Recomand și căutarea unui ghid mai specific, în funcție de versiunea de android și telefon, deoarece există posibilitatea unor diferențe în etapele descrise mai sus.

Odată ce telefonul este setat în modul de dezvoltator, pot fi instalate și aplicații care nu au fost verificate, în prealabil, de Google Play. Aplicația poate fi adăugată pe telefon, prin cablu de date, card de memorie, descărcată prin wi-fi, etc.

După instalarea aplicației, poate fi deschisă ca o aplicație normală sau lansată din aplicația Google Cardbord, aceasta fiind, automat, recunoscută ca aplicație pentru realitatea virtuală.

Telefonul trebuie introdus în dispozitivul de tip Google Cardboard și așezat pe cap. Prima scenă de intro, conține o căsuță de text (Fig. 19), cu informații legate de controlul navei și al modului în care se face interacțiunea, dar si butonul de start.

Fig. 19

După cum explică și scena de intro, navigarea se face prin mișcarea capului în direcția dorită și apăsarea butonului, fizic, de pe dispozitivul în care a fost montat telefonul.

A doua scenă (Fig. 20) este desfășurarea jocului, a fost setat cu o durată de 120 secunde, controlul navei se face tot prin mișcarea capului și acționarea proiectilelor laser se face prin apasarea butonului, fizic.

Fig. 20

Scena de final (Fig. 21) prezintă scorul maxim, scorul curent și oferă posibilitatea reluării jocului prin apăsarea butonului.

Fig. 21

4.5. Testarea si impresii

Jocul a fost testat pe telefonul mobil Samsung S6, dotat cu platforma Android 6.0.1, având un ecran de 5,1 inch, cu o rezoluție de 1.440 x 2.560 pixels și o densitate de 557 ppi, un procesor grafic Mali-T760MP8 și procesorul octa-core Exynos 7420 și 3 GB RAM.

Aplicația Flyer, instalată pe telefon, ocupă 43,3 MB. În timpul execuției nu am sesizat o reducere perceptibilă a numărului de cadre pe secundă și nici o epuizare dramatică a bateriei, dar față de majoritatea jocurilor 3D, implementarea în realitatea virtuală este, momentan, pretabilă telefoanelor din gama superioară, ca performanțe.

Unity oferă posibilitatea întocmirii unui raport, din fereastra Profiler, cu date legate de performanță, pe baza căruia se poate optimiza aplicația în zone diferite, cum ar fi timpul de randare, animațiile sau chiar, logica jocului.

Raportul generat (Fig. 22), referitor la gradul de încărcare al memorie RAM, arată un total de 241 MB, dintre care 53,6 MB sunt consumați de utilitarul Profiler, care generează raportul.

Fig. 22

Procentul mediu de încărcare al procesorului a fost în jurul valorii de 35%, după cum arată și graficul de mai jos (Fig. 23).

Fig. 23

5. Funcționarea aplicației

5.1. Structura aplicației

Cu cât aplicația devine din ce în ce mai mare, este foarte important să avem o structură logică a tuturor activelor jocului. Dacă scripturile, elementele grafice sunt bine structurate, e mult mai ușor, pentru noi, să le găsim și să le reutilizăm.

Fereastra Hierarchy include toate componentele jocului din scena curentă, ordonate după structura părinte-copil și este alcătuită din:

Vehicles (Fig. 24) include componentele grafice: animații, texturi;

System (Fig. 25) include scripturile care gestionează comportamentul jocului;

Camera (Fig. 26) include camera și scripturi destinate interacțiunii și navigării;

GUI (Fig. 27) include meniul și interfața utilizatorului;

Audio (Fig. 28) include componentele audio;

Fig. 24

Fig. 25

Fig. 26

Fig. 27

Fig. 28

5.2. Interacțiunea în VR

În mediul VR trebuie, constant, să putem interacționa cu obiectul privit de utilizator; pentru asta este nevoie de trei scripturi principale: VREyeRaycaster, VRInteractiveItem și VRInput.

Felul în care se determină unde privește utilizatorul, într-un mediu VR este foarte important, deoarece acestu lucru permite interacțiunea lui cu mediul (obiectele), fie că declanșăm o animație a obiectului sau lansăm un proiectil către o țintă.

Multe dispozitive cu ecran, ce pot fi atașate pe cap (HDM), nu suportă urmărirea ochilor utilizatorului și este necesară aproximarea punctului în care privește utilizatorul. Soluția pentru această problemă este una relativ simplă, deoarece utilizatorul aproape mereu privește în față, drept, din cauza distorsiunii lentilelor.

Abordarea este de a trimite în față o rază, în centrul camerei și de a detecta, dacă aceasta a ciocnit un obiect, cu zona de coliziune atașată sau nu.

Scriptul VREyeRaycaster trebuie amplasat pe camera principală, el are scopul de a trimite o rază în față, pentru a detecta, dacă se ciocnește de ceva, în calea sa. La fiecare apel al scriptului este trimisă o rază, folosind clasa Physics.Raycast, acesta poate fi setat să execute anumite layere, dacă este nevoie, dar se poate și folosi într-un singur layer, dacă se dorește mutarea tuturor obiectelor acolo, prin acest lucru se poate aduce o îmbunătățire de performanță.

Dacă raza a detectat o zonă de coliziune, atunci se încearcă găsirea componentei VRInteractiveItem pe obiectul țintit.

VRInteractiveItem interactible = hit.collider.GetComponent<VRInteractiveItem>();

//attempt to get the VRInteractiveItem on the hit object

m_CurrentInteractible = interactible;

În acest fel se determină dacă utilizatorul are în țintă un obiect (se uită la el sau nu) și putem folosi o metodă.

VRInput este o clasă simplă care interpretează datele de intrare oferite de utilizator.

public enum SwipeDirection

{

NONE,

UP,

DOWN,

LEFT,

RIGHT

};

public event Action<SwipeDirection> OnSwipe; // Called

every frame passing in the swipe, including if there is no swipe.

public event Action OnClick; // Called

when Fire1 is released and it's not a double click.

public event Action OnDown; // Called

when Fire1 is pressed.

public event Action OnUp; // Called

when Fire1 is released.

public event Action OnDoubleClick; // Called

when a double click is detected.

public event Action OnCancel; // Called

when Cancel is pressed.

VRInteractiveItem este o componentă care trebuie adăugată pe toate obiectele, cu care se dorește interacțiunea, de către utilizator.

public class VRInteractiveItem : MonoBehaviour

{

public event Action OnOver; // Called when the gaze moves

over this object

public event Action OnOut; // Called when the gaze leaves

this object

public event Action OnClick; // Called when click input is

detected whilst the gaze is over this object.

public event Action OnDoubleClick; // Called when double click

input is detected whilst the gaze is over this object.

public event Action OnUp; // Called when Fire1 is released

whilst the gaze is over this object.

public event Action OnDown; // Called when Fire1 is pressed

whilst the gaze is over this object.

private EventTrigger myTrigger;

protected bool m_IsOver;

public bool IsOver

{

get { return m_IsOver; } // Is the gaze currently over

this object?

}

Sunt șase evenimente la care scriptul reacționează și o booleană care verifică dacă utilizatorul are în țintă (reticul) obiectul.

Pentru a determina centrul de privire al utilizatorului se folosește un reticul, acesta poate fi de forma unui punct, cerc sau cruciuliță.

În mediile 3D tradiționale, acest reticul este poziționat în centrul ecranului, într-un punct fix, de cele mai multe ori. Spre deosebire de mediile tradiționale 3D, poziționarea acestuia într-un mediu de realitate virtuală, este de natură mult mai complexă, ce necesită o abordare diferită, deoarece atunci când utilizatorul privește în mediul VR, privirea converge asupra obiectelor apropiate de cameră și dacă reticulul ar fi într-un loc fix, acesta ar fi văzut dublu de către utilizator.

Acest fenoment este cunoscut ca diplopie și poate fi ușor simulat, prin așezarea unui deget în fața nasului, la o distanță destul de mică de ochi, dar variabilă de la om la om. Dacă punctul de privire este fixat în fundal, imaginea degetului apare dublată și dacă privim degetul, imaginea din fundal apare ușor dublată și neclară.

Pentru a evita această dublare a reticulului, atunci când privirea utilizatorului este focalizată la distanțe variabile, acesta trebuie poziționat în spațiul 3D, în același loc în care se află obiectele la care utilizatorul se uită în acel moment, dar și de a ține cont de distanța obiectelor față de cameră, pentru a putea menține o dimensiune constantă a acestuia.

Ca interacțiune, aplicația are o abordare simplă, utilizatorul pilotează nava prin simpla mișcare a capului, pentru a schimba punctul privit.

Schimarea poziției navei este dată de mișcarea de rotire a capului utilizatorului, în scriptul FlyerMovementController.cs

private IEnumerator MoveFlyer ()

{

while (m_IsGameRunning)

{

// Set the target marker position to a point forward of the

camera multiplied by the distance from the camera.

//Quaternion headRotation = InputTracking.GetLocalRotation

(VRNode.Head);

// *** CARDBOARD TRACKING ***

Quaternion headRotation = Camera.main.transform.parent.rotation;

m_TargetMarker.position = m_Camera.position + (headRotation *

Vector3.forward) * m_DistanceFromCamera;

// Move the camera container forward.

m_CameraContainer.Translate (Vector3.forward * Time.deltaTime *

m_Speed);

// Move the flyer towards the target marker.

m_Flyer.position = Vector3.Lerp(m_Flyer.position,

m_TargetMarker.position,

m_Damping * (1f – Mathf.Exp (k_ExpDampingCoef *

Time.deltaTime)));

// Calculate the vector from the target marker to the flyer.

Vector3 dist = m_Flyer.position – m_TargetMarker.position;

// Base the target markers pitch (x rotation) on the distance in

the y axis and it's roll (z rotation) on the distance in the x axis.

m_TargetMarker.eulerAngles = new Vector3 (dist.y, 0f, dist.x) *

k_BankingCoef;

// Make the flyer bank towards the marker.

m_Flyer.rotation = Quaternion.Lerp(m_Flyer.rotation,

m_TargetMarker.rotation,

m_Damping * (1f – Mathf.Exp (k_ExpDampingCoef *

Time.deltaTime)));

// Update the score text.

m_CurrentScore.text = "Score: " + SessionData.Score;

// Wait until next frame.

yield return null;

}

}

Pentru a distruge asteroizii este folosit laserul, controlat de scriptul FlyerLaserController.cs, care răspunde la evenimentul OnDown din VRinput.cs:

using UnityEngine;

using VRStandardAssets.Utils;

namespace VRStandardAssets.Flyer

{

// This script handles getting the laser instances from

// the object pool and firing them.

public class FlyerLaserController : MonoBehaviour

{

[SerializeField] private VRInput m_VRInput; //

Reference to the VRInput so when the fire button is pressed it can be handled.

[SerializeField] private FlyerGameController m_GameController; //

Reference to the game controller so firing can be limited to when the game is

running.

[SerializeField] private ObjectPool m_LaserObjectPool; //

Reference to the object pool the lasers belong to.

[SerializeField] private Transform m_LaserSpawnPosLeft; // The

positions the lasers should spawn from.

[SerializeField] private Transform m_LaserSpawnPosRight;

[SerializeField] private AudioSource m_LaserAudio; // The

audio source that should play firing sounds.

private void OnEnable()

{

m_VRInput.OnDown += HandleDown;

}

private void OnDisable()

{

m_VRInput.OnDown -= HandleDown;

}

private void HandleDown()

{

// If the game isn't running return.

if (!m_GameController.IsGameRunning)

return;

// Fire laser from each position.

SpawnLaser(m_LaserSpawnPosLeft);

SpawnLaser(m_LaserSpawnPosRight);

}

private void SpawnLaser(Transform gunPos)

{

// Get a laser from the pool.

GameObject laserGameObject =

m_LaserObjectPool.GetGameObjectFromPool();

// Set it's position and rotation based on the gun positon.

laserGameObject.transform.position = gunPos.position;

laserGameObject.transform.rotation = gunPos.rotation;

// Find the FlyerLaser component of the laser instance.

FlyerLaser flyerLaser = laserGameObject.GetComponent<FlyerLaser>();

// Set it's object pool so it knows where to return to.

flyerLaser.ObjectPool = m_LaserObjectPool;

// Restart the laser.

flyerLaser.Restart();

// Play laser audio.

m_LaserAudio.Play();

}

}

}

5.3. Deplasarea în VR

Mișcarea într-un mediu VR, pe lângă afișarea unui număr scăzut de cadre pe secundă, este principala sursă care poate cauza o senzație de amețeală. Implementarea felului în care se face deplasarea, trebuie gândit și testat încă de la începutul construcției aplicației.

Senzația de amețeală este cauzată de percepția mișcării în realitatea virtuală a utilizatorului, în timp ce corpul său rămâne nemișcat în realitate. Această stare neplăcută poate cauza chiar senzația de vomă. O situație din viața reală, care se aseamănă ca efecte, este cauzată în spălătoriile automate de mașini, odată ce periile sunt puse în funcțiune și încep să curățe mașina, creează impresia că mașina începe să se miște, deși ea este staționară, sau la plecarea trenului din gară, când avem senzația că se mișcă peronul, în timp ce noi staționăm.

O regulă solidă, ce trebuie respectată, pentru a evita inducerea de stări neplăcute utilizatorului, este de a nu mișca camera, separat, de mișcarea capului utilizatorului.

Mișcarea camerei în aplicația Flyer este cu o viteză constantă, pe direcția înainte și este prezentă și în interfața meniului premergător începerii jocului, astfel utilizatorul nu este supus unei accelerații spontane, dintr-o scenă statică, odată cu începerea jocului.

Urmele lăsate, în spate, de navă, cât și particulele din zonele exterioare cadrului scenei, induc senzația de viteză, dar și ajută, ca referință spațială, pentru orientarea utilizatorului.

5.4. Interfața în VR

De regulă în mediul VR, datorită proximității ecranului de ochii utilizatorului, dar și a efectului de mărire asupra imaginii cauzat de lentile, se preferă un ecran cu o densitate mare de pixeli.

Dispozitivele dedicate, produse în serie și disponibile pe piață, au cel puțin o rezoluție a ecranului de 1.920 x 1.080 (960 x 1.080 pentru fiecare ochi) sau, în cazul testului meu, pe un dispozitiv de tip Samsung Galaxy S6, 2.560 x 1.440 (1.280 x 1.440 pentru fiecare ochi). În ciuda acestui fapt, pixelii sunt vizibili cu ochiul liber.

Ținând cont de considerentele enumerate mai sus, atunci când se proiectează interfața utilizatorului (UI) și elementele sale, trebuie să nu scăpăm din vedere, modul în care acestea ajung să fie afișate pe ecran. Abordarea este una simplă și constă în utilizarea fonturilor mari sau folosirea lor îngroșată, iar liniile nu trebuie să fie subțiri. Desigur, și utilizarea efectului de anti-aliasing ajută la reducerea aspectului pixelat.

using UnityEngine;

namespace VRStandardAssets.Utils

{

// This class fades in and out arrows which indicate to

// the player which direction they should be facing.

public class GUIArrows : MonoBehaviour

{

[SerializeField] private float m_FadeDuration = 0.5f; // How long

it takes for the arrows to appear and disappear.

[SerializeField] private float m_ShowAngle = 60f; // How far

from the desired facing direction the player must be facing for the arrows to

appear.

[SerializeField] private Transform m_DesiredDirection; // Indicates

which direction the player should be facing (uses world space forward if null).

[SerializeField] private Transform m_Camera; // Reference

to the camera to determine which way the player is facing.

[SerializeField] private Renderer[] m_ArrowRenderers; // Reference

to the renderers of the arrows used to fade them in and out.

private float m_CurrentAlpha; // The alpha

the arrows currently have.

private float m_TargetAlpha; // The alpha

the arrows are fading towards.

private float m_FadeSpeed; // How much

the alpha should change per second (calculated from the fade duration).

private const string k_MaterialPropertyName = "_Alpha"; // The name

of the alpha property on the shader being used to fade the arrows.

private void Start ()

{

// Speed is distance (zero alpha to one alpha) divided by time

(duration).

m_FadeSpeed = 1f / m_FadeDuration;

}

private void Update()

{

// The vector in which the player should be facing is the forward

direction of the transform specified or world space.

Vector3 desiredForward = m_DesiredDirection == null ?

Vector3.forward : m_DesiredDirection.forward;

// The forward vector of the camera as it would be on a flat plane.

Vector3 flatCamForward = Vector3.ProjectOnPlane(m_Camera.forward,

Vector3.up).normalized;

// The difference angle between the desired facing and the current

facing of the player.

float angleDelta = Vector3.Angle (desiredForward, flatCamForward);

// If the difference is greater than the angle at which the arrows

are shown, their target alpha is one otherwise it is zero.

m_TargetAlpha = angleDelta > m_ShowAngle ? 1f : 0f;

// Increment the current alpha value towards the now chosen target

alpha and the calculated speed.

m_CurrentAlpha = Mathf.MoveTowards (m_CurrentAlpha, m_TargetAlpha,

m_FadeSpeed * Time.deltaTime);

// Go through all the arrow renderers and set the given property of

their material to the current alpha.

for (int i = 0; i < m_ArrowRenderers.Length; i++)

{

m_ArrowRenderers[i].material.SetFloat(k_MaterialPropertyName,

m_CurrentAlpha);

}

}

// Turn off the arrows entirely.

public void Hide()

{

gameObject.SetActive(false);

}

// Turn the arrows on.

public void Show ()

{

gameObject.SetActive(true);

}

}

}

5.5. Optimizarea aplicației

Dezvoltarea de aplicații în Unity pentru realitatea virtuală este ușor diferită față de aplicațiile normale, din mai multe considerente.

Unul dintre acestea, este modul în care se face previzualizarea comportamentului aplicației în Unity IDE, deoarece fiind vorba de o afișare stereoscopică, conținutul acesteia este procesat grafic de două ori, fapt care poate cauza de multe ori un efect de mișcare sacadată. Pentru a evita ulterioare experiențe neplăcute utilizatorului, este recomandat ca periodic, aplicația să fie construită și testată pe dispozitivul țintă.

Un alt factor important de care trebuie ținut cont, este utilizarea în exces a efectelor, deoarece acestea pot fi mari consumatoare de resurse și devine simțitor la numărul de cadre pe secundă. Dar această lipsă a unor efecte, nu trebuie văzută ca un minus, în experiența oferită, în final, utilizatorului, deoarece realitatea virtuală este o reprezentare a ochilor utilizatorului într-un spațiu virtual și multe efecte nu au sens, deoarece nu pot fi vizualizate nici în lumea reală.

Printre acestea, putem enumera: profunzimea câmpului, blurul, strălucirea temporară prin lentilă. Efectul de profunzime a câmpului ar putea fi implementat, dacă dispozitivul de realitate virtuală ar avea un senzor de urmărire a ochilor, în special, zona focalizată de aceștia.

Efecte ca antialiasing-ul ar avea utilitate pe ecrane cu o rezoluție și densitate a pixelilor mai mică, prin eliminarea muchiilor zimțate.

Spre deosebire de dispozitivul Oculus Rift, care folosește resursele PC-ului, în special puterea de procesare a plăcii grafice, implementarea VR prin google cardboard se folosește doar de puterea de procesare a procesorului existent în smartphone, care este mult inferioară. Dar, acest lucru a fost compensat, prin adăugarea ceței în interiorul scenei principale, prin acest artificiu, câmpul vizual este micșorat, iar obiectele (asteroizii) nu dau impresia că apar brusc, fapt ce reduce mult numărul de obiecte ce trebuiesc randate.

FlyerGameController.cs

using System.Collections;

using UnityEngine;

using UnityEngine.UI;

using VRStandardAssets.Utils;

namespace VRStandardAssets.Flyer

{

// This script controls the flow of the flyer

// game and how all the other controllers work

// together.

public class FlyerGameController : MonoBehaviour

{

[SerializeField] private int m_GameDuration = 115;

// The duration of the game

[SerializeField] private float m_IntroOutroFadeDuration = 0.5f;

// The duration of the fade before and after the intro

[SerializeField] private SelectionSlider m_SelectionSlider;

// The slider needed to start the game.

[SerializeField] private Reticle m_Reticle;

// The reticle so it can be turned on to aim at the selection slider.

[SerializeField] private FlyerHealthController m_HealthController;

// The flyer's health so it can be reset.

[SerializeField] private FlyerAlignmentChecker m_AlignmentChecker;

// The script to check ring alignments, it should only be on whilst the game

runs.

[SerializeField] private FlyerMovementController

m_FlyerMovementController; // The script controlling the movement of the

flyer.

[SerializeField] private EnvironmentController m_EnvironmentController;

// This needs to know when to start and stop spawning the environment.

[SerializeField] private UIController m_UIController;

// This needs to know when specific pieces of UI should be shown.

[SerializeField] private GUIArrows m_GuiArrows;

// The GUI Arrows shown at the start.

[SerializeField] private Image m_TimerBar;

// Timer slider to indicate time remaining.

//[SerializeField] private InputWarnings m_InputWarnings;

// This needs to know when to show different warnings.

[SerializeField] private VRCameraFade m_CameraFade;

// This is used to fade out and back in again as the game starts.

[SerializeField] private SelectionRadial m_SelectionRadial;

// Used to restart the game.

private float m_EndTime;

// The time at the point the game should end.

private float m_TimeRemaining;

// The time until the game should end.

private bool m_IsGameRunning;

// Whether the game is currently running.

public bool IsGameRunning { get { return m_IsGameRunning; } }

private IEnumerator Start()

{

while (true)

{

yield return StartCoroutine (StartPhase ());

yield return StartCoroutine (PlayPhase ());

yield return StartCoroutine (EndPhase ());

}

}

private IEnumerator StartPhase ()

{

// Make sure the Outro UI is not being shown and the intro UI is.

StartCoroutine(m_UIController.ShowIntroUI());

StartCoroutine(m_UIController.HideOutroUI ());

// To make sure the user is facing the right way show the arrows.

m_GuiArrows.Show ();

// Turn off the fog whilst showing the intro.

RenderSettings.fog = false;

// Make sure the game is stopped for the flyer's health.

m_HealthController.StopGame ();

// Since a selection slider is being used, hide the radial and show

the reticle.

m_SelectionRadial.Hide ();

m_Reticle.Show ();

// The user should hold Fire1 for the selection slider so turn on

warnings for tapping.

//m_InputWarnings.TurnOnDoubleTapWarnings ();

//m_InputWarnings.TurnOnSingleTapWarnings ();

// In order wait for the selection slider to fill, then the intro UI

to hide, then the camera to fade out.

yield return StartCoroutine (m_SelectionSlider.WaitForBarToFill ());

yield return StartCoroutine (m_UIController.HideIntroUI ());

yield return

StartCoroutine(m_CameraFade.BeginFadeOut(m_IntroOutroFadeDuration, false));

// Once the screen has faded out, we can hide UI elements we don't

want to see anymore like the arrows and reticle.

m_GuiArrows.Hide ();

m_Reticle.Hide ();

// Turn the fog back on so spawned objects won't appear suddenly.

RenderSettings.fog = true;

// The user now needs to tap to fire so turn off the warnings.

//m_InputWarnings.TurnOffDoubleTapWarnings ();

//m_InputWarnings.TurnOffSingleTapWarnings ();

// Now wait for the screen to fade back in.

yield return

StartCoroutine(m_CameraFade.BeginFadeIn(m_IntroOutroFadeDuration, false));

}

private IEnumerator PlayPhase ()

{

// The game is now running.

m_IsGameRunning = true;

// Start the various controllers.

m_AlignmentChecker.StartGame ();

m_HealthController.StartGame ();

m_FlyerMovementController.StartGame ();

m_EnvironmentController.StartEnvironment();

// The end of the game is the current time + the length of the game.

m_EndTime = Time.time + m_GameDuration;

// Each frame while the flyer is alive and there is time

remaining…

do

{

// Calculate the time remaining set the timer bar to fill by the

normalised time remaining.

m_TimeRemaining = m_EndTime – Time.time;

m_TimerBar.fillAmount = m_TimeRemaining / m_GameDuration;

// Wait until the next frame.

yield return null;

}

while (m_TimeRemaining > 0f && !m_HealthController.IsDead);

// Upon reaching this point either the time has run out or the flyer

is dead, either way the game is no longer running.

m_IsGameRunning = false;

}

private IEnumerator EndPhase ()

{

// Wait for the camera to fade out.

yield return

StartCoroutine(m_CameraFade.BeginFadeOut(m_IntroOutroFadeDuration, false));

// Show the required UI like the arrows and the radial.

m_GuiArrows.Show ();

m_SelectionRadial.Show ();

// Turn off the fog.

RenderSettings.fog = false;

// Show the outro UI.

StartCoroutine(m_UIController.ShowOutroUI());

// Stop the various controllers.

m_AlignmentChecker.StopGame();

m_HealthController.StopGame();

m_FlyerMovementController.StopGame();

m_EnvironmentController.StopEnvironment();

// The user needs to fill the radial to continue so turn the tap

warnings back on.

//m_InputWarnings.TurnOnDoubleTapWarnings();

//m_InputWarnings.TurnOnSingleTapWarnings();

// In order, wait for the screen to fade in, then wait for the user

to fill the radial.

yield return

StartCoroutine(m_CameraFade.BeginFadeIn(m_IntroOutroFadeDuration, false));

yield return

StartCoroutine(m_SelectionRadial.WaitForSelectionRadialToFill());

// Turn the warnings off now the user has filled the radial.

//m_InputWarnings.TurnOffDoubleTapWarnings();

//m_InputWarnings.TurnOffSingleTapWarnings();

// Hide the arrows.

m_GuiArrows.Hide();

// Wait for the outro UI to hide.

yield return StartCoroutine(m_UIController.HideOutroUI());

// Turn the fog back on.

RenderSettings.fog = true;

}

}

}

Pentru a reduce consumul de resurse a fost folosit conceptul de clonare a obiectelor:

using System.Collections.Generic;

using UnityEngine;

namespace VRStandardAssets.Utils

{

// This is a simple object pooling script that

// allows for random variation in prefabs.

public class ObjectPool : MonoBehaviour

{

[SerializeField] private GameObject[] m_Prefabs; // These are

prefabs which are all variations of the same (for example various asteroids).

[SerializeField] private int m_NumberInPool; // The

number of prefabs to be initially instanced for the pool.

private List<GameObject> m_Pool = new List<GameObject> (); // The list

of instantiated prefabs making up the pool.

private void Awake ()

{

// Add as many random variations to the pool as initially

determined.

for (int i = 0; i < m_NumberInPool; i++)

{

AddToPool ();

}

}

private void AddToPool ()

{

// Select a random prefab.

int randomIndex = Random.Range (0, m_Prefabs.Length);

// Instantiate the prefab.

GameObject instance = Instantiate(m_Prefabs[randomIndex]);

// Make the instance a child of this pool and turn it off.

instance.transform.parent = transform;

instance.SetActive (false);

// Add the instance to the pool for later use.

m_Pool.Add (instance);

}

public GameObject GetGameObjectFromPool ()

{

// If there aren't any instances left in the pool, add one.

if (m_Pool.Count == 0)

AddToPool ();

// Get a reference to the first gameobject in the pool.

GameObject ret = m_Pool[0];

// Remove that gameobject from the pool list.

m_Pool.RemoveAt(0);

// Activate the instance.

ret.SetActive (true);

// Put it in the root of the hierarchy.

ret.transform.parent = null;

// Return the unpooled instance.

return ret;

}

public void ReturnGameObjectToPool (GameObject go)

{

// Add the gameobject to the pool list.

m_Pool.Add (go);

// Deactivate the gameobject and make it a child of the pool.

go.SetActive (false);

go.transform.parent = transform;

}

}

}

Extras din: FlyerLaser.cs

private void OnTriggerEnter(Collider other)

{

// Try and get the asteroid component of the hit collider.

Asteroid asteroid = other.GetComponent<Asteroid>();

// If it doesn't exist return.

if (asteroid == null)

return;

// Otherwise call the Hit function of the asteroid.

asteroid.Hit();

// The laser has hit something.

m_Hit = true;

// Return the laser to the object pool.

ObjectPool.ReturnGameObjectToPool(gameObject);

}

5.6. Construirea (exportul) aplicației

Construirea aplicației Flyer în Unity a implicat mai multe etape, prima este adăugarea și setarea SDK-ului Android, setarea ADB (android debug bridge) pentru a asigura comunicarea între PC și dispozitivul android.

Exportul aplicației în formatul .apk, din câmpul File al meniului, unde se selectează Build & Run, acesta deschide fereastra de export (Fig. 29), ce permite setarea preferințelor.

Fig. 29

Alegerea făcută pentru compresia texturii a fost ETC2, aceasta are impact asupra fișierului AndroidManifest (Fig. 30), unde va include tag-uri, care specifică alegerea acestui format de compresie, în vederea restricționării posibilității de a instala aplicația doar pe dispozitivele ce oferă suport grafic hardware.

Fig. 30

Important este ca, înainte de a da click pe butonul Build, ce realizează exportul, de a intra în Player Settings, pentru a face setările necesare.

Am folosit orientarea statică Landscape Left, deoarece telefonul trebuie introdus în dispozitivul de montat pe cap, Google Cardboard într-un singur mod. Tot aici se fac și setările referitoare la numele aplicației, icoanei, versiunii și așa mai departe.

6. Posibilități de dezvoltare ulterioare

Aplicația poate fi portată cu ușurință pe sistemul de operare iOS, deoarece motorul grafic Unity, în care a fost dezvoltată, este unul multi platformă, dar din lipsa unui cont de dezvoltator pe platforma Apple Store, pentru a o putea testa pe un iphone și nu într-o mașină virtuală, ce simulează un telefon cu sistemul de operare iOS, am evitat acest aspect.

Următorul pas de dezvoltare pentru aplicație, ar fi integrarea ei cu rețeaua de socializare Facebook, pentru a putea realiza un spirit de competiție în comunitatea utilizatorilor, dar și pentru a deveni din ce în ce mai populară.

Cât despre funcționalitatea ei, se pot adăuga nivele, care își cresc dificultatea treptat, elemente noi, cum ar fi nave diferite, proiectile mai puternice, posibilitățile sunt, aproape, nelimitate.

În privința interacțiunii utilizatorului prin intermediul dispozitivului Google Cardboard, există un neajuns, acesta fiind existența unui singur buton, fapt apreciat de unii utilizatori pentru simplitatea pe care o oferă, dar și motiv de nemulțumire pentru alții. Acest aspect, din punct de vedere al dezvoltării de aplicații, presupune găsirea unor metode creative, prin care să implementeze anumite acțiuni, cum ar fi cea de întoarcere în scena anterioară sau ieșirea din aplicație (similară apăsării butonului de înapoi-back).

Pentru această acțiune, tot Google, propune întoarcerea dispozitvului spre stânga sau dreapta, la 90 de grade, deoarece în timpul interacțiunii în aplicație, acest semnal nu poate fi reprodus fizic de capul uman, decât dacă mișcarea dispozitivului se face cu mâna, după ce a fost îndepărtat de pe cap. Implementarea acțiunii de back, este momentan, în faza de analiză, nefiind prezentă în aplicația actuală.

7. Concluzii

Fiecare generație poate fi definită de o tehnologie, spre exemplu, pentru părinții noștri a fost internetul, noi suntem definiți de smartphone, sunt mari șanse ca următoarea tehnologie, care definește generația copiilor noștri, să fie realitatea virtuală.

Asta înseamnă că, încă de la vârste fragede, vor fi înconjurați de realitatea virtuală, în multe circumstanțe din viață, de la învățămant, la divertisment.

Posibile aplicații ale realității virtuale includ:

Simulatoare foarte realiste;

Divertisment, având potențialul de a schimba, dramatic, cinematografia actuală;

Design industrial și arhitectural;

Medicina, în scop terapeutic, dar și pentru chirurgia asistată de roboți;

Educație;

Jocuri;

Militar;

Artistic.

Din perspectiva dezvoltării de aplicații, implementate în mediul realității virtuale, acest domeniu, aflat în faze incipiente, prezintă multe avantaje:

Piața nu este, încă, saturată de studiouri mari, ce dezvoltă aplicații;

Resursele din care se poate învăța sunt destule și cantitativ dar și calitativ;

8. Abrevieri

ADB android debug bridge

API application programming interface

APPS applications (aplicații)

AR augmented reality

BSD Berkeley software distribution

DIY do it yourself

ETC2 Ericsson texture compression

Fig. figura

GPS global positioning system

HDM head display mount

IDE integrated development environment

MID-let application that uses Mobile Information Device Profile (MIDP)

NFC near field communication

PPI pixel per inch

RAM random access memory

SD storage device

SDK software development kit

SGL scalable graphics library

SMS short message service

SSAO screen space ambient occlusion

UI user interface

VR virtual reality (realitate virtuală)

wi-fi wireless fidelity

9. Bibliografie

https://en.wikipedia.org/wiki/Android_(operating_system) https://ro.wikipedia.org/wiki/Android_(sistem_de_operare) și căutari google, pentru a avea date cât mai recente, accesat online în 12.05.2016

http://developer.android.com/guide/basics/what-is-android.html accesat online în 12.05.2016.

http://www.itcsolutions.eu/2011/09/08/android-tutorial-concepte-activitati-si-resurse-ale-unei-aplicatii-android/ accesat online în 14.05.2016.

https://en.wikipedia.org/wiki/Virtual_reality accesat online în 14.05.2016

https://en.wikipedia.org/wiki/Google_Cardboard accesat online în 14.05.2016

https://www.google.com/get/cardboard/get-cardboard/ accesat online în 14.05.2016

https://www.youtube.com/watch?v=lFm4s50PnmY accesat online în 14.05.2016.

https://en.wikipedia.org/wiki/Unity_(game_engine) accesat online în 25.05.2016

https://play.google.com/store/apps/details?id=com.silicondroid.galaxyvr&hl=en accesat online în 24.05.2016

https://play.google.com/store/apps/details?id=com.gamearx.spacerumble&hl=e accesat online în 24.05.2016

https://en.wikipedia.org/wiki/Asteroids_(video_game) accesat online în 14.05.2016

Similar Posts