Package advanced.models3D

Source Code of advanced.models3D.Models3DScene

package advanced.models3D;

import java.awt.event.KeyEvent;

import javax.media.opengl.GL;

import org.mt4j.MTApplication;
import org.mt4j.components.MTComponent;
import org.mt4j.components.MTLight;
import org.mt4j.components.TransformSpace;
import org.mt4j.components.visibleComponents.shapes.mesh.MTTriangleMesh;
import org.mt4j.input.gestureAction.DefaultRotateAction;
import org.mt4j.input.gestureAction.DefaultZoomAction;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.arcballProcessor.ArcBallGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.arcballProcessor.ArcballProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.rotateProcessor.RotateProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleEvent;
import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.zoomProcessor.ZoomProcessor;
import org.mt4j.input.inputProcessors.globalProcessors.CursorTracer;
import org.mt4j.sceneManagement.AbstractScene;
import org.mt4j.util.MT4jSettings;
import org.mt4j.util.MTColor;
import org.mt4j.util.math.Tools3D;
import org.mt4j.util.math.Vector3D;
import org.mt4j.util.modelImporter.ModelImporterFactory;
import org.mt4j.util.opengl.GLMaterial;

public class Models3DScene extends AbstractScene {
  private MTApplication mtApp;
 
  //TODO switch button/wireframe
 
//  private String modelsPath = System.getProperty("user.dir") + File.separator + "examples" +  File.separator +"advanced"+ File.separator + "models3D"  + File.separator + "data" +  File.separator;
  private String modelsPath = "advanced" + MTApplication.separator  + "models3D"  + MTApplication.separator + "data" +  MTApplication.separator;

  public Models3DScene(MTApplication mtApplication, String name) {
    super(mtApplication, name);
    mtApp = mtApplication;
   
    this.setClearColor(new MTColor(40,40,40,255));
   
    this.registerGlobalInputProcessor(new CursorTracer(mtApp, this));
   
    //Make canvas zoomable
    this.getCanvas().registerInputProcessor(new ZoomProcessor(mtApp));
    this.getCanvas().addGestureListener(ZoomProcessor.class, new DefaultZoomAction());
   
    if (!(MT4jSettings.getInstance().isOpenGlMode())){
      System.err.println(this.getClass().getName() + " example can only be run in OpenGL mode.");
      return;
    }
   
    //Init light settings
    MTLight.enableLightningAndAmbient(mtApplication, 150, 150, 150, 255);
    //Create a light source //I think GL_LIGHT0 is used by processing!
    MTLight light = new MTLight(mtApplication, GL.GL_LIGHT3, new Vector3D(0,-300,0));
   
    //Set up a material to react to the light
    GLMaterial material = new GLMaterial(Tools3D.getGL(mtApplication));
    material.setAmbient(new float[]{ .5f, .5f, .5f, 1f });
    material.setDiffuse(new float[]{ .8f, .8f, .8f, 1f } );
    material.setEmission(new float[]{ .0f, .0f, .0f, 1f });
    material.setSpecular(new float[]{ 0.9f, 0.9f, 0.9f, 1f })// almost white: very reflective
    material.setShininess(110);// 0=no shine,  127=max shine
   
    //Group used to move to the screen center and to put the mesh group in
    MTComponent group1 = new MTComponent(mtApplication);
   
    //Create a group and set the light for the whole mesh group ->better for performance than setting light to more comps
    final MTComponent meshGroup = new MTComponent(mtApplication, "Mesh group");
    meshGroup.setLight(light);
   
    //Desired position for the meshes to appear at
    Vector3D destinationPosition = new Vector3D(mtApplication.width/2, mtApplication.height/2, 50);
    //Desired scale for the meshes
    float destinationScale = mtApplication.width*0.85f;

    //Load the meshes with the ModelImporterFactory (A file can contain more than 1 mesh)
    //Loads 3ds model
    MTTriangleMesh[] meshes = ModelImporterFactory.loadModel(mtApplication, modelsPath + "jazz_Obj" + MTApplication.separator + "honda_jazz.obj", 180, true, false );
   
    //Get the biggest mesh in the group to use as a reference for setting the position/scale
    final MTTriangleMesh biggestMesh = this.getBiggestMesh(meshes);
   
    Vector3D translationToScreenCenter = new Vector3D(destinationPosition);
    translationToScreenCenter.subtractLocal(biggestMesh.getCenterPointGlobal());
   
    Vector3D scalingPoint = new Vector3D(biggestMesh.getCenterPointGlobal());
    float biggestWidth = biggestMesh.getWidthXY(TransformSpace.GLOBAL)
    float scale = destinationScale/biggestWidth;
   
    //Move the group the the desired position
    group1.scaleGlobal(scale, scale, scale, scalingPoint);
    group1.translateGlobal(translationToScreenCenter);
    this.getCanvas().addChild(group1);
    group1.addChild(meshGroup);
   
    //Inverts the normals, if they are calculated pointing inside of the mesh instead of outside
    boolean invertNormals = true;
   
    for (int i = 0; i < meshes.length; i++) {
      MTTriangleMesh mesh = meshes[i];
      meshGroup.addChild(mesh);
      mesh.unregisterAllInputProcessors(); //Clear previously registered input processors
      mesh.setPickable(true);

      if (invertNormals){
        Vector3D[] normals = mesh.getGeometryInfo().getNormals();
        for (int j = 0; j < normals.length; j++) {
          Vector3D vector3d = normals[j];
          vector3d.scaleLocal(-1);
        }
        mesh.getGeometryInfo().setNormals(mesh.getGeometryInfo().getNormals(), mesh.isUseDirectGL(), mesh.isUseVBOs());
      }

      //If the mesh has more than 20 vertices, use a display list for faster rendering
      if (mesh.getVertexCount() > 20)
        mesh.generateAndUseDisplayLists();
      //Set the material to the mesh  (determines the reaction to the lightning)
      if (mesh.getMaterial() == null)
        mesh.setMaterial(material);
      mesh.setDrawNormals(false);
    }
   
    //Register arcball gesture manipulation to the whole mesh-group
    meshGroup.setComposite(true); //-> Group gets picked instead of its children
    meshGroup.registerInputProcessor(new ArcballProcessor(mtApplication, biggestMesh));
    meshGroup.addGestureListener(ArcballProcessor.class, new IGestureEventListener(){
      //@Override
      public boolean processGestureEvent(MTGestureEvent ge) {
        ArcBallGestureEvent aEvt =  (ArcBallGestureEvent)ge;
        meshGroup.transform(aEvt.getTransformationMatrix());
        return false;
      }
    });
   
    meshGroup.registerInputProcessor(new ScaleProcessor(mtApplication));
    meshGroup.addGestureListener(ScaleProcessor.class, new IGestureEventListener(){
      //@Override
      public boolean processGestureEvent(MTGestureEvent ge) {
        ScaleEvent se = (ScaleEvent)ge;
        meshGroup.scaleGlobal(se.getScaleFactorX(), se.getScaleFactorY(), se.getScaleFactorX(), biggestMesh.getCenterPointGlobal());
        return false;
      }
    });
   
    meshGroup.registerInputProcessor(new RotateProcessor(mtApplication));
    meshGroup.addGestureListener(RotateProcessor.class, new DefaultRotateAction());
  }

 
  public MTTriangleMesh getBiggestMesh(MTTriangleMesh[] meshes){
    MTTriangleMesh currentBiggestMesh = null;
    //Get the biggest mesh and extract its width
    float currentBiggestWidth = Float.MIN_VALUE;
    for (int i = 0; i < meshes.length; i++) {
      MTTriangleMesh triangleMesh = meshes[i];
      float width = triangleMesh.getWidthXY(TransformSpace.GLOBAL);
      if (width >= currentBiggestWidth || currentBiggestWidth == Float.MIN_VALUE){
        currentBiggestWidth = width;
        currentBiggestMesh = triangleMesh;
      }
    }
    return currentBiggestMesh;
  }
 
 
 
  //@Override
  public void init() {
    mtApp.registerKeyEvent(this);
  }

  //@Override
  public void shutDown() {
    mtApp.unregisterKeyEvent(this);
  }
 
  public void keyEvent(KeyEvent e){
    //System.out.println(e.getKeyCode());
    int evtID = e.getID();
    if (evtID != KeyEvent.KEY_PRESSED)
      return;
    switch (e.getKeyCode()){
    case KeyEvent.VK_F:
      System.out.println("FPS: " + mtApp.frameRate);
      break;
    case KeyEvent.VK_PLUS:
      this.getSceneCam().moveCamAndViewCenter(0, 0, -10);
      break;
    case KeyEvent.VK_MINUS:
      this.getSceneCam().moveCamAndViewCenter(0, 0, +10);
      break;
    case KeyEvent.VK_F12:
      getMTApplication().saveFrame(); //Screenshot
      break;
      default:
        break;
    }
  }


}
TOP

Related Classes of advanced.models3D.Models3DScene

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.