Systemy wirtualnej rzeczywistości. Komponenty i serwisy



Podobne dokumenty
Systemy wirtualnej rzeczywistości. Podstawy grafiki 3D

Systemy wirtualnej rzeczywistości. Sterowanie i wykrywanie kolizji

Rozdział 4 Komponenty gry na przykładzie prostopadłościanu

Programowanie telefonów z Windows Phone 7, cz. 3

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Programowanie obiektowe

Programowanie obiektowe

Politechnika Poznańska, Instytut Informatyki, SUM-TWO

Unity 2D - prosta gra

xmlns:prism= c. <ContentControl prism:regionmanager.regionname="mainregion" />

Przykładowa dostępna aplikacja w Visual Studio - krok po kroku

Klasy i obiekty cz II

Część XVII C++ Funkcje. Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład.

Programowanie obiektowe

WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM. NetBeans. Wykonał: Jacek Ventzke informatyka sem.

Ciekawym rozwiązaniem służącym do obsługi zdarzeń dla kilku przycisków w ramach jednej aktywności może być następujący kod:

Wykład 8: klasy cz. 4

Klasy i obiekty cz I Klasy, obiekty, podstawy używania obiektów

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Projekt Hurtownia, realizacja skojarzeń dostawców i produktów

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

Studia Podyplomowe Grafika Komputerowa i Techniki Multimedialne, 2017, semestr II Modelowanie 3D - Podstawy druku 3D. Ćwiczenie nr 4.

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

Druga aplikacja Prymitywy, alpha blending, obracanie bitmap oraz mały zestaw przydatnych funkcji wyświetlających własnej roboty.

1. Prymitywy graficzne

Aplikacje WWW - laboratorium

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Architektura interfejsu użytkownika

1 LINQ. Zaawansowane programowanie internetowe Instrukcja nr 1

Skalowanie i ustawianie arkuszy/układów wydruku w AutoCAD autor: M. Motylewicz, 2012

Wykład 4: Klasy i Metody

Gry Komputerowe Laboratorium 4. Teksturowanie Kolizje obiektów z otoczeniem. mgr inż. Michał Chwesiuk 1/29. Szczecin, r

Programowanie obiektowe

Kurs WWW. Paweł Rajba.

Programowanie komputerowe. Zajęcia 7

PHP: bloki kodu, tablice, obiekty i formularze

Zad. 6: Sterowanie robotem mobilnym

Java: otwórz okienko. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Temat: Transformacje 3D

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Język C++ zajęcia nr 2

Dynamiczne i wydajne tworzenie interfejsu. Piotr Michałkiewicz

Informatyka II. Laboratorium Aplikacja okienkowa

Programowanie strukturalne i obiektowe. Funkcje

Lab 9 Podstawy Programowania

Rozdział 4 KLASY, OBIEKTY, METODY

Unity 3D - podpowiedzi w grze. System cząstek

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

2) W wyświetlonym oknie należy zaznaczyć chęć utworzenia nowej aplikacji (wygląd okna może się różnić od powyższego); kliknąć OK

Podstawy Swing. Tomasz Borzyszkowski

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 6. Karol Tarnowski A-1 p.

Wstęp. Ale po co? Implementacja

Programowanie obiektowe

Tworzenie własnych komponentów

Operator przypisania. Jest czym innym niż konstruktor kopiujący!

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Usługi Informatyczne "SZANSA" - Gabriela Ciszyńska-Matuszek ul. Świerkowa 25, Bielsko-Biała

Mechanizm dziedziczenia

grafika 2D i animacja obsługa rotacji i elementy 3D-OpenGL w Androidzie

Modelowanie rynków finansowych z wykorzystaniem pakietu R

Rysunek 1: Okno timeline wykorzystywane do tworzenia animacji.

GLKit. Wykład 10. Programowanie aplikacji mobilnych na urządzenia Apple (IOS i ObjectiveC) #import "Fraction.h" #import <stdio.h>

Programowanie obiektowe

PARADYGMATY PROGRAMOWANIA Wykład 4

Ćwiczenie 14 Dmuchawce

Wprowadzenie w dziedziczenie. Klasa D dziedziczy klasę B: Klasa B klasa bazowa (base class), klasa D klasa pochodna (derived class).

Programowanie i struktury danych

Laboratorium Systemów Informacji Przestrzennej. Korzystanie z zewnętrznych usług geokodowania i nawigacji w środowisku OpenLayers

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Wykład 5 Okna MDI i SDI, dziedziczenie

Programowanie obiektowe

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

6.4. Efekty specjalne

Rys Odtwarzacz filmu. Możemy także skorzystać z programów służących do odtwarzania filmów np. Windows Media Player.

Języki i techniki programowania Ćwiczenia 2

dr Artur Bartoszewski dr Artur Bartoszewski - Aplikacje mobilne - Wykład

Zaawansowane programowanie w C++ (PCP)

Definiowanie własnych klas

WASM AppInventor Lab 3. Rysowanie i animacja po kanwie PODSTAWY PRACY Z KANWAMI

Grafika Komputerowa Materiały Laboratoryjne

Laboratorium 1. Część I. Podstawy biblioteki graficznej OpenGL.

Programowanie Obiektowe Ćwiczenie 4

Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

LABORATORIUM 7 Cel: 1_1

Interfejsy i klasy wewnętrzne

Unity 3D - własny ekran startowy i menu gry

Programowanie obiektowe Wykład 7. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/20

Laboratorium 7 Blog: dodawanie i edycja wpisów

Podstawy i języki programowania

VBA praca z makrami w Excelu

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

- Narzędzie Windows Forms. - Przykładowe aplikacje. Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Sieciowe Technologie Mobilne. Laboratorium 2

Materiały do laboratorium MS ACCESS BASIC

Transkrypt:

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych Systemy wirtualnej rzeczywistości Laboratorium Komponenty i serwisy Wstęp: W trzeciej części przedstawione zostaną podstawowe techniki obsługi modeli 3D oraz komponentowy sposób tworzenia aplikacji. Zaprezentowane zostaną wbudowane mechanizmy komponentów (GameComponent) i serisów (Services). 1. Wczytanie modelu XNA posiada wygodną klasę do reprezentacji modeli 3D, które mogą się składać z wielu siatek, z przypisanymi wieloma materiałami, efektami, animacjami oraz hierarchią. Posiada również gotowe importery z plików X oraz FBX. Postępując analogicznie do ładowania tekstury trawy załadujemy teraz model czołgu (czolg.fbx). Tworzymy obiekt typu Model: Model czolg; Dodajemy plik czolg.fbx do projektu i w LoadContent wczytujemy go do zmiennej czolg. czolg = Content.Load<Model>("czolg"); 2. Rysowanie modelu Przechodzimy do metody Draw. Poniżej kodu rysowania terenu umieścimy kod rysowania modelu czołgu. Model ten składa się z dwóch siatek ( korpus i wiezyczka ). Każda siatka ma przypisany własny zestaw efektów. W naszym przypadku wszystkie siatki będą miały po jednym efekcie, ale utworzymy pętlę dla przypadku, w którym miałyby ich więcej. W pierwszym kroku tworzymy tablice transformacji, która zawiera transformacje dla każdej siatki. Jeśli nie uwzględnimy tych transformacji poszczególne siatki będą rysowane w początku lokalnego układu współrzędnych modelu zamiast w odpowiednim dla siebie 1

miejscu. Następnie ustawiamy macierze świata, widoku i projekcji dla każdego efektu każdej siatki wczytanego modelu. Macierze widoku i projekcji pozostawiamy bez zmian, natomiast macierzy świata przypisujemy wartości pobrane przed chwilą do tablicy. Dodatkowo wymnożymy je przez macierz skalowania ponieważ wczytany model jest zdecydowanie za duży względem naszego terenu. Użyjemy współczynnika skalowania równego 0.07. Ponieważ nie wprowadziliśmy żadnego oświetlenia dodatkowo włączymy oświetlenie domyślne poprzez metodę EnableDefaultLighting. Na samym końcu rysujemy model metodą Draw dla każdej siatki. Matrix[] transformacje = new Matrix[czolg.Bones.Count]; czolg.copyabsolutebonetransformsto(transformacje); foreach (ModelMesh mesh in czolg.meshes) foreach (BasicEffect effect in mesh.effects) effect.enabledefaultlighting(); effect.view = widok; effect.projection = projekcja; effect.world = transformacje[mesh.parentbone.index] * Matrix.CreateScale(0.07f); mesh.draw(); Wynikiem powinien być obraz jak na rys. 1. Rys. 1 - Model czołgu 2

3. Komponenty i serwisy Nadszedł czas na uporządkowanie kodu. Stworzymy trzy komponenty reprezentujące odpowiednio kamerę, teren i gracza. Wykorzystamy do tego wbudowany mechanizm obsługi komponentów. Komponent jest reprezentowany przez klasę GameComponent (lub DrawableGameComponent w przypadku gdy komponent będzie rysowany). Łatwo można zauważyć, że część komponentów będzie wymagać dostępu do innych komponentów lub zmiennych z klasy głównej. Przykładem może tu być komponent terenu, który będzie potrzebował dostępu do komponentu kamery w celu prawidłowego ustawienia macierzy widoku. Eleganckim rozwiązaniem tego problemu są serwisy (Services). Umożliwiają one udostępnienie potrzebnych obiektów dowolnym komponentom. Praktyczne działanie komponentów i serwisów zostanie przedstawione poniżej. 3.1 Kamera Pierwszym komponentem będzie kamera. Tworzymy nowy komponent (Add->New Item..., wybieramy Game Component i nadajemy mu odpowiednią nazwę). W klasie kamery będziemy przechowywać informacje o jej położeniu i punkcie, na który jest zwrócona oraz parametry projekcji. Deklarujemy odpowiednie zmienne: Vector3 pozycja; Vector3 cel; float polewidzenia; float proporcjeobrazu; float bliskaplaszczyzna; float dalekaplaszczyzna; Następnie dodajemy właściwości do pobierania i ustawiania pozycji i celu: public Vector3 Pozycja get return pozycja; set pozycja = value; public Vector3 Cel get return cel; set cel = value; Udostępniamy macierz projekcji, korzystając z metody CreatePerspectiveFieldOfView klasy Matrix: 3

public Matrix Projekcja get return Matrix.CreatePerspectiveFieldOfView(poleWidzenia, proporcjeobrazu, bliskaplaszczyzna, dalekaplaszczyzna); Udostępniamy macierz widoku, korzystając z metody CreatLookAt: public Matrix Widok get return Matrix.CreateLookAt(pozycja, cel, Vector3.Up); Na koniec dodamy metodę do wprowadzenia parametrów projekcji: public void UstawProjekcje(float polewidzenia, float proporcjeobrazu, float bliskaplaszczyzna, float dalekaplaszczyzna) this.polewidzenia = polewidzenia; this.proporcjeobrazu = proporcjeobrazu; this.bliskaplaszczyzna = bliskaplaszczyzna; this.dalekaplaszczyzna = dalekaplaszczyzna; 3.2 Teren Następnym komponentem będzie Teren. Większość potrzebnego kodu jest już napisana. Tworzymy zatem nowy komponent i nadajemy mu odpowiednią nazwę. W przeciwieństwie do kamery teren będzie rysowany więc zmieniamy dziedziczenie z GameComponent na DrawableGameComponent. Deklarujemy potrzebne zmienne: VertexBuffer wierzcholki; IndexBuffer indeksy; BasicEffect basiceffect; Texture2D tekstura; Następnie tworzymy konstruktor, w którym wywołujemy metodę StworzTeren i ustawiamy parametry efektu (do tego będziemy potrzebowali urządzenie renderujące, do którego odwołujemy się poprzez Services później stworzymy ten serwis w klasie głównej) i tekstury: 4

public Teren(Game game, Texture2D tekstura, float rozmiar, float rozmiartekstury) : base(game) this.tekstura = tekstura; StworzTeren(rozmiar, rozmiartekstury); GraphicsDevice urzadzenie = (GraphicsDevice)Game.Services.GetService(typeof(GraphicsDevice)); basiceffect = new BasicEffect(urzadzenie, null); basiceffect.textureenabled = true; basiceffect.texture = tekstura; Przenosimy metodę StworzTeren z klasy głównej do klasy Teren. Dodajemy odwołanie do urządzenia poprzez serwis. Ponadto tym razem metoda pobiera dwa parametry (skala i skalatekstury) oraz nastąpiła drobna zmiana nazw buforów (z terenwierzcholki na wierzcholki oraz z terenindeksy na indeksy). Na koniec musimy zadbać o rysowanie terenu. Tutaj również wykorzystamy gotowy już kod, lekko go modyfikując. Ponownie odwołujemy się do serwisów. W tym przypadku odwołamy się również do kamery aby rysować teren z uwzględnieniem położenia kamery. public override void Draw(GameTime gametime) GraphicsDevice urzadzenie = (GraphicsDevice)Game.Services.GetService(typeof(GraphicsDevice)); Kamera kamera = (Kamera)Game.Services.GetService(typeof(Kamera)); basiceffect.projection = kamera.projekcja; basiceffect.view = kamera.widok; basiceffect.world = Matrix.Identity; basiceffect.begin(); urzadzenie.vertexdeclaration = new VertexDeclaration(urzadzenie, VertexPositionTexture.VertexElements); urzadzenie.vertices[0].setsource(wierzcholki, 0, VertexPositionTexture.SizeInBytes); urzadzenie.indices = indeksy; basiceffect.techniques[0].passes[0].begin(); urzadzenie.drawindexedprimitives(primitivetype.trianglelist, 0, 0, 4, 0, 2); basiceffect.techniques[0].passes[0].end(); basiceffect.end(); base.draw(gametime); 5

3.3 Gracz Ostatnim komponentem będzie Gracz. Tworzymy zatem komponent i deklarujemy odpowiednie zmienne. W przyszłości będziemy chcieli sterować czołgiem dlatego dodamy również zmienne opisujące rotację korpusu czołgu i jego wieżyczki. Poza tym stworzymy właściwości dla pozycji i rotacji: Vector3 pozycja; float rozmiar; float rotacjakorpusu; float rotacjawiezyczki; Model model; public Vector3 Pozycja get return pozycja; set pozycja = value; public float Rotacja get return rotacjakorpusu; Następnie tworzymy konstruktor: public Gracz(Game game, Model model, float rozmiar) : base(game) this.model = model; this.rozmiar = rozmiar; Dodajemy metodę do ustawiania rotacji czołgu i wieżyczki: public void UstawRotacje(float rotacjakorpusu, float rotacjawiezyczki) this.rotacjakorpusu = rotacjakorpusu; this.rotacjawiezyczki = rotacjawiezyczki; Na koniec dodajemy rysowanie czołgu. Również tutaj wykorzystamy napisany już kod wprowadzając jedynie drobne zmiany analogiczne do rysowania terenu. Jedyna poważna zmiana polega na uwzględnieniu położenia i rotacji gracza względem globalnego układu współrzędnych oraz obliczaniu dodatkowej transformacji dla siatki wieżyczki. Umożliwi nam to obracanie jej niezależnie od korpusu. 6

public override void Draw(GameTime gametime) GraphicsDevice urzadzenie = (GraphicsDevice)Game.Services.GetService(typeof(GraphicsDevice)); Kamera kamera = (Kamera)Game.Services.GetService(typeof(Kamera)); Matrix[] transformacje = new Matrix[model.Bones.Count]; model.copyabsolutebonetransformsto(transformacje); foreach (ModelMesh mesh in model.meshes) Matrix swiat = Matrix.CreateScale(rozmiar) * Matrix.CreateRotationY(rotacjaKorpusu) * Matrix.CreateTranslation(pozycja); if (mesh.name == "korpus") swiat = transformacje[mesh.parentbone.index] * swiat; if (mesh.name == "wiezyczka") swiat = Matrix.CreateRotationZ(rotacjaWiezyczki) * transformacje[mesh.parentbone.index] * swiat; foreach (BasicEffect effect in mesh.effects) effect.enabledefaultlighting(); effect.projection = kamera.projekcja; effect.view = kamera.widok; effect.world = swiat; mesh.draw(); base.draw(gametime); 3.4 Zmiany w klasie głównej Pozostało jedynie zaktualizować klasę główną. Zaczniemy od deklaracji nowoutworzonych komponentów: Kamera kamera; Teren teren; Gracz gracz; Przejdźmy do LoadContent. Pierwszą zmianą jaką tu wprowadzimy będzie dodanie serwisu udostępniającego urządzenie renderujące. Wczytywanie tekstury trawy i modelu czołgu pozostawimy bez zmian. protected override void LoadContent() spritebatch = new SpriteBatch(GraphicsDevice); 7

trawa = Content.Load<Texture2D>("trawa"); czolg = Content.Load<Model>("czolg"); Services.AddService(typeof(GraphicsDevice), graphics.graphicsdevice); Następnie tworzymy kamerę, dodajmy ją do listy komponentów i udostępnijmy ją jako serwis: kamera = new Kamera(this); kamera.ustawprojekcje(mathhelper.toradians(50), graphics.graphicsdevice.viewport.aspectratio, 0.1f, 1000.0f); kamera.pozycja = new Vector3(13.0f, 15.0f, 8.0f); Services.AddService(typeof(Kamera), kamera); Components.Add(kamera); Tworzymy teren i również dodajemy go do listy komponentów: teren = new Teren(this, trawa, 10.0f, 10.0f); Components.Add(teren); Ostatnim komponentem, który dodamy jest Gracz. Na koniec skierujemy kamerę na czołg ustawiając współrzędne czołgu jako celu kamery. gracz = new Gracz(this, czolg, 0.02f); gracz.pozycja = new Vector3(5.0f, 0.0f, -3.0f); gracz.ustawrotacje(0.0f, 0.0f); Components.Add(gracz); kamera.cel = gracz.pozycja; Usuwamy wcześniej dodaną zawartość metody Draw. Dzięki temu, że dodaliśmy nasze komponenty do listy komponentów nie musimy umieszczać w metodzie Draw żadnych dodatkowych odwołań do metod rysujących. Polecenie base.draw(gametime) spowoduje wywołanie metod Draw wszystkich komponentów na liście. protected override void Draw(GameTime gametime) graphics.graphicsdevice.clear(color.cornflowerblue); base.draw(gametime); 8

Wynikiem uruchomienia aplikacji powinien być obraz jak na rys. 2. Rys. 2 - Działająca aplikacja 9