1
\$\begingroup\$

I'm trying to ray-cast mouse clicks to the surface of a sphere (from which point, I'm going to get the coordinates of the vertex of the sphere's mesh that are closest to the click). The following Raycast code is not working, however, and I can't seem to figure out why:

public Vector3 rayCastToSphere(Vector3 origPos, Vector3 sphereCenter, Vector3 dir, float radius) { Vector3 output = new Vector3(); ray.set(origPos, sphereCenter); ray.direction.set(dir); ray.origin.set(origPos); boolean intersection = Intersector.intersectRaySphere(ray, sphereCenter, radius, output); Gdx.app.log("SphereCast Debug", output.toString() + ", Did it Intersect? " + intersection); return output; } 

My logging code here reveals that the raycasted click is never intersecting the sphere (thus it isn't returning a point at which the sphere is intersecting the click).

And this is the code I'm using to call the raycast from when the screen is clicked:

SphereRayCaster sr = new SphereRayCaster(); @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { Gdx.app.log("CamPos Debug", cam.position.toString()); Vector3 touchPos = new Vector3(screenX, screenY, 0f); Gdx.app.log("TouchPos", touchPos.toString()); Vector3 projectedTouchPos = cam.unproject(touchPos); projectedTouchPos.z = cam.position.z; Gdx.app.log("Projected TouchPos", projectedTouchPos.toString()); Vector3 rayCastOutput = sr.rayCastToSphere(projectedTouchPos, cam.direction, hexasphere.getCenter(), sphere.getRadius()); Gdx.app.log("Raycast Output Debug", rayCastOutput.toString()); //hexasphere.everyOther(); return true; } 
\$\endgroup\$
6
  • \$\begingroup\$ Well for starters where is ray in the 1st method you posted? There is no parameter or variable called ray. \$\endgroup\$ Commented Dec 6, 2024 at 18:48
  • \$\begingroup\$ @ray It is a member variable of the class. \$\endgroup\$ Commented Dec 6, 2024 at 19:47
  • \$\begingroup\$ Are you using an orthographic camera projection, or perspective? Where is your camera placed in your world and how is it oriented? And where is your sphere? (I ask these questions because the code here makes some choices that could work for certain answers, but will not work in the general case, and I want to figure out which of those special-vs-general distinctions are relevant for your application) \$\endgroup\$ Commented Dec 6, 2024 at 22:50
  • \$\begingroup\$ I'm using a Perspective Camera. It is positioned by default at (10, 10, 10), and the render code ensures that it is always facing the sphere (the center of the sphere is (0, 0, 0)). \$\endgroup\$ Commented Dec 7, 2024 at 6:17
  • \$\begingroup\$ @DMGregory The camera rotates around the sphere by 1 degree in different directions whenever w/s/a/d are pressed. \$\endgroup\$ Commented Dec 7, 2024 at 6:22

1 Answer 1

2
\$\begingroup\$

You are setting the origin of your Ray to the position of the Camera, it should be the unprojected position of the clicked screen-coordinate.

You can simplify your implementation by leaning more on already existing functionality in libGDX, for example, Camera already has a method for constructing a pick-ray.

If you change your touchDown method to this, it should pick and highlight the correct tile:

public boolean touchDown(int screenX, int screenY, int pointer, int button) { Ray ray = cam.getPickRay(screenX, screenY); Vector3 intersection = new Vector3(); // TODO: This should be a member to avoid allocation here, or pooled somehpw boolean intersects = Intersector.intersectRaySphere(ray, hexasphere.getCenter(), hexasphere.getRadius(), intersection); if (intersects) { IcoSphereTile touched = hexasphere.getClosestTile(hexasphere.projectToSphere(intersection)); touched.setTileType(IcoSphereTile.TileType.GRASS); return true; } else return false; } 
\$\endgroup\$
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.