【问题标题】:How to convert a 3D model to .h file to be imported in an iphone app?如何将 3D 模型转换为 .h 文件以导入 iphone 应用程序?
【发布时间】:2012-04-25 19:28:30
【问题描述】:

我需要将模型导入我的 iPhone 应用程序。我看到它应该被导出为 .h 文件,但我需要工具来形成这个 .h 文件,其中包含模型的顶点、法线..和所有模型的数据。我阅读了这篇关于如何向搅拌机添加脚本的文章,但我找不到在搅拌机 2.58 中添加 obj.py 脚本的路径。当我打开 blender.app 包时,我发现以下文件夹: Contents=>(MacOS(2.57, blender), Resources) 我找不到那篇文章提到的路径。

http://iphonedevelopment.blogspot.com/2009/06/using-3d-models-from-blender-in-opengl.html

即使不使用搅拌机,任何人都知道如何为模型创建 .h 文件?

【问题讨论】:

  • 如果您查看脚本,您会发现自己解释和编写类似的东西并不难。对于另一个建模包或直接从 .obj 到头文件的东西。它只是写出一些数组和 OpenGL 代码。如果您的问题与 Blender 相关而不是实际编程,您最好直接在某个论坛甚至 IRC 上询问 Blender 社区。​​span>

标签: iphone opengl-es 3d


【解决方案1】:

我相信您可以制作一个立即为 .h 文件生成的小型桌面应用程序。这是我为 Android 编写的 OBJ 加载器的主类。

请注意,我正在试验代码,所以它不干净,但它工作得很好!

您可以将该代码移植到桌面,然后在 fillInBuffers() 函数中,开始将数组写入文件。

顺便说一句,您将不得不调用 glDrawElements。我希望这会有所帮助;)

编辑:忘了说 Vector3D 是一个简单的类,它包含我用来保存 X、Y 和 Z 值,而 Face 类包含 UVW、顶点和顶点法线的数组

public class Model {

    // Constants
    private static final int FLOAT_SIZE_BYTES = 4;
    private static final int SHORT_SIZE_BYTES = 2;

    private FloatBuffer _vb;
    private FloatBuffer _nb;
    private ShortBuffer _ib;
    private FloatBuffer _tcb;

    private short[] indices;

    private float[] tempV;
    private float[] tempVt;
    private float[] tempVn;

    private ArrayList<Vector3D> vertices;
    private ArrayList<Vector3D> vertexTexture;
    private ArrayList<Vector3D> vertexNormal;
    private ArrayList<Face> faces;
    private int vertexCount;

    private ArrayList<GroupObject> groupObjects;

    //Android Stuff!
    private Context context;
    private int modelID;

    public Model(int modelID, Context activity)
    {
        this.vertices = new ArrayList<Vector3D>();
        this.vertexTexture = new ArrayList<Vector3D>();
        this.vertexNormal = new ArrayList<Vector3D>();
        this.faces = new ArrayList<Face>();

        this.groupObjects = new ArrayList<GroupObject>();

        this.modelID = modelID;
        this.context = activity;

        loadFile();
    }

    private int loadFile()
    {
        InputStream inputStream = context.getResources().openRawResource(modelID);

        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));

        try {
            loadOBJ(in);
            Log.d("LOADING FILE", "FILE LOADED SUCESSFULLY====================");
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return 1;
    }

    private void loadOBJ(BufferedReader in) throws IOException
    {
        Log.d("LOADING FILE", "STARTING!====================");
        GroupObject defaultObject = new GroupObject();
        GroupObject currentObject = defaultObject;

        this.groupObjects.add(defaultObject);

        String Line;            // Stores ever line we read!
        String[] Blocks;        // Stores string fragments after the split!!
        String CommandBlock;    // Stores Command Blocks such as: v, vt, vn, g, etc...

        while((Line = in.readLine()) != null)
        {
            Blocks = Line.split(" ");
            CommandBlock = Blocks[0];

//          Log.d("COMMAND BLOCK" , "---------- " + CommandBlock + " ----------");

            if(CommandBlock.equals("g"))
            {
                if(Blocks[1] == "default")
                    currentObject = defaultObject;
                else
                {
                    GroupObject groupObject = new GroupObject();
                    groupObject.setObjectName(Blocks[1]);
                    currentObject = groupObject;
                    groupObjects.add(groupObject);
                }
            }

            if(CommandBlock.equals("v"))
            {
                Vector3D vertex = new Vector3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), Float.parseFloat(Blocks[3]));
                this.vertices.add(vertex);
//              Log.d("VERTEX DATA", " " + vertex.getX() + ", " + vertex.getY() + ", " + vertex.getZ());
            }

            if(CommandBlock.equals("vt"))
            {
                Vector3D vertexTex = new Vector3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), 0.0f);
                this.vertexTexture.add(vertexTex);
//              Log.d("TEXTURE DATA", " " + vertexTex.getX() + ", " + vertexTex.getY() + ", " + vertexTex.getZ());
            }

            if(CommandBlock.equals("vn"))
            {
                Vector3D vertexNorm = new Vector3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), Float.parseFloat(Blocks[3]));
                this.vertexNormal.add(vertexNorm);
//              Log.d("NORMAL DATA", " " + vertexNorm.getX() + ", " + vertexNorm.getY() + ", " + vertexNorm.getZ());
            }

            if(CommandBlock.equals("f"))
            {
                Face face = new Face();
                faces.add(face);

                String[] faceParams;

                for(int i = 1; i < Blocks.length ; i++)
                {               
                    faceParams = Blocks[i].split("/");

                    face.getVertices().add(this.vertices.get(Integer.parseInt(faceParams[0]) - 1));                 

                    if(faceParams[1] == ""){}
                    else
                    {
                        face.getUvws().add(this.vertexTexture.get(Integer.parseInt(faceParams[1]) - 1));
                        face.getNormals().add(this.vertexNormal.get(Integer.parseInt(faceParams[2]) - 1));
                    }
                }
            }
        }

//      fillInBuffers();
        fillInBuffersWithNormals();

        Log.d("OBJ OBJECT DATA", "V = " + vertices.size() + " VN = " + vertexTexture.size() + " VT = " + vertexNormal.size());

    }

    private void fillInBuffers() {

        int facesSize = faces.size();

        vertexCount = facesSize * 3;

        tempV = new float[facesSize * 3 * 3];
        tempVt = new float[facesSize * 2 * 3];
        indices = new short[facesSize * 3];

        for(int i = 0; i < facesSize; i++)
        {
            Face face = faces.get(i);
            tempV[i * 9]     = face.getVertices().get(0).getX();
            tempV[i * 9 + 1] = face.getVertices().get(0).getY();
            tempV[i * 9 + 2] = face.getVertices().get(0).getZ();
            tempV[i * 9 + 3] = face.getVertices().get(1).getX();
            tempV[i * 9 + 4] = face.getVertices().get(1).getY();
            tempV[i * 9 + 5] = face.getVertices().get(1).getZ();
            tempV[i * 9 + 6] = face.getVertices().get(2).getX();
            tempV[i * 9 + 7] = face.getVertices().get(2).getY();
            tempV[i * 9 + 8] = face.getVertices().get(2).getZ();
            tempVt[i * 6]     = face.getUvws().get(0).getX();
            tempVt[i * 6 + 1] = face.getUvws().get(0).getY();
            tempVt[i * 6 + 2] = face.getUvws().get(1).getX();
            tempVt[i * 6 + 3] = face.getUvws().get(1).getY();
            tempVt[i * 6 + 4] = face.getUvws().get(2).getX();
            tempVt[i * 6 + 5] = face.getUvws().get(2).getY();
            indices[i * 3]     = (short) (i * 3);
            indices[i * 3 + 1] = (short) (i * 3 + 1);
            indices[i * 3 + 2] = (short) (i * 3 + 2);
        }

        _vb = ByteBuffer.allocateDirect(tempV.length
                * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _vb.put(tempV);
        _vb.position(0);

        _tcb = ByteBuffer.allocateDirect(tempVt.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _tcb.put(tempVt);
        _tcb.position(0);

        _ib = ByteBuffer.allocateDirect(indices.length
                * SHORT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
        _ib.put(indices);
        _ib.position(0);
    }

    private void fillInBuffersWithNormals() {

        int facesSize = faces.size();

        vertexCount = facesSize * 3;

        tempV = new float[facesSize * 3 * 3];
        tempVt = new float[facesSize * 2 * 3];
        tempVn = new float[facesSize * 3 * 3];
        indices = new short[facesSize * 3];

        for(int i = 0; i < facesSize; i++)
        {
            Face face = faces.get(i);
            tempV[i * 9]     = face.getVertices().get(0).getX();
            tempV[i * 9 + 1] = face.getVertices().get(0).getY();
            tempV[i * 9 + 2] = face.getVertices().get(0).getZ();
            tempV[i * 9 + 3] = face.getVertices().get(1).getX();
            tempV[i * 9 + 4] = face.getVertices().get(1).getY();
            tempV[i * 9 + 5] = face.getVertices().get(1).getZ();
            tempV[i * 9 + 6] = face.getVertices().get(2).getX();
            tempV[i * 9 + 7] = face.getVertices().get(2).getY();
            tempV[i * 9 + 8] = face.getVertices().get(2).getZ();

            tempVn[i * 9]     = face.getNormals().get(0).getX();
            tempVn[i * 9 + 1] = face.getNormals().get(0).getY();
            tempVn[i * 9 + 2] = face.getNormals().get(0).getZ();
            tempVn[i * 9 + 3] = face.getNormals().get(1).getX();
            tempVn[i * 9 + 4] = face.getNormals().get(1).getY();
            tempVn[i * 9 + 5] = face.getNormals().get(1).getZ();
            tempVn[i * 9 + 6] = face.getNormals().get(2).getX();
            tempVn[i * 9 + 7] = face.getNormals().get(2).getY();
            tempVn[i * 9 + 8] = face.getNormals().get(2).getZ();

            tempVt[i * 6]     = face.getUvws().get(0).getX();
            tempVt[i * 6 + 1] = face.getUvws().get(0).getY();
            tempVt[i * 6 + 2] = face.getUvws().get(1).getX();
            tempVt[i * 6 + 3] = face.getUvws().get(1).getY();
            tempVt[i * 6 + 4] = face.getUvws().get(2).getX();
            tempVt[i * 6 + 5] = face.getUvws().get(2).getY();

            indices[i * 3]     = (short) (i * 3);
            indices[i * 3 + 1] = (short) (i * 3 + 1);
            indices[i * 3 + 2] = (short) (i * 3 + 2);
        }

        _vb = ByteBuffer.allocateDirect(tempV.length
                * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _vb.put(tempV);
        _vb.position(0);

        _tcb = ByteBuffer.allocateDirect(tempVt.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _tcb.put(tempVt);
        _tcb.position(0);

        _nb = ByteBuffer.allocateDirect(tempVn.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _nb.put(tempVn);
        _nb.position(0);

        _ib = ByteBuffer.allocateDirect(indices.length
                * SHORT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
        _ib.put(indices);
        _ib.position(0);
    }

    public FloatBuffer getVertices()
    {
        return _vb;
    }

    public FloatBuffer getTexCoords()
    {
        return _tcb;
    }

    public ShortBuffer getIndices()
    {
        return _ib;
    }

    public FloatBuffer getNormals() {
        return _nb;
    }
}

【讨论】:

  • 有没有人写过任何 iOS 等价物?
猜你喜欢
  • 2011-06-14
  • 1970-01-01
  • 2011-05-21
  • 2013-03-16
  • 1970-01-01
  • 2020-02-24
  • 2012-02-23
  • 2012-03-05
  • 2011-07-10
相关资源
最近更新 更多