首页 > 解决方案 > JAVA3D 加载从搅拌机导出的 .obj 文件

问题描述

我正在尝试将 .obj 文件从搅拌机加载到 Java3D,但总是发生错误:

com.sun.j3d.utils.image.ImageException: javax.imageio.IIOException: 无法从 URL 获取输入流!

最奇怪的是,当我从网络加载模型时一切正常,但是当我将相同的文件导入搅拌机然后导出它(没有任何更改)时它不起作用。

    import java.applet.*;
    import java.awt.*;

    import javax.media.j3d.*;
    import javax.vecmath.*;

    import com.sun.j3d.utils.applet.MainFrame;
    import com.sun.j3d.utils.universe.SimpleUniverse;
    import com.sun.j3d.utils.universe.PlatformGeometry;
    import com.sun.j3d.utils.behaviors.keyboard.*;

    import com.sun.j3d.loaders.Scene;

    import com.sun.j3d.loaders.objectfile.ObjectFile;

    import java.io.*;

    import java.awt.event.KeyListener;
    import java.awt.event.KeyEvent;

    public class Mykeynavbeh extends Applet implements KeyListener {

     private SimpleUniverse universe = null;
     private Canvas3D canvas = null;
     private TransformGroup viewtrans = null;

     private TransformGroup tg = null;
     private Transform3D t3d = null;
     private Transform3D t3dstep = new Transform3D();
     private Matrix4d matrix = new Matrix4d();

     public Mykeynavbeh() {
      setLayout(new BorderLayout());
      GraphicsConfiguration config = SimpleUniverse
        .getPreferredConfiguration();

      canvas = new Canvas3D(config);
      add("Center", canvas);
      universe = new SimpleUniverse(canvas);

      BranchGroup scene = createSceneGraph();
      universe.getViewingPlatform().setNominalViewingTransform();

      universe.getViewer().getView().setBackClipDistance(100.0);

      canvas.addKeyListener(this);

      universe.addBranchGraph(scene);
     }

     private BranchGroup createSceneGraph() {
      BranchGroup objRoot = new BranchGroup();

      BoundingSphere bounds = new BoundingSphere(new Point3d(), 10000.0);

      viewtrans = universe.getViewingPlatform().getViewPlatformTransform();

      KeyNavigatorBehavior keyNavBeh = new KeyNavigatorBehavior(viewtrans);
      keyNavBeh.setSchedulingBounds(bounds);
      PlatformGeometry platformGeom = new PlatformGeometry();
      platformGeom.addChild(keyNavBeh);
      universe.getViewingPlatform().setPlatformGeometry(platformGeom);

      objRoot.addChild(createLadybird());

      Background background = new Background();
      background.setColor(0.75f, 0.69f, 0.680f);
      background.setApplicationBounds(bounds);
      objRoot.addChild(background);

      return objRoot;
     }

     private BranchGroup createLadybird() {

      BranchGroup objRoot = new BranchGroup();
      tg = new TransformGroup();
      t3d = new Transform3D();

      tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

      t3d.setTranslation(new Vector3d(-0.15, -0.3, -5.0));
      t3d.setRotation(new AxisAngle4f(0.0f, 0.0f, 0.0f, 0.0f));
      t3d.setScale(1.0);

      tg.setTransform(t3d);

      ObjectFile loader = new ObjectFile(ObjectFile.RESIZE);
      Scene s = null;

      File file = new java.io.File("model/female2.obj");

      try {
       s = loader.load(file.toURI().toURL());
      } catch (Exception e) {
       System.err.println(e);
       System.exit(1);
      }

      tg.addChild(s.getSceneGroup());

      objRoot.addChild(tg);
      objRoot.addChild(createLight());

      objRoot.compile();

      return objRoot;

     }

     private Light createLight() {
      DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f,
        1.0f, 1.0f), new Vector3f(-0.3f, 0.2f, -1.0f));

      light.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0));

      return light;
     }

     public static void main(String[] args) {
      Mykeynavbeh applet = new Mykeynavbeh();
      Frame frame = new MainFrame(applet, 800, 600);
     }

     public void keyTyped(KeyEvent e) {
      char key = e.getKeyChar();

      if (key == 'd') {
       t3dstep.set(new Vector3d(0.0, 0.0, -0.1));
       tg.getTransform(t3d);
       t3d.mul(t3dstep);
       tg.setTransform(t3d);
      }

      if (key == 's') {

       t3dstep.rotY(Math.PI / 32);
       tg.getTransform(t3d);
       t3d.get(matrix);
       t3d.setTranslation(new Vector3d(0.0, 0.0, 0.0));
       t3d.mul(t3dstep);
       t3d.setTranslation(new Vector3d(matrix.m03, matrix.m13, matrix.m23));
       tg.setTransform(t3d);

      }

      if (key == 'f') {

       t3dstep.rotY(-Math.PI / 32);
       tg.getTransform(t3d);
       t3d.get(matrix);
       t3d.setTranslation(new Vector3d(0.0, 0.0, 0.0));
       t3d.mul(t3dstep);
       t3d.setTranslation(new Vector3d(matrix.m03, matrix.m13, matrix.m23));
       tg.setTransform(t3d);

      }

      if (key == 'r') {

       t3dstep.rotX(Math.PI / 32);
       tg.getTransform(t3d);
       t3d.get(matrix);
       t3d.setTranslation(new Vector3d(0.0, 0.0, 0.0));
       t3d.mul(t3dstep);
       t3d.setTranslation(new Vector3d(matrix.m03, matrix.m13, matrix.m23));
       tg.setTransform(t3d);

      }

      if (key == 'v') {

       t3dstep.rotX(-Math.PI / 32);
       tg.getTransform(t3d);
       t3d.get(matrix);
       t3d.setTranslation(new Vector3d(0.0, 0.0, 0.0));
       t3d.mul(t3dstep);
       t3d.setTranslation(new Vector3d(matrix.m03, matrix.m13, matrix.m23));
       tg.setTransform(t3d);

      }

      if (key == 'e') {
       t3dstep.set(new Vector3d(0.0, 0.1, 0.0));
       tg.getTransform(t3d);
       t3d.mul(t3dstep);
       tg.setTransform(t3d);
      }

      if (key == 'c') {
       t3dstep.set(new Vector3d(0.0, -0.1, 0.0));
       tg.getTransform(t3d);
       t3d.mul(t3dstep);
       tg.setTransform(t3d);
      }
     }

     public void keyReleased(KeyEvent e) {
     }

     public void keyPressed(KeyEvent e) {
     }
    }

标签: blenderjava-3d

解决方案


请尝试以下步骤:

[1] 打开 .mtl 文件,确保所有纹理路径都是相对的,如下所示:

map_Kd女02_1.jpg

不像这样:

map_Kd C:\Users\Username\MyJava3D\Female02\model\female02_1.jpg(绝对路径)

在我的 PC 上,如果纹理路径不正确,那么 Java3D 1.5.1 中会出现该错误。在 Java3D 1.6.0 中,没有出现错误,但是纹理没有显示出来。

你说的是 Sweet Home 3D 中的 female02.obj 吗?(我只是从文件名“female2.obj”中猜测。)如果是这样,则需要 [2] 和 [3]。

[2] 对于多个纹理,在导出模型之前选中“Objects as OBJ Groups”和“Material Groups”(在左下角)。否则,纹理将不会显示。

[3] 对于 .obj 文件,纹理可能无法正确显示。如果是这样,将所有法线翻转到外面。

搅拌机 2.77:

对于每个部分(头发、脸、衣服……)

1) 在对象模式下,右键单击零件。

2) 按 Tab 键进入编辑模式。

3) 在 3D View 窗口中,按 Ctrl-n 几次。

4) 按 Tab 键进入对象模式。

5) 重复上述步骤 1) 至 4)。

[4] 另外,注释掉导出的 .obj 文件中所有以 'o' 开头的行。否则会出现如下错误:com.sun.j3d.loaders.ParsingErrorException: Unrecognized token, line~


推荐阅读