javagl / Obj

A simple Wavefront OBJ file loader
Other
181 stars 38 forks source link

Can I use this library for load obj and mtl files in Android for vuforia? #16

Closed rkoshti closed 1 year ago

rkoshti commented 5 years ago

Can I use this library for load obj and mtl files in Android for vuforia?

If yes can you please suggest a way ?

Thanks

javagl commented 5 years ago

I'm not so deeply familiar with Android, but this library is a plain Java library that is available as a JAR in Maven Central, and it is also used in other Android projects (https://github.com/google-ar/arcore-android-sdk ), so this part is definitely possible.

Regarding the Vuforia engine: I don't know this one. But the library loads OBJ and MTL files, and offers the geometry data (optionally in a form that is intended for rendering, e.g. with OpenGL). So I don't see a reason why it should not work.

(I cannot download the Vuforia samples. A basic rendering example could help to answer with more details)

rkoshti commented 5 years ago

I am also not much familiar with vuforia i have just started vuforia implementation. But i have a sample code available if you need that i can provide you that just drop your email and i will contact you there.

Here is the basic randerer function:

 private void renderModel(float[] projectionMatrix, float[] viewMatrix, float[] modelMatrix, int textureIndex)
    {
        MeshObject model;
        float[] modelViewProjection = new float[16];

        // Apply local transformation to our model
        if (mActivityRef.get().isDeviceTrackingActive())
        {
            Matrix.translateM(modelMatrix, 0, 0, -0.06f, 0);
            Matrix.rotateM(modelMatrix, 0, 90.0f, 1.0f, 0, 0);
            Matrix.scaleM(modelMatrix, 0, BUILDING_SCALE, BUILDING_SCALE, BUILDING_SCALE);

            model = mBuildingsModel;
        }
        else
        {
            Matrix.translateM(modelMatrix, 0, 0, 0, OBJECT_SCALE_FLOAT);
            Matrix.scaleM(modelMatrix, 0, OBJECT_SCALE_FLOAT, OBJECT_SCALE_FLOAT, OBJECT_SCALE_FLOAT);

            model = mTeapot;
        }

        // Combine device pose (view matrix) with model matrix
        Matrix.multiplyMM(modelMatrix, 0, viewMatrix, 0, modelMatrix, 0);

        // Do the final combination with the projection matrix
        Matrix.multiplyMM(modelViewProjection, 0, projectionMatrix, 0, modelMatrix, 0);

        // Activate the shader program and bind the vertex and tex coords
        GLES20.glUseProgram(shaderProgramID);

        GLES20.glVertexAttribPointer(vertexHandle, 3, GLES20.GL_FLOAT, false, 0, model.getVertices());
        GLES20.glVertexAttribPointer(textureCoordHandle, 2, GLES20.GL_FLOAT, false, 0, model.getTexCoords());

        GLES20.glEnableVertexAttribArray(vertexHandle);
        GLES20.glEnableVertexAttribArray(textureCoordHandle);

        // Activate texture 0, bind it, pass to shader
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures.get(textureIndex).mTextureID[0]);
        GLES20.glUniform1i(texSampler2DHandle, 0);

        // Pass the model view matrix to the shader
        GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, modelViewProjection, 0);

        // Finally draw the model
        if (mActivityRef.get().isDeviceTrackingActive())
        {
            GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, model.getNumObjectVertex());
        }
        else
        {
            GLES20.glDrawElements(GLES20.GL_TRIANGLES, model.getNumObjectIndex(), GLES20.GL_UNSIGNED_SHORT, model.getIndices());
        }

        // Disable the enabled arrays
        GLES20.glDisableVertexAttribArray(vertexHandle);
        GLES20.glDisableVertexAttribArray(textureCoordHandle);
    }
public void initRendering()
    {
        if (mTextures == null)
        {
            return;
        }

        GLES20.glClearColor(0.0f, 0.0f, 0.0f, Vuforia.requiresAlpha() ? 0.0f
                : 1.0f);

        for (Texture t : mTextures)
        {
            GLES20.glGenTextures(1, t.mTextureID, 0);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, t.mTextureID[0]);
            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
                    GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
                    GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
            GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,
                    t.mWidth, t.mHeight, 0, GLES20.GL_RGBA,
                    GLES20.GL_UNSIGNED_BYTE, t.mData);
        }

        shaderProgramID = SampleUtils.createProgramFromShaderSrc(
                CubeShaders.CUBE_MESH_VERTEX_SHADER,
                CubeShaders.CUBE_MESH_FRAGMENT_SHADER);

        vertexHandle = GLES20.glGetAttribLocation(shaderProgramID,
                "vertexPosition");
        textureCoordHandle = GLES20.glGetAttribLocation(shaderProgramID,
                "vertexTexCoord");
        mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgramID,
                "modelViewProjectionMatrix");
        texSampler2DHandle = GLES20.glGetUniformLocation(shaderProgramID,
                "texSampler2D");

        if(!mModelIsLoaded)
        {
            mTeapot = new Teapot();

            try {
                mBuildingsModel = new SampleApplication3DModel();
                mBuildingsModel.loadModel(mActivityRef.get().getResources().getAssets(),
                        "ImageTargets/Buildings.txt");
                mModelIsLoaded = true;
            } catch (IOException e)
            {
                Log.e(LOGTAG, "Unable to load buildings");
            }

            // Hide the Loading Dialog
            mActivityRef.get().loadingDialogHandler
                    .sendEmptyMessage(LoadingDialogHandler.HIDE_LOADING_DIALOG);
        }
    }

 **Buildings.txt** file 

[buildings.zip](https://github.com/javagl/Obj/files/3211968/buildings.zip)

**Mesh Object**

public abstract class MeshObject {

public enum BUFFER_TYPE
{
    BUFFER_TYPE_VERTEX, BUFFER_TYPE_TEXTURE_COORD, BUFFER_TYPE_NORMALS, BUFFER_TYPE_INDICES
}

public Buffer getVertices()
{
    return getBuffer(BUFFER_TYPE.BUFFER_TYPE_VERTEX);
}

public Buffer getTexCoords()
{
    return getBuffer(BUFFER_TYPE.BUFFER_TYPE_TEXTURE_COORD);
}

public Buffer getNormals()
{
    return getBuffer(BUFFER_TYPE.BUFFER_TYPE_NORMALS);
}

public Buffer getIndices()
{
    return getBuffer(BUFFER_TYPE.BUFFER_TYPE_INDICES);
}

protected Buffer fillBuffer(double[] array)
{
    // Convert to floats because OpenGL doesn't work on doubles, and manually
    // casting each input value would take too much time.
    // Each float takes 4 bytes
    ByteBuffer bb = ByteBuffer.allocateDirect(4 * array.length);
    bb.order(ByteOrder.LITTLE_ENDIAN);
    for (double d : array)
        bb.putFloat((float) d);
    bb.rewind();

    return bb;

}

protected Buffer fillBuffer(float[] array)
{
    // Each float takes 4 bytes
    ByteBuffer bb = ByteBuffer.allocateDirect(4 * array.length);
    bb.order(ByteOrder.LITTLE_ENDIAN);
    for (float d : array)
        bb.putFloat(d);
    bb.rewind();

    return bb;

}

protected Buffer fillBuffer(short[] array)
{
    // Each short takes 2 bytes
    ByteBuffer bb = ByteBuffer.allocateDirect(2 * array.length);
    bb.order(ByteOrder.LITTLE_ENDIAN);
    for (short s : array)
        bb.putShort(s);
    bb.rewind();

    return bb;

}

protected abstract Buffer getBuffer(BUFFER_TYPE bufferType);

public abstract int getNumObjectVertex();

public abstract int getNumObjectIndex();

}

javagl commented 1 year ago

Others will appreciate the code that you provided. But since this is unrelated to the Obj library, I'll close this.