viromedia / virocore

ViroCore cross-platform AR/VR renderer
MIT License
370 stars 108 forks source link

Confused with rayIntersectPlane #35

Open geetves opened 6 years ago

geetves commented 6 years ago

Hi, Can you please tell me how rayIntersectPlane works? If possible explain with simple example?

https://developer.viromedia.com/virocore/reference/com/viro/core/Vector.html#rayIntersectPlane(com.viro.core.Vector,%20com.viro.core.Vector,%20com.viro.core.Vector,%20com.viro.core.Vector)

Thanks

VikAdvani commented 6 years ago

Hi @geetves, Here is a sample showing how that method works:

        Vector rayDirection = new Vector(0, 0, -1);
        Vector rayOrigin = new Vector(0, 0,0);
        Vector pointOnPlane = new Vector(0, 0, -5);
        Vector normalOfPlane = new Vector(0, 0, 1);

        Vector collidePoint = new Vector();
        if(rayDirection.rayIntersectPlane(pointOnPlane, normalOfPlane, rayOrigin, collidePoint)) {
            System.out.println("Point: " + collidePoint.x + "," + collidePoint.y + ", " + collidePoint.z);
       }

In the sample above, we create a new vector called rayDirection with a x,y,z of (0, 0, -1), this will serve as the direction of the ray used for finding an intersection with a plane. Then we define the origin of the ray at (0,0,0) and name that vector rayOrigin. So now are ray is defined with an origin of (0,0,0) pointing in the direction of (0,0,-1).

Next we define our plane to intersect with. A plane is defined by a point on that plane and the normal vector of the plane. In this example the point on plane is(0,0, -5), defined in the vector named pointOnPlane and the normal is (0,0,1), defined in the vector named normalOfPlane. In this case the plane lies on the z axis at -5 and is pointing towards positive z.

Finally, the collidePoint vector is used pass information back. We define an empty vector and only use this value if rayIntersectPlane returns true.

Now we invoke rayIntersectPlane on the vector that represents the direction of the ray, which is rayDirection. In this example it will return true and print out the collide point which will be (0,0, -5). This is point on the plane that the ray collided with.

Let me know if this helps or if you need more info!

geetves commented 6 years ago

Thanks for the explanation. Actually I am creating an application where 3d object is resting on arplane. Now I have attached drag listener to the 3d object. On drag event I want to find if object is still on the ar plane or not. Is it achievable using this method?

In this method I think the plane is of infinite dimension, but ar plane is a finite dimension.

VikAdvani commented 6 years ago

Hi @geetves, You are correct in that this is a test of a plane of infinite dimension. What you can do is use rayIntersectPlane first, then if a collision occurred, check the collide point and use the getExtant() and getCenter() methods of ARPlaneAnchor to compute whether the collide point lies within the ARPlaneAnchor itself.

Those methods should give you the information you need to compute whether you are intersecting with the plane or not. Here's some more info describing the math: https://stackoverflow.com/questions/2752725/finding-whether-a-point-lies-inside-a-rectangle-or-not

Let me know if this helps. Thanks!

geetves commented 6 years ago

By rayIntersectTest, do you mean rayIntersectPlane? Or is this the method I don't know of where you can simply test the ray hit test by giving arguments, origin of the ray and direction of the ray?

VikAdvani commented 6 years ago

Hi @geetves, sorry, I mistyped, I meant rayIntersectPlane!

geetves commented 6 years ago

Yes, but OnDrag event of 3d object I don't have pointOnPlane.

VikAdvani commented 6 years ago

Hi @geetves, based on your use case the point on plane would be the ARPlane not the 3dObject which has the onDrag event callback. In that case, the point on plane would simply be getCenter() of ARPlaneAnchor. Let me know if I'm misunderstanding or if this makes sense. Thanks!

geetves commented 6 years ago

Yes, you are correct. On OnDrag event of 3d object, I don't know on which ARPlane the object is anchored to. My issue is finding the ARPlane the 3d object is currently resting on. Now since I don't know the ARPlane of the 3dObject I cannot get poinOnPlane of that ARPlane to use in rayIntersectPlane method. It would be cool if there is a method for hit testing taking only source point and direction in argument and returns all real-world features that are intersected by the ray.

performARHitTestWithPosition is one such method but its restriction is that its source point is only camera's current position.

VikAdvani commented 6 years ago

Hi @geetves, I'll put this suggestion into our backlog. Curious, how are you placing your 3d object in the world? If you are adding the 3D object to an ARNode, you can store the ARPlaneAnchor that comes with it in the onAnchorFound callback of ARScene.Listener. This way you can reference it to see if the object is dragging off the plane it is anchored to.

geetves commented 6 years ago

I am using ARPlacingObjects example provided by virocore as a reference

dthian commented 6 years ago

Hi @geetves, just wanted to ask, is your goal above an attempt at dragging a 3D object that is locked within the boundaries of an ARPlane?