Welcome! The code to the right is what we created in tutorial 1 with one small change: on line 10, we've reduced the dimensions of the box to 100.
In this next tutorial, we'll work with camera state which will allow us to animate the camera to a specific position. Later, we'll add a "head-up-display", also known as a HUD, which allows us to display screen-aligned information on a 2D plane, independent of the 3D scene. That means if we rotate the camera, the screen-aligned elements do not move.
First, let's add a couple of global variables. One will hold a reference to the EasyCam object instance. The second will contain a state object which identifies a specific camera orientation in the scene.
var easycam,
state = {
distance: 208,
center : [5, 3, -13],
rotation: [0.3, -0.4, -0.1, 0.85]
};
Next, in the setup() function on line 11, we assign the return value of createEasyCam() to the variable easycam. This will give us access to the methods within the EasyCam object.
On line 14, we call the .setState() method and pass the state object as the first parameter and the duration of the animation as the second parameter, specified in milliseconds. (1 second = 1000 milliseconds)
On line 15, we set the .state_reset property to be equal to the state object. If we don't do this, then a double-click or double tap would send the camera back to its default position rather than our desired new position. Experiment with this to see the difference.
Go ahead and run the sketch at this point to see the start up animation. We can still move the camera around and reset it back to the saved state position at any time with a double-click/tap.
Note: there are many ways to work with camera state. For instance, we could pass the state object as a parameter to the createEasyCam(). This would set the initial camera orientation to that defined in the state object. We could also create an array of states and connect screen objects or assign keys on the keyboard to trigger animations to those states. We can also query the state of the camera, store those states, or display them. Which takes us to the next step.
Now we'll add the HUD. This feature is useful to display the current state of a model.
First, we'll add two more global variables, x and y at line 7. These will serve as the base coordinates for our screen-aligned information display box. If you want to move the HUD to a different location on the screen, just adjust x and y. That's smart programming.
Next, we'll add a preload function. In 3D mode, only fonts loaded via loadFont() can be rendered, so they must be loaded from an external file.
function preload() {
f = loadFont('path-to-file/Roboto.otf');
}
On line 16, we can add a call to setAttributes() in order to enable anti-aliasing. This is more of a cosmetic option so that lines are smoothed.
Next, on lines 24 and 25, we use the font we just loaded and set the font size. We also adjust the global stroke color and weight - some cosmetic preferences to refine the on-screen design.
Line 34 could be more than a simple box. This is where you might render your next creation.
On line 37, we begin our HUD context. Notice the next lines of code are indented until we end our context. Some programmers do this with push() and pop() also. It helps to indicate that this section is slightly different than our 3D section above. Plus, it truly is a new context - the strokes and fills are not remembered.
On line 38, we turn off the lights because we do not want our 2D screen objects to be affected by the underlying 3D lighting model.
On line 39, we query the camera state with the method .getState() so we can display this in the HUD information area.
Lines 42-46 set up the background box for the HUD. These are 2D primitives used here, but they could also be 3D if you want to create some dimension. Note the slight transparency we are giving the fill on line 45.
Lines 49-53 create the labels for the data we are about to display.
Lines 56-60 display the camera state and the rendering frameRate(). Note, all these values are passed into the nfs() utility function to format the numbers into strings. Learn more about nfs here.
Go ahead and run the final sketch.
Another way to do HUD is to create and utilize additional HTML elements that sit above the canvas. There are examples of this in the EasyCam repository on GitHub, specifically: CameraStates and HeadUpDisplay.
document.oncontextmenu =()=> false;
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
createEasyCam();
}
function draw() {
background(0);
lights();
box(100);
}