2013-03-08 12 views
8

Ich versuche, 3D-Modelle in meiner Anwendung mit jPCT-AE zu laden. Ich lese verschiedene Tutorials durch und ich denke, ich verstehe die Grundlagen, aber ich habe es immer noch geschafft, die 3D-Dateien, die ich habe, zu integrieren.Laden Sie 3D-Modelle mit JPCT-AE

Ich benutze Teile von Codes, die ich in Tutorials gefunden Paket com.example.jpct;

import java.io.IOException; 
import java.io.InputStream; 
import java.io.UnsupportedEncodingException; 
import java.lang.reflect.Field; 

import javax.microedition.khronos.egl.EGL10; 
import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.egl.EGLDisplay; 
import javax.microedition.khronos.opengles.GL10; 

import android.app.Activity; 
import android.content.res.AssetManager; 
import android.opengl.GLSurfaceView; 
import android.os.Bundle; 
import android.view.MotionEvent; 

import com.threed.jpct.Camera; 
import com.threed.jpct.FrameBuffer; 
import com.threed.jpct.Light; 
import com.threed.jpct.Loader; 
import com.threed.jpct.Logger; 
import com.threed.jpct.Object3D; 
import com.threed.jpct.Primitives; 
import com.threed.jpct.RGBColor; 
import com.threed.jpct.SimpleVector; 
import com.threed.jpct.Texture; 
import com.threed.jpct.TextureManager; 
import com.threed.jpct.World; 
import com.threed.jpct.util.BitmapHelper; 
import com.threed.jpct.util.MemoryHelper; 
import java.io.*; 


import com.threed.jpct.*; 

import android.content.res.Resources; 
import android.opengl.GLSurfaceView.EGLConfigChooser; 
import android.opengl.GLSurfaceView.Renderer; 
import android.util.Log; 

/** 
* A simple demo. This shows more how to use jPCT-AE than it shows how to write 
* a proper application for Android. It includes basic activity management to 
* handle pause and resume... 
* 
* @author EgonOlsen 
* 
*/ 
public class MainActivity extends Activity { 

// Used to handle pause and resume... 
private static MainActivity master = null; 

private GLSurfaceView mGLView; 
private MyRenderer renderer = null; 
private FrameBuffer fb = null; 
private World world = null; 
private RGBColor back = new RGBColor(50, 50, 100); 

private float touchTurn = 0; 
private float touchTurnUp = 0; 

private float xpos = -1; 
private float ypos = -1; 

private Object3D cube = null; 
private int fps = 0; 

private Light sun = null; 

AssetManager assMan; 
InputStream is; 

private String thingName = "palm-realviz"; 
private int thingScale = 1;//end 


protected void onCreate(Bundle savedInstanceState) { 

    Logger.log("onCreate"); 

    if (master != null) { 
     copy(master); 
    } 

    super.onCreate(savedInstanceState); 
    mGLView = new GLSurfaceView(getApplication()); 

    mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() { 
     public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { 
      // Ensure that we get a 16bit framebuffer. Otherwise, we'll fall 
      // back to Pixelflinger on some device (read: Samsung I7500) 
      int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE }; 
      EGLConfig[] configs = new EGLConfig[1]; 
      int[] result = new int[1]; 
      egl.eglChooseConfig(display, attributes, configs, 1, result); 
      return configs[0]; 
     } 
    }); 

    renderer = new MyRenderer(); 
    mGLView.setRenderer(renderer); 
    setContentView(mGLView); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    mGLView.onPause(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    mGLView.onResume(); 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
} 

private void copy(Object src) { 
    try { 
     Logger.log("Copying data from master Activity!"); 
     Field[] fs = src.getClass().getDeclaredFields(); 
     for (Field f : fs) { 
      f.setAccessible(true); 
      f.set(this, f.get(src)); 
     } 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 

public boolean onTouchEvent(MotionEvent me) { 

    if (me.getAction() == MotionEvent.ACTION_DOWN) { 
     xpos = me.getX(); 
     ypos = me.getY(); 
     return true; 
    } 

    if (me.getAction() == MotionEvent.ACTION_UP) { 
     xpos = -1; 
     ypos = -1; 
     touchTurn = 0; 
     touchTurnUp = 0; 
     return true; 
    } 

    if (me.getAction() == MotionEvent.ACTION_MOVE) { 
     float xd = me.getX() - xpos; 
     float yd = me.getY() - ypos; 

     xpos = me.getX(); 
     ypos = me.getY(); 

     touchTurn = xd/-100f; 
     touchTurnUp = yd/-100f; 
     return true; 
    } 

    try { 
     Thread.sleep(15); 
    } catch (Exception e) { 
     // No need for this... 
    } 

    return super.onTouchEvent(me); 
} 

protected boolean isFullscreenOpaque() { 
    return true; 
} 

class MyRenderer implements GLSurfaceView.Renderer { 

    private long time = System.currentTimeMillis(); 

    public MyRenderer() { 
    } 

    public void onSurfaceChanged(GL10 gl, int w, int h) { 
     if (fb != null) { 
      fb.dispose(); 
     } 
     fb = new FrameBuffer(gl, w, h); 

     if (master == null) { 

      world = new World(); 
      world.setAmbientLight(20, 20, 20); 

      sun = new Light(world); 
      sun.setIntensity(250, 250, 250); 

      // Create a texture out of the icon...:-) 
      Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.ic_launcher)), 64, 64)); 
      TextureManager.getInstance().addTexture("texture", texture); 


      try { 
       cube = loadModel("assets/" + thingName + ".3ds", thingScale); 
      } catch (UnsupportedEncodingException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

        //Primitives.getCube(10); 
      //cube.calcTextureWrapSpherical(); 
      //cube.setTexture("texture"); 
      //cube.strip(); 
      cube.build(); 

      world.addObject(cube); 

      Camera cam = world.getCamera(); 
      cam.moveCamera(Camera.CAMERA_MOVEOUT, 50); 
      cam.lookAt(cube.getTransformedCenter()); 

      SimpleVector sv = new SimpleVector(); 
      sv.set(cube.getTransformedCenter()); 
      sv.y -= 100; 
      sv.z -= 100; 
      sun.setPosition(sv); 
      MemoryHelper.compact(); 

      if (master == null) { 
       Logger.log("Saving master Activity!"); 
       master = MainActivity.this; 
      } 
     } 
    } 

    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    } 

    public void onDrawFrame(GL10 gl) { 
     if (touchTurn != 0) { 
      cube.rotateY(touchTurn); 
      touchTurn = 0; 
     } 

     if (touchTurnUp != 0) { 
      cube.rotateX(touchTurnUp); 
      touchTurnUp = 0; 
     } 

     fb.clear(back); 
     world.renderScene(fb); 
     world.draw(fb); 
     fb.display(); 

     if (System.currentTimeMillis() - time >= 1000) { 
      Logger.log(fps + "fps"); 
      fps = 0; 
      time = System.currentTimeMillis(); 
     } 
     fps++; 
    } 

     private Object3D loadModel(String filename, float scale) throws UnsupportedEncodingException { 

      InputStream stream = new ByteArrayInputStream(filename.getBytes("UTF-8")); 
      Object3D[] model = Loader.load3DS(stream, scale); 
      Object3D o3d = new Object3D(0); 
      Object3D temp = null; 
      for (int i = 0; i < model.length; i++) { 
       temp = model[i]; 
       temp.setCenter(SimpleVector.ORIGIN); 
       temp.rotateX((float)(-.5*Math.PI)); 
       temp.rotateMesh(); 
       temp.setRotationMatrix(new Matrix()); 
       o3d = Object3D.mergeObjects(o3d, temp); 
       o3d.build(); 
      } 
      return o3d; 
     } 

} 
} 

So sind die Anwendungen nicht, hier ist mein Logcat

FATAL EXCEPTION: GLThread 93 
java.lang.RuntimeException: [ 1363008600568 ] - ERROR: Not a valid 3DS file! 
at com.threed.jpct.Logger.log(Logger.java:189) 
at com.threed.jpct.Loader.load3DS(Loader.java:1554) 
at com.threed.jpct.Loader.load3DS(Loader.java:154) 
at com.example.jpct.MainActivity$MyRenderer.loadModel(MainActivity.java:269) 
at com.example.jpct.MainActivity$MyRenderer.onSurfaceChanged(MainActivity.java:207) 
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1505) 
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240) 

die 3D-Datei ist in den "Assets" Ordner und ist eine 3ds gültige Datei (ich es auf anderen 3D-Engine getestet)

Können Sie mir bitte helfen?

Antwort

8

Versuchen Sie, Ihre InputStream in loadModel Methode mit diesem statt zu konstruieren:

InputStream stream = mContext.getAssets().open("FILENAME.3DS") 

Und sehen, ob es irgendetwas oder nicht ändert. Hier die Context ist die Application Context die Sie von der Aktivität erhalten können, die den Renderer erstellt:

// the "this" refers to your "MainActivity" 
Context mContext = this.getApplicationContext(); 
+2

Ich kann bestätigen, dass dies funktioniert. Anfangs sah ich einen schwarzen Bildschirm, weil mein 3ds-Dateiformat zu groß war (2,9 MB). Ich wechselte dann zu einer 3ds-Datei im Kilobyte-Bereich und es funktionierte großartig. Danke für deine Antwort. – JDS

0
InputStream stream = new ByteArrayInputStream(filename.getBytes("UTF-8")); 

ich in Ihrem Code erraten .. die obige Zeile die Datei nicht in die Input lesen ,, Stattdessen kopiert er nur das Dateinamenszeichenfolge-Objekt Byte-Array.

1
cube=Object3D.mergeAll(Loader.load3DS(getResources().getAssets().open("chair.3ds", 5)); 

Verwenden Sie diese Zeile, um 3ds-Datei zu laden. Auf die gleiche Weise können Sie andere Dateiformate laden, die von jPCT-AE unterstützt werden.