xxxxxxxxxx
// engineer: jWilliam Dunn
// 2023.0723 trying out new orbitControl in p5.js 1.7.0
// 2023.1028 update to p5.js 1.8.0
// shift middle-click to raise/drop the plane
// space-bar to run
p5.disableFriendlyErrors = true;
document.oncontextmenu=()=>false;
//var cam;
let smokeList = []; // The array of smoke particles
let smokeColor; // The color of the smoke
let smokeRate = 50; // The rate of smoke emission
let smokeCounter = 0; // The counter for smoke emission
function setup() {
createCanvas(windowWidth,windowHeight, WEBGL);
//cam = createEasyCam();
//cam.setRotationConstraint(true,false,false);
smokeColor = color(255);
}
let posA=0, posB=0, run=false;
function plant(){
//upper portion
noStroke();
fill(0,70,100);
translate(0,0,75);
box(100,100,50);
translate(0,0,-75);
//side portion
translate(0,25+12.5,25);
box(100,25,50);
translate(0,-25-12.5,-25);
//side portion
translate(0,-25-12.5,25);
box(100,25,50);
translate(0,+25+12.5,-25);
//edge strokes
noFill();
stroke(0);
strokeWeight(0.25);
translate(0,0,25);
box(100,50,50);
translate(0,0,25);
box(100);
translate(0,0,-50);
//smoke stack
fill(50);
translate(40,40,105);
box(10);
translate(-40,-40,-105);
}
function draw() {
orbitControl();
background(135,206,235);// sky
rotateX(PI/2);
rotateZ(-PI/3);
translate(0,0,-120); // drop the floor of the sketch
directionalLight(208,208,207, 0.25,0.4,-0.3);
directionalLight(208,208,207, -0.25,0.4,0.3);
ambientLight(16,16,15);
//ground
noStroke();
fill(184*0.6,177*0.6,133*0.6);
rotateX(PI/2);
cylinder(1000,1);
rotateX(-PI/2);
//gizmo Z axis
stroke("purple");
strokeWeight(1);
line(0,0,0, 0,0,50);
// conveyor
translate(0,0,1);
noStroke();
fill(170);
box(500,50,1);
translate(0,0,-1);
//plant 1
plant();
if(run&&posA>0.6&&posB<1)posB+=0.005;
// front door
push();
translate(-51,0,28+50*(1-MinJerk(posB)));
fill(127);
noStroke();
strokeWeight(0.25);
box(1.5,52,52);
pop();
// back door
push();
translate(51,0,28+50*(1-MinJerk(posB)));
fill(127);
noStroke();
box(1.5,52,52);
pop();
if(run&&posA<1)posA+=0.005;
if(posB<1) { // if door is open, render the input unit
// input unit
push();
translate(-200*(1-MinJerk(posA)),0,25.5);
fill(127,0,0);
stroke(0);
strokeWeight(0.25);
box(47);
pop();
}
// decoration
push();
translate(150,100,5);
fill(203,177,40);
noStroke();
box(90,70,10);
pop();
push();
translate(-60,-60,5);
rotateZ(PI/2);
fill(63,31,0);
noStroke();
cylinder(5,20, 10);
pop();
if(true||posB>=1) {
// Emit smoke particles
if (smokeCounter % smokeRate == 0) {
let smoke = new Smoke({x:40,y:40,z:110}, smokeColor);
smokeList.push(smoke);
}
smokeCounter++;
// Update smoke particles
for (let i=smokeList.length-1; i>=0; i--) {
let smoke = smokeList[i];
smoke.update();
if (smoke.isDead()) smokeList.splice(i, 1);
}
// Draw the smoke particles
let rsmoke = [smokeList];
rsmoke = rsmoke.reverse();
for (let smoke of rsmoke)
smoke.display();
}
}
function keyPressed() {
if(key==" ")run=true;
}
let MinJerk = t => (6*t*t-15*t+10)*t*t*t;
// Smoke class
class Smoke {
constructor(pos, color) {
this.pos = pos; // The position vector
this.color = color; // The color of the smoke
this.size = random(1.5,3); // The initial size of the smoke
this.shape1 = round(random(5,6));
this.shape2 = round(random(3,4));
this.growth = 0.15; // The growth rate of the smoke
this.lifespan = 255; // The lifespan of the smoke
this.decay = 2; // The decay rate of the smoke
this.rotX = 0;
}
// Update the smoke properties
update() {
// Increase the size
this.size += this.growth;
// Decrease the lifespan
this.lifespan -= this.decay;
// Move up slightly
this.pos.z += random(0.5);
this.pos.x += random(-0.15);
this.pos.y += random(-0.05);
this.rotX += random(0.03);
}
// Display the smoke
display() {
// Draw the smoke as a sphere with transparency
push();
translate(this.pos.x, this.pos.y, this.pos.z);
rotateX(this.rotX);
fill(this.color.levels[0],this.color.levels[1],this.color.levels[2], this.lifespan);
noStroke();
sphere(this.size,this.shape1,this.shape2);
pop();
}
// Check if the smoke is dead
isDead() {
return this.lifespan <= 0;
}
}