From 81f553aaeea541f98b4690e4a267be24235c589a Mon Sep 17 00:00:00 2001
From: Don BURNS
Date: Wed, 19 Sep 2001 23:41:39 +0000
Subject: [PATCH] o Updated Metrowerks files for MacOS. They aren't 100%
there yet, but getting there.
o First cut of osgcluster demo. Very simple beginings. Alas
I only one PC here so I can't test it in its current guise.
o New support for NodeCallbacks, via AppCallback attached to
osg::Node's, and a default osgUtil::AppVisitor which calls them on
each frame.
o Support for traversal masks in osg::NodeVisitor, osg::Node
which allows nodes to be switched on or off via a bit mask.
o Suppport for traversal number (frame number) and reference time
into osg::NodeVisitor to handle syncronization of app and cull
traversals. This also assist clustering as traversal number
master to slaves.
---
Metrowerks/Metrowerks.mcp | Bin 0 -> 214148 bytes
doc/doc++/osg/MatrixProduct.html | 51 +++
doc/doc++/osg/NodeCallback.html | 137 +++++++
doc/doc++/osg/Viewport.html | 203 ++++++++++
doc/doc++/osgUtil/AppVisitor.html | 142 +++++++
include/osg/Matrix.new | 224 +++++++++++
include/osg/Matrix.old | 184 +++++++++
include/osg/NodeCallback | 46 +++
include/osg/Viewport | 63 +++
include/osgUtil/AppVisitor | 67 ++++
src/Demos/osgcluster/Makedepend | 0
src/Demos/osgcluster/Makefile | 25 ++
src/Demos/osgcluster/README | 67 ++++
src/Demos/osgcluster/broadcaster.cpp | 125 ++++++
src/Demos/osgcluster/broadcaster.h | 45 +++
src/Demos/osgcluster/osgcluster.cpp | 350 +++++++++++++++++
src/Demos/osgcluster/receiver.cpp | 104 +++++
src/Demos/osgcluster/receiver.h | 39 ++
src/osg/Matrix.cpp.new | 558 ++++++++++++++++++++++++++
src/osg/Matrix.cpp.old | 568 +++++++++++++++++++++++++++
src/osg/Viewport.cpp | 22 ++
src/osgUtil/AppVisitor.cpp | 18 +
22 files changed, 3038 insertions(+)
create mode 100644 Metrowerks/Metrowerks.mcp
create mode 100644 doc/doc++/osg/MatrixProduct.html
create mode 100644 doc/doc++/osg/NodeCallback.html
create mode 100644 doc/doc++/osg/Viewport.html
create mode 100644 doc/doc++/osgUtil/AppVisitor.html
create mode 100644 include/osg/Matrix.new
create mode 100644 include/osg/Matrix.old
create mode 100644 include/osg/NodeCallback
create mode 100644 include/osg/Viewport
create mode 100644 include/osgUtil/AppVisitor
create mode 100644 src/Demos/osgcluster/Makedepend
create mode 100644 src/Demos/osgcluster/Makefile
create mode 100644 src/Demos/osgcluster/README
create mode 100644 src/Demos/osgcluster/broadcaster.cpp
create mode 100644 src/Demos/osgcluster/broadcaster.h
create mode 100644 src/Demos/osgcluster/osgcluster.cpp
create mode 100644 src/Demos/osgcluster/receiver.cpp
create mode 100644 src/Demos/osgcluster/receiver.h
create mode 100644 src/osg/Matrix.cpp.new
create mode 100644 src/osg/Matrix.cpp.old
create mode 100644 src/osg/Viewport.cpp
create mode 100644 src/osgUtil/AppVisitor.cpp
diff --git a/Metrowerks/Metrowerks.mcp b/Metrowerks/Metrowerks.mcp
new file mode 100644
index 0000000000000000000000000000000000000000..eff0ddd6e264533dd2869dd3fb28c6582eb367b5
GIT binary patch
literal 214148
zcmeF431D1B{m0*Kk|w>NKq*&gLrW=8NGWG2SK6dUO4Ej>(1IY@Cfjt|O*ZUqdU2IQ
zKn^)PKoO~;f~W{yc!1!AsE7iJ93CJFD&G3{0`33vn>V}rcK00~Xi9a(SH{xmL@Hh1
zmQJmUcV=^0!z7O0Vp-8`mUZ%E%UVL4WnYD@qvu_B7)+EUI05_^JOw(y*TF;JYv3E;
zn;;6NgBjo;&;SkxQcgXX3U&kYKoeL97J+6kA1nY`vgAHIK*aS9%EuaOA1LuN$!HHleZ~!
zZ-H-v_kwn?0*nNEfs4S!;1X~uI1QWyR)SUFbTAj}0nPxIf**h{fv3Uyz|G(e@G)>F
z_&E3k_#~(UZvl6KPk{%)W8iM^HgFlZ2h0Y?gE`=Ga0PfAECEk|AA(PVw}UIeRp4rH
z4fqUr2e=me2z(Y?2kr&WfX{*VgFS&;c$UQHP(M15?z5h?Vv)ONZ{5EA0jwv(XZ4`
z`ebh)_8@jAb|f}28PtRQz!WeQ><^}a1Hg1}AUFsd3}%2sz@eZ4%mjylS>SMRLz
zU;5x!AboHgkp4IUoCxIjlceDwMI>$8R}=u&6G`3o6=eX~kK&%Fms=pbzOtdr!3i0W{>6Hn?W0Q)n&KL@^50eFe1@Dijf;bA(7y
zZOGhtaco1ZDH+RT;+ckZv9v>0(KA}w>RVTy(WZ9fXlajZ4MJO!t7NsPMRbR&tH`j+
zm8>+CBLfVSk)<`B?vB?l>(3fg)J5bZ!rZpDCE_Jkb@P&it2);wy5!buWjpPXAoW-*
z9z8%Ea@^}&ySyK(dU|eZdKyvz`Z4Tjtqr9UEZ!bCkC9Qn)`}cVA-jR`V0SP9>;d)!
zdx5>dK42o)7fb?^K|RB4h0QhCO8bt0*8Ymz>(l6
za5Oju%m&ATIp8>OJUGD`oM*lkYY;mM3*JizAM+I(38Ljas^F
z>D<=&4f9vccdt&PB&*S!jgC)^To)M`J=bx7%Y{vyi2H`3QEE$~&vBHZGSV-ed)i!f
z45S@L%LxW{MBxfRZ;hb0y!(p#C>;}!&0s!Q02YEppvAx-ivN0~;sm!gIsdMA
zYu{l0*3bRTUnMsy);ZO(P1ndaW6*-oJXNRF+V<(VuBqgKY|cJAlZ~lO`ZfNoHITEp
z$a+`4_;G-@oHM6#_hMt6#k$nHkfb_6q#Z}N{aw%FvfbLVUG+^fX4E&OdNZkHy#DCf
zCl?9|W^yy7{;tJGRy`OjA0#2=q6N69k1yyQy>B8*W*_p-rHEsAd3yo)#a8%w$h
z7?w!m{T}Q|caK}XY}pEDoklNQeyaVrg`35yW$g>eoVlQ7$$S*KvyR8v)2W_t5d4I^Ijid+T@~9Z%HpzB-==6Q6<7|FsEPt@^AI&ReQTpiETag&albv$3k3v|3t$BT5_A~C0a
z#c}G<)u(0?Nlvc%kIWxwp(l0xV;w)G{VJU*UCD*Kh|+rWNd4!v*@Ut
zlrlSNGD;scTE}a2+^yraI!@?#-S+LZ4fh
z(Bivs)7uWYkWq|Wg9JLrUm}Gt@Jp@Swnzkq@Y4Wx
zF!J^Ny~gli!k6>J9Qfs4S!;1aM2@N_*W3|tO)T_eJ)8Idc&Rp4sCs~Hhq
z%ZOYHt^?PDE#L<5PVg@9ZcfiR)hjKWQ(aY&QLnmiPW4&}=TfiOP?!8GBb-ycBEmV#
zUI*cv>QxZ=72y-$li)7!DR2k)IJg_!13nFI2X}(cfPaHmz^mZ1KwcgBJdjsOz5u=m
zz68Du?gRIOkAeSy{{miOP!=iedJnh}+yrR5dX4G5#P0()19YNZZ+buRE#L#-RH!{FQCE8wf(JK%TV_uvoUyWkP_
zKKKE63_K2=06zo|fw*5
z>dO$Bofj)2!NP`T>g0nzB*Z?+yO@RI?dMq1ZpZ+R(ZHZkqM$n(H>GdV-qU;r>
zd89RgW-uR|2#U?SKTOahZZJ=hOS0aL;LU>Z08Ob4UEf#4u;Fqi=j0f&Mk!BOC7
za159YW`e`Pv0x534m5xxz$|b)I02jpP6CZ!E|>?JKr@&R7J!9d5oiI6!O36=I1IFc
zrC=Fo1E+xH=3*}!F#~x
zzK?yTGTwP2g^D5BLK3
z3ivemjHO1IE*hmB$iC`lUY$Sq>
zMCkhnHW8uEBJ_U*+lXKbk-Y)-6TyBW*iQueiJT2OKn$z~r-QS=nV=JNfjC$N-U8kV
z)_`uX79_wrupT5q59kFc&c1SO^w@7O)tc43>aauoNrb=WpsurqXe4HwO}0;`U(;@lD+5hGF<=fPsYHhL^S1x3x9#
z3vuuIftt|pQ(4&Jp{0T5`09TCq#wS4Uo+>-S)J(R89^9^u?E7wO{MdzhOq^dG+q70
zIj|>pZhxe@rInm1+#LoQs4i_|Xc(m$8TkJH@>2<2+sF?1*iA;Q;BcfhqU7y=moHfz
z#e|Pt9LgA;G<@tbJo~+}t(GgF$VNXMkV0-~0Xbb%Fy0|7AiRgk_o%vk84Az!>hetriBki?
z_oq(jkcS!wH4tiG=xHFlKDhU3crTRKOYTysU#s$dy(-jMsm_?0MJ)t)vi{m*iCR8T
zX1lUqMO(^TB@&jYIlE-$D_hy8s5!Z01}vVE5zf--XY2ShoxW1exFV)}MHMfshWZZ(9C4C$@j1o-3OIX>mw7IuG$t*Ns2sJS5HK3+K
z6rT&fZ65ZvFsv0I?@p-o1%|5@!gnWzYtI+AJAZFgoE+|j8VEH|q=CY_6H)bdkIZ#H
z?7e6F^rmIa^QYHOZ=SniE>T-c(~9XuY8&D^tgJeUm2G6fAg|R`<*!l+Z@4C$Z-wx8
zdxhre_iTo8hS%#n_VWkNbB7s2UjyN%a6`Y3U;h@GT(XDoH^pk5wA`YWt^LVt!dj3>
zXR`I}@$Q~@Z`PV)e{sjftiGkEFO|-!r7v6CRyud*#gfTXs<(boJlSWpuB>mGDQjiQ
z8ky|0#WJ0-q}p2^-(t1RU*J5nr~*gNUT;xGGPN?5PIfhPTCMF%>YExUsD450z#|i9
z&+a;?L9VNkzP!ITo9Ky?X(z?9Yst#X&UDIB9k)_sM!$xnF0Z|1*{Q2UN)=aBFDCu7
z=9H$WPr4m?5utqB^^R`4?18zN9&1(8vIThssPuw9)Iri>Y75V|v?;%*=CNE8>x?TU
z*e!M{!+Dh5o?J?C^-;8{eo>ni%w1v4DJ%$8d<2>0N4ORvXH4;0Y->q}{v^6
zy=7OVD5+G8a!bV|sZ>l_QBs;DInAmscTnL=8O$?RiIPNJz9Y3zk&?u6(L!Y$qLR2U
z))Q|^b;YH{8{%nZC$$zN0k!N?AnaAB9`uEV%qk2Hk;_}&M^G4yl`u*uTSmG>rW)Rn6);Wj%6%0
z17mkQU2h*_*~2VN@8g)X-d!0>_o_o%me()qV}wj>Ax{rPd0D-m7naTtdt4arm658x
zIgyEFGVz|(Qm`cGIZuT$f~%yqbZT9^Gb@~tjpp>mlNLif1?d_sSkb1F<+z2()M_pS
zg-Z1#db>6kTFygQYt9^o<2l0Qk*xZhZEmt}ZEQh*Z)Za%KlIH@B$KOCu{2i)*^}S@
zXzjezrlS4!zP0gmTqQN(Y3Z0vlZn2zB-OO{Qp^P08q2J=_xM$C0RyYrX^!`0*V-%{
z+ZaO$YG*;J+m6$z-fUiYVH~}wbQs;}pl7GLllJZsx-j0GNw9phosdrT_bJxW6YI7Q
zm+LErlGe%gPJ3TEk+t)eB)Zqyr7K3Wm89BfPxYsD<>{%ozIxmF%bHb;*~im~m|Y=u
z(g|Bu!Dw|ldSslAgA#{gk~vDPb2Qtp`*#KR0Jh3j
zq+`9AHK}xuEhBqL|kq{
zFf+xL$75Yu*s+@N*A-BeQ6Mg;3{3)BT+tU*9jRg(cDTQuS#@x=GTfB?W)oy+w)0d2GUc#xI
z9p0QyY>1bhU_nyMt~9l!H^WscXR#S)DQXPPU@p$Yr5jeH6YbbspKVIEcFI%NGJy1=
z=3Gtfy@hm?Z5sCel6Y*5R+k9VcI`rTw%RZ95j%ZF3Ud;}DICz=8SlmD;~Q0R`MuKS
zw)dn`*|m6_vrS6nm~yG`3I_Lhp@%Tb&h-p@$uc>u5oek3{#Y`zJbq4pA|01I@FLyH
z+Q;)ZkUF<3)`#V(T1)jc)xTp&q}HsqZC2S)nnWeuox}ziWi3V0nRKVMtS{cXaEZ44
z_H6%ZozlwE(CN*N1SvF;wNo=!iP)zMzS-F=#&K~3H*%c{!kJ*d6}`x
zKyDZ0;s$cNBDcmsZa3t*4dlinx7I*zcjOWVaubkSXCSu+a_bG`SR&C%8pyH4qSa#{
zw>NUV268ORXr&C~SklqzGmvBXN9!B|IhKO7(gt!YF==HCj8p!R3T)%za}mR7Z{G>~KYRqHAPIhH=Pt~QWk=~U|)138&O=^X}gEVpW1Yaqu`t=4r0
zaxCj=U2h=A(y`XF6_o3yy!#8~mECHQE$gzXCCxsQD?cX1Xi7cl+x^@22
zQ@JFrmfs>tyR3c1@~Q0K(AJh(&Hm??C%RZ{-TGQAo|RGWQS$4FpXp1-SsdPaaX~UB
z$NgnRYn#aZmtVm%{N+2UIi2EjzQ~m7wWR7$olqYXvJgEp_^h+!uf5w;)>cdYvihg+
z$RXRevmK>)gLPoNTG*YGLoM#gB3DSdwbg2be_C@Eg&%#F;+Dmt?^ZM-LBGW-o~84`
zXqakXZ8qCCXXeaxu??|?Oh3P!rFv%adPY}&XErl)UDx`Vvl?d2>`HZJX2$vw^0&@V
z3*oEn`5qniueR4QG}fpOvPU#pEC|Iw8P2quH;-XSmQbuU^m)f4>fYd;Om2II>pOu>odF>9_#JmJzw5DmRG$utM{>a7oNYtx*m)XW}2Yba6SklJ_NA%hIlo)zWAJ$(E2m;XBKv=KHqr-3gqXq4K;L-&64V~=d#{*UnY
z;GC9*U;MQZ<#zGZy|*2+b^G?u$#o_S!&3u4t}VBVr|-S<_Gh+le^RE;4#RNNK=|H7
zzSqO|Cc^h7^2QJnrGebvsg1H1zBi$CGMqO#dq4-_dlSRi5Omue_7J`|5!!=#AR+JB
zp^EUmiO?RL_F(oqdHCMMkhYrK^`bF+Z(>OIvuWcT_7J`|VXCwtEa$L?@V$v4+|Q;>
zbJ#=p-h`>rhOk`D9#j*<@4SX^PrtUNC65T+SXE!{?Pls8?TmQylgXKCgW3
zY8*00I_x2QUO8lX^|d#|VGrT+%Ga*OA#-HT9#n&P0lRF)wIS2eupyxaf;Es|?%_NP`ZkTiJ=CDmj-0rt_br@>G{&cr1r+CB7Hz1SEV1?EK&7tS;ggz_``xgj)XryI6ZYMii0r?+OSJS(k4&
zx%q$}3?H9T2Sgg-vZf#*vW$(a8%T(p$%fS;l>9pQp4R2EIz>dj%-^do%hrlq%w}(4
z@ax&giV}p#2iZ(avLrnGQ*hSYJE0qXAAHgTYaIHGd;>mN78Qj5m`yzuqmGf^z|nQ&
zIv`)|OaX-GI5tzQ`}Ze3D(BgM`}V&*2cHF>1_)8n{{b&6okrgRpKh-Q8I{@|Xw`n?
zFl1yki-SNT{AS{VcU~OZ0GE2sXxNhIgMSTv2p~kCWFu?45u#GJ2FgdL(SN{as?SNR
zD*DGdtY7J*O6n_hB2>xRVuvegRkacyp?N3qk(zHJK5A~8tmIL375wOht2)=iZ-F1v
z)+AC@ce9xt-6m?S`X-xWK|TCwVm)0+ym!bo4sX0D=E^|{3JG{2Tu)dral!<%*by~Oi1{|T}50ipU;HVYNC
zY8r?aX)dxYny(;Uta+UHWX)MO#X=tvYA$9Yx+BzxUo2JBs@X;?_DZPvB%3xxt(yCZ
zPtp7l;^mq@ODydq)cl%_oSRT1E1;aJs5PRF_%zMO6R*^K8u2R443;+IlugVemuQ^eAf8
zvKovUza(93A*It>iTgAcJ)NVuoIkDkCgP0d(x+L?rR~z+gxdGA!51aeeuB+LMXlP;
z6U*_0+OMb;q;0L{Y153GthgZgZy^>C
zMoPOrpr|$StHifzF8#PobLqzqYW{cP57~UwSmN6>pF;d$&1VyTMDupyk7_RVe!J$P
z|2s4neSA#wZNztKemAkyk1$Gn>Jy4uqr|5^srgI9ciDWjM4!@pCt^9CFnT&0@lV2N
zv6)XRYK@lh<};di5`R|n^N2sEx#&&$n=o3+zE@Fe^f!pVpt;oNi<&=4{3XqQPW)xf
z|4MwH=C2apZ}TxDh`*xwp2X5l!kB~DJSYr)92@By!k8vDVsnHsi`aZ!QESYp#8M~1
zm>8RHDr${M5kI8)R^o4Iel79Cnu~pXTXX6E?`SUl@LkPCPh#JMF(UgtMXfPEC4N-%
zmx)CegfY_IA1G>#`4{nHHXkcC^SI`_6F;H(B;p@xelYQmG(VPDbV?X2ZU3>N*4P%}
zr!;RTep>U@#NvB|u^ZSttLR`hk-;1s9vf;P)Ig|#A)tY}A<%}f34_u=xIXKk)E6Es
z8VJ{C%|Gb~G>Ga_iSTB$R3ii5Kl|)VHkQr~{J_c`!5co6D=aK2)W8tdK=^LQ5boTt
zY5x-q*uSjSO2lt^gQ$YKmhJ!-)Il^ssQ?{B=C7LXUQDATt6MQPIzBaWU1VhRT*m>m
z;hXyoZG?0fYM?pZBfmEc-=N;yU!CZkGkjGLwj2!%=8_sJFx0^C(Lngu-SFw_u%&N|
z2JFA??A0L$cg84hBaRwe5&CGkB1R(;^uPFl%O4sxvb))|Z(1rfsHY#d%~PzpC#OweJ^kjVf1J
zpZ`w4O%F_4q@
zLO*IC_cP>fH;|KeX+LHl_Z)I}8pu75+{X>%eu3O44CG!w?vn;`zeMgX1G!%z_bCIp
z7m>T$K<*{v?lF-2HFBRekoygCpD~d8EpneVkdt?ZKW8BKJLEoZAomC4o-vSn1-Wk*
z<#t-6T!Yf-r=4M>cM_s3YZG^2h+d-U^+Mu90U#qGr%F>P|yJ6zC`Xh
zMgWFab$=xHK5}0(0UQS8USlV)GZ+VU0lR|Tz<40pMr@=GeS@09^Q}8qJ
zbMPE^9{d8l0DcL61zrR%fnS5)fZu|b!7KJRbhOS6(oZVXS`pDrCa8ar6a8fk&Vjw4Wajt=!*v@$da$<|;8_0>jTwow4K6RmiocP^V
z13B@{iwxw%e=jzW6Cc0CKu*SiOAX{?tazJ&oQx-z8OYTmce#O_j7wJ-$jR9Cb^|#X
z->x)}lQHlr134KduQrgAvGf`Px#`Hg!$3~Px1Nw2}7uXPy@q5
z19G2IdOvwMX-9w~!BOC7a159YjsSG5ug^(<_LdFMEF}G!ru}R{+5XFw?t$ournA3
zb^*JB-N1OTJD33W0DFSHz}{dVFcItvCV|PI9_$CEfT>`AFby04rh@~)K|rpzVR$1n
zkpFAzjW}6&j!*+{S`E0o+wrDtOIYzx1EB^&4Gc~L`Fn?OcG|%yGCX>iYruZTEy|==
zsouD+E~;8v+tR)g2APe>teC%QMMKhGctJA0slF{8=PjnrcqWr7J@M9DIh*~>#AiyNr0qqVd#hy&BY1!55gCtv5)=R^D
z#hQ|tjIRKhCgm(%mtNBVg39vCmmj`bS2oG>r$L1dj$YorT%KhODs*tPveeaUeao2_
zOD0p;*rIr{&r491)7|Nnt!SMx<0ZYqLFrH6m4xye;Tc
zBa?ntLoe
ztZxV^M-Ju{(0<=S3^F^ANoUgj#%x%Qh&6O3V}7HMNxM`z>tX>t?_a4#oo&yP>n&?i
zAA9Agqi3J&by=z3(XJ@1txMz=0N=1AvAVvcr!SSx*3&e1(bl#lftG4iPKB-n%jPYv
zcduz7wY6M;xn%OjChIg;)D^ur;8GafvFUP+^=H+-^
zkX1DYP>ydw#^uB}`Ih6SyIh{SGF9wOB3G(=9MrCH99GdgfB@}KpSD=0GnVu*L{*=@
znD1S!c{!cFw|+tT*_zW&U*}ps&oD2i&-dyb)UJGe0pj&xE3N*YXOwdsQ!26_9}K{@svQfoZj?eWlI)Q)zCv_oFG
zD|IEP)ZcKG8d)mvx7Q$zRN1;%s);8n;ebuxYP6GfG>aeL-vn*;iXP=^7~tOo-sM#2
zZ-O1tlLJQP{5^uFb_RG49$1clh0N>Ye^WPra(oLiF6Yg95AM-l<8ZhC%{{nBg>v;V
zz6TE~$M7E9qnNGv`WW7W2bN=c5AI%2zCM+@Qu_X-!|R!CO>;9nD8VOG>K=Sm)3U&4
zKO&RA>vdPr4)>JOcUwQc7w!S*
z$7=;*PDC))b60%OKQyU!4f3z){FU4H8I#?%pslKpznVoq!~5x3*4LbaRIKt>CVG!J
zynfT{qrC>s@dFwWD9G!yb~%1e4ILIASdRY?mG_*$a{Ntf0Oj}=WL!?AJh@U&Q35`Mn5w47&ufp6?l3k#aH4UQhu`G#|+@zDoSy!h)Nv5yH&pBm^`ft`o*S$8Y#=D)VoZB
zdPr*^7?C
z`O*UnWw>Pz_xaM*Y@oxf(@okN{sn5HrBEi+K&XMCtby<^Q1{-gVRF7@?F;LtukQEy
z^rba^r~bOL;W?hX1G%WIdXUZQ8zLtWOinRox7+U4a$llB>YC>^UAE0UMoI0%afTay;gj1%E|1OUMoI0<=WWs
zTJgatC$nUFt@z-STh5NxiVsdXc{9&z#RsRH%*N@p;)7F8X6*D@@xdu4vwC{1_~4Y2
znLoW&d~nL0&W_iL4^BCmLDXx-2dA9OGU~PBgHujsBK2DF!6_%Rm3poC;FOaYO}$op
zaLUQ7r(P>QIORIn@mlf0DHmhMYsCkrocspwwc^8&ldHC8xV<50+(1so%y$~dH6r&e
z1G%}#z1u);9&+z7kZVHjMguvSIprn;x%tSw*Fa9*<$j-m+(P7THjrC{-1`mWWVYd3
zc3?Sqdo*z6E$m8e5CT`;LQdWq3tV{%xdd{7D{mnu@5nq@&|ek1ba_8qcOv8{_Hqnfmr@thXzc?&5=m)#+Gz
z^PJZ9B{H3Kr~T1$7t{X6y5i~3dWMko^_7F9*htL{I
zR5+w|9rh5h?IG5=ti8Uyzfa~y4*Pycb+$oc9QIJ9?7`reP-N(8AZHJ%g|ZWdPy?X`
zLJbUO4TNu$4(HxiZ4ZA3AND3Ncm;&NgNNTV4&I7}Utx&!1jDy?O46xkPO(O)I7kq<}ZOY`C6jxSpwp4eL3|JaX;ia6Qv-JyS0O3D-0A
z(u|!RzR7$NAxTqT+h_jL;2P*@9gWo;y|TVwyxC51>t(8;d-X!
z9$}|2f}5>a@n&61$-~?8vl74I^RIhUi0)8x#u~4s6jYAk{OcaYY|YolaQ^kca!lu6
zcP}VkpNg%e6s~7V7ng+&QUi!bZ^}xI;FTI#DzGBMAdOV@LkC+EPgcSKn{Yi-KLt7dw(wlXtx|szn9P^&
zS69jF02N&!B4Aee{5__pc65C@4c9;lEXTh>=Jn|lb$NyXl;c~FaXD|+dvK5b`rqAy
zdsK*?9@ss2P&tP8;2y6`KCS-765mrbiH96zRb<(s7EuiP@9)gXg?#q}?QJEU+uQ-2i&=7#H;
z`l%>?5AL~|VD4`e!ZW?J~TV
z4=l&@Uf#W+e0{?8OtHA~(590bm@c9`w~*p^_T#STTsh%-rUj)HF_U#Il_!VmnHK5I
zxf8BuDy#fDHB!zE-;MDtCtT08T(5w7l5k(}_oeE)Gwl-IB>7SQt|IvZMWSR;hPz!uRqGu1o=cjpv`Y`@Hq3
zMoiOpf&$C&uaJ3td|%~}I~%k2={pU7M+j=yoAsR_k9OsMSq!)xG5#{ozq_QrhW9Uv
zeWt%7xOdoAt``-(L&}8j<)hNF&_T)o-{o=dFexW|FTYH`<_R5$R_YFEhkTp2+y6?r
zFxC@qN_EBSn^L_S;^}O>l6LHYVr>Pi{#
z{GM9O&GeuIpP>4y0#7?vH7%31X?=spEU0hkkr~^*(ZA_$i4$GymEWk
z;a1AdmE-rVX^=hV%gF{@Dm~ibOb*}6cWR@Q=X=8E?OJ=pG<=>OR8II_e)wK~sS&at
zWQSXku}2oudwF+5%$F0smybrvLz_+t-^(x8jh%v}$~#)V?=hP^tqOXs+QI3R#fR_Z
zdv%31fOmB~`>T=C2k@?rXE{CzFUyXH&M=)-{HLd
z>_1{4w-LEV4dgZ<_k9DoEyz7)Aa^cuj~mFHhujkea_1xWLj$=Bk$ciWPWtc}13A<3
zjO6AnZEulZ%rmKEyuP(RnN7@T>d$0TJ@qHYH*ZX(yE2xG$lOl(V~jVHvTI%QSH#lY
z@oas2Jey7QcDsr!NXQ9eeSKa6^ZFCXuKM|#vgw#>0X#~f;$88D@m{woN_KN1!>vHP
zXLXX70bH6PGJ1^ykKDF&YF)fD>vpjHI$e{!2DfYRw#3R&qs35?kD>F1H@_%lfl@{jQZ$**=w5`KPtIo!K#qBpuuvPr3=|chme@uSNWt&u=1r
zT`1W>T_`f%T`0NyTH)FP$@1=9j^wu_Zv}AgLe+cvuwvJ~=jqvUX`HtNe`otOUb4L#
zCb_xV>$qNd)RIJ|#2}8Iz24uYMZnvkCD+%TMZm|ICEMGTCD+rDbD7>YkdtszR4y;4
zrXnYkOg{%MlI!V)`Ap9WySkwq
z7T|^=;_HSE0q^D_i9J>4*$=~-b{H;rFTpYA0-^-nfgxnpIDfeD^e1!rY<>trY`w`rY=GOrtT2&t0ZFBhx6%Gk-12AkfKG#
zThWqRxQdh&?$ZYxS$ZWYI^56H<$@3}s*8x9sY`xe1+zo{1_ysSt`xSG1;_?f!o2b#JF1(>=+#IKTKi5{k|N(eCZoQ$`kJxo1!
zpidw8nYtYAV(Lsf9efK@BIIK3B@*riUn1mY@+BfJMqeUPZuTw$E{5+SRn#Lc`NfJa
z5pXqsSD6yqDwT1%KuMm96O>4Jxj~7TyCb*@`B%5x8A?lWcLx_KKlK;8gv-IcedFR5
zB}Mo<2FH6`1suhQkiTPyM4)4cP=I5Ih`(cqgs)@d1pFN%C*{>MxqMIMi$IWL6lAhDaDVhKL0^hC|4|x(JqBB}!~X1cKEsQhw@}{K9RK%PD;OhNDYwjY^8}
zcMSQXxBQWZqlmnKXEpK?`Cso!4tM=yzC@<{4|*2?FEvUH%Kxx;6o8ieTbUQ|Y-L`;
zt(B4))Jl=@ZDmfttChL@;wt8^{c?9u-jn6oL5JttS9GXr>xv}G+g6rc)UvYN;)*$X
zPg>@F3tuASKX^+qfrGaQ1q|LI;y-wcgzw;;6Yw8Ba#BTVD`~Qv#$RzWo75piKl_#x
zVh`}%qoGu!=*57NGQK!cC&cCtL**8CJWr
z-{5e|w`VF+FL=0RJ3Y!PzoVB*D&J329P2$kkm-N*7J-2AK}7tZXEAQHaggA(u=AJi$l#|O#w8y|A{zUGt@@=$j!+skAmKVW<)
zhO_LoVN^ea`Vg9Hhkm%f<&cnWFK*O`vpqaFZz>
zAKWC0#s@b6Nz47s=apaN;9f#nUtZa{K6lG6ad2;uyk)zJ*beTNRpj7q0!|0_%=c?T
z&cWRdE_ZM@sZs~`k?~c7)4^TKD0OfzA)gM-Ik?xMewr$BaJK@A9NbNy#KGM}oDS}l
z@6$e~gG*b39NbN&$idwNN*&xyrr5#VB#Io|O+cETb8xTxA_w;p()#ks&h@!leu;y7
zi{vfaRm661x2z%ucN1_rxM#j!6LJpjc5u0ayGfNgxQ~pl8ss>?4wd}C4izDv4wY=V
zf=gU#{3=gBq4UTuT*2K0iX7Zcpv1x5M4S%pmG9HOAO}~yy(HG#-5=|YyK131zPi7=
zJD#q$-Pl!T!HPEhr?*=b*^}n2Ng^l$34%`OgI1PHTTc?<*p0EvwnG_Jw7)Q<7FRx=KRnXew#N
zqo<@4jh2#7+KrOt95HkIMGloqbgiu%tt~Gnmm61Pzho#ZB;|cxCD}ur(1H=kUU{$N
zQ}gDUPbuk_e7gSNFu(7tU#V4!Q2F>KsU=-1Nz(JVp((dtra4y&%t<>mCvq|d<+7Z$
zB(E^Wh`@5^hkTMyGKNT!bIi!?mpNB1!?kav1V;^J*HJ5)o{qa&tDRA5vUaMA-P##t
z#%m{+TCkn!V#anxi7girOS`3zwv~nF3|9*x}ZDHH^otCcC^X6{v7umd>
zZ6Wg(IA`Z=UDsUnG}#7in(3MRK`kkyz$e
zq`7$&$)!G}lgheKr@OXT=Q+Ahr;P=@gqqscoBQWK171M2jwz~{3n;_;yt-6
zhwtQ)N~-SWH;B4>4H+&zLu#qV=p;8~dwPpLrdZidPtgJ;4Jh*x#L9exG#3vcwbVa!
zlB;**MbYDKLTnFX;qJ&*M#!fHzjM^{u8kOYkH-)Ss&nYCk_)a0y;XQ@Kvc|Z1kP>(I
zA(iFgMJm12kMfD`-Qnp=`Qu8v!|6|Xp|U2G`IHhZ^D33<;#VrY)U)!5uD+Ge^|r1O
z|H>bct9^64CspQMDzV73R7$B=sl;NBQb|SLq*6*fNhLbHD4$T&W%<;y_T_VQSLOGM
z+g0o_N~pwJ>@?d`6fby*+Aa5xLUP_a3P~lNQOM9N^@FwKB3IA^EvLl?y%^*WTAFExo|OO
zNiDHwNh&vJNiDT#Nh>jFNh-H#Ni8<&TuMn-@VBHb1&
zJ(pcv?-E-Vp%P=4q%v!l#A0*LrMTF8F3ZCniYz`So2w;Lat(`+o5yV`t&QpyHxXB5
z*4D|?wrfCjblbIu5nm2!M$PT&BEB7rXk)G;;)g(OtSu$;?fn+iwYFqgWj!ME9FEK`
zk2Bv~WIB9QYrL1a;vy~Z(OEvGg3AiuW1!467kL|eY$_Ay{E?5qcS`0mMs)Ghi+
z_yjHgUHBf^rWMpb`XYSKZ1S`iDyV_)mFR7vZdKFZdpBj1%%NB{AHGkrKRy!P4WF1C
z*-n{Nm%;a45oaDItLnq>NzLgP`Bh(sPhOFZb;5rHuOCAO{O|DnXvbDmJRUx!w=3QS
zKMFoorgMU?V6%U8+bz$*Wqv=Y2ch~}HU}tbRo_D_`Xy9VvXoRe>ENOLjj>i=D2H6)T+6ec&2R+HJ^naX4^x}kKwayd#L#*
z{BYYIM(hPY!nTJIN5hY_?P0_!_))e!jF841ZQH|$Yv9M&_Aug3_-xxAMm!8Z*0zTc
z(l2vtd#D`&KhCy?+Ntp4ZF{Ia34VfY54C5)Pqh2DR@!osZ4b55mPXqiYVU*3we?^7
zEPS4p{};T;wuib2@MhZ{>Sn{|+xAc={j$KehdP;`aiMJwb=Sie+4fK;{nBFFL*2LG
zi*0+TdkKEBZ4V=>;Y)0L7&!&r3a-O#jw4Eo+#8TJs90IIU!5;8g#HRs#ew38G5=?~m5U*keKzw$T^vmhk6m~L7
z`sEB+(FXny{4H%O>s#P2z|TC{nis>Rr7dSA`=kw{r7dses!cSyiOt!``lHd`=+*EJ
zSsMqw70z*D|D$h#ueR-f^aJot+x|yOzjVnB1u|k|%*j{Z%#g7se2x4#0GEF0mN^IE
zqMNnx_ShOYiVZIPvS}^z9>US1wOOWTgiGDG$jplHYvAYFbH&N8-08wfjJ&*lze@ZboA0_0@r|0x7$V0L
zc0G%Y)RnO7d2HUNsI}_{h^3DSyFSR~{lehSun{{Z?D}suB1hP5GMif!wRW3FyiM~s
z@dq^*9e+skJBV-7{2}5GYyLd(M{GV`qK|4`Pkg)Pjl^<1VLbL^iLDdHOMi+F6UNJN
zA6L{G|1IKAX#Nth*b`y*5p3>K)Y|=E;!kP5i1=>JyNU17T>AObnoHSYH-z24$>y_)
zTD$*>_;WU&FpBu|njcDhujXyU;xmK^DK=kJ)S4ju`6bQeoYJp^36HS3Pf=^a%fw<&
zggr*H`HG^}9y5q#Od;$c|*nYpt%v-zo_);?zv|4j4qiKR}2eZ=0M69yMuicJ&tk@y#iS`({?U(j4^
z@0Xe{BNiJXOw6)*QBiB6__WwAVWQZ@uNAc>N*#Zr`9Fz8*MxodV)L@1*1pFP|4#F>
zh<~s71;l^Qd>io}HNT(uPnt`e|7`O~QR2U7E_(i}=3*Ov(_CyrbVrzU8JoW=YE8P0
z_#c{!9Z6jYlcXL0Qq-DUNBnQi4ZY{wKExg
zMRj_p@71-6JFI^!?CzWR&J}
z;G;EvD}0RR7sJPD{sH(-nm-8NS#$b1GS22xI4&YSLzprPzN_ZT;k#+R2|ix)o8Y@^
z{yDhVE@29O5ZOa>bRXH%=2LN=h}a5Y>WOgn6+aukkLKt(GEsB%9NAa%hv1Vme-S>}
z=KG_+NWJFM;QML57%p~0*dKq4Ox67D@clLa1e{|e?9X@*p`R4TuGQaH>`X(ikpu1Y
zX*1wrD}-rF;0J4tokYl!Fzp@iLo}CuJXCYhNrUFtX=J9&51`$V!!(zEMDG#~I1PTd
z<{RKgXwJAAIa2d4z>m`WS@_YKW6P0aY(8CdK3j7s|5(k%PS}?){X+P0n%@SOafdMd
zoA47f7oF2*5)K>zKS^`Zd86j@;d3=#2cM_8=)6hukHMQYe+14k5)NcMh%B)AL8IUc
zH5Z-ZGZGFu8Q!9K624gTE8yfwIOr}oeWUo}@K()5=SyvV@C5iW&1rX}P4hG0r)VxZ
z$L=K@{2q9_=J&!^X#N!ZRLw=_r`deQKJb;Ai_TYRF6E!D`2}$HCCs=L{ua%@4wtc>
zFymM7vuu8d=$t;2aL57hvo#l;cW54m$27kZzFKq9d8g*zhIeWHJ2=NkICN+D8qE)e
zcWW*>$G#;Tx*nd;{A&0*&F_GdC*jaX;q;B-e}OZ`NoWwA_iBDLJf%79j`V511%8g^
zqVu%opND5O|1mtP`9I_&Npc;de5m%uOA
z9Q{SGZwa&B4hM>V3eNcye*%7$=Kp}xHxdrt1AdL>_;lnQnv2e_)f_!VuG9QR`1P89
z0e*w#Ps87-`K$1E+5Cu!@ONu2I;YPh93kaXmg49sa+BuU;P2J^8}RpO{v!Nln;%&V
zf4}C_;kRfmI-$=b94R`#Rdd=M*{1nj@DFPK82m$;{|m{r#SkE
z+^zYS;P+_$Q~0Mf{}22#Ha|vmPCX@ISz=G)+3&|Gx>Ma_Q?
z=X?@oPk?_}^ONBBX)ulY6buV_wvBM)dUw(+3mQs!4R|1bP&Ha~V(_}4YxA5J|a
z9D5Y}o0_-4AJY7E__s9gg+HwM&Ch`UNb^4UlbYk}5zZ%J4t^7PN^=<}
z(U*id=qd7y=A1wBtmZ#~0||4)Zm|Q!#Rh(6^W%1c|6KF^;LmA33;w+3i{Zb}yc7O{
z=4tpZH5WTU7ZQ%c{~|AHjtxd$(i|N}eyurWM}DLEKj6Q$`SIi6FKaG(quvsZ7hA$6
z6h9082hGoc|55YH;D6Hm1MojL=lZ
z6X5^UydC~8&6DtdYc6($9Y{FgR`{!$<7W}{F5v`hCxT5YF8#9I<|h(GZEBsk3p}FJ
z4}j~86OV^i>Gb9BYR%WdYc#(QK0@aO_6$WpLyaUjwKA6yFS|4T@h6-&ONZ!gtgB0r+^$ABXR*IW`iVpgDSq
z?qTyr>Jr^k^L^oaX?`?(Z_Q7J@1wcYXQJj(AC8gGcny4#<{ySn*8F~Wz2;BA@dpWw
zFT$s2F7=se^SPW;{kFmG+(Y2ltAx3tAM~a8QuuVuSHrOn~6zM?a2J`epx57V47qO&w_h99o^Ti{1%eh&Od&98(XrMc7r
zol2PZMffqAOC4rw{xbYnn>P_f=V(s0=4=UxA-#^95oXXK6kS&bcKlpr4~>
zYmN@09hytsVw$gmW4jU-Y=(DgejU6^^V{HY&F_PwUkMAOzq&R5Iee|=e}gA%zHl_0
zb4XY?8NOa~v7e;o^k=k3^A0$6BVl15Jf->haP}oEdw-xr#hxN3YcB?}uNd`Cag`PEBq$SKMQ}a=F*S&iG;<^!*AC7RXFXD
zaPnCAEjBmU*75AEhJXCV*C@a9u@c}MgTq3Rp{s!iP1{arlqQNj%*muX=UAEU&@e{wbp%wC<2r8m!MZC}EtsPRsFrOK}Q
zMe$fyJRMrk5VD?}Jv8z{r;$A{?P+KLL&yM1n&PmBsF^*4)=;9tA+_tUhlp(tvCd`f
z_3izAeW`Rd?E4|r*#?bq*h7`F2ZLimk)f-BoIR)(My-)cQ_Sh(7phuY+w@a#KQaHj
zMzUATU$vqk=`Ux`W1f!prBj{pOeR%&;;p%Ic-HF|=GpU|dKR>mgVh&(`U5xDvL?)J
zYg^))Gl0YnWaswv1++W3Kq;qb+12_t4sZF^mG#mvZviPMnbE&xc#D~ovv^&4O#|>Q
zB{*jsBCRW%nu8_%B|6An-o9M_#^*2Vmn-EcOI@vha`F(K7fU8n%*nqf&et&>L6y_3
zfA;c_Ss3f#OSY~!pN;fxh^Mph5|eM_I91NtY|mhgNR_kB-#SeCU6m718DmfG8I<`b
zt*ZKz=&e-Ue2H3`RJO0msldo`MoU|LS>YuKL3(aP{)|K)zr*>5pmOBsu2iS~jncm?
zzuXQo)BJSdCu5Q)SKSRE#I|!
zTvqCLv@1$$>k@v2_76N<;@dv?>w$05PIi}VZCes(sYc~g=t{6`-r{=qnif)9<#We?
zcC{@@tu7q#+E@pN?T}Zd0AI%9?P(G`dtG0dI%mxA(~NmJ{uMGW$Jdd?lMUO|=Ub3*
zIq^-t<@o6?m#3~w6}ywjmFgY`wQC%QRrC%ZKs(e&Pnzp(h^jt)G2gpd^Kv?UZ~cPw
zvo)umzRtCNo?%{2pYPQ>s9pK`1Y9SL?~pQa{bm*oeT|_~cUn8zolRzKGVprAY^H(N
zolLgBBIQW;G@zu{*iGuNHhplzAaDOVD9160jV`q$8nvU{A?=V??n+$=D)l#9rAC$t
z{OvVJBUR?u!Pdl+OKjJ5*S2_>I?3a2f=N4?#Sidr0-EO9aBF~n6L^kN-{G0Lt+#$he$0>pi$fe~rWC{x|pF9u>;f$M_yRs2sz4
zaF1fP=Idj44<1;K={>l6LHYVr>PqSRmk!fOshROnf={T_J@~4oWr5FrL?(aN>#m|5
z?kT0o9f0Fr-lJ9ANet{>-m@I(%1YeJw|d@+Xk*#6Y00VWK89nI)riyp?<73`ydU75
zgl9RGdMc)>mGSlUat!a~J&M_ibJ+DUyq6Cw$Mjy_y`X%3
z0)7mq-_=~#Ip21RRlCwMo3eM1LgE?y$k;pe&aA%l;c~o;c#ou9(Db7bmWlj+c|EO$S_;)f%SSmSZ47(ij*rP-P&q3!auF~V%AY$&K(t2u#H9}s4s{4
zYY)%Td0{k6HLy0D?VB@mrrdQmWcqs>_&$6lU)Xf@cV;s)*LAI*IjdpT%&t^tW@fA}
zF>?qiDa!gP;t)Bf7=leSZPNJZP0O0+Pp_ZeJa@%hqPCW%71K=*9tv_YtHxkM)T)xz
zdMXgS>$1buvzArBXz@OJeo=g>%2ff#jU;2Dft=`YUjw<($W1bk8-v_r139@0*Bi*m
zFGlwn$jKeR{RO#dcFO~Lk$Zu!6y!YhCo>#AU?8^+xd#p8NgUft-Bm^_YR2%((ctf!uk>Jz*dxGd2FuKu%_E
ze9}Pf3FICw$Q9YkMdYbKzx@dEfr4DVOC>+QgWQws-)bPoOpVqy1G%S=`=Ei`)5v|u
zK<*jjZZnX37P$`_$o&Mlj~K}P6uFNY$o&kt+YRJ?j@-u#O9^47+
z4CF`ZUBIqjH!vRT4*qA)#i(!{7zsv!(O?W13)X;cuofi1I?xMJ;13`R`oTu932Xu9
zg7d)n;6m^O_#OBWcoO^=JO!Qx&wyvaPry&X&%n>YbKrUK3-AK?CHNJ15xfL`4SoZD
z3tk3)1b+g527dv61%Cto2mTKJ0saa81^$gSg|ia%uJ`)+E1Z=mV0NQ$R-$lLBF1ai
z5Y9^Es+N4BeorpHUrHKD7{HrOrH2>o^Mg}=QNnB3>EIZX_hN#ImU1K*zAL;jBb6W_Zs`ESEniTw2A_%h9N
zHik<5O
zH|ssPho1j;_uw8C%K3%yJ$O(#hWFqe#ca*j$M7CJupHBSaQA}p^{LdAGD8D>0=1Z%
z>G2UDOO0a{xZ;Mh5~&%x-8&vV5Aa^zvmEKoO5Dqbvl59Wy@JVH<;rvXFO-EVx6j{Z
zb~!uR)3b0^A}`xe{l$+dUil{J`75`)p+3l<>f?KV6h1v`2xleou(JHUv*%nMxxX#^
zO>6+=_!eYbPB<%(|B79{T6T^I-W_j`Ea9v~@)})f*h+%ZPdF=4scO`In@(*An6Sd}
z?8n;>DJz_n$W_fG2K{2wfsC@$N^&yWuTA=0Dr)$Sjcd9n_pN>T@CVlc&(o24)n#Na?qaGD;tBV5Is>f?0zRq`d99U?pZSC>Qij&v)+C9F!9?@X`$0SD^xo$2GMcrpKw
zp1us{b*4YeTl%BU>&bSPl)pD`+gERGTaw9IRlolPWy)Lkgq>bu)1c-%se0s#aCxhq
zu=GjfTkP~N&n2NjC0jeaKwNF7-y>hd>Nn@xrM&&^^zHJdzP$ZU*je7LA7!UMy9_R0
z1Q6Pr*xaDftB-sJe!QfT{v$SvZTUO4z)z4=UXVYPO?^)`BmE*@BA5T={53o+BnjszY6J*QSue=eLdM^swmxRIfZ?#pYNUqKN%2OE-dJ$
zSH5sqqLQuFhl#a*?t2v8s?#4K*7~_tzA#*+)Bi-Q_0zEse!5QoH?ggss%xaqXV~dW
zuO_zjQ@uj^sfutV{mPcZ+kvp&+6TwFjq>zDKlR<|a=2a3
z=mFHtdIb<>*X8ROjeLZJS5>lA_g-SVp3%28!vABZ?lvN*J~)0QVWfQ3Vb?P{
z{~z$}lFA1v^=#~VMjpPo@Zt1PpC;X|XXNe<(j)8>>aLfKZHIqAw~-T7vNh^A#A9r`
zZT=nUC)w$>e=NxV{{KjSt4^0X*z#33;+v7P?eseQSC?O1a}Mc~bh`SQ#Xj%mi%FlX
z)1@!$a+bb~ZA5Of(`%n2w)L~LYZmDrwbMu9@78Qp&eDzlBK;0Ky-xHo)=p1eO8UpN
zyy&y8hjnl5{oJ;{1@^9LL%~&FyV*T=lHu-di50SAtGM|6ITA2
z4|KF1u78a5msE0eJ3e*DWp+8gyodB(t8{Dko8Yx}`uC(=qIbek*hN(L%fHcWzvF)Mi>)3dNK9f-USvI;pDZU(v{9YwnwGR^SWS{rL_*~=<
zcKV+9ab$#@{w-`UBK=LM+k?%CcKRxOCnEk#s1@JW<@}p3nIg1b!h-wZ_WV-S&GdET
zFLwG_lv#D8UCyhdMgD51C-IRQyS>#5mXI!E0U;(j8E4D?{b)EgC!znRl+&its}B`B
z`MaH7cMI|1cKVDy(#0+bchEmIwtQ9M0@7vNB-}-rRlC~dzvBebu^|Z~``N6v({J04
zbj~4Rl%#8aZ#$lJ?bmfN(sjRBTS(9OwaDv!`6zuCq5Tr-E@Wf(OSOCe7NIXCOt_WJ
zH|+CXJc@L&W5PMuMPyGq{re9VhV-2$lX-`o{sVkXf1hjBeV=qaPVPkAqWT(e&my?C
zhj(EkQSnd0s0Y|gvCH}3yGh4~C5#b!wA)p6D>fUgQOVXAX@~ZUuSq(#C1I@Ci7vnU
zXQbmZ5~hlt>~X2;{O^)pr;@Fmr14sx`@*9m?er01x4G+}t_vxV+o^N)75X|@NVmq1
zBR8wBgO2nO!gJR_NBa0nNk2?q2Oa4nsIzWY^(6W|N*_r0%!-1)zfbgxO-tB(Xx`te
zx1odR7?m7}?Vb1c>TEaZV^z8}3%}9+UM)5m-N{aG{v2HU`>WVwbZ0w#gxIOp|99q+
zF6|`L%6V+NsvhxG(sxnGR_z30ZCBRqr0=TJrx4qITHUvmbh&;Ij^J4B@6~6XMf!L<
zz4kC-+uy6#z@xkC^j>0J&ZaX+m-7+U?n61YzgIo~8PdfL2p1lk_xI|?%Shi-B}cB=
zR`B;LH)2?S5Kc!I(j5TWNx^ezptS#QO+k}E^Y
zf3IG53hDdW={KTJ?eEoR{+;wmD%~0-`mp`I`cC>JDt<*6!&s{Av+7@BpY@VTI{lUN
z_nwDI-%ll5wZA0R{{F(-Nf*5n#(Y~g%D<{_-9-9Sm29mSf3p3(diM)R-(ROAul>Dx
z1F})^6T;YY*x3GF9YLN8Z95LX
z+T)-F*BQM_Ow__R#^>lg%Y!!SxFOMd4o^${CVJ1|<K`*h@I
z>?FNCneR2*;i3oZ0{zG4d#c&5@M}B{4{&YsJvI3RytC&)0rMo$d;KbS7vf_L*cXt5h_dJpU2^awFIZqjc*Zv^il0RAnD>9qC_I9d{$K%FP^
z{opM_>Gd6CRn%S#b8
z=6F}JHp^H{cl-Z=5ArzZ%ypvo)Oz?}<*VBh2c7S!jR)X2DPQ;)-t>M^E&OKXowngk
z?^Qp+Z&AL#nrqYJ?UI)v%De8y+kF2U4Z5Mq%Rj{1xmKVlcdOlh5^wYU&<^-*%Dd&^
z?ObPwy&I-{jl|pZK9jS!+m+Xp;x(SB#UWhsho$LJ8NH`HlErntC`a#E9>kn6qxT%1
zmb@i;&*819jbN(jJ%^|7fa|&Pqj!0r{7mRKe@qxQY2BVX2ES8zhqtnNFPQ)z;knCS
zkkxyyxp1i`tWyJ<>Gyo<44QCvDZitbYn|`;O{qb5xAOEuc#HpEqv6a{u{8T9b#-7r
z9Ic9_m$F!X$36?c*W(~vhc~@%uZNFPKB6t}qu=wX74%wnpYo>Chi$$OD~I!Ju{7sR
z_BlEZK1L}2LCiPoqw_tr{wetV9*14t$?ARh%kZ(vKb@7;d*8Eg_7a=bjeSh-AH4w|
z?{V1umyF(1!>B1oti_t1W-+~ARt2Bvak!UWk?4H}XLJuJ-}iY&@2ORvz$bYg6m-O^
z-t)s<@X5-XmEx^F}+;qdmMg!m}`4(-4?DN
z@jPfX2XFKJ+N-C0fV
z^U0}017hX!dm7LDa54N*kAqfY@R#uKhjN~@GFgi*uq5C4jWRs!{XKsp)!BD`4j(Az
z`@z2Rvpi^W7M}EhEDx)s&wXrtAj^Z&6g+vK99~=m*Eqz}2JrsUe{t(uX8J>1%-P-J
zo(I=cC-yxM&!xA!C-nZUJ2U+u9>T11)T>x=7lNn#A)ZHXcJq{%Ue2}lhp289*VKww
ziOgZmSM*wE_R7ow(KO@M`1IZ!}*~{rhmVDpn#o)BX^BvKzj@qLu9FmK#5a*Sy4is4@4V=V689OZ!9IiO(yZ2ZP(;wLe6Qw!rI@mo?z^TyaOv
+
+
+
+ class osg::Matrix::MatrixProduct
+
+
+
+
+
+
+
+
+Public Fields
-
+
const Matrix& A
+-
+
const Matrix& B
+
+
+
+Public Methods
-
+
MatrixProduct( const Matrix& lhs, const Matrix& rhs )
+
+
+
+
+
+
+Documentation
+
+
+
+
+
const Matrix& A
+
+
+
+
const Matrix& B
+
+
+
+
MatrixProduct( const Matrix& lhs, const Matrix& rhs )
+
+
+
- This class has no child classes.
+
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osg/NodeCallback.html b/doc/doc++/osg/NodeCallback.html
new file mode 100644
index 000000000..a5bb99de5
--- /dev/null
+++ b/doc/doc++/osg/NodeCallback.html
@@ -0,0 +1,137 @@
+
+
+
+
+ class SG_EXPORT osg::NodeCallback
+
+
+
+
+
+
+Inheritance:
+
+
+
+
+
+Public Fields
-
+
Requirements _requirements
+
+
+
+Public Methods
-
+
NodeCallback(const Requirements ncr=NO_REQUIREMENTS)
+-
+
virtual ~NodeCallback()
+-
+
inline void setRequirements(const Requirements ncr)
+ - Set what values from traversal are required by this NodeCallback
+
-
+
inline const Requirements getRequirements() const
+ - Get what values from traversal are required by this NodeCallback
+
-
+
virtual void operator()(Node*, NodeVisitor*)
+ - Callback method call by the NodeVisitor when visiting a node
+
+
+
+Public Members
-
+
enum Requirements
+ - The range of values which can be accumulated by the NodeVisitor.
+
+
+
+
+
+
+Public Methods
-
+
inline Referenced& operator = (Referenced&)
+-
+
inline void ref() const
+-
+
inline void unref() const
+-
+
inline const int referenceCount() const
+
+
+
+Protected Fields
-
+
mutable int _refCount
+
+
+
+
+
+
+Documentation
+
+
+
+
+
enum Requirements
+- The range of values which can be accumulated by the NodeVisitor.
+
+
+
+
+
NO_REQUIREMENTS
+
+
+
+
REQUIRES_TRAVERSAL
+
+
+
+
REQUIRES_PARENT_PATH
+
+
+
+
REQUIRES_ACCUMULATED_MATRIX
+
+
+
+
REQUIRES_ACCUMULATED_INVERSE
+
+
+
+
+
NodeCallback(const Requirements ncr=NO_REQUIREMENTS)
+
+
+
+
virtual ~NodeCallback()
+
+
+
+
inline void setRequirements(const Requirements ncr)
+- Set what values from traversal are required by this NodeCallback
+
+
+
+
inline const Requirements getRequirements() const
+- Get what values from traversal are required by this NodeCallback
+
+
+
+
virtual void operator()(Node*, NodeVisitor*)
+- Callback method call by the NodeVisitor when visiting a node
+
+
+
+
Requirements _requirements
+
+
+
- This class has no child classes.
+
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osg/Viewport.html b/doc/doc++/osg/Viewport.html
new file mode 100644
index 000000000..ed736af69
--- /dev/null
+++ b/doc/doc++/osg/Viewport.html
@@ -0,0 +1,203 @@
+
+
+
+
+ class SG_EXPORT osg::Viewport
+
+
+
+
+Encapsulte OpenGL glViewport
+
+
+Inheritance:
+
+
+
+
+
+Public Methods
-
+
Viewport()
+-
+
virtual bool isSameKindAs(const Object* obj) const
+-
+
virtual Object* clone() const
+-
+
virtual const char* className() const
+-
+
virtual const Type getType() const
+-
+
inline void setViewport(const int x, const int y, const int width, const int height)
+-
+
void getViewport(int& x, int& y, int& width, int& height)
+-
+
inline const int x() const
+-
+
inline const int y() const
+-
+
inline const int width() const
+-
+
inline const int height() const
+-
+
inline const float aspectRatio() const
+ - return the aspcetRatio of the viewport, which is equal to width/height
+
-
+
virtual void apply(State& state) const
+
+
+
+Protected Fields
-
+
int _x
+-
+
int _y
+-
+
int _width
+-
+
int _height
+
+
+
+Protected Methods
-
+
virtual ~Viewport()
+
+
+
+
+
+
+Public Methods
-
+
virtual void setStateSetModes(StateSet&, const GLModeValue) const
+-
+
virtual void compile(State&) const
+
+
+
+Public Members
-
+
typedef GLenum GLMode
+-
+
typedef unsigned int GLModeValue
+-
+
typedef unsigned int OverrideValue
+-
+
enum Values
+-
+
enum Type
+
+
+
+
Inherited from Object:
+
+
+
+
+
+Public Methods
-
+
inline Referenced& operator = (Referenced&)
+-
+
inline void ref() const
+-
+
inline void unref() const
+-
+
inline const int referenceCount() const
+
+
+
+Protected Fields
-
+
mutable int _refCount
+
+
+
+
+
+
+Documentation
+Encapsulte OpenGL glViewport
+
+
+
+
+
Viewport()
+
+
+
+
virtual bool isSameKindAs(const Object* obj) const
+
+
+
+
virtual Object* clone() const
+
+
+
+
virtual const char* className() const
+
+
+
+
virtual const Type getType() const
+
+
+
+
inline void setViewport(const int x, const int y, const int width, const int height)
+
+
+
+
void getViewport(int& x, int& y, int& width, int& height)
+
+
+
+
inline const int x() const
+
+
+
+
inline const int y() const
+
+
+
+
inline const int width() const
+
+
+
+
inline const int height() const
+
+
+
+
inline const float aspectRatio() const
+- return the aspcetRatio of the viewport, which is equal to width/height
+
+
+
+
virtual void apply(State& state) const
+
+
+
+
virtual ~Viewport()
+
+
+
+
int _x
+
+
+
+
int _y
+
+
+
+
int _width
+
+
+
+
int _height
+
+
+
- This class has no child classes.
+
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osgUtil/AppVisitor.html b/doc/doc++/osgUtil/AppVisitor.html
new file mode 100644
index 000000000..d001f5c94
--- /dev/null
+++ b/doc/doc++/osgUtil/AppVisitor.html
@@ -0,0 +1,142 @@
+
+
+
+
+ class OSGUTIL_EXPORT osgUtil::AppVisitor
+
+
+
+
+ Basic AppVisitor implementation for animating a scene.
+
+
+Inheritance:
+
+
+
+
+
+Public Methods
-
+
AppVisitor()
+-
+
virtual ~AppVisitor()
+-
+
virtual void reset()
+-
+
virtual void apply(osg::Node& node)
+-
+
virtual void apply(osg::Geode& node)
+-
+
virtual void apply(osg::Billboard& node)
+-
+
virtual void apply(osg::LightSource& node)
+-
+
virtual void apply(osg::Group& node)
+-
+
virtual void apply(osg::Transform& node)
+-
+
virtual void apply(osg::Switch& node)
+-
+
virtual void apply(osg::LOD& node)
+-
+
virtual void apply(osg::Impostor& node)
+
+
+
+Protected Methods
-
+
AppVisitor(const AppVisitor&)
+ - prevent unwanted copy construction
+
-
+
AppVisitor& operator = (const AppVisitor&)
+ - prevent unwanted copy operator
+
-
+
inline void handle_callbacks(osg::Node& node)
+
+
+
+
+
+
+Documentation
+
+Basic AppVisitor implementation for animating a scene.
+This visitor traverses the scene graph, call each nodes appCallback if
+it exists.
+
+
+
+
+
AppVisitor()
+
+
+
+
virtual ~AppVisitor()
+
+
+
+
virtual void reset()
+
+
+
+
virtual void apply(osg::Node& node)
+
+
+
+
virtual void apply(osg::Geode& node)
+
+
+
+
virtual void apply(osg::Billboard& node)
+
+
+
+
virtual void apply(osg::LightSource& node)
+
+
+
+
virtual void apply(osg::Group& node)
+
+
+
+
virtual void apply(osg::Transform& node)
+
+
+
+
virtual void apply(osg::Switch& node)
+
+
+
+
virtual void apply(osg::LOD& node)
+
+
+
+
virtual void apply(osg::Impostor& node)
+
+
+
+
AppVisitor(const AppVisitor&)
+- prevent unwanted copy construction
+
+
+
+
AppVisitor& operator = (const AppVisitor&)
+- prevent unwanted copy operator
+
+
+
+
inline void handle_callbacks(osg::Node& node)
+
+
+
- This class has no child classes.
+
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/include/osg/Matrix.new b/include/osg/Matrix.new
new file mode 100644
index 000000000..e05ddcc65
--- /dev/null
+++ b/include/osg/Matrix.new
@@ -0,0 +1,224 @@
+
+#ifndef OSG_Matrix
+#define OSG_Matrix 1
+
+#include
+#include
+#include
+//#include
+
+#ifdef OSG_USE_IO_DOT_H
+#include
+#else
+#include
+using namespace std;
+#endif
+
+#define METAOBJ(name) \
+ virtual Object* clone() const { return new name (); } \
+ virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } \
+ virtual const char* className() const { return #name; }
+
+namespace osg {
+
+class Quat;
+
+class SG_EXPORT Matrix : public Object
+{
+// private:
+ public:
+ float _mat[4][4];
+ bool fully_realized;
+
+ public:
+// const char* name() { return "My Matrix "; }
+ METAOBJ(Matrix)
+
+ Matrix();
+ Matrix( const Matrix& other );
+ explicit Matrix( float const * const def );
+ Matrix( float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33);
+
+ virtual ~Matrix() {}
+
+ Matrix& operator = (const Matrix& );
+
+ inline float& operator()(int col, int row) { return _mat[col][row]; }
+ inline float operator()(int col, int row) const { return _mat[col][row]; }
+
+ void set( float const * const );
+ void set( float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33);
+ const float * values() { return (const float *)_mat; }
+
+ void makeIdent();
+ void makeScale( const Vec3& );
+ void makeScale( float, float, float );
+
+ void makeTrans( const Vec3& );
+ void makeTrans( float, float, float );
+ //TODO: original preTrans was optimized (M=Tr*M)
+ // but also has the assumption that M (this) is an affine transformation Matrix
+ // can I still do something to optimize the same case now?
+
+ void makeRot( const Vec3& from, const Vec3& to );
+ void makeRot( float angle, const Vec3& orientation );
+ void makeRot( float angle, float x, float y, float z );
+ void makeRot( const Quat& );
+ void makeRot( float, float, float ); //Euler angles
+
+ bool invert( const Matrix& );
+ bool invertAffine( const Matrix& );
+
+ //basic utility functions to create new matrices or vectors
+ static Matrix scale( const Vec3& );
+ static Matrix scale( float, float, float );
+ static Matrix trans( const Vec3& );
+ static Matrix trans( float, float, float );
+ static Matrix rotate( const Vec3&, const Vec3& );
+ static Matrix rotate( float, float, float, float );
+ static Matrix rotate( const Quat& );
+
+ inline Vec3 preMult( const Vec3& v ) const;
+ inline Vec3 postMult( const Vec3& v ) const;
+ inline Vec3 operator* ( const Vec3& v ) const;
+ inline Vec4 preMult( const Vec4& v ) const;
+ inline Vec4 postMult( const Vec4& v ) const;
+ inline Vec4 operator* ( const Vec4& v ) const;
+
+//start of Deprecated methods
+
+ void copy( const Matrix& );
+ void preScale( float sx, float sy, float sz, const Matrix& m );
+ void postScale( const Matrix& m, float sx, float sy, float sz );
+ void preScale( float sx, float sy, float sz );
+ void postScale( float sx, float sy, float sz );
+
+ void preTrans( float tx, float ty, float tz, const Matrix& m );
+ void postTrans( const Matrix& m, float tx, float ty, float tz );
+ void preTrans( float tx, float ty, float tz);
+ void postTrans( float tx, float ty, float tz );
+
+ void preRot( float deg, float x, float y, float z, const Matrix& m );
+ void postRot( const Matrix& m, float deg, float x, float y, float z );
+ void preRot( float deg, float x, float y, float z );
+ void postRot( float deg, float x, float y, float z );
+
+ /** apply apply an 3x3 transform of v*M[0..2,0..2] */
+ inline static Vec3 transform3x3(const Vec3& v,const Matrix& m);
+ /** apply apply an 3x3 transform of M[0..2,0..2]*v */
+ inline static Vec3 transform3x3(const Matrix& m,const Vec3& v);
+
+//end of Deprecated methods
+
+
+ // basic matrix multiplication, our workhorse methods.
+ void mult( const Matrix&, const Matrix& );
+ void preMult( const Matrix& );
+ void postMult( const Matrix& );
+
+ // Helper class to optimize product expressions somewhat
+ class MatrixProduct {
+ public:
+ const Matrix& A;
+ const Matrix& B;
+
+ MatrixProduct( const Matrix& lhs, const Matrix& rhs ) : A(lhs), B(rhs) {}
+ };
+
+ inline MatrixProduct operator * ( const Matrix& other ) const
+ { return MatrixProduct(*this, other); }
+
+ inline void operator *= ( const Matrix& other )
+ { if( this == &other ) {
+ Matrix temp(other);
+ postMult( temp );
+ }
+ else postMult( other );
+ }
+ inline void operator = ( const MatrixProduct& p )
+ {
+ if( this == &(p.A)) postMult(p.B);
+ else if( this == &(p.B)) preMult(p.A);
+ else mult( p.A, p.B );
+ }
+
+ Matrix( const MatrixProduct& p ) //allows implicit evaluation of the product
+ { mult( p.A, p.B ); }
+};
+
+inline Vec3 Matrix::postMult ( const Vec3& v ) const {
+ float d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ;
+ return Vec3( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3])*d,
+ (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3])*d,
+ (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3])*d) ;
+}
+
+inline Vec3 Matrix::preMult (const Vec3& v ) const {
+ float d = 1.0f/(_mat[0][3]*v.x()+_mat[1][3]*v.y()+_mat[2][3]*v.z()+_mat[3][3]) ;
+ return Vec3( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0])*d,
+ (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1])*d,
+ (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2])*d);
+}
+inline Vec3 Matrix::operator* (const Vec3& v) const {
+ return postMult(v);
+}
+inline Vec3 operator* (const Vec3& v, const Matrix& m ) {
+ return m.preMult(v);
+}
+inline Vec4 Matrix::postMult(const Vec4& v) const {
+ return Vec4( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3]*v.w()),
+ (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3]*v.w()),
+ (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3]*v.w()),
+ (_mat[3][0]*v.x() + _mat[3][1]*v.y() + _mat[3][2]*v.z() + _mat[3][3]*v.w())) ;
+}
+/*
+inline Vec4 Matrix::preMult(const Vec4& v,const Matrix& m) {
+ return Vec4( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z() + m._mat[3][0]*v.w()),
+ (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z() + m._mat[3][1]*v.w()),
+ (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z() + m._mat[3][2]*v.w()),
+ (m._mat[0][3]*v.x() + m._mat[1][3]*v.y() + m._mat[2][3]*v.z() + m._mat[3][3]*v.w()));
+}
+*/
+inline Vec4 Matrix::operator* (const Vec4& v) const {
+ return postMult(v);
+}
+inline Vec4 operator* (const Vec4& v, const Matrix& m ) {
+ return m.preMult(v);
+}
+
+inline Vec3 Matrix::transform3x3(const Vec3& v,const Matrix& m)
+{
+ return Vec3( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z()),
+ (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z()),
+ (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z()));
+}
+
+inline Vec3 Matrix::transform3x3(const Matrix& m,const Vec3& v)
+{
+ return Vec3( (m._mat[0][0]*v.x() + m._mat[0][1]*v.y() + m._mat[0][2]*v.z()),
+ (m._mat[1][0]*v.x() + m._mat[1][1]*v.y() + m._mat[1][2]*v.z()),
+ (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ;
+}
+
+inline ostream& operator<< (ostream& os, const Matrix& m ) {
+ os << "{";
+ for(int row=0; row<4; ++row) {
+ os << "\t";
+ for(int col=0; col<4; ++col)
+ os << m(col,row) << " ";
+ os << endl;
+ }
+ os << "}" << endl;
+ return os;
+}
+
+}; //namespace osg
+
+
+#endif
diff --git a/include/osg/Matrix.old b/include/osg/Matrix.old
new file mode 100644
index 000000000..0455d431d
--- /dev/null
+++ b/include/osg/Matrix.old
@@ -0,0 +1,184 @@
+#ifndef OSG_MATRIX
+#define OSG_MATRIX 1
+
+#include
+#include
+#include
+
+#ifdef OSG_USE_IO_DOT_H
+#include
+#else
+#include
+using namespace std;
+#endif
+
+namespace osg {
+
+/** 4x4 Matrix for storage & manipulation of transformations in scene graph.
+ Provides basic maths operations, IO and via osg::Object reference counting.
+ You can directly load the matrix with OpenGL's LoadMatrixf() function via
+ the public member _mat as the matrix is stored in the OpenGL format.
+ Caution: The disadvantage of this feature is, that the matrix access is
+ 'transposed' if you compare it with the standard C/C++ 2d-array-access
+ convention . I.e. _mat[i][j] accesses the ith column of the jth row in the
+ 4x4 matrix.
+*/
+
+class SG_EXPORT Matrix : public Object
+{
+ public:
+ Matrix();
+ Matrix(const Matrix& matrix);
+ Matrix( float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33);
+
+ Matrix& operator = (const Matrix& matrix);
+
+ virtual ~Matrix();
+
+ virtual Object* clone() const { return new Matrix(); }
+ virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; }
+ virtual const char* className() const { return "Matrix"; }
+
+ void makeIdent();
+
+ void set(const float* m);
+
+ void set( float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33);
+
+ void copy(const Matrix& matrix);
+
+ void makeScale(float sx, float sy, float sz);
+ void preScale( float sx, float sy, float sz, const Matrix& m );
+ void postScale( const Matrix& m, float sx, float sy, float sz );
+
+ void preScale( float sx, float sy, float sz );
+ void postScale( float sx, float sy, float sz );
+
+
+ void makeTrans( float tx, float ty, float tz );
+ void preTrans( float tx, float ty, float tz, const Matrix& m );
+ void postTrans( const Matrix& m, float tx, float ty, float tz );
+
+ void preTrans( float tx, float ty, float tz );
+ void postTrans( float tx, float ty, float tz );
+
+
+ /**
+ * Calc the rotation matrix which aligns vector \a old_vec with
+ * vector \a new_vec. Both \a old_vec and \a new_vec must have
+ * length 1.0.
+ */
+ void makeRot( const Vec3& old_vec, const Vec3& new_vec );
+
+ void makeRot( float deg, float x, float y, float z );
+ void preRot( float deg, float x, float y, float z, const Matrix& m );
+ void postRot( const Matrix& m, float deg, float x, float y, float z );
+
+ void preRot( float deg, float x, float y, float z );
+ void postRot( float deg, float x, float y, float z );
+
+ void setTrans( float tx, float ty, float tz );
+ void setTrans( const Vec3& v );
+ Vec3 getTrans() const { return Vec3(_mat[3][0],_mat[3][1],_mat[3][2]); }
+
+ void preMult(const Matrix& m);
+ void postMult(const Matrix& m);
+ void mult(const Matrix& lhs,const Matrix& rhs);
+
+ Matrix operator * (const Matrix& m) const;
+
+ /** apply apply an 3x3 transform of v*M[0..2,0..2] */
+ inline static Vec3 transform3x3(const Vec3& v,const Matrix& m);
+ /** apply apply an 3x3 transform of M[0..2,0..2]*v */
+ inline static Vec3 transform3x3(const Matrix& m,const Vec3& v);
+
+ /** post multipy v. ie. (m*v) */
+ inline Vec3 operator * (const Vec3& v) const;
+
+ /** pre multipy v. ie. (v*m) */
+ friend inline Vec3 operator * (const Vec3& v,const Matrix& m);
+
+ /** post multipy v. ie. (m*v) */
+ inline Vec4 operator * (const Vec4& v) const;
+
+ /** pre multipy v. ie. (v*m) */
+ friend inline Vec4 operator * (const Vec4& v,const Matrix& m);
+
+ friend inline ostream& operator << (ostream& output, const Matrix& matrix);
+
+ bool invert(const Matrix& m);
+
+ public :
+ float _mat[4][4];
+
+ protected:
+};
+
+inline Vec3 Matrix::operator * (const Vec3& v) const
+{
+ float d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ;
+ return Vec3( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3])*d,
+ (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3])*d,
+ (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3])*d) ;
+}
+
+
+inline Vec3 operator * (const Vec3& v,const Matrix& m)
+{
+ float d = 1.0f/(m._mat[0][3]*v.x()+m._mat[1][3]*v.y()+m._mat[2][3]*v.z()+m._mat[3][3]) ;
+ return Vec3( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z() + m._mat[3][0])*d,
+ (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z() + m._mat[3][1])*d,
+ (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z() + m._mat[3][2])*d);
+}
+
+inline Vec4 Matrix::operator * (const Vec4& v) const
+{
+ return Vec4( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3]*v.w()),
+ (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3]*v.w()),
+ (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3]*v.w()),
+ (_mat[3][0]*v.x() + _mat[3][1]*v.y() + _mat[3][2]*v.z() + _mat[3][3]*v.w())) ;
+}
+
+
+inline Vec4 operator * (const Vec4& v,const Matrix& m)
+{
+ return Vec4( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z() + m._mat[3][0]*v.w()),
+ (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z() + m._mat[3][1]*v.w()),
+ (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z() + m._mat[3][2]*v.w()),
+ (m._mat[0][3]*v.x() + m._mat[1][3]*v.y() + m._mat[2][3]*v.z() + m._mat[3][3]*v.w()));
+}
+
+inline Vec3 Matrix::transform3x3(const Vec3& v,const Matrix& m)
+{
+ return Vec3( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z()),
+ (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z()),
+ (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z()));
+}
+
+inline Vec3 Matrix::transform3x3(const Matrix& m,const Vec3& v)
+{
+ return Vec3( (m._mat[0][0]*v.x() + m._mat[0][1]*v.y() + m._mat[0][2]*v.z()),
+ (m._mat[1][0]*v.x() + m._mat[1][1]*v.y() + m._mat[1][2]*v.z()),
+ (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ;
+}
+
+inline ostream& operator << (ostream& output, const Matrix& matrix)
+{
+ output << "{"<
+
+namespace osg {
+
+class Node;
+class NodeVisitor;
+
+class SG_EXPORT NodeCallback : public Referenced {
+
+ public :
+
+ /** The range of values which can be accumulated by the NodeVisitor. */
+ enum Requirements
+ {
+ NO_REQUIREMENTS = 0x0,
+ REQUIRES_TRAVERSAL = 0x1,
+ REQUIRES_PARENT_PATH = 0x2,
+ REQUIRES_ACCUMULATED_MATRIX = 0x4,
+ REQUIRES_ACCUMULATED_INVERSE = 0x8,
+ };
+
+ NodeCallback(const Requirements ncr=NO_REQUIREMENTS):_requirements(ncr) {}
+ virtual ~NodeCallback() {}
+
+
+ /** Set what values from traversal are required by this NodeCallback.*/
+ inline void setRequirements(const Requirements ncr) { _requirements=ncr; }
+
+ /** Get what values from traversal are required by this NodeCallback.*/
+ inline const Requirements getRequirements() const { return _requirements; }
+
+ /** Callback method call by the NodeVisitor when visiting a node.*/
+ virtual void operator()(Node*, NodeVisitor*) {}
+
+ public:
+
+ Requirements _requirements;
+};
+
+}; // namespace
+
+#endif
+
diff --git a/include/osg/Viewport b/include/osg/Viewport
new file mode 100644
index 000000000..12a6dd953
--- /dev/null
+++ b/include/osg/Viewport
@@ -0,0 +1,63 @@
+#ifndef OSG_VIEWPORT
+#define OSG_VIEWPORT 1
+
+#include
+#include
+#include
+
+namespace osg {
+
+/** Encapsulte OpenGL glViewport.
+*/
+class SG_EXPORT Viewport : public StateAttribute
+{
+ public :
+
+
+ Viewport();
+ virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=0L; }
+ virtual Object* clone() const { return new Viewport(); }
+ virtual const char* className() const { return "Viewport"; }
+
+ virtual const Type getType() const { return VIEWPORT; }
+
+ inline void setViewport(const int x,const int y,const int width,const int height)
+ {
+ _x = x;
+ _y = y;
+ _width = width;
+ _height = height;
+ }
+
+ void getViewport(int& x,int& y,int& width,int& height)
+ {
+ x = _x;
+ y = _y;
+ width = _width;
+ height = _height;
+ }
+
+ inline const int x() const { return _x; }
+ inline const int y() const { return _y; }
+ inline const int width() const { return _width; }
+ inline const int height() const { return _height; }
+
+ /** return the aspcetRatio of the viewport, which is equal to width/height.*/
+ inline const float aspectRatio() const { return (float)_width/(float)_height; }
+
+ virtual void apply(State& state) const;
+
+ protected:
+
+ virtual ~Viewport();
+
+ int _x;
+ int _y;
+ int _width;
+ int _height;
+
+};
+
+};
+
+#endif
diff --git a/include/osgUtil/AppVisitor b/include/osgUtil/AppVisitor
new file mode 100644
index 000000000..36e38e115
--- /dev/null
+++ b/include/osgUtil/AppVisitor
@@ -0,0 +1,67 @@
+#ifndef OSGUTIL_APPVISITOR
+#define OSGUTIL_APPVISITOR 1
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace osgUtil {
+
+/**
+ * Basic AppVisitor implementation for animating a scene.
+ * This visitor traverses the scene graph, call each nodes appCallback if
+ * it exists.
+ */
+class OSGUTIL_EXPORT AppVisitor : public osg::NodeVisitor
+{
+ public:
+
+ AppVisitor();
+ virtual ~AppVisitor();
+
+ virtual void reset();
+
+ virtual void apply(osg::Node& node) { handle_callbacks(node); }
+
+ virtual void apply(osg::Geode& node) { handle_callbacks(node); }
+ virtual void apply(osg::Billboard& node) { handle_callbacks(node); }
+ virtual void apply(osg::LightSource& node){ handle_callbacks(node); }
+
+ virtual void apply(osg::Group& node) { handle_callbacks(node); }
+ virtual void apply(osg::Transform& node) { handle_callbacks(node); }
+ virtual void apply(osg::Switch& node) { handle_callbacks(node); }
+ virtual void apply(osg::LOD& node) { handle_callbacks(node); }
+ virtual void apply(osg::Impostor& node) { handle_callbacks(node); }
+
+
+ protected:
+
+ /** prevent unwanted copy construction.*/
+ AppVisitor(const AppVisitor&):osg::NodeVisitor() {}
+
+ /** prevent unwanted copy operator.*/
+ AppVisitor& operator = (const AppVisitor&) { return *this; }
+
+ inline void handle_callbacks(osg::Node& node)
+ {
+ osg::NodeCallback* callback = node.getAppCallback();
+ if (callback) (*callback)(&node,this);
+ else if (node.getNumChildrenRequiringAppTraversal()>0) traverse(node);
+ }
+
+
+
+};
+
+};
+
+#endif
+
diff --git a/src/Demos/osgcluster/Makedepend b/src/Demos/osgcluster/Makedepend
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Demos/osgcluster/Makefile b/src/Demos/osgcluster/Makefile
new file mode 100644
index 000000000..0236fafff
--- /dev/null
+++ b/src/Demos/osgcluster/Makefile
@@ -0,0 +1,25 @@
+#!smake
+include ../../../Make/makedefs
+
+C++FILES = \
+ broadcaster.cpp\
+ receiver.cpp\
+ osgcluster.cpp
+
+C++FLAGS += -g
+
+TARGET = ../../../bin/osgcluster
+
+TARGET_BIN_FILES = osgcluster
+
+#note, use this library list when using the Performer osgPlugin.
+#LIBS = ${PFLIBS} -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
+
+#note, standard library list.
+LIBS = -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
+
+C++FLAGS += -I../../../include
+LDFLAGS += -L../../../lib
+
+include ../../../Make/makerules
+
diff --git a/src/Demos/osgcluster/README b/src/Demos/osgcluster/README
new file mode 100644
index 000000000..2d9da8288
--- /dev/null
+++ b/src/Demos/osgcluster/README
@@ -0,0 +1,67 @@
+osgcluster demonstates basic clustering of machines across a local area
+network using UDP packets to send camera position updates from a master viewer
+to slave viewers.
+
+Note, the broadcaster and reciever classes have currently been implement
+for Linux/IRIX, hence osgcluster will only work on these systems. It should
+also work with little extra work on other Unix based OS's. Support for
+WinSocket needs to be added to allow support for Windows. Anybody know
+WinSocket enough to tackle this? If so let us know.
+
+-
+
+On the master machine run:
+
+ osgcluster -m -f 30 mymodel.osg
+
+
+On the slave machines run:
+
+ for left channel:
+
+ osgcluster -s -f 30 -o 30 mymodel.osg
+
+ for right channel:
+
+ osgcluster -s -f 30 -o 30 mymodel.osg
+
+The options are :
+
+ -m set to viewer to master so that it broadcasts its camera postion.
+ -s set to viewer to slave so that it recivers its camera postion.
+ -n set the socket number to communicate over, defaults to 8100.
+ -o set offset the slave camera from the master position by specified
+ number of degress. positive offset turns camera towards right.
+ -f set the horizontal field of view of the camera.
+
+Sepetember 2001.
+Robert Osfield.
+
+
+
+Note: Using sgv with Peformer (for IRIX and Linux users only)
+=============================================================
+
+If you find problems with loading .pfb files its likely that its due to undefined
+symbols. This isn't a problem with the OSG implementation, but alas the only
+current solution is to directly link you app with the Performer libraries. The
+Makefile contains two library list. In Makefile you'll see something like :
+
+ #note, use this library list when using the Performer osgPlugin.
+ #LIBS = ${PFLIBS} -losgGLUT -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi
+
+ #note, standard library list.
+ LIBS = -losgGLUT -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi
+
+Simple comment in the LIBS line with PFLIBS and comment out the standard LIBS,
+then :
+
+ make clean
+ make
+
+Hopefully the Performer distribution will eventually work as a dynamic plugin
+but until that day we're stuck with this 'hack'...
+
+
+Robert Osfield,
+March 20001.
diff --git a/src/Demos/osgcluster/broadcaster.cpp b/src/Demos/osgcluster/broadcaster.cpp
new file mode 100644
index 000000000..5a6819d94
--- /dev/null
+++ b/src/Demos/osgcluster/broadcaster.cpp
@@ -0,0 +1,125 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef __linux
+#include
+#else
+#include
+#endif
+
+#include "broadcaster.h"
+
+#define _VERBOSE 1
+
+Broadcaster::Broadcaster( void )
+{
+ _port = 0;
+ _initialized = false;
+ _buffer = 0L;
+ _address = 0;
+}
+
+Broadcaster::~Broadcaster( void )
+{
+ close( _so );
+}
+
+bool Broadcaster::init( void )
+{
+ if( _port == 0 )
+ {
+ fprintf( stderr, "Broadcaster::init() - port not defined\n" );
+ return false;
+ }
+
+ if( (_so = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
+ {
+ perror( "socket" );
+ return false;
+ }
+ int on = 1;
+ setsockopt( _so, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = htons( _port );
+ if( _address == 0 )
+ {
+ struct ifreq ifr;
+ setsockopt( _so, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+#ifdef __linux
+ strcpy( ifr.ifr_name, "eth0" );
+#else
+ strcpy( ifr.ifr_name, "ef0" );
+#endif
+ if( (ioctl( _so, SIOCGIFBRDADDR, &ifr)) < 0 )
+ {
+ perror( "Broadcaster::init() Cannot get Broadcast Address" );
+ return false;
+ }
+ saddr.sin_addr.s_addr = (
+ ((sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr);
+ }
+ else
+ {
+ saddr.sin_addr.s_addr = _address;
+ }
+#ifdef _VERBOSE
+ unsigned char *ptr = (unsigned char *)&saddr.sin_addr.s_addr;
+ printf( "Broadcast address : %u.%u.%u.%u\n", ptr[0], ptr[1], ptr[2], ptr[3] );
+#endif
+
+ _initialized = true;
+ return _initialized;
+}
+
+void Broadcaster::setHost( const char *hostname )
+{
+ struct hostent *h;
+ if( (h = gethostbyname( hostname )) == 0L )
+ {
+ fprintf( stderr, "Broadcaster::setHost() - Cannot resolv an address for \"%s\".\n", hostname );
+ _address = 0;
+ }
+ else
+ _address = *(( unsigned long *)h->h_addr);
+}
+
+void Broadcaster::setPort( const short port )
+{
+ _port = port;
+}
+
+void Broadcaster::setBuffer( void *buffer, const unsigned int size )
+{
+ _buffer = buffer;
+ _buffer_size = size;
+}
+
+void Broadcaster::sync( void )
+{
+ _initialized || init();
+
+ if( _buffer == 0L )
+ {
+ fprintf( stderr, "Broadcaster::sync() - No buffer\n" );
+ return;
+ }
+
+ unsigned int size = sizeof( struct sockaddr_in );
+ sendto( _so, (const void *)_buffer, _buffer_size,
+ 0, (struct sockaddr *)&saddr, size );
+
+}
+
diff --git a/src/Demos/osgcluster/broadcaster.h b/src/Demos/osgcluster/broadcaster.h
new file mode 100644
index 000000000..8475619fa
--- /dev/null
+++ b/src/Demos/osgcluster/broadcaster.h
@@ -0,0 +1,45 @@
+#ifndef __BROADCASTER_H
+#define __BROADCASTER_H
+
+////////////////////////////////////////////////////////////
+// Broadcaster.h
+//
+// Class definition for broadcasting a buffer to a LAN
+//
+
+#include
+
+class Broadcaster
+{
+ public :
+
+ Broadcaster( void );
+ ~Broadcaster( void );
+
+ // Set the broadcast port
+ void setPort( const short port );
+
+ // Set the buffer to be broadcast
+ void setBuffer( void *buffer, const unsigned int buffer_size );
+
+ // Set a recipient host. If this is used, the Broadcaster
+ // no longer broadcasts, but rather directs UDP packets at
+ // host.
+ void setHost( const char *hostname );
+
+ // Sync broadcasts the buffer
+ void sync( void );
+
+ private :
+ bool init( void );
+
+ private :
+ int _so;
+ bool _initialized;
+ short _port;
+ void *_buffer;
+ unsigned int _buffer_size;
+ struct sockaddr_in saddr;
+ unsigned long _address;
+};
+#endif
diff --git a/src/Demos/osgcluster/osgcluster.cpp b/src/Demos/osgcluster/osgcluster.cpp
new file mode 100644
index 000000000..35b696f99
--- /dev/null
+++ b/src/Demos/osgcluster/osgcluster.cpp
@@ -0,0 +1,350 @@
+#ifdef USE_MEM_CHECK
+#include
+#endif
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+#include "receiver.h"
+#include "broadcaster.h"
+
+
+class CameraPacket {
+ public:
+
+ CameraPacket():_masterKilled(false) {}
+
+ void setPacket(const osg::Camera& camera,int tnum, double rtime)
+ {
+ _eye = camera.getEyePoint();
+ _center = camera.getCenterPoint();
+ _up = camera.getUpVector();
+ _traversalNumber = tnum;
+ _referenceTime = rtime;
+ }
+
+ void getCamera(osg::Camera& camera,float angle_offset=0.0f)
+ {
+
+ osg::Vec3 lv = _center-_eye;
+ osg::Matrix matrix;
+ matrix.makeIdent();
+ matrix.makeRot(angle_offset,_up.x(),_up.y(),_up.z());
+ lv = lv*matrix;
+
+ camera.setLookAt(_eye,_eye+lv,_up);
+
+ }
+
+ void getSceneViewUpdate(osgUtil::SceneView& sv)
+ {
+ sv.setTraversalNumber(_traversalNumber);
+ sv.setReferenceTime(_referenceTime);
+ }
+
+ void setMasterKilled(const bool flag) { _masterKilled = flag; }
+ const bool getMasterKilled() const { return _masterKilled; }
+
+ bool _masterKilled;
+ osg::Vec3 _eye;
+ osg::Vec3 _center;
+ osg::Vec3 _up;
+ bool _attachMatrix;
+ osg::Matrix _matrix;
+
+ int _traversalNumber;
+ double _referenceTime;
+
+};
+
+
+class MySceneView : public osgUtil::SceneView {
+
+ public:
+
+ enum ViewerMode
+ {
+ STAND_ALONE,
+ SLAVE,
+ MASTER
+ };
+
+ MySceneView(ViewerMode viewerMode,int socketNumber,float camera_fov, float camera_offset):
+ _viewerMode(viewerMode),_socketNumber(socketNumber),
+ _camera_fov(camera_fov), _camera_offset(camera_offset)
+ {
+ setDefaults();
+ getCamera()->setAdjustAspectRatioMode(osg::Camera::ADJUST_VERTICAL);
+ getCamera()->setFOV(camera_fov,camera_fov*(600.0f/800.0f),1.0f,1000.0f);
+
+ _bc.setPort(socketNumber);
+ _rc.setPort(socketNumber);
+ };
+
+ ~MySceneView()
+ {
+ if (_viewerMode==MASTER)
+ {
+ // need to broadcast my death.
+ CameraPacket cp;
+ cp.setPacket(*getCamera(),getTraversalNumber(),getReferenceTime());
+ cp.setMasterKilled(true);
+
+ _bc.setBuffer(&cp, sizeof( CameraPacket ));
+ _bc.sync();
+
+ cout << "broadcasting death"< NodeList;
+ NodeList nodeList;
+ for( i = 1; i < argc; i++ )
+ {
+
+ if (argv[i][0]=='-')
+ {
+ switch(argv[i][1])
+ {
+
+ case('m'):
+ viewerMode = MySceneView::MASTER;
+ break;
+ case('s'):
+ viewerMode = MySceneView::SLAVE;
+ break;
+ case('n'):
+ ++i;
+ if (iloadLibrary(argv[i]);
+ }
+ break;
+ case('e'):
+ ++i;
+ if (icreateLibraryNameForExt(argv[i]);
+ osgDB::Registry::instance()->loadLibrary(libName);
+ }
+ break;
+ }
+ } else
+ {
+ osg::Node *node = osgDB::readNodeFile( argv[i] );
+
+ if( node != (osg::Node *)0L )
+ {
+ if (node->getName().empty()) node->setName( argv[i] );
+ nodeList.push_back(node);
+ }
+ }
+
+ }
+
+ if (nodeList.size()==0)
+ {
+ osg::notify(osg::WARN) << "No data loaded."<1
+ {
+ osg::Group* group = new osg::Group();
+ for(NodeList::iterator itr=nodeList.begin();
+ itr!=nodeList.end();
+ ++itr)
+ {
+ group->addChild(*itr);
+ }
+
+ rootnode = group;
+ }
+
+ return rootnode;
+}
+
+
+int main( int argc, char **argv )
+{
+
+#ifdef USE_MEM_CHECK
+ mtrace();
+#endif
+
+ // initialize the GLUT
+ glutInit( &argc, argv );
+
+ if (argc<2)
+ {
+ osg::notify(osg::NOTICE)<<"usage:"< mySceneView = new MySceneView(viewerMode,socketNumber,camera_fov,camera_offset);
+
+ mySceneView->setSceneData(rootnode);
+
+ // initialize the viewer.
+ osgGLUT::Viewer viewer;
+ viewer.addViewport( mySceneView.get() );
+
+ // register trackball, flight and drive.
+ viewer.registerCameraManipulator(new osgUtil::TrackballManipulator);
+ viewer.registerCameraManipulator(new osgUtil::FlightManipulator);
+ viewer.registerCameraManipulator(new osgUtil::DriveManipulator);
+
+ viewer.open();
+ viewer.run();
+
+ return 0;
+}
diff --git a/src/Demos/osgcluster/receiver.cpp b/src/Demos/osgcluster/receiver.cpp
new file mode 100644
index 000000000..f24b9162c
--- /dev/null
+++ b/src/Demos/osgcluster/receiver.cpp
@@ -0,0 +1,104 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "receiver.h"
+
+Receiver::Receiver( void )
+{
+ _port = 0;
+ _initialized = false;
+ _buffer = 0L;
+}
+
+Receiver::~Receiver( void )
+{
+ close( _so );
+}
+
+bool Receiver::init( void )
+{
+ if( _port == 0 )
+ {
+ fprintf( stderr, "Receiver::init() - port not defined\n" );
+ return false;
+ }
+
+ if( (_so = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
+ {
+ perror( "socket" );
+ return false;
+ }
+ int on = 1;
+ setsockopt( _so, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+ struct sockaddr_in saddr;
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = htons( _port );
+ saddr.sin_addr.s_addr = 0;
+
+ if( bind( _so, (struct sockaddr *)&saddr, sizeof( saddr )) < 0 )
+ {
+ perror( "bind" );
+ return false;
+ }
+
+ _initialized = true;
+ return _initialized;
+}
+
+
+void Receiver::setPort( const short port )
+{
+ _port = port;
+}
+
+void Receiver::setBuffer( void *buffer, const unsigned int size )
+{
+ _buffer = buffer;
+ _buffer_size = size;
+}
+
+void Receiver::sync( void )
+{
+ _initialized || init();
+
+ if( _buffer == 0L )
+ {
+ fprintf( stderr, "Receiver::sync() - No buffer\n" );
+ return;
+ }
+
+#ifdef __linux
+ socklen_t
+#else
+ int
+#endif
+ size = sizeof( struct sockaddr_in );
+
+ fd_set fdset;
+ FD_ZERO( &fdset );
+ FD_SET( _so, &fdset );
+
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ recvfrom( _so, (caddr_t)_buffer, _buffer_size, 0, 0, &size );
+ while( select( _so+1, &fdset, 0L, 0L, &tv ) )
+ {
+ if( FD_ISSET( _so, &fdset ) )
+ {
+ recvfrom( _so, (caddr_t)_buffer, _buffer_size, 0, 0, &size );
+ }
+ }
+}
+
diff --git a/src/Demos/osgcluster/receiver.h b/src/Demos/osgcluster/receiver.h
new file mode 100644
index 000000000..20597e6d7
--- /dev/null
+++ b/src/Demos/osgcluster/receiver.h
@@ -0,0 +1,39 @@
+#ifndef __RECEIVER_H
+#define __RECEIVER_H
+
+
+////////////////////////////////////////////////////////////
+// Receiver.h
+//
+// Class definition for the recipient of a broadcasted message
+//
+
+
+class Receiver
+{
+ public :
+
+ Receiver();
+ ~Receiver();
+
+ // setBuffer defines the buffer into which the broadcasted
+ // message will be received.
+ void setBuffer( void *buffer, const unsigned int size );
+
+ // Define what port to listen and bind to
+ void setPort( const short port );
+
+ // Sync does a blocking wait to recieve next message
+ void sync( void );
+
+ private :
+ bool init( void );
+
+ private :
+ int _so;
+ bool _initialized;
+ short _port;
+ void *_buffer;
+ unsigned int _buffer_size;
+};
+#endif
diff --git a/src/osg/Matrix.cpp.new b/src/osg/Matrix.cpp.new
new file mode 100644
index 000000000..0eefc82ca
--- /dev/null
+++ b/src/osg/Matrix.cpp.new
@@ -0,0 +1,558 @@
+
+#include
+#include
+#include
+
+#include //memcpy
+#include //acos
+
+using namespace osg;
+
+#define WARN_DEPRECATED
+
+Matrix::Matrix() : Object(), fully_realized(false) {}
+
+Matrix::Matrix( const Matrix& other ) : Object() {
+ set( (float const * const) other._mat );
+}
+
+Matrix::Matrix( float const * const def ) {
+ set( def );
+}
+
+Matrix::Matrix(
+float a00, float a01, float a02, float a03,
+float a10, float a11, float a12, float a13,
+float a20, float a21, float a22, float a23,
+float a30, float a31, float a32, float a33)
+{
+ _mat[0][0] = a00;
+ _mat[0][1] = a01;
+ _mat[0][2] = a02;
+ _mat[0][3] = a03;
+
+ _mat[1][0] = a10;
+ _mat[1][1] = a11;
+ _mat[1][2] = a12;
+ _mat[1][3] = a13;
+
+ _mat[2][0] = a20;
+ _mat[2][1] = a21;
+ _mat[2][2] = a22;
+ _mat[2][3] = a23;
+
+ _mat[3][0] = a30;
+ _mat[3][1] = a31;
+ _mat[3][2] = a32;
+ _mat[3][3] = a33;
+}
+
+Matrix& Matrix::operator = (const Matrix& other ) {
+ if( &other == this ) return *this;
+ set((const float*)other._mat);
+ return *this;
+}
+
+void Matrix::set( float const * const def ) {
+ memcpy( _mat, def, sizeof(_mat) );
+ fully_realized = true;
+}
+
+void Matrix::set(
+ float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33)
+{
+ _mat[0][0] = a00;
+ _mat[0][1] = a01;
+ _mat[0][2] = a02;
+ _mat[0][3] = a03;
+
+ _mat[1][0] = a10;
+ _mat[1][1] = a11;
+ _mat[1][2] = a12;
+ _mat[1][3] = a13;
+
+ _mat[2][0] = a20;
+ _mat[2][1] = a21;
+ _mat[2][2] = a22;
+ _mat[2][3] = a23;
+
+ _mat[3][0] = a30;
+ _mat[3][1] = a31;
+ _mat[3][2] = a32;
+ _mat[3][3] = a33;
+}
+
+#define SET_ROW(row, v1, v2, v3, v4 ) \
+ _mat[0][(row)] = (v1); \
+ _mat[1][(row)] = (v2); \
+ _mat[2][(row)] = (v3); \
+ _mat[3][(row)] = (v4);
+
+
+void Matrix::makeIdent() {
+ SET_ROW(0, 1, 0, 0, 0 )
+ SET_ROW(1, 0, 1, 0, 0 )
+ SET_ROW(2, 0, 0, 1, 0 )
+ SET_ROW(3, 0, 0, 0, 1 )
+
+ fully_realized = true;
+}
+
+void Matrix::makeScale( const Vec3& v ) {
+ makeScale(v[0], v[1], v[2] );
+}
+
+void Matrix::makeScale( float x, float y, float z ) {
+ SET_ROW(0, x, 0, 0, 0 )
+ SET_ROW(1, 0, y, 0, 0 )
+ SET_ROW(2, 0, 0, z, 0 )
+ SET_ROW(3, 0, 0, 0, 1 )
+
+ fully_realized = true;
+}
+
+void Matrix::makeTrans( const Vec3& v ) {
+ makeTrans( v[0], v[1], v[2] );
+}
+
+void Matrix::makeTrans( float x, float y, float z ) {
+ SET_ROW(0, 1, 0, 0, x )
+ SET_ROW(1, 0, 1, 0, y )
+ SET_ROW(2, 0, 0, 1, z )
+ SET_ROW(3, 0, 0, 0, 1 )
+
+ fully_realized = true;
+}
+
+void Matrix::makeRot( const Vec3& from, const Vec3& to ) {
+ double d = from * to; // dot product == cos( angle between from & to )
+ if( d < 0.9999 ) {
+ double angle = acos(d);
+ Vec3 axis = to ^ from; //we know ((to) x (from)) is perpendicular to both
+ makeRot( angle, axis );
+ }
+ else
+ makeIdent();
+}
+
+void Matrix::makeRot( float angle, const Vec3& axis ) {
+ makeRot( angle, axis.x(), axis.y(), axis.z() );
+}
+
+void Matrix::makeRot( float angle, float x, float y, float z ) {
+ float d = sqrt( x*x + y*y + z*z );
+ if( d == 0 )
+ return;
+
+ float sin_half = sin( angle/2 );
+ float cos_half = cos( angle/2 );
+
+ Quat q( sin_half * (x/d),
+ sin_half * (y/d),
+ sin_half * (z/d),
+ cos_half );
+ makeRot( q );
+}
+
+void Matrix::makeRot( const Quat& q ) {
+ // taken from Shoemake/ACM SIGGRAPH 89
+ Vec4 v = q.asVec4();
+
+ double xs = 2 * v.x(); //assume q is already normalized? assert?
+ double ys = 2 * v.y(); // if not, xs = 2 * v.x() / d, ys = 2 * v.y() / d
+ double zs = 2 * v.z(); // and zs = 2 * v.z() /d where d = v.length2()
+
+ double xx = xs * v.x();
+ double xy = ys * v.x();
+ double xz = zs * v.x();
+ double yy = ys * v.y();
+ double yz = zs * v.y();
+ double zz = zs * v.z();
+ double wx = xs * v.w();
+ double wy = ys * v.w();
+ double wz = zs * v.w();
+
+ SET_ROW(0, 1.0-(yy+zz), xy - wz, xz + wz, 0.0 )
+ SET_ROW(1, xy + wz, 1.0-(xx+zz),yz - wx, 0.0 )
+ SET_ROW(2, xz - wy, yz + wx, 1.0-(xx+yy),0.0 )
+ SET_ROW(3, 0.0, 0.0, 0.0, 1.0 )
+
+ fully_realized = true;
+}
+
+void Matrix::makeRot( float yaw, float pitch, float roll) {
+ // lifted straight from SOLID library v1.01 Quaternion.h
+ // available from http://www.win.tue.nl/~gino/solid/
+ // and also distributed under the LGPL
+ float cosYaw = cos(yaw / 2);
+ float sinYaw = sin(yaw / 2);
+ float cosPitch = cos(pitch / 2);
+ float sinPitch = sin(pitch / 2);
+ float cosRoll = cos(roll / 2);
+ float sinRoll = sin(roll / 2);
+ Quat q(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
+ cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
+ cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
+ cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
+ makeRot( q );
+}
+
+#define INNER_PRODUCT(a,b,c,r) \
+ ((a)._mat[0][r] * (b)._mat[c][0]) \
+ +((a)._mat[1][r] * (b)._mat[c][1]) \
+ +((a)._mat[2][r] * (b)._mat[c][2]) \
+ +((a)._mat[3][r] * (b)._mat[c][3])
+
+void Matrix::mult( const Matrix& lhs, const Matrix& rhs ) {
+// PRECONDITION: We assume neither &lhs nor &rhs == this
+// if it did, use preMult or postMult instead
+ _mat[0][0] = INNER_PRODUCT(lhs, rhs, 0, 0);
+ _mat[0][1] = INNER_PRODUCT(lhs, rhs, 0, 1);
+ _mat[0][2] = INNER_PRODUCT(lhs, rhs, 0, 2);
+ _mat[0][3] = INNER_PRODUCT(lhs, rhs, 0, 3);
+ _mat[1][0] = INNER_PRODUCT(lhs, rhs, 1, 0);
+ _mat[1][1] = INNER_PRODUCT(lhs, rhs, 1, 1);
+ _mat[1][2] = INNER_PRODUCT(lhs, rhs, 1, 2);
+ _mat[1][3] = INNER_PRODUCT(lhs, rhs, 1, 3);
+ _mat[2][0] = INNER_PRODUCT(lhs, rhs, 2, 0);
+ _mat[2][1] = INNER_PRODUCT(lhs, rhs, 2, 1);
+ _mat[2][2] = INNER_PRODUCT(lhs, rhs, 2, 2);
+ _mat[2][3] = INNER_PRODUCT(lhs, rhs, 2, 3);
+ _mat[3][0] = INNER_PRODUCT(lhs, rhs, 3, 0);
+ _mat[3][1] = INNER_PRODUCT(lhs, rhs, 3, 1);
+ _mat[3][2] = INNER_PRODUCT(lhs, rhs, 3, 2);
+ _mat[3][3] = INNER_PRODUCT(lhs, rhs, 3, 3);
+ fully_realized = true;
+}
+
+void Matrix::preMult( const Matrix& other ) {
+ float t1,t2,t3,t4;
+ if( !fully_realized ) {
+ //act as if this were an identity Matrix
+ set((const float*)other._mat);
+ return;
+ }
+ for(int col=0; col<4; ++col) {
+ t1 = INNER_PRODUCT( other, *this, col, 0 );
+ t2 = INNER_PRODUCT( other, *this, col, 1 );
+ t3 = INNER_PRODUCT( other, *this, col, 2 );
+ t4 = INNER_PRODUCT( other, *this, col, 3 );
+ _mat[col][0] = t1;
+ _mat[col][1] = t2;
+ _mat[col][2] = t3;
+ _mat[col][3] = t4;
+ }
+}
+
+void Matrix::postMult( const Matrix& other ) {
+ float t[4];
+ if( !fully_realized ) {
+ //act as if this were an identity Matrix
+ set((const float*)other._mat);
+ return;
+ }
+ for(int row=0; row<4; ++row) {
+ t[0] = INNER_PRODUCT( *this, other, 0, row );
+ t[1] = INNER_PRODUCT( *this, other, 1, row );
+ t[2] = INNER_PRODUCT( *this, other, 2, row );
+ t[3] = INNER_PRODUCT( *this, other, 3, row );
+ SET_ROW(row, t[0], t[1], t[2], t[3] )
+ }
+}
+
+#undef SET_ROW
+#undef INNER_PRODUCT
+
+bool Matrix::invert( const Matrix& _m ) {
+
+ if (&_m==this)
+ {
+ Matrix tm(_m);
+ return invert(tm);
+ }
+ if ( _m._mat[0][3] == 0.0
+ && _m._mat[1][3] == 0.0
+ && _m._mat[2][3] == 0.0
+ && _m._mat[3][3] == 1.0 )
+ {
+ return invertAffine( _m );
+ }
+
+ // code lifted from VR Juggler.
+ // not cleanly added, but seems to work. RO.
+ const float* a = reinterpret_cast(_m._mat);
+ float* b = reinterpret_cast(_mat);
+
+ int n = 4;
+ int i, j, k;
+ int r[ 4], c[ 4], row[ 4], col[ 4];
+ float m[ 4][ 4*2], pivot, max_m, tmp_m, fac;
+
+ /* Initialization */
+ for ( i = 0; i < n; i ++ )
+ {
+ r[ i] = c[ i] = 0;
+ row[ i] = col[ i] = 0;
+ }
+
+ /* Set working matrix */
+ for ( i = 0; i < n; i++ )
+ {
+ for ( j = 0; j < n; j++ )
+ {
+ m[ i][ j] = a[ i * n + j];
+ m[ i][ j + n] = ( i == j ) ? 1.0 : 0.0 ;
+ }
+ }
+
+ /* Begin of loop */
+ for ( k = 0; k < n; k++ )
+ {
+ /* Choosing the pivot */
+ for ( i = 0, max_m = 0; i < n; i++ )
+ {
+ if ( row[ i] ) continue;
+ for ( j = 0; j < n; j++ )
+ {
+ if ( col[ j] ) continue;
+ tmp_m = fabs( m[ i][j]);
+ if ( tmp_m > max_m)
+ {
+ max_m = tmp_m;
+ r[ k] = i;
+ c[ k] = j;
+ }
+ }
+ }
+ row[ r[k] ] = col[ c[k] ] = 1;
+ pivot = m[ r[ k] ][ c[ k] ];
+
+ if ( fabs( pivot) <= 1e-20)
+ {
+ notify(WARN) << "*** pivot = %f in mat_inv. ***\n";
+ //exit( 0);
+ return false;
+ }
+
+ /* Normalization */
+ for ( j = 0; j < 2*n; j++ )
+ {
+ if ( j == c[ k] )
+ m[ r[ k]][ j] = 1.0;
+ else
+ m[ r[ k]][ j] /=pivot;
+ }
+
+ /* Reduction */
+ for ( i = 0; i < n; i++ )
+ {
+ if ( i == r[ k] )
+ continue;
+
+ for ( j=0, fac = m[ i][ c[k]];j < 2*n; j++ )
+ {
+ if ( j == c[ k] )
+ m[ i][ j] =0.0;
+ else
+ m[ i][ j] -=fac * m[ r[k]][ j];
+ }
+ }
+ }
+
+ /* Assign invers to a matrix */
+ for ( i = 0; i < n; i++ )
+ for ( j = 0; j < n; j++ )
+ row[ i] = ( c[ j] == i ) ? r[j] : row[ i];
+
+ for ( i = 0; i < n; i++ )
+ for ( j = 0; j < n; j++ )
+ b[ i * n + j] = m[ row[ i]][j + n];
+
+ return true; // It worked
+}
+
+const double PRECISION_LIMIT = 1.0e-15;
+
+bool Matrix::invertAffine( const Matrix& _m ) {
+ // adapted from Graphics Gems II.
+ //
+ // This method treats the matrix as a block matrix and calculates
+ // the inverse of one submatrix, improving performance over something
+ // that inverts any non-singular matrix:
+ // -1
+ // -1 [ A 0 ] -1 [ A 0 ]
+ // M = [ ] = [ -1 ]
+ // [ C 1 ] [-CA 1 ]
+ //
+ // returns true if _m is nonsingular, and (*this) contains its inverse
+ // otherwise returns false. (*this unchanged)
+
+ // assert (this.isAffine()) ?
+ double det_1, pos, neg, temp;
+
+ pos = neg = 0.0;
+
+#define ACCUMULATE \
+ { \
+ if(temp < 0.0) pos += temp; \
+ else neg += temp; \
+ }
+
+ temp = _m._mat[0][0] * _m._mat[1][1] * _m._mat[2][2]; ACCUMULATE;
+ temp = _m._mat[0][1] * _m._mat[1][2] * _m._mat[2][0]; ACCUMULATE;
+ temp = _m._mat[0][2] * _m._mat[1][0] * _m._mat[2][1]; ACCUMULATE;
+
+ temp = - _m._mat[0][2] * _m._mat[1][1] * _m._mat[2][0]; ACCUMULATE;
+ temp = - _m._mat[0][1] * _m._mat[1][0] * _m._mat[2][2]; ACCUMULATE;
+ temp = - _m._mat[0][0] * _m._mat[1][2] * _m._mat[2][1]; ACCUMULATE;
+
+ det_1 = pos + neg;
+
+ if( (det_1 == 0.0) || (abs(det_1/(pos-neg)) < PRECISION_LIMIT )) {
+ // _m has no inverse
+ notify(WARN) << "Matrix::invert(): Matrix has no inverse." << endl;
+ return false;
+ }
+
+ // inverse is adj(A)/det(A)
+ det_1 = 1.0 / det_1;
+
+ _mat[0][0] = (_m._mat[1][1] * _m._mat[2][2] - _m._mat[1][2] * _m._mat[2][1]) * det_1;
+ _mat[1][0] = (_m._mat[1][0] * _m._mat[2][2] - _m._mat[1][2] * _m._mat[2][0]) * det_1;
+ _mat[2][0] = (_m._mat[1][0] * _m._mat[2][1] - _m._mat[1][1] * _m._mat[2][0]) * det_1;
+ _mat[0][1] = (_m._mat[0][1] * _m._mat[2][2] - _m._mat[0][2] * _m._mat[2][1]) * det_1;
+ _mat[1][1] = (_m._mat[0][0] * _m._mat[2][2] - _m._mat[0][2] * _m._mat[2][0]) * det_1;
+ _mat[2][1] = (_m._mat[0][0] * _m._mat[2][1] - _m._mat[0][1] * _m._mat[2][0]) * det_1;
+ _mat[0][2] = (_m._mat[0][1] * _m._mat[1][2] - _m._mat[0][2] * _m._mat[1][1]) * det_1;
+ _mat[1][2] = (_m._mat[0][0] * _m._mat[1][2] - _m._mat[0][2] * _m._mat[1][0]) * det_1;
+ _mat[2][2] = (_m._mat[0][0] * _m._mat[1][1] - _m._mat[0][1] * _m._mat[1][0]) * det_1;
+
+ // calculate -C * inv(A)
+ _mat[3][0] = -(_m._mat[3][0] * _mat[0][0] + _m._mat[3][1] * _mat[1][0] + _m._mat[3][2] * _mat[2][0] );
+ _mat[3][1] = -(_m._mat[3][0] * _mat[0][1] + _m._mat[3][1] * _mat[1][1] + _m._mat[3][2] * _mat[2][1] );
+ _mat[3][2] = -(_m._mat[3][0] * _mat[0][2] + _m._mat[3][1] * _mat[1][2] + _m._mat[3][2] * _mat[2][2] );
+
+ _mat[0][3] = 0.0;
+ _mat[1][3] = 0.0;
+ _mat[2][3] = 0.0;
+ _mat[3][3] = 1.0;
+
+ fully_realized = true;
+ return true;
+}
+
+//static utility methods
+Matrix Matrix::scale(float sx, float sy, float sz) {
+ Matrix m;
+ m.makeScale(sx,sy,sz);
+ return m;
+}
+Matrix Matrix::scale(const Vec3& v ) {
+ return scale(v.x(), v.y(), v.z() );
+}
+Matrix Matrix::trans(float tx, float ty, float tz) {
+ Matrix m;
+ m.makeTrans(tx,ty,tz);
+ return m;
+}
+Matrix Matrix::trans(const Vec3& v ) {
+ return trans(v.x(), v.y(), v.z() );
+}
+Matrix Matrix::rotate( const Quat& q ) {
+ Matrix m;
+ m.makeRot( q );
+ return m;
+}
+Matrix Matrix::rotate(float angle, float x, float y, float z ) {
+ Matrix m;
+ m.makeRot(angle,x,y,z);
+ return m;
+}
+Matrix Matrix::rotate(const Vec3& from, const Vec3& to ) {
+ Matrix m;
+ m.makeRot(from,to);
+ return m;
+}
+
+//Deprecated methods
+void Matrix::copy( const Matrix& other) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::copy is deprecated. Use = instead.";
+#endif
+ (*this) = other;
+}
+void Matrix::preScale( float sx, float sy, float sz, const Matrix& m ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::preScale is deprecated. Use result = (Matrix::scale * m) instead.";
+ (*this) = ( scale(sx,sy,sz) * m );
+#endif
+}
+void Matrix::postScale( const Matrix& m, float sx, float sy, float sz ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::postScale is deprecated. Use result = (m * Matrix::scale()) instead.";
+ (*this) = ( m * scale(sx,sy,sz) );
+#endif
+}
+void Matrix::preScale( float sx, float sy, float sz ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::preScale is deprecated. Use M.preMult( Matrix::scale ) instead.";
+ preMult( scale(sx,sy,sz) );
+#endif
+}
+void Matrix::postScale( float sx, float sy, float sz ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::postScale is deprecated. Use M.postMult( Matrix::scale ) instead.";
+ postMult( scale(sx,sy,sz) );
+#endif
+}
+void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead.";
+ (*this) = trans(tx,ty,tz) * m;
+#endif
+}
+void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead.";
+ (*this) = m * trans(tx,ty,tz);
+#endif
+}
+void Matrix::preTrans( float sx, float sy, float sz ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead.";
+ preMult( trans(sx,sy,sz) );
+#endif
+}
+void Matrix::postTrans( float sx, float sy, float sz ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead.";
+ postMult( trans(sx,sy,sz) );
+#endif
+}
+void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::preRot is deprecated. Use result = Matrix::rot * m instead.";
+ (*this) = rotate(deg,x,y,z) * m;
+#endif
+}
+void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::postRot is deprecated. Use result = m * Matrix::rotate instead.";
+ (*this) = m * rotate(deg,x,y,z);
+#endif
+}
+void Matrix::preRot( float deg, float x, float y, float z ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::preRot is deprecated. Use m.preMult( Matrix::rotate ) instead.";
+ preMult( rotate(deg,x,y,z) );
+#endif
+}
+void Matrix::postRot( float deg, float x, float y, float z ) {
+#ifdef WARN_DEPRECATED
+ notify(NOTICE) << "Matrix::postRot is deprecated. Use m.postMult( Matrix::rotate ) instead.";
+ postMult( rotate(deg,x,y,z) );
+#endif
+}
diff --git a/src/osg/Matrix.cpp.old b/src/osg/Matrix.cpp.old
new file mode 100644
index 000000000..d48060776
--- /dev/null
+++ b/src/osg/Matrix.cpp.old
@@ -0,0 +1,568 @@
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#define square(x) ((x)*(x))
+#define DEG2RAD(x) ((x)*M_PI/180.0)
+#define RAD2DEG(x) ((x)*180.0/M_PI)
+
+using namespace osg;
+
+typedef struct quaternion_
+{
+ double x ;
+ double y ;
+ double z ;
+ double w ;
+} quaternion ;
+
+/* C = a(row).b(row) */
+
+#define matrix_inner_product( a, b, row, col, C ) \
+ { \
+ (C)[row][col] = (a)[row][0] * (b)[0][col] + \
+ (a)[row][1] * (b)[1][col] + \
+ (a)[row][2] * (b)[2][col] + \
+ (a)[row][3] * (b)[3][col]; \
+ }
+
+/* C = a.b */
+
+#define matrix_mult( a, b, C ) \
+ { \
+ matrix_inner_product( a, b, 0, 0, C ); \
+ matrix_inner_product( a, b, 0, 1, C ); \
+ matrix_inner_product( a, b, 0, 2, C ); \
+ matrix_inner_product( a, b, 0, 3, C ); \
+ matrix_inner_product( a, b, 1, 0, C ); \
+ matrix_inner_product( a, b, 1, 1, C ); \
+ matrix_inner_product( a, b, 1, 2, C ); \
+ matrix_inner_product( a, b, 1, 3, C ); \
+ matrix_inner_product( a, b, 2, 0, C ); \
+ matrix_inner_product( a, b, 2, 1, C ); \
+ matrix_inner_product( a, b, 2, 2, C ); \
+ matrix_inner_product( a, b, 2, 3, C ); \
+ matrix_inner_product( a, b, 3, 0, C ); \
+ matrix_inner_product( a, b, 3, 1, C ); \
+ matrix_inner_product( a, b, 3, 2, C ); \
+ matrix_inner_product( a, b, 3, 3, C ); \
+ }
+
+static void quaternion_matrix( quaternion *q, double mat[4][4] )
+{
+ /* copied from Shoemake/ACM SIGGRAPH 89 */
+ double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz ;
+
+ xs = q->x + q->x;
+ ys = q->y + q->y;
+ zs = q->z + q->z;
+
+ wx = q->w * xs ; wy = q->w * ys ; wz = q->w * zs ;
+ xx = q->x * xs ; xy = q->x * ys ; xz = q->x * zs ;
+ yy = q->y * ys ; yz = q->y * zs ; zz = q->z * zs ;
+
+ mat[0][0] = 1.0 - ( yy + zz ) ;
+ mat[0][1] = xy - wz ;
+ mat[0][2] = xz + wy ;
+ mat[1][0] = xy + wz ;
+ mat[1][1] = 1.0 - ( xx + zz ) ;
+ mat[1][2] = yz - wx ;
+ mat[2][0] = xz - wy ;
+ mat[2][1] = yz + wx ;
+ mat[2][2] = 1.0 - ( xx + yy ) ;
+
+ mat[0][3] = 0.0;
+ mat[1][3] = 0.0;
+ mat[2][3] = 0.0;
+
+ mat[3][0] = 0.0;
+ mat[3][1] = 0.0;
+ mat[3][2] = 0.0;
+ mat[3][3] = 1.0;
+}
+
+
+Matrix::Matrix()
+{
+ makeIdent();
+}
+
+
+Matrix::Matrix(const Matrix& matrix) : Object()
+{
+ memcpy(_mat,matrix._mat,sizeof(_mat));
+}
+
+
+Matrix& Matrix::operator = (const Matrix& matrix)
+{
+ if (&matrix==this) return *this;
+ memcpy(_mat,matrix._mat,sizeof(_mat));
+ return *this;
+}
+
+
+Matrix::Matrix(
+float a00, float a01, float a02, float a03,
+float a10, float a11, float a12, float a13,
+float a20, float a21, float a22, float a23,
+float a30, float a31, float a32, float a33)
+{
+ _mat[0][0] = a00;
+ _mat[0][1] = a01;
+ _mat[0][2] = a02;
+ _mat[0][3] = a03;
+
+ _mat[1][0] = a10;
+ _mat[1][1] = a11;
+ _mat[1][2] = a12;
+ _mat[1][3] = a13;
+
+ _mat[2][0] = a20;
+ _mat[2][1] = a21;
+ _mat[2][2] = a22;
+ _mat[2][3] = a23;
+
+ _mat[3][0] = a30;
+ _mat[3][1] = a31;
+ _mat[3][2] = a32;
+ _mat[3][3] = a33;
+}
+
+
+Matrix::~Matrix()
+{
+}
+
+
+void Matrix::makeIdent()
+{
+ _mat[0][0] = 1.0f;
+ _mat[0][1] = 0.0f;
+ _mat[0][2] = 0.0f;
+ _mat[0][3] = 0.0f;
+
+ _mat[1][0] = 0.0f;
+ _mat[1][1] = 1.0f;
+ _mat[1][2] = 0.0f;
+ _mat[1][3] = 0.0f;
+
+ _mat[2][0] = 0.0f;
+ _mat[2][1] = 0.0f;
+ _mat[2][2] = 1.0f;
+ _mat[2][3] = 0.0f;
+
+ _mat[3][0] = 0.0f;
+ _mat[3][1] = 0.0f;
+ _mat[3][2] = 0.0f;
+ _mat[3][3] = 1.0f;
+}
+
+void Matrix::set(const float* m)
+{
+ _mat[0][0] = m[0];
+ _mat[0][1] = m[1];
+ _mat[0][2] = m[2];
+ _mat[0][3] = m[3];
+
+ _mat[1][0] = m[4];
+ _mat[1][1] = m[5];
+ _mat[1][2] = m[6];
+ _mat[1][3] = m[7];
+
+ _mat[2][0] = m[8];
+ _mat[2][1] = m[9];
+ _mat[2][2] = m[10];
+ _mat[2][3] = m[11];
+
+ _mat[3][0] = m[12];
+ _mat[3][1] = m[13];
+ _mat[3][2] = m[14];
+ _mat[3][3] = m[15];
+}
+
+
+void Matrix::set(
+ float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33)
+{
+ _mat[0][0] = a00;
+ _mat[0][1] = a01;
+ _mat[0][2] = a02;
+ _mat[0][3] = a03;
+
+ _mat[1][0] = a10;
+ _mat[1][1] = a11;
+ _mat[1][2] = a12;
+ _mat[1][3] = a13;
+
+ _mat[2][0] = a20;
+ _mat[2][1] = a21;
+ _mat[2][2] = a22;
+ _mat[2][3] = a23;
+
+ _mat[3][0] = a30;
+ _mat[3][1] = a31;
+ _mat[3][2] = a32;
+ _mat[3][3] = a33;
+}
+
+void Matrix::copy(const Matrix& matrix)
+{
+ memcpy(_mat,matrix._mat,sizeof(_mat));
+}
+
+
+void Matrix::makeScale(float sx, float sy, float sz)
+{
+ makeIdent();
+ _mat[0][0] = sx;
+ _mat[1][1] = sy;
+ _mat[2][2] = sz;
+}
+
+
+void Matrix::preScale( float sx, float sy, float sz, const Matrix& m )
+{
+ Matrix transMat;
+ transMat.makeScale(sx, sy, sz);
+ mult(transMat,m);
+}
+
+
+void Matrix::postScale( const Matrix& m, float sx, float sy, float sz )
+{
+ Matrix transMat;
+ transMat.makeScale(sx, sy, sz);
+ mult(m,transMat);
+}
+
+
+void Matrix::preScale( float sx, float sy, float sz )
+{
+ Matrix transMat;
+ transMat.makeScale(sx, sy, sz);
+ preMult(transMat);
+}
+
+
+void Matrix::postScale( float sx, float sy, float sz )
+{
+ Matrix transMat;
+ transMat.makeScale(sx, sy, sz);
+ postMult(transMat);
+}
+
+
+void Matrix::makeTrans( float tx, float ty, float tz )
+{
+ makeIdent();
+ _mat[3][0] = tx;
+ _mat[3][1] = ty;
+ _mat[3][2] = tz;
+}
+
+
+void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m )
+{
+ Matrix transMat;
+ transMat.makeTrans(tx, ty, tz);
+ mult(transMat,m);
+}
+
+
+void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz )
+{
+ Matrix transMat;
+ transMat.makeTrans(tx, ty, tz);
+ mult(m,transMat);
+}
+
+
+void Matrix::preTrans( float tx, float ty, float tz )
+{
+ _mat[3][0] = (tx * _mat[0][0]) + (ty * _mat[1][0]) + (tz * _mat[2][0]) + _mat[3][0];
+ _mat[3][1] = (tx * _mat[0][1]) + (ty * _mat[1][1]) + (tz * _mat[2][1]) + _mat[3][1];
+ _mat[3][2] = (tx * _mat[0][2]) + (ty * _mat[1][2]) + (tz * _mat[2][2]) + _mat[3][2];
+ _mat[3][3] = (tx * _mat[0][3]) + (ty * _mat[1][3]) + (tz * _mat[2][3]) + _mat[3][3];
+}
+
+
+void Matrix::postTrans( float tx, float ty, float tz )
+{
+ Matrix transMat;
+ transMat.makeTrans(tx, ty, tz);
+ postMult(transMat);
+}
+
+void Matrix::makeRot( const Vec3& old_vec, const Vec3& new_vec )
+{
+ /* dot product == cos(angle old_vec<>new_vec). */
+ double d = new_vec * old_vec;
+ if ( d < 0.9999 )
+ {
+ double angle = acos( d );
+ Vec3 rot_axis = new_vec ^ old_vec;
+ makeRot( RAD2DEG(angle),
+ rot_axis.x(), rot_axis.y(), rot_axis.z() );
+ }
+ else
+ makeIdent();
+}
+
+void Matrix::makeRot( float deg, float x, float y, float z )
+{
+ double __mat[4][4];
+ quaternion q;
+ float d = sqrtf( square(x) + square(y) + square(z) );
+
+ if( d == 0 )
+ return;
+
+ float sin_HalfAngle = sinf( DEG2RAD(deg/2) );
+ float cos_HalfAngle = cosf( DEG2RAD(deg/2) );
+
+ q.x = sin_HalfAngle * (x/d);
+ q.y = sin_HalfAngle * (y/d);
+ q.z = sin_HalfAngle * (z/d);
+ q.w = cos_HalfAngle;
+
+ quaternion_matrix( &q, __mat );
+
+ for(int i=0;i<4;++i)
+ {
+ for(int j=0;j<4;++j)
+ {
+ _mat[i][j]=__mat[i][j];
+ }
+ }
+}
+
+
+void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m )
+{
+ Matrix rotMat;
+ rotMat.makeRot( deg, x, y, z );
+ mult(rotMat,m);
+}
+
+
+void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z )
+{
+ Matrix rotMat;
+ rotMat.makeRot( deg, x, y, z );
+ mult(m,rotMat);
+}
+
+
+void Matrix::preRot( float deg, float x, float y, float z )
+{
+ quaternion q;
+ double __mat[4][4];
+ float res_mat[4][4];
+
+ float d = sqrtf( square(x) + square(y) + square(z) );
+
+ if( d == 0 )
+ return;
+
+ float sin_HalfAngle = sinf( DEG2RAD(deg/2) );
+ float cos_HalfAngle = cosf( DEG2RAD(deg/2) );
+
+ q.x = sin_HalfAngle * (x/d);
+ q.y = sin_HalfAngle * (y/d);
+ q.z = sin_HalfAngle * (z/d);
+ q.w = cos_HalfAngle;
+
+ quaternion_matrix( &q, __mat );
+ matrix_mult( __mat, _mat, res_mat );
+ memcpy( _mat, res_mat, sizeof( _mat ) );
+}
+
+
+void Matrix::postRot( float deg, float x, float y, float z )
+{
+ quaternion q;
+ double __mat[4][4];
+ float res_mat[4][4];
+
+ float d = sqrtf( square(x) + square(y) + square(z) );
+
+ if( d == 0 )
+ return;
+
+ float sin_HalfAngle = sinf( DEG2RAD(deg/2) );
+ float cos_HalfAngle = cosf( DEG2RAD(deg/2) );
+
+ q.x = sin_HalfAngle * (x/d);
+ q.y = sin_HalfAngle * (y/d);
+ q.z = sin_HalfAngle * (z/d);
+ q.w = cos_HalfAngle;
+
+ quaternion_matrix( &q, __mat );
+ matrix_mult( _mat, __mat , res_mat );
+ memcpy( _mat, res_mat, sizeof( _mat ) );
+}
+
+
+void Matrix::setTrans( float tx, float ty, float tz )
+{
+ _mat[3][0] = tx;
+ _mat[3][1] = ty;
+ _mat[3][2] = tz;
+}
+
+
+void Matrix::setTrans( const Vec3& v )
+{
+ _mat[3][0] = v[0];
+ _mat[3][1] = v[1];
+ _mat[3][2] = v[2];
+}
+
+
+void Matrix::preMult(const Matrix& m)
+{
+ Matrix tm;
+ matrix_mult( m._mat, _mat, tm._mat );
+ *this = tm;
+}
+
+
+void Matrix::postMult(const Matrix& m)
+{
+ Matrix tm;
+ matrix_mult( _mat, m._mat, tm._mat );
+ *this = tm;
+}
+
+
+void Matrix::mult(const Matrix& lhs,const Matrix& rhs)
+{
+ if (&lhs==this || &rhs==this)
+ {
+ osg::Matrix tm;
+ matrix_mult( lhs._mat, rhs._mat, tm._mat );
+ *this = tm;
+ }
+ else
+ {
+ matrix_mult( lhs._mat, rhs._mat, _mat );
+ }
+}
+
+
+Matrix Matrix::operator * (const Matrix& m) const
+{
+ Matrix tm;
+ matrix_mult( _mat,m._mat, tm._mat );
+ return tm;
+}
+
+
+bool Matrix::invert(const Matrix& invm)
+{
+ if (&invm==this) {
+ Matrix tm(invm);
+ return invert(tm);
+ }
+
+ // code lifted from VR Juggler.
+ // not cleanly added, but seems to work. RO.
+
+ const float* a = reinterpret_cast(invm._mat);
+ float* b = reinterpret_cast(_mat);
+
+ int n = 4;
+ int i, j, k;
+ int r[ 4], c[ 4], row[ 4], col[ 4];
+ float m[ 4][ 4*2], pivot, max_m, tmp_m, fac;
+
+ /* Initialization */
+ for ( i = 0; i < n; i ++ )
+ {
+ r[ i] = c[ i] = 0;
+ row[ i] = col[ i] = 0;
+ }
+
+ /* Set working matrix */
+ for ( i = 0; i < n; i++ )
+ {
+ for ( j = 0; j < n; j++ )
+ {
+ m[ i][ j] = a[ i * n + j];
+ m[ i][ j + n] = ( i == j ) ? 1.0 : 0.0 ;
+ }
+ }
+
+ /* Begin of loop */
+ for ( k = 0; k < n; k++ )
+ {
+ /* Choosing the pivot */
+ for ( i = 0, max_m = 0; i < n; i++ )
+ {
+ if ( row[ i] ) continue;
+ for ( j = 0; j < n; j++ )
+ {
+ if ( col[ j] ) continue;
+ tmp_m = fabs( m[ i][j]);
+ if ( tmp_m > max_m)
+ {
+ max_m = tmp_m;
+ r[ k] = i;
+ c[ k] = j;
+ }
+ }
+ }
+ row[ r[k] ] = col[ c[k] ] = 1;
+ pivot = m[ r[ k] ][ c[ k] ];
+
+ if ( fabs( pivot) <= 1e-20)
+ {
+ notify(WARN) << "*** pivot = %f in mat_inv. ***\n";
+ //exit( 0);
+ return false;
+ }
+
+ /* Normalization */
+ for ( j = 0; j < 2*n; j++ )
+ {
+ if ( j == c[ k] )
+ m[ r[ k]][ j] = 1.0;
+ else
+ m[ r[ k]][ j] /=pivot;
+ }
+
+ /* Reduction */
+ for ( i = 0; i < n; i++ )
+ {
+ if ( i == r[ k] )
+ continue;
+
+ for ( j=0, fac = m[ i][ c[k]];j < 2*n; j++ )
+ {
+ if ( j == c[ k] )
+ m[ i][ j] =0.0;
+ else
+ m[ i][ j] -=fac * m[ r[k]][ j];
+ }
+ }
+ }
+
+ /* Assign invers to a matrix */
+ for ( i = 0; i < n; i++ )
+ for ( j = 0; j < n; j++ )
+ row[ i] = ( c[ j] == i ) ? r[j] : row[ i];
+
+ for ( i = 0; i < n; i++ )
+ for ( j = 0; j < n; j++ )
+ b[ i * n + j] = m[ row[ i]][j + n];
+
+ return true; // It worked
+}
diff --git a/src/osg/Viewport.cpp b/src/osg/Viewport.cpp
new file mode 100644
index 000000000..5bd5672de
--- /dev/null
+++ b/src/osg/Viewport.cpp
@@ -0,0 +1,22 @@
+#include
+
+using namespace osg;
+
+Viewport::Viewport()
+{
+ _x = 0;
+ _y = 0;
+ _width = 800;
+ _height = 600;
+}
+
+
+Viewport::~Viewport()
+{
+}
+
+void Viewport::apply(State&) const
+{
+ glViewport(_x,_y,_width,_height);
+}
+
diff --git a/src/osgUtil/AppVisitor.cpp b/src/osgUtil/AppVisitor.cpp
new file mode 100644
index 000000000..a11665a0c
--- /dev/null
+++ b/src/osgUtil/AppVisitor.cpp
@@ -0,0 +1,18 @@
+#include
+
+using namespace osg;
+using namespace osgUtil;
+
+AppVisitor::AppVisitor():NodeVisitor(TRAVERSE_ACTIVE_CHILDREN)
+{
+}
+
+
+AppVisitor::~AppVisitor()
+{
+}
+
+
+void AppVisitor::reset()
+{
+}