Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - tulsi

#1
Support / Re: Fitting an object inside the screen.
August 28, 2020, 06:43:01 PM
Thanks for your support.

The rotation problem is solved.

Please watch the below video.
https://raw.githubusercontent.com/tulsiojha/data/master/elongated.mp4

I dont know how to explain this. But you can see while i am rotating the the object its getting elongated.
I think it is a camera problem.

But i dont know how to fix it.

Thank you.
#2
Support / Re: Fitting an object inside the screen.
August 21, 2020, 02:02:41 PM
This is the output after uncommenting those lines.



Facing Inward.
#3
Support / Re: Fitting an object inside the screen.
August 21, 2020, 01:11:48 PM
Thank you.

Yes the getBack() was not identity. I removed lookat() method and now the object is inverted.


I am using code as below:


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(150, 150, 150);

                sun = new Light(world);
                sun.setIntensity(40, 40, 40);

                for (File f: getFilesDir().listFiles()){

                    if (MimeTypeMap.getFileExtensionFromUrl(f.getName()).equalsIgnoreCase("jpg") || MimeTypeMap.getFileExtensionFromUrl(f.getName()).equalsIgnoreCase("png") || MimeTypeMap.getFileExtensionFromUrl(f.getName()).equalsIgnoreCase("jpeg")){
                        Log.d("Files", f.getName());
                        try {
                            TextureManager.getInstance().addTexture(f.getName(), new Texture(new FileInputStream(new File(getFilesDir(), f.getName()))));
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                }
                object3D = loadModel();
                world.addObject(object3D);
                world.getCamera().setPosition(0,0,-20);

                MemoryHelper.compact();
                if (master == null) {
                    Logger.log("Saving master Activity!");
                    master = jpct.this;
                }
            }

        }



    private Object3D loadModel() {
        Object3D[] model = new Object3D[0];
        try {
            model = Loader.loadOBJ(new FileInputStream(new File(getFilesDir(), "01Alocasia_obj.obj")), new FileInputStream(new File(getFilesDir(), "01Alocasia_obj.mtl")), 0.01f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        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;
    }
#4
Support / Re: Fitting an object inside the screen.
August 21, 2020, 12:14:58 PM
I dont know whether i will be able to solve this or not.

I have two more questions for now.

1. One of my object is about 19m width (for now not considering height)  in real world. And It fits well in the  screen at scale 1. Now what will happen if I will load that on bigger screen like tablet or smaller screen than that at same scale.


2. Initially without any transformation all of my object are getting rotated by some angle, how can i know that by what factor they are being rotated?

Thank you.
#5
Support / Re: Fitting an object inside the screen.
August 21, 2020, 11:52:01 AM
Thank you for your help.

I implemented that code as below.


float[] cor = getWorldSpaceBounds(object3D);
Log.d("Interact", "onScale: "+Interact2D.project3D2D(world.getCamera(),fb, new SimpleVector(cor[1], cor[3], cor[5])));
Log.d("Interact", "onScale: "+Interact2D.project3D2D(world.getCamera(),fb, new SimpleVector(cor[0], cor[2], cor[4])));


But I think Output is not accurate:

Interact: onScale: (828.88245, 1424.3342, 8.988686E-4)
Interact: onScale: (-425.23065, -14.657715, 0.002846251)


The 3D object is inside the screen but the coordinates seems like they are not matching. But by using polygonManager method output was correct.
I dont know if i am using syntax correctly. :) :)
#6
Support / Re: Fitting an object inside the screen.
August 21, 2020, 10:47:18 AM
Thank you AeroShark333 and EgonOlsen for your time.

As I am new to JPCT and 3D programming it will take some more time for me to understand these components.

I had searched on this forum and found some code related to my problem as below:

private Point[] get2DVertices(SimpleVector[] vertices3d, Camera theCamera, FrameBuffer buffer) {
        Point[] vertices = new Point[vertices3d.length];
        for (int i = 0; i < vertices.length; i++) {
            SimpleVector point = Interact2D.project3D2D(theCamera, buffer, vertices3d[i]);
            vertices[i] = new Point((int)(point.x+.5f), (int)(point.y+.5f));
        }
        return vertices;
    }
    public float[] get2DBounds(Camera theCamera, FrameBuffer buffer) {
        System.out.println("get2DBounds");
        object3D.enableLazyTransformations();
        PolygonManager polyManager = object3D.getPolygonManager();
        SimpleVector[] vertices3d = new SimpleVector[polyManager.getMaxPolygonID()*3];
        int currentPoly = 0;
        int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, minZ = Integer.MAX_VALUE;
        int maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE, maxZ = Integer.MIN_VALUE;
        for (int i = 0; i < vertices3d.length; i+=3) {
            vertices3d[i] = polyManager.getTransformedVertex(currentPoly, 0);
            vertices3d[i+1] = polyManager.getTransformedVertex(currentPoly, 1);
            vertices3d[i+2] = polyManager.getTransformedVertex(currentPoly++, 2);
        }
        Point[] vertices = this.get2DVertices(vertices3d, theCamera, buffer);
        for (int i = 0; i < vertices.length; i+=3) {
            if (minX > vertices[i].x)
                minX = vertices[i].x;
            if (minX > vertices[i+1].x)
                minX = vertices[i+1].x;
            if (minX > vertices[i+2].x)
                minX = vertices[i+2].x;
            if (maxX < vertices[i].x)
                maxX = vertices[i].x;
            if (maxX < vertices[i+1].x)
                maxX = vertices[i+1].x;
            if (maxX < vertices[i+2].x)
                maxX = vertices[i+2].x;
            if (minY > vertices[i].y)
                minY = vertices[i].y;
            if (minY > vertices[i+1].y)
                minY = vertices[i+1].y;
            if (minY > vertices[i+2].y)
                minY = vertices[i+2].y;
            if (maxY < vertices[i].y)
                maxY = vertices[i].y;
            if (maxY < vertices[i+1].y)
                maxY = vertices[i+1].y;
            if (maxY < vertices[i+2].y)
                maxY = vertices[i+2].y;
        }
        object3D.disableLazyTransformations();
//        return new float[](minX, minY, (int)Math.abs(maxX-minX), (int)Math.abs(maxY-minY));
        return new float[]{minX, minY, maxX, maxY};
    }


:) :) This code goes over my mind..

I think this one is the second solution as discussed by AeroShark333 and EgonOlsen.
But this code is quite expensive to run multiple times. It takes about 2 seconds to execute. May be there is another way for this method.

I even tried FOV method as below:

double height = Math.max(getSize(object3D).x, getSize(object3D).z);
double fov = world.getCamera().getFOV();
double distance =(height/2)/Math.tan(fov/2);
world.getCamera().setPosition(0,0,-distance);


But this gave wired results.
May be this method has something to do with type of camera.

I know I donot have concepts on 3D programming but I am trying to learn. It will take some time for me.

Thank you for your support.
#7
Support / Fitting an object inside the screen.
August 20, 2020, 07:33:55 AM
Hello once again!!

In my app I will most probably have only one object on screen at a time. But that object may not be the same object every time like it can be a car, a chair, or something else like that.
Now the problem is those object may not have same size. But I want them to fit inside the screen.

I am able to get the realworld size of the object by using following function. Also I can get the screen resolution. But I dont know how to make relationship between them so that I can scale them accordingly.

public static SimpleVector getSize(Object3D object){
        float[] bbox = object.getMesh().getBoundingBox();
        Log.i("Util","getSize-bbox:"+bbox);
        float s = object.getScale();
        Log.i("Util","getSize-scale:"+object.getScale());
        Object3D[] par;
        par = object.getParents();
        while(par.length>0){
            s = s*par[0].getScale();
            Log.i("Util","getSize-parent:"+par[0].getScale());
            par = par[0].getParents();
        }
        SimpleVector out = new SimpleVector((bbox[1]-bbox[0])*s,(bbox[3]-bbox[2])*s,(bbox[5]-bbox[4])*s);
        Log.i("Util", "getSize:"+out.toString());
        return out;
    }


Thank you.. :)
#8
I think i have solved it.

Below is the video result.
https://raw.githubusercontent.com/tulsiojha/data/master/improved.mp4

I have used object.setScale() method instead of camera.setFOV() method.
Below is the code for it.
class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {


        @Override
        public boolean onScale(ScaleGestureDetector detector) {
         mScaleFactor*= detector.getScaleFactor();
            cur=mScaleFactor;
            mScaleFactor = Math.max(0.5f,Math.min(mScaleFactor, 2f));

               if (thing.getScale() >=0.5 && mScaleFactor >=0.5){
                   thing.setScale(mScaleFactor);
               }
               if (thing.getScale()<0.5)
                   thing.setScale(1);


            Log.d("Scaled", ""+thing.getScale());
            return true;
        }

    }


I don't know if this is the good method to it do or not.
And Thanks for your help.
#9
Thanks for your time.

Sorry.
But it is not working as expected.

Below is the code. May be I am doing something wrong at other place.
        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(150, 150, 150);

                sun = new Light(world);
                sun.setIntensity(250, 250, 250);
               
                    for (File f: getFilesDir().listFiles()){

                        if (MimeTypeMap.getFileExtensionFromUrl(f.getName()).equalsIgnoreCase("jpg") || MimeTypeMap.getFileExtensionFromUrl(f.getName()).equalsIgnoreCase("png") || MimeTypeMap.getFileExtensionFromUrl(f.getName()).equalsIgnoreCase("jpeg")){
                            Log.d("Files", f.getName());
                            try {
                                TextureManager.getInstance().addTexture(f.getName(), new Texture(new FileInputStream(new File(getFilesDir(), f.getName()))));
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                Object3D[] model = new Object3D[0];
                model = loadModel();

                thing=Object3D.createDummyObj();
                thing.build();
               
                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());
                    temp.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
                    temp.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);
                    temp.build();
                    temp.strip();
                    world.addObject(temp);
                    temp.addParent(thing);
                    temp.addCollisionListener(collisionListener);

                }

                world.getCamera().setPosition(0, 0, -20);
                world.getCamera().lookAt(thing.getTransformedCenter());
                thing.rotateX(180);
                thing.rotateMesh();
                thing.translate(thing.getCenter().x, -10f, thing.getCenter().z);
                thing.translateMesh();

                MemoryHelper.compact();

                if (master == null) {
                    Logger.log("Saving master Activity!");
                    master = MainActivity.this;
                }
            }
        }

public void onDrawFrame(GL10 gl) {
            if (touchTurn != 0) {
                thing.rotateY(touchTurn);
                touchTurn = 0;
            }

            if (touchTurnUp != 0) {
                thing.rotateX(touchTurnUp);
                touchTurnUp = 0;
            }

            world.getCamera().setFOV(2-mScaleFactor);

            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() {
        Object3D[] model = new Object3D[0];
        try {
            model = Loader.loadOBJ(new FileInputStream(new File(getFilesDir(), "hammer.obj")), new FileInputStream(new File(getFilesDir(), "hammer.mtl")), 1f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return model;
    }


For scaling
  float preV=mScaleFactor, cur=mScaleFactor;
    class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {


        @Override
        public boolean onScale(ScaleGestureDetector detector) {
         mScaleFactor*= detector.getScaleFactor();
            cur=mScaleFactor;
            mScaleFactor = Math.max(0.5f,Math.min(mScaleFactor, 1.5f));

            if (preV>cur){
                Log.d("Scale", "onScale: "+"down");
                if (mScaleFactor >=0.5 && mScaleFactor<=1.5){
                    world.getCamera().moveCamera(Camera.CAMERA_MOVEDOWN, mScaleFactor*1f);
                }
            }else {
                Log.d("Scale", "onScale: "+"up");
                if (mScaleFactor >=0.5 && mScaleFactor<=1.5){
                    world.getCamera().moveCamera(Camera.CAMERA_MOVEUP, mScaleFactor*1f);
                }
            }
            preV = mScaleFactor;
//            cube0.scale();

            Log.d("SCaled", ""+"prev: "+preV+" cur: "+cur);
            return true;
        }

    }


I Hope you don't mind.. :)
#10
Thanks for your reply.

I applied the translation and it worked but now another problem occurred.

When I zoom in or out its seems like it is moving to another place.

I have attached the video link below.

https://raw.githubusercontent.com/tulsiojha/data/master/video.mp4
#11
Support / place an object to top part of the screen
August 18, 2020, 07:39:24 AM
Hello,

I am new to JPCT, currently I am able to load .obj files and apply scale and rotation gesture.

Initially, when the object loads on the screen it appears at the center of screen. But I want it to be at top part of the screen.

Below is the picture of what I have now.



But I want as below.





Thanks. :) :)