Mouse events
In class we showed how we added to the library
so that we can get and respond to mouse events.
To do that, we override the definitions of these methods:
canvas.onDrag = (x, y) => { };
canvas.onMove = (x, y) => { };
canvas.onPress = (x, y) => { };
canvas.onRelease = (x, y) => { };
The arguments x
and y
represent the position of the cursor on the canvase,
where x ranges between -1.0 (left) and +1.0 (right),
and
y ranges between -1.0 (bottom) and +1.0 (top).
Keyboard events
In class we also showed how we added to the library
so that we can get and respond to keyboard events.
To do that, we override the definitions of these methods:
canvas.onKeyPress = key => { };
canvas.onKeyRelease = key => { };
The argument key
is the numerical keycode
for the key on the keyboard being pressed or released.
In class we showed how to use mouse and keyboard
events to let the user interactively
change various aspects of the animation.
Ray tracing to a triangle
We also showed how to trace a ray into the scene
to see which objects are at the cursor.
We implemented just the simple case of the
object being a sphere,
but we also talked about how to ray trace to
a triangle. That could be used to
allow us to
ray trace to an entire triangle mesh.
To ray trace to a triangle, the basic idea is that given three triangle vertices A,B,C,
we first ray trace to the
plane P that contains points A,B and C.
Then we need to check whether the
point S where the ray intersects P (where P • S == 0) is inside the triangle.
In other words, find S = V + tW for some t such that
P • S == 0.
Now consider just the edge
from vertex A to vertex B.
We can compute the equation of the plane Q
which is perpendicular to P
and which contains A and B.
Point S is "inside" this edge if
S is on the
same side of Q as vertex C.
This will be true when (Q • S) * (Q • C) > 0.
We do this for all three edges.
If S is inside all three edges,
then it is inside the triangle,
and we know that the ray has hit the triangle.
Ray tracing to a triangle mesh shape
To do hit testing on an entire triangle mesh,
we ray trace to all of its triangles.
If the ray hits any of those triangles,
then the ray has hit the mesh.
If the mesh is very complex,
we can do hit testing on a simplified
version of the mesh,
which is roughly the same shape as the rendered mesh,
but contains fewer triangles.
To do this hit testing, it would work to
transform all of the vertices of the mesh by
our transform matrix M.
But that can get expensive.
So in practice, it is better instead to transform the ray (V,W)
by the inverse matrix M-1.
This provides the same result at much lower computational expense.
Videos we watched
Homework -- due before class on Wednesday April 14
Starting with the code we implemented in class,
which is in hw8.zip,
implement interactive buttons and sliders in the 3D scene,
and possibly other kinds of widgets.
-
A button should have two parts:
the frame (which does not move)
and the button itself,
which depresses when the user presses down on it.
The frame, for example, can be made out of a cube or a cylinder.
The button itself can be made, for example, out of a cube, a cylinder or a sphere.
When the user presses a button, you should make
something happen in the 3D scene.
For example, some object could change color,
or something could start spinning.
Extra credit:
Try to implement two different types of buttons:
(a)
A button that makes something happen only while the button is pressed, and
(b)
a toggle button that turns something on when it is pressed and released,
and then turns something off when it is again pressed and released.
-
A slider should have at least two parts:
the frame (which does not move)
and the slide itself,
which moves along the frame when the user drags the cursor,
but cannot slide off the end of the frame.
The frame, for example, can be made out of a cube.
The slide can be made, for example, out of a cube or a cylinder.
Optionally your slider could also have other parts,
such as a visible rail that that slider moves along.
When the user adjusts a slider, you should make
something change in the 3D scene.
For example, some object could vary continuously in color,
or something could spin at a faster or slower rate.
For example, you can use three sliders side by side to
adjust some object's red, green and blue
color components, respectively.
For this use, it is good design practice to tint the sliders themselves
red, green and blue, respectively.
Extra credit:
Try creating your own kind of interactive widget,
such as a rotating dial,
or a choice panel
(a row of buttons such that when one button is pressed, the others all lift up).
Feel free to be creative.
Hint:
Tracking the active part of a button, or the moving slide of a slider,
is easier than you might think.
No matter what shape you are tracking with your cursor,
whether it is a cube or a cylinder or a sphere or something else,
you can use an invisible sphere as the target object.
You don't need an actual sphere mesh for this, only
the
S = [centerx,centery,centerz,radius]
data to pass into the third argument of your
rayHitsSphere(V,W,S)
function.
Just make sure that the center of sphere S
is the same as the center of your cube or cylinder
or whatever shape, and that the radius of
sphere S
is about the same as half the width of your shape.
You might want to tweak the radius
of S
a bit to see
what works best in practice.