czwartek, 30 marca 2017

[DSP2017] 9# Holowizja - choć pomaluj mój świat na żółto i na niebiesko…

Dziś małe uzupełnienie poprzedniego odcinka. Pokażę krótko, jak pokolorować ściany, podłogę i sufit pokoju i bynajmniej nie mam tu na myśli pracy malarza… bo stanie się to tylko w naszej głowie z HoloLens.

Do sceny z  HoloVision7  dodaję game obiekt o nazwie SpatialProcessing, a do niego skrypty z HoloToolkit o nazwach SurfaceMeshesToPlanes i RemoveSurfaceVertices oraz skrypt PlaySpaceManager z Holograms 230: Spatial mapping (z zakomentowaną linią

SpaceCollectionManager.Instance.GenerateItemsInWorld(horizontal, vertical);

odpowiedzialną za umieszczanie obiektów na scenie)

R0

W SurfaceMeshesToPlanes wybieramy w Surface Plane Prefab komponent SurfacePlane. Z kolei w inspektorze tego ostatniego ustawiamy materiały dla ścian, sufitu, podłogi, stołu pokoju.

image

Materiały dla nich możemy zdefiniować sami albo dla testu wykorzystać z Holograms 230: Spatial mapping.

Generalnie chodzi o to by przetworzyć zmapowaną przestrzeń, wykryć w niej podłogę, ściany, sufit czy stół, a potem je pokolorować.

Oto co wynurzyło się przed moimi oczami (po przejściu przez ścianę cofając się do tyłu z początkowego punktu, który był zdaje się w jakimś pustościanie).

R6

Scena dostępna na github jako HoloVision8.

Chciałem jeszcze umieścić bez ingerencji użytkownika na ścianie jakiś przedmiot, ale okazało się to niezbyt proste. Owszem Holograms 230: Spatial mapping dostarcza skrypty, które to robią, ale zależą one od starszej początkowej wersji Holo toolkitu. W nowym HoloToolkicie odnajdziemy natomiast skrypt TapToPlace, który przypięty do obiektu sprawi, że gdy najedziemy na niego kursorem i naciśniemy, to obiekt będzie podążał za kursorem osadzając się na siatce pokoju. W testowej scenie toolkitu nawet to działa, na mojej scenie póki co nie uzyskałem tego efektu. Inna sprawa, że samo renderowanie tej siatki, a potem wykrywanie ścian i kolorowanie nie działa natychmiast, a losowo w emulatorze może wyświetlić się scena bez pokoju…

Cześć, do następnego zwariowanego odcinka –Smile

sobota, 25 marca 2017

[DSP2017] 8# Holowizja - gdy zwykły pokój przestaje być zwykłym pokojem…

A gdyby pokój, w którym siedzę lub stoję, przestał być zwykłym pokojem i wzbogacić go o elementy nowe, na które oddziałują te dotychczasowe prawdziwe ?

HoloLens dzięki mapowaniu przestrzennemu (spatial mapping) może spełnić takie życzenie. Dziś przejdziemy drogę dla absolutnie początkujących w tym zakresie. Zobaczymy dobrze znany już nam sześcian i kulę w powietrzu, które po umieszczeniu na nich kursora i wypowiedzeniu magicznego “Shoot down” spadną z pewnym łoskotem na podłogę pokoju, po drodze być może odbijając się od innych przedmiotów.

Room1

W pokazanym pokoju “zestrzelony” słowem sześcian spadł za czarną bryłę i straciłem go z oczu w tej perspektywie, natomiast “zestrzelona” kula odbiła się kilka razy i dotoczyła się do lewego kąta podłogi.

Room2

A teraz już do rzeczy i po kolei, jak takie coś osiągnąć i skąd ta czerwona siatka, o której jeszcze nic nie wspomniałem.

Na bazie poprzedniego przykładu HoloVision6 przygotowałem wyjściową scenę, do której dodamy przestrzenne mapowanie. Usunąłem zieloną płaszczyznę pod sześcianem i kulą. Kierując się większym komfortem, wyłączyłem sobie jęczące audio source na sześcianie (odznaczyłem checka), choć nie było to konieczne. W Edit > Project Settings > Player w sekcji Publishing Settings upewniamy się, czy SpatialPerception jest zaznaczone.

Teraz sprawa kluczowa. W Unity przeciągamy z Assets  HoloToolkit/SpatialMapping/Prefabs/SpatialMapping.prefab do Hierarchy na główny poziom. Zaznaczamy opcję Draw Visual Meshes. W Spatial Mapping Manager w Surface Material ustawiamy Wireframe (na screenie poniżej jest RedWireframe, ale o tym nieco później).

Room3

Jakbyśmy mieli fizyczne urządzenie, to otaczający nas pokój zostałby zmapowany za pomocą siatki podzielonej na trójkąty. Emulator nie pozostawia nas jednak całkowicie bez szans i oferuje kilka predefiniowanych pokojów, które można do niego załadować.

image

Po odpaleniu na emulatorze zobaczymy już białą siatkę pokoju.

Skanowanie prawdziwego pokoju za każdym razem jest nieco czasochłonną i skomplikowaną czynnością. Zeskanowany model można w Device Portal zapisać do pliku. Wchodzimy na zakładkę 3D View. Pod Spatial mapping naciskamy przycisk Update, co spodowoduje pokazanie się modelu. Następnie naciskamy przycisk Save.

 Room7

HoloToolkit także dostarcza przykładową siatkę pokoju. Znajdziemy ją w Assets w HoloToolkit/SpatialMapping/Tests/Meshes/SRMesh.obj. Jak przeciągniemy ją na pole Room Model skryptu Object Surface Observer w inspektorze SpatialMapping, to będzie prezentowana zamiast pokoju dostarczanego na żywo (czy też wybranego do załadowania w emulatorze).

Co nam to daje w stosunku do wcześniejszego ładowania przykładowego pokoju wprost z emulatora?  Otóż teraz już w Unity mogę podejrzeć tę siatkę przechodząc w tryb podglądu za pomocą przycisku play na górze.

Room4

Aha, czemu jest ona u mnie czerwona? Biała wydawała mi się zbyt banalna i przygotowałem sobie materiał o nazwie RedWireframe w Assets/Materials na podstawie kopii Wireframe dostarczanego przez HoloToolkit (w HoloToolkit/SpatialMapping/Materials). W inspektorze RedWireframe ustawiłem Wire color na czerwony. Następnie w inspektorze SpatialMapping w polu Surface Material ustawiłem ten materiał (skrypt Spatial Mapping Manager).

Siatkę pokoju w Unity zobaczyć możemy również na scenie. Wystarczy będąc w trybie podglądu przejść do zakładki Scene.

Room5

Przedstawioną tutaj scenę z siatką i bryłami w powietrzu udostępniłem jako HoloVision7 na github.

To oczywiście nie jest wszystko, co można osiągnąć w mapowaniu przestrzennym w HoloLens. Jak zawsze wskażę tu tutoriale z Holo Academy: Holograms 101E: Introduction with Emulator (ostatnia sekcja) oraz Holograms 230: Spatial mapping. Zmapowany pokój można sobie pokolorować, wykryć w nim ściany, podłogę i sufit, coś sobie na nich poumieszczać (programowo lub pozwolić na to samemu użytkownikowi naszej aplikacji). Uwzględnienie chowania się przedmiotów za inne przedmioty też jest istotne, można niewidoczne ich części prezentować w odmienny sposób np. jako siatkę. Sprawia to wrażenie jakbyśmy mieli Rentgen w oczach.

Kolejny równie awangardowy i niczym nieograniczony odcinek rodzi się już w mojej głowie. A zatem do następnego razu!

poniedziałek, 20 marca 2017

[DSP2017] 7# Holowizja - mroczne dźwięki z horroru w przestrzeni 3D

Dźwięk przestrzenny jest niezbędny, by wizja w HoloLens wydawała się realna. I to będzie nasz temat na dziś.

Weźmy ostatni projekt HoloVision5. Dodamy do niego dźwięk skojarzony z sześcianem oraz dźwięk następujący po upadku sześcianu lub kuli na płaszczyznę.

Jak włączyć dźwięk przestrzenny? Po pierwsze w Edit –> Project Settings –> Audio ustawiamy Spatializer Plugin na MS HRTF Spatializer.

image

Darmowe pliki audio można pobrać np. z Unity Store. Czasami przypadek rodzi inspirację. Tak też było teraz, natrafiłem na pakiety z muzyką z horroru i stąd projekt oraz tytuł posta taki, a nie inny. Z pakietu Horror Ambient Sounds Pack wziąłem dwa pliki:  Horror Ambient Sounds Pack/Ambient Sounds/Horror Atmosphere/Ambience Mid.wav (demoniczne tło) oraz Horror Ambient Sounds Pack/Other/Scare.wav (echoistyczne uderzenie). Zaimportowałem je w Unity do nowo utworzonego folderu Resources w Assets.

Niech sześcian będzie nawiedzony. W tym celu na Cube przeciągam  Ambience Mid z Assets/Resources. W inspektorze dla Cube pojawił się nowy element o nazwie Audio Source. Dokonujemy jego konfiguracji:

1. Zaznaczamy opcje Spatialize oraz Loop

2. Spatial Blend ustawiamy na 1 (lub suwakiem przesuwamy do pozycji 3D)

3. W 3D Sound Settings zmniejszam Doppler Level (efekt Dopplera to zjawisko z lekcji fizyki by odbiór dźwięku przez nas był taki jak w realu, przy pomocy HoloLens możnaby je demonstrować uczniom, co może kiedyś nastąpi jak ceny spadną?) na 0.1 oraz Max Distance na 20.

Końcowe ustawienia można zobaczyć poniżej.

Win1

Teraz pora na wzbogacenie zderzenia upadającego sześcianu czy kuli z “trawą”. Aby to osiągnąć w Assets/Scripts tworzę nowy skrypt o nazwie ItemSounds i przeciągam go do inspektorów Cube i Sphere. Jego zadanie polega na odnalezieniu w Resources drugiego audio o nazwie Scare oraz odpalenie w momencie kolizji. Realizuje to poniższy prosty kod:

using UnityEngine;

public class ItemSounds : MonoBehaviour
{

    AudioSource audioSource = null;   
   
    void Start()
    {       
        audioSource = gameObject.AddComponent<AudioSource>();
        audioSource.playOnAwake = false;
        audioSource.spatialize = true;
        audioSource.spatialBlend = 1.0f;
        audioSource.dopplerLevel = 0.0f;
        audioSource.rolloffMode = AudioRolloffMode.Logarithmic;
        audioSource.maxDistance = 20f;
        audioSource.clip = Resources.Load<AudioClip>("Scare");       
    }

    void OnCollisionEnter(Collision collision)
    {       
        if (collision.relativeVelocity.magnitude >= 0.1f)
        {           
            audioSource.Play();
        }
    }
}

Eksportujemy do Visual Studio jak zawsze. Odpalamy. Zakładamy na uszy słuchawki. Chociaż scena wygląda tak samo jak ostatnio,

image

to już nasz odbiór całości jest inny z powodu dźwięku, który wywołuje uczucia jakbyśmy się znajdowali na cmentarzu o północy (potraktujmy to jako luźną interpretację częstej scenerii ostatnio dość znanego vloga).

db937ba25f71878ac570e9650737539c_full

Zacznijmy się przemieszczać. Jak się cofniemy to dźwięk stanie się cichszy. Jak się zbliżymy ponownie do “nawiedzonego sześcianu” to dźwięki ulegną wzmocnieniu. Jeśli sześcian nam zniknie z pola widzenia, a będzie z naszej prawej strony, to usłyszymy dźwięki w prawym uchu. Nasz umysł umiejscowi go po prawej stronie nawet jeśli go nie widzimy. Oczywiście analogicznie jest z lewej. W miarę przesuwania dźwięk może się nam przelać z prawego ucha, przez centrum głowy (przód lub tył), do ucha lewego…

Nakierujmy teraz kursor na sześcian lub kulę. Powiedzmy “Shoot down”. W momencie uderzenia o “trawę” usłyszymy pewien łoskot podbudowany echem niczym we śnie…

Całość tradycyjnie już dostępna jako HoloVision6 na github. Zapraszam do odsłuchu, przy czym na własne ryzyko. Jest naprawdę mrocznie…

Czy to wszystkie możliwości przestrzennego dźwięku w HoloLens? Nie!  Tradycyjnie już wspomnę o Holograms 101E: Introduction with Emulator oraz Holograms 220: Spatial sound z Holo akademii. O ile w pierwszym jest niewiele więcej niż dziś pokazałem, o tyle drugi pokazuje jak tworzyć interakcje dźwięku z rzeczywistym światem (którego efektem jest np. zanikanie) czy dodawać efekty do własnego głosu. W Holo toolkicie możemy znaleźć z kolei przydatne skrypty w folderze SpatialSound oraz przykładową scenę AudioOcclusionTest, gdzie zmienia się słyszany przez nas dźwięk w zależności od tego, czy od źródła oddziela nas ściana.

Do następnego razu. Cześć.

środa, 15 marca 2017

[DSP2017] 6# Holowizja - strzały słowem i… reset

Mieliśmy już sterowanie hologramem za pomocą spojrzenia i gestów z użyciem dłoni. Dziś pora na komendy wydawane głosowo.

Tradycyjnie już najpierw pobawiłem się tutorialami Holograms 101E: Introduction with Emulator (w zakresie głosu) oraz Holograms 212: Voice. Szkoda jedynie że bazują na początkowej wersji Holo toolkita, ale poza tym są najprawdę niezłe. W pierwszym mamy wydawanie komend głosowych przedmiotom z focusem (na które się wpatrujemy), jak również komend ogólnych do wszystkiego. W drugim momentami mamy już niemal odlot. Zaczyna się od zmiany ikony kursora na mikrofon i wyświetlania komend w celach informacyjnych, a potem trafiamy na… nagrywanie naszego głosu do zegarka kosmity (niczym jak do szafy w filmie “Miś”), dyktowanie tekstu czy otworzenie plecaka i kolorowaniu przedmiotów w powietrzu za pomocą komend zdefiniowanych w oparciu o reguły gramatyki. Co prawda techniczne możliwości w zakresie głosu osobom obeznanym w aplikacjach uniwersalnych Windows 10 mogą wydać się nawet dość typowe, ale scenaria i muzyka robią już swoje…

Emulator wspiera mikrofon, więc zabawa dostępna dla każdego. Przystępując do praktyki popatrzyłem sobie na testowe sceny do input-u w najnowszym Holo toolkicie. Znalazłem tam komendy wykonywane przez wskazane przedmioty (focus lub zaznaczenie) oraz komendy ogólne.

Przerobiłem poprzedni projekt HoloVision4 na obecny HoloVision5 w następujący sposób:

1. Przesunąłem sześcian na bok i dodałem kulę (sferę). Dodałem też dodatkowe “game” obiekty w celach grupujących i/lub do trzymania skryptów. Hierarchia sceny przedstawia się teraz następująco:

image

2.  Do obiektu SpeechInputSource dodałem skrypt SpeechInputSource (z HoloToolkit/Input/Scripts/Voice) i zdefiniowałem na nim dwie komendy głosowe “Shoot Down” oraz “Reset All”. Pierwsza spowoduje upadek wskazanego przedmiotu na płaszczyznę (poprzez dodanie do niego grawitacji jak ostatnio), druga zaś będzie skierowana ogólnie i ma powodować przywrócenie sceny do początkowego stanu.

image

3.  Do obiektu Items (trzymającego w sobie sześcian i kulę) dodaję skrypt SetGlobalListener (z HoloToolkit/Input/Scripts/SetGlobalListener) oraz nowo stworzony, własny skrypt ItemGlobalKeywords (w Assets/Scripts).

image

Skrypt ItemGlobalKeywords zapamiętuje początkowe położenia i rotacje dzieci elementu, do którego jest przypięty (w naszym przypadku będą to sześcian i kula). Jeśli zostanie odebrana komenda “Reset All”, to następuje przywracanie początkowych ustawień. Całość przedstawia się następująco:

using HoloToolkit.Unity.InputModule;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class ItemGlobalKeywords : MonoBehaviour, ISpeechHandler
{
    private Vector3[] cachedChildPositions;
    private Quaternion[] cachedChildRotations;
    private Renderer[] childRenderers;

    private void Awake()
    {
        childRenderers = GetComponentsInChildren<Renderer>();
        if (childRenderers != null && childRenderers.Length > 0)
        {
            cachedChildPositions = new Vector3[childRenderers.Length];
            cachedChildRotations = new Quaternion[childRenderers.Length];

            for (int i = 0; i < childRenderers.Length; i++)
            {
                cachedChildPositions[i] = childRenderers[i].transform.localPosition;
                cachedChildRotations[i] = childRenderers[i].transform.rotation;
            }
        }
    }

    public void OnSpeechKeywordRecognized(SpeechKeywordRecognizedEventData eventData)
    {
        switch (eventData.RecognizedText.ToLower())
        {
            case "reset all":
                if (childRenderers != null && childRenderers.Length > 0 &&
                    cachedChildPositions != null && cachedChildPositions.Length == childRenderers.Length &&
                    cachedChildRotations != null && cachedChildRotations.Length == childRenderers.Length)
                {
                    for (int i = 0; i < childRenderers.Length; i++)
                    {
                        var rigidbody = childRenderers[i].GetComponent<Rigidbody>();
                        if (rigidbody != null)
                        {
                            DestroyImmediate(rigidbody);
                        }

                        childRenderers[i].transform.localPosition = cachedChildPositions[i];
                        childRenderers[i].transform.rotation = cachedChildRotations[i];
                    }
                }
                break;
        }
    }

    private void OnDestroy()
    {
        for (int i = 0; i < childRenderers.Length; i++)
        {
            DestroyImmediate(childRenderers[i]);
        }
    }
}

4. Do obiektów Cube i Sphere podpinam nowo stworzony skrypt o nazwie ItemKeywords. Jego zadaniem jest dodanie grawitacji do obiektu, jeśli zostanie rozpoznana komenda “Shoot down”. Realizuje to poniższy kod:

using HoloToolkit.Unity.InputModule;
using UnityEngine;

[RequireComponent(typeof(Renderer))]
public class ItemKeywords : MonoBehaviour, ISpeechHandler
{
    public void OnShoot()
    {
        if (!this.GetComponent<Rigidbody>())
        {
            var rigidbody = this.gameObject.AddComponent<Rigidbody>();
            rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
        }
    }

    public void OnSpeechKeywordRecognized(SpeechKeywordRecognizedEventData eventData)
    {
        switch (eventData.RecognizedText.ToLower())
        {
            case "shoot down":
                OnShoot();
                break;
        }
    }
}

Eksportujemy jak zawsze do Visual Studio. Aha pamiętajmy o włączeniu mikrofonu w Capabilities. W tym celu wchodzimy w Edit > Project Settings > Player i na zakładce Windows Store szukamy sekcji Publishing Settings > Capabilities.

image

Odpalamy!

Wskazuję kursorem sześcian. Mówię “Shoot down”.

shot1

Buch! Teraz strzelam do kuli.

shot2

Po nakierowaniu wzroku (kursora) na kulę i wypowiedzeniu “Shoot down” również ona opada.

shot3

Jak chcemy zacząć zabawę od początku, zawsze możemy powiedzieć “Reset all”. Sześcian i kula wylądują z powrotem na swoich początkowych położeniach w powietrzu i znów będzie można sobie do nich postrzelać.

Życzę miłej zabawy i do zobaczenia w następnym odcinku.

poniedziałek, 13 marca 2017

[DSP2017] 5# Holowizja - strzał palcem

Witam ponownie w moich wizjach holograficznych. Na razie kontynuuję zaznajamianie się z platformą HoloLens. Dziś coś napiszę o gestach za pomocą dłoni.

Ze spraw poruszanych w rozdziale trzecim Holograms 101E: Introduction with Emulator oraz Holograms 211: Gesture póki co wybrałem sobie do sprawdzenia kursor z feedbackiem na pojawienie się dłoni oraz obsługę zdarzenia “air tap”. Podnosimy palec, zgłaszamy w ten sposób gotowość. Jeśli potem go opuścimy, to tak jakbyśmy kliknęli, tyle że w powietrzu. W jednej wersji HoloLens jest jeszcze clicker, by go używać zamiast ciągle swojego palca.

Możliwości w obsłudze gestów jest więcej. Można zdarzenie nawigacji wykorzystać do obracania przedmiotu za pomocą palca, czy też w ogóle śledzić dłonie i używać ich do manipulacji. HoloLens może też podpowiadać, kiedy nasze dłonie będą blisko wyjścia poza jego obszar obserwacji.

Za pomocą emulatora można zasymulować pojawienie się dłoni lewej i prawej z podaniem ich położenia:

EmulatorSettings

Naciśnięcie Enter oznacza “air tap”, a jeśli naciśniemy Alt i trzymajac prawy przycisk myszy zaczniemy przesuwać kursor, to nawet zdarzenie nawigacji/przewijania zasymulujemy i obrócimy sobie np. kosmonautę z Holograms 211. 

Holo akademia bazuje na elementach dość wczesnej wersji Holo Toolkit. W przykładzie podanym poniżej wypróbowałem najnowszą wersję toolkita pod kątem kursora i air tap.

Zacznijmy od kursora z feedbackiem. Chodzi o to, by po pojawieniu się dłoni kursor zmienił swoją postać np. na dłoń. Na scenie z sześcianem znanej z HoloVision3 poprzedni kursor zastąpiłem nowym z pliku CursorWithFeedback.prefab (Assets > HoloToolkit > Input > Prefabs > Cursor).

Teraz pora na obsługę “kliknięcia”. W tym celu w katalogu Scripts w Assets utworzyłem nowy skrypt C# o nazwie CubeCommands i przypiąłem do sześcianu. Kod skryptu przedstawia się następująco:

public class CubeCommands : MonoBehaviour, IInputClickHandler
{
    public void OnInputClicked(InputEventData eventData)
    {
        if (!this.GetComponent<Rigidbody>())
        {
            var rigidbody = gameObject.AddComponent<Rigidbody>();
            rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
        }
    }
}

Jak widzimy, zaimplementowałem metodę OnInputClicked z interfejsu IInputClickHandler. Jeśli obiekt nie miał poczucia grawitacji, czyli obiektu Rigidbody, to dodaję mu taki. Sześcian po zajściu takiego zdarzenia powinien spaść w dół (dla zmniejszenia zamieszania z kolorem wyrzuciłem poprzedni skrypt ustawiajacy kolor sześcianu na czerwony po objęciu go wzrokiem).

Odpalam i … nie działa. Szybko na logikę wywnioskowałem, że może potrzeba jakiegoś odniesienia, by sześcian miał na co spaść. I tak do sceny dołożyłem płaszczyznę, czyli obiekt typu Plane (Hierarchy: Create –> 3D Object –> Plane). Ustawiłem to nieco, by lepiej wyglądało w kamerze, sześcian też poprawiłem. Dla lepszego nastroju zmieniłem sobie światło na kolor niebieski. Dokładne ustawienia można odczytać sobie w Unity z tego projektu, pobierając go z gałęzi HoloVision4 na github.

Eksportuję once again do Visual Studio. Odpalam:

Schot1

Jak w ustawieniach emulatora pokażę lewą dłoń, to kursor zmieni się w dłoń. Taką postać też przyjmie podczas “klikania palcem”. Naciskam Enter i buch, szescian leci w dół!

Schot2

Hurra! 

Zamierzałem się jeszcze pobawić obracaniem sześcianu przy pomocy nowego Holo Toolkit, ale w jego plikach testowych i komponentach nie widzę dobrego przykładu na obsługę zdarzenia nawigacji/scrollowania. Ludzie pytają o to na forach, więc jest coś na rzeczy. Zawsze mogę użyć elementów bazujących na starszym toolkicie z akademii HoloLens, ale może znajdę działające rozwiązanie przy pomocy najnowszego API. Zobaczymy. Jak znajdę, na pewno o tym napiszę. A tymczasem do zobaczenia w następnym odcinku.

niedziela, 12 marca 2017

[DSP2017] 4# Holowizja - co się gapisz? uważaj, to coś znaczy

Jak komunikować się z hologramem w HoloLens? Jest kilka sposobów, wśród których można wymienić spojrzenie. I o nim dziś będzie mowa.

Holographic Academy znajdziemy o tym dwa tutoriale:  Holograms 101E: Introduction with Emulator i Holograms 210: Gaze. Pierwszy zawiera prosty przykład w rozdziale 2. Drugi tutorial we wszystkich swoich 6 częściach pokazuje bardziej zaawansowane przykłady. Jednak do jego rodziału trzeciego włącznie można jakoś obejść się bez fizycznego urządzenia i jest to bardziej zaawansowana realizacja tego, co już widzieliśmy w pierwszym tutorialu. Chodzi tutaj o wirtualny kursor, który po skierowaniu naszego wzroku na jakiś przedmiot zmieni wygląd i przyklei się do oglądanej płaszczyzny, a także o reakcję samego przedmiotu. I tym zajmiemy się dzisiaj.

Do bardziej zaawansowanych rzeczy z ostatnich trzech części drugiego tutoriala (przecinanie kierunkowe, ustawianie hologramu zawsze przodem do nas, czy podążanie za nami) może kiedyś wrócimy. Nie ma emulacji kierunku patrzenia, fizyczne urządzenie byłoby tutaj wskazane. Póki co, nie próbowałem odpalać na emulatorze.

Przykłady z akademii sobie odpaliłem, ogólnie super, działają (no może z wyjątkiem tego z pierwszego tutoriala, ale po zmianie kodu też poszedł). Aha, natrafiłem jeszcze na szkolenie Pluralsight zatytułowane HoloLens Development Fundamentals, które też mogę polecić. Tam są podstawy, ale zrealizowane w całości własnoręcznie, nawet kursor.

Czy jednak tworzenie - w sumie dość podstawowej rzeczy - jaką jest kursor i reakcja na spojrzenie - nie może być bardziej szybkie i proste? Może.  Przy pomocy HoloToolkit, a właściwie HoloToolkit-Unity, z którego dziś skorzystamy. Gwoli ścisłości, tutoriale z akademii i wspomniana kiedyś przeze mnie książka też używają pewnych elementów tego toolkitu, ale z początkowej, starej wersji. My dziś skorzystamy z najnowszej wersji, która różni się od tej początkowej dość istotnie. Upraszcza implementację i wprowadza infrastrukturę w postaci interfejsów. Dobrze opisuje to post Unity 5.5 and the HoloToolkit – Changes in Input when Developing HoloLens Apps. Generalnie jednak jakoś ta wiedza nie jest szeroko promowana…

Jak rozpocząć korzystanie z toolkitu w Unity?  Rzuciłem okiem na stronkę GetStarted, pobrałem gotową wersję i na kopii swojego projektu z sześcianem zaimportowałem pakiet HoloToolkit-Unity-v1.5.5.0.unitypackage do Unity (Assets -> Import Package -> Custom Package…). Jakich elementów użyć, by kursor nam działał i coś się działo na obiekcie?  Wobec braku dobrych tutoriali, znalazłem gdzieś na forum, że najlepiej sobie obejrzeć testowe sceny (po zaimportowaniu toolkitu w Assets > HoloToolkit > Input > Tests > Scenes), co też uczyniłem.

A teraz już do dzieła!

Czego potrzebujemy, by mieć kursor, który odpowiednio zachowa się na przedmiocie 3D?  Przeciągamy InputManager.prefab z Assets > HoloToolkit > Input > Prefabs do panelu Hierarchy.  Kursor wybieramy sobie z Assets > HoloToolkit > Input > Prefabs > Cursor. W naszym przypadku chcemy zmieniać jego postać po skrzyżowaniu naszego wzroku z przedmiotem i dobry będzie to tego Cursor.prefab. Przeciągamy go podobnie jak poprzednio do Hierarchy.

Projekt Unity eksportujemy tak jak w poprzednich postach do projektu Visual Studio i uruchamiamy na emulatorze (chyba że ma ktoś urządzenie). Gdy nie patrzymy na sześcian to kursor jawi się jako światełko:

CaptureC

Jak spojrzymy na sześcian, to kursor przybierze wygląd pierścienia przyległego do ściany:

CaptureD

Jak kierować spojrzeniem w emulatorze? Klikam i przeciągam myszą albo naciskam sobie klawisze strzałek na klawiaturze. Chodzenie to z kolei mogą być klawisze W, A, S i D. Wiecej o używaniu emulatora na stronie Using the HoloLens emulator.

A dlaczego nie zrobiłem póki co spoglądania na zielony, animowany szkielet, jaki mam w HoloVision2? Przymierzałem się, ale natrafiłem na kilka przeszkód. W inspektorze sześcianu na scenie jest coś takiego jak collider (tutaj box collider, są też inne rodzaje), automatycznie dodany. Bez elementu collider na modelu nie będą wykrywane kolizje i kursor będzie się zachowywać tak, jakby niczego tam nie było. W przypadku bardziej złożonych modeli możemy dodać do nich w inspektorze mesh collider otaczający wybrany mesh z modelu dokładnie takim jak on kształtem. Nie jest to jednak wydajne rozwiązanie, jeśli model animujemy. Collider typu mesh jest kosztowny w obliczeniach. Możemy wtedy dla poszczególnych części modelu poustawiać elementy collider (mesh czy bardziej wydajne jeśli nie stracimy dużo na kształcie - box, sphere czy capsule). Astronauta z akademii HoloLens jest tak właśnie zrobiony. O obiektach collider można poczytać w tutorialach z importu modeli do Unity czy książkach o tym środowisku. Okazuje się, że można nawet automatycznie próbować wygenerować collider-y za pomocą opcji Generate Colliders w inspektorze modelu z Assets. Na moim szkielecie nic się jednak samo nie wygenerowało. Mesh w tym modelu jest tylko jeden i dotyczy całej postaci w pozycji leżącej, jak ręcznie dodam do niego mesh collider to dotyczy on także pozycji leżącej, nawet jeśli szkielet stoi i jak trafię w collider to kursor może się zmienić, ale trzeba liczyć na łut szczęścia. Astronauta Microsoftu ma wiele elementów mesh w sobie, co ułatwia zdaje się tworzenie collider-ów dla poszczególnych części. Na razie temat zostawiam, może do niego wrócę za jakiś czas, zobaczymy.

Teraz reakcja obiektu na spojrzenie. Można stworzyć w Assets Unity własny skrypt w C# (prawy przycisk –> Create –> C# script), edytować go w Visual Studio poprzez podwójne kliknięcie i potem podpiąć do obiektu na scenie poprzez przeciągnięcie na jego zakładkę Inspector (albo od razu przez Add Component w inspektorze). Ja poszedłem jeszcze bardziej na skróty i podpiąłem skrypt FocusedObjectColorChanger z testów toolkita (Assets > HoloToolkit > Input > Tests > Scripts).

CaptureA

Jak nazwa wskazuje ustawia kolor obiektu na wskazany, jeśli spojrzymy na niego.  Oto kod:

   [RequireComponent(typeof(Renderer))]
   public class FocusedObjectColorChanger : MonoBehaviour, IFocusable
   {
       [Tooltip("Object color changes to this when focused.")]
       public Color FocusedColor = Color.red;

       private Color originalColor;
       private Material cachedMaterial;

       private void Awake()
       {
           cachedMaterial = GetComponent<Renderer>().material;
           originalColor = cachedMaterial.GetColor("_Color");
       }

       public void OnFocusEnter()
       {
           cachedMaterial.SetColor("_Color", FocusedColor);
       }

       public void OnFocusExit()
       {
           cachedMaterial.SetColor("_Color", originalColor);
       }

       private void OnDestroy()
       {
           DestroyImmediate(cachedMaterial);
       }
   }

Widzimy dość prostą klasę C#, która standardowo w przypadku skryptów dziedziczy po MonoBehaviour, a w przypadku obsługi focusa ze spojrzenia i w nowym HoloToolkicie dodatkowo implementuje interfejs IFocusable. Efekt działania prezentuję poniżej:

CaptureB

W przykładach toolkitu widziałem jeszcze skrypt GazeResponder, który podświetla materiał (trochę podobnie jak w przypadku astronauty w akademii HoloLens).

Dzisiejszy przykład udostępniłem na github jako HoloVision3.

Zabawa z HoloLens trwa nadal. Do zobaczenia w następnym odcinku.

środa, 8 marca 2017

[DSP2017] 3# Holowizja - Tańczący szkielet

Witam serdecznie. Ostatnio prezentowałem sześcian, dziś zrobimy coś nieco bardziej wyrafinowanego, choć nadal bez jednej linijki w C#. Będzie to ruszający się szkielet w zielonym świetle.

Na początku potrzebujemy model 3D, najlepiej w dość uniwersalnym formacie FBX. W sieci można znaleźć całkiem sporo darmowych i płatnych modeli. Unity oferuje je poprzez Asset Store. Inne przykładowe strony to:  http://tf3dm.com/, https://www.cgtrader.com/, https://www.turbosquid.com/. Na potrzebę dzisiejszej wizji wybrałem model Skeleton - PBR - Animated - Low Poly.

Mamy model, rozpakowujemy. Dostajemy zbiór plików, w tym pliki .FBX z nieruchomym szkieletem i różne jego animacje, a także tekstury czy coś takiego jak “normal map”. Jak zaimportować to do Unity?  Generalnie polega to na tym, że przeciągamy plik .FBX do folderu Assets w projekcie (jak poniżej), ale to nie wszystko. Jak przeciągniemy z Assets nasz model na scenę, to zobaczymy, że nie ma załadowanych tekstur i się nie rusza (jeśli zaimportowaliśmy model z animacją). W osiągnięciu pożądanego celu pomogło mi obejrzenie trzech filmików szkoleniowych na YouTube: 17 Unity: Importing FBX Files, Unity Tutorial #3 - Importing FBX assets in Unity, How to Import and Animate FBX file on Unity 5. Ostatni jest najlepszy.

Naładowani pewną dawką wiedzy, przystępujemy do dzieła. Na początek uporządkujmy nieco foldery w Assets. Tworzę foldery Characters, Skeleton, Animations, Scenes i Textures. Do Characters/Skeleton wrzuciłem nieruchomy szkielet i folder Materials, do Animations animowany szkielet, do Scenes plik sceny powstały z jej zapisania, do Textures pliki z Unity5_MetalRough_Texs w modelu. Do Materials dorzuciłem plik z NormalMap w modelu (powinien być oznaczony w zakładce Inspector jako normal map, o czym przypomni w odpowiednim momencie samo Unity i to zrobi).

image

image

Konfiguruję zaznaczony materiał.

image

W zakładce Inspector wybrałem shader Bumped Diffuse, a następnie wybrałem odpowiednie pliki graficzne za pomocą przycisków Select.

image

Model na scenie nabrał kolorów, ale jest za duży jak na HoloLens. W inspektorze w sekcji Model ustawiam skalę na 0.3 (można to zrobić przed importem do Visual Studio i do HoloLens). Aha, wcześniej ustawiłem jego pozycję na scenie na 0, –0.1, 2.5 i rotację Y na 180 (jak w poprzednim poście), a światło na scenie zrobiłem sobie zielone z większą intensywnością i nieco je przesunąłem.

image

Szkielet jednak nadal się nie rusza na poglądzie “gry”, a na dole w inspektorze animowanego modelu można znaleźć sekcję, w której można obejrzeć sobie jego ruchy.

image

W Assets wybieram Create, a następnie Animator Controller. Nadaję mu odpowiednią nazwę (u mnie AC Skeleton).

image

Przeciągam stworzy kontroler animacji na pole Controller w sekcji Animator w inspektorze modelu na scenie.

image

Przeciągam składową Take 001 z animowanego modelu w Assets na schemat kontrolera animacji. Pojawia się pomarańczowy element Take 001 połączony z blokiem Entry.

image

Teraz jak puszczę podgląd sceny, to szkielet się rusza, ale zatrzymuje się po jakimś czasie. Co zrobić, by ruszał się ciągle? W inspektorze animowanego modelu w Assets znajdujemy sekcję Take 001 i zaznaczamy check Loop Time.

image

Całość eksportuję z Unity do Visual Studio analogicznie jak w poprzednim poście. W emulatorze HoloLens mogę zaobserwować taniec zielonego szkieletu:

image

Źródła dzisiejszego projektu można znaleźć na github w folderze HoloVision2.

To tyle na dziś. Import animowanego modelu 3D do Unity mamy za sobą. W najbliższym czasie zaczniemy badać funkcjonalności specyficzne dla HoloLens.

sobota, 4 marca 2017

[DSP2017] 2# Holowizja - Holo World

By pisać na HoloLens od czegoś trzeba zacząć. Nie od razu Kraków zbudowano. Na pierwszy ogień poszło coś w stylu holistycznego Hello World aka Holo World, czyli sześcian jaki powinien pojawić się przed naszym nosem po założeniu okularów.

Na początek narzędzia. Nowe Unity nie wymaga dedykowanej wersji dla HoloLens jak kiedyś. Co do Visual Studio, potrzebna jest wersja 2015 najlepiej z Update 3. Na mojej maszynie zdarzyło się, że emulator HoloLens na początku nie chciał działać. Odinstalowałem Hyper-V i na nowo zainstalowałem, potem to samo uczyniłem z emulatorem i poszło.

Teraz kilka absolutnych podstaw. Tworzymy projekt 3D w Unity (Unity nie jest wymagane, ale jest preferowanym środowiskiem, w którym najłatwiej tworzyć dla HoloLens).

  • Główną kamerę pozycjonujemy na 0, 0, 0
  • Clear Flags ustawiamy na Solid Color, a tło na kolor czarny, który w Holo Lens będzie interpretowany jako przezroczysty (czyli realne otoczenie)
  • Clipping Planes kamery zmieniamy na 0.85
  • W Hierarchy przez Create tworzymy sześcian, zmieniamy jego pozycję, rotacje i skalę (skalę na 0.25 by się nam zmieścił po założeniu okularów) i zapisujemy scenę w menu File.
  • Testowo możemy sobie odpalić nasz filmik za pomocą przycisku odtwarzania u góry (na razie nic się szczególnego nie dzieje, nieruchomy sześcian)

To streszczenie 3 pierwszych “rozdziałów” z pierwszego tutoriala Holograms 100: Getting started with Unity z Holographic Academy Microsoft, która jak najbardziej wydaje sie godna polecenia.  Sześcian po sam początek jest najlepszy, dobrze na nim widać efekty zmian pozycjonowania i rotacji wzdłuż trzech osi.

image

Mamy już projekt w Unity, teraz wyeksportujmy go do Visual Studio. W końcu przecież mamy doczynienia z odmianą, co prawda dość wyjątkową, aplikacji uniwersalnej na Windows 10. Wykonujemy kilka kroków, które dobrze opisane są w rozdziale 4 z Holograms 100: Getting started with Unit. Jedynie nie zmieniałem MaxVersionTested na wartość z tutoriala (u mnie wygenerowała się wersja emulatora, czyli 10.0.14393.0)

image

Póki co nie piszemy ani linijki kodu. Ustawiamy całość na Release, x86 i wybieramy HoloLens Emulator (chyba że ma ktoś fizyczne urządzenie). Uruchamiamy bez debugowania. Najpierw oczywiście wstaje Windows na emulatorze okularów, potem pojawia się na chwilę ekran startowy naszej aplikacji z logiem Unity (na potrzeby edukacji nie przeszkadza), a potem dostajemy już poniższy widok:

image

Pierwsze Holo World za nami. Mam pewną wizję wizji, którą chciałbym docelowo sobie stworzyć, ale w najbliższym czasie dalej będę eksperymentować z tym, co oferuje HoloLens.

Aha, źródła trafiają na https://github.com/MarcinKruszynski/HoloVision. Dzisiejsza próba to HoloVision1.

Uwaga, wyczaiłem moim zdaniem całkiem niezłą książkę na temat HoloLens o tytule “Develop Microsoft HoloLens Apps Now”.

9781484222010

To tyle na dziś, widzimy się w następnym odcinku, czy też bardziej poście –Smile

czwartek, 2 marca 2017

[DSP2017] 1# Holowizja - intro

Inicjatywa http://dajsiepoznac.pl wydaje się jedyna w swoim rodzaju. To coś jakby na wzór przeglądu kapeli muzyki alternatywnej, gdzie każdy pomysł czy technologia, nawet coś najbardziej odjechanego jest w zasadzie możliwe.  Ostatnio trochę nie pisywałem, ale to właśnie dlatego by nabrać trochę sił przed startem.

Tegoroczny pomysł kontynuuje rozrywkowe podejście z roku ubiegłego, ale w innej materii. O ile poprzednio były to aplikacje mobilne, o tyle teraz też będę mobilne, ale holograficzne !!!  Dodam, że  póki co nie posiadam magicznych okularów za 12 koła, ale to może i lepiej dla DSP, bo będę odbywał holograficzną wędrówkę tak jak każdy z nas. Może uda się nieco odczarować dużą tajemniczość i małą popularność holograficznej wersji Windows 10. Pokażemy co się za tym kryje i jaką wiedzę, narzędzia z innych bardziej znanych nam dziedzin można tutaj wykorzystać.

Oderwijmy się od codzienności i odlećmy!  Po godzinach zróbmy coś dla fanu i dobrej zabawy, coś diametralnie zgoła innego. Załóżmy magiczne okulary (nawet ich nie mając) i do dzieła. Każda wizja powstała w głowie może się przed nami zwizualizować, niczym we śnie, halucynacji, grze czy bajce. Jak choćby inwazja dużych pająków w naszym pokoju…

HoloLens2

Czy to nie jest wspaniałe, móc widzieć to czego nie ma?  Słyszeć to, czego nie słychać?  Co więcej, kilka osób może współdzielić te halucynacje…

Hololens-Teomirn-fortepian

czy nawet się stać duchami, zjawami, ewentualnie zombi dzięki holoportacji…

holoportation-demo

Dodam, że HoloLens może służyć nie tylko do rozrywki, ba może rozrywkowe zastosowania nie stanowią tu nawet większości zastosowań…

Jako że generalnie jestem od zawsze związany z szeroko rozumianą platformą .NET, również i tutaj będzie C#, tyle że stosowany ze środowiskiem Unity, z którym wcześniej nie miałem doczynienia. Ale może to i lepiej, bo będzie więcej edukacji na łamach DSP i całość może okazać się bardziej przystępna niż ostatnio.  Niewykluczone, że dodatkowo w którymś momencie sięgnę po narzędzie Maya czy 3ds Max znane z czasów studiów, a wtedy wyrenderowałem sobie filmik z pochodem szkieletów we mgle (czy może smogu?) przy przygnębiającym żółtym świetle latarni ulicznych… 

Nie zamykam się wyłącznie na platfomę .NET czy C#. W zeszłym roku były u mnie  Java i Swift, niewykluczone że w tym roku odjadę jeszcze bardziej także i na tym polu. Nie wiem czy dam radę od razu w ramach samego projektu w tych ramach czasowych, ale dzięki tegorocznej formule DSP może pojawią się jakieś luźniejsze posty na temat Pythona czy R.  Języki te są obecnie bardzo istotne dla uczenia maszynowego, w nich powstaje najwięcej frameworków i bibliotek związanych z tą dziedziną. Zawsze przecież nasze holograficzne monstrum może się uczyć i próbować wyciągać wnioski z otaczającego nas świata!