Tutorial 08 Animation and User Input
1. Animation
This tutorial implements a WebGL animation application, based upon the work done in the previous tutorials. The animation will implement two types of motions: the motion of the box on top of the table and real-time viewport control (or scene navigation). The motion of the box will involve a upward motion of 5 units (along y axis) in approximately 3 seconds and then followed by a circular motion along a path within the horizontal plane at a speed of one revolution per 2-second. The navigation control includes moving and rotating the scene along or around the coordinate axes at users command via mouse and key actions. These actions are achieved by modifying the modelview transformation of the entire scene (e.g., for viewpoint control) or of the individual object (e.g., the flying box). Modifications to the modelview transformation have to be implemented in draw () function so that the modelview transformation will be updated in each animation frame.
The animation loop in WebGL can be accessed by calling requestAnimFrame(draw) at the beginning of the draw function. The call requests for the next frame to be drawn by invoking the draw function when the current call to draw function returns, therefore a rendering loop is formed. The returned value of the function call requestAnimFrame(draw)is a non-zero integer. It is assigned to a variable, requested, in the program. At the beginning, the current system time is also taken. The time will be used to estimate the duration of the animation and the time to render a frame, which allows us to calculate the current position of an object from its speed specification.
Copyright By Assignmentchef assignmentchef
requestId = requestAnimFrame(draw); currentTime = Date.now();
if (animationStartTime === undefined) {
animationStartTime = currentTime; }
// update the modelview transformation for the entire scene mat4.translate(pwgl.modelViewMatrix, [0.0, transY, transZ],
pwgl.modelViewMatrix); mat4.rotateX(pwgl.modelViewMatrix, xRot/50,
pwgl.modelViewMatrix); mat4.rotateY(pwgl.modelViewMatrix, yRot/50,
pwgl.modelViewMatrix); yRot = xRot =transY=transZ=0;
drawFloor(); drawTable();
//Draw box.
if (pwgl.y < 5) {// First move the box vertically from its original position on // top of the table (where y = 2.7) to 5 units above the// floor (y = 5). Let this movement take 3 secondspwgl.y = 2.7+(currentTime-pwgl.animationStartTime)/3000 * (5.0-// Then move the box in a circle where one revolution takes 2 // seconds pwgl.angle = (currentTime – pwgl.animationStartTime)/2000*2*Math.PI % (2*Math.PI); pwgl.x = Math.cos(pwgl.angle) * pwgl.circleRadius; pwgl.z = Math.sin(pwgl.angle) * pwgl.circleRadius;mat4.translate(pwgl.modelViewMatrix, [pwgl.x, pwgl.y, pwgl.z], pwgl.modelViewMatrix);mat4.scale(pwgl.modelViewMatrix, [0.5, 0.5, 0.5], pwgl.modelViewMatrix);uploadModelViewMatrixToShader();drawCube(pwgl.boxTexture); …2. User inputInteractive control is an important aspect of 3D graphics applications. For standard PCs, user-input devices are limited to mouse and keyboard and interactive control must be realised through such devices by monitoring key/mouse actions such as clicking and dragging of the mouse or pressing of the keys. These actions are monitored and handled by JavaScript event handling. Event handling is not a concept special for WebGL API or JavaScript. It is a part of most languages that support interactive applications. If you have some experiences in JavaScript, Java, C++, etc, you may have used it before. Here we briefly introduce the techniques of JavaScript key- and mouse-event handling that you will need in developing interactive WebGL applications.2.1 Key event handlingIn general, three keyboard events are generated when an alphanumeric key is pressed: a keydown event is first generated. a keypress event follows immediately. a keyup event is generated when the key is released, .The keydown and keyup events are actually different from the keypress event. The keydown and keyup events represent physical keys that are pressed down or released, while the keypress event represents which character is typed. A key event has two properties: keyCode contains the ASCII code for the uppercase version of the key. E.g., the key labelled A has a keycode 65, regardless of whether or not Caps lock is enabled. charCode gives you the ASCII value for the resulting character, i.e., A or aThe following example demonstrates the differences:document.addEventListener(‘keydown’, handleKeyDown, false); document.addEventListener(‘keyup’, handleKeyUp, false); document.addEventListener(‘keypress’, handleKeyPress, false);function handleKeyDown(event) {console.log(‘keydown – keyCode=%d, charCode=%d’, event.keyCode, event.charCode);function handleKeyUp(event) {console.log(‘keyup – keyCode=%d, charCode=%d’,event.keyCode, event.charCode);function handleKeyPress(event) {console.log(‘keypress – keyCode=%d, charCode=%d’,event.keyCode, event.charCode);In Firefox, pressing the key A generates the following result in the console:keydown – keyCode=65, charCode=0 keypress – keyCode=0, charCode=97 keyup – keyCode=65, charCode=02.2 Handling multiple keysFor some applications, you need to handle multiple keys at the same time, e.g., in games. To monitor which keys are being pressed at any time, a list of the keys that have been pressed needs to be maintained.Tracking Pressed Keysvar listOfPressedKeys={};//object for keeping the list of pressed keys//keydown event handler function handleKeyDown(event) {// On a keydown event, any immediate actions are handled first if (String.fromCharCode(event.keyCode) == S) {// Fire a weaponfireMissile();} else if (String.fromCharCode(event.keyCode) == W) {doSomething(); } else if()// Then store the information about which key has been pressed listOfPressedKeys[event.keyCode] = true;//Keyup event handler function handleKeyUp(event) {// Update list of keys that are pressed down listOfPressedKeys[event.keyCode] = false;Process Pressed KeysThis function is called each frame in the animation loop. Suppose we want to monitor the arrow keys:function monitorPressedKeys() {if (listOfPressedKeys[38]) {// Arrow up, acceleration speed += 0.5;if (listOfPressedKeys[40]) {// Arrow down, deceleration speed -= 0.5;if (listOfPressedKeys[37]) {// Arrow left, the user wants to turn left. turnLeft();//function to handle turn leftif (listOfPressedKeys[39]) {2.3 Mouse Events// Arrow right, the user wants to turn right. turnRight();//function to handle turn rightHTML 5 specification defines many mouse events. Some are simple events, e.g., mousedown, mouseup, mousemove, mouseover, and mouseout. Most browsers support them. Some are complex events, e.g., click, double click, mousedrag, etc. Such complex events might be useful for graphics applications, e.g., use mousedrag to rotate the viewport. Unfortunately, not all browsers support complex event (e.g., Firefox might not support the mousedrag event).In this tutorial, we will use simple mouse events mousedown, mouseup and mousemove to implement the viewport control. We utilise the properties clientX and clientY, which contain the distance from the mouse pointer to the upper-left corner of the browsers viewport, to specify the amount of translations or rotations. The mousedown and mouseup events also contain a property called button index indicating which mouse button is pressed or released. 0 the left mouse button 1 the middle mouse button/wheel; and 2 the right mouse button.Complete the provided unfinished program by providing the functions draw() and startup() and other missing statements or functions.User input: up & down arrows: change the diameter of the path of the cube mouse drag: rotate the scene Alt+mouse drag (or alt+mouse whel): translation in y Shift+ mouse drag (mouse wheel): translation in zNote: If you start from your program of the last practice, pay attention to the part of the lost context event handling function and variable for the increment control of the background colour. In this tutorial, the lost context control is still in place, but the simulator has been removed.
Reviews
There are no reviews yet.