Package edu.ups.gamedev.scene

Source Code of edu.ups.gamedev.scene.Model

package edu.ups.gamedev.scene;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import com.jme.bounding.BoundingSphere;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.TriMesh;
import com.jme.scene.lod.AreaClodMesh;
import com.jme.scene.state.RenderState;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;

/**
* Model is a generic class that loads a model file into a CLOD mesh. This
* class extends node, so a <code>Model</code> can be directly added to a
* scene graph once loaded. This model's level of detail will automatically
* be updated on the fly by the engine based on how far away the camera is.
*
* @author Walker Lindley
* @version $Revision: 1.1 $, $Date: 2008/01/26 08:13:22 $
*
* @see com.jme.scene.Node Node
* @see com.jme.scene.lod.AreaClodMesh AreaClodMesh
*
*/
public class Model extends Node {
  private static final long serialVersionUID = 1L;
  String name;
  URL filename;
  Spatial model;
 
  /**
   * Constructor taking the filename of the model to load.
   *
   * @param filename  the name of model file to load
   * @throws MalformedURLException
   */
  public Model(String filename) throws MalformedURLException {
    super();
    name = filename;
    this.filename = new File(filename).toURI().toURL();
    model = loadModel(this.filename);
    this.attachChild(getClodNodeFromParent((Node)model));
  }
 
  /**
   * Constructor taking the filename of the model to load and the name
   * that should be given to the node that is created.
   *
   * @param filename  the name of model file to load
   * @param name    the name to give the Node
   * @throws MalformedURLException
   */
  public Model(String filename, String name) throws MalformedURLException {
    super(name);
    this.filename = new File(filename).toURI().toURL();
    model = loadModel(this.filename);
    this.attachChild(getClodNodeFromParent((Node)model));
  }
 
  public static Node getModelNode(String filename) throws MalformedURLException {
    Node parent = new Node();
    parent.attachChild(loadModel(new File(filename).toURI().toURL()));
    System.out.println("Model " + filename + " loaded");
    if(parent == null) {
      System.out.println(" model is null");
    }
    Node clod = getClodNodeFromParent(parent);
    if(clod == null) {
      System.out.println(" clod is null");
    }
    return clod;
  }
 
  /**
   * Loads and returns the specified model.
   *
   * @return  a <code>Spatial</code> representing the model or <code>null</code> if
   *       it cannot load the specified model
   */
  public static Spatial loadModel(URL name) {
    Spatial model;
   
    FormatConverter converter = new ObjToJme();
    converter.setProperty("mtllib", name); //tell converter where to find the mtl file
   
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
   
    try {
      converter.convert(name.openStream(), outStream);
     
      //now that it's converted, load the model
      model = (Spatial)BinaryImporter.getInstance().load(new ByteArrayInputStream(outStream.toByteArray()));
    } catch (IOException e) {
      System.err.println("Error while converting or loading the model");
      System.out.println("Error while converting or loading the model");
      e.printStackTrace();
      System.exit(-1);
      return null;
    }
   
    return model;
  }
 
  /**
   * Generates and returns an <code>AreaClodMesh</code> for the given model. Note that
   * this method was shamelessly stolen from the JME tutorial HelloLOD.
   *
   * @param meshParent  the <code>Node/code> that is the parent of the model
   * @return        a <code>Node</code> with the generated <code>AreaClodMesh
   *             </code> as a child
   *
   */
  public static Node getClodNodeFromParent(Node meshParent) {
        // Create a node to hold my cLOD mesh objects
        Node clodNode = new Node("Clod node");
        // For each mesh in maggie
        for (int i = 0; i < meshParent.getQuantity(); i++){
            final Spatial child = meshParent.getChild(i);
            if(child instanceof Node) {
                clodNode.attachChild(getClodNodeFromParent((Node)child));
            }
            else if ( child instanceof TriMesh ) {
                // Create an AreaClodMesh for that mesh.  Let it compute records automatically
                AreaClodMesh acm = new AreaClodMesh("part"+i,(TriMesh)child, null);
                acm.setModelBound(new BoundingSphere());
                acm.updateModelBound();

                // Allow 1/2 of a triangle in every pixel on the screen in the bounds.
                acm.setTrisPerPixel(.5f);

                // Force a move of 2 units before updating the mesh geometry
                acm.setDistanceTolerance(2);

                // Give the clodMesh node the material state that the original had.
                acm.setRenderState(child.getRenderState(RenderState.RS_MATERIAL));

                // Attach clod node.
                clodNode.attachChild(acm);
            }
            else
            {
                System.err.println("Unhandled Spatial type: " + child.getClass());
            }
        }
        return clodNode;
    }
 
  @Override
  public String getName() {
    return name;
  }
 
}
TOP

Related Classes of edu.ups.gamedev.scene.Model

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.