Raycasting of box - which side of box(voxel) i am looking at

Post Reply
Teyn
Posts: 6
Joined: Wed Jan 07, 2015 10:13 am

Raycasting of box - which side of box(voxel) i am looking at

Post by Teyn »

Hi, i am working on a voxel Game(minecraft-clone) using Java and libGDX as a framework, so that means i am using bulletWraper, but it has the same functions as a bullet, doesnt it?

Now to my problem: I am using this code:

Code: Select all

private static final Vector3 rayFrom = new Vector3();
private static final Vector3 rayTo = new Vector3();
private static final ClosestRayResultCallback callback = new ClosestRayResultCallback(rayFrom, rayTo);

public static btCollisionObject rayTest(btCollisionWorld collisionWorld, Ray ray) {
    rayFrom.set(ray.origin);
    // 50 meters max from the origin
    rayTo.set(ray.direction).scl(50f).add(rayFrom);

    // we reuse the ClosestRayResultCallback, thus we need to reset its
    // values
    callback.setCollisionObject(null);
    callback.setClosestHitFraction(1f);
    callback.getRayFromWorld().setValue(rayFrom.x, rayFrom.y, rayFrom.z);
    callback.getRayToWorld().setValue(rayTo.x, rayTo.y, rayTo.z);

    collisionWorld.rayTest(rayFrom, rayTo, callback);

    if (callback.hasHit()) {
        return callback.getCollisionObject();
    }

    return null;
}
and then use that function:

Code: Select all

private Viewport pickingViewport;
    private btCollisionWorld collisionWorld;

    // a constructor which takes a Viewport and the collision world and stores them
    public BulletInputProcessor(...) { ... }

    public boolean click(screenX, screenY) {
            Ray pickRay = pickingViewport.getPickRay(screenX, screenY);

            btCollisionObject body = rayTest(collisionWorld, pickRay); //using our function, which returns an collision object.
            if (body != null) {
                // do whatever you want with this body now
                return true;
            }

        return false;
    }
And well, this works for destroying bodies, in my case. As i saied, i am working on VoxelGame, and to place a object, i need the face of block i am clicking. Isnt there any solution for that? I am constructing my CollisionObject(that are stored in CollisionWorld) pretty simply, i dont think i have to post it in here.

So my question is: How to know which side of block i am clicking? Cant I just add some magic lines to my boxShape? Probably cant. :D
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: Raycasting of box - which side of box(voxel) i am lookin

Post by xexuxjy »

Just having the collision object returned means you can't directly find that out... it would be more useful if you could get access to the callback object as that should have the collision point, distance etc as well as the collision shape.
Failing that you'll have do some work in Java to calculate that information again , though at least this time you'll have your object so can get it's position and dimensions.
Teyn
Posts: 6
Joined: Wed Jan 07, 2015 10:13 am

Re: Raycasting of box - which side of box(voxel) i am lookin

Post by Teyn »

well, i can calculate dimensions and those things. I have access to full bullet body, of course including shape. But from where to getrhat hit position?
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: Raycasting of box - which side of box(voxel) i am lookin

Post by xexuxjy »

You could modify the libgdx code to give you more access to the callback info, something like the below, though it's not particularly thread safe. That would give you the hit point and contact normal. But you'd still need to use that to decide which face had been hit.

public static ClosestRayResultCallback rayTestWithCallback(btCollisionWorld collisionWorld, Ray ray) {
rayFrom.set(ray.origin);
// 50 meters max from the origin
rayTo.set(ray.direction).scl(50f).add(rayFrom);

// we reuse the ClosestRayResultCallback, thus we need to reset its
// values
callback.setCollisionObject(null);
callback.setClosestHitFraction(1f);
callback.getRayFromWorld().setValue(rayFrom.x, rayFrom.y, rayFrom.z);
callback.getRayToWorld().setValue(rayTo.x, rayTo.y, rayTo.z);

collisionWorld.rayTest(rayFrom, rayTo, callback);

if (callback.hasHit()) {
return callback;
}

return null;
}
Post Reply