/* (non-Javadoc) * @see org.apache.batik.parser.PathHandler#curvetoQuadraticSmoothRel(float, float) */ public void curvetoQuadraticSmoothRel(float x, float y) throws ParseException { if (verbose) System.out.println("curvetoQuadraticSmoothRel: " + x + "," + y); Vertex lastPoint = pathPoints.getLast(); if (lastPoint instanceof BezierVertex && cubicBezVertTOQuadricControlPoint.get(lastPoint) != null) { Vertex lastEndPoint = new Vertex( pathPoints.getLast().getX(), pathPoints.getLast().getY(), pathPoints.getLast().getZ()); // Get control point of last QuadTo Vertex lastQuadControlPoint = cubicBezVertTOQuadricControlPoint.get(lastPoint); cubicBezVertTOQuadricControlPoint.remove(lastPoint); // Rotate that controlpoint around the end point of the last QuadTo lastQuadControlPoint.rotateZ(lastEndPoint, 180); // Put in startPoint = last QuadTo Endpoint of this smoothQuadTo, the calculated control // point, and the endpoint of smoothQuadTo BezierVertex b5 = Tools3D.getCubicFromQuadraticCurve( lastEndPoint, lastQuadControlPoint, new Vertex(lastPoint.getX() + x, lastPoint.getY() + y, 0)); // Save last quad control point cubicBezVertTOQuadricControlPoint.put(b5, lastQuadControlPoint); pathPoints.add(b5); currentSubPath.add(b5); } else { if (verbose) System.out.println( "couldnt get last control point at curvetoQuadraticSmoothRel - using last point as the control point"); Vertex lastEndPoint = new Vertex(lastPoint.getX(), lastPoint.getY(), 0); Vertex quadControlPoint = new Vertex(lastPoint.getX(), lastPoint.getY(), 0); BezierVertex b5 = Tools3D.getCubicFromQuadraticCurve( lastEndPoint, quadControlPoint, new Vertex(lastPoint.getX() + x, lastPoint.getY() + y, 0)); cubicBezVertTOQuadricControlPoint.put(b5, quadControlPoint); pathPoints.add(b5); currentSubPath.add(b5); } }
/* (non-Javadoc) * @see org.apache.batik.parser.PathHandler#arcAbs(float, float, float, boolean, boolean, float, float) */ public void arcAbs( float rx, float ry, float phi, boolean large_arc, boolean sweep, float x, float y) throws ParseException { if (verbose) System.out.println( "arcAbs: " + rx + " " + ry + " " + phi + " " + large_arc + " " + sweep + " " + x + " " + y); Vertex lastPoint = pathPoints.getLast(); List<Vertex> arcVertices = Tools3D.arcTo(lastPoint.x, lastPoint.y, rx, ry, phi, large_arc, sweep, x, y, 40); // Prevent odd picking behavour, in which the normal is // not correctly computed, because the 2 points are the same if (!arcVertices.isEmpty() && lastPoint != null && arcVertices.get(0).equalsVector(lastPoint)) { arcVertices.remove(0); } pathPoints.addAll(arcVertices); currentSubPath.addAll(arcVertices); }
/* * (non-Javadoc) * * @see * org.mt4j.input.inputProcessors.IGestureEventListener#processGestureEvent * (org.mt4j.input.inputProcessors.MTGestureEvent) */ public boolean processGestureEvent(MTGestureEvent ge) { if (ge instanceof TapEvent) { TapEvent te = (TapEvent) ge; if (te.getTapID() == TapEvent.TAPPED) { Vector3D w = Tools3D.project(app, app.getCurrentScene().getSceneCam(), te.getLocationOnScreen()); Vector3D x = suggestionBox.globalToLocal(w); float zero = suggestionBox.getVerticesLocal()[0].y; float heightPerLine = suggestionBox.getHeightXY(TransformSpace.LOCAL) / (float) (suggestionBox.getLineCount() + 1); int line = (int) ((x.y - zero) / heightPerLine); if (currentSuggestions.size() > line) { try { setText(currentSuggestions.get(line)); } catch (NullPointerException ex) { setText("Error in MTSuggestionTextArea"); } } } } return false; }
/* (non-Javadoc) * @see org.apache.batik.parser.PathHandler#curvetoQuadraticRel(float, float, float, float) */ public void curvetoQuadraticRel(float x1, float y1, float x, float y) throws ParseException { if (verbose) System.out.println("curvetoQuadraticRel: " + x1 + "," + y1 + " " + x + "," + y); if (!pathPoints.isEmpty() && pathPoints.getLast() != null) { Vertex lastPoint = pathPoints.getLast(); Vertex lastEndPoint = new Vertex(lastPoint.getX(), lastPoint.getY(), lastPoint.getZ()); Vertex quadControlPoint = new Vertex(lastPoint.getX() + x1, lastPoint.getY() + y1, 0); // Put in startPoint = last QuadTo Endpoint of this smoothQuadTo, the calculated control // point, and the endpoint of smoothQuadTo BezierVertex b5 = Tools3D.getCubicFromQuadraticCurve( lastEndPoint, quadControlPoint, new Vertex(lastPoint.getX() + x, lastPoint.getY() + y, 0)); cubicBezVertTOQuadricControlPoint.put(b5, quadControlPoint); pathPoints.add(b5); currentSubPath.add(b5); } else { System.out.println("last point null at curvetoQuadraticRel"); } }
/** * Assigns the texture. * * @param pathToModel * @param modelFile * @param scene * @param m * @param sceneMaterialID * @param mesh */ private void assignMaterial( String pathToModel, File modelFile, Scene3ds scene, Mesh3ds m, int sceneMaterialID, MTTriangleMesh mesh) { if (scene.materials() > 0) { if (m.faceMats() > 0) { // Just take the first material in the mesh, it could have more but we dont support more // than 1 material for a mesh // materialIndexForMesh = m.faceMat(0).matIndex(); Material3ds mat = scene.material(sceneMaterialID); String materialName = mat.name(); if (debug) logger.debug( "Material name for mesh \"" + mesh.getName() + ":-> \"" + materialName + "\""); materialName.trim(); materialName.toLowerCase(); // Try to load texture try { PImage cachedImage = textureCache.get(materialName); if (cachedImage != null) { mesh.setTexture(cachedImage); mesh.setTextureEnabled(true); if (debug) logger.debug("->Loaded texture from CACHE : \"" + materialName + "\""); return; } if (modelFile.exists()) { // If model is loaded from local file system String modelFolder = modelFile .getParent(); // pathToModel.substring(), // pathToModel.lastIndexOf(File.pathSeparator) File modelFolderFile = new File(modelFolder); if (modelFolderFile.exists() && modelFolderFile.isDirectory()) modelFolder = modelFolderFile.getAbsolutePath(); else { modelFolder = ""; } String[] suffix = new String[] { "jpg", "JPG", "tga", "TGA", "bmp", "BMP", "png", "PNG", "tiff", "TIFF" }; for (int j = 0; j < suffix.length; j++) { String suffixString = suffix[j]; // Try to load and set texture to mesh String texturePath = modelFolder + MTApplication.separator + materialName + "." + suffixString; File textureFile = new File(texturePath); if (textureFile.exists()) { boolean success = textureFile.renameTo(new File(texturePath)); if (!success) { // File was not successfully renamed logger.debug("failed to RENAME file: " + textureFile.getAbsolutePath()); } PImage texture = null; if (MT4jSettings.getInstance().isOpenGlMode()) { // TODO check if render thread PImage img = pa.loadImage(texturePath); if (Tools3D.isPowerOfTwoDimension(img)) { texture = new GLTexture( pa, img, new GLTextureSettings( TEXTURE_TARGET.TEXTURE_2D, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); } else { texture = new GLTexture( pa, img, new GLTextureSettings( TEXTURE_TARGET.RECTANGULAR, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); // ((GLTexture)texture).setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, // EXPANSION_FILTER.Bilinear); } } else { texture = pa.loadImage(texturePath); } mesh.setTexture(texture); mesh.setTextureEnabled(true); textureCache.put(materialName, texture); if (debug) logger.debug("->Loaded material texture: \"" + materialName + "\""); break; } if (j + 1 == suffix.length) { logger.error("Couldnt load material texture: \"" + materialName + "\""); } } } else { // Probably loading from jar file PImage texture = null; String[] suffix = new String[] { "jpg", "JPG", "tga", "TGA", "bmp", "BMP", "png", "PNG", "tiff", "TIFF" }; for (String suffixString : suffix) { String modelFolder = pathToModel.substring(0, pathToModel.lastIndexOf(MTApplication.separator)); String texturePath = modelFolder + MTApplication.separator + materialName + "." + suffixString; if (MT4jSettings.getInstance().isOpenGlMode()) { PImage img = pa.loadImage(texturePath); if (Tools3D.isPowerOfTwoDimension(img)) { texture = new GLTexture( pa, img, new GLTextureSettings( TEXTURE_TARGET.TEXTURE_2D, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); } else { texture = new GLTexture( pa, img, new GLTextureSettings( TEXTURE_TARGET.RECTANGULAR, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); // ((GLTexture)texture).setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, // EXPANSION_FILTER.Bilinear); } } else { texture = pa.loadImage(texturePath); } mesh.setTexture(texture); mesh.setTextureEnabled(true); textureCache.put(materialName, texture); if (debug) logger.debug("->Loaded material texture: \"" + materialName + "\""); break; } } } catch (Exception e) { logger.error(e.getMessage()); } } // if (m.faceMats() > 0) } // if (scene.materials() > 0) }
// FIXME TEST -> adapt tex coords for non fitting, NPOT gl texture private void adaptTexCoordsForNPOTUse() { PImage tex = this.getTexture(); if (tex instanceof GLTexture) { Tools3D.adaptTextureCoordsNPOT(this, (GLTexture) tex); } }
/** * Instantiates a new model display scene. * * @param mtApplication the mt application * @param name the name */ public Space3DScene(MTApplication mtApplication, String name) { super(mtApplication, name); this.pa = mtApplication; if (!MT4jSettings.getInstance().isOpenGlMode()) { System.err.println("Scene only usable when using the OpenGL renderer! - See settings.txt"); return; } this.setClearColor(new MTColor(200, 200, 200, 255)); this.registerGlobalInputProcessor(new CursorTracer(pa, this)); // Add a background image for the scene this.getCanvas() .addChild(new MTBackgroundImage(pa, pa.loadImage(imagesPath + "3040.jpg"), true)); // Init light settings MTLight.enableLightningAndAmbient(pa, 150, 150, 150, 255); // Create a light source //I think GL_LIGHT0 is used by processing! // MTLight light = new MTLight(pa, GL.GL_LIGHT3, new Vector3D(0,0,0)); MTLight light = new MTLight(pa, GL.GL_LIGHT3, new Vector3D(pa.width / 5f, -pa.height / 10f, 0)); // Set up a material to react to the light GLMaterial material = new GLMaterial(Tools3D.getGL(pa)); material.setAmbient(new float[] {.1f, .1f, .1f, 1f}); material.setDiffuse(new float[] {1.0f, 1.0f, 1.0f, 1f}); material.setEmission(new float[] {.0f, .0f, .0f, 1f}); material.setSpecular(new float[] {1.0f, 1.0f, 1.0f, 1f}); // almost white: very reflective material.setShininess(127); // 0=no shine, 127=max shine // Create the earth earth = new MTSphere(pa, "earth", 40, 40, 80, TextureMode.Projected); // TextureMode.Polar); earth.setLight(light); earth.setMaterial(material); earth.rotateX(earth.getCenterPointRelativeToParent(), -90); earth.setTexture( new GLTexture( pa, imagesPath + "worldMap.jpg", new GLTextureSettings( TEXTURE_TARGET.TEXTURE_2D, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.CLAMP_TO_EDGE, WRAP_MODE.CLAMP_TO_EDGE))); earth.generateAndUseDisplayLists(); earth.setPositionGlobal( new Vector3D( pa.width / 2f, pa.height / 2f, 250)); // earth.setPositionGlobal(new Vector3D(200, 200, 250)); // Animate earth rotation new Animation( "rotation animation", new MultiPurposeInterpolator(0, 360, 17000, 0, 1, -1), earth) .addAnimationListener( new IAnimationListener() { public void processAnimationEvent(AnimationEvent ae) { earth.rotateY(earth.getCenterPointLocal(), ae.getDelta(), TransformSpace.LOCAL); } }) .start(); // Put planets in a group that can be manipulated by gestures // so the rotation of the planets doesent get changed by the gestures MTComponent group = new MTComponent(mtApplication); group.setComposite( true); // This makes the group "consume" all picking and gestures of the children group.registerInputProcessor(new DragProcessor(mtApplication)); group.addGestureListener(DragProcessor.class, new DefaultDragAction()); group.addGestureListener(DragProcessor.class, new InertiaDragAction(80, 0.8f, 10)); group.registerInputProcessor(new RotateProcessor(mtApplication)); group.addGestureListener(RotateProcessor.class, new DefaultRotateAction()); // Scale the earth from the center. Else it might get distorted group.registerInputProcessor(new ScaleProcessor(mtApplication)); group.addGestureListener( ScaleProcessor.class, new IGestureEventListener() { public boolean processGestureEvent(MTGestureEvent ge) { ScaleEvent se = (ScaleEvent) ge; earth.scaleGlobal( se.getScaleFactorX(), se.getScaleFactorY(), se.getScaleFactorX(), earth.getCenterPointGlobal()); return false; } }); this.getCanvas().addChild(group); group.addChild(earth); // Create the moon final MTSphere moonSphere = new MTSphere(pa, "moon", 35, 35, 25, TextureMode.Polar); moonSphere.setMaterial(material); moonSphere.translate(new Vector3D(earth.getRadius() + moonSphere.getRadius() + 50, 0, 0)); moonSphere.setTexture( new GLTexture( pa, imagesPath + "moonmap1k.jpg", new GLTextureSettings( TEXTURE_TARGET.RECTANGULAR, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.CLAMP_TO_EDGE, WRAP_MODE.CLAMP_TO_EDGE))); moonSphere.generateAndUseDisplayLists(); moonSphere.unregisterAllInputProcessors(); // Rotate the moon around the earth new Animation( "moon animation", new MultiPurposeInterpolator(0, 360, 12000, 0, 1, -1), moonSphere) .addAnimationListener( new IAnimationListener() { public void processAnimationEvent(AnimationEvent ae) { moonSphere.rotateZ( earth.getCenterPointLocal(), ae.getDelta(), TransformSpace.RELATIVE_TO_PARENT); } }) .start(); // Rotate the moon around ints own center new Animation( "moon animation around own axis", new MultiPurposeInterpolator(0, 360, 9000, 0, 1, -1), moonSphere) .addAnimationListener( new IAnimationListener() { public void processAnimationEvent(AnimationEvent ae) { moonSphere.rotateZ( moonSphere.getCenterPointLocal(), -3 * ae.getDelta(), TransformSpace.LOCAL); moonSphere.rotateY( moonSphere.getCenterPointLocal(), 0.5f * ae.getDelta(), TransformSpace.LOCAL); } }) .start(); earth.addChild(moonSphere); }