2013-03-08 39 views
8

Tôi đang cố gắng tải các mô hình 3D trong ứng dụng của mình với jPCT-AE. Tôi đọc qua một số hướng dẫn và tôi nghĩ rằng tôi hiểu những điều cơ bản, nhưng tôi vẫn chưa thành công trong việc tích hợp các tập tin 3D mà tôi có.Tải mô hình 3D với jPCT-AE

Tôi đang sử dụng các đoạn mã tôi tìm thấy trên hướng dẫn gói 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; 
     } 

} 
} 

Vì vậy, các ứng dụng bị lỗi, đây là logcat tôi

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) 

file 3d là trong "tài sản" thư mục, và là một file 3ds hợp lệ (Tôi đã thử nghiệm nó trên công cụ 3d khác)

Bạn có thể giúp tôi không?

Trả lời

8

Cố gắng xây dựng phương pháp InputStream trong loadModel của bạn với thay này:

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

Và xem nếu nó thay đổi bất cứ điều gì hay không. Ở đây ContextApplication Context mà bạn có thể nhận được từ các Hoạt động tạo ra các renderer:

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

Tôi có thể xác nhận tính năng này hoạt động. Ban đầu tôi đã nhìn thấy một màn hình màu đen vì định dạng tệp 3ds của tôi quá lớn (2.9MB). Sau đó tôi chuyển sang một tệp 3ds trong phạm vi kilobyte và nó hoạt động rất tốt. Cảm ơn câu trả lời của bạn. – JDS

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

Tôi đoán .. dòng trên trong mã của bạn không đọc các tập tin vào InputStream ,, thay vì chỉ sao chép mảng byte đối tượng chuỗi tên tệp ..

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

Sử dụng dòng này để tải tệp 3ds. Theo cách tương tự, bạn có thể tải các định dạng tệp khác được hỗ trợ bởi jPCT-AE.

Các vấn đề liên quan