Skąd pomysł na projekt?
Będąc studentem w wielkim mieście musiałem wkręcić się w nową grę Pokemon GO (ale oczywiście dopiero jak przeszedł największy szał 😉 ). Dzięki niej spacery ze słuchawkami na uszach nabrały nowego sensu. Ale najbardziej w nowej grze zaintrygowała mnie funkcja AR (rozszerzonej rzeczywistości), bo tym razem nie ograniczała się do statycznych obiektów jak w wielu dostępnych w Internecie demach. A skoro i tak już robiłem kolejne projekty w Xamarinie to trzeba było zorientować się czy mogę coś takiego osiągnąć programując w C#. Mniej więcej w tym samym momencie pojawiła się pierwsza wersja biblioteki ARCore dla mojego Xiaomi Mi 9T. Coraz więcej znaków na niebie dawało nadzieję na fajny ciekawy. Niestety po przejrzeniu przykładów w dokumentacji biblioteki ARCore tworzonej przez Google’a stwierdziłem, że temat może być znaczniej bardziej skomplikowany niż sobie bym tego życzył. Ale tutaj z pomocą przyszedł Microsoft ze swoją dokumentacją oraz twórcy biblioteki UrhoSharp. Trzeba było jeszcze znaleźć jakieś zastosowanie dla rozszerzonej rzeczywistości… I tutaj z inspiracją przyszła moja obecna praca 🙂
O aplikacji
Plan był taki, aby opracować aplikację, która pozwoli handlowcom tworzyć szybkie wizualizacje opraw oświetleniowych (drogowych, do wnętrz, itd.) dla potencjalnych klientów. Wyszedłem z założenia, że każdy pracownik posiada smartphone’a oraz umie używać wbudowanej w niego kamery. Nic by też nie stało na przeszkodzie, aby wykorzystywać aplikację do prezentacji wszystkich produktów firmy bez dodatkowej potrzeby jeżdżenia ciężarówką wypełnioną każdym wariantem produkowanej przez zakład lampy.
Zacząłem od opracowania uproszczonego modelu 3D oprawy Siled Celebra. Na początku, z racji jakiejś znajomości ze szkoły średniej/studiów, postanowiłem wykorzystać do tego oprogramowanie Autodesk Autocad. Pomimo bardzo zadowalającego efektu podczas renderowania oprawy pod różnymi kątami (jak na swój pierwszy raz w świecie 3D) okazało się, że eksport modeli do formatów obsługiwanych przez UrhoSharp’a jest trochę bardziej skomplikowany. Po obejrzeniu wielu YouTube’owych poradników skończyłem z wirtualną maszyną Debian’a i zainstalowanym Blender’em posiadającym plug-in „Urho3D-Blender„. Po wielu podejściach do różnych konfiguracji oraz wersji Blendera i rozszerzenia udało się w końcu trafić na taką, z którą robienie kolejnych modeli było już szybsze i sprawniejsze.
Po opracowaniu opraw zabrałem się za wykonanie słupa. Tutaj na szczęście mogłem posiłkować się gotowymi modelami (np. śrub z plug-in’u Bolt Factory). No i w końcu coś zaczęło się prezentować.
Równolegle do tworzonych modeli 3D powstawał również kod źródłowy robiony w Xamarin Android. SDK zostało wybrane ze względu na pokrycie niemal w 90% funkcji dostarczanych przez Javowe SDK od Google’a i dodatkowo po prostu bardziej jestem Team Microsoft niż Team Google czy Team Oracle.
Kodzenie zacząłem od interfejsu aplikacji (w sumie znany temat, więc chociaż od początku było widać jakiś efekt). Największy problem był z pionowym suwakiem do ustalania wysokości oprawy/długości słupa. Niestety Google nie przewidziało takiej kontrolki w swojej bibliotece. Na szczęście metodą prób i błędów udało się w końcu opracować jakiś kompromis co pozwoliło na przejście do bardziej zaawansowanych rzeczy.
Pierwszą z nich było wykonanie jakiegoś algorytmu pozwalającego na tworzenie całej instalacji lamp składającej się z zadanej ilości. W tym celu w świecie AR należało dodać minimum dwie oprawy, a algorytm robił resztę – obliczał odległość między najdalszymi oprawami i generował symetrycznie kolejne w tych samych odległościach. Do ekstrapolacji zostało wykorzystane proste równanie liniowe – w planach było opracowanie kolejnych wariantów algorytmu wykorzystujących bardziej wymyślne równania krzywych. Niestety świat w którym pracowałem występował w 3 wymiarach, więc estymacji potrzebnych parametrów musiałem dokonywać z pomocą równań macierzowych w funkcji StartCreatingNewInstallation() (czemu oczywiście podołałem 😉 ).
Kolejną rzeczą na której mi zależało było generowanie cienia przez słup z lampą zgodnie z aktualnym położeniem słońca. Do wykonania tej funkcjonalności potrzebowałem dodać obsługę kompasu oraz GPS’u. Na bazie tych informacji (oraz aktualnej daty i godziny) mogłem obliczyć położenie słońca na niebie. Później wystarczyło dodać node’a ze źródłem światła znajdującym się w obliczonym miejscu i można było patrzeć jak wirtualny cień pokrywa się z tym rzeczywistym. W planach było jeszcze uzależnienie jasności źródła światła od wartości natężenia światła odczytywanego ze smartphone’owego czujnika, ale ostatecznie nie wcieliłem tego planu w życie.
Iiiiiiii… Potem czar UrhoSharp’a prysnął. Przy próbie wykonania bardziej zaawansowanych rzeczy w tym silniku graficznym zaczęły pojawiać się błędy i artefakty (np. nieprawidłowe generowanie cienia – szczegóły w zrzutach ekranu i nagraniach wideo). Na pomoc w Internecie też za bardzo nie było co liczyć – okazało się, że UrhoSharp był portem silnika graficznego Urho3D i użytkownicy Urho3D oraz UrhoSharp’a za bardzo się nie lubili (przynajmniej takie były moje odczucia, gdy prosiłem o wsparcie) 😉 . Microsoft reklamował UrhoSharp’a na stronie głównej dotyczącej Xamarin’a (na szczęście już z tego pomysłu się wycofał) i niestety dałem się zwieść. Na dodatek dzisiaj nie mam możliwości przetestowania mojej aplikacji na nowym telefonie Samsung Galaxy Note 10+, ponieważ najnowsza wersja ARCore’a generuje wyjątki zaraz po uruchomieniu opracowanej aplikacji (a UrhoSharp już od kilku lat nie jest aktualizowany) – teoretycznie jest możliwość manualnej aktualizacji potrzebnych bibliotek, ale stwierdziłem, że szkoda na to zachodu.
Głównym przekonującym argumentem za UrhoSharp’em (oprócz bardzo dużej prostoty przy tworzeniu wirtualnego świata) była licencja MIT, ale dzisiaj podchodząc jeszcze raz do tego projektu poszedłbym pewnie w stronę Unity albo bezpośrednio w ARCore’a – może kiedyś podejmę się przeportowania aplikacji, kto wie.
Ale co się nauczyłem przy tym projekcie to moje 😉
TODO
Poniżej prezentuję listę rzeczy, które chciałem uwzględnić w rozwoju tej aplikacji:
- Poprawa działania światła dziennego i generowanego przez nie cienia,
- Ulepszenie algorytmu do generowania całych instalacji lamp,
- Dodanie nowych modeli opraw,
- Opracowanie interfejsu pozwalającego na sterowanie wirtualnymi oprawami za pomocą aplikacji zarządzania inteligentnymi oprawami (CMS).
Zrzuty ekranu
Kody źródłowe
Aplikacja
Tak jak wspominałem wcześniej aplikacja została opracowana raczej jako proof of concept i po nabytych doświadczeniach nie nadaje się raczej do rozwoju/udostępnienia 🙂 Oczywiście jak ktoś będzie naprawdę jej potrzebował to zapraszam do kontaktu/sekcji komentarzy albo zachęcam do własnoręcznej kompilacji ze źródeł dostępnych na moim GitHub’ie.