commit b64448bee54305949356e688dbb6f796ddda6163 Author: Victor Date: Wed Nov 14 19:14:46 2018 +0200 Initial 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 0000000..d64f244 Binary files /dev/null and b/libs/Adler32.class differ diff --git a/libs/Deflate$Config.class b/libs/Deflate$Config.class new file mode 100644 index 0000000..bf9ff11 Binary files /dev/null and b/libs/Deflate$Config.class differ diff --git a/libs/Deflate.class b/libs/Deflate.class new file mode 100644 index 0000000..50794d6 Binary files /dev/null and b/libs/Deflate.class differ diff --git a/libs/Encoder.class b/libs/Encoder.class new file mode 100644 index 0000000..5f05702 Binary files /dev/null and b/libs/Encoder.class differ diff --git a/libs/Gif/a.class b/libs/Gif/a.class new file mode 100644 index 0000000..613321e Binary files /dev/null and b/libs/Gif/a.class differ diff --git a/libs/Gif/b.class b/libs/Gif/b.class new file mode 100644 index 0000000..2ac6e3e Binary files /dev/null and b/libs/Gif/b.class differ diff --git a/libs/Gif/c.class b/libs/Gif/c.class new file mode 100644 index 0000000..c049fa4 Binary files /dev/null and b/libs/Gif/c.class differ diff --git a/libs/JZlib.class b/libs/JZlib.class new file mode 100644 index 0000000..a036122 Binary files /dev/null and b/libs/JZlib.class differ diff --git a/libs/JpegEncoder$DCT.class b/libs/JpegEncoder$DCT.class new file mode 100644 index 0000000..656153a Binary files /dev/null and b/libs/JpegEncoder$DCT.class differ diff --git a/libs/JpegEncoder$Huffman.class b/libs/JpegEncoder$Huffman.class new file mode 100644 index 0000000..e2bd3a1 Binary files /dev/null and b/libs/JpegEncoder$Huffman.class differ diff --git a/libs/JpegEncoder$JpegInfo.class b/libs/JpegEncoder$JpegInfo.class new file mode 100644 index 0000000..8cddb3e Binary files /dev/null and b/libs/JpegEncoder$JpegInfo.class differ diff --git a/libs/JpegEncoder.class b/libs/JpegEncoder.class new file mode 100644 index 0000000..48f579d Binary files /dev/null and b/libs/JpegEncoder.class differ diff --git a/libs/Lib_gif.class b/libs/Lib_gif.class new file mode 100644 index 0000000..461da95 Binary files /dev/null and b/libs/Lib_gif.class differ diff --git a/libs/Lib_jpeg.class b/libs/Lib_jpeg.class new file mode 100644 index 0000000..0ccf642 Binary files /dev/null and b/libs/Lib_jpeg.class differ diff --git a/libs/Lib_png3.class b/libs/Lib_png3.class new file mode 100644 index 0000000..8818ef1 Binary files /dev/null and b/libs/Lib_png3.class differ diff --git a/libs/StaticTree.class b/libs/StaticTree.class new file mode 100644 index 0000000..6baf9d9 Binary files /dev/null and b/libs/StaticTree.class differ diff --git a/libs/Tree.class b/libs/Tree.class new file mode 100644 index 0000000..b3fc347 Binary files /dev/null and b/libs/Tree.class differ diff --git a/libs/ZStream.class b/libs/ZStream.class new file mode 100644 index 0000000..afb48d5 Binary files /dev/null and b/libs/ZStream.class differ diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..2e961e7 --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 0000000..82ec708 Binary files /dev/null and b/src/examples/cubes.s3d differ diff --git a/src/examples/home.s3d b/src/examples/home.s3d new file mode 100644 index 0000000..c6ebcf3 Binary files /dev/null and b/src/examples/home.s3d differ diff --git a/src/examples/logo.s3d b/src/examples/logo.s3d new file mode 100644 index 0000000..a703d9a Binary files /dev/null and b/src/examples/logo.s3d differ diff --git a/src/examples/tank.s3d b/src/examples/tank.s3d new file mode 100644 index 0000000..a446d5c Binary files /dev/null and b/src/examples/tank.s3d differ diff --git a/src/icon.png b/src/icon.png new file mode 100644 index 0000000..cca65ee Binary files /dev/null and b/src/icon.png differ diff --git a/src/img/30/Omni.png b/src/img/30/Omni.png new file mode 100644 index 0000000..cec73f1 Binary files /dev/null and b/src/img/30/Omni.png differ diff --git a/src/img/30/TargetL.png b/src/img/30/TargetL.png new file mode 100644 index 0000000..f08f876 Binary files /dev/null and b/src/img/30/TargetL.png differ diff --git a/src/img/30/Zoom.png b/src/img/30/Zoom.png new file mode 100644 index 0000000..d166a94 Binary files /dev/null and b/src/img/30/Zoom.png differ diff --git a/src/img/30/box.png b/src/img/30/box.png new file mode 100644 index 0000000..61e58ff Binary files /dev/null and b/src/img/30/box.png differ diff --git a/src/img/30/brush.png b/src/img/30/brush.png new file mode 100644 index 0000000..67b829b Binary files /dev/null and b/src/img/30/brush.png differ diff --git a/src/img/30/cone.png b/src/img/30/cone.png new file mode 100644 index 0000000..0474ff8 Binary files /dev/null and b/src/img/30/cone.png differ diff --git a/src/img/30/cursor.png b/src/img/30/cursor.png new file mode 100644 index 0000000..bce3256 Binary files /dev/null and b/src/img/30/cursor.png differ diff --git a/src/img/30/cylinder.png b/src/img/30/cylinder.png new file mode 100644 index 0000000..85ffa6e Binary files /dev/null and b/src/img/30/cylinder.png differ diff --git a/src/img/30/disk.png b/src/img/30/disk.png new file mode 100644 index 0000000..4206b49 Binary files /dev/null and b/src/img/30/disk.png differ diff --git a/src/img/30/eye.png b/src/img/30/eye.png new file mode 100644 index 0000000..a7f292e Binary files /dev/null and b/src/img/30/eye.png differ diff --git a/src/img/30/geom.png b/src/img/30/geom.png new file mode 100644 index 0000000..a372d17 Binary files /dev/null and b/src/img/30/geom.png differ diff --git a/src/img/30/modes.png b/src/img/30/modes.png new file mode 100644 index 0000000..3aba3ce Binary files /dev/null and b/src/img/30/modes.png differ diff --git a/src/img/30/move.png b/src/img/30/move.png new file mode 100644 index 0000000..9846f04 Binary files /dev/null and b/src/img/30/move.png differ diff --git a/src/img/30/moveObj.png b/src/img/30/moveObj.png new file mode 100644 index 0000000..14c53d1 Binary files /dev/null and b/src/img/30/moveObj.png differ diff --git a/src/img/30/plane.png b/src/img/30/plane.png new file mode 100644 index 0000000..bf99811 Binary files /dev/null and b/src/img/30/plane.png differ diff --git a/src/img/30/pyramide.png b/src/img/30/pyramide.png new file mode 100644 index 0000000..04066f5 Binary files /dev/null and b/src/img/30/pyramide.png differ diff --git a/src/img/30/rotateObj.png b/src/img/30/rotateObj.png new file mode 100644 index 0000000..4a656c8 Binary files /dev/null and b/src/img/30/rotateObj.png differ diff --git a/src/img/30/scaleObj.png b/src/img/30/scaleObj.png new file mode 100644 index 0000000..f40f877 Binary files /dev/null and b/src/img/30/scaleObj.png differ diff --git a/src/img/30/sel.png b/src/img/30/sel.png new file mode 100644 index 0000000..756ac42 Binary files /dev/null and b/src/img/30/sel.png differ diff --git a/src/img/30/sel3d.png b/src/img/30/sel3d.png new file mode 100644 index 0000000..b883b60 Binary files /dev/null and b/src/img/30/sel3d.png differ diff --git a/src/img/30/sellist.png b/src/img/30/sellist.png new file mode 100644 index 0000000..7b859f1 Binary files /dev/null and b/src/img/30/sellist.png differ diff --git a/src/img/30/sphere.png b/src/img/30/sphere.png new file mode 100644 index 0000000..fe2ca78 Binary files /dev/null and b/src/img/30/sphere.png differ diff --git a/src/img/30/tex.jpg b/src/img/30/tex.jpg new file mode 100644 index 0000000..e840315 Binary files /dev/null and b/src/img/30/tex.jpg differ diff --git a/src/img/30/torus.png b/src/img/30/torus.png new file mode 100644 index 0000000..f62bca3 Binary files /dev/null and b/src/img/30/torus.png differ diff --git a/src/img/30/triangle.png b/src/img/30/triangle.png new file mode 100644 index 0000000..e097a4e Binary files /dev/null and b/src/img/30/triangle.png differ diff --git a/src/img/60/Omni.png b/src/img/60/Omni.png new file mode 100644 index 0000000..5802cf8 Binary files /dev/null and b/src/img/60/Omni.png differ diff --git a/src/img/60/Zoom.png b/src/img/60/Zoom.png new file mode 100644 index 0000000..b56e7b3 Binary files /dev/null and b/src/img/60/Zoom.png differ diff --git a/src/img/60/box.png b/src/img/60/box.png new file mode 100644 index 0000000..ceb00c9 Binary files /dev/null and b/src/img/60/box.png differ diff --git a/src/img/60/cone.png b/src/img/60/cone.png new file mode 100644 index 0000000..b5b464d Binary files /dev/null and b/src/img/60/cone.png differ diff --git a/src/img/60/cursor.png b/src/img/60/cursor.png new file mode 100644 index 0000000..e9b0339 Binary files /dev/null and b/src/img/60/cursor.png differ diff --git a/src/img/60/cylinder.png b/src/img/60/cylinder.png new file mode 100644 index 0000000..f398b59 Binary files /dev/null and b/src/img/60/cylinder.png differ diff --git a/src/img/60/disk.png b/src/img/60/disk.png new file mode 100644 index 0000000..29818b5 Binary files /dev/null and b/src/img/60/disk.png differ diff --git a/src/img/60/eye.png b/src/img/60/eye.png new file mode 100644 index 0000000..c9f3e89 Binary files /dev/null and b/src/img/60/eye.png differ diff --git a/src/img/60/geom.png b/src/img/60/geom.png new file mode 100644 index 0000000..7a900f3 Binary files /dev/null and b/src/img/60/geom.png differ diff --git a/src/img/60/modes.png b/src/img/60/modes.png new file mode 100644 index 0000000..44ece9b Binary files /dev/null and b/src/img/60/modes.png differ diff --git a/src/img/60/move.png b/src/img/60/move.png new file mode 100644 index 0000000..5217e8b Binary files /dev/null and b/src/img/60/move.png differ diff --git a/src/img/60/moveObj.png b/src/img/60/moveObj.png new file mode 100644 index 0000000..1e07946 Binary files /dev/null and b/src/img/60/moveObj.png differ diff --git a/src/img/60/plane.png b/src/img/60/plane.png new file mode 100644 index 0000000..af3d770 Binary files /dev/null and b/src/img/60/plane.png differ diff --git a/src/img/60/pyramide.png b/src/img/60/pyramide.png new file mode 100644 index 0000000..62225f9 Binary files /dev/null and b/src/img/60/pyramide.png differ diff --git a/src/img/60/rotateObj.png b/src/img/60/rotateObj.png new file mode 100644 index 0000000..5c4db4d Binary files /dev/null and b/src/img/60/rotateObj.png differ diff --git a/src/img/60/scaleObj.png b/src/img/60/scaleObj.png new file mode 100644 index 0000000..5ccecab Binary files /dev/null and b/src/img/60/scaleObj.png differ diff --git a/src/img/60/sel.png b/src/img/60/sel.png new file mode 100644 index 0000000..cca36c3 Binary files /dev/null and b/src/img/60/sel.png differ diff --git a/src/img/60/sel3d.png b/src/img/60/sel3d.png new file mode 100644 index 0000000..725edce Binary files /dev/null and b/src/img/60/sel3d.png differ diff --git a/src/img/60/sellist.png b/src/img/60/sellist.png new file mode 100644 index 0000000..b3fe553 Binary files /dev/null and b/src/img/60/sellist.png differ diff --git a/src/img/60/sphere.png b/src/img/60/sphere.png new file mode 100644 index 0000000..0b1095b Binary files /dev/null and b/src/img/60/sphere.png differ diff --git a/src/img/60/torus.png b/src/img/60/torus.png new file mode 100644 index 0000000..5284905 Binary files /dev/null and b/src/img/60/torus.png differ diff --git a/src/img/60/triangle.png b/src/img/60/triangle.png new file mode 100644 index 0000000..e0fd299 Binary files /dev/null and b/src/img/60/triangle.png differ