![]() |
C/C++ & Visual C++Kurz DirectX (33.) |
┌vodem | DatovΘ struktury | Kurz DirectX | Downloads | Otßzky a odpov∞di |
|
V dneÜnφ lekci vylepÜφme kameru, p°idßme re₧im, kdy se kamera bude pohybovat po p°edem definovanΘ cest∞. Dßle p°idßme n∞kolik metod do t°φdy XDisplay starajφcφ se o mlhu. 33.1. Pohyb kameryDo te∩ byl pohyb kamery zajiÜt∞n pouze pomocφ interaktivnφho ovlßdßnφ, kterΘ vy₧adovalo vstup z klßvesnice. V dneÜnφ lekci p°idßme do kamery neinteraktivnφ re₧im, kdy pohyb kamery bude °φzen automaticky. Abychom pohyb jednoznaΦn∞ urΦili, jsou t°eba t°i zßkladnφ informace: poloha kamery, sm∞r a Φas, kdy se v tΘto konfiguraci kamera nachßzφ. Soubor cesty V²Üe uvedeny informace budou ulo₧eny v souboru path.txt, kter² bude mφt nßsledujφcφ formßt: Na ka₧dΘm °ßdku tedy bude jedna klφΦovß hodnoty polohy kamery. Mezi dv∞ma polohami se bude plynule interpolovat. Soubor budeme Φφst po °ßdcφch, jednotlivΘ °ßdky rozklßdat do jednotliv²ch polo₧ek pomocφ odd∞lovaΦe (zde st°ednφk). Struktura PathSegment Z tΘto struktury postavφme spojov² seznam vÜech segment∙ naΦten²ch ze souboru. struct PathSegment PathSegment *pNext; Struktura uchovßvß vÜechny parametry kamery a navφc jeÜt∞ ukazatel na nßslednφka a p°edch∙dce ve spojovΘm seznamu. ╪et∞z bude vypadat nßsledovn∞:
Nynφ upravφme t°φdu XCamera. Za prvΘ p°idßme n∞kolik Φlensk²ch prom∞nn²ch: // Cela path (1) // Rezim kamery (6) 1) Ukazatel na prvnφ segment spojovΘho seznamu cesty enum PATHSTATUS 5) Modifikßtor rychlosti pohybu. Implicitn∞ je roven 1.0 (Φas v souboru path odpovφdß skuteΦnosti). enum CAMERAMODE 7) Informace o tom, zda je cesta naΦtena ze souboru. Nejd°φve je pochopiteln∞ nutno soubor path naΦφst a teprve pak je mo₧no spustit vlastnφ pohyb. virtual HRESULT LoadPath(LPCSTR szPath); (1) float ExtractNumber(int i, char *line); (7) 1) Metoda naΦte soubor path a vytvo°φ spojov² seznam popsan² v²Üe. Nakonec p°ipravφ kameru pro spuÜt∞nφ interpolace. Nynφ vÜechny tyto metody naimplementujeme. Nejslo₧it∞jÜφ metoda je LoadPath(), kterß vyu₧φvß metodu ExtractNumber(). ZaΦneme tedy od tΘto metody: float XCamera::ExtractNumber(int i, char *line) for(int u = 0; u < i; u++) // Find first ; Mo₧nß nenφ na prvnφ pohled vid∞t, co tato metoda vlastn∞ d∞lß. P°ijφmß dva parametry: celΘ Φφslo jako po°adφ Φφsla, kterΘ chceme extrahovat a °et∞zec °ßdky ze souboru path. Z tohoto °et∞zce je vybrßno Φφslo podle parametru i, potΘ se p°evede na float, kter² je vrßcen. V prvnφ smyΦce tedy p°eskßΦeme vÜechny Φφsla p°ed po₧adovan²m. Funkce strspn() vracφ index v²skytu odd∞lovaΦe. Tuto hodnotu ve vstupnφm °et∞zci p°eskoΦφm a to opakujeme tak dlouho a₧ se dostaneme p°ed po₧adovanΘ Φφslo. V dalÜφ Φßsti se pou₧ije stejn² postup na zkopφrovßnφ Φßsti vstupu do pomocnΘ prom∞nnΘ number, kter² jeÜt∞ zakonΦφme znakem '\0' a nakonec p°evedeme funkci atof() na float. Metoda LoadPath() naΦte ze souboru cestu a vytvo°φ spojov² seznam. HRESULT XCamera::LoadPath(LPCSTR szPath) char szFullPath[MAX_PATH]; V prvnφ Φßsti naΦteme soubor pomocφ funkce cmnLoadFileFromPath(). Tato funkce je v knihovn∞ common.dll. Proto₧e nevφme velikost souboru, nejprve zavolßme funkci s hodnotou NULL. Takto nßm vrßtφ velikost bufferu, kter² musφme alokovat pro soubor. V druhΘm volßnφ ji₧ pou₧ijeme buffer file. Funkce cmnGetDataFilePath() je op∞t z knihovny common.dll a pouze spojφ cestu spuÜt∞nΘho programu a zadanΘho souboru, tφm vytvo°φ ·plnou cestu k souboru cesty. Na zßv∞r tΘto Φßsti vyma₧eme p°edchozφ cestu, pokud takovß existuje. pfile je ukazatel stejn∞ jako file, ale s pfile budeme pozd∞ji h²bat. file nesmφme zm∞nit, proto₧e ho nakonec budeme dealokovat. while(pfile[0] != '\0') D3DXVec3Normalize(&ps.vDir, &ps.vDir);
V poslednφ Φßsti p°ipravφme ostatnφ prom∞nnΘ pro spuÜt∞nφ pohybu. Za prvΘ °φkßme, ₧e cesta je naΦtena. Do prom∞nnΘ m_curInterpolation ulo₧φme poΦßteΦnφ segment stejn∞ jako do prom∞nnΘ m_curSeg. Nakonec nastavφme pozorovacφ a pozorovan² bod. K tomu pou₧ijeme objekt aktußlnφ polohy m_curInterpolation. m_curInterpolation.vPos je p°φmo pozorovacφ bod a pozorovan² dostaneme jednoduÜe tak, ₧e k tΘto hodnot∞ p°iΦteme sm∞r m_curInterpolation.vDir. Nßsledujφcφ trojicφ metod se dß ovlßdat pohyb kamery. Ka₧dß z t∞chto metod se nejprve p°esv∞dΦφ, zda-li je naΦtena n∞jakß cesta. Metoda StartPath() provede dv∞ v∞ci. Nastavenφm p°φznaku m_ePathStatus na hodnotu PLAY zp∙sobφ, ₧e se zaΦne poΦφtat Φas interpolace, kter² je ulo₧en v prom∞nnΘ m_curInterpolation.fTime. Pomocφ tΘto hodnoty se interpoluje (k tomu se dostaneme za chvilku) a pokud se m∞nφ, kamera se pohybuje. Za druhΘ je t°eba kame°e °φci, aby p°eÜla z interaktivnφho re₧imu do re₧imu PATH. Toto se dß rovn∞₧ nastavit metodou SetCameraMode(). Aby se pohyb kamery projevil po vizußlnφ strßnce, je t°eba jeÜt∞ trochu upravit metodu ProcessCamera(). Ta se rozd∞lφ na dva p°φpade: interaktivnφ a automatick² s cestou. Interaktivnφ re₧im z∙stane stejn² jako doposud. Zajφmav∞jÜφ bude druh² zmφn∞n² zp∙sob: // Path mode D3DXVec3Lerp(&m_curInterpolation.vPos, &m_curSeg->vPos, &m_curSeg->pNext->vPos, s); Pokud je nastaven p°φsluÜn² re₧im pomocφ metody SetCameraMode() (Φi metodou StartPath()), je pozorovan² a pozorovacφ bod poΦφtßn zcela jinak.
Interpolace probφhß pouze pokud je sekvence spuÜt∞na (prvnφ podmφnka). V tomto p°φpad∞ se vynßsobφ Φas modifikßtorem zrychlenφ, spoΦφtß se Φasov² rozdφl mezi
aktußlnφm a nßsledujφcφm segmentem a urΦφ se faktor interpolace. Ten je 0.0 pokud je kamera na zaΦßtku aktußlnφho segmentu nebo 1.0 pokud se kamera nachßzφ na zaΦßtku nßsledujφcφho segmentu.
V p°φpad∞, ₧e faktor je v∞tÜφ ne₧ 1.0, znamenß to, ₧e jsme ji₧ v dalÜφm segmentu a je t°eba p°epnout aktußlnφ segment, tedy z nßsledujφcφho se stane aktußlnφ. V opaΦnΘm p°φpad∞, tedy kdy₧ je faktor zßporn², znamenß to, ₧e jsme se dostali do p°edchozφho segmentu, zde je t°eba pou₧φt ukazatel na p°edchßzejφcφ segment (kamera se pohybuje v opaΦnΘm sm∞ru). Pokud ukazatele pNext nebo pPrevious ukazujφ na NULL, znamenß to, ₧e jsme na konci sekvence a je t°eba se vrßtit na zaΦßtek. Po p°epnutφ aktußlnφho segmentu
je t°eba znovu spoΦφtat faktor. Na zßv∞r nastavφme pozorovacφ a pozorovan² bod pro matici pohledu. VÜimn∞te si, ₧e tyto °ßdky jsou stejnΘ jako v metod∞ LoadPath(). 33.2. Podpora mlhy ve t°φd∞ XDisplayMinule jsme si °φkali n∞co mßlo o mlze, ale nastavovali jsme ji p°φmo ve t°φd∞ XTerrain dost neohraban²m zp∙sobem. Proto jsem p°idal t°i novΘ funkce do t°φdy XDisplay. EnableFog(BOOL bEnable) - vypne nebo zapne mlhu Parametr uFogType m∙₧e nab²vat hodnot: D3DFOG_LINEAR, D3DFOG_EXP nebo D3DFOG_EXP2. U lineßrnφ mlhy je t°eba nastavit parametry fStart a fEnd. U exponencißlnφ musφ b²t nastaven parametr fDensity. Parametry Color urΦuje barvu mlhy. 33.3. Zßv∞rA je tu op∞t konec! P°φklad si samoz°ejm∞ m∙₧ete stßhnout v sekci Download vΦetn∞ zdrojov²ch k≤d∙. Abyste vid∞li v²sledek dneÜnφ prßce, stiskn∞te klßvesu C, kterou spustφte pohyb kamery podle cesty zadanΘ v souboru path.txt, kter² si samoz°ejm∞ m∙₧ete upravit dle libosti. A jak² problΘm budeme °eÜit p°φÜt∞? P°φÜt∞ bych Vßm cht∞l ukßzat dalÜφ optimalizaΦnφ techniku LOD (Level Of Detail), kterß pracuje na principu sni₧ovßnφ slo₧itosti terΘnu. T∞Üφm se p°φÜt∞ nashledanou.
|
|