Compare commits
10 commits
2c9514f7fa
...
098623f86c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
098623f86c | ||
|
|
cf5b81ec8b | ||
|
|
f41b131563 | ||
|
|
3232913c81 | ||
|
|
4c7933b802 | ||
|
|
c0d1a3cd74 | ||
|
|
92a91b3295 | ||
|
|
6fd82fd0d7 | ||
|
|
10206177c7 | ||
|
|
3fa5b4f4c6 |
|
|
@ -1,4 +1,10 @@
|
||||||
Run with `python3 -m http.server`
|
# Running locally
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python3 -m http.server 8080
|
||||||
|
```
|
||||||
|
|
||||||
|
Then simply go to [http://0.0.0.0:8080](http://0.0.0.0:8080) in your browser.
|
||||||
|
|
||||||
# Acknowledgement
|
# Acknowledgement
|
||||||
|
|
||||||
|
|
|
||||||
3978
assets/onion_fill.obj
Normal file
3978
assets/onion_fill.obj
Normal file
File diff suppressed because it is too large
Load diff
30425
assets/onion_stroke.obj
Normal file
30425
assets/onion_stroke.obj
Normal file
File diff suppressed because it is too large
Load diff
121
sketch.js
121
sketch.js
|
|
@ -15,9 +15,9 @@ class RotatingOnion {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an orbiting object to the onion
|
// Add an orbiting object to the onion
|
||||||
addOrbitingObject(orbitRadius, speed, scale, tiltAngleX, tiltAngleY) {
|
addOrbitingObject(model, orbitRadius, speed, scale, tiltAngleX, tiltAngleY) {
|
||||||
const tiltAngle = { x: tiltAngleX, y: tiltAngleY }; // Pass both X and Y tilt angles
|
const tiltAngle = { x: tiltAngleX, y: tiltAngleY }; // Pass both X and Y tilt angles
|
||||||
this.orbitingObjects.push(new OrbitingObject(this, orbitRadius, speed, scale, tiltAngle));
|
this.orbitingObjects.push(new OrbitingObject(this, model, orbitRadius, speed, scale, tiltAngle));
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
|
|
@ -40,7 +40,11 @@ class RotatingOnion {
|
||||||
rotateY(this.angles.y);
|
rotateY(this.angles.y);
|
||||||
rotateZ(this.angles.z);
|
rotateZ(this.angles.z);
|
||||||
scale(this.scale);
|
scale(this.scale);
|
||||||
model(onion);
|
model(onion_stroke);
|
||||||
|
push()
|
||||||
|
emissiveMaterial(backgroundColor)
|
||||||
|
model(onion_fill);
|
||||||
|
pop()
|
||||||
|
|
||||||
// Display all orbiting objects
|
// Display all orbiting objects
|
||||||
for (let obj of this.orbitingObjects) {
|
for (let obj of this.orbitingObjects) {
|
||||||
|
|
@ -66,11 +70,18 @@ class RotatingOnion {
|
||||||
}
|
}
|
||||||
|
|
||||||
class OrbitingObject {
|
class OrbitingObject {
|
||||||
constructor(parent, orbitRadius, speed, scale, tiltAngle) {
|
constructor(parent, model, orbitRadius, speed, scale, tiltAngle) {
|
||||||
this.parent = parent; // The parent object (Onion)
|
this.parent = parent; // The parent object (Onion)
|
||||||
|
this.model = model
|
||||||
this.orbitRadius = orbitRadius;
|
this.orbitRadius = orbitRadius;
|
||||||
this.speed = speed; // Orbiting speed (angular speed)
|
this.speed = speed; // Orbiting speed (angular speed)
|
||||||
this.scale = scale;
|
this.scale = scale;
|
||||||
|
this.rotationAngle_x = random(360);
|
||||||
|
this.rotationAngle_y = random(360);
|
||||||
|
this.rotationAngle_z = random(360);
|
||||||
|
this.rotationSpeed_x = random(0.5, 2);
|
||||||
|
this.rotationSpeed_y = random(0.5, 2);
|
||||||
|
this.rotationSpeed_z = random(0.5, 2);
|
||||||
|
|
||||||
this.angle = random(360); // Start at a random position in the orbit
|
this.angle = random(360); // Start at a random position in the orbit
|
||||||
this.tiltAngle = tiltAngle;
|
this.tiltAngle = tiltAngle;
|
||||||
|
|
@ -80,6 +91,11 @@ class OrbitingObject {
|
||||||
// Update the angle to simulate rotation around the parent
|
// Update the angle to simulate rotation around the parent
|
||||||
this.angle += this.speed;
|
this.angle += this.speed;
|
||||||
|
|
||||||
|
// Rotate in place
|
||||||
|
this.rotationAngle_x += this.rotationSpeed_x;
|
||||||
|
this.rotationAngle_y += this.rotationSpeed_y;
|
||||||
|
this.rotationAngle_z += this.rotationSpeed_z;
|
||||||
|
|
||||||
// Calculate the position of the orbiting object in the un-tilted plane
|
// Calculate the position of the orbiting object in the un-tilted plane
|
||||||
const x = this.orbitRadius * cos(this.angle);
|
const x = this.orbitRadius * cos(this.angle);
|
||||||
const z = this.orbitRadius * sin(this.angle);
|
const z = this.orbitRadius * sin(this.angle);
|
||||||
|
|
@ -105,32 +121,94 @@ class OrbitingObject {
|
||||||
display() {
|
display() {
|
||||||
push();
|
push();
|
||||||
translate(this.x, this.y, this.z); // Move to the correct orbit position
|
translate(this.x, this.y, this.z); // Move to the correct orbit position
|
||||||
sphere(this.scale); // Display the object (could be another model or shape)
|
|
||||||
|
// Apply in-place rotation
|
||||||
|
rotateX(this.rotationAngle_x)
|
||||||
|
rotateY(this.rotationAngle_y);
|
||||||
|
rotateZ(this.rotationAngle_z)
|
||||||
|
|
||||||
|
scale(this.scale);
|
||||||
|
model(this.model);
|
||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Text3D {
|
||||||
|
constructor(fromColor, toColor, textString, position_x, position_y) {
|
||||||
|
this.position_x = position_x
|
||||||
|
this.position_y = position_y
|
||||||
|
this.fromColor = fromColor;
|
||||||
|
this.toColor = toColor;
|
||||||
|
this.textString = textString;
|
||||||
|
this.depth = 30; // Number of layers for 3D effect
|
||||||
|
this.depthSpacing = 0.60; // Depth spacing between layers
|
||||||
|
this.rotationY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
// Apply rotation toward the camera
|
||||||
|
rotateY(this.rotationY);
|
||||||
|
|
||||||
|
push();
|
||||||
|
for (let i = 0; i < this.depth; i++) {
|
||||||
|
let r = map(i, 0, this.depth - 1, this.fromColor[0], this.toColor[0]);
|
||||||
|
let g = map(i, 0, this.depth - 1, this.fromColor[1], this.toColor[1]);
|
||||||
|
let b = map(i, 0, this.depth - 1, this.fromColor[2], this.toColor[2]);
|
||||||
|
|
||||||
|
fill(r, g, b);
|
||||||
|
translate(0, 0, this.depthSpacing);
|
||||||
|
text(this.textString, this.position_x, this.position_y);
|
||||||
|
}
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
// Get the camera position
|
||||||
|
let camX = camera.eyeX;
|
||||||
|
let camZ = camera.eyeZ;
|
||||||
|
|
||||||
|
// Get the camera position
|
||||||
|
let targetRotY = atan2(camX, camZ); // Calculate target Y rotation
|
||||||
|
|
||||||
|
// Ensure shortest rotation path by normalizing angles
|
||||||
|
let delta = (targetRotY - this.rotationY + 540) % 360 - 180; // Keeps within -180 to 180 range
|
||||||
|
this.rotationY += delta * 0.05; // Interpolate rotation smoothly
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
onion = loadModel('./assets/onion.obj');
|
onion_stroke = loadModel('./assets/onion_stroke.obj');
|
||||||
|
onion_fill = loadModel('./assets/onion_fill.obj');
|
||||||
font = loadFont('./assets/jgs5.ttf');
|
font = loadFont('./assets/jgs5.ttf');
|
||||||
}
|
}
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
createCanvas(windowWidth, windowHeight, WEBGL);
|
createCanvas(windowWidth, windowHeight, WEBGL);
|
||||||
angleMode(DEGREES);
|
angleMode(DEGREES);
|
||||||
ambientMaterial(0, 0, 0, 0);
|
noStroke();
|
||||||
stroke(255);
|
|
||||||
strokeWeight(0.5);
|
|
||||||
textFont(font, 60);
|
textFont(font, 60);
|
||||||
textAlign(CENTER, CENTER);
|
textAlign(CENTER, CENTER);
|
||||||
randomSeed()
|
randomSeed()
|
||||||
|
|
||||||
|
// Background color
|
||||||
|
backgroundColor = [0, 0, 0];
|
||||||
|
|
||||||
|
// Initialize camera to get its position
|
||||||
|
camera = createCamera();
|
||||||
|
|
||||||
|
// Initialize 3D text
|
||||||
|
startGradient = [210, 0, 255]; // Start color
|
||||||
|
endGradient = [0, 255, 180]; // End color
|
||||||
|
text3D = new Text3D(startGradient, endGradient, "PLACEHOLDER", 0, 350);
|
||||||
|
|
||||||
// Initialize the onion object with radius, angles, and scale
|
// Initialize the onion object with radius, angles, and scale
|
||||||
onionObj = new RotatingOnion({ x: 0, y: random(360), z: 180 }, globalScaleVar);
|
onionObj = new RotatingOnion({ x: 0, y: random(360), z: 180 }, globalScaleVar);
|
||||||
|
|
||||||
// Add orbiting objects to the onion
|
// Add orbiting objects to the onion
|
||||||
for (let i = 1.8; i <= 4.8; i += 0.6) {
|
for (let i = 1.8; i <= 4.8; i += 0.6) {
|
||||||
onionObj.addOrbitingObject(
|
onionObj.addOrbitingObject(
|
||||||
|
onion_fill,
|
||||||
i,
|
i,
|
||||||
random(0.1, 0.8),
|
random(0.1, 0.8),
|
||||||
globalScaleVar * 0.0001 * random(1, 6),
|
globalScaleVar * 0.0001 * random(1, 6),
|
||||||
|
|
@ -141,18 +219,29 @@ function setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
background(0);
|
background(backgroundColor);
|
||||||
noFill();
|
|
||||||
orbitControl();
|
orbitControl();
|
||||||
|
ambientLight(100);
|
||||||
|
shininess(0);
|
||||||
|
specularMaterial(255, 255, 255);
|
||||||
|
|
||||||
// Update the onion object
|
directionalLight(
|
||||||
|
startGradient[0], startGradient[1], startGradient[2], // color
|
||||||
|
-180, 180, 0 // direction
|
||||||
|
);
|
||||||
|
|
||||||
|
directionalLight(
|
||||||
|
endGradient[0], endGradient[1], endGradient[2], // color
|
||||||
|
180, -180, 0 // direction
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update objects
|
||||||
onionObj.update();
|
onionObj.update();
|
||||||
|
text3D.update();
|
||||||
|
|
||||||
// Display the onion and its orbiting objects
|
// Display the onion, orbiting objects and the 3D text
|
||||||
onionObj.display();
|
onionObj.display();
|
||||||
|
text3D.display();
|
||||||
fill(255, 255, 255);
|
|
||||||
text('PLACEHOLDER', 0, 350);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function windowResized() {
|
function windowResized() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue