/** (c) subpixel 2009 - http://subpixels.com * * class Flier * 2009-01-20 Created by subpixel */ // ---------------------------------------------------------------------------- // The objects "flying" through space. Asteroids, whatever. // ---------------------------------------------------------------------------- public class Flier { Scene scene; // The scene this flier belongs to Channel channel; // The effect channel controlling this flier // Position float X; float Y; float Z; // Velocity float vX; float vY; float vZ; // Rotation float thetaX; float thetaY; float thetaZ; // Angular velocity float omegaX; float omegaY; float omegaZ; // Size of central box float szCentral; // Size of surrounding boxes float s1; float s2; float s3; float s4; float s5; float s6; // Distance of surrounding boxes from central box (measured from cenres) float d1; float d2; float d3; float d4; float d5; float d6; // -------------------------------------------------------------------------- // Constructor // -------------------------------------------------------------------------- Flier(Scene scene, Channel channel) { this.scene = scene; this.channel = channel; randomise(); } // -------------------------------------------------------------------------- // Set new location etc with randomised values // -------------------------------------------------------------------------- void randomise() { X = 0; Y = 0; Z = -random(1000); vX = random(-1, 1); vY = random(-1, 1); vZ = random(10) + 0.2; thetaX = random(TWO_PI); thetaY = random(TWO_PI); thetaZ = 0; // Already as (dis-)oriented as one can be from 2 axes. :o) omegaX = random(0.01, 0.1); omegaY = random(0.01, 0.1); omegaZ = 0; // Spinning on a 3rd axis doesn't help.. gives strange motion float sz = random(1, 4) * 10; float sz_2 = sz * 0.5; szCentral = sz; // Set size of the central box if (scene.master.forceRegular || channel.forceRegular) { s1 = s2 = s3 = s4 = s5 = s6 = sz_2; // Half central box size d1 = d2 = d3 = d4 = d5 = d6 = sz; // Spaced by central box size } else { // Size of 6 boxes surrounding central box s1 = random(sz_2, sz); s2 = random(sz_2, sz); s3 = random(sz_2, sz); s4 = random(sz_2, sz); s5 = random(sz_2, sz); s6 = random(sz_2, sz); // Distance of 6 surrounding boxes from central box (measured from centres) d1 = sz_2 + random(s1 / 2, s1 * 2); d2 = sz_2 + random(s2 / 2, s2 * 2); d3 = sz_2 + random(s3 / 2, s3 * 2); d4 = sz_2 + random(s4 / 2, s4 * 2); d5 = sz_2 + random(s5 / 2, s5 * 2); d6 = sz_2 + random(s6 / 2, s6 * 2); } } // -------------------------------------------------------------------------- // Paint to screen // -------------------------------------------------------------------------- void draw() { if (!scene.master.display || !channel.display) return; pushMatrix(); // For entre method // ------------------------------------------------------------------------ // Base settings for flier: location, orientation, fill colour // ------------------------------------------------------------------------ translate(X, Y, Z); // Central box position rotateX(thetaX); // Orientation rotateY(thetaY); // ... rotateZ(thetaZ); // ... color fillColour = color(100); // White 100% opacity if (channel.effectActive[1]) // Yellow boxes fillColour = color(17, 90, 100); // Yellow 100% opacity // Don't stroke edges. noStroke(); // ------------------------------------------------------------------------ // Central box // ------------------------------------------------------------------------ pushMatrix(); if (channel.effectActive[0]) // Yellow sphere centre { fill(17, 100, 100, 90); // Yello 90% opacity sphere(szCentral / 2); } else // Usual box { fill(fillColour); box(szCentral); } popMatrix(); // ------------------------------------------------------------------------ // RIGHT SIDE // ------------------------------------------------------------------------ pushMatrix(); translate(d1, 0, 0); fill(fillColour); box(s1); popMatrix(); // ------------------------------------------------------------------------ // LEFT SIDE // ------------------------------------------------------------------------ pushMatrix(); translate(-d2, 0, 0); fill(fillColour); box(s2); popMatrix(); // ------------------------------------------------------------------------ // BOTTOM SIDE // ------------------------------------------------------------------------ pushMatrix(); translate(0, d3, 0); fill(fillColour); box(s3); popMatrix(); // ------------------------------------------------------------------------ // TOP SIDE // ------------------------------------------------------------------------ pushMatrix(); if (channel.effectActive[2]) // Heli blades head { EffectParameters ep = channel.effectParams[2]; translate(0, -d4, 0); rotateY(ep.elapsedTime * 0.015); // Spin the blades fill(240, 90, 100); // Blue 100% opacity box(s4*0.75); // Wing-nut ;o) // Heli blades float wingspan = szCentral * 8; fill(100); // White 100% opacity box(wingspan, -s4/8, s4/2); box(s4/2, -s4/8, wingspan); } else // Usual box { translate(0, -d4, 0); // TOP SIDE fill(fillColour); box(s4); } popMatrix(); // ------------------------------------------------------------------------ // FRONT SIDE // ------------------------------------------------------------------------ if (channel.effectActive[3]) // Heli cockpit { pushMatrix(); translate(0, d4/2, d5); fill(67, 75, 100, 80); // Some pale blue, 80% opacity box(s5*2.5, s5, s5*3); popMatrix(); } else { pushMatrix(); translate(0, 0, d5); fill(fillColour); box(s5); popMatrix(); } // ------------------------------------------------------------------------ // BACK SIDE // ------------------------------------------------------------------------ pushMatrix(); translate(0, 0, -d6); fill(fillColour); box(s6); popMatrix(); // ------------------------------------------------------------------------ // Effects... // ------------------------------------------------------------------------ // EffectParameters epm; // EffectParameters epc; // // // Effect BLAH // pushMatrix(); // if (channel.effectActive[0]) // { // fill(17, 100, 100, 90); // Yellow 90% opacity // sphere(50); // } // popMatrix(); // ------------------------------------------------------------------------ // Done // ------------------------------------------------------------------------ popMatrix(); } // -------------------------------------------------------------------------- // update state // -------------------------------------------------------------------------- public void update() { if (!scene.master.doUpdate || !channel.doUpdate) return; // Update position and rotation if(Z > 2000) // Flown past us ("through the screen") already { randomise(); } else { //TODO: precalc adjustments for all channles outside this loop if (scene.master.travel && channel.travel) { float velocityAdjustment = scene.master.velocityAdjust ? scene.master.velocityAdjustment : 1.0; if (channel.velocityAdjust) velocityAdjustment *= channel.velocityAdjustment; if (velocityAdjustment != 0) // Move (constant velocity) { X += vX * velocityAdjustment; Y += vY * velocityAdjustment; Z += vZ * velocityAdjustment; } } if (scene.master.tumble && channel.tumble) { float tumbleAdjustment = scene.master.tumbleAdjust ? scene.master.tumbleAdjustment : 1.0; if (channel.tumbleAdjust) tumbleAdjustment *= channel.tumbleAdjustment; // Limit the adjustment factor; too fast looks rubbish if (tumbleAdjustment < -maxTumbleAdjustment) tumbleAdjustment = -maxTumbleAdjustment; else if (tumbleAdjustment > maxTumbleAdjustment) tumbleAdjustment = maxTumbleAdjustment; if (tumbleAdjustment != 0) // Rotate { thetaX += omegaX * tumbleAdjustment; thetaY += omegaY * tumbleAdjustment; thetaZ += omegaZ * tumbleAdjustment; } } } } }