xxxxxxxxxx
103
let customModel; // Hold our custom double perspective model
let enterAnimationDuration = 3; // seconds initial loading animation will last
let enterAnimationFrames; // frames initial loading animation will last
let faceCam; // Camera pointing to the face
let bulbCam; // Camera pointing to the lightbulb
let mainCam; // Camera user controls
let mainToFaceCamFrame; // Frame user decides to view the face
let mainToBulbCamFrame; // Frame user decides to view the lightbulb
// Initially I wrote my own easing function, following www.febucci.com/2018/08/easing-functions,
// but then I found easings.net, and after trying a bunch, choose the "Elastic Ease In and Out", found below
function easeInOutElastic(x) {
const c5 = (2 * Math.PI) / 4.5;
return x === 0
? 0
: x === 1
? 1
: x < 0.5
? -(Math.pow(2, 20 * x - 10) * Math.sin((20 * x - 11.125) * c5)) / 2
: (Math.pow(2, -20 * x + 10) * Math.sin((20 * x - 11.125) * c5)) / 2 + 1;
}
function preload() {
customModel = loadModel('perspective model.obj', true)
}
function setup() {
// Initialise the canvas
createCanvas(400, 400, WEBGL);
frameRate(60);
windowResized(); // Just calling it manually to resize the window without duplicating code
// Animate entry animation in specified duration, regardless of frame rate
enterAnimationFrames = getTargetFrameRate() * enterAnimationDuration;
// Initialise camera, and point to the 1st side (face)
faceCam = createCamera();
faceCam.ortho();
faceCam.setPosition(0, 0, 800);
faceCam.lookAt(0, 1, 0)
// Initialise camera, and point to the 2nd side (lightbulb-heart)
bulbCam = createCamera();
bulbCam.ortho();
bulbCam.setPosition(800, 0, 0);
bulbCam.lookAt(0, 1, 0)
// Initialise main camera
mainCam = createCamera();
ortho();
noStroke();
}
function draw() {
background('honeydew'); // Some other nice bg colours: seashell', 'azure'
// Allow the user to move the camera around (orbiting the model)
orbitControl();
// Add some lightning (it adds an ambient and directional light)
lights();
// The initial entry animation
if (frameCount < enterAnimationFrames) {
rotateY(lerp(0, TWO_PI*2, easeInOutElastic(frameCount/enterAnimationFrames)));
scale(lerp(0, 1, easeInOutElastic(frameCount/enterAnimationFrames)));
}
// Transition the main camera to point towards the 1st side (face)
if (frameCount - mainToFaceCamFrame < getFrameRate()) {
mainCam.slerp(mainCam, faceCam, 9/getFrameRate())
}
// Transition the main camera to point towards the 2nd side (lightbulb)
if (frameCount - mainToBulbCamFrame < getFrameRate()) {
mainCam.slerp(mainCam, bulbCam, 9/getFrameRate())
}
// Draw custom model
fill(64, 112, 112);
model(customModel);
}
function keyPressed(event) {
if (event.key == 1) {
// Transition camera to first camera (looking at the 1st side)
mainToFaceCamFrame = frameCount
} else if (event.key == 2) {
// Transition camera to second camera (looking at the 2nd side)
mainToBulbCamFrame = frameCount
}
}
function windowResized() {
// Resize the canvas, while preserving the aspect ratio
let windowSize = windowWidth > windowHeight ? windowHeight : windowWidth
resizeCanvas(windowSize, windowSize)
}