用jPCT AE加载三维模型



我正在尝试用jPCT AE在我的应用程序中加载三维模型。我读了几个教程,我想我理解了基本知识,但我还没有成功地集成我的3d文件。

我正在使用我在教程中找到的代码片段包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;
        }
}
}

所以应用程序失败了,这是我的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)

3d文件在"assets"文件夹中,是一个3ds有效文件(我在其他3d引擎上测试过(

你能帮我吗?

尝试用以下方法在loadModel中构造InputStream

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

看看它是否改变了什么。这里的ContextApplication Context,您可以从创建渲染器的"活动"中获得:

// the "this" refers to your "MainActivity"
Context mContext = this.getApplicationContext(); 
cube=Object3D.mergeAll(Loader.load3DS(getResources().getAssets().open("chair.3ds", 5));

使用此行加载3ds文件。以同样的方式,您可以加载jPCT AE支持的其他文件格式。

Amrish Kumar的回答几乎是对的,但他漏掉了一个重要的括号。

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

你最好发现任何错误!

所以:

try {
     cube = Object3D.mergeAll(Loader.load3DS(getResources().getAssets().open("cubeship.3ds"), 1));
} catch (IOException e) {
     e.printStackTrace();
}

希望这能帮助任何未来的搜索者!

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

我想。。代码中的上一行没有将文件读入InputStream,而只是复制文件名字符串对象字节数组。。

最新更新