simon-heinen / droidar

DroidAR Mobile Locationbased Augmented Reality Framework for Android
GNU General Public License v3.0
225 stars 275 forks source link

Positioning external .obj 3D objects on Marker #8

Open bharatparikh opened 11 years ago

bharatparikh commented 11 years ago

I am using ModelLoaderAdapter, ARMarker along with DroidAR to load external .obj models. The model is loaded fine long with its texture but is not positioned on the Marker. Loading a simple cube positions it fine on the Marker but in the same code when I replace the cube with a .obj model the positioning goes off. I tried manually positioning the object by creating a Vec() object for position and rotation but couldn't position it correctly on the Marker (also not sure if this is the correct way to do it).

Following is a snippet of code being used (trimmed for brevity):

public class MyExternalModelSetup extends MarkerDetectionSetup {
        private MarkerObjectMap mMarkerObjectMap; 

         //since the external model is being loaded asynchronously we don't have it yet with us to load into the markerobject map hence store the map in a local variable for later use
    @Override
    public void _a3_registerMarkerObjects(MarkerObjectMap markerObjectMap) {
        mMarkerObjectMap = markerObjectMap;
    }

        //loading the external model in this method since it gives a renderer object to work with which is required while loading an external object
    @Override
    public void _b_addWorldsToRenderer(GL1Renderer renderer,
            GLFactory objectFactory, GeoObj currentPosition) {
        renderer.addRenderElement(world);
        GDXConnection.init(myTargetActivity, renderer);

//once the model is loaded put it in the markerobjectmap thus associating it with a markerid
        new ModelLoader(renderer, mFileName, mTextureName) {
            @Override
            public void modelLoaded(MeshComponent gdxMesh) {
                mMarkerObjectMap.put(getSimpleMeshPlacer(mMarkerId, gdxMesh, camera));
            }
        };
}

    @Override
    public void _c_addActionsToEvents(EventManager eventManager,
            CustomGLSurfaceView arView, SystemUpdater updater) {
        arView.addOnTouchMoveListener(new ActionMoveCameraBuffered(camera, 5, 25));
        Action rot = new ActionRotateCameraBuffered(camera);
        updater.addObjectToUpdateCycle(rot);
        eventManager.addOnOrientationChangedAction(rot);
        eventManager.addOnTrackballAction(new ActionMoveCameraBuffered(camera, 1, 25));

    }

    private SimpleMeshPlacer getSimpleMeshPlacer(int markerId, MeshComponent mesh, GLCamera c) {
        SimpleMeshPlacer meshPlacer = new SimpleMeshPlacer(markerId, mesh, c) {
            boolean firstTime = true;

            @Override
            public void setObjectPos(Vec positionVec) {
                if (firstTime) {
                    firstTime = false;
            myTargetMesh.addChild(GLFactory.getInstance().newCoordinateSystem());
                    Obj aNewObject = new Obj();
                    aNewObject.setComp(myTargetMesh);
                    world.add(aNewObject);
                }
                myTargetMesh.setPosition(positionVec);
            }

            @Override
            public void setObjRotation(float[] rotMatrix) {
                if (myTargetMesh != null) {
                    myTargetMesh.setRotationMatrix(rotMatrix);
                }
            }
        };
        return meshPlacer;
    }   
}

public class SimpleMeshPlacer extends BasicMarker {
    protected MeshComponent myTargetMesh;

    public SimpleMeshPlacer(int id, MeshComponent mesh, GLCamera camera) {
        super(id, camera);
        myTargetMesh = mesh;
    }

    @Override
    public void setObjRotation(float[] rotMatrix) {
        myTargetMesh.setRotationMatrix(rotMatrix);
    }

    @Override
    public void setObjectPos(Vec positionVec) {
        myTargetMesh.setPosition(positionVec);
    }
}   

What is that I am doing wrong here? Please help.

simon-heinen commented 11 years ago

There is also a setup for multiple markers which takes the current camera rotation translation and calculates the markers world position and translation instead of changing the camera rotation and translation. so the marker will be placed in the world instead of being the center of the world. maybe this code might help you? Try to use only the rotation or only the position for the object to figure out which one is the problem.

bharatparikh commented 11 years ago

Thanks for your reply. Meanwhile, I tried scaling down the object to about 5% of its current size in all dimensions and it seemed to do the trick. Seems like the camera was getting placed inside the object because of its size. The 3D object was prepared in Blender and exported as a .obj file. I will try out your suggestion about the multiple marker setup and share the results.

simon-heinen commented 11 years ago

Sounds good :) If you want also share some screenshots ;)

On Fri, Jul 5, 2013 at 12:01 PM, bharatparikh notifications@github.comwrote:

Thanks for your reply. Meanwhile, I tried scaling down the object to about 5% of its current size in all dimensions and it seemed to do the trick. Seems like the camera was getting placed inside the object because of its size. The 3D object was prepared in Blender and exported as a .obj file. I will try out your suggestion about the multiple marker setup and share the results.

— Reply to this email directly or view it on GitHubhttps://github.com/bitstars/droidar/issues/8#issuecomment-20510166 .