package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.utils.setTimeout;
import frocessing.color.ColorHSV;
import org.papervision3d.cameras.CameraType;
import org.papervision3d.cameras.SpringCamera3D;
import org.papervision3d.core.culling.FrustumCuller;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.shadematerials.GouraudMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.view.BasicView;
/**
* ...
* @author Mario
*/
[SWF(width="900", height="480", backgroundColor="#000000")]
public class PaperCity extends BasicView
{
private var COLOR:ColorHSV;
private var p:DisplayObject3D;
public function PaperCity():void
{
super(stage.stageWidth, stage.stageHeight, true, false, CameraType.DEBUG);
Wonderfl.capture_delay(4)
var plane:Plane = new Plane(new WireframeMaterial(0xffffff, 0.1), 10000, 10000, 2, 2)
plane.y = -1500;
plane.pitch(89);
scene.addChild(plane);
camera.far = 10000;
camera.fov = 70;
camera.x = -980;
camera.y = 1500;
camera.z = -2446;
camera.rotationX = 391;
camera.rotationY = 21;
camera.rotationZ = 0;
COLOR = new ColorHSV(1, 1, 1);
init();
}
public function init():void
{
p = new DisplayObject3D()
scene.addChild(p)
var light:PointLight3D = new PointLight3D(false);
light.x = 0;
light.y = 10000;
light.z = 0;
scene.addChild(light);
var cube:Cube;
var buildingCount:int = 1;
var blockCount:int = 13;
var iterator:int;
// Each block has one more building than the last as we go outward
for (var k:int = 0; k < blockCount; k++)
{
// Create each building in that block
for (var j:int = 0; j < buildingCount; j++)
{
var theta:Number = (j / buildingCount) * Math.PI * 2;
var xPos :int = Math.cos(theta) * (300 * k) + Math.random() * 40;
var zPos :int = Math.sin(theta) * (300 * k) + Math.random() * 40;
var size:int = Utils.randRange(200, 400);
var sizeH:int = Utils.randRange(200, 400);
var levels :int = Utils.randRange(1, 5);
var yLevel:int = 0;
/**material**/
COLOR.s = Math.random() * 0.5 + 0.5;
var material:GouraudMaterial = new GouraudMaterial(light, COLOR.value, 0x000000, 1);
var materialsList:MaterialsList = new MaterialsList();
materialsList.addMaterial(material, "all");
// Create the single building
for (var i:int = 0; i < levels; i++)
{
var ratio:Number = (levels - i) / levels;
var width:int = size * ratio;
var depth:int = size * ratio;
var height:int = (size * 2.5) * ratio;
cube = new Cube(materialsList, width, depth, height);
cube.extra = { height: size * ratio };;
cube.name = 'cube' + i;
cube.x = xPos;
cube.y = yLevel;
cube.z = zPos;
//scaleY = 0;
yLevel += ((size * 2) * ratio) + 5;
setTimeout(scene.addChild, iterator * 0.05 * 1000, cube);
iterator++;
}
//iterator += 5;
}
buildingCount++;
}
startRendering();
}
override protected function onRenderTick(e:Event = null):void
{
var c:Cube = scene.getChildByName('cube1') as Cube;
super.onRenderTick(e);
}
}
}
internal class Utils
{
/**
* Return a random element inside an array
* @param array, The array you want to get a random element from
* @return *, An object in that array
*/
public static function randInArray(array:*):*
{
if (array) return array[randRange(0, array.length - 1)];
}
/**
* Random interger within range.
* @param min
* @param max
* @return
*/
public static function randRange(min:int, max:int):int
{
var fmin:Number = min - .4999;
var fmax:Number = max + .4999;
return int(Math.round(fmin + (fmax - fmin) * Math.random()));
}
}
/**
* Modify the color of an asset without destroying color contrast / shading in the asset.
* Uses hue/saturation/brightness/contrast to modify a color keeping contrast between colors in the asset intact
* @version 1.3
*/
internal class ColorHelper
{
/**
* Colorize an asset based on an RGB value
* @param rgb Hex color value
* @param amount How much of the original color to keep. [0.0-1.0], 1.0 means none. Range can exceed 1.0 for experimental results
*/
public static function colorize(rgb:Number, amount:Number=1):Array
{
var r:Number;
var g:Number;
var b:Number;
var inv_amount:Number;
// Found after some googling - @ http://www.faqs.org/faqs/graphics/colorspace-faq/ (ctrl+f luminance)
var LUMA_R:Number = 0.4086;
var LUMA_G:Number = 0.7094;
var LUMA_B:Number = 0.0920;
r = (((rgb >> 16) & 0xFF) / 0xFF);
g = (((rgb >> 8) & 0xFF) / 0xFF);
b = ((rgb & 0xFF) / 0xFF);
inv_amount = (1 - amount);
return concat([(inv_amount + ((amount * r) * LUMA_R)), ((amount * r) * LUMA_G), ((amount * r) * LUMA_B), 0, 0,
((amount * g) * LUMA_R), (inv_amount + ((amount * g) * LUMA_G)), ((amount * g) * LUMA_B), 0, 0,
((amount * b) * LUMA_R), ((amount * b) * LUMA_G), (inv_amount + ((amount * b) * LUMA_B)), 0, 0,
0, 0, 0, 1, 0]);
}
/**
* Concat two matrices
* Could be used to mix colors, but for now it only concacts with an identy matrix
* @param mat Matrix we want to concact
*/
public static function concat( mat:Array ):Array
{
// Identity matrix
var matrix:Array = [1, 0, 0, 0, 0, // RED
0, 1, 0, 0, 0, // GREEN
0, 0, 1, 0, 0, // BLUE
0, 0, 0, 1, 0]; // ALPHA
var temp:Array = new Array();
var i:int = 0;
var x:int, y:int;
// Loop through the matrice
for (y = 0; y < 4; y++ )
{
for (x = 0; x < 5; x++ )
{
temp[ int( i + x) ] = Number(mat[i]) * Number(matrix[x]) +
Number(mat[int(i + 1)]) * Number(matrix[int(x + 5)]) +
Number(mat[int(i + 2)]) * Number(matrix[int(x + 10)]) +
Number(mat[int(i + 3)]) * Number(matrix[int(x + 15)]) +
(x == 4 ? Number(mat[int(i + 4)]) : 0);
}
i+=5;
}
return temp;
}
}