(c)2003 Pavel Pindora
Email Kontakt Pro více informací je zde formulář
3DOT engine
Pokračování na následujícím listě
New 16.1.2005 Start tutorial 3DOT
.NET 1.12.2007 3DOT Opengl ActiveX for IE
|
Stručná charakteristika projektu 3DOT engine Cílem projektu je vyvinout software, pracující se základními OpenGl objekty v 3D prostoru , které mohou měnit své parametry, dynamicky, během online renderování a to na základě dat přicházejících za pomocí různých interfejsů z reálného světa a zpracovaných pomocí skriptovacích či jiných technik, použitých v tomto engine nebo i mimo něj. Projekt si neklade za cíl modelování k tomu jsou určeny jiné 3D programy, ze kterými jej nelze srovnávat i když některé modelovací možnosti snad bude mít ale spíše jen jako výsledek po zpracování dat. Pokud je nutné použít složitější 3D tvary , je potřeba je vymodelovat v příslušném 3D software a exportovat do obj, který tento engine je schopen importovat 3DOT engine je výchozím prostředkem pro projekty : 3D Vizualizací ViDJ ... |
¨
05.08.2003 Volba a parametrizace scén (efektů)
14.08.2003 Napojení vybraného parametru na joystick, načtení scény,...
27.09.2003 Import obj souboru , ovládání jeho vybraných parametrů
09.10.2003 Světla a ovládání jejich vybraných parametrů
17.10.2003 Implementace materiálu na obj soubor
19.10.2003 Driving vykreslování polygonů obj souboru
01..12.2003 Uložení scény vytvořené importem obj souborů
07.12.2003 Automatický tvar polygon z obj
27.12.2003 Návrh skriptovacích rozhraní
18.04.2004 Uživatelská správa proměnných a skriptovací rozhraní
----------- Pokračování ----------------
10.10.2004 Vkládání primitiv včetně quadric objektů
2.10.2005 Vertex Fragment shader, GLSL
Protože jsem se setkal s problémem vizualizace dat v 3D prostoru , např. Prezentace teplotního profilu běžícího pásu , vyhodnocení teploty železničního soukolí ale i zobrazení 3D grafu , rozhodl jsem se vyvinout jednoduchý (alespoň zpočátku :-) 3D engine postavený na OpenGl, který by umožňoval řešit výše popsané úlohy.
Pro
vývoj 3DOT je použit Microsoft Visual C++ 6.0
Toto
prostředí by mělo mít nejméně dvě vrstvy :
1.vrstva
statická, t.j. Nemění se vlastnosti vložených prvku na základě
příchozích dat . Prvky se nahrají ze souboru .scene při spuštění
aplikace .
2.vrstva
- dynamická . Zde je možno měnit vlastnosti prvků na základě příchozích
dat , t.j. Je možná změna proporcí , barvy , polohy, rotace. K dynamickým
prvkům je možno naimportovat objekty ze souboru .obj (podporovány jsou v,f)
Pohled na 3DOT engine

Ve spodní části můžeme ovládat nastavení kamery na určité místo v enginu a směrovat její pohled. Mimo to stiskem a podržením levého tlačítka myši , můžeme ve scéně směrovat pohled. Pohyb ovládáme stejným způsobem tlačítky, šipka nahoru (vpřed),dolů (zpět),vlevo,vpravo, přičemž směr pohybu určuje pohled. No a protože někdy dlouho trvá než se někam přemístíme , je zde právě možnost rychlé změny Camera Position View, kdy zadáme souřadnici a stiskem tlačítka Set je nastavena nová posice nebo pohled (View).

Dále je zde informace o počtu framů za sekundu, Thread informuje o počtu průchodů v samostatném threadu mající na starosti matematiku, sběr dat apod. Tento thread je v současnosti součástí 3DOT ale bude přemístěn do samostatné DLL, kdy dynamickou změnou dll během vykreslování bude možno měnit výsledné efekty . Jsou prováděny testy přenosu dat po sítí aby bylo možno úplně odlehčit PCčko s 3DOT od výpočtů, které nejvíce zabírají strojový čas procesoru.
Po načtení scény ze souboru můžeme prohlížet parametry prvků, které jsou použity . V horní části je listing všech prvků a ve spodní části vlastní parametry vybraného prvku.

Pokud zvolíme Data Root listingu, můžeme ovlivňovat globální parametry scény , jako například Translate, Rotate, PushMatrix .
Pro ilustraci principu ovládání scény, je na následujícím obrázku vidět , že Enable TrRot povoluje provedení Rotate v ose Y , co bude povoleno je dáno váhou nastaveného bitu
| 1.bit váha 1 | Povolit provést Translate | uplatňují se parametry TranslX,Y,Z, ke kterým se může přičíst Add TraX,Y,Z |
| 2.bit váha 2 | Povolit Rotate v ose X | uplatňují se parametry RotateX, ke kterým se může přičíst Add RotateX |
| 3.bit váha 4 | Povolit Rotate v ose Y | uplatňují se parametry RotateY, ke kterým se může přičíst Add RotateY |
| 4.bit váha 8 | Povolit Rotate v ose Z | uplatňují se parametry RotateZ, ke kterým se může přičíst Add Rotate Z |

Globální scéna představuje všechny prvky , které jsou použity a provedením Rotate budou všechny ovlivněny, dále má každý prvek svoji rotaci takže může rotovat i samostatně.
Z obrázku je dále zřejmé, že byly použity dva druhy prvků Triangle a Quad
Tato část informuje, jak jsou uloženy parametry ve třídě aby bylo možno vytvořit dllku , která bude matematicky nebo jinak ovlivňovat procesy ve scéně .
class Objects : public CObject
{
public:
//--------------- Parametry globalni sceny ---------------------
float ScnArrayTrnnsl[3]; // 3x pozice sceny (x,y,z)
float ScnArAddTrnnsl[3]; // 3x pricteni k pozici sceny (x,y,z)
float ScnArrayRotate[3]; // 3x rotace sceny (x,y,z)
float ScnArAddRotate[3]; // 3x pricteni k rotaci sceny (x,y,z)
UINT ScnArrayJeTrRo; // 1x 1.bit je translate 2.3.4. bit je Rotate X,Y,Z
//----------------------- Nova spedifikace dne 03.06.2003 ----------------------------
CStringArray ArrayNameObTri; // 1. Nazev Objektu -------------------------------------
CUIntArray ArrayTypeObTri; // 2. Typ objektu GL_TRIANGLES,GL_QUADS-----------------
CUIntArray ArrayOCountTri; // 3. Pocet vrcholu objketu,napr. triangle=3-------------
CUIntArray ArrayTexSidTri; // 4. 1x cislo pouzite textury 0=neni ------------------
CPtrArray ArrayColorsTri; // 5. 3x (RGB) barvy kazdeho vrcholu x pocet vrcholu
CPtrArray ArrayTexturTri; // 6. 2x urceni polohy textury x pocet vrcholu , viz popis nad Popis textury
CPtrArray ArrayVertexTri; // 7. 3x pozice vertexu (x,y,z) x pocet vrcholu
CPtrArray ArrayTrnnslTri; // 8. 3x pozice objektu (x,y,z) -------------------
CPtrArray ArrayRotateTri; // 9. 3x rotace objektu (x,y,z) -------------------
CUIntArray ArrayFlagPsTri; // 10. 1x priznak provest glPushMatrix -------------------
CPtrArray ArrayPoBModTri; // 11. 2x Polygon mode pred glBegin x ArrayPocetBTri glPolygonMode( GL_BACK,GL_FILL );
CPtrArray ArrayPoEModTri; // 12. 2x Polygon mode za glEnd x ArrayPocetETri napr glPolygonMode( GL_BACK,GL_FILL );
CUIntArray ArrayPocetBTri; // 13. 1x Pocet Polygon mode begin -------------------
CUIntArray ArrayPocetETri; // 14. 1x Pocet Polygon mode end -------------------
CUIntArray ArrayJeTrRoTri; // 15. 1x 1.bit je translate 2.3.4. bit je Rotate X,Y,Z
long CountObjTri; // . Celkovy pocet objektu -------------------
//------------------------------------
void ClearData( void )
{
//---------------------------------
if( ArrayNameObTri.GetSize()>0 )ArrayNameObTri.RemoveAll();// 1.
if( ArrayTypeObTri.GetSize()>0 )ArrayTypeObTri.RemoveAll();// 2.
if( ArrayOCountTri.GetSize()>0 )ArrayOCountTri.RemoveAll();// 3.
if( ArrayTexSidTri.GetSize()>0 )ArrayTexSidTri.RemoveAll();// 4.
A pro příklad, jak probíhá načtení parametrů barvy v nějaké smyčce ,která načítá vlastnosti všech objektů. Podotýkám, že ukazatel efektColor musí být globální, jinak nám zanikne při opuštění funkce a vyskočí nám assert jakmile na něho šáhneme. Stejně tak musí být ošetřeny všechny vlastnosti i ty které nepoužijeme.
//--------------------------------------------------5
UINT sizeMalloc = sizeof(UINT) * (efektOCount * 3);
efektColor = (UINT*)malloc( sizeMalloc ) ;
if(efektColor==NULL ){AfxMessageBox("Error allocated memory",MB_OK | MB_ICONERROR);exit(0);};
efektColor[0] = CoBS1R;
efektColor[1] = CoBS1G;
efektColor[2] = CoBS1B;
efektColor[3] = CoBS2R;
efektColor[4] = CoBS2G;
efektColor[5] = CoBS2B;
efektColor[6] = CoBS3R;
efektColor[7] = CoBS3G;
efektColor[8] = CoBS3B ;
m_Objects.ArrayColorsTri.Add(efektColor);
//--------------------------------------------------6
3DOT může obsahovat až 30 nezávislých výpočtů obrazovek, scén neboli efektů tvořených pomocí OpenGl, následující obrázek pro představu znázorňuje obrazovku 1 a 2, které vznikají dvěma nezávislými výpočty založených na vzorcích
Efektx1 = float(5 * sin(i));
Efekty1 = float(5 * cos(i));


Volba těchto obrazovek se provede stiskem tlačítek v příslušném toolbaru

Stiskem
můžeme
spustit animaci obrazovek, přičemž každá scéna bude trvat dle zvoleného
času a právě probíhající scéna je indikována "checknutím" tlačítka
.![]()
Parametry jednotlivých obrazovek je možno prohlédnout a měnit pomocí Tree Docking dialogu , kliknutím na položku Data Root se tree rozbalí
a dalším kliknutím můžeme rozbalit položku Efekts ( je zde i vidět, že scéna je tvořena OpenGl primitivou GL_Triangle),
navolíme například parametry obrazovky 2 , které se skrývají pod položkou Efect Button 2. Ty se nám vylistují v samostatném Listingu

Parametrů je prozatím 10 a není problém přidat další , jejich editaci lze provést tak , že klikneme v listingu na parametr, který nás zajímá ( Parameter0 - 10 ) a jeho hodnota se přenese do příslušného zadavatele .


Hodnota Range from to slouží k nastaven rozsahu Slideru , kterým můžeme rychle měnit parametr ale jen v celočíselném rozsahu , pokud potřebujeme zadávat desetiny, musíme hodnotu zadat do editboxu. Nové hodnoty se automaticky zpětně přenesou do listingu.Nakonec je potřeba dodat, že pokud zvolíme v listingu jinou položku než Parameter0 - 10 tak se do zadavatele nic nepřenese.
Další probíhající rozpracovanost:
Napojení vybraných parametrů na ovládače polohy ( joystick,mouse )
Archivace parametrů do volitelných souborů a tím větší možnost variability scén
Zpracování parametrů pomocí skriptů od událostí (Timer,...)
Jak již bylo dříve řečeno je možné pomocí tlačítek
volit scény, obrazovky představující nějaký efekt a podobně. Byla změněna
možnost načtení scény ze souboru tak, že soubor se načte pod tlačítko ,
které je navoleno. Máme-li tlačítkem navolenou např. scénu 3 tak její
parametry můžeme načíst ze souboru s extenzí *.scene . Data získána ze
souboru jsou načtena do dříve popsané třídy (class) Objects
a pro příklad uvedu řádek (jeden řádek popisuje jeden objekt např GL_TRIANGLE
) tak jak je uložen v souboru.
*TYPE4;NAME=TRIANGLE_0;COUNTVR=3;TEXTURE=1;COLOR=255;0;0;0;255;255;255;0;255;> VTEXTUR=0.000000;0.000000;1.000000;0.000000;1.000000;1.000000;> VERTEX=40.000000;0.000000;0.000000;40.000000;0.000000;0.000000;40.000000;0.000000;0.000000;> JETRROT=0;TRANSL=>ROTATE=>FLAGP=0;POCPMB=0;POCPME=0;POMODB=>POMODE=>
*TYPE4
Typ OpenGl primitivy , viz class Objects
Name Název primitivy, podle které se zobrazuje ve stromu
COUNTVR Počet vrcholů triangl má 3, quad 4
TEXTURE Jaká je použitá textura , 0=žádná
COLOR barvy pro každý vrchol primitivy v RGB, triangl má tři vrcholy ,každý představuje 3 hodnoty pro vyjádření v RGB
VTEXTUR Jak je použitá textura.
VERTEX X.Y.Z poloha vrcholu , opět dle počtu vrcholů
další JETRROT ,TRANSL,... popisují otočení v prostoru a nejsou zde použity
Příklad načtení scény pod tlačítko 3 , které neobsahuje žádný efektový výpočet.

Příklad načtení stejné scény pod tlačítko 1 , které obsahuje efektový výpočet.

(později bude realizováno napojení na další reálné zdroje dat , audio, A/D převodníky, seriové COM či USB kanály , XML, apod.)
Do stromu Data Root jsou pro začátek a ověření principu vloženy parametry globálního pozicování scény pomocí Translate , Rotate,

viz další obrázek , Transl X-Z představuje translaci a Rotate X-Z rotaci. Add RotateX-Z je hodnota která se připočte k hodnotě Rotate X-Z a to dle následujícího vzorce , uvedeného pro příklad pro X Rotate X = Rotate X + Add RotateX

Pokud je povoleno pozicování pomocí hodnoty Enable TrRot dojde k roztočení scény . Povolení provedeme tak, že myši selektujeme řádek Enable... a ten se přenese do zadavatele , který již byl dříve popsán ale v současnosti je poněkud změněn.

Pro tento případ nás hlavně budou zajímat checkbuttony 0001 - 8000 , kterých je 16 a umožňují ovládat jednotlivé bity hodnoty podle váhy , která je na nich napsaná v hexadecimálním vyjádření . Pro Enable... tak byla zadána hodnota 15 decimálně t.j. 0F hexa a je tak povoleno jak Translate tak i Rotate. Patnáct ale můžeme i jednoduše zapsat do edit boxu.
Nyní máme povoleno pozicování a protože chceme rotovat scénou , řekněme po ose Z (dle vzorce Rotate Z = Rotate Z + Add RotateZ), pomocí joysticku, bude potřeba navolit do zadavatele řádek Add RotateZ , pak nastavíme rozsah Slideru na např. Range from. -10 a Range to na 10 . Nyní bychom mohli měnit hodnotu sliderem nebo přímo v editboxu a tím scénu roztočit ale chceme ji roztáčet pomocí joysticku s tím, že pokud je joy v klidu scéna bude stát a podle úhlu naklonění doleva,doprava bude možno měnit rychlost roztáčení

Povolení
ovládání joystickem je potřeba provést ve sloupci
a to checknutím Enbl Slider , nato zvolíme operátor (v současnosti + - * /)
, představující operaci, která se provede s hodnotou přicházející z
polohy joysticku (ta je vidět v List boxu na řádku JoySt. X,Y) . V našem
případě se bude násobit údajem 1. Údaj je možno dle potřeby měnit zde
.
Nyní již joystickem budeme moci ovládat scénu . Funkce je jednoduchá :
Počítač sejme hodnotu z joysticku
Hodnota se přepočte dle operátoru
v časových intervalech a jen při změně hodnoty se nastaví slider
jeho změna ovlivní scénu dle zvoleného řádku v List boxu.
Jak je z popisu zřejmé je možno joystickem ovládat i jiné parametry.
Ovladatelné parametry budou v boxu nějakým způsobem odlišeny.
Do
ovládatelných parametrů přibude i class Objects
Soubor obj je mimo jiné i grafický formát popisující geometrické vlastnosti (a nejen ty) objektů používaných u Wavefront's Advanced Visualizer . Jsou dva způsoby jak je v 3DOT načíst a to buď v File Import OBJ file nebo v tools, kde jsou větši možnosti. Při importu jsou podporovány jen vertexy prvků POINT, LINE, TRIANGLES, POLYGON.

Zvolením Tools vyjede OGL dialog , ve kterém si v Set Directory vybereme adresář , kde jsou námi požadované soubory.
Soubory se vylistujou v seznamu a nyní vybráním jednoho, můžeme obj vložit do scény a to buď jako samostatný objekt nebo objekt skupiny, v obou případech může být vloženo automaticky více stejných obj do předdefinovaných tvarů, v současnosti jsou uvolněny ty nejjednodušší a to Single, Quads. Každá skupina má volitelný číselný identifikátor od 1 do 999. .

Příklad: Řekněme, že chceme vložit tolik obj souborů aby byl vytvořen Quads , který na svých stránách (a,b,c,d) má 5 obj s názvem triplane_simple.obj a má deset cylindrů, celý tento komplex bude vložen do skupiny s ID 999.
Nejdříve vybereme požadovaný soubor triplane_simple.obj a potom radiobuttonem navolíme Quads.

Uvolní se tlačítko Parameter a jeho stiskem vyjede okno, kde navolíme parametry jak budou obj do Quads nasázeny.

Nyní dáme OK a dle předchozího obrázku, použitím Add necháme zavést obj do scény. Výsledkëm bude následující obrázek.

Je jasné, že za triplane_simple.obj se skrývá jen obyčejný trojúhelník ale pokud bychom vložili nějaký obj s mnohatisící polygony, pak bychom se asi nedočkali počítače, vykreslujícího takovýhle tvar.
Vybrané parametry každého trojúhelníku je možno měnit v jeho Properties.

Důležité je ovládání Properties skupiny , potom můžeme s celým útvarem pracovat jako s jediným objektem , např. posouvat ho ,rotovat s ním, připočítat hodnotu k barvě a to vše v každém Frame. Kdežto, pokud navolíme samostatný trojúhelník dle předchozího obrázku, ovládáme pouze jen jediný fragment skupiny.

Dále je příklad načtení obj bez skupiny.

Bez možnosti osvětlit scénu by nemělo valného smyslu importovat obj soubory, neboť ztrácejí plastičnost a tím jsou z nich jen 2D vyplněné obrysy, což však nijak neomezuje jejich použití ve specifických případech . Znázorňuje nám to následující levý obrázek na pravém jsou již implementována světla. Je však nutné mít v obj souboru i parametry normál, dá se to zjístit tak, že si otevřeme obj v notepadu a najdeme face položky (je jich tam hodně) tak např. f 972/1050/835 , poslední 835 je odkaz na normálu .

V OpenGl je k dispozici standartně 8 světel a to Ambientní a Diffusní . Ambientí je okolní světlo nemájící směr a osvětluje nám vše ze všech stran stejně. Diffusní světlo má pozici a směr , na předchozím pravém obrázku je vidět , že dif. světlo svítí z našeho pohledu.
Stejně jako jinde je možno provést listing parametrů světel v Frame Tree. Na obrázku je listing parametrů Ambientního světla , kde můžeme pomocí zadavatelů měnit její barevné složky RLight...,G...,B..., Enable Lig. zakáže implementaci světel scény a hrníček by nám jakoby zhasl
( připomenu , že zadavatelem může být Slider, JoyStick, jiné datové zdroje z reálného světa ).

Listing Diffusních světel zahrnuje všech 8 ( Light Diffuse 0 - 7 ) ale 0 je Ambientní světlo takže pro diffusní máme vlastně jen 7, i když 0 můžeme přeměnit taky na diff , viz následující obrázky, kdy vidíme, že jsou vypsány Properties Light Diffuse0 ale položka Enable lig. má hodnotu 0 takže diffuse ja zakázána .

Můžeme to porovnat s listingem Light Diffuse 1 . položka Type... říká že se jedná o Diff. světlo (1), (0 Ambient).
Enable Lig jeho povolení
Další položky se týkají pozice.
Důležitá je položka Size Light , která se uplatní pouze tehdy, jestliže Type Light je větší než 9

Potom se místo světla vykresluje blending Quads s nanesenou textůrou , její druh určuje číslo, které vyjde vydělením Type Light... / 10 . Nejlépe to ukážeme na následujícím obrázku , kde je listing pro Light Diffuse 1 , vidíme že Type = 10, Size = 19.

Výsledek po vykreslení :

Pro Type = 20
¨
Pro tyto blendingem vytvořené světla se uplatní i položky X Y Zlight Rot... , AddX Y Zlight... a můžeme tyto textůry např. nechat rozrotovat s max. možnou rychlostí a tím vytvořit zajímavé světelné efekty.
Byla implementována možnost měnit materiál obj souboru a to díky normál, které jsou zavedeny ( viz Světla ) . Je třeba zdůraznit, že všechny obrázky obj souborů uvedené v pojednání o světlech mají zavedený materiál , nyní je nově uvolněna možnost měnit parametry materiálu v listingu Tree baru. Poklepáním na zvolený obj (dle následujícího obrázku např. hrnicek.obj) se zpřístupní položka Materiál,

jejím vybráním se vylistují jeho parametry, jehož vybrané části je možno ovládat v zadavatelích ( připomenu , že zadavatelem může být Slider, JoyStick, jiné datové zdroje z reálného světa )

Nejdříve demonstruji Enable Mat. a to zakázáním (hodnota 0) , protože hrníček s materiálem jste již viděli ve Světlech
hrníček není skoro vidět protože jeho základní barva RGB
je 50,50,50.
Změníme ji na
100,50,100 a výsledek
nyní opět zapnem materiál
.
Dále demonstruji položky Front0 Emis.=0 , jedná se vlastně o
barevnou emisní R složku
,
Front Shini = 10
Front Shini = 100
Pod tímto pojmem se ukrývá možnost vykreslovat jen určité polygony načtené z obj souboru. Tyto vlastnosti opět můžeme měnit dynamicky během chodu aplikace pomocí zadavatelů ( připomenu , že zadavatelem může být Slider, JoyStick, jiné datové zdroje z reálného světa ).. Podívejme se na následující obrázek s listingem properties hrnicek.obj.

Je zde navíc Draw P.from Draw P.count , Draw PXth
Draw P.from udává od kterého polygonu se obj začne
vykreslovat
zde
jsem dal zadavatelem 400.
Draw P.count kolik polygonů se vykreslí , Draw P.from
vrátím zpět na 0
a zadal jsem Draw P.count=639
Nyní dám vše jak bylo a Draw PXth = 3 , to znamená , že se bude vykreslovat každý třetí polygon
a to je výsledek
.
Scénu vytvořenou importem obj a upravenou pomocí některých výše popsaných metod, je možno uložit dle postupu znázorňující následující obrázek , vybereme položku menu Save obj scene. Uloží se veškeré obj prvky použité ve scéně. Otevření je obdobné pomocí Open obj scene. Podstatný rozdíl je v tom, že pod Soubory typu je zadávací text , kde můžeme zadat číslo skupiny (Load to group) do které chceme scénu uložit.

Pro názornost slouží další obrázky ,podotýkám, že scéna tvořena pěti hexagony (5 x hexagon.obj) byla uložena pod skupinou 999:
1. Je nahrána scéna tvořená pěti hexagony beze změny skupiny ( Load to group = 0)

2. Přihrán stejný soubor do skupiny 10 ( Load to group = 10) a protože scéna má stejné parametry zdánlivě se nic neděje ale ve skutečnosti jsou dvě na sobě a mají rozdílnou skupinu (999 a 10)

3. Vybraním ObjGroup 10 a změnou jeho parametrů Translate Y = -3 se tato skupina posune pod 999.

A pro úplnost ,
poslední otevřenou scénu smažeme takto
v našem příkladě zmizí ObjGroup 10,
poslední obj zrušíme tady
a z pěti hexagonu zbudou 4.
Již známym způsobem vyvoláme OGL dialog , zvolením Tools a otevřeme adresář z našimi obj soubory, kde navolíme např.hexagon.obj, přepneme RadioButton na Poly.

Potom nastavíme parametry (Button Parametr) , například :
Počet obj na obvodu pomyslného polygonu (Count obj...) = 5
Radius (vzdálenost od středu) = 3
Počet cylindrů (Count cylinder) = 10
Mezi cylindry (Between) = 1
Okolo jaké osy se bude tvar tvořit (Owner) = Axis Z

Pokud chceme aby každý cylinder měl jinou skupinu , zaškrkneme Auto add Group (ale Group ID + Count cylinder nesmí být věší než 999 takže potom bychom Group ID museli snížit na např.980 ).
Potom dáme OK , Add Group ID a výsledek je zde
.
Skriptovací rozhraní bude mít pro tento projekt zásadní vliv. Umožní uživatelům 3DOT modifikovat vybrané vlastnosti objektů na základě skriptu a tím vytvářet nové dynamické efekty scén.
Skriptovací stroje bude nutné ale volit z ohledem na uživatelskou přívětivost a rychlost. Z hlediska přívětivosti je dobrou volbou
problematická bude asi jeho rychlost,hlavně u rozsáhlých kódů. Přesto jsem začal tento skript implementovat do modulu tak aby bylo možné ho používat jako plugin pro 3DOT. Příklad jak jsem implementoval scripting v jakési demoaplikaci VisualC++6 je zde .
Je možno použít i Java skript.
Pro možnost ovládání 3DOT aplikace po sítí a tím i pro odlehčení PCčka se spuštěným 3DOT počítám s implementací takového síťového rozhraní , nejlépe na TCP/IP (IPX by ale byl rychlejší) , které by bylo schopné přenášet data dostatečnou rychlostí i na 10Mb ethernetech . Zde se ovšem nebudou sdílet metody rozhraní ( viz.UserData zde ) ale budou se přenášet přímé hodnoty do remote skriptu a hodnoty výstupů z něho. Takovýto skript bude velmi rychlý ale je potřeba zvážit počet přenášených hodnot, neboť zde by mohlo docházet ke zpomalení aplikace, čekající na data.
Pro na rychlost méně náročné požadavky, uvažuji o možnost použití standartizovaných XML přenosů a SOAP.
Zde se nejedná o skript v pravém slova smyslu ale je zde dána možnost programováníznalým uživatelům vytvořit vlastní DLL knihovnu se svým specifickým kódem , který bude mít přístup k metodám rozhraní ( viz.UserData zde ) a tím bude dána možnost ovlivňovat chod 3DOT. DLLka však bude mít pevně dané exportovatelné funkce.
Projekt 3DOT bude volat skripty na základě daných událostí: Nejlépe je to vidět na následujícím obrázku.
Událost Render_scény je volána před tím než dojde k překreslení scény , zde bude volána funkce RenderScene v Bin_plugin , zde však bude kritická sekce neboť pokud dojde k uživatelské chybě v Bin_pluginu tak scéna zhavaruje. Dále bude zde možnost nastavit flag přenosu pro požadavek na Remote_script a jakmile dojde ke zpracování, Render_scéne převezme data , to znamená ,že nemusí dojít ke změně hned při další překreslování ale i po delší době.
Událost Timer zpracovává skript nezávisle na renderování , zde bude volána funkce TimerEvent v Bin_plugin . Pokud dojde k zablokování skriptu neohrozí to renderování ale nelze očekávat výsledek skriptem generovaných hodnot. I zde může být nastaven požadavek na Remote_script.
Událost Thread zpracovává skript nezávisle na renderování ,volání funkce ThreadEvent v Bin_plugin . Jinak platí vše co v události Timer .

Prvotní krokem pro implementaci skriptovacích strojů do 3DOT bude rozhraní , které umožní uživatelům zakládat proměnné , případně je rušit . Hodnoty těchto proměnných pak bude moci pomocí funkcí SetValue ,GetValue ( viz.UserData zde ) měnit nebo číst v uživatelských skriptech. Tyto proměnné bude moci uživatel napojovat dále na vlastnosti objektů ,jako např. TranslateXYZ,RotateXYZ,barvu, případně i na jednotlivé vertexy ,textůry,materiály apod.
Globální proměnné
slouží například k napojení vlastností 3D objektů (GL_TRIANGLE,obj,...)
do skriptu , kde mohou být použity k výpočtu . Pro správu slouží takzvaný
data manager , vyvolávaný stiskem
v nabídce
.
Poté je aktivován plovoucí dialog , kde je možno provádět operace s proměnnými . Levá část dialogu tvoří okno se seznamem vytvořených proměnných , které mohou být uloženy ve složce UserVar. System je zatím prázdný a pro zajímavost , zde budou systémové proměnné, vložené natvrdo po startu programu, obsahující hodnoty polohy myši, joysticku, časovačů apod.
Střední část slouží k vytvoření nové proměnné resp. proměnných typu float a integer, případně je možno vytvořit složku (folder) a do této vkládat další prom. String a Buffer není zatím podporován.
Můžeme vložit i větší počet dat a to tak, že do Count dáme počet, nastavíme číslo do Index , Name určí pod jakým názvem budou nové data, k tomuto názvu se při vytváření přidá hodnota Indexu zvětšována při větším počtu o 1. Pro příklad vidíme v levé části vytvořené proměnné s názvem TestData0 - TestData9.
Tyto byly vytvořeny s následujícími parametry :
Count = 10
Index = 0
Name = TestData
Inic Val Udává jaká hodnota se vloží do proměnné po startu aplikace
Okno Data manageru

Pro archivaci vytvořených hodnot včetně nakonektovaných vlastností jsou tlačítka Load,Save,Save As. Archivace se provádí do souboru s příponou mvar
Formát je následující :
"Název proměnné s celou cestou" TypProměnné HodnotaProměnné "NapojenaVlastnost"
Příklad
/Root/UserVar/NewItem0 2 0 -
/Root/UserVar/TestData0 1 10.000000 Light$Diffuse0%RLight$Diffuse
/Root/UserVar/TestData1 1 20.000000 Light$Diffuse0%GLight$Diffuse
/Root/UserVar/TestData2 1 0.000000 Light$Diffuse0%BLight$Diffuse
/Root/UserVar/TestData3 1 0.000000 hexagon.obj0#999%Translate$X
/Root/UserVar/TestData4 1 0.000000 hexagon.obj0#999%Translate$Y
/Root/UserVar/TestData5 1 0.000000 hexagon.obj0#999%Translate$Z
/Root/UserVar/TestData6 1 0.000000 999%GroupsTranslate$X
/Root/UserVar/TestData7 1 0.000000 999%GroupsTranslate$Y
/Root/UserVar/TestData8 1 0.000000 999%GroupsTranslate$Z
/Root/UserVar 0 ___ -
/Root/UserVar/TestData9 1 0.000000 Light$Ambient%RLight$Ambient
/Root 0 ___ -
/Root/System 0 ___ -
"Název proměnné s celou
cestou" /Root/UserVar/NewItem0
TypProměnné 1= float 2=integer
HodnotaProměnné 0 pro integer 0.000000 pro float
NapojenaVlastnost 999%GroupsTranslate$X
Pravá část je rozdělena na dvě části . Horní velké okno je určeno ke sledování hodnot navolených proměnných v reálném čase v intervalu 0.5.sec. Proměnnou do tohoto okna zařadíme tak, že v levé části označíme tu ,kterou požadujeme, stiskem Add Watch-> ji vložíme do sledování.. Aby nebylo nutné po spuštění aplikace to pořád opakovat, je možno si skupinu archivovat na disk, tlačítky Load W group, Save W group..
Spodní část okna
![]()
slouží k zadávání hodnot po inicializaci (Inic value) a k přímé změně během chodu aplikace (Run value)
K
vlastnímu napojení proměnné na vlastnost 3D objektu slouží
a to následujícím způsobem :
V horní části listingu všech prvků vybereme ten, kterému chceme pomocí proměnné měnit nějakou vlastnost (např. TRIANGLE_12)

a ve spodní části vlastní parametr vybraného prvku.(Translate X)

Nyní
se tato vlastnost automaticky přenese do okna Data Manageru
.V levé části si vybereme proměnnou, na kterou chceme tuto vlastnost napojit
a stiskneme button Connect 3D prop . Nyní, pokud do sloupce Run Value
zadáme hodnotu, posune se objekt po ose X.
Nic již
nebrání použít skript k ovlivňování napojených vlastností v proměnných
. Pro tento účel je doposud aplikován Inicializační skript, který se
provede po stisku tlačítka start
a to jen jednou po stisku. Render skript se provádí během rendrovací
smyčky . Zatím nemám vyzkoušeno jak rozsáhlý skript může být aniž by
došlo k zpomalování renderování. Render skript je spuštěn jen za
podmínky, že Inicializační skript je proveden a nenastala v něm chyba .
Inicializační skript se nachází v souboru IniScript.dotscript , který
v aktuálním adresáři můžeme editovat např. pomocí notepadu a Render
skript je v RenderScript.dotscript .
Chybová hlášení jak ze skriptů
tak z Data Manageru se vyvolají stiskem tlačítka
v toolbaru a pokud nastane chyba , signalizuje to toto tlačítko rozblikáním.
Příklad VB inicializačního skriptu IniScript.dotscript:
jmeno1=mUserData.SetValue("/Root/UserVar/TestData8",0.2)
a renderovacího skriptu RenderScript.dotscript :
Dim jmeno1
Dim jmeno2
jmeno1=mUserData.GetValue("/Root/UserVar/TestData8")
jmeno1=jmeno1 + 0.02
if jmeno1>10 then
jmeno1 = 0.0
end if
jmeno1=mUserData.SetValue("/Root/UserVar/TestData8",jmeno1)
jmeno2=mUserData.GetValue("/Root/UserVar/NewItem0")
jmeno2=jmeno2+1
jmeno1=mUserData.SetValue("/Root/UserVar/NewItem0",jmeno2)
Rozhraní, kterým přistupuje skript k proměnným je :
mUserData.GetValue jehož parametrem je string s názvem proměnné od které chceme získat hodnotu
mUserData.SetValue jehož parametrem je string s názvem proměnné do které chceme zapsat hodnotu a velikost zapisované hodnoty
je důležité dodržovat formát zapisované hodnoty, opět nejlépe na příkladě :
pro float proměnnou
jmeno1=jmeno1 + 0.02
jmeno1=0.0
pro Integer
jmeno2=jmeno2+1
Pokud to nebude dodrženo , bude hodnota skriptovacím strojem ignorována a nebude se nic dít