Getting psychedelic with Sandy 3D
Posted by Dennis on Sep 13, 2007 in 3D, ActionScript, Flash, Flex • 8 commentsSandy 3D on acid … Created with 3ds Max combined with Dreammania’s AS3 Geom Class Exporter. Sandy 3.0 will be released in a few weeks, so the wait is almost over!! I’ve included the main class so you can see what’s going on here …
Turn on, tune in, drop out
Here are all the classes that are used.
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.BlurFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
import sandy.core.World3D;
import sandy.core.light.Light3D;
import sandy.core.scenegraph.Camera3D;
import sandy.core.scenegraph.Group;
import sandy.materials.Appearance;
import sandy.materials.ColorMaterial;
[SWF(width="600", height="600", backgroundColor="#000000", frameRate="48")]
/**
* SandyPsychedelic.as
* 13 September 2007
* @author Dennis Ippel - http://www.rozengain.com
*
*/
public class SandyPsychedelic extends Sprite
{
private var world:World3D;
private var speed:Number,
radius1:Number, radius2:Number, radius3:Number,
angle1:Number, angle2:Number, angle3:Number,
startZPos:int,
zIncrement:int,
currentColorIndex:uint,
colors:Array;
private var yingyang:YingYang,
peaceSymbol:PeaceSymbol,
ohm:Ohm;
private var screenBitmapData:BitmapData;
private var screenBitmap:Bitmap;
/**
* Initialize the 3D scene and create the symbols
*
*/
public function SandyPsychedelic()
{
// -- set all radii to 0
radius1 = radius2 = radius3 = 0;
// -- give each symbol a different start angle value
angle1 = 0;
angle2 = 45;
angle3 = 90;
// -- standard symbol depth. this value is used to
// reset a symbol's position once it has disappeared
// behind the camera
startZPos = -6000;
// -- the speed with which a symbol flies towards the camera
zIncrement = 100;
// -- create an array with some psychedelic colors
createColorArray();
// -- create a bitmapdata object. this is used to copy
// what's on the screen in a given frame. this creates
// the illusion that there's more than 3 objects in
// the scene.
screenBitmapData = new BitmapData(
800,
800,
false,
0x000000
);
screenBitmap = new Bitmap();
addChild( screenBitmap );
// -- instantiate the 3D world
world = World3D.getInstance();
world.container = this;
world.root = new Group( "rootGroup" );
world.light.setPower( Light3D.MAX_POWER );
// -- create the camera
world.camera = new Camera3D( 600, 600 );
world.camera.x = 0;
world.camera.y = 0;
world.camera.z = 300;
world.camera.lookAt( 0, 0, 0 );
world.root.addChild( world.camera );
// -- create the Ying Yang symbol
yingyang = new YingYang( "yingyang" );
yingyang.appearance = new Appearance(
new ColorMaterial( nextColor )
);
yingyang.appearance.frontMaterial.lightingEnable = true;
yingyang.z = startZPos;
// -- create the Peace symbol
peaceSymbol = new PeaceSymbol( "peace" );
peaceSymbol.appearance = new Appearance(
new ColorMaterial( nextColor )
);
peaceSymbol.appearance.frontMaterial.lightingEnable = true;
peaceSymbol.z = startZPos;
peaceSymbol.visible = false;
// -- create the Ohm symbol
ohm = new Ohm( "ohm" );
ohm.appearance = new Appearance(
new ColorMaterial( nextColor )
);
ohm.appearance.frontMaterial.lightingEnable = true;
ohm.z = startZPos;
ohm.visible = false;
// -- add the symbols to the scene
world.root.addChild( yingyang );
world.root.addChild( peaceSymbol );
world.root.addChild( ohm );
// -- start the animation loop
addEventListener( Event.ENTER_FRAME, animate );
}
/**
* The animation loop
* @param event
*
*/
private function animate( event:Event ):void
{
// -- animate the Ying Yang symbol
yingyang.x = Math.sin( angle1 ) * radius1;
yingyang.y = Math.cos( angle1 ) * radius1;
yingyang.rotateY += 8;
yingyang.z += zIncrement;
// -- update for the next step
angle1 += 0.5;
radius1 += 1;
if( peaceSymbol.visible )
{
// -- animate the Peace symbol
peaceSymbol.x = Math.sin( angle2 ) * radius2;
peaceSymbol.y = Math.cos( angle2 ) * radius2;
peaceSymbol.rotateY += 8;
peaceSymbol.z += zIncrement;
// -- update for the next step
angle2 += 0.5;
radius2 += 1;
}
if( ohm.visible )
{
// -- animate the Ohm symbol
ohm.x = Math.sin( angle3 ) * radius3;
ohm.y = Math.cos( angle3 ) * radius3;
ohm.rotateY += 8;
ohm.z += zIncrement;
// -- update for the next step
angle3 += 0.5;
radius3 += 1;
}
// -- copy the current screen into a bitmapdata
// object.
captureScreen();
// -- render the 3D scene
world.render();
if( yingyang.z > world.camera.z )
{
// -- reset the position and give it a new color
yingyang.z = startZPos;
yingyang.appearance.frontMaterial = new ColorMaterial( nextColor );
yingyang.appearance.frontMaterial.lightingEnable = true;
radius1 = 0;
} else if( yingyang.z >= startZPos * 0.3 && !peaceSymbol.visible ) {
// -- show the Peace symbol for the first time
peaceSymbol.visible = true;
} else if( yingyang.z >= startZPos * 0.6 && !ohm.visible ) {
// -- show the Ying Yang symbol for the first time
ohm.visible = true;
}
if( peaceSymbol.z > world.camera.z )
{
// -- reset the position and give it a new color
peaceSymbol.z = startZPos;
peaceSymbol.appearance.frontMaterial = new ColorMaterial( nextColor );
peaceSymbol.appearance.frontMaterial.lightingEnable = true;
radius2 = 0;
}
if( ohm.z > world.camera.z )
{
// -- reset the position and give it a new color
ohm.z = startZPos;
ohm.appearance.frontMaterial = new ColorMaterial( nextColor );
ohm.appearance.frontMaterial.lightingEnable = true;
radius3 = 0;
}
}
/**
* Create the color array and fill it up with
* psychedelic colors.
*
*/
private function createColorArray():void
{
colors = [
0xff0000,
0x00ff00,
0xffffff,
0xffa500,
0xffff00,
0x0000ff
];
}
/**
* Get the next color from the array
* @return the next color
*
*/
private function get nextColor():uint
{
if( currentColorIndex == colors.length )
currentColorIndex = 0;
return colors[ currentColorIndex++ ];
}
/**
* Store the current frame in a BitmapData object
* and apply a BlurFilter
*
*/
private function captureScreen():void
{
screenBitmapData.draw(
this
);
screenBitmapData.applyFilter(
screenBitmapData,
new Rectangle( 0, 0, 800, 800 ),
new Point( 0, 0 ),
new BlurFilter( 2, 2, 1 )
);
screenBitmap.bitmapData = screenBitmapData;
}
}
}




Hi Dennis!
That’s a beauty
Let’s have it as a demo for Sandy!
Really nice. How do you do that…
Wonder how I could use this to improve the user experience of my website. You guys seem to know what you are doing. Would be great if you could do some fresh postings on a frequent basis.
It’s very good article. Great site with very good look and perfect information. I like it too.
Nice work. Would love to have this eye catcher on my website
WoW that looks really good. I wish I knew how to code like you guys
My compliments.
wow…just passing thru and saw this. I would LOVE to have this for a screensaver….
I’m happy to tell you that Sandy 3.1 will be released very soon, probably today
It is further enhanced for flexibility and with some new features.
So go ahead and test it!