Game Development Reference
In-Depth Information
3.5P
ICKING
As we saw earlier,
unprojecting
is commonly used to determine if the player may be trying
to interact with a game object in 3D space.
Givenaninputposition
i={i
x
, i
y
, i
z
}
wewillcalculatearaythatwecanusewithinourgame's
world to determine if there are any objects that intersects it.
First for
i
z
= 0, which scales the unprojected point towards the near clipping plane
Then, for
i
z
= 1, which scales the unprojected point towards the far clipping plane
Having two points in world space we can now calculate a normalized direction vector
We can now create a ray such that its position is
p0
and it points in the direction
v
, we send
this ray to our world database or physics system and we can perform intersection testing to
find what objects lie behind the input position I = {i
x
, i
y
, i
z
}.
ray GetRayFromMouseClick(const vector2& screenPosition, const matrix& world, const matrix& view, const matrix& projection, const view-
port& viewport)
{
vector3 p0 = screenPosition;
p0.z() = 0.f;
vector3 p1 = screenPosition;
p1.z() = 1.f;
p0 = viewport.Unproject(p0, world, view, projection);
p1 = viewport.Unproject(p1, world, view, projection);
vector3 direction = vector3::Normalize(p1 - p0);
return ray(p0, direction);
}
Now that we have a ray we will need to use it to query the game world or physics system to
findifthereareanycollisions,thiswilldependlargelyonhoweachgameorganizesitsdata,
but typically you will have an engine function we can call that will return a list of contacts
that intersect with the ray.