From b64448bee54305949356e688dbb6f796ddda6163 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 14 Nov 2018 19:14:46 +0200 Subject: [PATCH] Initial --- build.xml | 83 ++ libs/Adler32.class | Bin 0 -> 1347 bytes libs/Deflate$Config.class | Bin 0 -> 577 bytes libs/Deflate.class | Bin 0 -> 22540 bytes libs/Encoder.class | Bin 0 -> 5391 bytes libs/Gif/a.class | Bin 0 -> 4243 bytes libs/Gif/b.class | Bin 0 -> 2754 bytes libs/Gif/c.class | Bin 0 -> 3860 bytes libs/JZlib.class | Bin 0 -> 1108 bytes libs/JpegEncoder$DCT.class | Bin 0 -> 7817 bytes libs/JpegEncoder$Huffman.class | Bin 0 -> 9285 bytes libs/JpegEncoder$JpegInfo.class | Bin 0 -> 4252 bytes libs/JpegEncoder.class | Bin 0 -> 8852 bytes libs/Lib_gif.class | Bin 0 -> 1137 bytes libs/Lib_jpeg.class | Bin 0 -> 1793 bytes libs/Lib_png3.class | Bin 0 -> 1933 bytes libs/StaticTree.class | Bin 0 -> 5556 bytes libs/Tree.class | Bin 0 -> 10703 bytes libs/ZStream.class | Bin 0 -> 4001 bytes nbproject/build-impl.xml | 1250 ++++++++++++++++ nbproject/genfiles.properties | 8 + nbproject/private/private.properties | 8 + nbproject/private/private.xml | 7 + nbproject/project.properties | 106 ++ nbproject/project.xml | 10 + src/Color.java | 492 +++++++ src/Create.java | 507 +++++++ src/Edit.java | 566 +++++++ src/Editor.java | 2038 ++++++++++++++++++++++++++ src/Face.java | 1493 +++++++++++++++++++ src/FileMan.java | 411 ++++++ src/Group.java | 237 +++ src/Ksort.java | 50 + src/Light.java | 34 + src/Line.java | 101 ++ src/Loader.java | 505 +++++++ src/Main.java | 422 ++++++ src/MainMenu.java | 534 +++++++ src/Material.java | 33 + src/MaterialEditor.java | 602 ++++++++ src/Matrix3D.java | 209 +++ src/Menu.java | 112 ++ src/Model.java | 331 +++++ src/Saver.java | 146 ++ src/StartWindow.java | 186 +++ src/Statics.java | 16 + src/Triangle.java | 467 ++++++ src/Vertex.java | 151 ++ src/examples/cubes.s3d | Bin 0 -> 16804 bytes src/examples/home.s3d | Bin 0 -> 1368 bytes src/examples/logo.s3d | Bin 0 -> 5364 bytes src/examples/tank.s3d | Bin 0 -> 40923 bytes src/icon.png | Bin 0 -> 2834 bytes src/img/30/Omni.png | Bin 0 -> 780 bytes src/img/30/TargetL.png | Bin 0 -> 520 bytes src/img/30/Zoom.png | Bin 0 -> 1131 bytes src/img/30/box.png | Bin 0 -> 1419 bytes src/img/30/brush.png | Bin 0 -> 820 bytes src/img/30/cone.png | Bin 0 -> 3795 bytes src/img/30/cursor.png | Bin 0 -> 736 bytes src/img/30/cylinder.png | Bin 0 -> 3927 bytes src/img/30/disk.png | Bin 0 -> 2586 bytes src/img/30/eye.png | Bin 0 -> 1380 bytes src/img/30/geom.png | Bin 0 -> 1819 bytes src/img/30/modes.png | Bin 0 -> 3467 bytes src/img/30/move.png | Bin 0 -> 1474 bytes src/img/30/moveObj.png | Bin 0 -> 1193 bytes src/img/30/plane.png | Bin 0 -> 2817 bytes src/img/30/pyramide.png | Bin 0 -> 2958 bytes src/img/30/rotateObj.png | Bin 0 -> 1470 bytes src/img/30/scaleObj.png | Bin 0 -> 1302 bytes src/img/30/sel.png | Bin 0 -> 1115 bytes src/img/30/sel3d.png | Bin 0 -> 1097 bytes src/img/30/sellist.png | Bin 0 -> 1028 bytes src/img/30/sphere.png | Bin 0 -> 3773 bytes src/img/30/tex.jpg | Bin 0 -> 18411 bytes src/img/30/torus.png | Bin 0 -> 3063 bytes src/img/30/triangle.png | Bin 0 -> 2629 bytes src/img/60/Omni.png | Bin 0 -> 1854 bytes src/img/60/Zoom.png | Bin 0 -> 2806 bytes src/img/60/box.png | Bin 0 -> 4249 bytes src/img/60/cone.png | Bin 0 -> 10696 bytes src/img/60/cursor.png | Bin 0 -> 1658 bytes src/img/60/cylinder.png | Bin 0 -> 11965 bytes src/img/60/disk.png | Bin 0 -> 7520 bytes src/img/60/eye.png | Bin 0 -> 5314 bytes src/img/60/geom.png | Bin 0 -> 4678 bytes src/img/60/modes.png | Bin 0 -> 9294 bytes src/img/60/move.png | Bin 0 -> 1599 bytes src/img/60/moveObj.png | Bin 0 -> 3611 bytes src/img/60/plane.png | Bin 0 -> 8772 bytes src/img/60/pyramide.png | Bin 0 -> 9450 bytes src/img/60/rotateObj.png | Bin 0 -> 3700 bytes src/img/60/scaleObj.png | Bin 0 -> 3304 bytes src/img/60/sel.png | Bin 0 -> 1902 bytes src/img/60/sel3d.png | Bin 0 -> 4552 bytes src/img/60/sellist.png | Bin 0 -> 3465 bytes src/img/60/sphere.png | Bin 0 -> 14916 bytes src/img/60/torus.png | Bin 0 -> 9585 bytes src/img/60/triangle.png | Bin 0 -> 7660 bytes 100 files changed, 11115 insertions(+) create mode 100644 build.xml create mode 100644 libs/Adler32.class create mode 100644 libs/Deflate$Config.class create mode 100644 libs/Deflate.class create mode 100644 libs/Encoder.class create mode 100644 libs/Gif/a.class create mode 100644 libs/Gif/b.class create mode 100644 libs/Gif/c.class create mode 100644 libs/JZlib.class create mode 100644 libs/JpegEncoder$DCT.class create mode 100644 libs/JpegEncoder$Huffman.class create mode 100644 libs/JpegEncoder$JpegInfo.class create mode 100644 libs/JpegEncoder.class create mode 100644 libs/Lib_gif.class create mode 100644 libs/Lib_jpeg.class create mode 100644 libs/Lib_png3.class create mode 100644 libs/StaticTree.class create mode 100644 libs/Tree.class create mode 100644 libs/ZStream.class create mode 100644 nbproject/build-impl.xml create mode 100644 nbproject/genfiles.properties create mode 100644 nbproject/private/private.properties create mode 100644 nbproject/private/private.xml create mode 100644 nbproject/project.properties create mode 100644 nbproject/project.xml create mode 100644 src/Color.java create mode 100644 src/Create.java create mode 100644 src/Edit.java create mode 100644 src/Editor.java create mode 100644 src/Face.java create mode 100644 src/FileMan.java create mode 100644 src/Group.java create mode 100644 src/Ksort.java create mode 100644 src/Light.java create mode 100644 src/Line.java create mode 100644 src/Loader.java create mode 100644 src/Main.java create mode 100644 src/MainMenu.java create mode 100644 src/Material.java create mode 100644 src/MaterialEditor.java create mode 100644 src/Matrix3D.java create mode 100644 src/Menu.java create mode 100644 src/Model.java create mode 100644 src/Saver.java create mode 100644 src/StartWindow.java create mode 100644 src/Statics.java create mode 100644 src/Triangle.java create mode 100644 src/Vertex.java create mode 100644 src/examples/cubes.s3d create mode 100644 src/examples/home.s3d create mode 100644 src/examples/logo.s3d create mode 100644 src/examples/tank.s3d create mode 100644 src/icon.png create mode 100644 src/img/30/Omni.png create mode 100644 src/img/30/TargetL.png create mode 100644 src/img/30/Zoom.png create mode 100644 src/img/30/box.png create mode 100644 src/img/30/brush.png create mode 100644 src/img/30/cone.png create mode 100644 src/img/30/cursor.png create mode 100644 src/img/30/cylinder.png create mode 100644 src/img/30/disk.png create mode 100644 src/img/30/eye.png create mode 100644 src/img/30/geom.png create mode 100644 src/img/30/modes.png create mode 100644 src/img/30/move.png create mode 100644 src/img/30/moveObj.png create mode 100644 src/img/30/plane.png create mode 100644 src/img/30/pyramide.png create mode 100644 src/img/30/rotateObj.png create mode 100644 src/img/30/scaleObj.png create mode 100644 src/img/30/sel.png create mode 100644 src/img/30/sel3d.png create mode 100644 src/img/30/sellist.png create mode 100644 src/img/30/sphere.png create mode 100644 src/img/30/tex.jpg create mode 100644 src/img/30/torus.png create mode 100644 src/img/30/triangle.png create mode 100644 src/img/60/Omni.png create mode 100644 src/img/60/Zoom.png create mode 100644 src/img/60/box.png create mode 100644 src/img/60/cone.png create mode 100644 src/img/60/cursor.png create mode 100644 src/img/60/cylinder.png create mode 100644 src/img/60/disk.png create mode 100644 src/img/60/eye.png create mode 100644 src/img/60/geom.png create mode 100644 src/img/60/modes.png create mode 100644 src/img/60/move.png create mode 100644 src/img/60/moveObj.png create mode 100644 src/img/60/plane.png create mode 100644 src/img/60/pyramide.png create mode 100644 src/img/60/rotateObj.png create mode 100644 src/img/60/scaleObj.png create mode 100644 src/img/60/sel.png create mode 100644 src/img/60/sel3d.png create mode 100644 src/img/60/sellist.png create mode 100644 src/img/60/sphere.png create mode 100644 src/img/60/torus.png create mode 100644 src/img/60/triangle.png diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..ab19f23 --- /dev/null +++ b/build.xml @@ -0,0 +1,83 @@ + + + + + + Builds, tests, and runs the project . + + + diff --git a/libs/Adler32.class b/libs/Adler32.class new file mode 100644 index 0000000000000000000000000000000000000000..d64f244e593eabc75c22e67cbfee2114110a5562 GIT binary patch literal 1347 zcmeHG+e;K-6#t#wxjF9UXgh0OO3N-9>XxEDB!OCiq6TVWX_wjEQAej)TW9SCMX)_Y z{R2e^Mc|WQ5CjoD^df}+LqvfuLHW{ygxi@>Lz7;6Y97w_JHK=N&YbVV+M9O(VmP8g z#sQHrf4STySdnp1#vy{x-qwGbK%IneN6MLY4aXfc?2H*?_Z7DH_OuN#))xp;tL0ek zNkXu?W{^!Csia9L=(ZfQH*+;^rU#6;%}h~uDq+}zM%wc94N`E&t!YADcU#gn(~S)$ z2(qyb2}*U>aC>KGO&51ENf3PlW7dQ5%qSr++|IP+B+VO4*`~wP^l?u#5Y+xuCY>

~l#aa5Ki-r2abFeZ8iD9#FsT-!bP8iMf^l+T(IZUI3rx~m*z_I_Enz&TL!CsDhd;HV}jTVgm1U*=C{aR;-!gIV34ne(8MI|yL^FF)|# AyZ`_I literal 0 HcmV?d00001 diff --git a/libs/Deflate$Config.class b/libs/Deflate$Config.class new file mode 100644 index 0000000000000000000000000000000000000000..bf9ff111ecd3c6d4e1248b7e7f7733322ead48c4 GIT binary patch literal 577 zcmY*V+fLg+6r6ROI594vKq!=3+ER)7q4|I!UV@M!MexvymtNA1*(8h1T1uR%^gH?^ zeXx-Fzz6VAh&d*zR7*Q^cF)dJKz@ET~fGAH_j&ts;5xD);|ZS{&mBqvx)iFY)B)SXzLXG(cC2pwIl0ne#}dUJ^9{Uu+_~j zjY6|;ojIFd56$$G9;Q55?PrNjFZ9&PesSpM6FZ|&H*+I9R)~7enQ1rGvzg)fO8>-+ zQk|QFr-2U&;m2$~P0Xnk&1lhnf2Duu2u-|+&_EbrNgxtawxwMEGE(BbJh8zRW3>sA?hX5pk#WKOdGP|YGQ@_oYil5sFB<8EmXW+ zz>9YZRN~zNe%$g4RO42)Km9on6N6ig#$gBZxworcrkWXHr literal 0 HcmV?d00001 diff --git a/libs/Deflate.class b/libs/Deflate.class new file mode 100644 index 0000000000000000000000000000000000000000..50794d68b5582cedd8769ba65ec16dfe71bb2746 GIT binary patch literal 22540 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 m_o#z@gvX7KP#3*So3N|?1&GdZgcd?`24+)CO|j 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 literal 0 HcmV?d00001 diff --git a/libs/Gif/b.class b/libs/Gif/b.class new file mode 100644 index 0000000000000000000000000000000000000000..2ac6e3e14599d472e7705db6f68588559223f4c4 GIT binary patch literal 2754 zcma)8TXR!Y6kaFiVz4qSU-s!!E zKl~^nX*qAn5lbd4Ic~`bOC}?t$tJ>!gbZOTVH@EU!mEVsgdK#PgdRdK;Wa`ZVHe>I zLOON5uBV#w=J(Pa-|P#39GbaY5e z4ofyB!?KU?0bwuU5aA%<-I(Ork*AxN_hK@_-Vw$|2?hB$CS!!7bdM3n<-?d1*_t9u z6J`h}Wq(X&**e7$CAQ||qnMm#>kMI@?k8-WC45Ra$NJ96`xqSmVjnn|YB*6=(29#@qkMyZfTWa9xqgSS$-e;wdL8UNv z6sL-%9?Y_9x-h0mw10kdY^GG4o;rmocNdSQM>Nq;g*K!~=tv)dULMAtQCIp9qI*cmM5%xtlQGVT4P{OIw){ET!%K4Dyjsf(5FoGK8gkh)FT@q!^M?3{@$HuoOdEiXkt>P?%zfOfht(7*bOV zp(%#e6hm%`p*V09c32Kz9XYiAz-qXjU;Xc-(|2NlSib8>AQ9h9et9<;wKyvAR^xZHwxL&k6*Ui$$AJXapx6x-jpDC;>?lh1$&@M_U5 z(KJhq9YWARFr+dcs%74UzL3g{OtD3I#s@oLB#-+BH;Hc7qO7YH^=OiPwPWZ-5|-!b zJ3HEMiGwlGj!^beNGn(Vs+Y6^Gli-p;T4nCdXsBCSgk0uUQC{{Ho*N!R8I;C6M>jM zt1%bl*#OHm+Ks||fXP@Pcf)Nc9jEF+6RR?&o{8XtSWjn*e@o(*B3fs7yr*1w;MiWI zQ0>duzGp8j9lN-WBXgN>=(;R=VT`usJ#)Cn3wseXKF=5kMLlD4=MB`iAWdjy%yQ+I zTKH?}_iWE7WGv6PBBnw1tU@khT;(v&9)4PeFKQXCR(|t6la+YkjEP_z7P%#>L70sK zh${iav(*uu*>Yu&0$5$H^w)-RH(chZAHY3q>|Tl1G=Vdy{^4Rh9y|MJOyh~&smC+~ zR17(n@*&2s$e&M$J$ORw??+-PpVs|^*tU9%AE`MSm6(?$Id84WxvLASZ(Ee-xeLo- zE5-w9r-1tn@0P*QMip3-(vib*ZOzk#wQ%aokl9)_)UnSleeT$(HCe9Q$5+&^{S6-D z1!?|DC|VFsf*BG+xY@Nkjh$>ROPZ-nUTJEdX5Fa1L=jy4GAG%IUmY1bTx*8wL?nY;4qchp)TxfKzH#$ExIzKl$_Zu82x&A_HW`iSjeak-zh_l=P literal 0 HcmV?d00001 diff --git a/libs/Gif/c.class b/libs/Gif/c.class new file mode 100644 index 0000000000000000000000000000000000000000..c049fa4716d9cd7f9111a3561ceadc6129b0070d GIT binary patch literal 3860 zcmbtXU2I%O6+UCP4d)LVXmV4K@DHLa&UI#ZB8e=9kLCJ{|Mvq)!ip=s`Nl z;(ivu9%Pf_Y;v4?^W6I|X%-kR(6It7vRGnqg55vrkUM?ooI_&z(8?)?yy>%N&mKDK zP{18@q4K9!PT8Kfuzq=cV+q!$uQV?>BtN=-arV4J4qnLd>$w&5+!dD2DxN3tu)c{0 z_Rd8-PvKd^v+mHoORHa4oo%gNeron3o98cF-B`bJ*`ZP&tv`9`!ubt&^XSIv`OiMG zdKFo~>{x;j63IYMa28C9$W4p5O^eV?i@;5b*iDP@O^Xbmi*U)@Js|t0jBn*Q$FIu>Mub?NR7zp#(;4I#c@*g-ZB0 zqepFTZh2n16)7rGDp4wI!m71WU#ZujE|{0Nmsi5AZwqI)bK?~_; z)f@*Dp{MU0mYEsdV19|@a4?@MyL2=7xQXTwcd2UJ+JBh6sm^(6wZ83Qns?l#zSAcT zE0JnBQ-#WSE$7_y8=o2+i@U}WW8?4ZGe7J(doiRH(i9NNH?uRBy~0gg4Gg?2u36$66?o^WW-~{t4NO#FR3e` z{1<5!-;R{8g18~J>dI%A*n<+|NnAG${8b6<$2!<{;LWk@jWTum@0c(q%uB%SYk%sq z;9KyTwXE}{W=lt9K{_Z0q`lG<2(%EFrrLB6HpLh!{Ey?cCi1<8ZfmV>7KJHdCk;Iv z?$SeM?ELNOvy?B(-!qh2=p76FjG@>!poQo5$;wNc5qa>FqCL(GU6rUfZ_{u27cSk9HFiP>-D85ff^6c^X4=RwNJhPI23^N}O{wMTsAA$|nK-hhH z7xz)_n+yO<;||ZWUF2JMS>(plQ=54C}mY&zYMqR0{B3MQFg_Ly&1$T}abNV|u$1F~7qFr*!r&AP>yK=$L^a_4-Nq#?;~Cf zT^Dj16(s6kUU$s$aB(Zz$|bpS$qg+l#cs9BYMYYEYcOt$Sg+<8d>OS92X$UakWA=M z@%;k5v{cyQil+*!^ffN+rsSecOVO6*qZNG+C}?)C^4u>)n+^Po$-j4Qqh@ z#DQjguvqONfu-I8a1LzE!qyzi*02lm4Ug~#LJw!2;Aip2N8ndR;7meSTm?r;ojw;_ zA#uS2@JJjAGj2jw2w!CL{X6q}cV^^or(eDTKoy>5;h_R4c$9(18F<1Vb21no2cwWd z(Kzx?{OZsT535cz4#LA{43=u6@Hq0rsN)YO0|qOeFfCEDnk}0;;mUT&-}o?4JfZ1^%WYm~uP~|= z#USMg>veoLd<$2bf}41xMJxkeQq=XDi#7BFw{6pkk2(vpZOf+HoW{v@)m16zO#2l( zG&#D>q@S^L(AMVCkN655Zd0A-@^=QSrSkupm8y;2VUG$%5Dv`Ahu&c9`n@443(tcv zh+Z&AmdYLK^r-I-JN`JJ?P*LZdLJC)U5r=WFz8|H6=yUV_Xk=)4oa+6XhImIcPl%U zy*xaC3PQYtlQEwjt9LZ$N3aV?oHT%S*n~7J;DltTb+~Ro7IJ@CL0*(NkGv%DGIBxU z736agQ+!e4^T?|blmFU3ye={2UyzvcHzdA@v?=ix@+FDM|FXp7cSU0IyDBlA|C+?t zk#9(R6Zw|Jw~_Bid>6SSaT#lx!wPR>MekvSw{WE=S!5q^VQ?RRsr&$Mup!vBY2ZGt lq^7q&L*f(uNyMQFt^fi<-{KboAb%DFJJ?aO+lwRj{{ZFcy5;}? literal 0 HcmV?d00001 diff --git a/libs/JpegEncoder$DCT.class b/libs/JpegEncoder$DCT.class new file mode 100644 index 0000000000000000000000000000000000000000..656153ac5f4b4be5c710b4cdeead150c858facee GIT binary patch literal 7817 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 IiDy3WKez*5p#T5? literal 0 HcmV?d00001 diff --git a/libs/JpegEncoder$JpegInfo.class b/libs/JpegEncoder$JpegInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..8cddb3e8820cb8ba5e22bd80c433aadaaa61a498 GIT binary patch literal 4252 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 literal 0 HcmV?d00001 diff --git a/libs/JpegEncoder.class b/libs/JpegEncoder.class new file mode 100644 index 0000000000000000000000000000000000000000..48f579d1691880d5abc0d6a44e70954803ae7717 GIT binary patch literal 8852 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 B;i>=t literal 0 HcmV?d00001 diff --git a/libs/Lib_gif.class b/libs/Lib_gif.class new file mode 100644 index 0000000000000000000000000000000000000000..461da952b3b10e1cc417b70fb906ac9c39fd3709 GIT binary patch literal 1137 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 literal 0 HcmV?d00001 diff --git a/libs/StaticTree.class b/libs/StaticTree.class new file mode 100644 index 0000000000000000000000000000000000000000..6baf9d98297cfd44d891e7cd136c89a1f9d1dfef GIT binary patch literal 5556 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 RN0-Zdx>~Daba@<&{Ra=haD4y( literal 0 HcmV?d00001 diff --git a/libs/Tree.class b/libs/Tree.class new file mode 100644 index 0000000000000000000000000000000000000000..b3fc3477a322d34d365edfdf371aba4c3cbf4273 GIT binary patch literal 10703 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 GYWP3jmhrm) literal 0 HcmV?d00001 diff --git a/libs/ZStream.class b/libs/ZStream.class new file mode 100644 index 0000000000000000000000000000000000000000..afb48d5b47f2e36660807febfe85c39bc09df87e GIT binary patch literal 4001 zcmaJ@Yj7J^75>(et%ui})FSF26Z;u)QL zzH{&W&bjBFbJstcnAr+Crt5P5%&i0zAyr|`99I^7x8`( z9}w|D5g!Usd{}mVM6{2J_?W-j8%L-h%bb> z?2EGDOCr83BwrEjK@ks$_^L#>Cfe6ToCx6S0X(81G~9P*?vDQS#JC16t)Xe4Tw1b> zk~L`*mrWl}8R4SA)KGO%IGY<8%?)J^jNc}+&=ASy_V4Ag9O z$~JT$<5}m^5X|O=(j#e`&d&%WqT$qVE|Z!}WyD8FgFl-az1`-V7)$jH=Taks8X6f( zDm9oJOb<+G2xN1qv9Xa+-wXWHu!a7ewPRzWV`9Ca7zX<$`edbT`>&!Af3E32%G7^g zsAhUz9dj}@Hl7|GshOXn*OGb6$`wi)>JIfYdI!>yH;?gj#!;hCRP#ZrY#Fwy?ciUg;K%VtHGD(nq;~M%6V>yWC|s7WO-rQ ztV|fwMOvbn@{CcOG%5wbj?r%&E-Z=TETb`v1@blK?HJNzC0!!j#oDSbnn%qd$3!|S zxS>?Ot70s&@UqIN7Wt z&7^TILq`^ebj+Y2;s_@O?NsWR#2sS$hK?e>siTClj<*V2!n%%cpj)(J9)7j!m2n;0Ya1;tYd#%kdT+XYrJd zag6F178l<%iFd-k(^EVpbMj76c-5NE|+)@638 zSlv4km(A_@Kg-$pcAK&e6PK?eVT(%2#o;h%ixOOsxtjs!F|O29y~xi=)o!CArHQl_%;ttGYhPEN=VVGkqx0nmcAOxYjT(40ICEqNAo2T#Md0sl$b>X4({ z!WCeL`f(2;?7%4^-QEKO(?sAal6Uxexw?*)U^3nu*+l(1b(^O_?Kz?Lx7lml{Xv+F zRpOYztiyCGJ*v;OFtu-@;Zmwc6ji6a$fXLoR3XgauyVxL&mkRhNEu$c??pJ*J)A+8 zvldblNzPD+6XQV|f!XT-_NJj0ZO zZoSywCiLE<#vH|KPNOOVPm<^iqWmOWiKje{w>pla3~JGJ+^8IDbS!T9<*MHCJjr~t z#4h&B8{b4z&8K|}Pt)gl<;yOln0v^WdkZmC)TN&%X_NBGoHO@?;K$N(&b#;$e!J;+ zOUe@|Q72Udt zZ8na2V9PlVXszmTDx08euW?1U+XT(-oWt&ra%kbNHU0#yP979xY6Gf<38Dg`V(y6F zYizIwsW!*+8+_212ZD%zh|LvQMWbkZ;G*)t+3mQO&l>O(1o1Pb`{!(}U+|x%U*ZIQ zg=g?<{06_pU+_CTi{Ik{{-6c%M=gdwX&v~pb^~XoxLb9ImT-zEsCD9)Tc|hjW@2uK zY;(1&t36ZI$XDy672IuCmUb13rJi0E7<}i={+NIJ8XC5XvWj}&x}3Q)=I1#(?Q>qU ziuNQ`KYuUd?^^z@i}^Qk{YDLUx5xZWN;$_gUMD;+kNG8!9BLJtWSs(kMFalERQ;WY zeHPc?A3Wec`HlM*zYYK9x8ym#RnMzr$blKG+er&}n^VmTc)O}*nZ1XakDPNVRetrd z_0SSQJ-bUPTy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Classpath to J2ME Ant extension library (libs.j2me_ant_ext.classpath property) is not set. For example: location of mobility/modules/org-netbeans-mobility-antext.jar file in the IDE installation directory. + Platform home (platform.home property) is not set. Value of this property should be ${platform.active.description} emulator home directory location. + Platform boot classpath (platform.bootclasspath property) is not set. Value of this property should be ${platform.active.description} emulator boot classpath containing all J2ME classes provided by emulator. + Must set src.dir + Must set build.dir + Must set dist.dir + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set preprocessed.dir + + + + + + + + + + + + + + + + + + Must set build.classes.dir + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + Must set obfuscated.classes.dir + + + + Must set obfuscated.classes.dir + Must set obfuscator.srcjar + Must set obfuscator.destjar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set preverify.classes.dir + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MicroEdition-Configuration: ${platform.configuration} + + MicroEdition-Configuration: ${platform.configuration} + + + + MicroEdition-Profile: ${platform.profile} + + MicroEdition-Profile: ${platform.profile} + + + + Must set dist.jad + + + + + + + + + + + + + + + + + + + + + + + + ${manifest.midlets}${evaluated.manifest.apipermissions}${evaluated.manifest.pushregistry}${manifest.others}${manifest.jad} + ${manifest.midlets}${evaluated.manifest.apipermissions}${evaluated.manifest.pushregistry}${manifest.others}${manifest.manifest} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Starting emulator with port number ${active.debug.port} + + + + + + + + + + + + + + + + + Starting emulator with port number ${active.debug.port} + + + + + + + + + + + + + + + + + Must set dist.javadoc.dir + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${all.configurations} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Property deployment.${deployment.method}.scriptfile not set. The property should point to an Ant script providing ${deployment.method} deployment. + + + + + + + + Classpath to Ant Contrib library (libs.ant-contrib.classpath property) is not set. + + + + + + + + + Active project configuration: @{cfg} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Property build.root.dir is not set. By default its value should be \"build\". + Property dist.root.dir is not set. By default its value should be \"dist\". + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..9977f8c --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +build.xml.data.CRC32=e04156cc +build.xml.script.CRC32=871132c0 +build.xml.stylesheet.CRC32=9c6a911d +nbproject/build-impl.xml.data.CRC32=e04156cc +nbproject/build-impl.xml.script.CRC32=44247065 +nbproject/build-impl.xml.stylesheet.CRC32=051c3749 diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties new file mode 100644 index 0000000..e1f34d5 --- /dev/null +++ b/nbproject/private/private.properties @@ -0,0 +1,8 @@ +#Mon, 21 Oct 2013 10:01:29 +0300 +app-version.autoincrement=true +config.active= +deployment.counter=4 +deployment.number=0.0.3 +javadoc.preview=true +netbeans.user=C\:\\Users\\aNNiMON\\AppData\\Roaming\\NetBeans\\dev +platform.apis.defaults=JSR179-1.0,JSR75-1.0 diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 0000000..6807a2b --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..1857603 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,106 @@ +abilities=MMAPI=1.0,CLDC=1.1,OBEX=1.0,JSR179=1.0,bin/api__.jar=1.0,JSR82=1.0,JSR184=1.0,NOKIAUI=1.0,WMA=1.1,libs/jsr75.jar=1.0,MIDP=2.0,JSR75=1.0,JSR172=1.0, +all.configurations=\ +application.args= +application.description= +application.description.detail= +application.name= +application.vendor=Vendor +build.classes.dir=${build.dir}/compiled +build.classes.excludes=**/*.java,**/*.form,**/*.class,**/.nbintdb,**/*.mvd,**/*.wsclient,**/*.vmd +build.dir=build/${config.active} +build.root.dir=build +debug.level=debug +debugger.timeout= +deployment.copy.target=deploy +deployment.instance=default +deployment.jarurl=${dist.jar} +deployment.method=NONE +deployment.override.jarurl=false +dist.dir=dist/${config.active} +dist.jad=S3DEditor.jad +dist.jar=S3DEditor.jar +dist.javadoc.dir=${dist.dir}/doc +dist.root.dir=dist +extra.classpath= +file.reference.S3DEditor-libs=libs +filter.exclude.tests=false +filter.excludes= +filter.more.excludes=**/overview.html,**/package.html +filter.use.standard=true +jar.compress=true +javac.debug=true +javac.deprecation=false +javac.encoding=UTF-8 +javac.optimize=false +javac.source=1.3 +javac.target=1.3 +javadoc.author=false +javadoc.encoding= +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +libs.classpath=${file.reference.S3DEditor-libs} +main.class= +main.class.class=applet +manifest.apipermissions= +manifest.file=manifest.mf +manifest.is.liblet=false +manifest.jad= +manifest.manifest= +manifest.midlets=MIDlet-1: Shaman,/icon.png,Main\n +manifest.others=MIDlet-Vendor: Shaman\nMIDlet-Name: S3DEditor\nMIDlet-Version: 1.0\n +manifest.pushregistry= +name=S3DEditor +no.dependencies=false +nokiaS80.application.icon= +obfuscated.classes.dir=${build.dir}/obfuscated +obfuscation.custom= +obfuscation.level=0 +obfuscator.destjar=${build.dir}/obfuscated.jar +obfuscator.srcjar=${build.dir}/before-obfuscation.jar +platform.active=Oracle_Java_TM__Platform_Micro_Edition_SDK_3_2 +platform.active.description=CLDC Oracle Java(TM) Platform Micro Edition SDK 3.2 +platform.apis=JSR75-1.0,JSR179-1.0 +platform.bootclasspath=${platform.home}/lib/jsr75_1.0.jar:${platform.home}/lib/jsr179_1.0.jar:${platform.home}/lib/midp_2.0.jar:${platform.home}/lib/cldc_1.1.jar +platform.configuration=CLDC-1.1 +platform.device=JavaMEPhone2 +platform.fat.jar=true +platform.profile=MIDP-2.0 +platform.trigger=CLDC +platform.type=UEI-1.0.1 +preprocessed.dir=${build.dir}/preprocessed +preverify.classes.dir=${build.dir}/preverified +preverify.sources.dir=${build.dir}/preverifysrc +resources.dir=resources +run.cmd.options= +run.jvmargs= +run.method=STANDARD +run.security.domain=trusted +run.use.security.domain=false +savaje.application.icon= +savaje.application.icon.focused= +savaje.application.icon.small= +savaje.application.uid=TBD +savaje.bundle.base= +savaje.bundle.debug=false +savaje.bundle.debug.port= +semc.application.caps= +semc.application.icon= +semc.application.icon.count= +semc.application.icon.splash= +semc.application.icon.splash.installonly=false +semc.application.uid=E0055103 +semc.certificate.path= +semc.private.key.password= +semc.private.key.path= +sign.alias= +sign.enabled=false +sign.keystore= +src.dir=src +use.emptyapis=true +use.preprocessor=true diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..2d5d882 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,10 @@ + + + org.netbeans.modules.kjava.j2meproject + + + S3DEditor + 1.6 + + + diff --git a/src/Color.java b/src/Color.java new file mode 100644 index 0000000..11ab77d --- /dev/null +++ b/src/Color.java @@ -0,0 +1,492 @@ +/* + * Экран выбора цвета. + */ + +/* + * To change this template, choose Tools | Templates and open the template in + * the editor. + */ + +import javax.microedition.lcdui.*; + +/** + * @author Shaman + */ +public class Color extends Canvas{ + + int ww,hh,in,k,mode=0,sh; // ширина, высота экрана, текущий редактируемый элемент, клавиатура, текущее окно, и что-то еще + static int r=0xff,gr=0xff,b=0xff; + public static int x,y,frame; + private float h, s, v; + public static float H = 0; + private int[] data; + private int[] colordata; + private float dh, ds, dv; + private int offset = 3; + // private Image buf; + // private Graphics p; + /** + * constructor + */ + public Color() { + setFullScreenMode(true); + ww=getWidth(); + hh=getHeight(); + //buf=Image.createImage(ww, hh); + //p=buf.getGraphics(); + dh = 360.0f / (float) (ww - 6); + ds = 255.0f / 128.0f; + dv = 255.0f / 128.0f; + colordata = new int[128 * 128]; + sh=Statics.font.getHeight(); + } + + /** + * paint + */ + public void paint(Graphics g) { + g.setFont(Statics.font); + if(frame==0){ + g.setColor(Statics.menuBack); + g.fillRect(0, 0, ww,hh); + g.setColor(0xff0000); + g.fillRect(5, sh+5, r*(ww/2)/255, 20); + g.setColor(0x00ff00); + g.fillRect(15, sh+30, gr*(ww/2)/255, 20); + g.setColor(0xff); + g.fillRect(25, sh+55, b*(ww/2)/255, 20); + g.setColor(r,gr,b); + g.fillRect(5, sh+90, (ww-10), 25); + if(in==0)g.setColor(0xffaaaa); else g.setColor(0x677667); + g.drawRect(5, sh+5, r*(ww/2)/255, 20); + if(in==1)g.setColor(0xffaaaa); else g.setColor(0x677667); + g.drawRect(15, sh+30, gr*(ww/2)/255, 20); + if(in==2)g.setColor(0xffaaaa); else g.setColor(0x677667); + g.drawRect(25, sh+55, b*(ww/2)/255, 20); + g.setColor(0x677667); + g.drawRect(5, sh+90, (ww-10), 25); + g.setColor(Statics.textColor); + g.drawString(""+r, ww/2+15, sh+5, 20); + g.drawString(""+gr, ww/2+25, sh+30, 20); + g.drawString(""+b, ww/2+35, sh+55, 20);} + else if(frame==1){ + //g.setColor(0xffff00); + //g.drawRect(0, 0, ww - 1, hh - 1); + if(x>=128)x=127; + if(y>=128)y=127; + if(x<0)x=0; + if(y<0)y=0; + g.setColor(Statics.menuBack); + g.fillRect(0, 0, ww, hh); + + //hsvline + h = 0; + for (int i = 0; i < ww - 6; i++) { + data = HSVtoRGB((int) h, 255, 255); + h += dh; + if(Math.abs(Math.floor(H)-Math.floor(h))<=1) + g.setColor(255-data[0],255-data[1],255-data[2]); + else + g.setColor(data[0], data[1], data[2]); + g.drawLine(offset + i, sh+6, offset + i, sh+24); + } + if(in<1){ + upData(); + } + if(in==0)g.setColor(0xffaaaa); else g.setColor(0x677667); + g.drawRect(2, sh+5, ww - 5, 20); + if(in==1)g.setColor(0xffaaaa); else g.setColor(0x677667); + g.drawRect(15, sh+38, 129, 129); + g.drawRGB(colordata, 0, 128, 16, sh+39, 128, 128, false); + g.setColor(colordata[y*128+x]); + g.fillRect(144, sh+39, 20, 128); + g.setColor(0x555555); + g.drawArc(x+9, y+sh+32, 15, 15, 0, 360); + //g.drawString("" + (int)H, ww/2, sh+39, 20); + } + drawLeftSoft(g,frame==0?(Statics.russian?"Палитра":"Palette"):"RGB"); + drawRightSoft(g,"Ok"); + repaint(); + if(k!=0){ + sk(); + } + } + + private void upData(){ + // обновляем HSV-квадрат + v = 255; + for (int i = 0; i < 128; i++) { + s = 255; + for (int i2 = 0; i2 < 128; i2++) { + data = HSVtoRGB((int) H, (int) s, (int) v); + colordata[(i * 128) + i2] = data[0] << 16 | data[1] << 8 | data[2]; + s -= ds; + } + v -= dv; + } + } + + private void drawLeftSoft(Graphics g,String s){ + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(0, hh - sh+1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(0, hh - sh+1, g.getFont().stringWidth(s)+5, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, 2, hh - 2, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, hh - 1, 36);} + else{ + g.setColor(8947967); + g.fillRoundRect(0, hh - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(0, hh - 40, g.getFont().stringWidth(s)+5, 38,15,15); + g.setColor(0x555555); + g.drawString(s, 2, hh + sh/2 - 20, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, hh +sh/2 - 19, 36); + } + } + + private void drawRightSoft(Graphics g,String s){ + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(ww-g.getFont().stringWidth(s)-5, hh - sh + 1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(ww-g.getFont().stringWidth(s)-5, hh - sh + 1, g.getFont().stringWidth(s)+4, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, ww - 4, hh - 2, 40); + g.setColor(Statics.textColor); + g.drawString(s, ww - 3, hh - 1, 40);} + else{ + g.setColor(8947967); + g.fillRoundRect(ww-g.getFont().stringWidth(s)-5, hh - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(ww-g.getFont().stringWidth(s)-5, hh-40, g.getFont().stringWidth(s)+4, 38,15,15); + g.setColor(0x555555); + g.drawString(s, ww - 4, hh+sh/2- 20, 40); + g.setColor(Statics.textColor); + g.drawString(s, ww - 3, hh+sh/2 - 19, 40); + } + } + + public static int[] HSVtoRGB(int H, int S, int V) { + int divisor = 255 * 60; + int f; + int hTemp; + int p, q, t; + int VS; + if (S == 0) { + return new int[]{V, V, V}; + } else { + if (H == 360) { + hTemp = 0; + } else { + hTemp = H; + } + + f = hTemp % 60; + hTemp = hTemp / 60; + + VS = V * S; + p = V - VS / 255; + q = V - (VS * f) / divisor; + t = V - (VS * (60 - f)) / divisor; + + if (hTemp == 0) { + return new int[]{V, t, p}; + } else if (hTemp == 1) { + return new int[]{q, V, p}; + } else if (hTemp == 2) { + return new int[]{p, V, t}; + } else if (hTemp == 3) { + return new int[]{p, q, V}; + } else if (hTemp == 4) { + return new int[]{t, p, V}; + } else if (hTemp == 5) { + return new int[]{V, p, q}; + } else { + return new int[]{0, 0, 0}; + } + } + } + + public static float[] RGBtoHSV(float rr,float gg,float bb){ + float computedH,computedS,computedV; + + rr=rr/255; gg=gg/255; bb=bb/255; + float minRGB = Math.min(rr,Math.min(gg,bb)); + float maxRGB = Math.max(rr,Math.max(gg,bb)); + + // Black-gray-white + if (minRGB==maxRGB) { + computedV = minRGB*255; + return new float[]{0,255,255-computedV}; + } + + // Colors other than black-gray-white: + float dd = (rr==minRGB) ? gg-bb : ((bb==minRGB) ? rr-gg : bb-rr); + float hh = (rr==minRGB) ? 3 : ((bb==minRGB) ? 1 : 5); + computedH = 60*(hh - dd/(maxRGB - minRGB)); + computedS = 255*(maxRGB - minRGB)/maxRGB; + computedV = maxRGB*255; + return new float[]{computedH,255-computedS,255-computedV}; + } + + private void sk(){ + // обработка клавиш + int sp=1; + int gac=getGameAction(k); + switch(gac){ + case LEFT: if(frame==0){ + if(in==0&&r>=sp) + r-=sp; + else if(in==1&&gr>=sp) + gr-=sp; + else if(in==2&&b>=sp) + b-=sp; + } + else{ + if(in==0){ + if((H-=5)<0) + H=360;} + else if(in==1){if(x>=1)x-=1;} + } break; + case RIGHT: if(frame==0){ + if(in==0&&r<=254) + r+=sp; + else if(in==1&&gr<=254) + gr+=sp; + else if(in==2&&b<=254) + b+=sp;} + else { + if(in==0){ + if((H+=5)>360) + H=0;} + else if(in==1){if(x<127)x+=1;} + }break;} + switch(k){ + case 56: if(in==1&&frame==1){ + if(y<127)y+=1; + }break; + case 50: if(in==1&&frame==1){ + if(y>=1)y-=1; + } + } + } + + public void setColor(int c){ + r=c>>16&0xff; + gr=c>>8&0xff; + b=c&0xff; + if(frame==1){ + float[] data=RGBtoHSV(r,gr,b); H=data[0]; x=(int)(data[1]*128/255); y=(int)(data[2]*128/255); upData(); + } + } + + /** + * Called when a key is pressed. + */ + protected void keyPressed(int key) { + if((key==50||key==56||key==52||key==54)&&frame==1&&in==1)k=key; + int sp=5; + String strCode = null; + try { + strCode = getKeyName(key).toLowerCase(); + } + catch (IllegalArgumentException e) { + } + if (strCode != null) + { + if (((("soft1".equals(strCode)) || ("soft 1".equals(strCode)) || ("soft_1".equals(strCode)) || ("softkey 1".equals(strCode)) || ("sk2(left)".equals(strCode)) || (strCode.startsWith("left soft"))))){ + if(frame==0){frame=1; float[] data=RGBtoHSV(r,gr,b); H=data[0]; x=(int)(data[1]*128/255); y=(int)(data[2]*128/255); upData(); } else{ frame=0; setColor(colordata[y*128+x]); } in=0; return;} //left + if (("soft2".equals(strCode)) || ("soft 2".equals(strCode)) || ("soft_2".equals(strCode)) || ("softkey 4".equals(strCode)) || ("sk1(right)".equals(strCode)) || (strCode.startsWith("right soft"))){ + returnColor(); return;}//right + } + switch (key) + { + case -202: + case -21: + case -6: + case 21: + case 105: + case 113: + case 57345: + if(frame==0){frame=1; float[] data=RGBtoHSV(r,gr,b); H=data[0]; x=(int)(data[1]*128/255); y=(int)(data[2]*128/255); upData(); } else{ frame=0; setColor(colordata[y*128+x]); } in=0; break;//left + case -203: + case -22: + case -7: + case 22: + case 106: + case 112: + case 57346: + returnColor();break;//right + } + int ga=getGameAction(key); + switch(ga){ + case LEFT: if(in==-1&&frame==1){frame=0;break;}if(frame==0){ + if(in==0&&r>=sp) + r-=sp; + else if(in==1&&gr>=sp) + gr-=sp; + else if(in==2&&b>=sp) + b-=sp; + } + else{ + if(in==0){ + if((H-=sp)<0) + H=360;} + else if(in==1){} + } break; + case RIGHT: if(in==-1&&frame==0){frame=1;break;} + if(frame==0){ + if(in==0&&r<=254) + r+=sp; + else if(in==1&&gr<=254) + gr+=sp; + else if(in==2&&b<=254) + b+=sp;} + else { + if(in==0){ + if((H+=sp)>360) + H=0;} + else if(in==1){} + } break; + case UP: if (in>0&&key!=50)in--;break; + case DOWN: if(in<2&&key!=56)in++;if(frame==1&&in>1)in=1;break; + case FIRE: returnColor(); + } + if(key==49){frame=0; setColor(colordata[y*128+x]); in=0; } + else if(key==51){frame=1; float[] data=RGBtoHSV(r,gr,b); H=data[0]; x=(int)(data[1]*128/255); y=(int)(data[2]*128/255); in=0; } + } + + private void returnColor(){ + // возвращаем выбранный цвет в соответствующие места + int rl; + if(frame==0) + rl=r<<16|gr<<8|b; + else rl=colordata[y*128+x]; + switch(mode){ + case 0: Main.main.e.color=rl;break; + case 1: Statics.edBack=rl;Main.main.e.clearBuffers();break; + case 2: Statics.curColor=rl;break; + case 3: Statics.gridColor=rl;break; + case 4: Statics.menuBack=rl;break; + case 5: Statics.textColor=rl;break; + case 6: Statics.menuTextColor=rl;Main.main.menu.menu.textColor=rl;break; + case 7: Statics.background=rl;break; + } + if(mode==0||mode==7)Main.main.toEditor(); else Main.main.toMenu(); + + } + + /** + * Called when a key is released. + */ + protected void keyReleased(int keyCode) { + k=0; + } + + /** + * Called when a key is repeated (held down). + */ + protected void keyRepeated(int keyCode) { + k=keyCode; + } + + /** + * Called when the pointer is dragged. + */ + protected void pointerDragged(int xp, int yp) { + if(frame==0){ + if(xp>=5&&yp>=sh+5&&xp<=ww/2+5&&yp<=25+sh){ + r=(xp-5)*255/(ww/2); + } + if(xp>=15&&yp>=sh+30&&xp<=ww/2+15&&yp<=sh+50){ + gr=(xp-15)*255/(ww/2); + } + if(xp>=25&&yp>=sh+55&&xp<=ww/2+25&&yp<=sh+75){ + b=(xp-25)*255/(ww/2); + } + if(xp>=5&&yp>=sh+90&&xp<=ww-5&&yp<=sh+115){ + frame=1; + float[] data=RGBtoHSV(r,gr,b); + H=data[0]; + x=(int)(data[1]*128/255); + y=(int)(data[2]*128/255); + } + } + else if(frame==1){ + if(xp>=3&&xp<=ww-3&&yp>=sh+6&&yp<=sh+24){ + H=(xp-3)*360/(ww-3); + if(H>=360)H=0; + if(H<0)H=360; + upData(); + } + else if(xp>=16&&yp>=sh+39&&xp<=144&&yp<=sh+167){ + x=(xp-16); + y=yp-sh-39; + } + } + } + + /** + * Called when the pointer is pressed. + */ + protected void pointerPressed(int xp, int yp) { + if(yp>=hh-40){ + if(xp<=ww/4){ + if(frame==0){ + frame=1; + float[] data=RGBtoHSV(r,gr,b); + H=data[0]; + x=(int)(data[1]*128/255); + y=(int)(data[2]*128/255);} + else{ + frame=0; + setColor(colordata[y*128+x]); + } + } + else if(xp>=ww-ww/4){ + returnColor(); + } + } + if(frame==0){ + if(xp>=5&&yp>=sh+5&&xp<=ww/2+5&&yp<=25+sh){ + r=(xp-5)*255/(ww/2); + } + if(xp>=15&&yp>=sh+30&&xp<=ww/2+15&&yp<=sh+50){ + gr=(xp-15)*255/(ww/2); + } + if(xp>=25&&yp>=sh+55&&xp<=ww/2+25&&yp<=sh+75){ + b=(xp-25)*255/(ww/2); + } + if(xp>=5&&yp>=sh+90&&xp<=ww-5&&yp<=sh+115){ + frame=1; + float[] data=RGBtoHSV(r,gr,b); + H=data[0]; + x=(int)(data[1]*128/255); + y=(int)(data[2]*128/255); + } + } + else if(frame==1){ + if(xp>=3&&xp<=ww-3&&yp>=sh+6&&yp<=sh+24){ + H=(xp-3)*360/(ww-3); + if(H>=360)H=0; + if(H<0)H=360; + upData(); + } + else if(xp>=16&&yp>=sh+39&&xp<=144&&yp<=sh+167){ + x=(xp-16); + y=yp-sh-39; + } + } + } + + /** + * Called when the pointer is released. + */ + protected void pointerReleased(int x, int y) { + } + +} diff --git a/src/Create.java b/src/Create.java new file mode 100644 index 0000000..12aa62d --- /dev/null +++ b/src/Create.java @@ -0,0 +1,507 @@ +/* + * Класс для создания основных трехмерных фигур. Плоскость, куб, рамка-куба, тор, сфера, пирамида, диск, цилиндр и конус =) + */ + +public class Create +{ + public static Face[] plane(Vertex m, Vertex n, int color) + { + Vertex a=new Vertex(m), b=new Vertex(n); + if(m.x>n.x){ + a.x=n.x; + b.x=m.x; + }else{ + a.x=m.x; + b.x=n.x; + } + if(m.z>=n.z){ + a.z=m.z; + b.z=n.z; + }else{ + a.z=n.z; + b.z=m.z; + } + Triangle[] v = new Triangle[2]; + Vertex v1 = new Vertex(a); + v1.setUV(0,0); + Vertex v2 = new Vertex(a.x, a.y, b.z); + v2.setUV(0, 1); + Vertex v3 = new Vertex(b.x, a.y, a.z); + v3.setUV(1, 0); + Vertex v4 = new Vertex(b.x, a.y, b.z); + v4.setUV(1, 1); + v[0] = new Triangle(v1, v2, v3, color); + v[0].norm(0,1,0); + v[0].setUV(); + // v[0].setUV(new float[]{0,0,0,1,1,0}); + v[1] = new Triangle(v3, v2, v4, color); + v[1].norm(0,1,0); + v[1].setUV(); + // v[1].setUV(new float[]{1,0,0,1,1,1}); + return v; } + + public static Face[] box(Vertex m, Vertex n, int color) { + Vertex a=new Vertex(),b=new Vertex(); + if(m.x>n.x){a.x=n.x;b.x=m.x;} + else{a.x=m.x;b.x=n.x;} + if(m.y>n.y){a.y=n.y;b.y=m.y;} + else{a.y=m.y;b.y=n.y;} + if(m.z>n.z){a.z=n.z;b.z=m.z;} + else{a.z=m.z;b.z=n.z;} + Triangle[] t = new Triangle[12]; + Vertex[] v = new Vertex[8]; + v[0] = new Vertex(a); + v[1] = new Vertex(a.x, b.y, a.z); + v[2] = new Vertex(b.x, b.y, a.z); + v[3] = new Vertex(b.x, a.y, a.z); + v[4] = new Vertex(a.x, a.y, b.z); + v[5] = new Vertex(a.x, b.y, b.z); + v[6] = new Vertex(b); + v[7] = new Vertex(b.x, a.y, b.z); + + t[0] = new Triangle(v[0], v[1], v[2], color); + t[0].norm(0, 0, -1); + t[0].smooth=false; + t[0].setUV(new float[]{0,1,0,0,1,0}); + t[1] = new Triangle(v[2], v[3], v[0], color); + t[1].norm(0, 0, -1); + t[1].smooth=false; + t[1].setUV(new float[]{1,0,1,1,0,1}); + + t[2] = new Triangle(v[0], v[1], v[5], color); + t[2].norm(-1, 0, 0); + t[2].smooth=false; + t[2].setUV(new float[]{1,1,1,0,0,0}); + t[3] = new Triangle(v[5], v[4], v[0], color); + t[3].norm(-1, 0, 0); + t[3].smooth=false; + t[3].setUV(new float[]{0,0,0,1,1,1}); + + t[4] = new Triangle(v[3], v[2], v[6], color); + t[4].norm(1,0,0); + t[4].smooth=false; + t[4].setUV(new float[]{0,1,0,0,1,0}); + t[5] = new Triangle(v[6], v[7], v[3], color); + t[5].norm(1,0,0); + t[5].smooth=false; + t[5].setUV(new float[]{1,0,1,1,0,1}); + + t[6] = new Triangle(v[1], v[5], v[6], color); + t[6].norm(0,1,0); + t[6].smooth=false; + t[6].setUV(new float[]{0,1,0,0,1,0}); + t[7] = new Triangle(v[6], v[2], v[1], color); + t[7].norm(0,1,0); + t[7].smooth=false; + t[7].setUV(new float[]{1,0,1,1,0,1}); + + t[8] = new Triangle(v[0], v[4], v[7], color); + t[8].norm(0,-1,0); + t[8].smooth=false; + t[8].setUV(new float[]{0,0,0,1,1,1}); + t[9] = new Triangle(v[7], v[3], v[0], color); + t[9].norm(0,-1,0); + t[9].smooth=false; + t[9].setUV(new float[]{1,1,1,0,0,0}); + + t[10] = new Triangle(v[4], v[5], v[6], color); + t[10].norm(0,0,1); + t[10].smooth=false; + t[10].setUV(new float[]{1,1,1,0,0,0}); + t[11] = new Triangle(v[6], v[7], v[4], color); + t[11].norm(0,0,1); + t[11].smooth=false; + t[11].setUV(new float[]{0,0,0,1,1,1}); + return t; } + + public static Face[] wireBox(Vertex a,Vertex b,int color){ + Line[] l=new Line[12]; + Vertex[] v=new Vertex[8]; + v[0] = new Vertex(a); + v[1] = new Vertex(a.x, b.y, a.z); + v[2] = new Vertex(b.x, b.y, a.z); + v[3] = new Vertex(b.x, a.y, a.z); + v[4] = new Vertex(a.x, a.y, b.z); + v[5] = new Vertex(a.x, b.y, b.z); + v[6] = new Vertex(b); + v[7] = new Vertex(b.x, a.y, b.z); + l[0]=new Line(v[0],v[3],color); + l[1]=new Line(v[0],v[1],color); + l[2]=new Line(v[1],v[2],color); + l[3]=new Line(v[2],v[3],color); + l[4]=new Line(v[0],v[4],color); + l[5]=new Line(v[1],v[5],color); + l[6]=new Line(v[2],v[6],color); + l[7]=new Line(v[3],v[7],color); + l[8]=new Line(v[4],v[5],color); + l[9]=new Line(v[5],v[6],color); + l[10]=new Line(v[6],v[7],color); + l[11]=new Line(v[4],v[7],color); + return l; + } + + public static Face[] torus(Vertex c, int R1, int R2, int SEGS1, int SEGS2, int color) { + int j; + int n = 0; + + if ((SEGS1 < 2) || (SEGS2 < 2)) return null; + int numVerts = 0; + int numFaces = 0; + + Vertex[] verts = new Vertex[SEGS1 * SEGS2]; + Triangle[] faces = new Triangle[SEGS1 * SEGS2 * 2]; + for (int i = 0; i < SEGS1; ++i) + for (j = 0; j < SEGS2; ++j) { + verts[numVerts] = new Vertex(); + float a1 = i * 6.2831854820251465F / SEGS1; + float a2 = j * 6.2831854820251465F / SEGS2; + int cx = (int)((R1 + R2 * Math.cos(a2)) * Math.cos(a1)); + int cz = (int)((R1 + R2 * Math.cos(a2)) * Math.sin(a1)); + int cy = (int)(R2 * Math.sin(a2)); + verts[numVerts].u = 1024 * i / SEGS1; + verts[numVerts].u/=1024; + verts[numVerts].v = 256 * j / SEGS2; + verts[numVerts].v/=256; + verts[numVerts].x = (cx + c.x); + verts[numVerts].y = (cy + c.y); + verts[numVerts].z = (cz + c.z); + ++numVerts; + } + + for (int i = 0; i < SEGS1; ++i) { + for (j = 0; j < SEGS2; ++j) { + faces[numFaces] = new Triangle(nv(), nv(), nv(), color); + faces[numFaces].a = verts[(n + j)]; + faces[numFaces].b = verts[((n + (j + 1) % SEGS2) % numVerts)]; + faces[numFaces].c = verts[((n + (j + 1) % SEGS2 + SEGS2) % numVerts)]; + faces[numFaces].norm(); + faces[numFaces].setUV(new float[]{faces[numFaces].a.u,faces[numFaces].a.v,faces[numFaces].b.u,faces[numFaces].b.v,faces[numFaces].c.u,faces[numFaces].c.v}); + + numFaces++; + faces[numFaces] = new Triangle(nv(), nv(), nv(), color); + faces[numFaces].a = verts[((n + (j + 1) % SEGS2 + SEGS2) % numVerts)]; + faces[numFaces].b = verts[((n + j + SEGS2) % numVerts)]; + faces[numFaces].c = verts[(n + j)]; + faces[numFaces].norm(); + faces[numFaces].setUV(new float[]{faces[numFaces].a.u,faces[numFaces].a.v,faces[numFaces].b.u,faces[numFaces].b.v,faces[numFaces].c.u,faces[numFaces].c.v}); + + numFaces++; + } + n += SEGS2; + } + return faces; } + + static Vertex nv() { + return new Vertex(); } + + public static Face[] pyramid(Vertex c, Vertex c2, int h, int color) { + Triangle[] t = new Triangle[6]; + Vertex[] v = new Vertex[5]; + if(c2.xc.z) c2.z=c.z-(c2.z-c.z); + v[0] = new Vertex(c.x, c.y + h, c.z); + v[1] = new Vertex(c2); + int cx = c.x - c2.x + c.x; int cz = c.z + c.z - c2.z; + v[2] = new Vertex(cx, c.y, c2.z); + v[3] = new Vertex(cx, c.y, cz); + v[4] = new Vertex(c2.x, c.y, cz); + t[0] = new Triangle(v[1], v[2], v[3], color); + t[0].norm(); + t[0].smooth=false; + t[0].setUV(new float[]{1,0,0,0,0,1}); + t[1] = new Triangle(v[3], v[4], v[1], color); + t[1].norm(); + t[1].smooth=false; + t[1].setUV(new float[]{0,1,1,1,1,0}); + if(h>0){t[0].invert();t[1].invert();} + t[2] = new Triangle(v[2], v[0], v[1], color); + t[2].norm(); + t[2].smooth=false; + t[2].setUV(new float[]{0,1,0.5F,0,1,1}); + t[3] = new Triangle(v[2], v[0], v[3], color); + t[3].norm(); + t[3].smooth=false; + t[3].setUV(new float[]{1,1,0.5F,0,0,1}); + t[4] = new Triangle(v[1], v[0], v[4], color); + t[4].norm(); + t[4].smooth=false; + t[4].setUV(new float[]{0,1,0.5F,0,1,1}); + t[5] = new Triangle(v[3], v[0], v[4], color); + t[5].norm(); + t[5].smooth=false; + t[5].setUV(new float[]{1,1,0.5F,0,0,1}); + if(h>0){t[3].invert();t[5].invert();}else{t[2].invert();t[4].invert();} + return t; + } + + public static Face[] disk(Vertex c,double r,int slices,int color){ + double angle = 6.2831853071795862D / (double)slices; + Triangle[] t=new Triangle[slices]; + Vertex[] vx=new Vertex[slices+1]; + vx[0]=new Vertex(c); + vx[0].setUV(0.5F, 0.5F); + for(int i=1;i0){t[i+3].invert();t[i+1].invert();}else{t[i].invert();t[i+2].invert();} + } + return t; + } + + public static Face[] cone(Vertex c,double r,int h,int slices,int color){ + double angle = 6.2831853071795862D / (double)slices; + Triangle[] t=new Triangle[slices*2]; + Vertex[] v=new Vertex[slices+2]; + v[0]=new Vertex(c); + v[v.length-1]=new Vertex(c.x,c.y+h,c.z); + v[0].u=v[0].v=0.5f; + v[v.length-1].u=v[v.length-1].v=0.5f; + for(int i=1;i0&&i!=slices-1){t[j+1].invert();}else if(h<0){t[j].invert();if(i==slices-1)t[j+1].invert();} + } + return t; + } + + public static Face[] sphere(Vertex c,double gRad,int gnRings,int gnSects,int color){ +// общее количество треугольников будет: + + int gnTria = (gnRings+1) * gnSects * 2; + + //===Нетрудно подсчитать и общее количество вершин: + + int gnVert = (gnRings+1) * gnSects + 2; + //====== Формирование массива вершин + Triangle[] t=new Triangle[gnTria]; + Vertex[] v=new Vertex[gnVert]; + + //====== Северный полюс + + v[0] = new Vertex (c.x, c.y+(int)gRad, c.z); + + //====== Индекс последней вершины (на южном полюсе) + + int last = gnVert - 1; //====== Южный полюс + + v[last] = new Vertex (c.x, c.y-(int)gRad, c.z); + + v[0].u=v[0].v=0; + v[last].u=0; + v[last].v=1; + + //====== Подготовка констант + + double da = Math.PI / (gnRings +2), + + db = 2 * Math.PI / gnSects, + + af = Math.PI - da/2; + + double bf = 2 * Math.PI - db/2; + + //=== Индекс вершины, следующей за северным полюсом + + int n = 1; + + //=== Цикл по широтам + + for ( double a = da; a < af; a += da) + + { + + //=== Координата у постоянна для всего кольца + + double у = gRad * Math.cos(a), + + //====== Вспомогательная точка + + xz = gRad * Math.sin(a); + + //====== Цикл по секциям (долгота) + + for ( double b = 0.; b < bf; n++, b += db) + + { + + // Координаты проекции в экваториальной плоскости + + double x = xz * Math.sin(b); + double z = xz * Math.cos(b); + + v[n] = new Vertex ((int)x+c.x, (int)у+c.y, (int)z+c.z); + v[n].u=(float)(b/bf); + v[n].v=(float)(a/af); + } } + + //====== Формирование массива индексов + + //====== Треугольники вблизи полюсов + + for (n = 0; n < gnSects; n++) + + { + t[n]=new Triangle(v[0],v[n + 1],n == gnSects - 1 ? v[1] : v[n + 2],color); + t[n].norm(); + if(n==gnSects-1) + t[n].setUV(new float[]{v[0].u,v[0].v,v[n+1].u,v[n+1].v,1,v[n+1].v}); + else t[n].setUV(new float[]{(v[n+1].u+v[n+2].u)/2,v[0].v,v[n+1].u,v[n+1].v,v[n+2].u,v[n+2].v}); + + //====== Индекс общей вершины (северный полюс) + + + //====== Индекс общей вершины (южный полюс) + t[gnTria-gnSects+n]=new Triangle(v[last],v[last-1-n],v[last-1 - ( (1 + n) % gnSects)],color); + t[gnTria-gnSects+n].norm(); + if(n==gnSects-1) + t[gnTria-gnSects+n].setUV(new float[]{v[last].u,v[last].v,v[last-1-n].u,v[last-1-n].v,1,v[last-1-n].v}); + else t[gnTria-gnSects+n].setUV(new float[]{(v[last-1-n].u+v[last-1 - ( (1 + n) % gnSects)].u)/2,v[last].v,v[last-1-n].u,v[last-1 - n].v,v[last-1 - ( (1 + n) % gnSects)].u,v[last-1 - ( (1 + n) % gnSects)].v}); + + } + + //====== Треугольники разбиения колец + + //====== Вершина, следующая за полюсом + + int k = 1; + + //====== gnSects - номер следующего треугольника + + n = gnSects; + + for (int i = 0; i < gnRings; i++, k += gnSects) { + + for (int j = 0; j < gnSects; j++, n += 2) { + + //======= Индекс общей вершины + + t[n]=new Triangle(v[k + j],v[k + gnSects + j],v[k + gnSects + ((j + 1) % gnSects)],color); + t[n].norm(); + if(j==gnSects-1) + t[n].setUV(new float[]{v[k+j].u,v[k+j].v,v[k+gnSects+j].u,v[k+gnSects+j].v,1,v[k + gnSects + ((j + 1) % gnSects)].v}); + else t[n].setUV(new float[]{v[k+j].u,v[k+j].v,v[k+gnSects+j].u,v[k+gnSects+j].v,v[k + gnSects + ((j + 1) % gnSects)].u,v[k + gnSects + ((j + 1) % gnSects)].v}); + + //======= Индекс текущей вершины + + + //======= Замыкание + + + //======= To же для второго треугольника + + t[n+1]=new Triangle(t[n].a,t[n].c,v[k + ((j + 1) % gnSects)],color); + t[n+1].norm(); + if(j==gnSects-1) + t[n+1].setUV(new float[]{t[n].uv[0],t[n].uv[1],t[n].uv[4],t[n].uv[5],1,v[k + ((j + 1) % gnSects)].v}); + else t[n+1].setUV(new float[]{t[n].uv[0],t[n].uv[1],t[n].uv[4],t[n].uv[5],v[k + ((j + 1) % gnSects)].u,v[k + ((j + 1) % gnSects)].v}); + + }} + return t; + } +} + +/* public static void calcNormals(Triangle[] faces) + { + for (int i = 0; i < faces.length; i++) { + float ax = faces[i].c.x - faces[i].a.x; + float ay = faces[i].c.y - faces[i].a.y; + float az = faces[i].c.z - faces[i].a.z; + float bx = faces[i].b.x - faces[i].a.x; + float by = faces[i].b.y - faces[i].a.y; + float bz = faces[i].b.z - faces[i].a.z; + float nx = ay * bz - az * by; + float ny = az * bx - ax * bz; + float nz = ax * by - ay * bx; + double l = Math.sqrt(nx * nx + ny * ny + nz * nz); + faces[i].nx /=l; + faces[i].ny /=l; + faces[i].nz /=l; + } + }*/ diff --git a/src/Edit.java b/src/Edit.java new file mode 100644 index 0000000..1a6d893 --- /dev/null +++ b/src/Edit.java @@ -0,0 +1,566 @@ +/* + * Это окно редактирования, ну то, что открывается по нажатию на клавишу 9. + */ + +/* + * To change this template, choose Tools | Templates and open the template in + * the editor. + */ + +import javax.microedition.lcdui.*; + +/** + * @author Shaman + */ +public class Edit extends Canvas{ + int w,h,md,xs,ys,cx,cy,tn; // md - текущее меню + public static int mo; // текущий режим. 0 - объекты, 1 - полигоны, 2 - вершины. + Menu m; + Image modes,tex; + Triangle sel; + int selv=0; + boolean mv=false; + Font f; + int sh; + + + /** + * constructor + */ + public Edit() { + setFullScreenMode(true); + m = new Menu(null, Statics.font); + w=getWidth(); + h=getHeight(); + f=Statics.font; + sh=f.getHeight(); + try{ + modes=Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/modes.png"); + }catch(Exception e){} + toEdit(); + } + + /** + * paint + */ + public void paint(Graphics g) { + g.setColor(Statics.menuBack); + g.fillRect(0, 0, w, h); + if(md!=1){ // если мы в обычном меню + m.paint(g, 0, h/3, w, h, 1); + g.setColor(0x888888); + g.fillRoundRect(w/2-modes.getWidth()/2+mo*(Statics.bigImages?66:33), h/3-(Statics.bigImages?60:30)-modes.getHeight()/2, (Statics.bigImages?60:30), (Statics.bigImages?60:30), 15, 15); + //g.setColor(0x333333); + //g.drawRoundRect(w/2-modes.getWidth()/2+mo*33, h/3-30-modes.getHeight()/2, 31, 31, 20, 20); + g.setColor(0xbbbbbb); + g.drawRoundRect(w/2-modes.getWidth()/2+mo*(Statics.bigImages?66:33)-1, h/3-(Statics.bigImages?60:30)-modes.getHeight()/2-1, (Statics.bigImages?62:31), (Statics.bigImages?62:31), 15, 15); + g.setColor(0x888888); + g.drawRoundRect(w/2-modes.getWidth()/2+mo*(Statics.bigImages?66:33), h/3-(Statics.bigImages?60:30)-modes.getHeight()/2, (Statics.bigImages?60:30), (Statics.bigImages?60:30), 15, 15); + g.drawImage(modes, w/2, h/3-modes.getHeight(), 3); + drawLeftSoft(g,Statics.russian?"Назад":"Back"); + drawRightSoft(g,Statics.russian?"Выбрать":"Select"); + } + else{ // или если в режиме редактирования UV-координат для вершин + g.setColor(0); + g.drawRect(5, 5, w-10, h-50); + if(tex!=null)g.drawImage(tex, 5, 5, 20); + if(mo==1&&Editor.sel2!=null){ + for(int i=0;i", w-(w-ld-10)/4, h-25, Graphics.TOP|Graphics.HCENTER); + drawLeftSoft(g,"Ok"); + } + repaint(); + } + + private void toEdit(){ + md=0; + if(mo!=1)m.setElems(new String[]{Statics.russian?"Свойства":"Properties",Statics.russian?"UV-координаты":"UV-coord",Statics.russian?"Нормали":"Normals",Statics.russian?"Сглаживание":"Smooth",Statics.russian?"Пробный материал":"Test material",Statics.russian?"Удалить материал":"Delete material",Statics.russian?"Удалить":"Delete"}); + else m.setElems(new String[]{Statics.russian?"Свойства":"Properties",Statics.russian?"UV-координаты":"UV-coord",Statics.russian?"Нормали":"Normals",Statics.russian?"Сглаживание":"Smooth",Statics.russian?"Пробный материал":"Test material",Statics.russian?"Удалить материал":"Delete material",Statics.russian?"Удалить":"Delete",Statics.russian?"Отделить":"Detach"}); + } + + private void toUV(){ + if(mo==1){ + md=1; + mv=false; + sel=null; + } + } + + private void toNormals(){ + md=2; + m.setElems(new String[]{Statics.russian?"Обратить":"Inverse",Statics.russian?"Пересчитать":"Recalculate"}); + } + + private void toSmooth(){ + md=3; + m.setElems(new String[]{Statics.russian?"Вкл":"On",Statics.russian?"Выкл":"Off"}); + } + + /** + * Called when a key is pressed. + */ + protected void keyPressed(int key) { + int ga=getGameAction(key); + switch(ga){ + case UP: if(md==1){ if(mv)move(0,-5); else if(cy>=5)cy-=5; } else m.up();break; + case DOWN: if(md==1){ if(mv)move(0,5); else if(cy<=h-55)cy+=5; } else m.down();break; + case RIGHT:if(md==1){ if(mv)move(5,0); else if(cx<=w-15)cx+=5; } else if(mo<2){mo++; + toEdit();}break; + case LEFT:if(md==1){ if(mv)move(-5,0); else if(cx>=5)cx-=5; } else if(mo>0){mo--; + toEdit();}break; + case FIRE: if(md==1){ + if(!mv){ + select(cx,cy); + } + else mv=false; + } else fire();break; + } + String strCode = null; + try { + strCode = getKeyName(key).toLowerCase(); + } + catch (IllegalArgumentException e) { + } + if (strCode != null) + { + if (((("soft1".equals(strCode)) || ("soft 1".equals(strCode)) || ("soft_1".equals(strCode)) || ("softkey 1".equals(strCode)) || ("sk2(left)".equals(strCode)) || (strCode.startsWith("left soft"))))) + { back(); return;}//left + if (("soft2".equals(strCode)) || ("soft 2".equals(strCode)) || ("soft_2".equals(strCode)) || ("softkey 4".equals(strCode)) || ("sk1(right)".equals(strCode)) || (strCode.startsWith("right soft"))) + {fire();return; }//right + } + switch (key) + { + case -202: + case -21: + case -6: + case 21: + case 105: + case 113: + case 57345: + back();break;//left + case -203: + case -22: + case -7: + case 22: + case 106: + case 112: + case 57346: + fire();break;//right + } + if(md==1){ + if(key==KEY_STAR){ + tn--; + if(tn<0){if(MaterialEditor.mat!=null&&!MaterialEditor.mat.isEmpty())tn=MaterialEditor.mat.size(); else tn=0; } + updImg(); + } + if(key==KEY_POUND){ + if(MaterialEditor.mat!=null&&!MaterialEditor.mat.isEmpty()){ + tn++; + if(tn>MaterialEditor.mat.size())tn=0; + } + updImg(); + } + } + } + + private void updImg(){ + // обновление заднего изображения из доступных текстур в редакторе материалов + if(tn==0||MaterialEditor.mat==null||tn>MaterialEditor.mat.size()){ + tex=null; + return;} + Material mat=(Material)MaterialEditor.mat.elementAt(tn-1); + if(mat.texture==null){tex=null;return; } + tex=Main.resizeImage(Image.createRGBImage(mat.texture, mat.w, mat.h, false), w-10, h-50); + } + + private void drawLeftSoft(Graphics g,String s){ + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(0, h - sh+1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(0, h - sh+1, g.getFont().stringWidth(s)+5, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, 2, h - 2, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, h - 1, 36);} + else{ + g.setColor(8947967); + g.fillRoundRect(0, h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(0, h - 40, g.getFont().stringWidth(s)+5, 38,15,15); + g.setColor(0x555555); + g.drawString(s, 2, h + sh/2 - 20, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, h +sh/2 - 19, 36); + } + } + + private void drawRightSoft(Graphics g,String s){ + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - sh + 1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h - sh + 1, g.getFont().stringWidth(s)+4, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, w - 4, h - 2, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h - 1, 40);} + else{ + g.setColor(8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h-40, g.getFont().stringWidth(s)+4, 38,15,15); + g.setColor(0x555555); + g.drawString(s, w - 4, h+sh/2- 20, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h+sh/2 - 19, 40); + } + } + + private void select(int xs,int ys){ // выбор вершин при редактировании uv + if(Editor.sel2==null||Editor.sel2.isEmpty())return; + boolean flg=false; + for(int i=0;i=t.uv[0]*(w-5)-5&&xs<=t.uv[0]*(w-5)+5&&ys>=t.uv[1]*(h-55)-5&&ys<=t.uv[1]*(h-55)+5){ + sel=t; + selv=1; + flg=true; + break; + } + if(xs>=t.uv[2]*(w-5)-5&&xs<=t.uv[2]*(w-5)+5&&ys>=t.uv[3]*(h-55)-5&&ys<=t.uv[3]*(h-55)+5){ + sel=t; + selv=2; + flg=true; + break; + } + if(xs>=t.uv[4]*(w-5)-5&&xs<=t.uv[4]*(w-5)+5&&ys>=t.uv[5]*(h-55)-5&&ys<=t.uv[5]*(h-55)+5){ + sel=t; + selv=3; + flg=true; + break; + } + if(!flg){ + int ai=(int)((t.uv[0]*(w-5) - xs) * (t.uv[3]*(h-55) - t.uv[1]*(h-55)) - (t.uv[2]*(w-5) - t.uv[0]*(w-5)) * (t.uv[1]*(h-55) - ys)); + int bi=(int)((t.uv[2]*(w-5) - xs) * (t.uv[5]*(h-55) - t.uv[3]*(h-55)) - (t.uv[4]*(w-5) - t.uv[2]*(w-5)) * (t.uv[3]*(h-55) - ys)); + int ci=(int)((t.uv[4]*(w-5) - xs) * (t.uv[1]*(h-55) - t.uv[5]*(h-55)) - (t.uv[0]*(w-5) - t.uv[4]*(w-5)) * (t.uv[5]*(h-55) - ys)); + if((ai>=0&&bi>=0&&ci>=0)||(ai<=0&&bi<=0&&ci<=0)){ sel=t; + selv=0; + flg=true; + break; + } + } + } + mv=flg; + } + + private void move(int xs,int ys){ // двигаем UV-координаты выбранного полигона + if(sel!=null){ + if(selv==0||selv==1){ + sel.uv[0]+=(float)(xs)/(w-5); + sel.uv[1]+=(float)(ys)/(h-55); + } + if(selv==0||selv==2){ + sel.uv[2]+=(float)(xs)/(w-5); + sel.uv[3]+=(float)(ys)/(h-55); + } + if(selv==0||selv==3){ + sel.uv[4]+=(float)(xs)/(w-5); + sel.uv[5]+=(float)(ys)/(h-55); + } + } + } + + public void fire(){ // метод при нажатии на 5 или Ок + switch(m.index){ + case 4: Material ma=new Material(); + Image tex=null; + try{ + tex=Image.createImage("/img/30/tex.jpg"); + }catch(Exception e){} + ma.setDiffuseMap(tex); + ma.self=0.2f; + //m.opacity=200; + Main.main.e.m.setMaterial(ma); MaterialEditor.mat.addElement(ma); Main.main.toEditor(); break; + case 0: if(md==2){ inverse(); Main.main.toEditor();} else if(md==3){smoothOn(); Main.main.toEditor();} + else + if(Editor.sel!=null&&Editor.sel.size()==1&&Editor.sel.firstElement() instanceof Group){ + Form fo=new Form(Statics.russian?"Свойства":"Properties"); + Main.main.d.setCurrent(fo); + fo.addCommand(new Command("Ok",1,1)); + final TextField nm=new TextField(Statics.russian?"Имя:":"Name",((Group)(Editor.sel.elementAt(0))).name,50,TextField.ANY); + fo.append(nm); + final ChoiceGroup cg=new ChoiceGroup("",List.MULTIPLE,new String[]{Statics.russian?"Видимый":"Visible"},null); + cg.setSelectedFlags(new boolean[]{((Group)(Editor.sel.elementAt(0))).visible}); + fo.append(cg); + fo.append(""+((Group)(Editor.sel.elementAt(0))).f.size()+(Statics.russian?" полигонов":" triangles")); + fo.append(""+((Group)(Editor.sel.elementAt(0))).v.size()+(Statics.russian?" вершин":" vertexes")); + fo.setCommandListener(new CommandListener(){ + public void commandAction(Command c,Displayable dis){ + ((Group)(Editor.sel.elementAt(0))).name=nm.getString(); + ((Group)(Editor.sel.elementAt(0))).visible=cg.isSelected(0); + Main.main.toEdit(); + } + }); + } break; + case 1: if(md==0)toUV(); else if(md==2){recalculateNormals(); Main.main.toEditor();} else if(md==3){smoothOff(); Main.main.toEditor();} break; + case 2: toNormals(); break; + case 3: toSmooth(); break; + case 5: deleteMaterial(); Main.main.toEditor(); break; + case 6: if(mo==0&&Editor.sel!=null){ + for(int i=0;i=5)cy-=5;break; + case DOWN: if(mv)move(0,5); else if(cy<=h-55)cy+=5;break; + case RIGHT:if(mv)move(5,0); else if(cx<=w-15)cx+=5;break; + case LEFT:if(mv)move(-5,0); else if(cx>=5)cx-=5;break; + } + } + } + + /** + * Called when the pointer is dragged. + */ + protected void pointerDragged(int x, int y) { + if(md==1&&mv){ + move(x-xs,y-ys); + xs=x; + ys=y; + } + } + + /** + * Called when the pointer is pressed. + */ + protected void pointerPressed(int xp, int yp) { + if(yp>=h-40){ + if(xp<=w/4){ + if(md>=1&&md<=3)toEdit(); else Main.main.toEditor(); + } + else if(xp>=w-w/4){ + if(md!=1)fire(); + } + } + if(md!=1){ + if(yp>h/3-modes.getHeight()/2){ + int ti=m.getTouchIndex(yp); + if(ti!=0xffffff){ + m.index=ti; + repaint(); + fire(); + } + } + if(yp<=h/3-modes.getHeight()/2){ + if(xp-((w-modes.getWidth())/2)<=modes.getWidth()/3){ + mo=0; + toEdit(); + } + else if(xp-((w-modes.getWidth())/2)<=modes.getWidth()*2/3){ + mo=1; + toEdit(); + } + else if(xp-((w-modes.getWidth())/2)<=modes.getWidth()){ + mo=2; + toEdit(); + } + } + } + else{ + int ld=Statics.font.stringWidth("Ok")+5; + if(xp>w-(w-ld-5)/2-5&&yp>=h-40){ + tn--; + if(tn<0){if(MaterialEditor.mat!=null&&!MaterialEditor.mat.isEmpty())tn=MaterialEditor.mat.size(); else tn=0; } + updImg(); + } + else if(xp>ld+(w-ld-5)/2&&yp>=h-40){ + if(MaterialEditor.mat!=null&&!MaterialEditor.mat.isEmpty()){ + tn++; + if(tn>MaterialEditor.mat.size())tn=0; + } + updImg(); + } + else{ + xs=xp; + ys=yp; + select(xp,yp); + } + } + } + + /** + * Called when the pointer is released. + */ + protected void pointerReleased(int x, int y) { + if(md==1) + mv=false; + } +} diff --git a/src/Editor.java b/src/Editor.java new file mode 100644 index 0000000..0562c29 --- /dev/null +++ b/src/Editor.java @@ -0,0 +1,2038 @@ +/* + * Окно редактора - основная рабочая среда. Самый большой и сложный класс. + */ +import java.util.*; +import javax.microedition.lcdui.*; + +public class Editor extends Canvas +{ + Model m; //объект модели + int w; //ширина экрана + int h;// высота экрана + short mode;//режим взаимодействия + short km;//код клавиш + short x=20;//поворот по Х + short y=40;//поворот по Y + short z;//поворот по Z + int xo;//сдвиг + int yo = 0; + int zo = 0; + int dist=0; + int shading=1; // 0 - lambert flat, 1 - lambert, 2 - flat, 3 - wire, 4 - bounding boxes + short act; // момент создания фигуры + short in = 0; //текущий инструмент + short iy; //поворот фигур в окне инструментов + int color=0xffffff; + int ex0,ey0,ez0,ex,ey,ez,cDupl,centerX,centerY,centerZ; //переменные для сдвига,поворота и центра при редактировании + float exs,eys,ezs; + short view=0; // 0 - perspective, 1 - top, 2 - bottom, 3 - left, 4 - right, 5 - front, 6 - back, 7... - cameras + short modem=0; // режим окна + boolean selact; //момент выделения (для select by frame и select3d + int curselx,cursely,curselz; //для 3д-выделения + int xs,ys; // координаты сенсорного нажатия + Matrix3D n; //матрица + Vertex ver1 = new Vertex(); //точки для создания новой фигуры + Vertex ver2 = new Vertex(); + Vertex cur = new Vertex(); //курсор + Image[] modes,instrs; //режимы и инструменты + Image instr; //иконка текущего инструмента + String[] innames = { Statics.russian?"Куб":"Box", Statics.russian?"Тор":"Torus", Statics.russian?"Пирамида":"Pyramide" , Statics.russian?"Цилиндр":"Cylinder", Statics.russian?"Конус":"Cone", Statics.russian?"Сфера":"Sphere", Statics.russian?"Диск":"Disk",Statics.russian?"Полигоны":"Triangles",Statics.russian?"Плоскость":"Plane",/*"Линия","Прямоугольник","Окружность","Эллипс","Текст",*/Statics.russian?"Точечный свет":"Omni light"/*,"Направленный"/*,"Прожектор","Свободная","Направленная"*/}; //инструменты + Image buf; //для двойной буферизации + Graphics g; + int[] rgb,rgb2; // экран + int[] zb,zb2; // Z-буфер + Group gr; //для POLY + public static Vector sel,sel2,sel3; // выделение + Timer timer,mattimer; // таймеры + boolean inf=true; // отрисовывать ли софты + boolean hold=false; // зажатие клавиши + boolean edges=false; //ребра + boolean starPressed=false; // нажата ли звездочка + String name="",vendor="",description=""; + Menu shad,select; // меню для шейдингов и видов + final int BOX=0,TORUS=1,PYRAMIDE=2,CYLINDER=3,CONE=4,SPHERE=5,DISK=6,POLY=7,PLANE=8,/*LINE=9,RECT=10,CIRCLE=11,ELLIPSE=12,TEXT=13,*/OMNILIGHT=9;//TARGETLIGHT=10;//,SPOTLIGHT=16,FREECAM=17,TARGETCAM=18; // инструменты + + + public Editor() + { + m = new Model(); + init(); } + + public Editor(Model mo) { + m = mo; + init(); + } + + //инициализация + private void init() { + setFullScreenMode(true); + w = getWidth(); + h = getHeight(); + buf=Image.createImage(w, h); + g=buf.getGraphics(); + rgb=new int[w*h]; + zb=new int[w*h]; + n = new Matrix3D(); + name="Model"; + vendor="Vendor"; + /*m.l=new Light[3]; + m.l[1]=new Light(0,0,-300); + m.l[0]=new Light(0,200,0); + m.l[2]=new Light(0,0,300);*/ + resetTimer(); + try{ + modes = new Image[]{Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/geom.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/eye.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/move.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/Zoom.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/cursor.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/sel.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/sel3d.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/sellist.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/moveObj.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/rotateObj.png"),Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/scaleObj.png")}; + instr=Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/box.png"); + }catch(Exception e){} + cls(); + render(); + draw(); + } + + //Паинт + protected void paint(Graphics r){ + if(modem==1)drawInstr(); // режим modem == 1 значит рисуем инструменты + if(km!=0)sk(km); // опрос клавиш + if(modem==10){ // окошко дублирования выбранных объектов + g.setColor(Statics.menuBack); + int sw=g.getFont().stringWidth(Statics.russian?"Число дубликатов:":"Num of copies"),shh=g.getFont().getHeight(); + g.fillRect(w/2-sw/2, h/2-30, sw, 60); + g.setColor(0); + g.drawRect(w/2-sw/2, h/2-30, sw, 60); + g.setColor(0x777777); + g.fillRect(w/2-g.getFont().stringWidth("999")/2, h/2-shh/2, g.getFont().stringWidth("999"), shh); + g.setColor(Statics.textColor); + g.drawString(Statics.russian?"Число дубликатов:":"Num of copies", w/2-sw/2, h/2-30, 20); + g.drawString(""+cDupl, w/2-g.getFont().stringWidth("999")/2, h/2-shh/2, 20); + g.setColor(0x888888); + g.fillRoundRect(w/2-30, h/4-30, 60, 60, 20, 20); + g.fillRoundRect(w/2-30, h-h/4-30, 60, 60, 20, 20); + g.setColor(0); + g.drawRoundRect(w/2-30, h/4-30, 60, 60, 20, 20); + g.drawRoundRect(w/2-30, h-h/4-30, 60, 60, 20, 20); + g.setColor(0xffffff); + g.fillTriangle(w/2-10, h/4+10, w/2+10, h/4+10, w/2, h/4-10); + g.fillTriangle(w/2-10, h-h/4-10, w/2+10, h-h/4-10, w/2, h-h/4+10); + drawLeftSoft("Ok"); + drawRightSoft(Statics.russian?"Отмена":"Cancel"); + } + if(modem==9){ // окошко выбора по списку + //draw(); + g.setFont(select.f); + g.setColor(0xcdcacc); + int sw=select.f.stringWidth((Statics.russian?"Объектов: ":"Objects: ")+m.g.size()+(Statics.russian?" выбрано: ":"selected: ")+((sel==null||sel.isEmpty())?0:sel.size())+" "),shh=select.f.getHeight(); + if(shh*((m.g==null?0:m.g.size())+(m.l==null?0:m.l.size())+2)>h){ + g.fillRect(w/2-sw/2, 0, sw, shh*2); + g.setColor(Statics.menuBack); + g.fillRect(w/2-sw/2, shh*2, sw, h-shh*2); + g.setColor(Statics.textColor); + g.drawString(Statics.russian?"Выбор по списку":"List choice", w/2, 0, 17); + g.drawString((Statics.russian?"Объектов: ":"Objects: ")+((m.g==null?0:m.g.size())+(m.l==null?0:m.l.size()))+(Statics.russian?" выбрано: ":"selected: ")+((sel==null||sel.isEmpty())?0:sel.size()),w/2, shh, 17); + g.setClip(w/2-sw/2, shh*2, sw, h-shh*2); + select.paint(g, w/2-sw/2, shh*2, sw, h-shh*2, 1); + if(sel!=null){ + g.setColor(0xaa00); + for(int i=0;i0){ // опции по левому софткею при выборе по списку + g.setColor(Statics.menuBack); + g.fillRect(0, h-shh*2, Statics.font.stringWidth(Statics.russian?"Выделить все":"Select all")+3, shh*2); + g.setColor(0xaaaa00); + g.fillRect(0,h-(act)*shh-1, Statics.font.stringWidth(Statics.russian?"Выделить все":"Select all")+3, shh); + g.setColor(Statics.textColor); + g.drawString(Statics.russian?"Выделить все":"Select all", 2, h-shh*2, 20); + g.drawString(Statics.russian?"Снять все":"Deselect", 2, h-shh, 20); + g.setColor(0); + g.drawRect(0, h-shh*2-1, Statics.font.stringWidth(Statics.russian?"Выделить все":"Select all")+3, shh*2); + } + } + if(modem==4||modem==3||modem==5){ // modem 3,4,5 - это выбор режима при нажатии на 0. + g.drawRGB(rgb, 0, w, 0, 0, w, h, false); + if(modem==3){ + if(mode>3)mode=0; + if(mode<0)mode=3;} + else if(modem==4){ + if(mode>7)mode=4; + if(mode<4)mode=7;} + else if(modem==5){ + if(mode>10)mode=8; + if(mode<8)mode=10;} + g.setColor(Statics.menuBack); + g.fillRect(0, h-(Statics.bigImages?67:37), w, (Statics.bigImages?67:37)); + g.setColor(0); + g.drawRect(1, h-(Statics.bigImages?66:36), w-3, (Statics.bigImages?64:34)); + int ai,bi; + if(modem==3){ai=0;bi=4;}else if(modem==4){ai=4;bi=4;}else {ai=8;bi=3;} + for(int i=0;i3)g.fillTriangle(w/2, h-(Statics.bigImages?65:35), w/2-5, h-(Statics.bigImages?62:32), w/2+5, h-(Statics.bigImages?62:32)); + if(modem<5)g.fillTriangle(w/2, h-3, w/2-5, h-6, w/2+5, h-6); + } + } + else if(modem==2){ // меню выбора шейдинга и обзора + g.setColor(Statics.menuBack); + g.fillRect(0, 0, shad.f.stringWidth(Statics.russian?"описанные боксы":"Bounding boxes"), h); + g.setColor(0); + g.drawRect(0, 0, shad.f.stringWidth(Statics.russian?"описанные боксы":"Bounding boxes"), h); + shad.paint(g, 0, 0, shad.f.stringWidth(Statics.russian?"описанные боксы":"Bounding boxes"), h, 0); + } + r.drawImage(buf, 0, 0, 20); + repaint(); + } + private void cls(){ // очищение экрана и буфера глубины. Обычное и быстрое с дополнительными буферами, ведь arraycopy очень быстр. + if(rgb2!=null&&zb2!=null){ + if(!Statics.extraBuffers){rgb2=null;zb2=null;cls();} + else{ + System.arraycopy(rgb2, 0, rgb, 0, rgb.length); + System.arraycopy(zb2, 0, zb, 0, zb.length);} + } + else{ + if(Statics.extraBuffers){clearBuffers(); } + else + for (int i=0;i57)&&view==0){ // вращение обзора посредством навигационных клавиш или джойстика + int ga=getGameAction(k); + switch(ga){ + case UP: x-=5;if(x>360)x-=360;render();break; + case DOWN: x+=5;if(x<0)x+=360;render();break; + case RIGHT: y+=5;if(y>360)y-=360;render();break; + case LEFT: y-=5;if(y<0)y+=360;render();break; + } + } + if(mode==0||mode==6){ // mode 0 - добавление геометрии, 6 - трехмерное выделение + if(view==0){ // view 0 - перспективный обзор + int sp=50; + if(dist>3000)sp=100; + if(dist>5000)sp=200; + switch(k){ + case 50: cur.y+=sp;break; + case 56: cur.y -= sp; break; + case 52: + cur.x -= sp; break; + case 54: + cur.x += sp;break; + case 49: cur.z-=sp;break; + case 51: cur.z+=sp;break; + } + } + else{ // остальные view - боковые проекции + int sp=50; + if(dist>10000)sp=10; + else if(dist>3000)sp=30; + switch(k){ + case 50: if(view==1)cur.z+=sp;else cur.y+=sp; break; + case 56: if(view==1)cur.z-=sp;else cur.y-=sp; break; + case 52: if(view==1||view==3)cur.x-=sp; else cur.z-=sp; break; + case 54: if(view==1||view==3)cur.x+=sp; else cur.z+=sp; break; + } + } + } + else if(mode==1&&view==0){ // mode 1 - обзор вращением + switch (k) { + case 50: x -= 5;if(x<0)x+=360;render(); break; + case 56: x += 5;if(x>360)x-=360;render(); break; + case 52: y -= 5;if(y<0)y+=360;render(); break; + case 54: y += 5;if(y>360)y-=360;render(); break; + case 49: z -= 5;if(z<0)z+=360;render(); break; + case 51: z += 5;if(z>360)z-=360;render();} + } + else if(mode==2){ // mode 2 - смещение + int sp=100; + if(view==0){ + if(dist>7000)sp=300; + else if(dist>5000)sp=200; + else if(dist>3000)sp=150; + switch (k) { + case 50: + yo -= sp;render(); break; + case 56: + yo += sp;render(); break; + case 52: + xo += sp;render(); break; + case 54: + xo -= sp;render(); break; + case 49: + zo -= sp;render(); break; + case 51: + zo += sp;render();} + } + else{ + if(dist>10000)sp=10; + else if(dist>3000)sp=50; + switch (k) { + case 50: + if(view==1)zo-=sp; else yo -= sp; render(); break; + case 56: + if(view==1)zo+=sp; else yo += sp; render(); break; + case 52: + if(view==2)zo+=sp; else xo += sp;render(); break; + case 54: + if(view==2)zo-=sp; else xo -= sp;render(); break; + } + } + } + else if(mode==3){ // масштабирование + if(k==50){ if(view!=0&&dist<-5000)dist-=20;else if(view!=0&&dist>2000)dist-=200; else dist-=100;render();} + if(k==56){ if(view!=0&&dist<-5000)dist+=20;else if(view!=0&&dist>2000)dist+=200; else dist+=100;render();} + } + else if(mode==4||mode==5){ // выделение + switch(k){ + case 50: cur.sy-=3;break; + case 56: cur.sy+=3;break; + case 52: cur.sx-=3;break; + case 54: cur.sx+=3;break; + } + } + else if(mode==8){ // движение выделенного + int sp=20; + if(dist>3000)sp=50; + if(dist>5000)sp=100; + switch(k){ + case 50: ey0+=sp;render();break; + case 56: ey0-=sp;render();break; + case 52: ex0-=sp;render();break; + case 54: ex0+=sp;render();break; + case 49: ez0+=sp;render();break; + case 51: ez0-=sp;render();break; + } + } + else if(mode==9){ // вращение выделенного + switch(k){ + case 50: ex-=2;render();break; + case 56: ex+=2;render();break; + case 52: ey+=2;render();break; + case 54: ey-=2;render();break; + case 49: ez+=2;render();break; + case 51: ez-=2;render();break; + } + } + else if(mode==10){ // масштабирование выделенного + switch(k){ + case 50: eys*=1.02;render();break; + case 56: eys/=1.02;render();break; + case 52: exs/=1.02;render();break; + case 54: exs*=1.02;render();break; + case 49: ezs/=1.02;render();break; + case 51: ezs*=1.02;render();break; + } + } + + draw(); + } + + public void setMatrix(){ // настраиваем матрицу на текущее положение + n.unit(); + n.translate(xo, yo, zo); + n.yrot(y); + n.xrot(x); + n.zrot(z); + n.translate(0, 0, dist); + } + + // визуализация сцены + public void render(){ + cls(); + setMatrix(); + if(Statics.grid)drawGrid(); + // m.render(rgb,zb, n,shading); + if(m.l!=null){for(int i=0;i7&&mode<11&&act==1&&Edit.mo==0))gro.render(rgb, zb, n,m.l,shading,view); + }} + if(sel!=null&&!sel.isEmpty()&&Edit.mo==0){ + for(int i=0;i0&&mode==0) + drawNewObj(); + if((Edit.mo==1||Edit.mo==2)&&act==1){ + if(mode==8){ + n.unit(); + n.translate(ex0, ey0, ez0); + n.translate(xo, yo, zo); + n.yrot(y); + n.xrot(x); + n.zrot(z); + n.translate(0, 0, dist); + } + else if(mode==9){ + n.unit(); + n.translate(-centerX, -centerY, -centerZ); + n.yrot(ey); + n.xrot(ex); + n.zrot(ez); + n.translate(centerX, centerY, centerZ); + n.translate(xo, yo, zo); + n.yrot(y); + n.xrot(x); + n.zrot(z); + n.translate(0, 0, dist); + } + else if(mode==10){ + n.unit(); + n.translate(-centerX, -centerY, -centerZ); + n.scale(exs, eys, ezs); + n.translate(centerX, centerY, centerZ); + n.translate(xo, yo, zo); + n.yrot(y); + n.xrot(x); + n.zrot(z); + n.translate(0, 0, dist); + } + } + if(Edit.mo==1&&sel2!=null&&!sel2.isEmpty()){ + for(int i=0;i=8&&act==1&&Statics.touch){ + g.drawRect(3,(Statics.bigImages?63:33),w-6,h-(Statics.bigImages?106:76)); + g.drawLine(w/3,(Statics.bigImages?63:33),w/3,h-43); + g.drawLine(w*2/3,(Statics.bigImages?63:33),w*2/3,h-43); + g.setColor(Statics.textColor); + if(mode==8){ + g.drawString("X "+ex0/10, w/3, (Statics.bigImages?63:33), Graphics.RIGHT|Graphics.TOP); + g.drawString("Y "+ey0/10, w/2, (Statics.bigImages?63:33), 17); + g.drawString("Z "+ez0/10, w*2/3+1, (Statics.bigImages?63:33), 20); + } + else if(mode==9){ + g.drawString("X "+ex, w/3, (Statics.bigImages?63:33), Graphics.RIGHT|Graphics.TOP); + g.drawString("Y "+ey, w/2, (Statics.bigImages?63:33), 17); + g.drawString("Z "+ez, w*2/3+1, (Statics.bigImages?63:33), 20); + } + else if(mode==10){ + g.drawString("X "+(String.valueOf(exs)).substring(0, (String.valueOf(exs).indexOf('.')+2)), w/3, (Statics.bigImages?63:33), Graphics.RIGHT|Graphics.TOP); + g.drawString("Y "+(String.valueOf(eys)).substring(0, (String.valueOf(eys).indexOf('.')+2)), w/2, (Statics.bigImages?63:33), 17); + g.drawString("Z "+(String.valueOf(ezs)).substring(0, (String.valueOf(ezs).indexOf('.')+2)), w*2/3+1, (Statics.bigImages?63:33), 20); + } + String s=Statics.russian?"Дубликат":"Copy"; + g.setColor(starPressed?0xbb3333:8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - 80, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h-80, g.getFont().stringWidth(s)+4, 38,15,15); + g.setColor(0x555555); + g.drawString(s, w - 4, h+Statics.font.getHeight()/2- 60, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h+Statics.font.getHeight()/2 - 59, 40); + } + g.drawImage(modes[mode], w/2, h-1, Graphics.BOTTOM|Graphics.HCENTER); + if(mode==4&&Statics.touch){ + String s=Statics.russian?"Добавить":"Add"; + g.setColor(starPressed?0xbb3333:8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - 80, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h-80, g.getFont().stringWidth(s)+4, 38,15,15); + g.setColor(0x555555); + g.drawString(s, w - 4, h+Statics.font.getHeight()/2- 60, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h+Statics.font.getHeight()/2 - 59, 40); + } + if(inf==true||Statics.touch&&modem!=9){ + if(in==POLY&&act>0&&mode==0) + drawRightSoft("Ok"); + else if(mode>=8&&act==1)drawRightSoft(Statics.russian?"Отмена":"Cancel"); + else drawRightSoft(Statics.russian?"Меню":"Menu"); + if(mode>=8)drawLeftSoft("Ok"); else drawLeftSoft(Statics.touch?(Statics.russian?"Редакт":"Edit"):(Statics.russian?"Инстр":"Geometry")); + } + } + + private void drawFlatArray(Face[] t){ // метод отрисовки плоской закраской + for (int i = t.length-1; i >=0 ; i--) { + if(t[i]!=null&&t[i] instanceof Triangle){ + t[i].setVertexMatrix(n); + t[i].setMatrix(n); + ((Triangle)t[i]).paintFlat(g); + } + } + } + + private void drawArray(Face[] t,int v){ + drawArray(t,true,v); + } + + //нарисовать массив полигонов, учитывая выбор сортировки + private void drawArray(Face[] t,boolean sr,int v) { + if(sr){for (int i = 0; i < t.length; i++) { + if(t[i]!=null)t[i].setVertexMatrix(n); + } + Ksort.sort(t); + } + for (int i = t.length-1; i >=0 ; i--) { + if(t[i]!=null){ + if(!sr)t[i].setVertexMatrix(n); + t[i].setMatrix(n); + t[i].light(null); + t[i].paint(g,v); + } + } + } + + //нарисовать новый объект, тот, что сейчас создается + private void drawNewObj() { + if(ver1!=null)ver1.setMatrix(n); + if(ver2!=null)ver2.setMatrix(n); + if(Statics.touch){ + if (in == BOX){ + int vrx=(int)Math.sqrt((ver1.sx-xs)*(ver1.sx-xs)+(ver1.sy-ys)*(ver1.sy-ys))*10; + drawArray( Create.box(new Vertex(ver1.x-vrx,ver1.y-vrx,ver1.z-vrx),new Vertex(ver1.x+vrx,ver1.y+vrx,ver1.z+vrx) , color),view);} + else if (in == TORUS){ + drawArray(Create.torus(ver1, Math.abs(ver1.sx-xs)*10,Math.abs(ver1.sy-ys)*10, 5, 5, color),view); + } + else if (in == PYRAMIDE){ + drawArray(Create.pyramid(ver1, new Vertex(ver1.x+Math.abs(ver1.sx-xs)*10,ver1.y,ver1.z+Math.abs(ver1.sx-xs)*10), (ver1.sy-ys)*10, color),view); + } + else if (in == CYLINDER) drawArray( Create.cylinder(ver1,Math.abs(ver1.sx-xs)*10, (ver1.sy-ys)*10, 10, color),view); + else if (in == CONE) drawArray( Create.cone(ver1, Math.abs(ver1.sx-xs)*10, (ver1.sy-ys)*10, 10, color),view); + else if( in == SPHERE) drawArray( Create.sphere(ver1, Math.sqrt((ver1.sx-xs)*(ver1.sx-xs)+(ver1.sy-ys)*(ver1.sy-ys))*10, 10, 10, color),view); + else if(in==DISK){ + if(act==1) drawArray(Create.disk(ver1,Math.sqrt((ver1.sx-xs)*(ver1.sx-xs)+(ver1.sy-ys)*(ver1.sy-ys))*10, 10, color),view); + } + else if(in==POLY){gr.draw(g, n,null); + if(act==2){ + g.setColor(0xbb0000); + g.fillRect(ver1.sx - 1, ver1.sy - 10, 2, 20); + g.fillRect(ver1.sx - 10, ver1.sy - 1, 20, 2); + g.setColor(0); + g.fillRect(ver1.sx - 4, ver1.sy - 4, 8, 8); + } + if(act==3){ + g.setColor(0xbb0000); + g.fillRect(ver1.sx - 1, ver1.sy - 10, 2, 20); + g.fillRect(ver1.sx - 10, ver1.sy - 1, 20, 2); + g.fillRect(ver2.sx - 1, ver2.sy - 10, 2, 20); + g.fillRect(ver2.sx - 10, ver2.sy - 1, 20, 2); + g.setColor(0); + g.fillRect(ver1.sx - 4, ver1.sy - 4, 8, 8); + g.fillRect(ver2.sx - 4, ver2.sy - 4, 8, 8); + g.setColor(color); + g.drawLine(ver1.sx, ver1.sy, ver2.sx, ver2.sy);} + } + else if(in==PLANE){ + if(act==1) drawArray(Create.plane(new Vertex(ver1.x-Math.abs(ver1.sx-xs)*10,ver1.y,ver1.z-Math.abs(ver1.sy-ys)*10), new Vertex(ver1.x+Math.abs(ver1.sx-xs)*10,ver1.y,ver1.z+Math.abs(ver1.sy-ys)*10), color),view); + } + } + else{ + if (in == BOX){ + drawArray( Create.box(ver1, cur, color),view);} + else if (in == TORUS){ + drawArray(Create.torus(ver1, (int)Math.sqrt((cur.x - ver1.x) * (cur.x - ver1.x) + (cur.z - ver1.z) * (cur.z - ver1.z)), (int)Math.sqrt((cur.y-ver1.y)*(cur.y-ver1.y)), 5, 5, color),view); + } + else if (in == PYRAMIDE){ + drawArray( Create.pyramid(ver1, new Vertex(cur.x,ver1.y,cur.z), cur.y-ver1.y, color),view); + } + else if (in == CYLINDER) drawArray( Create.cylinder(ver1,Math.sqrt((cur.x-ver1.x)*(cur.x-ver1.x)+(cur.z-ver1.z)*(cur.z-ver1.z)), cur.y-ver1.y, 10, color),view); + else if (in == CONE) drawArray( Create.cone(ver1, Math.sqrt((cur.x-ver1.x)*(cur.x-ver1.x)+(cur.z-ver1.z)*(cur.z-ver1.z)), cur.y-ver1.y, 10, color),view); + else if( in == SPHERE) drawArray( Create.sphere(ver1, Math.sqrt((cur.x - ver1.x) * (cur.x - ver1.x) + (cur.z - ver1.z) * (cur.z - ver1.z)+(cur.y-ver1.y)*(cur.y-ver1.y)), 10, 10, color),view); + else if(in==DISK){ + if(act==1) drawArray(Create.disk(ver1,Math.sqrt((cur.x-ver1.x)*(cur.x-ver1.x)+(cur.z-ver1.z)*(cur.z-ver1.z)), 10, color),view); + } + else if(in==POLY){gr.draw(g, n,null); + g.setColor(color); + if(act==2){g.drawLine(ver1.sx, ver1.sy, cur.sx, cur.sy);} + if(act==3) g.fillTriangle(ver1.sx, ver1.sy, ver2.sx, ver2.sy, cur.sx, cur.sy); + } + else if(in==PLANE){ + if(act==1) drawArray(Create.plane(ver1, cur, color),view); + } + } + } + + private void drawLeftSoft(String s){ + int sh=g.getFont().getHeight(); + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(0, h - sh+1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(0, h - sh+1, g.getFont().stringWidth(s)+5, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, 2, h - 2, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, h - 1, 36);} + else{ + g.setColor(8947967); + g.fillRoundRect(0, h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(0, h - 40, g.getFont().stringWidth(s)+5, 38,15,15); + g.setColor(0x555555); + g.drawString(s, 2, h + sh/2 - 20, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, h +sh/2 - 19, 36); + } + } + + private void drawRightSoft(String s){ + int sh=g.getFont().getHeight(); + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - sh + 1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h - sh + 1, g.getFont().stringWidth(s)+4, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, w - 4, h - 2, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h - 1, 40);} + else{ + g.setColor(8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h-40, g.getFont().stringWidth(s)+4, 38,15,15); + g.setColor(0x555555); + g.drawString(s, w - 4, h+sh/2- 20, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h+sh/2 - 19, 40); + } + } + + //3Д-сетка + private void drawGrid() { + if(view==0){ + for (int i = -1000; i <= 1000; i += 100) { + Vertex v = new Vertex(i, 0, -1000); + Vertex v2 = new Vertex(i, 0, 1000); + v.setMatrix(n); + v2.setMatrix(n); + (new Line(v,v2,Statics.gridColor)).render(rgb, zb); + v = new Vertex(-1000, 0, i); + v2 = new Vertex(1000, 0, i); + v.setMatrix(n); + v2.setMatrix(n); + (new Line(v,v2,Statics.gridColor)).render(rgb, zb); + }} + else{ + for(int i=0;i6)||Statics.touch)return; + int cx=0,cy=0; + if(mode==0||mode==6)cur.setMatrix(n); + g.setColor(Statics.curColor); + if(view==0||mode==5||mode==4){cx=cur.sx;cy=cur.sy;} + else if(view==1){double distsc=(double)dist; + if(distsc>0)distsc=distsc/10000+0.1; + else if(distsc==0)distsc=0.1; + else distsc=0.1+distsc/100000; + cx=(int)(w/2+xo*distsc+cur.x*distsc);cy=(int)(h/2-zo*distsc-cur.z*distsc);} + else if(view==2){double distsc=(double)dist; + if(distsc>0)distsc=distsc/10000+0.1; + else if(distsc==0)distsc=0.1; + else distsc=0.1+distsc/100000; + cx=(int)(w/2+zo*distsc+cur.z*distsc);cy=(int)(h/2-yo*distsc-cur.y*distsc);} + else if(view==3){double distsc=(double)dist; + if(distsc>0)distsc=distsc/10000+0.1; + else if(distsc==0)distsc=0.1; + else distsc=0.1+distsc/100000; + cx=(int)(w/2+xo*distsc+cur.x*distsc);cy=(int)(h/2-yo*distsc-cur.y*distsc);} + g.fillRect(cx - 1, cy - 10, 2, 20); + g.fillRect(cx - 10, cy - 1, 20, 2); + g.setColor(0); + g.fillRect(cx - 4, cy - 4, 8, 8); } + + private void ci(String sin,int i){ + try{ + instrs[i]=Image.createImage("/img/"+(Statics.bigImages?"60":"30")+"/"+sin+".png"); + }catch(Exception e){} + } + + //отрисовка окна инструментов + private void drawInstr() { + int sh=g.getFont().getHeight(); + g.setColor(Statics.menuBack); + g.fillRect(0, 0, w, h); + n.unit(); + n.yrot(iy); + n.xrot(30); + n.translate(0F, 0F, 100.0F); + int itmp=0; + if(instrs==null){ + if(in<=OMNILIGHT){ + instrs=new Image[10]; + ci("box",BOX); + ci("torus",TORUS); + ci("pyramide",PYRAMIDE); + ci("cylinder",CYLINDER); + ci("cone",CONE); + ci("sphere",SPHERE); + ci("disk",DISK); + ci("triangle",POLY); + ci("plane",PLANE); + ci("Omni",OMNILIGHT); } + /* else if(in>=LINE&&inOMNILIGHT){ + instrs=new Image[2]; + ci("Omni",0); + ci("TargetL",1); + // ci("Spot",2); + } + /*else if(in>=FREECAM){ + instrs=new Image[2]; + ci("FreeCam",0); + ci("TargetCam",1); + }*/ + } + String inmode=null; + if(in<=OMNILIGHT){ + itmp=0; + inmode=Statics.russian?"Геометрия":"Primitives"; + } + /*else if(in>=LINE&&inOMNILIGHT){ + itmp=OMNILIGHT; + inmode=Statics.russian?"Освещение":"Illumination"; + } + /*else if(in>=FREECAM){ + itmp=FREECAM; + inmode="Камеры"; + }*/ + if (in == BOX) drawArray( Create.box(new Vertex(-500, -900, -500), new Vertex(500, 100, 500), 21760),0); + else if (in == TORUS) drawArray( Create.torus(new Vertex(0, -500, 0), 1000, 200, 15, 15, 21760),true,0); + else if (in == PYRAMIDE) drawArray( Create.pyramid(new Vertex(0, -800, 0), new Vertex(-700, -800, 700), 1000, 21760),0); + else if (in == CYLINDER) drawArray( Create.cylinder(new Vertex(0,-800,0),700, 1000, 30, 21760),0); + else if (in == CONE) drawArray(Create.cone(new Vertex(0,-800,0), 700, 1000, 30, 21760),0); + else if (in == SPHERE){ + drawArray(Create.sphere(new Vertex(0,-500,0), 700, 10,10, 21760),0); + } + else if (in == DISK) drawArray( Create.disk(new Vertex(0,-500,0),1000, 30, 21760),false,0); + else if (in == PLANE) drawArray(Create.plane(new Vertex(-700,-500,700), new Vertex(700,-500,-700), 21760),false,0); + else if (in == OMNILIGHT){ drawFlatArray( Create.pyramid(new Vertex(0, -400, 0), new Vertex(-150, -400, 150), -500, 0xdddd00)); + drawFlatArray( Create.pyramid(new Vertex(0, -400, 0), new Vertex(-150, -400, 150), 500, 0xdddd00)); + } + int j = 5; int k = sh*2 + 5; + for (int i = 0; i < instrs.length; i++) { + if(instrs[i]!=null)g.drawImage(instrs[i], j, k, 20); + if (in == i+itmp){ + g.setColor(0xff0000); + g.drawRect(j+1, k+1, (Statics.bigImages?58:28), (Statics.bigImages?58:28)); + } + else g.setColor(0xcccccc); + g.drawRect(j, k, (Statics.bigImages?60:30), (Statics.bigImages?60:30)); + j += (Statics.bigImages?65:35); + if (j + (Statics.bigImages?60:30) > w) { + j = 5; + k += (Statics.bigImages?65:35); + } + } + g.setFont(Statics.font); + drawRightSoft("Ok"); + g.setColor(Statics.textColor); + g.drawString(innames[in], w / 2, sh+1, 17); + //g.drawString("<1", 3, 1, 20); + //g.drawString("3>", w-3, 1, Graphics.TOP|Graphics.RIGHT); + g.drawString(inmode, w/2, 1, 17); + iy += 5; + if(iy>360)iy-=360; + } + + //метод при нажатии клавиш + protected void keyPressed(int key){ + if(modem==10){ //дубликаты + int gkey=getGameAction(key); + if(gkey==UP){cDupl++;} + else if(gkey==DOWN){if(cDupl>1)cDupl--;} + else if(gkey==FIRE){ duplicate(); modem=0; render(); draw();} + String strCode = null; + try { + strCode = getKeyName(key).toLowerCase(); + } + catch (IllegalArgumentException e) { + } + if (strCode != null) + { + if (((("soft1".equals(strCode)) || ("soft 1".equals(strCode)) || ("soft_1".equals(strCode)) || ("softkey 1".equals(strCode)) || ("sk2(left)".equals(strCode)) || (strCode.startsWith("left soft")))) + ){ duplicate();modem=0; render(); draw();} + if (("soft2".equals(strCode)) || ("soft 2".equals(strCode)) || ("soft_2".equals(strCode)) || ("softkey 4".equals(strCode)) || ("sk1(right)".equals(strCode)) || (strCode.startsWith("right soft"))){ + act=0;modem=0;render(); draw(); + } + } + switch (key) + { + case -202: + case -21: + case -6: + case 21: + case 105: + case 113: + case 57345: + duplicate();modem=0; render(); draw(); break; + case -203: + case -22: + case -7: + case 22: + case 106: + case 112: + case 57346: + act=0;modem=0;render(); draw(); break; + } + } + else if(modem==9){ // выбор по списку + String strCode = null; + try { + strCode = getKeyName(key).toLowerCase(); + } + catch (IllegalArgumentException e) { + } + if (strCode != null) + { + if (((("soft1".equals(strCode)) || ("soft 1".equals(strCode)) || ("soft_1".equals(strCode)) || ("softkey 1".equals(strCode)) || ("sk2(left)".equals(strCode)) || (strCode.startsWith("left soft")))) + ){if(act==0){act=2; } else{if(act==1)sel=null; else{sel=null; sel=new Vector(); for(int i=0; i=0*/)ob=m.l.elementAt(select.index); + else ob=m.g.elementAt(select.index-mll); + if(!sel.contains(ob)) + sel.addElement(ob); + else sel.removeElement(ob);} + else{if(act==1)sel=null; else{sel=null; sel=new Vector(); for(int i=0; i7&&mode<11&&view==0) mode=4; if((!(modem==4||modem==5)&&view!=0)||view==0)modem=0;draw();} + int ga=getGameAction(key); + switch(ga){ + case RIGHT: mode++;break; + case LEFT: mode--;break; + case FIRE: if(view==0&&((sel!=null&&!sel.isEmpty()&&Edit.mo==0)||(sel2!=null&&!sel2.isEmpty()&&Edit.mo==1)||(sel3!=null&&!sel3.isEmpty()&&Edit.mo==2))){if(mode==8){act=1;ex0=ey0=ez0=0;} else if(mode==9){act=1;ex=ey=ez=0;} else if(mode==10){act=1;exs=eys=ezs=1;} modem=0; draw();} else if((view==0&&mode<7||view!=0&&mode<4&&mode!=1)&&mode!=7){modem=0; draw();} if(mode==7){toSelectionMenu();}break; + case DOWN: if(modem==3){modem=4;mode=4;} else if(modem==4){modem=5;mode=8;}break; + case UP: if(modem==4){ modem=3;mode=0;} else if(modem==5){modem=4;mode=4;}break; + } + } + else if(modem==2){ // меню шэйдинга и просмотра + int ga=getGameAction(key); + switch(ga){ + case UP: shad.up();break; + case DOWN: shad.down();break; + case FIRE: if(shad.index<4) view=(short)shad.index; else if(shad.index>4)shading=shad.index-5;shad=null;modem=0;render();draw();break; + } + } + else if(modem==1){ // инструменты + int itmp=0; + String strCode = null; + if(in<=OMNILIGHT){ + itmp=0; + } + /*else if(in>=LINE&&inOMNILIGHT){ + itmp=OMNILIGHT; + } + /* else if(in>=FREECAM){ + itmp=FREECAM; + }*/ + if (strCode != null) + { + if (("soft2".equals(strCode)) || ("soft 2".equals(strCode)) || ("soft_2".equals(strCode)) || ("softkey 4".equals(strCode)) || ("sk1(right)".equals(strCode)) || (strCode.startsWith("right soft"))){ + instr=instrs[in-itmp];instrs=null;System.gc();mode = 0; modem=0; act = 0;render();draw();} + } + switch(key){ + case -203: + case -22: + case -7: + case 22: + case 106: + case 112: + case 57346: + instr=instrs[in-itmp];instrs=null;System.gc();mode = 0; modem=0; act = 0;render();draw();break; + case 49: //instrs=null; + /*if(in>=LINE&&in=OMNILIGHT&&in=FREECAM)in=OMNILIGHT;*/ + //if (in>OMNILIGHT) in=0;break; + case 51: //instrs=null; + /*if(in=LINE&&in=OMNILIGHT&&in=0) in-=pl;break; + } + } + + + else{ // рабочее место + String strCode = null; + + try { + strCode = getKeyName(key).toLowerCase(); + } + catch (IllegalArgumentException e) { + } + if (strCode != null) + { + if (((("soft1".equals(strCode)) || ("soft 1".equals(strCode)) || ("soft_1".equals(strCode)) || ("softkey 1".equals(strCode)) || ("sk2(left)".equals(strCode)) || (strCode.startsWith("left soft"))))) + {modem = 1; return; } + if (("soft2".equals(strCode)) || ("soft 2".equals(strCode)) || ("soft_2".equals(strCode)) || ("softkey 4".equals(strCode)) || ("sk1(right)".equals(strCode)) || (strCode.startsWith("right soft"))) + { back(); return; } + } + switch (key) + { + case -202: + case -21: + case -6: + case 21: + case 105: + case 113: + case 57345: + modem = 1; break; + case -203: + case -22: + case -7: + case 22: + case 106: + case 112: + case 57346: + back(); break; + case 53: + if (mode == 0) fire(); + if(mode==4) pick(cur.sx,cur.sy); + if(mode==5) + if(selact){if(Edit.mo==0)sel=m.select(curselx,cursely,cur.sx,cur.sy,n); else if(Edit.mo==1)sel2=m.selectTr(curselx,cursely,cur.sx,cur.sy); else if(Edit.mo==2) sel3=m.selectVer(curselx,cursely,cur.sx,cur.sy); + showNotify(); + selact=false;} + else{curselx=cur.sx;cursely=cur.sy; selact=true;} + if(mode==6) + if(selact){if(Edit.mo==0)sel=m.select3d(new int[]{curselx,cursely,curselz,cur.x,cur.y,cur.z}, n); else if(Edit.mo==1)sel2=m.select3dTr(new int[]{curselx,cursely,curselz,cur.x,cur.y,cur.z}); else if(Edit.mo==2)sel3=m.select3dVer(new int[]{curselx,cursely,curselz,cur.x,cur.y,cur.z}); + showNotify(); + selact=false;} + else{curselx=cur.x;cursely=cur.y; curselz=cur.z; selact=true;} + if(mode>7&&mode<11) + if(act==1){ + act=0; + if(starPressed){ + modem=10;cDupl=1;} else if(Edit.mo==0){ + for(int i=0;i3&&mode<8){selact=false; modem=4;} + else modem=5; + if(act==1&&mode>=8&&mode<=10){ act=0;render();draw();} + break; + case 55: modem=2; + shad=new Menu(new String[]{Statics.russian?"Перспектива":"Perspective",Statics.russian?"сверху":"top",Statics.russian?"справа":"right",Statics.russian?"спереди":"front","--------",Statics.russian?"полигоны":"polygons",Statics.russian?"сглаживание":"smooth",Statics.russian?"плоское":"flat",Statics.russian?"ребра":"wires",Statics.russian?"описанные боксы":"Bounding boxes"},Statics.font); + shad.textColor=0xeeeaec; + shad.selTextColor=0xaaa6a8; + shad.curColor=0xffffff; + shad.ave=new short[]{4};break; + case KEY_STAR: if(mode>=8&&mode<=10||mode==4) starPressed=true; + } + if(mode==0&&key>48&&key<58)sk((short)key);else km=(short)key;} + } + + protected void keyRepeated(int key){ + hold=true; + if(key==KEY_STAR&&mode==0)Main.main.toMatEd(); + if(key==57)Main.main.saveScreen(buf); + if(modem==0&&key==55){ + modem=2; + shad=new Menu(new String[]{Statics.russian?"Перспектива":"Perspective",Statics.russian?"сверху":"top",Statics.russian?"справа":"right",Statics.russian?"спереди":"front","--------",Statics.russian?"полигоны":"polygons",Statics.russian?"сглаживание":"smooth",Statics.russian?"плоское":"flat",Statics.russian?"ребра":"wires",Statics.russian?"описанные боксы":"Bounding boxes"},Statics.font); + shad.textColor=0xeeeaec; + shad.selTextColor=0xaaa6a8; + shad.curColor=0xffffff; + shad.ave=new short[]{4};} + if(modem==0&&mode==0)km=(short)key; + } + + protected void keyReleased(int key){ + km=0; + if(key==KEY_STAR){ starPressed=false; if(mode==0&&!hold){ Main.main.toColor(); Main.main.color.setColor(color);}} + if(modem==0&&act==0&&key==57&&!hold)Main.main.toEdit(); + hold=false; + } + + protected void pointerPressed(int xp,int yp){ + if(modem==10){ + if(xp<=w/2+30&&xp>=w/2-30){ + if(yp>=h/4-30&&yp<=h/4+30){cDupl++;} + else if(yp>=h-h/4-30&&yp<=h-h/4+30){if(cDupl>1)cDupl--;} + } + else if(yp>=h-40){ + if(xp<=w/4){duplicate();modem=0; render(); draw();} + else if(xp>=w-w/4){act=0;modem=0; render(); draw();} + } + } + else if(modem==9){ + if(act==0){ + if(yp>=h-40&&xp>=w-w/4){ + modem=4; + select=null; + } + else{ + xs=xp; + ys=yp; + } + } + else{ + xs=xp; + ys=yp; + if(xp<=Statics.font.stringWidth(Statics.russian?"Выбрать все":"Select all")){ + if(yp>=h-select.sh){ + act=1; + } + else if(yp>=h-select.sh*2){ + act=2; + } + } + } + } + else if(modem==3||modem==4||modem==5){ + if(yp>=h-(Statics.bigImages?60:30)&&xp<=(Statics.bigImages?65:35)*(modem==5?3:4)+3){ + short imode=(short)((xp-3)/(Statics.bigImages?65:35)+(modem==4?4:(modem==5?8:0))); + if(mode==imode){if(view==0&&((sel!=null&&!sel.isEmpty()&&Edit.mo==0)||(sel2!=null&&!sel2.isEmpty()&&Edit.mo==1)||(sel3!=null&&!sel3.isEmpty()&&Edit.mo==2))){if(mode==8){act=1;ex0=ey0=ez0=0;} else if(mode==9){act=1;ex=ey=ez=0;} else if(mode==10){act=1;exs=eys=ezs=1;} modem=0; draw();} else if((view==0&&mode<7||view!=0&&mode<4&&mode!=1)&&mode!=7){modem=0; draw();} if(mode==7){toSelectionMenu();}} else mode=imode; + } + else if(yp<=h-(Statics.bigImages?60:30)&&yp>=h-(Statics.bigImages?60:30)-40){ + if(xp>=w/2&&modem!=5)modem++; + else if(xp<=w/2&&modem!=3)modem--; + } + } + else if(modem==2){ + if(xp<=shad.f.stringWidth(Statics.russian?"описанные боксы":"Bounding boxes")){ + int shi=shad.getTouchIndex(yp); + if(shi!=0xffffff)shad.index=shi; + } + else modem=0; + } + else if(modem==1){ + if(yp>=h-40&&xp>=w-40){ instr=instrs[in];instrs=null;System.gc();mode = 0; modem=0; act = 0;render();draw(); } + else if(yp>Statics.font.getHeight()*2){ + int wiw=(w-5)/(Statics.bigImages?65:35); + int imod=(xp-5)/(Statics.bigImages?65:35)+(yp-Statics.font.getHeight()*2-5)/(Statics.bigImages?65:35)*wiw; + if(imod<=OMNILIGHT&&imod>=0){if(in==imod){instr=instrs[in];instrs=null;System.gc();mode = 0;modem=0; act = 0;render();draw();} else in=(short)imod;} + } + } + else if(modem==0){ + if(xp<=w/2+(Statics.bigImages?35:20)&&xp>=w/2-(Statics.bigImages?35:20)&&yp>=h-(Statics.bigImages?60:30)){if(mode<4)modem=3;else if(mode>=4&&mode<8)modem=4; else if(mode>7)modem=5; } + else if(xp>=w-(Statics.bigImages?60:30)&&yp<=(Statics.bigImages?60:30))modem=1; + else if((mode>=8||mode==4)&&yp>=h-80&&xp>=w-w/4&&yp<=h-40)starPressed=!starPressed; + else if(xp>=w-(Statics.bigImages?123:63)&&xp<=w-(Statics.bigImages?60:30)&&yp<=(Statics.bigImages?60:30)){ + if(mattimer!=null){ + mattimer.cancel(); + mattimer=null; + } + mattimer=new Timer(); + TimerTask mt=new TimerTask(){ + public void run(){ + Main.main.toMatEd(); + } + }; + mattimer.schedule(mt, 1000); + } + else if(xp<=(Statics.bigImages?60:30)&&yp<=(Statics.bigImages?60:30)){ + modem=2; + shad=new Menu(new String[]{Statics.russian?"Перспектива":"Perspective",Statics.russian?"сверху":"top",Statics.russian?"справа":"right",Statics.russian?"спереди":"front","--------",Statics.russian?"полигоны":"polygons",Statics.russian?"сглаживание":"smooth",Statics.russian?"плоское":"flat",Statics.russian?"ребра":"wires",Statics.russian?"описанные боксы":"Bounding boxes"},Statics.font); + shad.textColor=0xeeeaec; + shad.selTextColor=0xaaa6a8; + shad.curColor=0xffffff; + shad.ave=new short[]{4};} + else if(yp>=h-40){ + if(xp<=40){if(mode>=8&&act==1){ + act=0; + if(starPressed){modem=10;cDupl=1;} + else if(Edit.mo==0){ + for(int i=0;i=w-40)back(); + } + else{ + xs=xp; + ys=yp; + if(mode==0){ + int[] unpr=Vertex.unProject(n, xp, yp); + if(in==POLY){ + if(act==0){ + gr=new Group(null,"Object",m.g==null||m.g.isEmpty()?0:m.g.size()); + act=2; + if(Statics.randColor)color=(new Random()).nextInt(0xffffff); + ver1=new Vertex(unpr[0],0,unpr[1]); + } + else if(act==1){ + act=2; + if(Statics.randColor)color=(new Random()).nextInt(0xffffff); + ver1=new Vertex(unpr[0],0,unpr[1]); + } + else if(act==2){ + act=3; + ver2=new Vertex(unpr[0],0,unpr[1]); + } + else if(act==3){ + act=1; + Triangle tr=new Triangle(new Vertex(ver1),new Vertex(ver2),new Vertex(unpr[0],0,unpr[1]),color); + tr.norm(); + tr.smooth=false; + tr.setMatrix(n); + if(tr.rnz>0){tr.nz*=-1;tr.nx*=-1;tr.ny*=-1;} + gr.add(tr); + } + return; + } + if(act==0)ver1 = new Vertex(unpr[0],0,unpr[1]); + if(Statics.randColor)color=(new Random()).nextInt(0xffffff); + act=1; + } + else if(mode>0&&mode<4){ + curselx=xp; + cursely=yp; + } + else if(mode==4){ + pick(xp,yp); + render(); + draw(); + } + else if(mode==5){ + selact=true; + curselx=xp; + cursely=yp; + } + else if(mode==6){ + int[] unpr=Vertex.unProject(n, xp, yp); + ver1 = new Vertex(unpr[0],0,unpr[1]); + selact=true; + } + else if(mode>=8){ + if(act==0){ + act=1; + if(mode==8){ex0=ey0=ez0=0;} else if(mode==9){ex=ey=ez=0;} else if(mode==10){exs=eys=ezs=1;} + } + else if(act==1){ + curselx=xp; + cursely=yp; + } + } + } + } + } + + protected void pointerDragged(int xp,int yp){ + if(modem==0){ + xs=xp; + ys=yp; + if(mode==1){ + x+=yp-cursely; + y-=xp-curselx; + curselx=xp; + cursely=yp; + } + else if(mode==2){ + xo+=(xp-curselx)*10; + yo-=(yp-cursely)*10; + curselx=xp; + cursely=yp; + } + else if(mode==3){ + dist+=(yp-cursely)*20; + curselx=xp; + cursely=yp; + } + else if(mode==8){ + if(curselx<=w/3){ + ex0-=(yp-cursely)*10; + } + else if(curselx<=w*2/3&&curselx>w/3){ + ey0-=(yp-cursely)*10; + } + else{ + ez0-=(yp-cursely)*10; + } + cursely=yp; + } + else if(mode==9){ + if(curselx<=w/3){ + ex+=(yp-cursely); + } + else if(curselx<=w*2/3&&curselx>w/3){ + ey+=(yp-cursely); + } + else{ + ez+=(yp-cursely); + } + cursely=yp; + } + else if(mode==10){ + if(curselx<=w/3){ + if(ypw/3){ + if(yp7)render(); + draw(); + } + else if(modem==2){ + int shi=shad.getTouchIndex(yp); + if(shi!=0xffffff)shad.index=shi; + } + else if(modem==9){ + select.move(yp-ys); + ys=yp; + } + } + + protected void pointerReleased(int xp,int yp){ + if(modem==0){ + if(xp>=w-(Statics.bigImages?123:63)&&xp<=w-(Statics.bigImages?60:30)&&yp<=(Statics.bigImages?60:30)&&mattimer!=null){ + if(mattimer!=null){ + mattimer.cancel(); + } + mattimer=null; + Main.main.toColor(); Main.main.color.setColor(color);} + if(mode==0&&act==1){ + if(in==POLY)return; + act=0; + if (in == BOX){ + int vrx=(int)Math.sqrt((ver1.sx-xs)*(ver1.sx-xs)+(ver1.sy-ys)*(ver1.sy-ys))*10; + m.add( Create.box(new Vertex(ver1.x-vrx,ver1.y-vrx,ver1.z-vrx),new Vertex(ver1.x+vrx,ver1.y+vrx,ver1.z+vrx) , color),"box");} + else if (in == TORUS){ + m.add(Create.torus(ver1, Math.abs(ver1.sx-xs)*10,Math.abs(ver1.sy-ys)*10, 20, 10, color),"torus"); + } + else if (in == PYRAMIDE){ + m.add(Create.pyramid(ver1, new Vertex(ver1.x+Math.abs(ver1.sx-xs)*10,ver1.y,ver1.z+Math.abs(ver1.sx-xs)*10), (ver1.sy-ys)*10, color),"pyramid"); + } + else if (in == CYLINDER) m.add( Create.cylinder(ver1,Math.abs(ver1.sx-xs)*10, (ver1.sy-ys)*10, 30, color),"cylinder"); + else if (in == CONE) m.add( Create.cone(ver1, Math.abs(ver1.sx-xs)*10, (ver1.sy-ys)*10, 30, color),"cone"); + else if( in == SPHERE)m.add( Create.sphere(ver1, Math.sqrt((ver1.sx-xs)*(ver1.sx-xs)+(ver1.sy-ys)*(ver1.sy-ys))*10, 20, 20, color),"sphere"); + else if(in==DISK){ + m.add(Create.disk(ver1,Math.sqrt((ver1.sx-xs)*(ver1.sx-xs)+(ver1.sy-ys)*(ver1.sy-ys))*10, 30, color),"disk"); + } + else if(in==POLY){ + /*gr.draw(g, n,null); + g.setColor(color); + if(act==2){g.drawLine(ver1.sx, ver1.sy, cur.sx, cur.sy);} + if(act==3) g.fillTriangle(ver1.sx, ver1.sy, ver2.sx, ver2.sy, cur.sx, cur.sy); + */} + else if(in==PLANE){ + m.add(Create.plane(new Vertex(ver1.x-Math.abs(ver1.sx-xs)*10,ver1.y,ver1.z-Math.abs(ver1.sy-ys)*10), new Vertex(ver1.x+Math.abs(ver1.sx-xs)*10,ver1.y,ver1.z+Math.abs(ver1.sy-ys)*10), color),"plane"); + } + else if(in==OMNILIGHT){ + if(m.l==null){ + m.l=new Vector(); + } + m.l.addElement(new Light(ver1)); + sel=new Vector(); + sel.addElement(m.l.lastElement()); + } + if(in!=OMNILIGHT){ + m.getLast().countBoundary(); + centerX=m.getLast().ax; + centerY=m.getLast().ay; + centerZ=m.getLast().az; + sel=null; + System.gc(); + sel=new Vector(); + sel.addElement(m.getLast()); + } + ver1=null; + } + else if(mode==5){ + if(Edit.mo==0)sel=m.select(curselx,cursely,xs,ys,n); else if(Edit.mo==1)sel2=m.selectTr(curselx,cursely,xs,ys); else if(Edit.mo==2) sel3=m.selectVer(curselx,cursely,xs,ys); + showNotify(); + selact=false; + } + else if(mode==6){ + int vrx; + if(ver1!=null){vrx=(int)Math.sqrt((ver1.sx-xs)*(ver1.sx-xs)+(ver1.sy-ys)*(ver1.sy-ys))*10; + if(Edit.mo==0)sel=m.select3d(new int[]{ver1.x-vrx,ver1.y-vrx,ver1.z-vrx,ver1.x+vrx,ver1.y+vrx,ver1.z+vrx}, n); else if(Edit.mo==1)sel2=m.select3dTr(new int[]{ver1.x-vrx,ver1.y-vrx,ver1.z-vrx,ver1.x+vrx,ver1.y+vrx,ver1.z+vrx}); else if(Edit.mo==2)sel3=m.select3dVer(new int[]{ver1.x-vrx,ver1.y-vrx,ver1.z-vrx,ver1.x+vrx,ver1.y+vrx,ver1.z+vrx}); + } + showNotify(); + selact=false; + ver1=null; + } + render(); + draw(); + } + else if(modem==2){ + int shi=shad.getTouchIndex(yp); + if(shi==shad.index){ + if(shi<4)view=(short)shi; + else if(shi>4)shading=shi-5; + modem=0; + render(); + draw(); + shad=null; + } + } + else if(modem==9){ + if(act==0){ + if(xp==xs&&yp==ys){ + if(yp>=h-40&&xp<=w/4){ act=2; } + else{ + int shi=select.getTouchIndex(yp); + if(shi!=0xffffff){ + if(sel==null)sel=new Vector(); + Object addobj; + if(m.l!=null&&shi=h-select.sh&&act==1){ + act=0; sel=null; render(); draw(); + } + else if(yp>=h-select.sh*2&&act==2){ + sel=null; sel=new Vector(); + for(int i=0; i0){act=0; + if(!gr.f.isEmpty()){ + m.g.addElement(gr); + gr.countBoundary(); + sel=null; + System.gc(); + sel=new Vector(); + sel.addElement(gr); + centerX=gr.ax; + centerY=gr.ay; + centerZ=gr.az; + } + gr=null; + System.gc(); + } + else if(mode>=8&&act==1){modem=5;act=0;render();draw();} + else Main.main.toMenu(); + } + + //при нажатии на 5 или джой. + private void fire(){ + resetTimer(); + if(in==POLY){ + if(act==0){ + gr=new Group(null,"Object",m.g.size()); + act=2; + if(Statics.randColor)color=(new Random()).nextInt(0xffffff); + ver1=new Vertex(cur); + } + else if(act==1){ + act=2; + if(Statics.randColor)color=(new Random()).nextInt(0xffffff); + ver1=new Vertex(cur); + } + else if(act==2){ + act=3; + ver2=new Vertex(cur); + } + else if(act==3){ + act=1; + Triangle tr=new Triangle(new Vertex(ver1),new Vertex(ver2),new Vertex(cur),color); + tr.norm(); + tr.smooth=false; + tr.setMatrix(n); + if(tr.rnz>0){tr.nz*=-1;tr.nx*=-1;tr.ny*=-1;} + gr.add(tr); + } + return; + } + + act++; + if(act>1)act=0; + if (act == 1){ ver1 = new Vertex(cur); + if(Statics.randColor)color=(new Random()).nextInt(0xffffff); + } + if (act == 0 && in != OMNILIGHT) { + if (in == BOX){m.add(Create.box(ver1,cur, color),"box"); +// Group la=m.getLast(); +// la.countBoundary(); + } + else if (in == TORUS){ m.add(Create.torus(ver1, (int)Math.sqrt((cur.x - ver1.x) * (cur.x - ver1.x) + (cur.z - ver1.z) * (cur.z - ver1.z)), (int)Math.sqrt((cur.y-ver1.y)*(cur.y-ver1.y)), 20, 10, color),"torus"); +// m.getLast().countBoundary(); + } + else if (in == PYRAMIDE){ m.add(Create.pyramid(ver1, new Vertex(cur.x,ver1.y,cur.z), cur.y-ver1.y, color),"pyramid"); +// m.getLast().countBoundary(); + } + else if (in == CYLINDER){ m.add(Create.cylinder(ver1,Math.sqrt((cur.x-ver1.x)*(cur.x-ver1.x)+(cur.z-ver1.z)*(cur.z-ver1.z)), cur.y-ver1.y, 30, color),"cylinder");} + else if (in == CONE) m.add(Create.cone(ver1, Math.sqrt((cur.x-ver1.x)*(cur.x-ver1.x)+(cur.z-ver1.z)*(cur.z-ver1.z)), cur.y-ver1.y, 30, color),"cone"); + else if (in == SPHERE) m.add(Create.sphere(ver1, Math.sqrt((cur.x - ver1.x) * (cur.x - ver1.x) + (cur.z - ver1.z) * (cur.z - ver1.z)+(cur.y-ver1.y)*(cur.y-ver1.y)), 20, 20, color),"sphere"); + else if (in == DISK) m.add(Create.disk(ver1,Math.sqrt((cur.x-ver1.x)*(cur.x-ver1.x)+(cur.z-ver1.z)*(cur.z-ver1.z)), 30, color),"disk"); + else if (in == PLANE) m.add(Create.plane(ver1, cur, color),"plane"); + m.getLast().countBoundary(); + centerX=m.getLast().ax; + centerY=m.getLast().ay; + centerZ=m.getLast().az; + sel=null; + System.gc(); + sel=new Vector(); + sel.addElement(m.getLast()); +// cur.y = 0; + } + if(in==OMNILIGHT){ + if(m.l==null){ + m.l=new Vector(); + } + m.l.addElement(new Light(cur)); + act=0; + sel=new Vector(); + sel.addElement(m.l.lastElement()); + System.gc(); + } + + } + +} \ No newline at end of file diff --git a/src/Face.java b/src/Face.java new file mode 100644 index 0000000..d5eaee7 --- /dev/null +++ b/src/Face.java @@ -0,0 +1,1493 @@ +// класс для полигонов, обобщает треугольники и линии (которые в итоге не были добавлены и остались только системными, но все легко исправимо) +// также здесь расположены все методы отрисовки треугольников со всеми предустановками +import javax.microedition.lcdui.Graphics; + +public class Face +{ + public int color; + + public int getS() // получить среднюю координату по Z (для сортировки) + { + return 0; } + public Vertex getCenter() { return null; } + public void paint(Graphics g,int v) { } + + public void paint(int[] rgb) { } + + public void paint(Graphics g, int col,int v) { } + public void move(int a, int b, int c) { } + + public void setVertexMatrix(Matrix3D m) { } + + public void setMatrix(Matrix3D m) { } + + public void light(java.util.Vector l){ + + } + + public boolean picking(int x,int y){ + return false; + } + + public void soequal() { } + + public void render(int[] r,int[] z){ + + } + public boolean isVisible(int v){ + return false; + } + + public void renderTriangle(int[] rgb,int asx,int asy,int bsx,int bsy,int csx,int csy,int col) { + + //---------------------------- + //| A | + //| **** | + //| ******* | + //| ********** | + //| B************ | + //| *********** | + //| ********* | + //|------@@@@@@-------| + //| ***** | + //| *** | + //| C | + //---------------------------- + //if(alpha==0)return; + //сортируем вершины, чтобы они были по порядку + if(bsy < asy) { //если b выше чем a + int tx=asx,ty=asy; + asx=bsx; + asy=bsy; + bsx=tx; + bsy=ty; + } + if(csy < asy) { //если c выше чем a + int tx=csx,ty=csy; + csx=asx; + csy=asy; + asx=tx; + asy=ty; + } + if (bsy > csy) { //если b ниже чем c + int tx=bsx,ty=bsy; + bsx=csx; + bsy=csy; + csx=tx; + csy=ty; + } + if(asy == csy) return; + final int fp = 16; + + + int x1=0, x2=0, tempI=0; + int dx_start = 0, dx_end = 0; //приращения для треугольника + // int zac=0,zab=0,zxstart=a.zc<>fp); //начало линии + int x_end = bsx; //конец линии + if(x_start == x_end) return; + + + + + + x_start = x_end = asx< Statics.h) y_end = Statics.h; + + + for(;y_start x_end) { //если надо меняем начало и конец отрезка + x1 = x_end>>fp; + x2 = x_start>>fp; + // z1=zxend; + // z2=zxstart; + } else { + x1 = x_start>>fp; + x2 = x_end>>fp; + // z1=zxstart; + // z2=zxend; + } + + + // if(x2!=x1) + //zxx=(z2-z1)/(x2-x1); + // else zxx=0; + + + if(x1 < 0){ x1 = 0;/*z1+=x2-x1==0?0:zxx*(x2-x1);*/} + if(x2 > Statics.w) x2 = Statics.w; + + + tempI = Statics.w * y_start; + x1 += tempI; //от куда рисовать в массиве + x2 += tempI; //до куда рисовать в массив + while(x1(-Vertex.dist+1)<>16&0xff,gc=col>>8&0xff,bc=col&0xff,rd=rgb[x1]>>16&0xff,gd=rgb[x1]>>8&0xff,bd=rgb[x1]&0xff; + rgb[x1] = (alphacolor(rc,rd,alpha)<<16)|(alphacolor(gc,gd,alpha)<<8)|(alphacolor(bc,bd,alpha)); + + }*/ +//z[x1]=z1;} +x1++; +//z1+=zxx; + } + + x_start += dx_start;//находим начало и конец отрезка + x_end += dx_end; + // zxstart+=zac; + // zxend+=zab; + } + + } + + public void renderFlatTriangle(int[] rgb,int[] z,Vertex a, Vertex b, Vertex c,int col) { + + //---------------------------- + //| A | + //| **** | + //| ******* | + //| ********** | + //| B************ | + //| *********** | + //| ********* | + //|------@@@@@@-------| + //| ***** | + //| *** | + //| C | + //---------------------------- + //if(alpha==0)return; + //сортируем вершины, чтобы они были по порядку + if(b.sy < a.sy) { //если b выше чем a + Vertex t = a; + a = b; + b = t; + } + if(c.sy < a.sy) { //если c выше чем a + Vertex t = c; + c = a; + a = t; + } + if (b.sy > c.sy) { //если b ниже чем c + Vertex t = b; + b = c; + c = t; + } + if(a.sy == c.sy) return; + final int fp = 16; + + + int x1=0, x2=0, tempI=0; + int dx_start = 0, dx_end = 0; //приращения для треугольника + int zac=0,zab=0,zxstart=(a.zc+Vertex.dist)<>fp); //начало линии + int x_end = b.sx; //конец линии + if(x_start == x_end) return; + + + + + + x_start = x_end = a.sx< Statics.h) y_end = Statics.h; + + + for(;y_start x_end) { //если надо меняем начало и конец отрезка + x1 = x_end>>fp; + x2 = x_start>>fp; + z1=zxend; + z2=zxstart; + } else { + x1 = x_start>>fp; + x2 = x_end>>fp; + z1=zxstart; + z2=zxend; + } + + + if(x2!=x1) + zxx=(z2-z1)/(x2-x1); + else zxx=0; + + + if(x1 < 0){ x1 = 0;/*z1+=x2-x1==0?0:zxx*(x2-x1);*/} + if(x2 > Statics.w) x2 = Statics.w; + + + tempI = Statics.w * y_start; + x1 += tempI; //от куда рисовать в массиве + x2 += tempI; //до куда рисовать в массив + while(x1(-Vertex.dist+1)<>16&0xff,gc=col>>8&0xff,bc=col&0xff,rd=rgb[x1]>>16&0xff,gd=rgb[x1]>>8&0xff,bd=rgb[x1]&0xff; + rgb[x1] = (alphacolor(rc,rd,alpha)<<16)|(alphacolor(gc,gd,alpha)<<8)|(alphacolor(bc,bd,alpha)); + + }*/ +z[x1]=z1;} +x1++; +z1+=zxx; + } + + x_start += dx_start;//находим начало и конец отрезка + x_end += dx_end; + zxstart+=zac; + zxend+=zab; + } + + } + + public void renderFlatTriangle(int[] rgb,int[] z,Vertex a, Vertex b, Vertex c,int col,int alpha) { + + //---------------------------- + //| A | + //| **** | + //| ******* | + //| ********** | + //| B************ | + //| *********** | + //| ********* | + //|------@@@@@@-------| + //| ***** | + //| *** | + //| C | + //---------------------------- + //if(alpha==0)return; + //сортируем вершины, чтобы они были по порядку + if(b.sy < a.sy) { //если b выше чем a + Vertex t = a; + a = b; + b = t; + } + if(c.sy < a.sy) { //если c выше чем a + Vertex t = c; + c = a; + a = t; + } + if (b.sy > c.sy) { //если b ниже чем c + Vertex t = b; + b = c; + c = t; + } + if(a.sy == c.sy) return; + final int fp = 16; + + + int x1=0, x2=0, tempI=0; + int dx_start = 0, dx_end = 0; //приращения для треугольника + int zac=0,zab=0,zxstart=(a.zc+Vertex.dist)<>fp); //начало линии + int x_end = b.sx; //конец линии + if(x_start == x_end) return; + + + + + + x_start = x_end = a.sx< Statics.h) y_end = Statics.h; + + + for(;y_start x_end) { //если надо меняем начало и конец отрезка + x1 = x_end>>fp; + x2 = x_start>>fp; + z1=zxend; + z2=zxstart; + } else { + x1 = x_start>>fp; + x2 = x_end>>fp; + z1=zxstart; + z2=zxend; + } + + + if(x2!=x1) + zxx=(z2-z1)/(x2-x1); + else zxx=0; + + + if(x1 < 0){ x1 = 0;/*z1+=x2-x1==0?0:zxx*(x2-x1);*/} + if(x2 > Statics.w) x2 = Statics.w; + + + tempI = Statics.w * y_start; + x1 += tempI; //от куда рисовать в массиве + x2 += tempI; //до куда рисовать в массив + while(x1(-Vertex.dist+1)<>16&0xff,gc=col>>8&0xff,bc=col&0xff,rd=rgb[x1]>>16&0xff,gd=rgb[x1]>>8&0xff,bd=rgb[x1]&0xff; + rgb[x1] = (alphacolor(rc,rd,alpha)<<16)|(alphacolor(gc,gd,alpha)<<8)|(alphacolor(bc,bd,alpha)); + + } +z[x1]=z1;} +x1++; +z1+=zxx; + } + + x_start += dx_start;//находим начало и конец отрезка + x_end += dx_end; + zxstart+=zac; + zxend+=zab; + } + + } + + public void renderTriangle(int[] rgb,int[] z,Vertex a, Vertex b, Vertex c,int col) { + + //---------------------------- + //| A | + //| **** | + //| ******* | + //| ********** | + //| B************ | + //| *********** | + //| ********* | + //|---------@@@@@@-----------| + //| ***** | + //| *** | + //| C | + //---------------------------- + //if(alpha==0)return; + //сортируем вершины, чтобы они были по порядку + if(b.sy < a.sy) { //если b выше чем a + Vertex t = a; + a = b; + b = t; + } + if(c.sy < a.sy) { //если c выше чем a + Vertex t = c; + c = a; + a = t; + } + if (b.sy > c.sy) { //если b ниже чем c + Vertex t = b; + b = c; + c = t; + } + if(a.sy == c.sy) return; + final int fp = 16; + + + int x1=0, x2=0, tempI=0; + int dx_start = 0, dx_end = 0; //приращения для треугльника + int zac=0,zab=0,zxstart=(a.zc+Vertex.dist)<> 16 & 0xFF; int gc = col >> 8 & 0xFF; int bc = col & 0xFF,rcc,gcc,bcc; + int kac=0,kab=0,kxstart=a.k,kxend=a.k,kxx,k1,k2; + + if(c.sy!=a.sy){ + tempI = c.sy - a.sy; + dx_start = (c.sx - a.sx)<>fp); //начало линии + int x_end = b.sx; //конец линии + if(x_start == x_end) return; + + + + + + x_start = x_end = a.sx< Statics.h) y_end = Statics.h; + + + for(;y_start x_end) { //если надо меняем начало и конец отрезка + x1 = x_end>>fp; + x2 = x_start>>fp; + z1=zxend; + z2=zxstart; + k1=kxend; + k2=kxstart; + } else { + x1 = x_start>>fp; + x2 = x_end>>fp; + z1=zxstart; + z2=zxend; + k1=kxstart; + k2=kxend; + } + + + if(x2!=x1){ + zxx=(z2-z1)/(x2-x1); + kxx=(k2-k1)/(x2-x1); + } + else{ + zxx=0; + kxx=0; + } + + + if(x1 < 0){ x1 = 0;/*z1+=x2-x1==0?0:zxx*(x2-x1);*/} + if(x2 > Statics.w) x2 = Statics.w; + + + tempI = Statics.w * y_start; + x1 += tempI; //от куда рисовать в массиве + x2 += tempI; //до куда рисовать в массив + while(x1(-Vertex.dist+1)<>fp))/100; + rcc = (int)(rc * kk1); + if(rcc<0)rcc=0; + if(rcc>255)rcc=255; + gcc = (int)(gc * kk1); + if(gcc<0)gcc=0; + if(gcc>255)gcc=255; + bcc = (int)(bc * kk1); + if(bcc<0)bcc=0; + if(bcc>255)bcc=255; + rgb[x1]=rcc << 16 | gcc << 8 | bcc; +/*else{ + int rc=col>>16&0xff,gc=col>>8&0xff,bc=col&0xff,rd=rgb[x1]>>16&0xff,gd=rgb[x1]>>8&0xff,bd=rgb[x1]&0xff; + rgb[x1] = (alphacolor(rc,rd,alpha)<<16)|(alphacolor(gc,gd,alpha)<<8)|(alphacolor(bc,bd,alpha)); + + }*/ +z[x1]=z1;} +k1+=kxx; +x1++; +z1+=zxx; + } + + x_start += dx_start;//находим начало и конец отрезка + x_end += dx_end; + zxstart+=zac; + zxend+=zab; + kxstart+=kac; + kxend+=kab; + } + + } + + public void renderTriangle(int[] rgb,int[] z,Vertex a, Vertex b, Vertex c,Material mat) { + + //---------------------------- + //| A | + //| **** | + //| ******* | + //| ********** | + //| B************ | + //| *********** | + //| ********* | + //|---------@@@@@@-----------| + //| ***** | + //| *** | + //| C | + //---------------------------- + //if(alpha==0)return; + //сортируем вершины, чтобы они были по порядку + if(b.sy < a.sy) { //если b выше чем a + Vertex t = a; + a = b; + b = t; + } + if(c.sy < a.sy) { //если c выше чем a + Vertex t = c; + c = a; + a = t; + } + if (b.sy > c.sy) { //если b ниже чем c + Vertex t = b; + b = c; + c = t; + } + if(a.sy == c.sy) return; + final int fp = 16; + + + int x1=0, x2=0, tempI=0; + int dx_start = 0, dx_end = 0; //приращения для треугльника + int zac=0,zab=0,zxstart=(a.zc+Vertex.dist)<> 16 & 0xFF; int gc = mat.diffuseColor >> 8 & 0xFF; int bc = mat.diffuseColor & 0xFF,rcc,gcc,bcc; + int kac=0,kab=0,kxstart=a.k,kxend=a.k,kxx,k1,k2; + + if(c.sy!=a.sy){ + tempI = c.sy - a.sy; + dx_start = (c.sx - a.sx)<>fp); //начало линии + int x_end = b.sx; //конец линии + if(x_start == x_end) return; + + + + + + x_start = x_end = a.sx< Statics.h) y_end = Statics.h; + + + for(;y_start x_end) { //если надо меняем начало и конец отрезка + x1 = x_end>>fp; + x2 = x_start>>fp; + z1=zxend; + z2=zxstart; + k1=kxend; + k2=kxstart; + } else { + x1 = x_start>>fp; + x2 = x_end>>fp; + z1=zxstart; + z2=zxend; + k1=kxstart; + k2=kxend; + } + + + if(x2!=x1){ + zxx=(z2-z1)/(x2-x1); + kxx=(k2-k1)/(x2-x1); + } + else{ + zxx=0; + kxx=0; + } + + + if(x1 < 0){ x1 = 0;/*z1+=x2-x1==0?0:zxx*(x2-x1);*/} + if(x2 > Statics.w) x2 = Statics.w; + + + tempI = Statics.w * y_start; + x1 += tempI; //от куда рисовать в массиве + x2 += tempI; //до куда рисовать в массив + while(x1(-Vertex.dist+1)<>fp))/100; + rcc = (int)(rc * kk1+rc*mat.self); + if(rcc<0)rcc=0; + if(rcc>rc)rcc=rc; + gcc = (int)(gc * kk1+gc*mat.self); + if(gcc<0)gcc=0; + if(gcc>gc)gcc=gc; + bcc = (int)(bc * kk1+bc*mat.self); + if(bcc<0)bcc=0; + if(bcc>bc)bcc=bc; +if(mat.opacity==255) + rgb[x1]=rcc << 16 | gcc << 8 | bcc; +else{ + int rd=rgb[x1]>>16&0xff,gd=rgb[x1]>>8&0xff,bd=rgb[x1]&0xff; + rgb[x1] = (alphacolor(rcc,rd,mat.opacity)<<16)|(alphacolor(gcc,gd,mat.opacity)<<8)|(alphacolor(bcc,bd,mat.opacity)); + + } +z[x1]=z1;} +k1+=kxx; +x1++; +z1+=zxx; + } + + x_start += dx_start;//находим начало и конец отрезка + x_end += dx_end; + zxstart+=zac; + zxend+=zab; + kxstart+=kac; + kxend+=kab; + } + + } + + public void renderLine(int[] rgb,int[] z,Vertex a,Vertex b,int col){ +if(a.sy>b.sy){ +Vertex tmp=a; +a=b; +b=tmp; +} +if(a.sx==b.sx){ + int zs=a.zc<<16,ze=b.zc<<16,zx,xx,yst=a.sy,yend=b.sy; + if(a.sy!=b.sy&&a.zc!=b.zc)zx=((b.zc-a.zc)<<16)/(b.sy-a.sy); else zx=0; + if(yst<0){ + zs+=zx*(-yst); + yst=0; + } + if(yend>Statics.h)yend=Statics.h-1; + for(int y=yst;y<=yend;y++){ + xx=y*Statics.w+a.sx; + if(y>0&&a.sx>0&&y(-Vertex.dist+1)<<16) + { + rgb[xx]=col; + z[xx]=zs; + } + zs+=zx; + } +} +else if(a.sy==b.sy){ + int x,xe,zs=a.zc<<16,ze=b.zc<<16,zx,xx,xst; + + if(a.sx=Statics.w){ + xe=Statics.w-1; + } + for(int i=x;i<=xe;i++){ + xx=a.sy*Statics.w+i; + if(a.sy>0&&i>0&&a.sy(-Vertex.dist+1)<<16){ + rgb[xx]=col; + z[xx]=zs; + } + zs+=zx; + } +} +else{ +int ax=(b.sx-a.sx)<<16,ay=(b.sy-a.sy)<<16; +int zs=a.zc<<16,ze=b.zc<<16,zx,xx,yst=a.sy,yend=b.sy,xend; +double length=Math.sqrt(ax*ax+ay*ay); +ax/=length; + zx=((b.zc-a.zc)<<16); + zx/=b.sy-a.sy; +int x=a.sx<<16; +/*if(yst<0){ + zs+=zx*(-yst); + x+=ax*(-yst); + yst=0; +} +if(yend>Statics.h)yend=(Statics.h-1); +if(x<0){ + zs+=zx*(-x); + yst+=ay*(-x); + x=0; +}*/ +for(int y=yst;y<=yend;y+=1){ + xx=y*Statics.w+(x>>16); + if(y>=0&&x>=0&&y>16)(-Vertex.dist+1)<<16){ + rgb[xx]=col; + z[xx]=zs; + } +x+=ax; +//if(x>=Statics.w)break; +zs+=zx; +} +} +} + + public void drawLine(int[] rgb, int[] z, Vertex v, Vertex v2,int col) { + int xerr, yerr, dx, dy, d, incx = 0, incy = 0, xx, yy; + xerr = 0; + yerr = 0; + int fp = 16; + int ffp = 1 << fp; + dx = (v2.sx - v.sx) << fp; + dy = (v2.sy - v.sy) << fp; + if (dx > 0) { + incx = ffp; + } + if (dx == 0) { + incx = 0; + } + if (dx < 0) { + incx = -ffp; + } + if (dy > 0) { + incy = ffp; + } + if (dy == 0) { + incy = 0; + } + if (dy < 0) { + incy = -ffp; + } + dx = Math.abs(dx); + dy = Math.abs(dy); + d = Math.max(dx, dy); + xx = v.sx << fp; + yy = v.sy << fp; + int yyy = 0; + int xxx = 0; + for (int i = 0; i < d; i += ffp) { + yyy = yy >> fp; + xxx = xx >> fp; + if (yyy < 0 || xxx < 0) { + xerr += dx; + yerr += dy; + if (xerr >= d) { + xerr -= d; + xx += incx; + } + if (yerr >= d) { + yerr -= d; + yy += incy; + } + continue; + } + if (!(yyy > Statics.h-1 || xxx > Statics.w - 1)) + rgb[(yy >> fp) * Statics.w + (xx >> fp)] = col; + + + xerr += dx; + yerr += dy; + if (xerr >= d) { + xerr -= d; + xx += incx; + } + if (yerr >= d) { + yerr -= d; + yy += incy; + } + + } + } + + public void drawLine(int[] rgb, int vsx,int vsy,int v2sx,int v2sy,int col) { + int xerr, yerr, dx, dy, d, incx = 0, incy = 0, xx, yy; + xerr = 0; + yerr = 0; + int fp = 16; + int ffp = 1 << fp; + dx = (v2sx - vsx) << fp; + dy = (v2sy - vsy) << fp; + if (dx > 0) { + incx = ffp; + } + if (dx == 0) { + incx = 0; + } + if (dx < 0) { + incx = -ffp; + } + if (dy > 0) { + incy = ffp; + } + if (dy == 0) { + incy = 0; + } + if (dy < 0) { + incy = -ffp; + } + dx = Math.abs(dx); + dy = Math.abs(dy); + d = Math.max(dx, dy); + xx = vsx << fp; + yy = vsy << fp; + int yyy = 0; + int xxx = 0; + for (int i = 0; i < d; i += ffp) { + yyy = yy >> fp; + xxx = xx >> fp; + if (yyy < 0 || xxx < 0) { + xerr += dx; + yerr += dy; + if (xerr >= d) { + xerr -= d; + xx += incx; + } + if (yerr >= d) { + yerr -= d; + yy += incy; + } + continue; + } + if (!(yyy > Statics.h-1 || xxx > Statics.w - 1)) + rgb[(yy >> fp) * Statics.w + (xx >> fp)] = col; + + + xerr += dx; + yerr += dy; + if (xerr >= d) { + xerr -= d; + xx += incx; + } + if (yerr >= d) { + yerr -= d; + yy += incy; + } + + } + } + + public void renderAffineTexturedTriangle(Material m,int[] rgb,int[] zb,Vertex a,Vertex b,Vertex c,float k){ + renderAffineTexturedTriangle(m,rgb,zb,new float[]{a.u,a.v,b.u,b.v,c.u,c.v},a,b,c,k); + } + + public static boolean SUBPIXEL=true,SUBTEXEL=true; +public void renderAffineTexturedTriangle(Material mat,int[] rgb,int[] zb,float[] uv,Vertex a, Vertex b, Vertex c,float lk) { + int[] tex=mat.texture; + int iw=mat.w,ih=mat.h; + int au=(int)(uv[0]*(iw-1)),av=(int)(uv[1]*(ih-1)),bu=(int)(uv[2]*(iw-1)),bv=(int)(uv[3]*(ih-1)),cu=(int)(uv[4]*(iw-1)),cv=(int)(uv[5]*(ih-1)); + if (a.sy > b.sy) { + Vertex tmp_vertex = a; + a = b; + b = tmp_vertex; + int itm=au; + au=bu; + bu=itm; + itm=av; + av=bv; + bv=itm; + } + if (a.sy > c.sy) { + Vertex tmp_vertex = a; + a = c; + c = tmp_vertex; + int itm=au; + au=cu; + cu=itm; + itm=av; + av=cv; + cv=itm; + } + if (b.sy > c.sy) { + Vertex tmp_vertex = b; + b = c; + c = tmp_vertex; + int itm=bu; + bu=cu; + cu=itm; + itm=bv; + bv=cv; + cv=itm; + } + float asx=a.sx,bsx=b.sx,csx=c.sx,asy=a.sy,bsy=b.sy,csy=c.sy; + float az1,bz1,cz1; + if (!(Math.floor(csy) <= Math.ceil(asy))) { + /*a.cc = (255f * (a.rnz >= 0 ? 0f : -a.rnz)); + b.cc = (255f * (b.rnz >= 0 ? 0f : -b.rnz)); + c.cc = (255f * (c.rnz >= 0 ? 0f : -c.rnz));*/ + az1 = 1f / (a.zc+Vertex.dist/* + 20f*/); + bz1 = 1f / (b.zc+Vertex.dist/* + 20f*/); + cz1 = 1f / (c.zc+Vertex.dist/* + 20f*/); + float k = (bsy - asy) / (csy - asy); + float x_start = asx + (csx - asx) * k; + float u_start = au + (cu - au) * k; + float v_start = av + (cv - av) * k; +// float c_start = a.cc + (c.cc - a.cc) * k; + float z1_start = az1 + (cz1 - az1) * k; + float x_end = bsx; + float u_end = bu; + float v_end = bv; +// float c_end = b.cc; + float z1_end = bz1; + float du = (u_start - u_end) / (x_start - x_end); + float dv = (v_start - v_end) / (x_start - x_end); +// float dc = (c_start - c_end) / (x_start - x_end); + float dz1 = (z1_start - z1_end) / (x_start - x_end); + x_start = asx; + u_start = au; + v_start = av; +// c_start = a.cc; + z1_start = az1; + float dx_start = (csx - asx) / (csy - asy); + float du_start = (cu - au) / (csy - asy); + float dv_start = (cv - av) / (csy - asy); +// float dc_start = (c.cc - a.cc) / (csy - asy); + float dz1_start = (cz1 - az1) / (csy - asy); + float tmp; + if (SUBPIXEL) { + tmp = (float) (Math.ceil(asy) - asy); + x_start += dx_start * tmp; + u_start += du_start * tmp; + v_start += dv_start * tmp; + z1_start += dz1_start * tmp; + } + float dx_end=0f; + float dz1_end=0f; + float du_end=0f; + float dv_end=0f; + // float dc_end=0f; + if (Math.ceil(bsy) > Math.ceil(asy)) { + tmp = (float) (Math.ceil(asy) - asy); + x_end = asx; + u_end = au; + v_end = av; +// c_end = a.cc; + z1_end = az1; + dx_end = (bsx - asx) / (bsy - asy); + du_end = (bu - au) / (bsy - asy); +// dc_end = (b.cc - a.cc) / (bsy - asy); + dv_end = (bv - av) / (bsy - asy); + dz1_end = (bz1 - az1) / (bsy - asy); + } else { + tmp = (float) (Math.ceil(bsy) - bsy); + x_end = bsx; + u_end = bu; + v_end = bv; +// c_end = b.cc; + z1_end = bz1; + dx_end = (csx - bsx) / (csy - bsy); + du_end = (cu - bu) / (csy - bsy); + dv_end = (cv - bv) / (csy - bsy); +// dc_end = (c.cc - b.cc) / (csy - bsy); + dz1_end = (cz1 - bz1) / (csy - bsy); + } + if (SUBPIXEL) { + x_end += dx_end * tmp; + u_end += du_end * tmp; + v_end += dv_end * tmp; + z1_end += dz1_end * tmp; + } + for (int current_ty = (int) Math.ceil(asy); (float) current_ty < Math.ceil(csy); current_ty++) { + if ((float) current_ty == Math.ceil(bsy)) { + x_end = bsx; + u_end = bu; + v_end = bv; +// c_end = b.cc; + z1_end = bz1; + dx_end = (csx - bsx) / (csy - bsy); + du_end = (cu - bu) / (csy - bsy); + dv_end = (cv - bv) / (csy - bsy); +// dc_end = (c.cc - b.cc) / (csy - bsy); + dz1_end = (cz1 - bz1) / (csy - bsy); + if (SUBPIXEL) { + tmp = (float) (Math.ceil(bsy) - bsy); + x_end += dx_end * tmp; + u_end += du_end * tmp; + v_end += dv_end * tmp; + z1_end += dz1_end * tmp; + } + } + int length=0; + float x=0f; + float u=0f; + float v=0f; + float z1=0f; + // float cc=0f; + if (x_start > x_end) { + x = x_end; + u = u_end; + v = v_end; + // cc = c_end; + z1 = z1_end; + length = (int) (Math.ceil(x_start) - Math.ceil(x_end)); + } else { + x = x_start; + u = u_start; + v = v_start; +// cc = c_start; + z1 = z1_start; + length = (int) (Math.ceil(x_end) - Math.ceil(x_start)); + } + int current_tx = (int) Math.ceil(x); + if (length > 0) { + if (SUBTEXEL) { + tmp = (float) (Math.ceil(x) - x); + u += du * tmp; + v += dv * tmp; + } + while (length-- > 0) { + if (current_ty < Statics.h && current_tx < Statics.w && current_tx>=0 && current_ty>=0) { + try { + int col=tex[((int) (v*(mat.vs>=0?mat.vs:-mat.vs)+(mat.vo>=0?mat.vo:-Math.floor(mat.vo)+mat.vo)*100)%ih) * iw + ((int)(u*(mat.us>=0?mat.us:-mat.us)+(mat.uo>0?mat.uo:-Math.floor(mat.uo)+mat.uo)*100)%iw)]; + if((((int)(1/z1))<<16)=0xffffff?((col>>24)&0xff)==0xff:true)){ + int rrc = col >> 16 & 0xFF; int rgc = col >> 8 & 0xFF; int rbc = col & 0xFF; + int rc = (int)(rrc * lk+mat.self*rrc); + if(rc>rrc)rc=rrc; + if(rc<0)rc=0; + int gc = (int)(rgc * lk+mat.self*rgc); + if(gc>rgc)gc=rgc; + if(gc<0)gc=0; + int bc = (int)(rbc * lk+mat.self*rbc); + if(bc>rbc)bc=rbc; + if(bc<0)bc=0; + if(mat.opacity==255){ + rgb[current_ty*Statics.w+current_tx]=rc << 16 | gc << 8 | bc; + } + else{ + int rd=rgb[current_ty*Statics.w+current_tx]>>16&0xff,gd=rgb[current_ty*Statics.w+current_tx]>>8&0xff,bd=rgb[current_ty*Statics.w+current_tx]&0xff; + rgb[current_ty*Statics.w+current_tx] = (alphacolor(rc,rd,mat.opacity)<<16)|(alphacolor(gc,gd,mat.opacity)<<8)|(alphacolor(bc,bd,mat.opacity)); + + } + zb[current_ty*Statics.w+current_tx]=((int)(1/z1))<<16; + } + } catch (Exception ex) { + } + } + u += du; + v += dv; +// cc += dc; + z1 += dz1; + current_tx++; + } + } + x_start += dx_start; + u_start += du_start; + v_start += dv_start; +// c_start += dc_start; + z1_start += dz1_start; + x_end += dx_end; + u_end += du_end; + v_end += dv_end; +// c_end += dc_end; + z1_end += dz1_end; + } + } + } + +public void renderAffineTexturedTriangle(Material m,int[] rgb,int[] zb,Vertex a,Vertex b,Vertex c){ + renderAffineTexturedTriangle(m,rgb,zb,new float[]{a.u,a.v,b.u,b.v,c.u,c.v},a,b,c); + } + +public void renderAffineTexturedTriangle(Material mat,int[] rgb,int[] zb,float[] uv,Vertex a, Vertex b, Vertex c) { + int[] tex=mat.texture; + int iw=mat.w,ih=mat.h; + int au=(int)(uv[0]*(iw-1)),av=(int)(uv[1]*(ih-1)),bu=(int)(uv[2]*(iw-1)),bv=(int)(uv[3]*(ih-1)),cu=(int)(uv[4]*(iw-1)),cv=(int)(uv[5]*(ih-1)); + if (a.sy > b.sy) { + Vertex tmp_vertex = a; + a = b; + b = tmp_vertex; + int itm=au; + au=bu; + bu=itm; + itm=av; + av=bv; + bv=itm; + } + if (a.sy > c.sy) { + Vertex tmp_vertex = a; + a = c; + c = tmp_vertex; + int itm=au; + au=cu; + cu=itm; + itm=av; + av=cv; + cv=itm; + } + if (b.sy > c.sy) { + Vertex tmp_vertex = b; + b = c; + c = tmp_vertex; + int itm=bu; + bu=cu; + cu=itm; + itm=bv; + bv=cv; + cv=itm; + } + float asx=a.sx,bsx=b.sx,csx=c.sx,asy=a.sy,bsy=b.sy,csy=c.sy; + float az1,bz1,cz1,acc,bcc,ccc; + if (!(Math.floor(csy) <= Math.ceil(asy))) { + if(mat.doubleSided){ + acc=Math.abs((float)(a.k>>16)/100f); + bcc=Math.abs((float)(b.k>>16)/100f); + ccc=Math.abs((float)(c.k>>16)/100f); + } + else{ + acc = /*(255f * */(a.k <= 0 ? 0f : (float)(a.k>>16)/100f); + bcc = /*(255f * */(b.k <= 0 ? 0f : (float)(b.k>>16)/100f); + ccc = /*(255f * */(c.k <= 0 ? 0f : (float)(c.k>>16)/100f); + } + az1 = 1f / (a.zc + Vertex.dist); + bz1 = 1f / (b.zc + Vertex.dist); + cz1 = 1f / (c.zc + Vertex.dist); + float k = (bsy - asy) / (csy - asy); + float x_start = asx + (csx - asx) * k; + float u_start = au + (cu - au) * k; + float v_start = av + (cv - av) * k; + float c_start = acc + (ccc - acc) * k; + float z1_start = az1 + (cz1 - az1) * k; + float x_end = bsx; + float u_end = bu; + float v_end = bv; + float c_end = bcc; + float z1_end = bz1; + float du = (u_start - u_end) / (x_start - x_end); + float dv = (v_start - v_end) / (x_start - x_end); + float dc = (c_start - c_end) / (x_start - x_end); + float dz1 = (z1_start - z1_end) / (x_start - x_end); + x_start = asx; + u_start = au; + v_start = av; + c_start = acc; + z1_start = az1; + float dx_start = (csx - asx) / (csy - asy); + float du_start = (cu - au) / (csy - asy); + float dv_start = (cv - av) / (csy - asy); + float dc_start = (ccc - acc) / (csy - asy); + float dz1_start = (cz1 - az1) / (csy - asy); + float tmp; + if (SUBPIXEL) { + tmp = (float) (Math.ceil(asy) - asy); + x_start += dx_start * tmp; + u_start += du_start * tmp; + v_start += dv_start * tmp; + z1_start += dz1_start * tmp; + } + float dx_end=0f; + float dz1_end=0f; + float du_end=0f; + float dv_end=0f; + float dc_end=0f; + if (Math.ceil(bsy) > Math.ceil(asy)) { + tmp = (float) (Math.ceil(asy) - asy); + x_end = asx; + u_end = au; + v_end = av; + c_end = acc; + z1_end = az1; + dx_end = (bsx - asx) / (bsy - asy); + du_end = (bu - au) / (bsy - asy); + dc_end = (bcc - acc) / (bsy - asy); + dv_end = (bv - av) / (bsy - asy); + dz1_end = (bz1 - az1) / (bsy - asy); + } else { + tmp = (float) (Math.ceil(bsy) - bsy); + x_end = bsx; + u_end = bu; + v_end = bv; + c_end = bcc; + z1_end = bz1; + dx_end = (csx - bsx) / (csy - bsy); + du_end = (cu - bu) / (csy - bsy); + dv_end = (cv - bv) / (csy - bsy); + dc_end = (ccc - bcc) / (csy - bsy); + dz1_end = (cz1 - bz1) / (csy - bsy); + } + if (SUBPIXEL) { + x_end += dx_end * tmp; + u_end += du_end * tmp; + v_end += dv_end * tmp; + z1_end += dz1_end * tmp; + } + for (int current_ty = (int) Math.ceil(asy); (float) current_ty < Math.ceil(csy); current_ty++) { + if ((float) current_ty == Math.ceil(bsy)) { + x_end = bsx; + u_end = bu; + v_end = bv; + c_end = bcc; + z1_end = bz1; + dx_end = (csx - bsx) / (csy - bsy); + du_end = (cu - bu) / (csy - bsy); + dv_end = (cv - bv) / (csy - bsy); + dc_end = (ccc - bcc) / (csy - bsy); + dz1_end = (cz1 - bz1) / (csy - bsy); + if (SUBPIXEL) { + tmp = (float) (Math.ceil(bsy) - bsy); + x_end += dx_end * tmp; + u_end += du_end * tmp; + v_end += dv_end * tmp; + z1_end += dz1_end * tmp; + } + } + int length=0; + float x=0f; + float u=0f; + float v=0f; + float z1=0f; + float cc=0f; + if (x_start > x_end) { + x = x_end; + u = u_end; + v = v_end; + cc = c_end; + z1 = z1_end; + length = (int) (Math.ceil(x_start) - Math.ceil(x_end)); + } else { + x = x_start; + u = u_start; + v = v_start; + cc = c_start; + z1 = z1_start; + length = (int) (Math.ceil(x_end) - Math.ceil(x_start)); + } + int current_tx = (int) Math.ceil(x); + if (length > 0) { + if (SUBTEXEL) { + tmp = (float) (Math.ceil(x) - x); + u += du * tmp; + v += dv * tmp; + } + while (length-- > 0) { + if (current_ty < Statics.h && current_tx < Statics.w && current_tx>=0 && current_ty>=0) { + try { + int col=tex[((int)(v*(mat.vs>=0?mat.vs:-mat.vs)+(mat.vo>=0?mat.vo:-Math.floor(mat.vo)+mat.vo)*100)%ih) * iw + ((int)(u*(mat.us>=0?mat.us:-mat.us)+(mat.uo>0?mat.uo:-Math.floor(mat.uo)+mat.uo)*100)%iw)]; + if((((int)(1/z1))<<16)=0xffffff?((col>>24)&0xff)==0xff:true)){ + int rrc = col >> 16 & 0xFF; int rgc = col >> 8 & 0xFF; int rbc = col & 0xFF; + int rc = (int)(rrc * cc+mat.self*rrc); + if(rc>rrc)rc=rrc; + if(rc<0)rc=0; + int gc = (int)(rgc * cc+mat.self*rgc); + if(gc>rgc)gc=rgc; + if(gc<0)gc=0; + int bc = (int)(rbc * cc+mat.self*rbc); + if(bc>rbc)bc=rbc; + if(bc<0)bc=0; + if(mat.opacity==255){ + rgb[current_ty*Statics.w+current_tx]=rc << 16 | gc << 8 | bc; + } + else{ + int rd=rgb[current_ty*Statics.w+current_tx]>>16&0xff,gd=rgb[current_ty*Statics.w+current_tx]>>8&0xff,bd=rgb[current_ty*Statics.w+current_tx]&0xff; + rgb[current_ty*Statics.w+current_tx] = (alphacolor(rc,rd,mat.opacity)<<16)|(alphacolor(gc,gd,mat.opacity)<<8)|(alphacolor(bc,bd,mat.opacity)); + + } + zb[current_ty*Statics.w+current_tx]=((int)(1/z1))<<16; + } + } catch (Exception ex) { + } + } + u += du; + v += dv; + cc += dc; + z1 += dz1; + current_tx++; + } + } + x_start += dx_start; + u_start += du_start; + v_start += dv_start; + c_start += dc_start; + z1_start += dz1_start; + x_end += dx_end; + u_end += du_end; + v_end += dv_end; + c_end += dc_end; + z1_end += dz1_end; + } + } + } + + + +private int alphacolor(int trans,int old,int a){ +return (old*(255-a)+trans*a)/255; +} + + + + public boolean cursorOnVertex(int a, int b, int c) { return false; + } +} \ No newline at end of file diff --git a/src/FileMan.java b/src/FileMan.java new file mode 100644 index 0000000..6c7c7f9 --- /dev/null +++ b/src/FileMan.java @@ -0,0 +1,411 @@ +// Файловый менеджер, конечно + +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +import java.io.*; +import java.util.Enumeration; +import javax.microedition.io.*; +import javax.microedition.io.file.*; +import javax.microedition.lcdui.*; + +/** + * @author Александр + */ +public class FileMan extends Canvas/* implements CommandListener */{ + + Menu m,sm; + String path; + int md,type,xs,ys; // 0 - open, 1 - save, 2 - texture, 3 - rendered image + Image imgtosave; + + /** + * constructor + */ + public FileMan(int ty) { + setFullScreenMode(true); + path="/"; + md=0; + type=ty; + m=new Menu(null,Statics.font); + if(type!=1&&type!=3)sm=new Menu(new String[]{Statics.russian?"Выбрать":"Select",Statics.russian?"Отмена":"Cancel"},Statics.font); + else sm=new Menu(new String[]{Statics.russian?"Выбрать":"Select",Statics.russian?"Новый файл":"New file",Statics.russian?"Отмена":"Cancel"},Statics.font); + setEnum(path); + /*try { + setCommandListener(this); + addCommand(new Command("Exit", Command.EXIT, 1)); + } catch (Exception e) { + e.printStackTrace(); + }*/ + } + + /** + * paint + */ + public void paint(Graphics g) { + g.setColor(Statics.menuBack); + g.fillRect(0, 0, Statics.w, Statics.h); + m.paint(g, 0, 0, Statics.w, Statics.h-40, 0); + if(md==0){ + drawLeftSoft(g,Statics.russian?"Назад":"Back"); + drawRightSoft(g,Statics.russian?"Опции":"Options"); + } + if(md==1){ + g.setColor(Statics.menuBack); + g.fillRect(Statics.w-Statics.font.stringWidth("Новый файл"), Statics.h-Statics.font.getHeight()*3, Statics.font.stringWidth("Новый файл"), Statics.font.getHeight()*3); + g.setColor(0x444444); + g.drawRect(Statics.w-Statics.font.stringWidth("Новый файл"), Statics.h-Statics.font.getHeight()*3, Statics.font.stringWidth("Новый файл"), Statics.font.getHeight()*3); + sm.paint(g, Statics.w-Statics.font.stringWidth("Новый файл"), Statics.h-Statics.font.getHeight()*3, Statics.font.stringWidth("Новый файл"), Statics.font.getHeight()*3, 2); + } + if(md==2){ + g.setColor(Statics.menuBack); + g.fillRect(Statics.w/2-Statics.font.stringWidth("Перезаписать?")/2, Statics.h/2-30, Statics.font.stringWidth("Перезаписать?"), 60); + g.setColor(0x444444); + g.fillRect(Statics.w/2-Statics.font.stringWidth("Перезаписать?")/2, Statics.h/2-30, Statics.font.stringWidth("Перезаписать?"), 60); + g.setColor(Statics.textColor); + g.drawString(Statics.russian?"Перезаписать?":"Rewrite", Statics.w/2, Statics.h/2, 17); + drawLeftSoft(g,Statics.russian?"Да":"Yes"); + drawRightSoft(g,Statics.russian?"Нет":"No"); + } + } + + private void drawLeftSoft(Graphics g,String s){ + int sh=g.getFont().getHeight(); + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(0, Statics.h - sh+1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(0, Statics.h - sh+1, g.getFont().stringWidth(s)+5, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, 2, Statics.h - 2, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, Statics.h - 1, 36);} + else{ + g.setColor(8947967); + g.fillRoundRect(0, Statics.h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(0, Statics.h - 40, g.getFont().stringWidth(s)+5, 38,15,15); + g.setColor(0x555555); + g.drawString(s, 2, Statics.h + sh/2 - 20, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, Statics.h +sh/2 - 19, 36); + } + } + + private void drawRightSoft(Graphics g,String s){ + int sh=g.getFont().getHeight(); + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(Statics.w-g.getFont().stringWidth(s)-5, Statics.h - sh + 1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(Statics.w-g.getFont().stringWidth(s)-5, Statics.h - sh + 1, g.getFont().stringWidth(s)+4, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, Statics.w - 4, Statics.h - 2, 40); + g.setColor(Statics.textColor); + g.drawString(s, Statics.w - 3, Statics.h - 1, 40);} + else{ + g.setColor(8947967); + g.fillRoundRect(Statics.w-g.getFont().stringWidth(s)-5, Statics.h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(Statics.w-g.getFont().stringWidth(s)-5, Statics.h-40, g.getFont().stringWidth(s)+4, 38,15,15); + g.setColor(0x555555); + g.drawString(s, Statics.w - 4, Statics.h+sh/2- 20, 40); + g.setColor(Statics.textColor); + g.drawString(s, Statics.w - 3, Statics.h+sh/2 - 19, 40); + } + } + + private void setEnum(String path){ +Enumeration en=null; +try{ +if(path.equals("/")) +en=FileSystemRegistry.listRoots(); +else{ +FileConnection fc=(FileConnection)Connector.open("file://"+path); +if(fc.exists()) +en=fc.list(); +fc.close(); +} +}catch(Exception e){en=null;} +if(en!=null){ + m.setElems(en,!path.equals("/")); + m.index=0; +} +} + + /** + * Called when a key is pressed. + */ + protected void keyPressed(int key) { + String strCode = null; + try { + strCode = getKeyName(key).toLowerCase(); + } + catch (IllegalArgumentException e) { + } + if (strCode != null) + { + if (("soft1".equals(strCode)) || ("soft 1".equals(strCode)) || ("soft_1".equals(strCode)) || ("softkey 1".equals(strCode)) || ("sk2(left)".equals(strCode)) || (strCode.startsWith("left soft"))){ + left(); return; } + if (("soft2".equals(strCode)) || ("soft 2".equals(strCode)) || ("soft_2".equals(strCode)) || ("softkey 4".equals(strCode)) || ("sk1(right)".equals(strCode)) || (strCode.startsWith("right soft"))){ + right(); return;} + } + switch (key) + { + case -202: + case -21: + case -6: + case 21: + case 105: + case 113: + case 57345: + left(); break; + case -203: + case -22: + case -7: + case 22: + case 106: + case 112: + case 57346: + right(); break; + } + int ga=getGameAction(key); + switch(ga){ + case FIRE: + if(md==0||md==1&&sm.index==0){ + md=0; + if(m.index==0&&!path.equals("/"))up(); + else{ + if((path+m.getSelestedName()).endsWith("/")){path=path+m.getSelestedName(); + setEnum(path); } + else{ + if(type==0)Main.main.menu.open(path+m.getSelestedName()); + else if(type==1) md=2; + else if(type==2){ + setMap(path+m.getSelestedName()); + } + else if(type==3){ + md=1; + sm.index=1; + right(); + } } + }} + else right(); + break; + case UP: if(md==0)m.up(); else if(md==1)sm.up();break; + case DOWN: if(md==0)m.down(); else if(md==1)sm.down();break; + } + repaint(); + } + + private void left(){ + if(md==0)up(); + else if(md==1){md=0; repaint(); } + else if(md==2)if(type==1)Main.main.menu.save(path+m.getSelestedName()); else{ + md=1; + sm.index=1; + right(); + } + } + + private void up(){ + if(path.equals("/")){ + if(type==2)Main.main.d.setCurrent(Main.main.me); + else Main.main.toMenu(); + } +int i=path.lastIndexOf('/',path.length()-2); +path=path.substring(0,i+1); +setEnum(path); +repaint(); +} + + private void right(){ + if(md==0)md=1; + else if(md==1)switch(sm.index){ + case 0: if(m.index==0&&!path.equals("/")){ md=0; up();} + else{ + if((m.getSelestedName()).endsWith("/")){ + path=path+m.getSelestedName(); + setEnum(path); } + else{ + if(type==0)Main.main.menu.open(path+m.getSelestedName()); + else if(type==1) md=2; + else if(type==2){ + setMap(path+m.getSelestedName()); + } + else if(type==3){ + md=1; + sm.index=1; + right(); } } + } break; + case 1: if(type==1||type==3){ + //newfile + final TextBox tb=new TextBox(Statics.russian?"Имя файла":"File name",Main.main.e.name.equals("")?"model":Main.main.e.name,30,TextField.ANY); + Main.main.d.setCurrent(tb); + if(type==1)tb.addCommand(new Command("Ok",Command.OK,1)); + else if(type==3){ + tb.addCommand(new Command(Statics.russian?"Сохранить в Jpg":"Save as Jpg",Command.OK,1)); + tb.addCommand(new Command(Statics.russian?"Сохранить в Png":"Save as Png",Command.OK,2)); + tb.addCommand(new Command(Statics.russian?"Сохранить в Gif":"Save as Gif",Command.OK,3)); + } + tb.addCommand(new Command(Statics.russian?"Отмена":"Cancel",Command.CANCEL,4)); + tb.setCommandListener(new CommandListener(){ + public void commandAction(Command com,Displayable d){ + if(com.getPriority()<4){ + String n=tb.getString(); + String[] s=m.e; + boolean flag; + String ext=""; + if(com.getPriority()==1)ext=type==1?".s3d":".jpg"; + else if(com.getPriority()==2)ext=".png"; + else if(com.getPriority()==3)ext=".gif"; + int i=-1,j; + while(true){ + i++; + flag=false; + for(j=0;j=Statics.h-40)left(); + else if(x>=Statics.w-Statics.w/4&&y>=Statics.h-40)right(); + else{ + /*int mi=m.getTouchIndex(y); + if(mi!=0xffffff)m.index=mi; + repaint();*/ + xs=x; + ys=y; + } + } + else{ + if(x>=Statics.w-Statics.font.stringWidth(Statics.russian?"Новый файл":"New File")){ + int mi=sm.getTouchIndex(y); + if(mi!=0xffffff){ + sm.index=mi; + right(); + } + } + else{ + md=0; + repaint(); + } + } + } + + /** + * Called when the pointer is released. + */ + protected void pointerReleased(int x, int y) { + int mi=m.getTouchIndex(y); + if(xs==x&&ys==y){ + if(mi==m.index){ + if(m.index==0&&!path.equals("/"))up(); + else{ + if(m.getSelestedName().endsWith("/")){ + path=path+m.getSelestedName(); + setEnum(path);} else{ if(type==0)Main.main.menu.open(path+m.getSelestedName()); else if(type==1)md=2; else if(type==2){ + setMap(path+m.getSelestedName()); + } }} + } + else m.index=mi; + } + repaint(); + } + + /** + * Called when action should be handled + */ + public void commandAction(Command command, Displayable displayable) { + } +} diff --git a/src/Group.java b/src/Group.java new file mode 100644 index 0000000..2f5666c --- /dev/null +++ b/src/Group.java @@ -0,0 +1,237 @@ +// класс для так называемых Групп - массивов полигонов, образующих отдельные объекты + +import java.util.*; +import javax.microedition.lcdui.Graphics; +public class Group +{ + public int ax,ay,az,maxx,maxy,maxz,minx,miny,minz; + public Vector f,v; + public String name=""; + public boolean visible=true; + public Group(){ + f=new Vector(); + v=new Vector(); + int id=0; + if(Main.main.e.m!=null)id=Main.main.e.m.g.size(); + name="Group_"+id; + } + public Group(Face[] t,String n,int in){ + f=new Vector(); + v=new Vector(); + if(t==null)return; + for(int i=0;i=0){verNorm();} + name=n+"_"+in; + } + + public void triNorm(){ // нормали для треугольников + for (int i=0;imaxx)maxx=ve.x; + if(ve.xmaxy)maxy=ve.y; + if(ve.ymaxz)maxz=ve.z; + if(ve.z= 0; --i) { + if(f.elementAt(i) instanceof Triangle){ + ((Triangle)f.elementAt(i)).setMatrix(n); + if(((Triangle)f.elementAt(i)).isVisible(0)){ + ((Triangle)f.elementAt(i)).light(l); + ((Triangle)f.elementAt(i)).paint(g,0); + } + } + else{ + ((Line)f.elementAt(i)).paint(g); + } + } + } + // shad: 0 - poly, 1 - smooth, 2 - flat, 3 - wire, 4 - bounding box + public void render(int[] r,int[] z,Matrix3D n,Vector l,int shad, int view) { + if(!visible)return; + if(shad!=4){ for(int i=0;i=0&&k=0){z[Statics.w*k+j]=(ver.zc-50)<<16; + r[Statics.w*k+j]=0x111177; + } + } + } + } + } + for (int i = f.size() - 1; i >= 0; --i) { + if(Editor.sel2!=null&&Editor.sel2.contains(f.elementAt(i))&&Edit.mo==1) continue; + if(f.elementAt(i) instanceof Triangle){ + Triangle t=((Triangle)f.elementAt(i)); + t.setMatrix(n); + if(t.isVisible(view)){ + if((shad==1&&!t.smooth)||shad==0)t.light(l); + t.render(r,z,shad,view);} + } + else{ + Line line=(Line)f.elementAt(i); + line.render(r, z,view); + } + }} + else{ + Group gr=new Group(Create.wireBox(new Vertex(minx,miny,minz), new Vertex(maxx,maxy,maxz), 0xffffff),null,-1); + gr.render(r, z, n, null, 3,view); + } + } + + public int[] getBounce(Matrix3D m){ // ограничивающий прямооугольник (2D) + int[] b=new int[5]; + Vertex ve=(Vertex)v.firstElement(); + ve.setMatrix(m); + b[0]=b[2]=ve.sx; + b[1]=b[3]=ve.sy; + b[4]=ve.zc; + for (int i=0;ib[2])b[2]=ve.sx; + if(ve.sy>b[3])b[3]=ve.sy; + if(ve.zcb[3])b[3]=ve.x; + if(ve.y>b[4])b[4]=ve.y; + if(ve.z>b[5])b[5]=ve.z; + } + return b; + } + + public boolean picking(int x,int y){ // проверка на попадание группы под курсор + boolean b=false; + for (int i=0;i= 0) { + k = d[m]; + for(i=k; i= k) && (((Face)e.elementAt(j-k)).getS() > tmpsz) ) { + e.setElementAt(e.elementAt(j - k),j); + j -= k; + } + e.setElementAt(temp,j); + } + } + } + +public static void sort(Face[] e) { + Face temp=null; + int i=0, j=0, k=0, m = 0,s=e.length,tmpsz; + + while(d[m] < s) ++m; + + while(--m >= 0) { + k = d[m]; + for(i=k; i= k) && ((e[j-k]).getS() > tmpsz) ) { + e[j]=e[j - k]; + j -= k; + } + e[j]=temp; + } + } + } + +} \ No newline at end of file diff --git a/src/Light.java b/src/Light.java new file mode 100644 index 0000000..1b883a6 --- /dev/null +++ b/src/Light.java @@ -0,0 +1,34 @@ +/** + * Точка всенаправленного источника света. + * @author Shaman + */ +public class Light { + + public int x, y, z, xc, yc, zc, sx, sy; + public float s = 1; + + public Light(int a, int b, int c) { + xc = x = a; + yc = y = b; + zc = z = c; + } + + public Light(Vertex v) { + xc = x = v.x; + yc = y = v.y; + zc = z = v.z; + } + + public void setMatrix(Matrix3D m) { + xc = (int) (x * m.xx + y * m.xy + z * m.xz); + yc = (int) (x * m.yx + y * m.yy + z * m.yz); + zc = (int) (x * m.zx + y * m.zy + z * m.zz); + xc += (int) m.xo; + yc += (int) m.yo; + zc += (int) m.zo; + int z2 = (zc > -Vertex.dist + 1) ? zc : -Vertex.dist + 1; + z2 += Vertex.dist; + sx = (Statics.w / 2 + xc * Statics.pers / z2); + sy = (Statics.h / 2 - yc * Statics.pers / z2); + } +} diff --git a/src/Line.java b/src/Line.java new file mode 100644 index 0000000..37ad25b --- /dev/null +++ b/src/Line.java @@ -0,0 +1,101 @@ +import javax.microedition.lcdui.Graphics; + +public class Line extends Face +{ + public Vertex a; + public Vertex b; + + public Line(Vertex v1, Vertex v2, int col) + { + a = v1; + b = v2; + color = col;} + + public int getS() { + return ((a.zc + b.zc) / 2); } + + public void paint(Graphics g) { + paint(g, color); } + + public void setVertexMatrix(Matrix3D m) { + a.setMatrix(m); + b.setMatrix(m); + } + + public void render(int r[],int z[]){ + if(a.zc<-Vertex.dist&&b.zc<-Vertex.dist) return; + if(a.zc>Statics.limit&&b.zc>Statics.limit) return; + if(a.zc<-Vertex.dist){ + int xc=a.xc + (b.xc - a.xc) * (-Vertex.dist - a.zc) / (b.zc - a.zc); + int yc=a.yc + (b.yc - a.yc) * (-Vertex.dist - a.zc) / (b.zc - a.zc); + a.xc=xc; + a.yc=yc; + a.zc=-Vertex.dist+1; + a.to2d(); + } + if(b.zc<-Vertex.dist){ + int xc=b.xc + (a.xc - b.xc) * (-Vertex.dist+1 - b.zc) / (a.zc - b.zc); + int yc=b.yc + (a.yc - b.yc) * (-Vertex.dist+1 - b.zc) / (a.zc - b.zc); + b.xc=xc; + b.yc=yc; + b.zc=-Vertex.dist+1; + b.to2d(); + } + if(a.sx<0&&b.sx<0)return; + if(a.sy<0&&b.sy<0)return; + if(a.sx>Statics.w&&b.sx>Statics.w)return; + if(a.sy>Statics.h&&b.sy>Statics.h)return; + drawLine(r,a.sx,a.sy,b.sx,b.sy,color); + } + + public void render(int[] r,int[] z,int v){ + double scale=0; + if(v!=0){ + scale=(double)Main.main.e.dist; + if(scale>0)scale=scale/10000+0.1; + else if(scale==0)scale=0.1; + else scale=0.1+scale/100000;} + if(v==0)render(r,z); + else if(v==1){ + int x0=Main.main.e.xo; + int z0=Main.main.e.zo; + drawLine(r,(int)(Statics.w/2+a.x*scale+x0*scale),(int)(Statics.h/2-a.z*scale-z0*scale),(int)(Statics.w/2+x0*scale+b.x*scale),(int)(Statics.h/2-b.z*scale-z0*scale),color);} + else if(v==2){ + int y0=Main.main.e.yo; + int z0=Main.main.e.zo; + drawLine(r,(int)(Statics.w/2+z0*scale+a.z*scale),(int)(Statics.h/2-y0*scale-a.y*scale),(int)(Statics.w/2+z0*scale+b.z*scale),(int)(Statics.h/2-y0*scale-b.y*scale),color); + } + else if(v==3){ + int y0=Main.main.e.yo; + int x0=Main.main.e.xo; + drawLine(r,(int)(Statics.w/2+x0*scale+a.x*scale),(int)(Statics.h/2-y0*scale-a.y*scale),(int)(Statics.w/2+x0*scale+b.x*scale),(int)(Statics.h/2-y0*scale-b.y*scale),color); + } + } + + public void paint(Graphics g, int col) { + if(a.zc<-Vertex.dist&&b.zc<-Vertex.dist) return; + if(a.zc>Statics.limit&&b.zc>Statics.limit) return; + if(a.zc<-Vertex.dist){ + int xc=a.xc + (b.xc - a.xc) * (-Vertex.dist - a.zc) / (b.zc - a.zc); + int yc=a.yc + (b.yc - a.yc) * (-Vertex.dist - a.zc) / (b.zc - a.zc); + a.xc=xc; + a.yc=yc; + a.zc=-Vertex.dist+1; + a.to2d(); + } + if(b.zc<-Vertex.dist){ + int xc=b.xc + (a.xc - b.xc) * (-Vertex.dist+1 - b.zc) / (a.zc - b.zc); + int yc=b.yc + (a.yc - b.yc) * (-Vertex.dist+1 - b.zc) / (a.zc - b.zc); + b.xc=xc; + b.yc=yc; + b.zc=-Vertex.dist+1; + b.to2d(); + } + if(a.sx<0&&b.sx<0)return; + if(a.sy<0&&b.sy<0)return; + if(a.sx>Statics.w&&b.sx>Statics.w)return; + if(a.sy>Statics.h&&b.sy>Statics.h)return; + g.setColor(col); + g.drawLine(a.sx, a.sy, b.sx, b.sy); + } +} \ No newline at end of file diff --git a/src/Loader.java b/src/Loader.java new file mode 100644 index 0000000..2499c01 --- /dev/null +++ b/src/Loader.java @@ -0,0 +1,505 @@ +// загрузчик моделей s3d, obj и wax из файлов. Wax бывает не корректен из-за группированных объектов, которые здесь не поддерживаются + +/* + * To change this template, choose Tools | Templates and open the template in + * the editor. + */ +import java.io.*; +import java.util.Vector; +import javax.microedition.io.*; +import javax.microedition.io.file.*; +import javax.microedition.lcdui.Image; +/** + * + * @author Shaman + */ +public class Loader { + int p; + public Loader(){ + } + public Model openWax(InputStream ist){ + Model m=new Model(); + Matrix3D n=Main.main.e.n; + String s=" "; + try{ + DataInputStream is=new DataInputStream(ist); + byte[] b=new byte[is.available()]; + is.read(b); + s=new String(b); + is.close(); + double[] in; + while(p>=0){ + p=s.indexOf("0){ + by=dis.readByte(); + if(by=='v'){ + byte b=dis.readByte(); + if(b==' '){ + if(readFace){m.add(gr); gr.countBoundary();gr.triNorm(); if(!vn){gr.verNorm(); } vert+=gr.v.size(); gr=new Group(); readFace=false;vt=false;vn=false; } + readVertexInfo(dis,gr); } + else{ + byte b1=dis.readByte(); + if(b1==' '){ + if(b=='t'){if(!vt)vt=true; readUVInfo(dis,uv);} + else if(b=='n'){if(!vn)vn=true;readNormInfo(dis,vno); } + } + } + } + else if(by=='f'){if(dis.readByte()==' '){if(!readFace)readFace=true; readFaceInfo(dis,gr,uv,vno,vn,vt,vert); }} + else if(by=='g'){if(dis.readByte()==' '){String st=new String(); while(by!=10&&by!=13){by=dis.readByte();st=st+(char)by;} gr.name=st; } } + else{ while(by!=10&&by!=13&&dis.available()>0) by=dis.readByte(); } + } + if(gr.v.size()>0&&gr.f.size()>0){m.add(gr); gr.triNorm(); if(!vn)gr.verNorm(); gr.countBoundary(); } + dis.close(); + }catch(Exception e){return m; + } + return m; + } + + public void readVertexInfo(DataInputStream dis,Group gr) throws IOException{ + byte b=dis.readByte(); + String s=new String(); + while(b==' ') + b=dis.readByte(); + while(b!=' '){ + if((char)b>='0'&&(char)b<='9'||b=='-'||b=='.')s=s+(char)b; + b=dis.readByte(); + } + float xx; + if(s.length()>0) xx=Float.parseFloat(s); else xx=0f; + while(b==' ') + b=dis.readByte(); + s=new String(); + while(b!=' '){ + if((char)b>='0'&&(char)b<='9'||b=='-'||b=='.')s=s+(char)b; + b=dis.readByte(); + } + float yy; + if(s.length()>0) yy=Float.parseFloat(s); else yy=0f; + while(b==' ') + b=dis.readByte(); + s=new String(); + while(b!='\n'){ + if((char)b>='0'&&(char)b<='9'||b=='-'||b=='.')s=s+(char)b; + b=dis.readByte(); + } + float zz; + if(s.length()>0)zz=Float.parseFloat(s); else zz=0f; + Vertex v3f=new Vertex((int)(xx*10),(int)(yy*10),(int)(zz*10)); + gr.v.addElement(v3f); + } + + //texture coordinates + public void readUVInfo(DataInputStream dis,Vector uv) throws IOException{ + String s=new String(); + byte b=dis.readByte(); + while(b==' ') + b=dis.readByte(); + while(b!=' '){ + if((char)b>='0'&&(char)b<='9'||b=='-'||b=='.')s=s+(char)b; + b=dis.readByte(); + } + Float uu; + if(s.length()>0) uu=new Float(Float.parseFloat(s)); else uu=new Float(0f); + while(b==' ') + b=dis.readByte(); + s=new String(); + while(b!=' '&&b!='\n'&&b!='\r'){ + if((char)b>='0'&&(char)b<='9'||b=='-'||b=='.')s=s+(char)b; + b=dis.readByte(); + } + Float vv; + if(s.length()>0) vv=new Float(Float.parseFloat(s)); else vv=new Float(0f); + uv.addElement(uu); + uv.addElement(vv); + } + + public void readNormInfo(DataInputStream dis,Vector v) throws IOException{ + byte b=dis.readByte(); + String s=new String(); + while(b==' ') + b=dis.readByte(); + while(b!=' '){ + if((char)b>='0'&&(char)b<='9'||b=='-'||b=='.')s=s+(char)b; + b=dis.readByte(); + } + Float xx; + if(s.length()>0) xx=new Float(Float.parseFloat(s)); else xx=new Float(0f); + v.addElement(xx); + while(b==' ') + b=dis.readByte(); + s=new String(); + while(b!=' '){ + if((char)b>='0'&&(char)b<='9'||b=='-'||b=='.')s=s+(char)b; + b=dis.readByte(); + } + Float yy; + if(s.length()>0) yy=new Float(Float.parseFloat(s)); else yy=new Float(0f); + v.addElement(yy); + while(b==' ') + b=dis.readByte(); + s=new String(); + while(b!='\n'){ + if((char)b>='0'&&(char)b<='9'||b=='-'||b=='.')s=s+(char)b; + b=dis.readByte(); + } + Float zz; + if(s.length()>00) zz=new Float(Float.parseFloat(s)); else zz=new Float(0f); + v.addElement(zz); + } + + //polygons + public void readFaceInfo(DataInputStream dis,Group gr,Vector uv,Vector vno,boolean vn,boolean vt,int vert) throws IOException{ + Vector f=new Vector(); + byte b=dis.readByte(); + while(b!='\n'&&b!='\r'&&dis.available()>0){ + String s=new String(); + if(b==' '){ + while(b==' '){ + //if(dis.available()<=0)break; + b=dis.readByte();}} + else if(b=='/'){while(b=='/')b=dis.readByte();} + while(b!=' '&&b!='/'&&b!='\n'&&b!='\r'){ + if((char)b>='0'&&(char)b<='9')s=s+(char)b; + //if(dis.available()<=0)break; + if(dis.available()>0)b=dis.readByte(); + } + if(s.length()>0){Integer ind=new Integer(Integer.parseInt(s)); + f.addElement(ind);} + //if(b=='\n'||b=='\r'||dis.available()<=0)break; + } + + if(!vn&&!vt){ + for(int i=1;i<=f.size()-2;i++) + gr.add(new Triangle((Vertex)gr.v.elementAt(((Integer)f.elementAt(0)).intValue()-vert-1),(Vertex)gr.v.elementAt(((Integer)f.elementAt(i)).intValue()-vert-1),(Vertex)gr.v.elementAt(((Integer)f.elementAt(i+1)).intValue()-vert-1),0xffffff)); + } + else if(vn^vt){ + for(int i=0; i=0){ + t.material=(Material)MaterialEditor.mat.elementAt(mnum); + } + if(d.readBoolean()){ + t.uv=new float[6]; + t.uv[0]=d.readFloat(); + t.uv[1]=d.readFloat(); + t.uv[2]=d.readFloat(); + t.uv[3]=d.readFloat(); + t.uv[4]=d.readFloat(); + t.uv[5]=d.readFloat(); + } + } + g.countBoundary(); + m.add(g); + } + for(i=0;i> 24) & 0xff; + r = (pixels[i] >> 16) & 0xff; + g = (pixels[i] >> 8) & 0xff; + b = pixels[i++] & 0xff; + if (total>part){ + R+=r*part; G+=g*part; B+=b*part; A+=a*part; + } + else{ + R+=r*total; G+=g*total; B+=b*total; A+=a*total; + addon = part - total; +///set new pixel + lines[j++]=((R/oldW)<<16)|((G/oldW)<<8)| + (B/oldW)|((A/oldW)<<24); // A?? + } + total-=part; + } + } + } + } + else{ /// newW > oldW + int part = oldW; + for (int k = 0; k < oldH; k++) { // trough all lines + int i = k * oldW; // index in old pix + int j = k * newW; // index in new pix + int total= 0; + int r=0, g=0, b=0, a=0; + for (int m=0; m=part){ + R=r*part; G=g*part; B=b*part; A=a*part; + total-=part; + } + else{ + if (0!=total){ + R=r*total; G=g*total; B=b*total; A=a*total; + } + a = (pixels[i] >> 24) & 0xff; + r = (pixels[i] >> 16) & 0xff; + g = (pixels[i] >> 8) & 0xff; + b = pixels[i++] & 0xff; + int addon = part - total; + R+=r*addon; G+=g*addon; B+=b*addon; A+=a*addon; + total=newW - addon; + } +///set new pixel + lines[j++]=((R/oldW)<<16)|((G/oldW)<<8)| + (B/oldW)|((A/oldW)<<24); // A?? + } + } + } +/// проходим по столбцам + if (newH < oldH) { + for (int k = 0; k < newW; k++) { // trough columns + int i = k; // index in lines pix + int j = k; // index in new pix + int part = newH; + int addon = 0, r=0, g=0, b=0, a=0; + for (int m=0; m> 24) & 0xff;// may no rotate + a = lines[i] & 0xff000000; + r = (lines[i] >> 16) & 0xff; + g = (lines[i] >> 8) & 0xff; + b = lines[i] & 0xff; + i+=newW; + if (total>part){ + R+=r*part; G+=g*part; B+=b*part; A+=a;//*part; + } + else{ + R+=r*total; G+=g*total; B+=b*total; A+=a;//*total; + addon = part - total; +///set new pixel + if (0!=A) + columns[j]=((R/oldH)<<16)|((G/oldH)<<8)| + (B/oldH)|0xff000000; // A?? + else + columns[j]=0;//((R/oldH)<<16)|((G/oldH)<<8)|(B/oldH); // A?? + j+=newW; + } + total-=part; + } + } + } + } + else{ + int part = oldH; + for (int k = 0; k < newW; k++) { // trough all lines + int i = k; // index in old pix + int j = k; // index in new pix + int total= 0; + int r=0, g=0, b=0, a=0; + for (int m=0; m=part){ + R=r*part; G=g*part; B=b*part; A=a;//*part; + total-=part; + } + else{ + if (0!=total){ + R=r*total; G=g*total; B=b*total; A=a;//*total; + } +// a = (lines[i] >> 24) & 0xff;// may no rotate + a = lines[i] & 0xff000000; + r = (lines[i] >> 16) & 0xff; + g = (lines[i] >> 8) & 0xff; + b = lines[i] & 0xff; + i+=newW; + int addon = part - total; + R+=r*addon; G+=g*addon; B+=b*addon; A+=a;//*addon; + total=newH - addon; + } +///set new pixel + if (0!=A) + columns[j]=((R/oldH)<<16)|((G/oldH)<<8)| + (B/oldH)|0xff000000; // A?? + else + columns[j]=0;//((R/oldH)<<16)|((G/oldH)<<8)|(B/oldH); + + j+=newW; + } + } + } + return Image.createRGBImage(columns,newW,newH,true); + } + + public void fullReset(){ + String rsname="S3DEditor 0.6"; +try{ + RecordStore.deleteRecordStore(rsname); + notifyDestroyed(); +}catch(Exception e){} + } + +} \ No newline at end of file diff --git a/src/MainMenu.java b/src/MainMenu.java new file mode 100644 index 0000000..fc036bb --- /dev/null +++ b/src/MainMenu.java @@ -0,0 +1,534 @@ +// Главное меню программы. + +import javax.microedition.io.*; +import javax.microedition.io.file.FileConnection; +import javax.microedition.lcdui.*; +import java.io.*; + +public class MainMenu extends Canvas implements CommandListener +{ + Menu menu; + int m,w,h; + int sh = Statics.font.getHeight(); + String title; + + public MainMenu() + { + setFullScreenMode(true); + menu = new Menu(null, Statics.font); + Statics.w=w=getWidth(); + Statics.h=h=getHeight(); + Statics.pers=(int)(w*1.25); + menu.curColor = 0xcccccc; + menu.textColor=Statics.menuTextColor; + menu.selTextColor=Statics.menuTextColor; + } + + void toMenu() { + if(Main.main.e==null) menu.setElems(new String[] { Statics.russian?"Файл":"File", Statics.russian?"Настройки":"Settings", Statics.russian?"Дополнительно":"Extra"}); + else menu.setElems(new String[] {Statics.russian?"Файл":"File", Statics.russian?"Настройки":"Settings", Statics.russian?"Дополнительно":"Extra", Statics.russian?"Визуализировать":"Render"}); + title = Statics.russian?"Меню":"Menu"; + m = 0; } + + void toFile() { + menu.setElems(new String[] { Statics.russian?"Новый":"New", Statics.russian?"Открыть":"Open", Statics.russian?"Сохранить":"Save", Statics.russian?"Справка":"Help", Statics.russian?"Инфо":"About", Statics.russian?"Выход":"Exit" }); + title = Statics.russian?"Файл":"File"; + m = 1; } + + void toSet() { + menu.setElems(new String[] { Statics.russian?"Общие":"General", Statics.russian?"Цвета":"Color scheme", Statics.russian?"Сброс":"Full reset"}); + title = Statics.russian?"Настройки":"Settings"; + m = 2; } + + void toColors() { + menu.setElems(new String[] { Statics.russian?"Фон редактора":"Editor field", Statics.russian?"Курсор":"Cursor", Statics.russian?"Сетка":"Grid", Statics.russian?"Фон меню":"Menu background", Statics.russian?"Текст":"Text", Statics.russian?"Эл-ты меню":"Menu items",Statics.russian?"Фон рендера":"Render background"}); + title = Statics.russian?"Цвета":"Color scheme"; + m = 3; } + + void toDop() { + if(Main.main.e==null) menu.setElems(new String[] {Statics.russian?"Примеры":"Examples"}); + else menu.setElems(new String[] {Statics.russian?"Примеры":"Examples",Statics.russian?"Сброс вида":"Reset view",Statics.russian?"Описание":"Description"}); + title = Statics.russian?"Дополнительно":"Extra"; + m = 4; } + + void toExamples() { + menu.setElems(new String[] {Statics.russian?"Кубы":"Cubes",Statics.russian?"Домик":"Home",Statics.russian?"Танк":"Tank",Statics.russian?"Логотип":"Logo"}); + title = Statics.russian?"Примеры":"Examples"; + m = 5; + } + void toSettings(){ + Form set=new Form(Statics.russian?"Настройки":"General Settings"); + Main.main.d.setCurrent(set); + final ChoiceGroup sett=new ChoiceGroup("",List.MULTIPLE); + sett.append(Statics.russian?"Сетка":"Grid",null); + sett.append(Statics.russian?"Вспомогательные буферы":"Extra Buffers",null); + sett.append(Statics.russian?"Сенсорный ввод":"Touch Input",null); + sett.append(Statics.russian?"Крупные иконки":"Big Icons",null); + sett.append(Statics.russian?"Случайный цвет новых объектов":"Random Color of new objects",null); + sett.setSelectedFlags(new boolean[]{Statics.grid,Statics.extraBuffers,Statics.touch,Statics.bigImages,Statics.randColor}); + set.append(sett); + final TextField lim=new TextField(Statics.russian?"Дальность отрисовки":"Visible distance",""+Statics.limit,10,TextField.NUMERIC); + final TextField per=new TextField(Statics.russian?"Перспектива":"Perspective",""+Statics.pers,10,TextField.NUMERIC); + set.append(lim); + set.append(per); + final ChoiceGroup tex=new ChoiceGroup(Statics.russian?"Сжатие текстур":"Texture compression",List.EXCLUSIVE); + tex.append("Png", null); + tex.append("Jpg", null); + tex.append(Statics.russian?"Без потерь(большой размер файла)":"Lossless(huge file size)", null); + tex.append("Gif(256 colors)", null); + tex.setSelectedIndex(Statics.textureSaving, true); + set.append(tex); + final ChoiceGroup fontc=new ChoiceGroup(Statics.russian?"Шрифт":"Font size",List.EXCLUSIVE); + fontc.append(Statics.russian?"Мелкий":"Small", null); + fontc.append(Statics.russian?"Средний":"Medium",null); + fontc.append(Statics.russian?"Крупный":"Large",null); + int ii=Statics.font.getSize(); + if(ii==Font.SIZE_SMALL)fontc.setSelectedIndex(0, true); + else if(ii==Font.SIZE_MEDIUM)fontc.setSelectedIndex(1, true); + else fontc.setSelectedIndex(2, true); + set.append(fontc); + final ChoiceGroup lang=new ChoiceGroup(Statics.russian?"Язык":"Language",List.EXCLUSIVE); + lang.append("Русский", null); + lang.append("English",null); + lang.setSelectedIndex(Statics.russian?0:1,true); + set.append(lang); + set.addCommand(new Command("Ok",Command.OK,1)); + set.setCommandListener(new CommandListener(){ + public void commandAction(Command c,Displayable d){ + int met; + if(fontc.getSelectedIndex()==0)met=Font.SIZE_SMALL; + else if(fontc.getSelectedIndex()==1)met=Font.SIZE_MEDIUM; + else met=Font.SIZE_LARGE; + Statics.font=Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, met); + Statics.russian=lang.getSelectedIndex()==0; + Statics.limit=Integer.parseInt(lim.getString()); + Statics.pers=Integer.parseInt(per.getString()); + Statics.textureSaving=tex.getSelectedIndex(); + boolean[] ba=new boolean[5]; + sett.getSelectedFlags(ba); + Statics.grid=ba[0]; + Statics.extraBuffers=ba[1]; + Statics.touch=ba[2]; + Statics.bigImages=ba[3]; + Statics.randColor=ba[4]; + Main.main.d.setCurrent(Main.main.menu); + } + }); + } + + public void paint(Graphics g) + { + if(m==6){ + g.drawRGB(Main.main.e.rgb, 0, w, 0, 0, w,h, false); + drawLeftSoft(g,Statics.russian?"Сохранить":"Save"); + drawRightSoft(g,">"); + repaint(); + return; + } + g.setColor(Statics.menuBack); + g.fillRect(0, 0, w, h); + menu.paint(g, 0, h/3, w, h, 1); + //drawBorders(g); + g.setColor(Statics.textColor); + g.drawString(title, w / 2, 0, 17); + drawLeftSoft(g,Statics.russian?"Выбор":"Select"); + if ((Main.main.e != null) || (m > 0)) + drawRightSoft(g,Statics.russian?"Назад":"Back"); + } + + public void drawBorders(Graphics g) { + g.setColor(8947967); + g.fillRect(0, 0, w, sh / 2); + g.fillRect(0, h - sh + 1, w, sh / 2); + g.setColor(7632107); + g.fillRect(0, h - sh / 2 + 1, w, sh / 2); + g.fillRect(0, sh / 2, w, sh / 2); + } + + private void drawLeftSoft(Graphics g,String s){ + int sh=g.getFont().getHeight(); + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(0, h - sh+1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(0, h - sh+1, g.getFont().stringWidth(s)+5, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, 2, h - 2, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, h - 1, 36);} + else{ + g.setColor(8947967); + g.fillRoundRect(0, h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(0, h - 40, g.getFont().stringWidth(s)+5, 38,15,15); + g.setColor(0x555555); + g.drawString(s, 2, h + sh/2 - 20, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, h +sh/2 - 19, 36); + } + } + + private void drawRightSoft(Graphics g,String s){ + int sh=g.getFont().getHeight(); + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - sh + 1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h - sh + 1, g.getFont().stringWidth(s)+4, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, w - 4, h - 2, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h - 1, 40);} + else{ + g.setColor(8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h-40, g.getFont().stringWidth(s)+4, 38,15,15); + g.setColor(0x555555); + g.drawString(s, w - 4, h+sh/2- 20, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h+sh/2 - 19, 40); + } + } + + protected void keyPressed(int keyCode) + { + int g = getGameAction(keyCode); + if (g == 1) { + menu.up(); + } else if (g == 6) { + menu.down(); + } else if (g == 8) { + fire(); + } else { + String strCode = null; + try { + strCode = getKeyName(keyCode).toLowerCase(); + } + catch (IllegalArgumentException e) { + } + if (strCode != null) + { + if (("soft1".equals(strCode)) || ("soft 1".equals(strCode)) || ("soft_1".equals(strCode)) || ("softkey 1".equals(strCode)) || ("sk2(left)".equals(strCode)) || (strCode.startsWith("left soft"))){ + fire(); return; } + if (("soft2".equals(strCode)) || ("soft 2".equals(strCode)) || ("soft_2".equals(strCode)) || ("softkey 4".equals(strCode)) || ("sk1(right)".equals(strCode)) || (strCode.startsWith("right soft"))){ + back(); return;} + } + switch (keyCode) + { + case -202: + case -21: + case -6: + case 21: + case 105: + case 113: + case 57345: + fire(); break; + case -203: + case -22: + case -7: + case 22: + case 106: + case 112: + case 57346: + back(); break; + } + } + repaint(); } + + public void fire() { + switch (m) { + case 0: + switch (menu.index) { + case 0: + toFile(); break; + case 1: + toSet(); break; + case 2: + toDop();break; + case 3: render();break;} + break; + case 1: + switch (menu.index) { + case 0: + newModel(); break; + case 1: + open(); break; + case 2: + save(); break; + case 3: + help(); break; + case 4: + info(); break; + case 5: + exit(); } + break; + case 2: + switch (menu.index) + { + case 0: + toSettings();break; + case 1: + toColors(); break; + case 2: Main.main.fullReset(); break; + } + break; + case 4: + switch (menu.index) { + case 0: + toExamples();break; + case 1: Main.main.resetView();break; + case 2: desc(); + } break; + case 3: Main.main.setColor(menu.index+1); break; + case 5: switch(menu.index){ + case 0: loadExample("/examples/cubes.s3d"); break; + case 1: loadExample("/examples/home.s3d"); break; + case 2: loadExample("/examples/tank.s3d"); break; + case 3: loadExample("/examples/logo.s3d"); break; + } break; + case 6: Main.main.toSaveRender(); + } + repaint(); + } + + private void loadExample(String s){ + Main.main.newEditor(); + System.gc(); + Loader l=new Loader(); + if(s.endsWith(".obj")) + Main.main.e.m=l.loadObj(getClass().getResourceAsStream(s)); + else Main.main.e.m=l.loadResourceAsS3D(s); + Main.main.toEditor(); + } + + private void render(){ + m=6; + Editor e=Main.main.e; + for(int i=0;i) уровень полигонов и нажать назад, то в рабочем окне вы сможете выделять и взаимодействовать с полигонами и т.д. Теперь о пунктах меню:\n - Свойства. Свойства выделенного объекта (работает только если выбран один объект). Можно менять имя объекта, его видимость, узнать информацию об объекте.\n UV-координаты. Настройка текстурных координат для выбранных полигонов (на выбранном уровне полигонов разумеется). Как известно, у каждой вершины треугольника для текстурирования есть текстурные координаты, их и можно редактировать. так же клавишами * и # можно выбрать текстуру из доступных материалов для наглядного редактирования.\n Нормали. Это перпендикуляры к полигонам и вершинам, нужны в основном для освещения. Их можно обратить (перевернуть) и перерасчитать для выбранных объектов на соответствующем уровне. Не советую без необходимости перерасчитывать нормали для полигонов и объектов, т.к. чаще всего это будет неправильно и для многих треугольников придется вручную обращать нормали.\n Сглаживание. Применяется для объектов и полигонов. Включает или выключает сглаживание между полигонами наподобие групп сглаживания в 3d studio max, но здесь только две группы - сглаживание и плоское освещение.\n - Пробный материал. Назначает тестовый материал на все объекты и добавляется в список в редакторе материалов. Просто так.\n - Удалить материал. С выбранных объектов или полигонов.\n - Удалить. удаляет выбранные объекты/полигоны/вершины.\n - Отделить. Отделяет выбранные полигоны в отдельный объект."); + help.append("Edition menu is for more wide edition. Three icons define the edition level: objects, polygons and vertexes. That means if you choose (<>) polygon level in workspace you are able to select and transform only triangles in scene. Now about menu itms:\n - Properties. Properties of selected object(is available if only one object is selected) show its name, visibility,info.\n UVs - texture coordinates for selected triangles(of course, on the polygon level). Every vertex has uv coordinates according to its position on flat texture. Use * and # to change background image from available scene material.\n - Normals. It's a perpendicular for triangle. Is necessary for lighting. You can invert and recalculate it for any objects, but I don't advise to recalculate normals for objects and triangles without need because it will be incorrect and you will have to invert them manually.\n - Smooth. Turns on and off smoothing between polygons. Like smoothing groups in 3ds max but much easier.\n - Test material. Applies test material to the all objects. Just like that.\n - Delete material. Deletes material in selected polygons or objects. \n - Delete. Objects/triangles/vertexes.\n - Detach. Separates selected polygons into single object."); + break; + case 3: help.setTitle(Statics.russian?"Цвет и материалы":"Colors and materials"); + if(Statics.russian)help.append("Нажав звездочку или квадрат цвета в рабочем пространстве открывает настройка цвета. Можно вручную подобрать цвет по RGB или же найти его в палитре. Соответственно, если зажать звездочку или цветной квадрат, открывается Редактор материалов. Изначально там список материалов в сцене. Если выбрать любой, можно увидеть настройки для материала. По порядку: название, непрозрачность, самосвечение, масштабирование по U и V (горизонтально и вертикально) и сдвиг по U и V(это для текстуры), цвет, текстурная карта, двухсторонняя видимость и бесцветность(т.е. независимо от текстуры или цвета материала, полигон с этим материалом будет иметь цвет, который был ему задан при создании)."); + else help.append("Press * or color square in workspace and you will see setteing of color. You're able to set it manually using RGB or find color in palette. If you hold the same buttons, material editor opens. Here you may find list of materials in scene and settings for every material. In order:\n name, opacity, self illumination, scaling and offset of texture along U and V, diffuse color, texture map, double-sided visibility and colorless (independently from used color or texture, triangle draws with color which was given while creation)."); + break; + } + Main.main.d.setCurrent(help); + } + } + } + + public void desc(){ + final Form f=new Form(Statics.russian?"Описание":"Scene descriptor"); + final TextField nm=new TextField(Statics.russian?"Название:":"Name",Main.main.e.name,30,TextField.ANY),vn=new TextField(Statics.russian?"Создатель:":"Creator",Main.main.e.vendor,30,TextField.ANY),desc=new TextField(Statics.russian?"Описание:":"Description",Main.main.e.description,30,TextField.ANY); + f.append(""+Main.main.e.m.g.size()+(Statics.russian?" объектов":"objects")); + int fin=0,vin=0; + for(int i=0;i=h-40){ + if(xp<=w/4){ + fire(); + } + else if(xp>=w-w/4)back(); + } + int t = menu.getTouchIndex(yp); + if (t != 16777215) + menu.index = t; + repaint(); + } + + protected void pointerReleased(int x, int y) + { + int t = menu.getTouchIndex(y); + if (t != 16777215) { + menu.index = t; + fire(); + } + repaint(); + } +} \ No newline at end of file diff --git a/src/Material.java b/src/Material.java new file mode 100644 index 0000000..51d6650 --- /dev/null +++ b/src/Material.java @@ -0,0 +1,33 @@ +// класс материала для полигона + +/* + * To change this template, choose Tools | Templates and open the template in + * the editor. + */ +import javax.microedition.lcdui.Image; +/** + * + * @author Shaman + */ +public class Material { + public int diffuseColor,opacity; + public boolean doubleSided=false,useFaceColor=false; + public float self,us=1f,vs=1f,uo=0f,vo=0f; // самосвечение, масштаб текстуры по u и v, сдвиг по u и v + public int[] texture; + public int w,h; + public String desc=""; + + public Material(){ + diffuseColor=0xffffff; + opacity=255; + self=0f; + desc="Material"; + } + + public void setDiffuseMap(Image im){ + w=im.getWidth(); + h=im.getHeight(); + texture=new int[w*h]; + im.getRGB(texture, 0, w, 0, 0, w, h); + } +} diff --git a/src/MaterialEditor.java b/src/MaterialEditor.java new file mode 100644 index 0000000..4ad10df --- /dev/null +++ b/src/MaterialEditor.java @@ -0,0 +1,602 @@ +// редактор матерьялов + +/* + * To change this template, choose Tools | Templates and open the template in + * the editor. + */ +import java.util.Vector; +import javax.microedition.io.Connector; +import javax.microedition.lcdui.*; +/** + * + * @author Shaman + */ +public class MaterialEditor extends Canvas{ + int w,h,in,md,el,sh=Statics.font.getHeight(),xs,ys,xd,yd,elnum; + float dh,hh,H; + Menu m; + int[] data; + public static Vector mat=new Vector(); + Material ma; + public MaterialEditor(){ + setFullScreenMode(true); + w=getWidth(); + h=getHeight(); + dh = 360.0f / 80; + m=new Menu(new String[]{Statics.russian?"Добавить":"Add",Statics.russian?"Применить":"Apply",Statics.russian?"Удалить":"Delete"},Statics.font); + m.textColor=Statics.textColor; + } + public void paint(Graphics g){ + g.setColor(Statics.menuBack); + g.fillRect(0, 0, w, h); + if(md<=1){ + g.setColor(Statics.textColor); + int is=mat.size(); + String ss=""; + if(Statics.russian){ + String s2=Integer.toString(mat.size()); + short ii=Short.parseShort(s2.substring(s2.length()-1)); + if(is>=10&&is<=20)ss="ов"; + else{ + if(ii==1)ss=""; + else if(ii>=2&&ii<=4)ss="а"; + else if(ii==0||ii>=5&&ii<=9)ss="ов"; + } + } + else{ + if(is>1)ss="s"; + } + g.setFont(Statics.font); + g.drawString(""+is+(Statics.russian?" материал":" material")+ss, w/2, 0, 17); + g.setColor(0x777777); + g.drawRect( 3,sh+3, w-6, h-sh*2-6); + int jx=5,jy=sh+5; + for(int i=0;i=49) g.drawRGB(mm.texture, 0, mm.w, jx+1, jy+1, 49, mm.h>=49?49:mm.h, false); + else g.drawRGB(mm.texture, 0, mm.w, jx+25-mm.w/2, jy+25-mm.w/2, mm.w, mm.h>=49?49:mm.h, false); + } + if(in==i){g.setColor(0xaa0000); + g.drawRect(jx+1, jy+1, 48, 48); + } + else g.setColor(0x777777); + g.drawRect(jx, jy, 50, 50); + jx+=60; + if(jx+50>w-3){jy+=60;jx=5;} + } + if(md==1){ + m.paint(g, 0, h-m.f.getHeight()*3, m.f.stringWidth(Statics.russian?"Применить":"Delete"), 100, 1); + } + else if(md==0){if(is==0)drawLeftSoft(g,Statics.russian?"Добавить":"Add"); + else drawLeftSoft(g,Statics.russian?"Опции":"Options");} + drawRightSoft(g,Statics.russian?"Назад":"Back"); + } + else if(md==2||md==3){ + g.setColor(ma.diffuseColor); + g.fillRect(w/2-65, 18+sh*5, 60, 60); + if(ma.texture!=null){ + if(ma.w>=60) g.drawRGB(ma.texture, 0, ma.w, w/2+5, 18+sh*5, 60, ma.h>=60?60:ma.h, false); + else g.drawRGB(ma.texture, 0, ma.w, w/2+35-ma.w/2, 48+sh*5-30, ma.w, ma.h>=60?60:ma.h, false);} + else{ + g.setColor(0xffffff); + g.fillRect(w/2+5, 18+sh*5, 60, 60); + g.setColor(0xff0000); + g.drawLine(w/2+5, 18+sh*5, w/2+65, 78+sh*5); + g.drawLine(w/2+5, 78+sh*5, w/2+65, 18+sh*5); + } + g.setColor(0xbbbbbb); + g.fillRect(3, 3, w-6, sh); + g.fillRect(w/2-Statics.font.stringWidth("999")/2, 6+sh, Statics.font.stringWidth("999"), sh); + g.fillRect(w/2-Statics.font.stringWidth("999")/2, 9+sh*2, Statics.font.stringWidth("999"), sh); + g.fillRect(w/2-Statics.font.stringWidth("9999"), 12+sh*3, Statics.font.stringWidth("9999"), sh); + g.fillRect(w/2+Statics.font.stringWidth("Vscl "), 12+sh*3, Statics.font.stringWidth("9999"), sh); + g.fillRect(w/2-Statics.font.stringWidth("9999"), 15+sh*4, Statics.font.stringWidth("9999"), sh); + g.fillRect(w/2+Statics.font.stringWidth("Voff "), 15+sh*4, Statics.font.stringWidth("9999"), sh); + g.fillRect(w/2-Statics.font.stringWidth(Statics.russian?" двухсторонний":" double-sided")/2-20, 18+sh*5+63, 20, 20); + g.fillRect(w/2-Statics.font.stringWidth(Statics.russian?" бесцветный":" colorless")/2-20, 18+sh*6+63, 20, 20); + g.drawRect(w/2-65, 18+sh*5, 60, 60); + g.drawRect(w/2+5, 18+sh*5, 60, 60); + if(ma.doubleSided){ + g.setColor(0x555555); + g.fillRect(w/2-Statics.font.stringWidth(Statics.russian?" двухсторонний":" double-sided")/2-16, 18+sh*5+67, 12, 12); + } + if(ma.useFaceColor){ + g.setColor(0x555555); + g.fillRect(w/2-Statics.font.stringWidth(Statics.russian?" бесцветный":" colorless")/2-16, 18+sh*6+67, 12, 12); + } + g.setColor(Statics.textColor); + g.setFont(Statics.font); + g.drawString(ma.desc, w/2, 3, 17); + g.drawString((Statics.russian?"непрозрачность ":"opacity ")+ma.opacity, w/2+Statics.font.stringWidth("999")/2+1, 6+sh, Graphics.RIGHT|Graphics.TOP); + g.drawString("self "+(new Float(ma.self*100).intValue()), w/2+Statics.font.stringWidth("999")/2, 9+sh*2, Graphics.RIGHT|Graphics.TOP); + g.drawString("Uscl "+String.valueOf(ma.us).substring(0, String.valueOf(ma.us).indexOf('.')+2), w/2, 12+sh*3, Graphics.RIGHT|Graphics.TOP); + g.drawString("Vscl "+String.valueOf(ma.vs).substring(0, String.valueOf(ma.vs).indexOf('.')+2), w/2, 12+sh*3, Graphics.LEFT|Graphics.TOP); + g.drawString("Uoff "+String.valueOf(ma.uo).substring(0, String.valueOf(ma.uo).indexOf('.')+2), w/2, 15+sh*4, Graphics.RIGHT|Graphics.TOP); + g.drawString("Voff "+String.valueOf(ma.vo).substring(0, String.valueOf(ma.vo).indexOf('.')+2), w/2, 15+sh*4, Graphics.LEFT|Graphics.TOP); + g.drawString(Statics.russian?" двухсторонний":" double-sided", w/2, 18+sh*5+63, 17); + g.drawString(Statics.russian?" бесцветный":" colorless", w/2, 21+sh*6+63, 17); + int xe=0,ye=0,xxe=0,yye=sh; + //String des=null; + switch(el){ + case 0: ye=3; xe=3; xxe=w-6;/*des="material name";*/ break; + case 1: ye=6+sh; xe=w/2-Statics.font.stringWidth("999")/2; xxe=Statics.font.stringWidth("999");break; + case 2: ye=9+sh*2; xe=w/2-Statics.font.stringWidth("999")/2; xxe=Statics.font.stringWidth("999");break; + case 3: ye=12+sh*3; xe=w/2-Statics.font.stringWidth("9999"); xxe=Statics.font.stringWidth("9999");break; + case 4: ye=12+sh*3; xe=w/2+Statics.font.stringWidth("Vscl "); xxe=Statics.font.stringWidth("9999");break; + case 5: ye=15+sh*4; xe=w/2-Statics.font.stringWidth("9999"); xxe=Statics.font.stringWidth("9999");break; + case 6: ye=15+sh*4; xe=w/2+Statics.font.stringWidth("Voff "); xxe=Statics.font.stringWidth("9999");break; + case 7: ye=18+sh*5; xe=w/2-65; xxe=60; yye=60;break; + case 8: ye=18+sh*5; xe=w/2+5; xxe=60; yye=60;break; + case 9: xe=w/2-Statics.font.stringWidth(Statics.russian?" двухсторонний":" double-sided")/2-20; ye=18+sh*5+63; xxe=20; yye=20; break; + case 10: xe=w/2-Statics.font.stringWidth(Statics.russian?" бесцветный":" colorless")/2-20; ye=18+sh*6+63; xxe=20; yye=20; break; + } + g.setColor(0xcccc00); + g.drawRect(xe, ye, xxe, yye); + g.drawRect(xe+1, ye+1, xxe-2, yye-2); + drawRightSoft(g,Statics.russian?"Назад":"Back"); + if(md==3){ + g.setColor(0x888888); + g.fillRect(w/2-45, sh*2, 90, 119); + g.setColor(0xbbbb22); + g.drawRect(w/2-45, sh*2, 90, 119); + hh = 0; + for (int i = 0; i < 80; i++) { + int[] dt = Color.HSVtoRGB((int) hh, 255, 255); + hh += dh; + if(Math.abs(Math.floor(H)-Math.floor(hh))<=10) + g.setColor(255-dt[0],255-dt[1],255-dt[2]); + else + g.setColor(dt[0], dt[1], dt[2]); + g.drawLine(w/2-40 + i, sh*2+6, w/2-40 + i, sh*2+24); + } + g.drawRGB(data, 0, 80, w/2-40, sh*2+39, 80, 80, false); + g.setColor(0x222222); + g.drawArc(w/2-50+xd, sh*2+29+yd, 20, 20, 0, 360); + } + } + else if(md>=4){ + if(ma.texture!=null){ + g.drawRGB(ma.texture, 0, ma.w, w/2-ma.w/2, h/2-ma.h/2, ma.w, ma.h, true); + g.setColor(0); + g.drawRect(w, w, w, h); + } + else{ + g.setFont(Statics.font); + g.setColor(0xffffff); + g.fillRect(w/2-50, h/2-50, 100, 100); + g.setColor(0xff0000); + g.drawLine(w/2-50, h/2-50, w/2+50, h/2+50); + g.drawLine(w/2+50, h/2-50, w/2-50, h/2+50); + g.setColor(0); + g.drawRect(w/2-51, h/2-51, 102, 102); + g.drawString("no texture map", w/2, h/2, 17); + } + drawLeftSoft(g,Statics.russian?"Назад":"Back"); + if(ma.texture==null)drawRightSoft(g,Statics.russian?"Добавить":"Add"); else drawRightSoft(g,Statics.russian?"Опции":"Options"); + if(md==5){ + g.setColor(Statics.menuBack); + g.fillRect(w-Statics.font.stringWidth(Statics.russian?"Удалить":"Delete"), h-sh*2, Statics.font.stringWidth(Statics.russian?"Удалить":"Delete"), sh*2); + g.setColor(0); + g.drawRect(w-Statics.font.stringWidth(Statics.russian?"Удалить":"Delete"), h-sh*2, Statics.font.stringWidth(Statics.russian?"Удалить":"Delete"), sh*2); + g.setColor(0xaaaa00); + g.fillRect(w-Statics.font.stringWidth(Statics.russian?"Удалить":"Delete"), h-sh*(2-elnum), Statics.font.stringWidth(Statics.russian?"Удалить":"Delete"), sh); + g.setColor(Statics.menuTextColor); + g.drawString(Statics.russian?"Сменить":"Change", w, h-sh, Graphics.RIGHT|Graphics.BOTTOM); + g.drawString(Statics.russian?"Удалить":"Delete", w, h, Graphics.RIGHT|Graphics.BOTTOM); + + } + } + repaint(); + } + + private void updateData(float H){ + //palitra + if(data==null)data=new int[80*80]; + float ds=255f/80f; + float dv=255f/80f; + float v = 255; + float s; + for (int i = 0; i < 80; i++) { + s = 255; + for (int i2 = 0; i2 < 80; i2++) { + int[] dt = Color.HSVtoRGB((int) H, (int) s,(int) v); + data[(i * 80) + i2] = dt[0] << 16 | dt[1] << 8 | dt[2]; + s -= ds; + } + v -= dv; + } + } + + private void drawLeftSoft(Graphics g,String s){ + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(0, h - sh+1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(0, h - sh+1, g.getFont().stringWidth(s)+5, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, 2, h - 2, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, h - 1, 36);} + else{ + g.setColor(8947967); + g.fillRoundRect(0, h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(0, h - 40, g.getFont().stringWidth(s)+5, 38,15,15); + g.setColor(0x555555); + g.drawString(s, 2, h + sh/2 - 20, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, h +sh/2 - 19, 36); + } + } + + private void drawRightSoft(Graphics g,String s){ + if(!Statics.touch){ + g.setColor(8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - sh + 1, g.getFont().stringWidth(s)+5, sh-1,10,10); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h - sh + 1, g.getFont().stringWidth(s)+4, sh-2,10,10); + g.setColor(0x555555); + g.drawString(s, w - 4, h - 2, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h - 1, 40);} + else{ + g.setColor(8947967); + g.fillRoundRect(w-g.getFont().stringWidth(s)-5, h - 40, g.getFont().stringWidth(s)+5, 39,15,15); + g.setColor(0); + g.drawRoundRect(w-g.getFont().stringWidth(s)-5, h-40, g.getFont().stringWidth(s)+4, 38,15,15); + g.setColor(0x555555); + g.drawString(s, w - 4, h+sh/2- 20, 40); + g.setColor(Statics.textColor); + g.drawString(s, w - 3, h+sh/2 - 19, 40); + } + } + + protected void keyPressed(int key){ + String strCode = "null"; + + try { + strCode = getKeyName(key).toLowerCase(); + } + catch (IllegalArgumentException e) { + } +// if (strCode != null) +// { + if (((("soft1".equals(strCode)) || ("soft 1".equals(strCode)) || ("soft_1".equals(strCode)) || ("softkey 1".equals(strCode)) || ("sk2(left)".equals(strCode)) || (strCode.startsWith("left soft"))))) + { if( mat.isEmpty()){ + mat.addElement(new Material()); in=0;} else if(md==0)md=1; else if(md==1)fire(); else if(md==3)md=2; else if(md==4)md=2; else if(md==5)md=4; return; + } + else if (("soft2".equals(strCode)) || ("soft 2".equals(strCode)) || ("soft_2".equals(strCode)) || ("softkey 4".equals(strCode)) || ("sk1(right)".equals(strCode)) || (strCode.startsWith("right soft"))){ + if(md==1)md=0; + else if(md==0)Main.main.toEditor(); + else if(md==2)md=0; + else if(md==3){ + md=2; ma.diffuseColor=data[yd*80+xd]; data=null; } + else if(md==4){ + if(ma.texture==null)setNewMap(); + else md=5; + } + else if(md==5){ + if(elnum==0)setNewMap(); + else if(elnum==1) deleteMap(); + } + return; } + else switch (key) + { + case -202: + case -21: + case -6: + case 21: + case 105: + case 113: + case 57345: + if(mat.isEmpty()){ + mat.addElement(new Material()); in=0;} else if(md==0)md=1; else if(md==1)fire(); else if(md==3)md=2; else if(md==4)md=2; else if(md==5)md=4; + break; + case -203: + case -22: + case -7: + case 22: + case 106: + case 112: + case 57346: + if(md==1)md=0; + else if(md==0)Main.main.toEditor(); + else if(md==2)md=0; + else if(md==3){ + md=2; ma.diffuseColor=data[yd*80+xd]; data=null;} + else if(md==4){ + if(ma.texture==null)setNewMap(); + else md=5; + } + else if(md==5){ + if(elnum==0)setNewMap(); + else if(elnum==1) deleteMap(); + } + break; + case 53:// mat.addElement(new Material());break; + } + int gameact=getGameAction(key); + switch(gameact){ + case LEFT: if(md==0){if(--in<0) in=mat.size()-1;} else if(md==2&&(key<49||key>57)&&el>0){ + el--; + } + else if(md==3){ + if(xd>1)xd-=2; + } + break; + case RIGHT: if(md==0){if(++in>=mat.size())in=0;} else if(md==2&&(key<49||key>57)&&el<10)el++; else if(md==3){if(xd<78)xd+=2; } break; + case UP: if(md==0){int num=(w-8+10)/60; + in-=num; + if(in<0)in=mat.size()-1;}else if(md==1)m.up(); + else if(md==2&&el>0){ + if(el<4||el==9||el==10)el--; + else if(el==4||el==5||el==7)el-=2; + else el-=3; + } + else if(md==3){if(yd>1)yd-=2;} + else if(md==5){ + elnum--; + if(elnum<0)elnum=1; + } + break; + case DOWN: if(md==0){int numm=(w-8+10)/60; + in+=numm; + if(in>=mat.size())in=0;}else if(md==1) m.down(); + else if(md==2&&el<10){ + if(el==3||el==5)el+=2; + else el++; + } + else if(md==3){ + if(yd<78)yd+=2; + }else if(md==5){ + elnum++; + if(elnum>1)elnum=0; + } + break; + case FIRE: if(md==1) fire(); else if(md==0&&!mat.isEmpty()){md=2; ma=(Material)mat.elementAt(in); } else if(md==2){ + if(el==0)editMatName(); + else if(el==7){md=3; + float[] dt=Color.RGBtoHSV(ma.diffuseColor>>16&0xff, ma.diffuseColor>>8 &0xff,ma.diffuseColor&0xff); + H=dt[0]; + xd=(int)(dt[1]*80/255); + yd=(int)(dt[2]*80/255); + updateData(H); + } + else if(el==8)md=4; + else if(el==9)ma.doubleSided=!ma.doubleSided; + else if(el==10)ma.useFaceColor=!ma.useFaceColor; + } + else if(md==5){ + if(elnum==0)setNewMap(); + else deleteMap(); + } + break; + } + if(md==2&&(key==52||key==54)){ + int tmp; + if(key==52)tmp=-1; else tmp=1; + switch(el){ + case 1: if(ma.opacity<=255&&ma.opacity>=0)ma.opacity+=5*tmp; if(ma.opacity<0)ma.opacity=0;if(ma.opacity>255)ma.opacity=255;break; + case 2: if(ma.self>=0&&ma.self<=1)ma.self+=0.05f*tmp;if(ma.self<0)ma.self=0;if(ma.self>1)ma.self=1;break; + case 3: ma.us+=tmp*0.05f;break; + case 4: ma.vs+=tmp*0.05f;break; + case 5: ma.uo+=tmp*0.1f;break; + case 6: ma.vo+=tmp*0.1f;break; + } + } + if(md==3&&key==49){if((H-=5)<0)H=360; updateData(H); } + if(md==3&&key==51){if((H+=5)>=360)H=0; updateData(H); } +} + + private void setNewMap(){ + Main.main.toOpenMap(); + } + private void deleteMap(){ + ma.texture=null; + md=4; + } + + public void setMap(Image img){ + ma.setDiffuseMap(img); + } + + protected void keyRepeated(int key){ + if(md==3){ + int ga=getGameAction(key); + if(ga==LEFT&&xd>4)xd-=5; + if(ga==RIGHT&&xd<75)xd+=5; + if(ga==UP&&yd>4)yd-=5; + if(ga==DOWN&&yd<75)yd+=5; + if(key==49){if((H-=5)<0)H=360; updateData(H); } + if(key==51){if((H+=5)>=360)H=0; updateData(H); } + } + else if(md==2&&(key==52||key==54)){ + int tmp; + if(key==52)tmp=-1; else tmp=1; + switch(el){ + case 1: if(ma.opacity<=255&&ma.opacity>=0)ma.opacity+=5*tmp; if(ma.opacity<0)ma.opacity=0;if(ma.opacity>255)ma.opacity=255;break; + case 2: if(ma.self>=0&&ma.self<=1)ma.self+=0.05f*tmp;if(ma.self<0)ma.self=0;if(ma.self>1)ma.self=1;break; + case 3: ma.us+=tmp*0.05f;break; + case 4: ma.vs+=tmp*0.05f;break; + case 5: ma.uo+=tmp*0.1f;break; + case 6: ma.vo+=tmp*0.1f;break; + } + } + } + + public void fire(){ + switch(m.index){ + case 0: mat.addElement(new Material());break; + case 1: if(!mat.isEmpty()){ + if(Edit.mo==0&&Editor.sel!=null) + for (int i=0;i=h-40&&xp<=w/4){ + if(mat.isEmpty()){ + mat.addElement(new Material()); in=0;} else md=1; + } + else if(yp>=h-40&&xp>=w-w/4){ + Main.main.toEditor(); + } + else{ + int wiw=(w+5)/60; + int iis=(xp-5)/60+(yp-sh-5)/60*wiw; + if(iis>=0&&iis=0&&ind<3) + if(m.index==ind)fire(); else m.index=ind;} + if(yp>=h-40&&xp>=w-w/4){ + md=0; + } + } + else if(md==2){ + if(yp>=h-40&&xp>=w-w/4){ + md=0; + } + else if(yp>=3 && xp>=3 && xp<=w-6 && yp<=3+sh){ + el=0; + editMatName(); + } + else if(yp>=6+sh && xp>=w/2-Statics.font.stringWidth("999")/2 && xp<=w/2+Statics.font.stringWidth("999")/2 && yp<=sh*2+6){ + el=1; + } + else if(yp>=9+sh*2 && xp>=w/2-Statics.font.stringWidth("999")/2 && xp<=w/2+Statics.font.stringWidth("999")/2 && yp<=9+sh*3){ + el=2; + } + else if(yp>=12+sh*3 && xp>=w/2-Statics.font.stringWidth("9999") && xp<=w/2 && yp<=12+sh*4){ + el=3; + } + else if(yp>=12+sh*3 && xp>=w/2+Statics.font.stringWidth("Vscl ") && xp<=w/2+Statics.font.stringWidth("Vscl 9999") && yp<=12+sh*4){ + el=4; + } + else if(yp>=15+sh*4 && xp>=w/2-Statics.font.stringWidth("9999") && xp<=w/2 && yp<=15+sh*5){ + el=5; + } + else if(yp>=15+sh*4 && xp>=w/2+Statics.font.stringWidth("Voff ") && xp<=w/2+Statics.font.stringWidth("Voff 9999") && yp<=15+sh*5){ + el=6; + } + else if(yp>=18+sh*5 && xp>=w/2-65 && xp<=w/2-5 && yp<=78+sh*5){ + el=7; + md=3; + float[] dt=Color.RGBtoHSV(ma.diffuseColor>>16&0xff, ma.diffuseColor>>8 &0xff,ma.diffuseColor&0xff); + H=dt[0]; + xd=(int)(dt[1]*80/255); + yd=(int)(dt[2]*80/255); + updateData(H); + } + else if(yp>=18+sh*5 && xp>=w/2+5 && xp<=w/2+65 && yp<=78+sh*5){ + el=8; + md=4; + } + else if(yp>=18+sh*5+63 && xp>=w/2-Statics.font.stringWidth(Statics.russian?" двухсторонний":" double-sided")/2-20 && xp<=w/2-Statics.font.stringWidth(Statics.russian?" двухсторонний":" double-sided")/2 && yp<=18+sh*5+83){ + el=9; + ma.doubleSided=!ma.doubleSided; + } + else if(yp>=18+sh*6+63 && xp>=w/2-Statics.font.stringWidth(Statics.russian?" бесцветный":" colorless")/2-20 && xp<=w/2-Statics.font.stringWidth(Statics.russian?" бесцветный":" colorless")/2 && yp<=18+sh*6+83){ + el=10; + ma.useFaceColor=!ma.useFaceColor; + } + xs=xp; + ys=yp; + } + else if(md==3){ + if(yp>=h-40&&xp>=w-w/4){ + md=2; + ma.diffuseColor=data[yd*80+xd]; + data=null;} + else if(xp>=w/2-40&&xp=sh*2+6&&yp<=sh*2+24){H=(xp-w/2+40)*360/80; if(H>=360)H=0; if(H<0)H=360; updateData(H); } + else if(yp>=sh*2+39&&yp=h-40&&xp>=w-w/4){ + if(ma.texture==null)setNewMap(); else md=5; + } + else if(yp>=h-40&&xp<=w/4){ + if(md==4)md=2; + } + } + else if(md==5){ + if(xp>=w-Statics.font.stringWidth(Statics.russian?"Удалить":"Delete")){ + if(yp>=h-sh){ + elnum=1; + deleteMap(); + } + else if(yp>=h-sh*2){ + elnum=0; + setNewMap(); + } + } + else if(yp>=h-40&&xp<=w/4){ + md=4; + } + } + } + protected void pointerDragged(int xp, int yp){ + if(md==2){ + switch(el){ + case 1: if(ma.opacity<=255&&ma.opacity>=0)ma.opacity+=xp-xs; if(ma.opacity<0)ma.opacity=0;if(ma.opacity>255)ma.opacity=255;break; + case 2: if(ma.self>=0&&ma.self<=1)ma.self+=((float)(xp-xs))/100f;if(ma.self<0)ma.self=0;if(ma.self>1)ma.self=1;break; + case 3: ma.us+=(xp-xs)*0.05f;break; + case 4: ma.vs+=(xp-xs)*0.05f;break; + case 5: ma.uo+=(xp-xs)*0.1f;break; + case 6: ma.vo+=(xp-xs)*0.1f;break; + } + xs=xp; + ys=yp; + } + else if(md==3){ + if(xp>=w/2-40&&xp=sh*2+6&&yp<=sh*2+24){H=(xp-w/2+40)*360/80;if(H>=360)H=0; if(H<0)H=360; updateData(H); } + else if(yp>=sh*2+39&&yp= 0; ) { + float x = v[i]; + float y = v[(i + 1)]; + float z = v[(i + 2)]; + tv[i] = (int)(x * lxx + y * lxy + z * lxz + lxo); + tv[(i + 1)] = (int)(x * lyx + y * lyy + z * lyz + lyo); + tv[(i + 2)] = (int)(x * lzx + y * lzy + z * lzz + lzo); + } + } + + public String toString() { + return "[" + xo + "," + xx + "," + xy + "," + xz + ";" + yo + "," + yx + "," + yy + "," + yz + ";" + zo + "," + zx + "," + zy + "," + zz + "]"; + } +} \ No newline at end of file diff --git a/src/Menu.java b/src/Menu.java new file mode 100644 index 0000000..797a553 --- /dev/null +++ b/src/Menu.java @@ -0,0 +1,112 @@ +// графическое меню, по сути универсальное, но не красивое :) + +import java.util.Enumeration; +import java.util.Vector; +import javax.microedition.lcdui.Font; +import javax.microedition.lcdui.Graphics; + +public class Menu +{ + public int textColor = 0x99; + public int curColor = 0xffff00; + public int selTextColor = 0x4444ff; + public int index; + public int sh; + public int by; + public int yy,hy; + public String[] e; + Font f; + public short[] ave; + + public Menu(String[] s, Font font) + { + e = s; + sh = font.getHeight(); + f = font; } + + public void paint(Graphics g, int px, int py, int w, int h, int align) { + yy = py; + hy=h; + g.setFont(f); + g.setColor(curColor); + int y = py + sh * index + by; + //if ((y > h + py - sh)) + //by -= sh; + //if(y > py+sh) + //by -= sh; + g.fillRect(px, y, w, sh); + for (int i = 0; i < e.length; ++i) { + int z = i * sh + py + by; + if(z>=py+h)continue; + if(i==index){g.setColor(selTextColor); + } + else g.setColor(textColor); + if (align == 0) + g.drawString(e[i], px, z, 20); + else if (align == 1) + g.drawString(e[i], w / 2 + px, z, 17); + else + g.drawString(e[i], px + w, z, 24); + } + } + + public void up() { + index -= 1; + if (index < 0){ + index = (e.length - 1); + if(by+yy+sh*index>yy+hy-sh)by=-sh*index+hy-sh; + } + if(ave!=null) + for(int i=0;ihy)by=-sh*index; + } + + public void down() { + index += 1; + if (index >= e.length){ + index = 0; + if(by+yy+sh*indexyy+hy-sh)by-=sh; + } + public void move(int yp){ + if(yp>0&&by<=0)by+=yp; + if(yp<0&&by+yy+e.length*sh>=yy+hy) by+=yp; + } + + public int getTouchIndex(int y) { + int touch = (y - yy - by) / sh; + if ((touch < e.length) && (touch >= 0)) + return touch; + return 16777215; } + + public int getSize(){ + return e.length; + } + + public String getSelestedName() { + return e[index]; } + + public void setElems(Enumeration en,boolean bl){ + Vector v=new Vector(); + if(bl)v.addElement(". ."); + while(en.hasMoreElements()) + v.addElement(en.nextElement().toString()); + e=new String[v.size()]; + v.copyInto(e); + by=0; + } + + public void setElems(String[] s) { + e = s; + index = 0; } + + public void setElem(int i, String s) { + if ((i >= 0) && (i < e.length)) + e[i] = s; + } +} \ No newline at end of file diff --git a/src/Model.java b/src/Model.java new file mode 100644 index 0000000..3b582ca --- /dev/null +++ b/src/Model.java @@ -0,0 +1,331 @@ +// класс содержащий модель - массив групп и источников света + +import java.util.Vector; +import javax.microedition.lcdui.Graphics; + +public class Model +{ + Vector g; + + Vector l; // освещение + + public Model() + { + g = new Vector(); + + l=new Vector(); + } + + public void draw(Graphics gr, Matrix3D m) { + if(l!=null&&!l.isEmpty()){for(int i=0;ix){ + int tmp=sx; + sx=x; + x=tmp; + } + if(sy>y){ + int tmp=sy; + sy=y; + y=tmp; + } + Vector p=new Vector(); + if(l!=null)for(int i=0;i=sx&&z.sx-10<=x)||(z.sx+10>=sx&&z.sx+10<=x)||(z.sx-10<=sx&&z.sx+10>=x))&&((z.sy-10>=sy&&z.sy-10<=y)||(z.sy+10>=sy&&z.sy+10<=y)||(z.sy-10<=sy&&z.sy+10>=y)))p.addElement(z); + } + int[] b; + if(g!=null)for (int i=0;i=sx&&b[0]<=x)||(b[2]>=sx&&b[2]<=x)||(b[0]<=sx&&b[2]>=x))&&((b[1]>=sy&&b[1]<=y)||(b[3]>=sy&&b[3]<=y)||(b[1]<=sy&&b[3]>=y)))p.addElement(gr); + } + return p; + } + + public Vector selectTr(int sx,int sy,int x,int y){ // треугольники + if(sx>x){ + int tmp=sx; + sx=x; + x=tmp; + } + if(sy>y){ + int tmp=sy; + sy=y; + y=tmp; + } + Vector p=new Vector(); + for(int i=0;i=sx&&tr.a.sy<=y&&tr.a.sy>=sy)||(tr.b.sx<=x&&tr.b.sx>=sx&&tr.b.sy<=y&&tr.b.sy>=sy)||(tr.c.sx<=x&&tr.c.sx>=sx&&tr.c.sy<=y&&tr.c.sy>=sy)) p.addElement(tr); + } + } + return p; + } + + public Vector selectVer(int sx,int sy,int x,int y){ // вершины + if(sx>x){ + int tmp=sx; + sx=x; + x=tmp; + } + if(sy>y){ + int tmp=sy; + sy=y; + y=tmp; + } + Vector p=new Vector(); + for(int i=0;i=sx&&ver.sx<=x&&ver.sy>=sy&&ver.sy<=y)p.addElement(ver); + } + } + return p; + } + + public Vector select3d(int[] s,Matrix3D m){ // объекты, попавшие в трехмерное выделение + if(s[0]>s[3]){ + int tmp=s[0]; + s[0]=s[3]; + s[3]=tmp; + } + if(s[1]>s[4]){ + int tmp=s[1]; + s[1]=s[4]; + s[4]=tmp; + } + if(s[2]>s[5]){ + int tmp=s[2]; + s[2]=s[5]; + s[5]=tmp; + } + Vector p=new Vector(); + if(l!=null)for (int i=0;i=s[0]&&z.x<=s[3]&&z.y>=s[1]&&z.y<=s[4]&&z.z>=s[2]&&z.z<=s[5])p.addElement(z); + } + int[] b; + if(g!=null)for(int i=0;i=s[0]&&b[0]<=s[3])||(b[3]>=s[0]&&b[3]<=s[3])||(b[0]<=s[0]&&b[3]>=s[3]))&&((b[1]>=s[1]&&b[1]<=s[4])||(b[4]>=s[1]&&b[4]<=s[4])||(b[1]<=s[1]&&b[4]>=s[4]))&&((b[2]>=s[2]&&b[2]<=s[5])||(b[5]>=s[2]&&b[5]<=s[5])||(b[2]<=s[2]&&b[5]>=s[5]))) p.addElement(gr); + } + return p; + } + + public Vector select3dTr(int[] s){ + if(s[0]>s[3]){ + int tmp=s[0]; + s[0]=s[3]; + s[3]=tmp; + } + if(s[1]>s[4]){ + int tmp=s[1]; + s[1]=s[4]; + s[4]=tmp; + } + if(s[2]>s[5]){ + int tmp=s[2]; + s[2]=s[5]; + s[5]=tmp; + } + Vector p=new Vector(); + for(int i=0;i=s[0]&&tr.a.y<=s[4]&&tr.a.y>=s[1]&&tr.a.z<=s[5]&&tr.a.z>=s[2])||(tr.b.x<=s[3]&&tr.b.x>=s[0]&&tr.b.y<=s[4]&&tr.b.y>=s[1]&&tr.b.z<=s[5]&&tr.b.z>=s[2])||(tr.c.x<=s[3]&&tr.c.x>=s[0]&&tr.c.y<=s[4]&&tr.c.y>=s[1]&&tr.c.z<=s[5]&&tr.c.z>=s[2])) p.addElement(tr); + } + } + return p; + } + + public Vector select3dVer(int[] s){ + if(s[0]>s[3]){ + int tmp=s[0]; + s[0]=s[3]; + s[3]=tmp; + } + if(s[1]>s[4]){ + int tmp=s[1]; + s[1]=s[4]; + s[4]=tmp; + } + if(s[2]>s[5]){ + int tmp=s[2]; + s[2]=s[5]; + s[5]=tmp; + } + Vector p=new Vector(); + for(int i=0;i=s[0]&&ver.x<=s[3]&&ver.y>=s[1]&&ver.y<=s[4]&&ver.z>=s[2]&&ver.z<=s[5])p.addElement(ver); + } + } + return p; + } + + public Object pick(int x,int y,Matrix3D m){ // ближайший объект на месте щелчка курсором + int[] b; + int max=Integer.MAX_VALUE; + Object ret=null; + if(l!=null)for(int i=0;i=li.sx-10&&x<=li.sx+10&&y>=li.sy-10&&y<=li.sy+10&&li.zc>=(-Vertex.dist+1)){max=li.zc;ret=li;} + } + if(g!=null)for(int i=0;i=b[0]&&x<=b[2]&&y>=b[1]&&y<=b[3]&&b[4]>=(-Vertex.dist+1)){max=b[4];ret=gr;} + } + return ret; + } + + public Triangle pickTr(int x,int y,Matrix3D m){ + int minz=Integer.MAX_VALUE; + Triangle ret=null; + for (int i=0;i=0&&bi>=0&&ci>=0)||(ai<=0&&bi<=0&&ci<=0))&&tr.getS()>16)&0xff,g=(ma.texture[j]>>8)&0xff,b=ma.texture[j]&0xff; + dos.writeInt(r); + dos.writeInt(g); + dos.writeInt(b);*/ + dos.writeInt(ma.texture[j]); + } + } + } + } + for(i=0;i", w-w/4+15, h/2-10, 17); + g.drawString("<", w/4-15, h/2-10, 17); + if(Statics.touch)g.drawString("Ok", w/2, h-h/4+10, 17); + else drawLeftSoft(g,"Ok"); + } + repaint(); + } + + private void drawLeftSoft(Graphics g,String s){ + int ssh=g.getFont().getHeight(); + g.setColor(8947967); + g.fillRoundRect(0, getHeight() - ssh+1, g.getFont().stringWidth(s)+5, ssh-1,10,10); + g.setColor(0); + g.drawRoundRect(0, getHeight() - ssh+1, g.getFont().stringWidth(s)+5, ssh-2,10,10); + g.setColor(0x555555); + g.drawString(s, 2, h - 2, 36); + g.setColor(Statics.textColor); + g.drawString(s, 3, h - 1, 36); + } + + public void keyPressed(int key){ + if(wind==2){ + int ga=getGameAction(key); + switch(ga){ + case LEFT: + case RIGHT: Statics.bigImages=!Statics.bigImages;break; + case FIRE: Main.main.toMenu();break; + } + } + if(wind==0){ + int ga=getGameAction(key); + switch(ga){ + case UP: i--; if(i<0)i=1;break; + case DOWN: i++; if(i>1)i=0;break; + case FIRE: Statics.russian=(i==0); wind=1;break; + } + } + String strCode = null; + try { + strCode = getKeyName(key).toLowerCase(); + } + catch (IllegalArgumentException e) { + } + if (strCode != null) + { + if (((("soft1".equals(strCode)) || ("soft 1".equals(strCode)) || ("soft_1".equals(strCode)) || ("softkey 1".equals(strCode)) || ("sk2(left)".equals(strCode)) || (strCode.startsWith("left soft"))))) + { if(wind==0)wind=1; else if(wind==1)wind=2; else{if(!Statics.bigImages)Statics.font=Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_MEDIUM); Main.main.toMenu();}}//left + /*if (("soft2".equals(strCode)) || ("soft 2".equals(strCode)) || ("soft_2".equals(strCode)) || ("softkey 4".equals(strCode)) || ("sk1(right)".equals(strCode)) || (strCode.startsWith("right soft"))) + {fire(); }//right*/ + } + switch (key) + { + case -202: + case -21: + case -6: + case 21: + case 105: + case 113: + case 57345: + if(wind==0){wind=1; Statics.russian=(i==0); } else if(wind==1) wind=2; else{if(!Statics.bigImages)Statics.font=Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_MEDIUM); Main.main.toMenu(); }break;//left + /*case -203: + case -22: + case -7: + case 22: + case 106: + case 112: + case 57346: + fire();break;//right*/ + } + } + + protected void pointerDragged(int x,int y){ + if(wind==0){if(y>h/2)i=1; else i=0; } + } + + protected void pointerReleased(int x,int y){ + if(wind==0){Statics.russian=(i==0);wind=1; } + } + + protected void pointerPressed(int x,int y){ + if(wind==0){ + if(y>h/2)i=1; else i=0; + } + else if(wind==1){ + Statics.touch=true; + wind=2; + } + else if(wind==2){ + if(x>w-w/4||x> 16 & 0xFF; int gc = color >> 8 & 0xFF; int bc = color & 0xFF; + rc = (int)(rc * -k); + gc = (int)(gc * -k); + bc = (int)(bc * -k); + paint(g, rc << 16 | gc << 8 | bc,v); + } + + // col - цвет, v - обзор: перспективный или один из боковых + public void paint(Graphics g, int col,int v) { + double dis=1; + g.setColor(col); + if(v!=0){ + dis=(double)Main.main.e.dist; + if(dis>0)dis=(dis/10000)+0.1; + else if(dis==0)dis=0.1; + else dis=0.1+dis/100000; + } + if(v==0)g.fillTriangle(a.sx, a.sy, b.sx, b.sy, c.sx, c.sy); + else if(v==1){ + int x0=Main.main.e.xo; + int z0=Main.main.e.zo; + // int scale=1; + g.fillTriangle((int)(Statics.w/2+x0*dis+a.x*dis),(int)(Statics.h/2-z0*dis-a.z*dis),(int)(Statics.w/2+x0*dis+b.x*dis),(int)(Statics.h/2-z0*dis-b.z*dis),(int)(Statics.w/2+x0*dis+c.x*dis),(int)(Statics.h/2-z0*dis-c.z*dis)); + } + else if(v==2){ + int y0=Main.main.e.yo; + int z0=Main.main.e.zo; + //int scale=1; + g.fillTriangle((int)(Statics.w/2+z0*dis+a.z*dis),(int)(Statics.h/2-y0*dis-a.y*dis),(int)(Statics.w/2+z0*dis+b.z*dis),(int)(Statics.h/2-y0*dis-b.y*dis),(int)(Statics.w/2+z0*dis+c.z*dis),(int)(Statics.h/2-y0*dis-c.y*dis)); + } + else if(v==3){ + int y0=Main.main.e.yo; + int x0=Main.main.e.xo; + // int scale=1; + g.fillTriangle((int)(Statics.w/2+x0*dis+a.x*dis),(int)(Statics.h/2-y0*dis-a.y*dis),(int)(Statics.w/2+x0*dis+b.x*dis),(int)(Statics.h/2-y0*dis-b.y*dis),(int)(Statics.w/2+x0*dis+c.x*dis),(int)(Statics.h/2-y0*dis-c.y*dis)); + } + } + + public void setVertexMatrix(Matrix3D m) { + a.setMatrix(m); + b.setMatrix(m); + c.setMatrix(m); + } + public boolean isVisible(int v){ // проверка полигона на видимость + if(v==0){ + if(a.zc<-Vertex.dist&&b.zc<-Vertex.dist&&c.zc<-Vertex.dist) return false; + if(a.zc>Statics.limit&&b.zc>Statics.limit&&c.zc>Statics.limit) return false; + if((a.sx<0&&b.sx<0&&c.sx<0)||(a.sx>Statics.w&&b.sx>Statics.w&&c.sx>Statics.w))return false; + if((a.sy<0&&b.sy<0&&c.sy<0)||(a.sy>Statics.h&&b.sy>Statics.h&&c.sy>Statics.h)) return false; + if(material!=null&&material.doubleSided)return true; + if(/*(material==null||material.opacity==255)&&*/rnz>0)return false; + } + else{ + double dis=(double)Main.main.e.dist; + if(dis>0)dis=dis/10000+0.1; + else if(dis==0)dis=0.1; + else dis=0.1+dis/100000; + int x0=Main.main.e.xo; + int z0=Main.main.e.zo; + int y0=Main.main.e.yo; + int w=Statics.w,h=Statics.h; + if(((a.x*dis+x0*dis<-w/2&&b.x*dis+x0*dis<-w/2&&c.x*dis+x0*dis<-w/2)||(a.x*dis+x0*dis>w/2&&b.x*dis+x0*dis>w/2&&c.x*dis+x0*dis>w/2))&&(v==1||v==3))return false; + if(((a.z*dis+z0*dis<-h/2&&b.z*dis+z0*dis<-h/2&&c.z*dis+z0*dis<-h/2)||(a.z*dis+z0*dis>h/2&&b.z*dis+z0*dis>h/2&&c.z*dis+z0*dis>h/2))&&v==1)return false; + if(((a.z*dis+z0*dis<-w/2&&b.z*dis+z0*dis<-w/2&&c.z*dis+z0*dis<-w/2)||(a.z*dis+z0*dis>w/2&&b.z*dis+z0*dis>w/2&&c.z*dis+z0*dis>w/2))&&v==2)return false; + if(((a.y*dis+y0*dis<-h/2&&b.y*dis+y0*dis<-h/2&&c.y*dis+y0*dis<-h/2)||(a.y*dis+y0*dis>h/2&&b.y*dis+y0*dis>h/2&&c.y*dis+y0*dis>h/2))&&(v==3||v==2))return false; + } + return true; + } + + public void setMatrix(Matrix3D m) + { + rnx = (nx * m.xx + ny * m.xy + nz * m.xz); + rny = (nx * m.yx + ny * m.yy + nz * m.yz); + rnz = (nx * m.zx + ny * m.zy + nz * m.zz); + } + + public void soequal(){ + nx=rnx; + ny=rny; + nz=rnz; + double length = Math.sqrt(nx * nx + ny * ny + nz * nz); + nx = (float)(nx / ((length == 0D) ? 1D : length)); + ny = (float)(ny / ((length == 0D) ? 1D : length)); + nz = (float)(nz / ((length == 0D) ? 1D : length)); + } + + public void light(Vector l){ // рассчет освещения при отключенном сглаживании (все точки треугольника освещены одинаково) + if(l!=null&&!l.isEmpty()){ + int mx=(a.xc+b.xc+c.xc)/3; + int my=(a.yc+b.yc+c.yc)/3; + k=0; + float kk; + for(int i=0;i0){if(material!=null&&material.doubleSided)kk=-kk; else kk=0;} + kk*=li.s; + k+=kk; + } + } + else{ + k=rnz; + if(k>0){if(material!=null&&material.doubleSided)k=-k; else k=0;} + } + } + + // рендеринг полигона. r - экранный буфер, z - буфер глубины, s - тип шейдинга, v - обзор + public void render(int[] r,int[] z,int s,int v){ + if(v!=0){ + switch(v){ + case 1: top(r,z,s);break; + case 2: right(r,z,s);break; + case 3: front(r,z,s);break; + } + return; + } + byte culling=0; // проверка на залезание треугольника за экран, т.е. когда одна или две из вершин по Z < 0. + //В этом случае треугольник разбивается на два и один подтреугольники соответственно для корректного просчета координат вершин, но искажений исбежать все равно не удалось. Печальбеда. + Vertex ver1=null,ver2=null,ver3=null,ver4=null,ver5=null; + if(a.zc<-Vertex.dist&&b.zc>-Vertex.dist&&c.zc>-Vertex.dist||b.zc<-Vertex.dist&&a.zc>-Vertex.dist&&c.zc>-Vertex.dist||c.zc<-Vertex.dist&&a.zc>-Vertex.dist&&b.zc>-Vertex.dist){ + culling=1; + if(a.zc<-Vertex.dist){ver1=a;ver2=b;ver3=c;if(uv!=null){ver2.u=uv[2];ver2.v=uv[3];ver3.u=uv[4];ver3.v=uv[5];} } + else if(b.zc<-Vertex.dist){ver1=b;ver2=a;ver3=c;if(uv!=null){ver2.u=uv[0];ver2.v=uv[1];ver3.u=uv[4];ver3.v=uv[5];} } + else{ ver1=c;ver2=a;ver3=b;if(uv!=null){ver2.u=uv[0];ver2.v=uv[1];ver3.u=uv[2];ver3.v=uv[3];} } + ver4=new Vertex(); + ver5=new Vertex(); + ver4.zc=-Vertex.dist+1; + ver5.zc=-Vertex.dist+1; + ver4.xc=ver2.xc + (ver1.xc - ver2.xc) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver4.yc=ver2.yc + (ver1.yc - ver2.yc) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver4.k=ver2.k + (ver1.k - ver2.k) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver4.u=ver2.u + (ver1.u - ver2.u) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver4.v=ver2.v + (ver1.v - ver2.v) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver5.xc=ver3.xc + (ver1.xc - ver3.xc) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver5.yc=ver3.yc + (ver1.yc - ver3.yc) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver5.k=ver3.k + (ver1.k - ver3.k) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver5.u=ver3.u + (ver1.u - ver3.u) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver5.v=ver3.v + (ver1.v - ver3.v) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver4.to2d(); + ver5.to2d(); + } + if(a.zc<-Vertex.dist&&b.zc<-Vertex.dist||a.zc<-Vertex.dist&&c.zc<-Vertex.dist||b.zc<-Vertex.dist&&c.zc<-Vertex.dist){ + if(a.zc>-Vertex.dist){ver1=a;ver2=b;ver3=c;if(uv!=null){ver2.u=uv[2];ver2.v=uv[3];ver3.u=uv[4];ver3.v=uv[5];} } + else if(b.zc>-Vertex.dist){ver1=b;ver2=a;ver3=c;if(uv!=null){ver2.u=uv[0];ver2.v=uv[1];ver3.u=uv[4];ver3.v=uv[5];} } + else{ver1=c;ver2=a;ver3=b;if(uv!=null){ver2.u=uv[0];ver2.v=uv[1];ver3.u=uv[2];ver3.v=uv[3];} } + ver4=new Vertex(); + ver5=new Vertex(); + ver4.zc=-Vertex.dist+1; + ver5.zc=-Vertex.dist+1; + ver4.xc=ver2.xc + (ver1.xc - ver2.xc) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver4.yc=ver2.yc + (ver1.yc - ver2.yc) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver4.k=ver2.k + (ver1.k - ver2.k) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver4.u=ver2.u + (ver1.u - ver2.u) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver4.v=ver2.v + (ver1.v - ver2.v) * (-Vertex.dist+1 - ver2.zc) / (ver1.zc - ver2.zc); + ver5.xc=ver3.xc + (ver1.xc - ver3.xc) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver5.yc=ver3.yc + (ver1.yc - ver3.yc) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver5.k=ver3.k + (ver1.k - ver3.k) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver5.u=ver3.u + (ver1.u - ver3.u) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver5.v=ver3.v + (ver1.v - ver3.v) * (-Vertex.dist+1 - ver3.zc) / (ver1.zc - ver3.zc); + ver4.to2d(); + ver5.to2d(); + culling=2;} + if(s==0){ + if(material==null){ + int rc = color >> 16 & 0xFF; int gc = color >> 8 & 0xFF; int bc = color & 0xFF; + rc = (int)(rc * -k); + if(rc>255)rc=255; + if(rc<0)rc=0; + gc = (int)(gc * -k); + if(gc>255)gc=255; + if(gc<0)gc=0; + bc = (int)(bc * -k); + if(bc>255)bc=255; + if(bc<0)bc=0; + if(culling==0) + renderFlatTriangle(r,z,a,b,c,rc << 16 | gc << 8 | bc); + else if(culling==1){ + renderFlatTriangle(r,z,ver3,ver2,ver4,rc << 16 | gc << 8 | bc); + renderFlatTriangle(r,z,ver3,ver4,ver5,rc << 16 | gc << 8 | bc); + } + else renderFlatTriangle(r,z,ver1,ver4,ver5,rc << 16 | gc << 8 | bc); + } + else{ + if(material.texture==null||material.useFaceColor){ + int rc = (material.useFaceColor?color:material.diffuseColor) >> 16 & 0xFF; int gc = (material.useFaceColor?color:material.diffuseColor) >> 8 & 0xFF; int bc = (material.useFaceColor?color:material.diffuseColor) & 0xFF; + rc = (int)(rc * -k); + if(rc>255)rc=255; + if(rc<0)rc=0; + gc = (int)(gc * -k); + if(gc>255)gc=255; + if(gc<0)gc=0; + bc = (int)(bc * -k); + if(bc>255)bc=255; + if(bc<0)bc=0; + if(culling==0)renderFlatTriangle(r,z,a,b,c,rc << 16 | gc << 8 | bc); + else if(culling==1){renderFlatTriangle(r,z,ver3,ver2,ver4,rc << 16 | gc << 8 | bc); + renderFlatTriangle(r,z,ver3,ver4,ver5,rc << 16 | gc << 8 | bc); + } + else renderFlatTriangle(r,z,ver1,ver4,ver5,rc << 16 | gc << 8 | bc); + } + else{ + if(uv!=null){ + if(culling==0)renderAffineTexturedTriangle(material,r,z,uv,a,b,c,-k); + else if(culling==1){renderAffineTexturedTriangle(material,r,z,uv,ver3,ver2,ver4,-k); + renderAffineTexturedTriangle(material,r,z,uv,ver3,ver4,ver5,-k);} + else renderAffineTexturedTriangle(material,r,z,uv,ver1,ver4,ver5,-k); + } + else{ + if(culling==0)renderAffineTexturedTriangle(material,r,z,a,b,c,-k); + else if(culling==1){renderAffineTexturedTriangle(material,r,z,ver3,ver2,ver4,-k); + renderAffineTexturedTriangle(material,r,z,ver3,ver4,ver5,-k);} + else renderAffineTexturedTriangle(material,r,z,ver1,ver4,ver5,-k); + } + } + } + } + else if(s==1){ + if(material==null){ + if(!smooth){ + int rc = color >> 16 & 0xFF; int gc = color >> 8 & 0xFF; int bc = color & 0xFF; + rc = (int)(rc * -k); + if(rc>255)rc=255; + if(rc<0)rc=0; + gc = (int)(gc * -k); + if(gc>255)gc=255; + if(gc<0)gc=0; + bc = (int)(bc * -k); + if(bc>255)bc=255; + if(bc<0)bc=0; + if(culling==0) + renderFlatTriangle(r,z,a,b,c,rc << 16 | gc << 8 | bc); + else if(culling==1){ + renderFlatTriangle(r,z,ver3,ver2,ver4,rc << 16 | gc << 8 | bc); + renderFlatTriangle(r,z,ver3,ver4,ver5,rc << 16 | gc << 8 | bc); + } + else renderFlatTriangle(r,z,ver1,ver4,ver5,rc << 16 | gc << 8 | bc); + } + else{ + if(culling==0) + renderTriangle(r,z,a,b,c,color); + else if(culling==1){ + renderTriangle(r,z,ver3,ver2,ver4,color); + renderTriangle(r,z,ver3,ver4,ver5,color); + } + else renderTriangle(r,z,ver1,ver4,ver5,color); + } + } + else{ + if(material.texture==null||material.useFaceColor){ + if(!smooth){ + int rc = (material.useFaceColor?color:material.diffuseColor) >> 16 & 0xFF; int gc = (material.useFaceColor?color:material.diffuseColor) >> 8 & 0xFF; int bc = (material.useFaceColor?color:material.diffuseColor) & 0xFF; + int rrc = (int)(rc * -k+rc*material.self); + if(rrc>rc)rrc=rc; + if(rc<0)rc=0; + int rgc = (int)(gc * -k+gc*material.self); + if(rgc>gc)rgc=gc; + if(gc<0)gc=0; + int rbc = (int)(bc * -k+bc*material.self); + if(rbc>bc)rbc=bc; + if(bc<0)bc=0; + if(culling==0)renderFlatTriangle(r,z,a,b,c,rrc << 16 | rgc << 8 | rbc,material.opacity); + else if(culling==1){renderFlatTriangle(r,z,ver3,ver2,ver4,rrc << 16 | rgc << 8 | rbc,material.opacity); + renderFlatTriangle(r,z,ver3,ver4,ver5,rrc << 16 | rgc << 8 | rbc,material.opacity); + } + else renderFlatTriangle(r,z,ver1,ver4,ver5,rrc << 16 | rgc << 8 | rbc,material.opacity); + } + else{ + int col=0; + if(material.useFaceColor){ + col=material.diffuseColor; + material.diffuseColor=color;} + if(culling==0)renderTriangle(r,z,a,b,c,material); + else if(culling==1){renderTriangle(r,z,ver3,ver2,ver4,material); + renderTriangle(r,z,ver3,ver4,ver5,material); + } + else renderTriangle(r,z,ver1,ver4,ver5,material); + if(material.useFaceColor)material.diffuseColor=col; + } + } + else{ + if(!smooth){ + if(uv!=null){ + if(culling==0)renderAffineTexturedTriangle(material,r,z,uv,a,b,c,-k); + else if(culling==1){renderAffineTexturedTriangle(material,r,z,uv,ver3,ver2,ver4,-k); + renderAffineTexturedTriangle(material,r,z,uv,ver3,ver4,ver5,-k);} + else renderAffineTexturedTriangle(material,r,z,uv,ver1,ver4,ver5,-k); + } + else{ + if(culling==0)renderAffineTexturedTriangle(material,r,z,a,b,c,-k); + else if(culling==1){renderAffineTexturedTriangle(material,r,z,ver3,ver2,ver4,-k); + renderAffineTexturedTriangle(material,r,z,ver3,ver4,ver5,-k);} + else renderAffineTexturedTriangle(material,r,z,ver1,ver4,ver5,-k); + } + } + else{ + if(uv!=null){ + if(culling==0)renderAffineTexturedTriangle(material,r,z,uv,a,b,c); + else if(culling==1){renderAffineTexturedTriangle(material,r,z,uv,ver3,ver2,ver4); + renderAffineTexturedTriangle(material,r,z,uv,ver3,ver4,ver5);} + else renderAffineTexturedTriangle(material,r,z,uv,ver1,ver4,ver5); + } + else{ + if(culling==0)renderAffineTexturedTriangle(material,r,z,a,b,c); + else if(culling==1){renderAffineTexturedTriangle(material,r,z,ver3,ver2,ver4); + renderAffineTexturedTriangle(material,r,z,ver3,ver4,ver5);} + else renderAffineTexturedTriangle(material,r,z,ver1,ver4,ver5); + } + } + } + } + } + else if(s==2){ + if(culling==0)renderFlatTriangle(r,z,a,b,c,color); + else if(culling==1){renderFlatTriangle(r,z,ver3,ver2,ver4,color); + renderFlatTriangle(r,z,ver3,ver5,ver4,color); + } + else renderFlatTriangle(r,z,ver1,ver5,ver4,color); + } + else if(s==3){ + + if(culling==0){ + drawLine(r,z,a,b,color); + drawLine(r,z,a,c,color); + drawLine(r,z,b,c,color);} + else if(culling==1){renderFlatTriangle(r,z,ver3,ver2,ver4,color); + renderFlatTriangle(r,z,ver3,ver5,ver4,color); + drawLine(r,z,ver3,ver2,color); + drawLine(r,z,ver3,ver5,color); + drawLine(r,z,ver2,ver4,color); +// drawLine(r,z,ver4,ver5,color); + } + else{ renderFlatTriangle(r,z,ver1,ver5,ver4,color); + drawLine(r,z,ver1,ver5,color); + drawLine(r,z,ver1,ver4,color); +// drawLine(r,z,ver4,ver5,color); + } + } + } + + private void top(int[] r,int[] z,int s){ + int x0=Main.main.e.xo; + int z0=Main.main.e.zo; + double scale=(double)Main.main.e.dist; + if(scale>0)scale=scale/10000+0.1; + else if(scale==0)scale=0.1; + else scale=0.1+scale/100000; + render(r,(int)(Statics.w/2+x0*scale+a.x*scale),(int)(Statics.h/2-z0*scale-a.z*scale),(int)(Statics.w/2+x0*scale+b.x*scale),(int)(Statics.h/2-z0*scale-b.z*scale),(int)(Statics.w/2+x0*scale+c.x*scale),(int)(Statics.h/2-z0*scale-c.z*scale),s); + } + + private void right(int[] r,int[] z,int s){ + int y0=Main.main.e.yo; + int z0=Main.main.e.zo; + double scale=(double)Main.main.e.dist; + if(scale>0)scale=scale/10000+0.1; + else if(scale==0)scale=0.1; + else scale=0.1+scale/100000; + render(r,(int)(Statics.w/2+z0*scale+a.z*scale),(int)(Statics.h/2-y0*scale-a.y*scale),(int)(Statics.w/2+z0*scale+b.z*scale),(int)(Statics.h/2-y0*scale-b.y*scale),(int)(Statics.w/2+z0*scale+c.z*scale),(int)(Statics.h/2-y0*scale-c.y*scale),s); + } + + private void front(int[] r,int[] z,int s){ + int y0=Main.main.e.yo; + int x0=Main.main.e.xo; + double scale=(double)Main.main.e.dist; + if(scale>0)scale=scale/10000+0.1; + else if(scale==0)scale=0.1; + else scale=0.1+scale/100000; + render(r,(int)(Statics.w/2+x0*scale+a.x*scale),(int)(Statics.h/2-y0*scale-a.y*scale),(int)(Statics.w/2+x0*scale+b.x*scale),(int)(Statics.h/2-y0*scale-b.y*scale),(int)(Statics.w/2+x0*scale+c.x*scale),(int)(Statics.h/2-y0*scale-c.y*scale),s); + } + + private void render(int[] r,int asx,int asy,int bsx,int bsy,int csx,int csy,int s){ + if(s==0||s==1){ + int rc = color >> 16 & 0xFF; int gc = color >> 8 & 0xFF; int bc = color & 0xFF; + rc = (int)(rc * -k); + if(rc>255)rc=255; + if(rc<0)rc=0; + gc = (int)(gc * -k); + if(gc>255)gc=255; + if(gc<0)gc=0; + bc = (int)(bc * -k); + if(bc>255)bc=255; + if(bc<0)bc=0; + renderTriangle(r,asx,asy,bsx,bsy,csx,csy,rc << 16 | gc << 8 | bc); + } + else if(s==2){ + renderTriangle(r,asx,asy,bsx,bsy,csx,csy,color); + } + else if(s==3){ + drawLine(r,asx,asy,bsx,bsy,color); + drawLine(r,asx,asy,csx,csy,color); + drawLine(r,bsx,bsy,csx,csy,color); + } + } + +} \ No newline at end of file diff --git a/src/Vertex.java b/src/Vertex.java new file mode 100644 index 0000000..71fcbc5 --- /dev/null +++ b/src/Vertex.java @@ -0,0 +1,151 @@ + +import java.util.Vector; + +/** + * Вершина + * @author Shaman + */ +public class Vertex { + + public int sx, sy; + public int xc, yc, zc; + public int x, y, z; + public float nx, ny, nz; + public float rnx, rny, rnz; + public int k; + public float u, v; + + public static int dist = 3000; + + public Vertex() { + } + + public Vertex(int a1, int a2, int a3) { + xc = (x = a1); + yc = (y = a2); + zc = (z = a3); + to2d(); + } + + public Vertex(Vertex vertex) { + x = vertex.x; + y = vertex.y; + z = vertex.z; + nx = vertex.nx; + ny = vertex.ny; + nz = vertex.nz; + xc = vertex.xc; + yc = vertex.yc; + zc = vertex.zc; + u = vertex.u; + v = vertex.u; + to2d(); + } + + public void sn(float rx, float ry, float rz) { + nx = rx; + ny = ry; + nz = rz; + } + + public void setUV(float a, float b) { + u = a; + v = b; + } + + public void setMatrix(Matrix3D m) { + xc = (int) (x * m.xx + y * m.xy + z * m.xz); + yc = (int) (x * m.yx + y * m.yy + z * m.yz); + zc = (int) (x * m.zx + y * m.zy + z * m.zz); + xc += (int) m.xo; + yc += (int) m.yo; + zc += (int) m.zo; + rnx = (nx * m.xx + ny * m.xy + nz * m.xz); + rny = (nx * m.yx + ny * m.yy + nz * m.yz); + rnz = (nx * m.zx + ny * m.zy + nz * m.zz); + to2d(); + } + + public final void to2d() { + if (zc == -dist) { + zc = -dist + 1; + } + if (zc > -dist) { // Здесь я пытался решить рассчет координат точек при Z < 0, ведь в этом случае они ведут себя неправильно, но так и не смог и оставил обычные формулы рассчета проекции. + // int z2 = (zc > -dist) ? zc : -dist-1; + + int z2 = zc + dist; + sx = (Statics.w / 2 + xc * Statics.pers / z2); + sy = (Statics.h / 2 - yc * Statics.pers / z2); + } + /* else if(zc<-dist){ + int z2=zc+dist; + sx = (Statics.w / 2 - xc*z2/Statics.pers); + sy = (Statics.h / 2 + yc*z2/Statics.pers); + }*/ + /* else{ + sx = (Statics.w / 2 + xc);//*Statics.pers/5); + sy = (Statics.h / 2 - yc);//*Statics.pers/5); + }*/ + } + + /** + * Рассчет освещения в точке для дальнейшей интерполяции при отрисовке сглаженного полигона + * @param light + */ + public void light(Vector light) { + if (light != null && !light.isEmpty()) { + k = 0; + int kk; + for (int i = 0; i < light.size(); i++) { + if (light.elementAt(i) == null) + continue; + Light li = (Light) light.elementAt(i); + float lx = xc - li.xc, ly = yc - li.yc, lz = zc - li.zc; + double len = Math.sqrt(lx * lx + ly * ly + lz * lz); + lx /= len; + ly /= len; + lz /= len; + kk = (int) ((lx * rnx + ly * rny + lz * rnz) * 100) << 16; + if (kk > 0) + kk = 0; + kk *= -li.s; + k += kk; + } + } else { + float kk = -rnz; + k = (int) ((kk) * 100) << 16; + } + } + + public void move(int a, int b, int c) { + x += a; + y += b; + z += c; + } + + public void normalize() { + double length = Math.sqrt(nx * nx + ny * ny + nz * nz); + nx = (float) (nx / ((length == 0D) ? 1D : length)); + ny = (float) (ny / ((length == 0D) ? 1D : length)); + nz = (float) (nz / ((length == 0D) ? 1D : length)); + } + + public void soequal() { + x = xc; + y = yc; + z = zc; + } + + public void soeqNorm() { + nx = rnx; + ny = rny; + nz = rnz; + } + + public static int[] unProject(Matrix3D m, int xs, int ys) { // обратная проекция в 3D + float a = Statics.pers * m.xx - xs * m.zx + Statics.w / 2 * m.zx, b = Statics.pers * m.xz - xs * m.zz + Statics.w / 2 * m.zz; + float c = Statics.pers * m.yx - Statics.h / 2 * m.zx + ys * m.zx, d = Statics.pers * m.yz - Statics.h / 2 * m.zz + ys * m.zz; + float e = xs * m.zo + xs * dist - Statics.w / 2 * m.zo - Statics.w / 2 * dist - Statics.pers * m.xo, f = Statics.h / 2 * m.zo + Statics.h / 2 * dist - ys * m.zo - ys * dist - Statics.pers * m.yo; + return new int[]{(int) ((e * d - b * f) / (a * d - c * b)), (int) ((a * f - c * e) / (a * d - c * b))}; + } +} diff --git a/src/examples/cubes.s3d b/src/examples/cubes.s3d new file mode 100644 index 0000000000000000000000000000000000000000..82ec70825b7c92cb74689dd943c54ce9d5e8699f GIT binary patch literal 16804 zcmb7{%aJ5U4n&7n3PB0>L?K3q7O;hAAt(fe;B^+y4X?}#tQwMswD1c29FB~G(G z`QNv1-+r0rq>AM+UZIrukyXZ>~Y*TMK0_kD7b*LoLIPam*x z@U&j+V-Tu@q_U$kEs#juK&yV^2>*UUy7UM(QUvMeh^NW3K-ZO0JZ`a08^~kyP?9chx zcQ|itb%}4)vk&`wrzdgrk^Wv_^5_G$UiTOK))uF~%?maTyK@)QKUmJ<8)yHqZ|>wc z_+Rmyn&i)X3O{(Vx12l!xp89b;IDZa_uOM& zu44Ek$E=Ov+Pc_3d@iOQda>U;<2(CmPyWXI)(31odxpE1ynRN*-QUw0SuWO4`{bKk zw?8znUSoT;zpm#Q3Af2foLDW4`?tDyKH({DUFe4=c?;ufuVUlyxe&b_3xf>@R{On1eS94Iq*3+3J$M#}9wEkS}@w=Fw^y&WMyWC?x7;gGB zPxijX#vXBvKX?CCoE+#c_TuclO}^c~{lVQhF>&@MHcp<*L7rlGg5?P|4vm=)d#o4J zw?3^)e3wt`2Rm2Kob}+~cZyhz{JYP-f9pDq-r*4YtoG!0P4caeacX=u#P?@&h<$UZ zXP*IUa~@hx^}|=Jw%!f)y&Lk(-fAdTL+UrC7vp+1#PL`g8<>;pE#q$+!5% z$xKLLPQJAnmovM2 zV&eLoiOJb zu^&uLectiJ-rPKs?0W{(C3{;#Yz_aGB;WdU+&wSE^%9RG{ z*Ry)-We(P=dhA;d+;MVc<%#dEjeCCaTm8jwOODl0-1B3PJkjC>ww`u*vaiO;QMJ`V zpS}<5Wq(%UF4pd9z4&g8*bcT=&P>;X%cpe~r{BT6#~YK^dc^rI7Uyh}W1hxcj~r?x z&hLrAuW{E4@AVN=BRRI7xa*+{e>=%5#t+Q9sWCqGr=H}(N8RGTJn-?1cAS6zQ)9V- z{rfJyJgH$%jj6%D^}yDXzbigs*8AKzbs3KpIaWjQyZ#>M z6aRT~Rtr;4p9fFvtlAIG-{;x$tjg0|p0TdycTLXwZhQyZ6X(70V}9%FckR`M{N@Xu-_294jAKq0t-KFC$$`Cm9`*2_hxbqX7l+?q-dBz3 z!}$@%`;JvijpUoP@ne4MlaqS;T%7Z{K9BzN-TcXMuv!@}&+M1)LkqZ^=ZPma>goe0 z_YQvOvON7;%D(Rgu-^;fN4<^X{i7bfi;`pQ;;T!}*>Y?Aif^B@e1}yWvwLW}HOcYd zsl9l@Mb5bc=G*qyi~Wl;pWT1N&F}b<)4T`MlRn*F&hpskn|Gae zKn;91t7rIPe0kV^#BDC>kdp^2PkuM< zImDk_8;4B|{TrHmryjlDdqfTP!@Y3Vi=ABB^(WuKw?E(4S5MCXJcB2X^P?W`BIn*X zXJC1F9*j#3;`YfoEc|Zn)?w9PI8Tc5x?+tNyR-Ag~Tx<<|;Se6X z+TYK3Mk8~~`j}tm(#~GtmpsRgo_?P_&eQCP=~bV;x3TNDKJMY~xegvK_Q&tfwTq2& zmh6MkqT_OgWs_CT5<86-}cn~sh2*@lf7`1)BX9wY{Ne`(YAl!F`5kUs|ME00{cYUsH5$Qb9(94|OFhZ4Hu>KEh$Cn6iZ?F0 zh^rnv@63~D_Wc&cCx0VPoZo%1n}_w_r}>S|*+!$oliIKPi|@uh&4InD7d*e!llNlY zjl25JWaYhzF5=cRdz)7bZ!quG#!vGjX6-l{H=f>%2|LeJzoxa-+p<~=o9Py5#A*0Yb;x3<{Y z_ug{m{hoN7``Hr{rw`oK(>nmq*vHn``|vsY&67BCqKlZ{;JlLyw=S`74Y4)g)ws_! z+^oae7~8x4jFTsEVr*d6;HiIgflutq4Se4dR~NKu4aLNP!yi14^_cJXvC)TTt}#6I zX+7h+d1F5q{`xe}oTu{bGkNdd=N|j=6wB?4o;Dub z_rY4`rLNe&qwjd43wdKN3@_^i&+q2>PEUN%8UDc)Cr@=@72o$RvDQn!<4aFs;>gEd z ze9LorMO*Q#H%^|Om(TT0f8vUZ9S-xnJD>1`d+TXjv?uTS^h}I&eskdUld;V&2VxxR0@WM!@=hKe+WI?t5_q+uz5*_q;T>i{%lW zCy)KnhyAD5`Q5r?uItl!HcxWMSuAJvJ1+Lp1uf*JF8aJX*VySDo?!WlZ@u)a@2t*} z_{Oj1VE^CgV{_a&biJSHLY&$L&+nc?pOMD@q{}^LttS{=qVvD3XFlSBD~|r)ezl12 e?EkF4))4Ic)WsaFXZC7N&CRoePc)kK$NvGnEI7#k literal 0 HcmV?d00001 diff --git a/src/examples/home.s3d b/src/examples/home.s3d new file mode 100644 index 0000000000000000000000000000000000000000..c6ebcf377234d3160124f89dd4db52b5419c1eb4 GIT binary patch literal 1368 zcmah|yKO@;3{;sqaGx@7j8q;XwTo6YiIj^TKKO_KtC)y-?Jve_3a6m zqjQF{pKx(4b9!F#>x^wbo(&xHw{v>FKW76^F6x!tediizI;Y~rnR^Z2 z&>Ugo{oW@0F0Ot&gV$YR5eJ@r87oHV+Pil5qxPD#%p0-h8fIPn;rSTcX_xbVIFG0G%w^BN^N~J!G%;jV%bG6?q4Rjg$oyn?V#tzH z$2|N!4erm0qi0#w)BYfP!^1kG-VcuxLza58*X~pIlyS1Ri1Y7nz{K3~kGj3wn};sB zUuYwFSf+Svcj7Z2+GDWgJhra~EIr1+r~FkO;ilaJfE`$DU`^$8n0Y__I#d?mU}>F@Fh17>+Pz zZ%WVS(SpeZm3xS>Ua}T|*(-Ck{uV5*Ii*+rfM+~9r_7ya)*ip(1gHH4TaR^M&6uAs z-mzvoKkkj3F~a0prksK?wjTFe^n&fI2Xp0j!SYeHQ%tD~?6JlrtMA2v=`S2%kTGVx%-9x8e|VUm{XuK5OU_8<@DBL} zilYLSj^>U9k{zbpK{X`c~me%+VaqvBu^W4@(|6Ym_AtH-5( zkYT;F-uNcgy+ZTe`x953(W`q$&7a*t>a3jpa_^uln0E1uyGh~F!{0-G;4b~ceCOI2 zB7Vk++G1{5b2D$@iZk_84aIf;WMl2+UgxnN*k5ziU)vB?ZJpoJ z2gqKJdW^^1*bt}k!{1sj+DGK#{cMfzdksYDVc^S7yRqj12R`-rhjz2&YZZq-;Z zXaB(#>%w!4XOS@d-Knkhz*K%``|swyE8D{#YZZUO2jChM3rLX}tBV6R^e*j#9+zn|WR8HaL;jXfTnM`f$drf|773j^2(_nKrJ z4|v*eY~7m?d)-eN57#Vgh>MXN>tVKfN?E?Oti{BMqiyHxfG*<{7npfWocubM)B-%( zns==DJKme9auyrqx~GhIbe7)OD0dlOdv)IO6v10q*xfy?4YxcKo{{T@ev04BC literal 0 HcmV?d00001 diff --git a/src/examples/tank.s3d b/src/examples/tank.s3d new file mode 100644 index 0000000000000000000000000000000000000000..a446d5cc9a46f3043c1873490db4cf2b172fdf38 GIT binary patch literal 40923 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 TT9ho;M{eU}xO0HpUHAPT6Nx=A literal 0 HcmV?d00001 diff --git a/src/icon.png b/src/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cca65eef64d4c23b643eb40d5ba482bd2a983c10 GIT binary patch literal 2834 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 literal 0 HcmV?d00001 diff --git a/src/img/30/Omni.png b/src/img/30/Omni.png new file mode 100644 index 0000000000000000000000000000000000000000..cec73f163e51c7d26bd0bc4caccdf9b0fe296700 GIT binary patch literal 780 zcmV+n1M~ceP)HlF5TT7b7#M$Wwm+6L9+0?Qh(Hk-rs));&C_Q<&3E#pjG z^k1X42VD0?#^yX8xadBnkE>*ENgDw_f~Nhn2VaotB)ePCW4uexn!=WQN-v}oUO=l zGB2r?bHJ3nlu(t=q-FEo@lj*<4@tz$?-XZ%X#{&p1nj>mAhlG$IbRg#eIg1;q{Yo5 z4tv5lP#!}0lNicKPc02W5Y5DaJGE9F>Am-9mmLI9DQRN10VXK zqi00Jwt^rA$MwX3gXGKiUJ>w%n=7Auuej{*=n7CpJ9s0^a-Q%~)1}**&!ddyw_U=n zVgdC;G&+V==1w%)Arc)evF*e#XpK8Uu4%!!aV>%l9m$LTzjDaJbzb>)8a-vM8gqbEaT<~Biz(pb; z)R!lD!+GGJL>j3$Py(H-jlwV&$5$T>Fr!GCJ5`gsHuNdD*(NQh*JYy9Th8*(<4N>m zmApKc*k8$`7|XS+S**SX{43gb*|S9|5}R^)vqX7@7I|d3ky=?oGGV%=PWL+CMEGfA2oAkj4mpTSk!$_(2 zBegbwZm+`T#Ts#O<(PzwmJo`EM7TF12)tNy!D85gt6xC-oPv;SfmbZd@2N0Mil6IQ zFp<~AJ8ow7t79?D>EPhmdS#bRCq4t2EgTjPRCam1bFL%1jl?G5@9zkv=4`0w^r`28FF!D*t1iuObU2yA+f}#Ntf?~y+2tR}E zkJBJBTQe>>W|)7XHQ$5VW))mLy+PG&ln}jbn3U<)<9kw13wi|SEbJAWxH4%37WP$? zk$PG*DE?Lg;|E(Lu%*Kyk}Lh_UkT&%!NBsN<_NzOvFU*|5>r>7fV3tK6{8ZW+!E?M zFX$tekY8=Ou8#FdvTDP$Kx_T8F7vnGgf;XD8(}_&HlC3=L)$yk9kxbiiSDid0000< KMNUMnLSTZkm+Y_r literal 0 HcmV?d00001 diff --git a/src/img/30/Zoom.png b/src/img/30/Zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..d166a94757b86500f5350297a2adca803d947978 GIT binary patch literal 1131 zcmV-x1eE)UP)xLzZ^^qnrcByYg_5@q8BZHX95eQEhSM2`@_c%Nyzif%scN) zNXV=FOioU|)!yD-o|~JiO-V^H<>loWYieqqN+c3-M@L8WtpjIfW?qxYWUUDa2|qFz zjGx$SwkIbi$5>lit8Z*+587b(JhFEs^o@aRLz=Gcz;w)6>(8Yl9ma8a{zY zy=s-(c7A?N&d$z=+wCScn~hj37Gg9S$?`&^xljrNt$@20tflKaz4nDmW6jJzZ zR8-V&0)fzcadClQr^n+VPN&ls?cUy=5B&GDySqy^H#f=3$_gndDLLxx?adDeIxsNs zUU6};COSIWwYIiKuCA`!mzS5v2*n4ZHJMERItVuy3}kC-i)gjl7ohsj0s;#Jf)ANY z<_U;t3sZZ1eC(?$rg(pU|39JsJWzWpsQh$nY|MX^Lu+Ug6BB=FYiqM0@bK_3ASjl> zY&P4(V)1#uLh+8@U>1w@G(A22*S@|!8^T^f;m`a6<8SdurP7Px;bFGl;H<1HC6~+n zMlP3|uwGbGf1!9#d~h61O-vb@bowBmBzEZn*AgerdUpb(7T3N~tl)^ehupnc*S zBLtuWCKih6YZxfh$jAu))@Cxa7NfGV@?)?;Yjbn6b98jnrc$YFFsD5L{F2K}wt_$Z z3Fbq=M03y0&CzdlDS&x=7iKT7rKRP4aJGjsnUt?oD(~TUu$62;?^3WVP_QJ-25mJG ziA34pcoeKdRAgi%1s4$67TI_KD;|r8Uy&V~NQf;PSn?;>1PMg~ zv516(gk%YcY;YW-jAM^IW6#`s=iJlXU$HQbGqx3*MQYpKrBe0xC`!Ut1H)H__|h9C zYkw$Pi*jr3A0KF*{M)l|WurPV3NU`jLq20jaXsvP`@pw*|Frjy544qeujszxz|6^= zK_Tl@&^Ibwnc5puyEKa@#|H4l)c?BM-`EwZcz;>8S7lFJ1Y1U|g5^L2n9&S$Js3~` z0W7jXZT4fP*E;+9h;K~exei5ro^Ww(l(YlIA)Bq%7qMQ&x zBZcjx0z`lU3rays%0&=n5yvBbykXa7;i=b^`*8d2Kj)8beYAe|^69IWkH3DhomI%v zN_0R32?Mso1W+g$c~BZOt~sr2Tys(*5xE@xM!6U)nx*^uH~)5X>yrmJE^U1G()tfJ zyKl9uO)dyn3CP&XVn!ZR6LrU~VhA8XB0C5@_WcQUkwk_nj_WvXYH4?C@55Yf@6E29 z8eKaQC&s%)J4H*O0Vvjy1V{|-K_nRizE~7bRl`9utEzfjkJh{CdOKZfg6ZGOe2+ZQ zhCs>L8q5ePXXFe5fsCdYM4Eul$)D7<0MN`r9qO*`rp#mD+6RnB}5&@uq0df*V1_nnih(#`d z3;|A+=evJ3v&g@tXeyi}_ zik9g`slbJz|BZ}bq)-gcsMh1b;8Mv*$y3r|nG~&_L=`YwDM&r$89NpB56VF=y1IyQ z#Wtdem?sV3*%5F&99AuPQAwV2NvZ7bu3{6Kqct-7q`V08UXPN`3oKcYt%~|VDZ}8E zp*D04vhm`k9X7-S$df!F^<}ZO=tE#v`A*Jj?J|-L%7m%|oMkWP-7+kcJ%Dg&C~!jJ z3eqz(1ZE6|RqpTX_n)G~kSASU8}oG2Olxb|7(yVDn3P$xV303gH9}g;#j5hk3wMWZpryT5IH85o@ zvx*;9eerA;H=FIz`eZWkP=_W`;84&zdZ0KA3}BIx) zw05t5@4^S~y?OO)wO|y?m^CrLgch zRLXDvdha(M!OkBGyN{-?)$8AxE#_tMARm92e>B0*&NXMI@&Cvn&*1Mj_ul<*eq+0w zyfz(Qm|VEG`pKGI->lY0FV9ANY3AFV5AXfy&fO!EU%Wnf`$W|?ubSof%5hT9=c6yj Ze*sozBK+uV)p`H`002ovPDHLkV1jDCu5thX literal 0 HcmV?d00001 diff --git a/src/img/30/brush.png b/src/img/30/brush.png new file mode 100644 index 0000000000000000000000000000000000000000..67b829b20143fba74996168bfc1b710e64d1d33f GIT binary patch literal 820 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%0DsmLU?kmcBAmEiDG5T0W*o)6%bJ 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 literal 0 HcmV?d00001 diff --git a/src/img/30/disk.png b/src/img/30/disk.png new file mode 100644 index 0000000000000000000000000000000000000000..4206b4950305fd694d621fa91f3ddc18acbe1e80 GIT binary patch literal 2586 zcmV+#3gz{QP)FjhXI@=<(NTCEV+_GjgPJvm7`h947N?>)j zy6Xyol6JLv^rrPWfo7I&30L@b6|jBh9KMlUky_pB2OFH4)2wj~>dWf(Hkf`{c`Zcc z3}N@Rz5_!_2+2royxta#SIL&Ll0To}alv)J`A5r{L6!rdu0!u(DnkK0OinX@#Lm3LtGPHmaynSgtRlq74pgt~TMu4DA}`0MXWRT^(Tb1+7JP-DM*|8aB#Q z$?Iy>NJ8iD&r_s;%AiwOf|hndxnXs-t2|dLj6Rc-UYDbnBp%8QltvrV)5Q7HDyNz~ zPI6D%eI3HeFBe`*`_UId;6~(=;CBnIyY;a&W^53fWc7ql%?CPz(Mp3nqJi!+2N@G7 z1dm*EE*$T-3atJx0zwTJ z)Y17&IX%Lg$-7f*Mp6l`^C!D|NOxlT zliy}#noEho`$tlG%xT2*Nt3qJ-{_7AsVGZ;Mo;>?uZGS|b7>hz0`hVRCK~u$I8l48p6c zumiv%2f73E{rj#%%)n=4g_yn>rH+{MR_8ryVF7f}rcE|@0Qkgx$=)LZ#7W66gAD*W zE&nWGcq4#FxSg5{;8XXedTZt)&QD#h2|#>1)mhyKm}fu8u+b(F)1P^Ie>{Xl`91e0 zds94h;Y-9$|7N8+`hbr#vfbGt0wuaID*ES1D{@S*0dz9`a^f6hD}=qy>RDub(=rrq zGf2OE`G0!2bBQ2Sw45S_@Myj?CPLo0M4#R zY9x@r$IL>fp$-5a-y@U`Tm#UtH+kyF7IfUg)J-Jnf9AdPVtprob4*#zR4n4wOtD@H zpzDKs{K*-pe_nc|Rt%uW(tYtP4?y2tA{vcr3|@I=G7=u^zWIa<)u-Ra*Yb1QNaEU& z<}<^sa>(A)sZSbT9y)!o>QYQ+B82(zl+54;6sNh^PY6UI!<~qn#C?iJMDB7;tq1HO zxb7=O4vZR=Txf=i(VpPW`fSH0GKb(kcE|R9^$f%tLi?cxy7fW#GF3O5FbrM|OJ^OtusFc0t9EyM?1lRlCB40et!lD8NChyq(PS%Kye>7`_ zL4f#fmWWakT+jN0B<}aU>&OC3{*7ZbkR@zZuB{cL{j%pj$aLvBuIBFaKH_tM1ILUC z8Jn~W=_#TU&t49POu#4QAB_k|$&!T?w&=v5+0~g5bOB%@`{tsdqd`?PReII!;P2Y+9Nw! zA#}L3xx2yHF!|wQNj#!K8|OGb$$n^<@O$*^_V@u6!I^bw2di!)Y@a!mKByliY(3W< z%w-%2Tc3Ll`@rjjEee2-XJP)U`WscLn1P3@6_}w*YZEXdHlHuVvv$;u zmMYAImit3&9}spp1jBR#q+Ej_GhO!CxLZs`MYH(g#U*oKH*5$3+cEQi=qum&~R(8(HCnpErU5oGa zSwZif&Org`g16OdL8S)6Za?dW`R3O$5;O9hZw_F_9K70$x$)$s9?VzImMbt{S}O{~ zrRtv{u0z+ed9D7GJE9=Kbegt?5k34zkMj(9WZ|Mm@;tiiv_5_hWx6&>^*QUCvYpRw zG1+(ZeGfaM*+wXYv2fFgfK;wdVYDhV6-Ty`+G1-?VO< wWSLlP!hOV>fPyEOjR_v`y-7XuUnbW16DhY1e@J5|+5i9m07*qoM6N<$f=k^Jxc~qF literal 0 HcmV?d00001 diff --git a/src/img/30/eye.png b/src/img/30/eye.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f292e13d63adef03bd4b0697afb40e5dfd06f2 GIT binary patch literal 1380 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 literal 0 HcmV?d00001 diff --git a/src/img/30/modes.png b/src/img/30/modes.png new file mode 100644 index 0000000000000000000000000000000000000000..3aba3ce90ffefeb0788f065e5104022c9acd1d60 GIT binary patch literal 3467 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 literal 0 HcmV?d00001 diff --git a/src/img/30/move.png b/src/img/30/move.png new file mode 100644 index 0000000000000000000000000000000000000000..9846f049f2f75775d35cb1f06024ef0ddb7f7d81 GIT binary patch literal 1474 zcmV;z1wHzSP)zRG&zbMyMj#NLSwiu+_!-Vl=c*8Z{eKUHh9WD1b)^4p(41yw50oiHJL`? zoQAmKHY~jfI7}^v7_|8T6B^ompaJq&F>o`~E2=Q>3NX9*Pb40?4QqcRgj+^!ca^x0 za7?{sH>MENYJSDE+Piq|%bzjl@&klyZiH}1QP%sN?kMqg;i*S-ek*2NxQE1px5)M< zOg{DtW;Wb|)2ss!L$-n{_v|`Qf1_5Y(&3j}Plif)Z()4JbxhcQ1LMut@y6NTka+Yq z>>~3ZJai>p2^_)oh0}C1TxRb_RCWsz58ou{HB98_{r+jV&a6QHxSbGQhMFz_l>BL< zE#Cv>)xs&QNm$dNNuW`Ik8%1sE~PzV2ys-XR(y3@ik8W1TpAtI~MG6rw_n@@6wjZ8m}F}ar!yXPvm z)*9H3`U1k)vbXDqXRQcm9+|>Ewvd5U7?b}E0UH_k6-I75XZaqL(~MWLo0$-eW4OM- z^6ZgCNEe^<+0o$>$~nSxOd#(PMrB=qYQ7o0gG@^GOoAU0TL7*LDiB@tH6o1X5wfM0 zrS7m1sdZFwJ?-&0VryN;vy{50_|$j$D03;##}+hW1n>7%m}@dyls0i8>rx7btP7xB za}wd1XEA(JHP^C=foBksTEmHI5VG}*WeooOG=erfvVZ%8Jn~_DXnHM1X4JuLkr~z$ zozP_6C1&j7b=FGDgsbj%D}RaX%b8`h#T;jrVnB2r>=TM$A72RjafRG4jv#2`DFm#o z0%!hb-N6f3T|0 z@B-0FD}=k@ey`B&=o67cB}xZ6jyqBqCxF}HecZPX!~27S@J&910prL>omtfpE33GH zpkI__EftohNXX}T-o1Xp+n7i3RZ#wF{_Z7wjBAu$RV~;{P&2$%mBV|r8FsO`5W^@K zt*m_rzLslwh)FK~zXt$YX5D6`<@V_-!Fld3s8^N2V|fYGE6ZRPO?F;JSShU%K+rC` zv~mK=jDeH$;F44f)uLj!E!oYI@3M@}^LN5&ZV_xEvbjArmVcv<(Js{`cG3Q)hX5(ZB-DuC>B`ApCJo6yR7wim32OA4q`;vqfv|4A!vCulW6 cV_qcuFZO9uyCdk38~^|S07*qoM6N<$g4&eCMgRZ+ literal 0 HcmV?d00001 diff --git a/src/img/30/moveObj.png b/src/img/30/moveObj.png new file mode 100644 index 0000000000000000000000000000000000000000..14c53d1aa2a32b331730cbffc51c7b07831639ba GIT binary patch literal 1193 zcmV;a1XlZrP)YM9rOFk^OP^_9nq`rH%4!PR>Le>Gj{`*1Efx_Mjg>}oSEEW~!`MkC&s zuh(A9YY+h(#9DD947uqAbSLiJoVB$9EsK){b$M^Ep4wZ~iyeVaeKd3E`0HPv9X~qG z{>Qemf4o30v6NRMew?k+Y^4ZL80{fn3`ng|uS3+bWHjVM$ilNP_38IJs&Upg4L>8S zet(0HXP5cr;Xw}W-^7uTF77P1n2A6O^lB(6!L=@F2DS+%bQxYU{v)Hik?wNB`CW z{R1KSZl87wtkqZ?ZBbyLl|Z9mF#@3{Xan}HzyL~P0*`E$N3IZ%%?EUa9!fbfCMByC z*^H3lNSvb@JIva7@e)X#^E*$q6D8W<1)3n#1ioODpcLpp5g8#=LVvinzZ%0zv<6Ob zc)kMXGMz`P6!-@1X_P3e6$EG`kjh#Y{93WpVxbr+8i^xCusE6)nkgux^N4X45rqTd z#FC_r)nWZ?4dYodHVYLbUJwiEkT&`HUvVy18zL_CyMtfAUZg8r#5~WBNs;rb7 z*Rn_((geCZg;5Y&$a*l` zt5{8#>JQ|~ra;x#byvSRpB{NIaMNcO+cU8-C>&AjxV&VkBq@bnh4MV&YK#$RAXFpA z_5gMkHEjfd#KA;P*N+W*xpmceX0f*Ie9L|kY5`(ejhKtG3QBqWC_)AenO=kIQY_R` z;&OapkJt+@3}^~qt9#I%giPJ|0MqN;NJ%TB7Ew3=>FC100000NkvXX Hu0mjfvW!45 literal 0 HcmV?d00001 diff --git a/src/img/30/plane.png b/src/img/30/plane.png new file mode 100644 index 0000000000000000000000000000000000000000..bf99811c244aa3b2efb2e68de6f466fcb739eaa0 GIT binary patch literal 2817 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 Tkk}>+00000NkvXXu0mjf!$@dr literal 0 HcmV?d00001 diff --git a/src/img/30/pyramide.png b/src/img/30/pyramide.png new file mode 100644 index 0000000000000000000000000000000000000000..04066f5a7bb39730e3806ff1fb99f60ec36a8640 GIT binary patch literal 2958 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 M07*qoM6N<$f^2|=u>b%7 literal 0 HcmV?d00001 diff --git a/src/img/30/sel.png b/src/img/30/sel.png new file mode 100644 index 0000000000000000000000000000000000000000..756ac42ddf0bf2b5983b6cc864550acf667daee7 GIT binary patch literal 1115 zcmV-h1f=_kP)9uI2c3;j!Q*cs6T|bj7xrv;}1mU~ z5kqtk7Zf8}H{xE6#Sw{?k)kN>YxK-L7aoM-tG-Ex`OyR6=G}YW{qDKvyWctQ$&>Hi z8X6j6*4EaZ>GvfjCdxB1G9;CimG3MqEp>Bqb1zLyOdvl$|2L^rnrvfZb2vUeZo}j8 z09$WwZ%tugp*Sxu?{{-^b5N_*uZZcatgOyhfn#D~6tS_firLxOS4>}IWaOW?A^bl* zJ^iD8i^j~Inwp}0OG``7nX#Ff89uhn&CNpG1S@cSe0+OEL>p7Zw&?U?feBqZd$TrQ`;x3{-2GBN_B50Fs*=}`v-1x>cLwo>4`yF1Y7 zbPyaI46d%O+Re?)AO0;U^5v`K3J3^L%VaVNd~!6>X-+W6;3kANqx}v}A>}(hu90Zk0g)#5cziN-Qjg5_`B9W+ub%L+2?^0u9BL%*= zxPZ&cOX%$E1dT>R`?|WiAT2FTIx#U}^-Yi3$H(VGeSJLzIXgRp^Ye44tE+>_$w}%x z8j>$3C#RI00H!6E^i?+PHoW>A^#LLSINScJez(Cm9*@2an z75Yq=E#P{W%gV|`tbtwY9YgNCkon2CY_0MI=2vT}ov1CobTaVp#`^i;I7aii%PauZ2t> zdWY&|WMl+{B-CqCsX%gavh15F*L~K}(eX2qDLOh@iIoX?hNPqP0x6vroidE5y zcO!~bEI7Op@Av!t(y||g!310Sr}W3W=ZG02-8gxIw?g ztu3*|%ON2lug1s6e>8okdIkgpy#E-7lwQJ2^W$|IMdMNJuE7$8i*Ob#<`-2XBoH27_R<1Eg{b;1cid?sA!nW+@{6na{|> z!{Z&umFR1XaeUBniVaMCOH_Vz@_Wb;dWd^|fiI8cFR(+&?0y|JCxOC%D808)63 zDb+~Ff6P@?RdpX*$GMLI7tLE_j^TWZKMCr37mk1Xpb-s;iHV7$A%SVbPJ?P%cWD2D z({I2z&S=GJCmOZ4x2ut!dGwn*BDX$mOC={K_n|}Fu|V7vWFVKznN%ueAOWV=>z{zd z#03As!onw{r+vvZ)@ZpyDYPcyp^b&=8x$1uS|k#&uCA^C!I6fAh5e;csTi%PTCMgO zcBD&1MMaO()6<_F_o2}g1OQ~j6naeUL7xG_JG6C1MMZ5W6bfebIiG(4EL0>BwcJi7 P00000NkvXXu0mjfi$)P* literal 0 HcmV?d00001 diff --git a/src/img/30/sellist.png b/src/img/30/sellist.png new file mode 100644 index 0000000000000000000000000000000000000000..7b859f1e8a91d880c83addb6dfc1062f4cbe99af GIT binary patch literal 1028 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 literal 0 HcmV?d00001 diff --git a/src/img/30/tex.jpg b/src/img/30/tex.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e8403154f8bec6775b79bfebc2cec26fc798d85a GIT binary patch literal 18411 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 b!TPkITlj}fmT-2W$skgvpKeDzDGdMF*wI*j literal 0 HcmV?d00001 diff --git a/src/img/30/torus.png b/src/img/30/torus.png new file mode 100644 index 0000000000000000000000000000000000000000..f62bca32c0589ccc9ede106bd11f1f00fefc41cf GIT binary patch literal 3063 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 literal 0 HcmV?d00001 diff --git a/src/img/60/Omni.png b/src/img/60/Omni.png new file mode 100644 index 0000000000000000000000000000000000000000..5802cf88e58ec1e20876569616365579afbb1809 GIT binary patch literal 1854 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 literal 0 HcmV?d00001 diff --git a/src/img/60/Zoom.png b/src/img/60/Zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..b56e7b37fb8efbfc055dcd93bf63ceb8f913c591 GIT binary patch literal 2806 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 IM6N<$f=4l3Y5)KL literal 0 HcmV?d00001 diff --git a/src/img/60/box.png b/src/img/60/box.png new file mode 100644 index 0000000000000000000000000000000000000000..ceb00c9196276ba0f7a76b83dfa002834718635f GIT binary patch literal 4249 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 literal 0 HcmV?d00001 diff --git a/src/img/60/cone.png b/src/img/60/cone.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b464d3fd8e5f9f12741ad310b707b9c0ac2269 GIT binary patch literal 10696 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 Ef{zy(xc~qF literal 0 HcmV?d00001 diff --git a/src/img/60/cylinder.png b/src/img/60/cylinder.png new file mode 100644 index 0000000000000000000000000000000000000000..f398b59f8d6c97d826248ddff9303489101019c4 GIT binary patch literal 11965 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 P00000NkvXXu0mjf8PLrL literal 0 HcmV?d00001 diff --git a/src/img/60/disk.png b/src/img/60/disk.png new file mode 100644 index 0000000000000000000000000000000000000000..29818b52deda1eb46736cdd1b4fa1ced8c355edf GIT binary patch literal 7520 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 afqh&%MHX{8#{ZgA;FW@!e3>jF@c#fg_HOn7 literal 0 HcmV?d00001 diff --git a/src/img/60/eye.png b/src/img/60/eye.png new file mode 100644 index 0000000000000000000000000000000000000000..c9f3e8933f04a58021a360a96cab1d3831c5b205 GIT binary patch literal 5314 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 UhB}`84gdfE07*qoM6N<$g2#|ED*ylh literal 0 HcmV?d00001 diff --git a/src/img/60/geom.png b/src/img/60/geom.png new file mode 100644 index 0000000000000000000000000000000000000000..7a900f36fbd82cc24fce9ff4cb118aeb8ca50087 GIT binary patch literal 4678 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 IM6N<$g4=Hsu>b%7 literal 0 HcmV?d00001 diff --git a/src/img/60/modes.png b/src/img/60/modes.png new file mode 100644 index 0000000000000000000000000000000000000000..44ece9b6c59e3b6ca6c8ff6987c197bc2f404e2b GIT binary patch literal 9294 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 literal 0 HcmV?d00001 diff --git a/src/img/60/move.png b/src/img/60/move.png new file mode 100644 index 0000000000000000000000000000000000000000..5217e8b8a3ca5654bbed3267dd17ad15917aaa78 GIT binary patch literal 1599 zcmV-F2Eh4=P)({LRpWf$O&bjYB_kHg@*MROhcDK*&?)$v&`#j%! z-gD0TKIc7NUjKg<;1kjKEWspvYg}j?;RXRHZV2TX6?{!5R^*x%#TJPI7sWI~{PAhw zn-X25C9w(g5#3ld3V9=clkYM4kxtNx;0aNbUv?+t4&4UB7k>%g_?r?up#`yJ(ol|l z4>HWRz%YDU0)JyUCAv(_Vw3418(H%eANB4v)@5K_=f{n zj&@4$lp4iWhyw1}WF$lPCgcqK#s%$Ij}l#>Cb6mX5RE!A4%_>GbqUs!4eb=Q2%Z*$ z_Rq6G_QhWyyH5e69@eJ>Ppd)fE7DMoYk~9+W?)kbaV#_B5)Pn`S~p6a>9 z1?_ZwY)=WU_f)}IoYfFS9vOqouA5xY&TA|5>%r&od8Xi3M`26H3>UO>#GdyQVao_P zgjzxd<4EK1HcKm{nk$fQ{(%eHDUs&c_F1xiGiLqi7xqFH(OAVe5?zdXHo?_jLYnD& zE@-zC?ATWq!)Nt;3r(db6$~6Z3}`92r25L z%W8RoHyj>;l-6&!pxue!TG597box$~@QS$-nj}xWEhdxv^)C*==96DT=)pnSX^RX= zaCqggP@f0dW#_QGFTsZXus-@nnz&HZ0Jtq#yJrw!t_s9!9-VcZDVruG5`hR$^`0r;ywy#(=ZkE;%h z8{?OWo}|T=hz9SdCRkN?0X7{Qg}CEmss-am9jJ#AT_Or@7YiRM>4is+UDXVzhZ5Y* zJi@^R7Kk}|31Z*8tXeRB)WJT&jC0s0wH3k-4?y(mBdP=A#`yW?Fz+fIO^)_H3rW=s zLsXp#AaP>67`N-Iw3GX=Pg*O4Rek~ywSx|X9_oYOLW@hnD%kBs(5|E(^v7&Z;=?$V z--lhzw8*_JsGy6iTL>2_jW1@G`O%^YQqBUO8P;6VjGOZmwi;r=XAA%Gq9k74hVngBCOnVPSI*9cz>r* zp9k8Ntd`Ip)<^%c2kLXMT5_=-_DydEoxwzx)$!KDfh54N%8$9A-N|~mPFjN#f9QAq z*2C^)JTke0_nOHC=R+=NcOp1*;WHlg0n{)YTb$*z0(PH;wa@o(LA#5bmWAQ7W+4-K zI)Y(#xMjM^S_bSg!J6l~xu9J^)-rR}pF!~N$$4r2o$c^&X(t!7dv;#h%_k2l^4lP! zZt*60He?}r`zX={JKFbB|bbV~EhG$C#G06Kj8)5Y`raK1PQ-Tei zDp*Gk#pT;i!KwpoZiDS)Lt5v_=dpCl@+Pa6fIY1cRCq=)Sl`=zwNvBe@gHh(a$iz2 z1nxVn7_6_ZJsyl*JWI2Tu=43sF2Q=Tp`7Zanh!Pi_KqTR;Cv$)t}R^9j`h^JPs=7+ z+KG2>LKFD!HgZ9`x_9DP1>5bl^v!636}y@pz;bQuwX}+scGG%Cl813QO`zLh1Ak+= zHg?n6L{Hc@tC2m^c_+Xx-wOWL)_!TLV7ndhOHznfLjx>HJ)zMZ@mA5&I}cuD2>YZr x2;bU#=fNiWE_$oQmh8Wa-dnN>|Igk``v>4a)QC-#kh}l@002ovPDHLkV1hp|5V8OO literal 0 HcmV?d00001 diff --git a/src/img/60/moveObj.png b/src/img/60/moveObj.png new file mode 100644 index 0000000000000000000000000000000000000000..1e07946d3f366332d953dd7d137e9bbba14b27a3 GIT binary patch literal 3611 zcmV+$4&?EPP)#7SVn|K>C&{)Y1qF6$;Rz0uhA}h30{i*s+~BPR8Sz%W6d3E!Zx& zcoGWU(rBcsnX~VIum4)>|6luvyYqvzlpnBl1@INXR{&oDdy~2$?h9kiLAF1{m6CG`P%n&gg;Jz3{KP`3Csyh`Pp;Wja|7G{Y;UlAt*+mnh@8JU z@LUugl!66Mm@)grfz%(nwk40=G!^c9^EK@UzNY|x<(YEZQ!DjVPj`LiYVBhyCS%W5 zHnV8Fdyof4>j7KJKB{ujX9Qpnl%wqq3t5I#M(i0$zy8Folv6Xx+`d*gddp0>_tstc ziRTsYNAEv-^QTVn<9l{b98d6iwO@~|*7oO`Dw+a`BAH-`QV&XWVHLj3^Tiwis-VnI zj#3pF!6CR4YZ#P~!NACo59Q|lX_bYWru6;;qv5fwnVfm)maw#GfZy{^PrT!I|L)Pd z4&5@#%Wm4u-d!Dbc9gnwdTvw#QJ^&ExzkJ3g9=eWF0zFS47Q9wmLMviN=yVbkSMr0 zGE9Z_3f7`gM@Zet9WwJjc=L9>`=@uNU)hvC+(~sUtSzzfwLYIc_B2}#?qvU=9UQu5 zoP$$=T)=P^)@oYYT7~2sqc`+!>iuR&OLH&~5hMg83rHTwvOq`_?e*wC zah5MG_c^kAj6*v++_p8RlO=>a;afYCJM;&R^^LYciZW2A$ekn+RGeBIGeHrAjr|?f zh9Q@L_5T9c5Ze%FN(f3wQ$mrFv=fSUN?s%s1?1g6PtL=~qA?K^%>#ZuqcIVRM2XP> zBU2&9Kv_AeinxIo8WaVB3gKLk1#{EQq_ny<6l$t!K+-^(CuFUZypvOmrnEXKolZ)p zm5^aX1WzuI!3LFss^H#4yfTOeZh}MzB8Uj;5Y%v22twix-W=K{x+QOV2_T|KqJ%V% z6e(#dCvT?|os@Pbr!^ADa;23gD8kZ(1fxLZLiBG|UybZE97j|LE~G)4gBFMi<{O9P zn@Q>BR8>F(Gz5}V30WY`0(mP?v{H&zlh;`mNYVsB&`_Tj3>i{-5RGh@ixH<1CpwrZ zL`cNI1xJz4P{CaArf?;jN9m1%sEUNp2O_d~5(jm~0C?OFD zO}|W4$qJ>8&UmV{GayXC1TVLWo!h9(6k;$FmWUbs)D%@UC_-0EGRAt z3KE2nY=BdeLRm3y{%5%%T_XpnQjLSXo#XmCV1*Kb7}PPYVB3T(z= z&sba+)SMh6Q$?kbm2pU$=ujc&C?quuf>1gXo7smOUu%do*3O4^FxKF;Q%57#N_1y+ zy(Ef|7AetPTXNXwKSlO|6i%0~#ZW;yCJ!WQ>(luQ~m7W7&l)Q>wc0 zz-v8N?;FuJMnFy;ph$&0K$Zw0IGtRXFP&}CZ{R?>S#8NpiAXeJbhLK7jKnNbdqQ0s zEAu^2rI^Suz|@GU3|1;w6M7|dyOH&1tRzOYToI~(Bnc$a^xdI5*fB0Fb)AK-6M!T@ zqDGzy<85cLa;AbOn_8t^!Mri1UO9DaT$A=|Ru@Y`mQYNjlxr1(^_tp+vdCCo=@Zl_ zM-$3PkhY>lhV+bTu_i9`DOVtp;7MS|xNzMLr#9u-yz|sqr>dJuZP6(!qbvoAO*9WK zst&jt5)Jo&8^nbk>uVLA={9EY^g~@@o>H}PY-q5^A`9e`37I#C#Q;1B$c&Oq z8QDrrZ?3}nHT$M>90&pjw+q`woTGCvzp~+voo;1VDx0XZf>_8hk~Bxmi3_W&KV4I< zR(BA5B;-5V6gzX;+cQ`kpp~GNV*|q~a32o%#POgo-q_2ltH?yo zITsZTrbm>q7Mxlzj?FpUzSA2(Xk#CGs(jsx$HF7GjE7T~Il`h=4j9bMQLk2%wK5nT zCD}g4OJ28^i5(+EGk*A0Gdz5Hz|$2-u>D;khBxOt-$qa)G4XpDq7g&MO#NxaeA7jmaKbPBj( zR+%12$WvipaC#7T!nd#1m&E@!-oEdX*WSM8o-=vtM7?u6I@#gnubAP${!!}M&a;u% zZb`XrG>}%{gNT)}@y71W0Nxtqq|wnzh$Soz8n+bW;^QhC3Z6Y%m6>q?gR>P|KED|E zTvot`U;LsoM?UzLANz$@j^7neJ^RQt2d6o7{nT(Cb-s5NX|%IP!ApaBI9T6s7v9KK zhQ8MfjxQMxE<_dw&5gwWa!W%MoBURR=ziy;Jv(^WDE;Y$`rvZq6F;*({qjeC>6O2? z=g`R$kB^N1tqAAk8#MX0ux32G;MjCim0dv+fm#qzTphu1(dK|~RA9M;ho6h=XbZbK zN|DGpA#$;msqknw9)R@Imj!TTp8d<&`t{FMHgWT0`eog}%R1fao2Yz_HVSJ!Z{!79TOMbn19o&=DH#KvFS#&D1!)q&FkXTCCKQkZEq#y^#dQ+2sw;@=kI-q%cp z;l8sa(JxFl6{u?GffF?=1Eolt0lxJeZ#j|%G_MYg+eiJpb)qT6k|i`g!|rRFQ|)fNR^|J*C&W)yV2{k3=tgv26}%;LlnMz4fm@ z6yG|1!|eXa(SUmm=6Gdz6eNS-f_XrIBsfu&ZqGP%dO*HZ-TUg6fANl&w?2H^Z0qR% z+~;qOEWi5n+4Y?&8}6x@l=zTsjjg;)MQgQNjx0adCl7L=$qy>Z#j!Ht5|F(4Vp&@-73P+V`I9B1XZ!#9lOufQ7Z0~Tc*FMm zygT17Jh^t&Uw&===cD=CNAo}{(LXH`?YC0twbQUZk%y(N?Qmwg70zB3z};>&(p~LS zUjT6JFqQ{y-P!qffOo!b?`IG1TfFbrKX&SUpSy4T_G@o>(H;o_cgS1dE#<^Bk@=(R z5A0j5j{eHlaQ9np?)>9{tyy`o{Zpm9;9$xrBk?I9UKW5JCWd5PwzHRrNui86yPU5}yACA8LPrkvgbtBj9zi}LSyCl>sUKmPow{&+F_ zJ1^PMSpj&@PwoG!o4z`C-*0^M#QUB(neY73>E1m*F)4Td?5z{`@&c^y81Nu^QJJH) zQAMYf>OEIa7f;Sk6(?sWixabx`IEDg`H9^V#i_mDLbW#@o_Xkvhi6{@*<;=Px9@8o zZNRU`@YT#3igs;YWaRxS6&~!0{9Bx hD}b*6{$5`HH2~eK9XVCS2+RNg002ovPDHLkV1f*l{|Nv9 literal 0 HcmV?d00001 diff --git a/src/img/60/plane.png b/src/img/60/plane.png new file mode 100644 index 0000000000000000000000000000000000000000..af3d770f36266c898a68070f551805c8a76f0281 GIT binary patch literal 8772 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 literal 0 HcmV?d00001 diff --git a/src/img/60/rotateObj.png b/src/img/60/rotateObj.png new file mode 100644 index 0000000000000000000000000000000000000000..5c4db4dc86393b76734bfbe08b939f0670c66827 GIT binary patch literal 3700 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 literal 0 HcmV?d00001 diff --git a/src/img/60/sel3d.png b/src/img/60/sel3d.png new file mode 100644 index 0000000000000000000000000000000000000000..725edce5c00b59faef8bf63eb74393399ca715bd GIT binary patch literal 4552 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 literal 0 HcmV?d00001 diff --git a/src/img/60/sphere.png b/src/img/60/sphere.png new file mode 100644 index 0000000000000000000000000000000000000000..0b1095b675525bd6a5a4e37afbeb4868749b446f GIT binary patch literal 14916 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�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 a{|*32By7xL6qz#s0000