package away3d.lights { import away3d.containers.*; import away3d.core.base.*; import away3d.core.draw.*; import away3d.core.light.*; import away3d.core.render.*; import away3d.core.utils.*; import away3d.materials.ColorMaterial; import away3d.primitives.Sphere; /** * Lightsource that colors all shaded materials proportional to the dot product of the offset vector with the normal vector. * The scalar value of distance does not affect the resulting light intensity, it is calulated as if the * source is an infinite distance away with an infinite brightness. */ public class DirectionalLight3D extends Object3D implements ILightProvider, IClonable { private var _color:int; private var _red:int; private var _green:int; private var _blue:int; private var _ambient:Number; private var _diffuse:Number; private var _specular:Number; private var _brightness:Number; private var _colorDirty:Boolean; private var _ambientDirty:Boolean; private var _diffuseDirty:Boolean; private var _specularDirty:Boolean; private var _brightnessDirty:Boolean; private var _ls:DirectionalLight = new DirectionalLight(); private var _debugPrimitive:Sphere; private var _debugMaterial:ColorMaterial; private var _debug:Boolean; /** * Defines the color of the light object. */ public function get color():int { return _color; } public function set color(val:int):void { _color = val; _red = (_color & 0xFF0000) >> 16; _green = (_color & 0xFF00) >> 8; _blue = (_color & 0xFF); _colorDirty = true; _ambientDirty = true; _diffuseDirty = true; _specularDirty = true; } /** * Defines a coefficient for the ambient light intensity. */ public function get ambient():Number { return _ambient; } public function set ambient(val:Number):void { if (val < 0) val = 0; _ambient = val; _ambientDirty = true; } /** * Defines a coefficient for the diffuse light intensity. */ public function get diffuse():Number { return _diffuse; } public function set diffuse(val:Number):void { if (val < 0) val = 0; _diffuse = val; _diffuseDirty = true; } /** * Defines a coefficient for the specular light intensity. */ public function get specular():Number { return _specular; } public function set specular(val:Number):void { if (val < 0) val = 0; _specular = val; _specularDirty = true; } //TODO: brightness on directional light needs implementing /** * Defines a coefficient for the overall light intensity. */ public function get brightness():Number { return _brightness; } public function set brightness(val:Number):void { _brightness = val; _brightnessDirty = true; } /** * Toggles debug mode: light object is visualised in the scene. */ public function get debug():Boolean { return _debug; } public function set debug(val:Boolean):void { _debug = val; } public function get debugPrimitive():Object3D { if (!_debugPrimitive) _debugPrimitive = new Sphere(); if (!_debugMaterial) { _debugMaterial = new ColorMaterial(); _debugPrimitive.material = _debugMaterial; } _debugMaterial.color = color; return _debugPrimitive; } /** * Creates a new DirectionalLight3D object. * * @param init [optional] An initialisation object for specifying default instance properties. */ public function DirectionalLight3D(init:Object = null) { super(init); color = ini.getColor("color", 0xFFFFFF); ambient = ini.getNumber("ambient", 0.5, {min:0, max:1}); diffuse = ini.getNumber("diffuse", 0.5, {min:0, max:10}); specular = ini.getNumber("specular", 1, {min:0, max:1}); brightness = ini.getNumber("brightness", 1); debug = ini.getBoolean("debug", false); _ls.light = this; addOnTransformChange(_ls.updateDirection); } /** * @inheritDoc */ public function light(consumeer:ILightConsumer):void { //update color if (_colorDirty) { _ls.red = _red; _ls.green = _green; _ls.blue = _blue; } //update ambient diffuse if (_ambientDirty || _diffuseDirty || _brightnessDirty) _ls.updateAmbientDiffuseBitmap(ambient, diffuse); //update ambient if (_ambientDirty || _brightnessDirty) { _ambientDirty = false; _ls.updateAmbientBitmap(ambient); } //update diffuse if (_diffuseDirty || _brightnessDirty) { _diffuseDirty = false; _ls.updateDiffuseBitmap(diffuse); } //update specular if (_specularDirty || _brightnessDirty) { _specularDirty = false; _ls.updateSpecularBitmap(specular); } consumeer.directionalLight(_ls); _colorDirty = false; _brightnessDirty = false; } /** * Duplicates the light object's properties to another DirectionalLight3D object * * @param object [optional] The new object instance into which all properties are copied * @return The new object instance with duplicated properties applied */ public override function clone(object:Object3D = null):Object3D { var light:DirectionalLight3D = (object as DirectionalLight3D) || new DirectionalLight3D(); super.clone(light); light.color = color; light.brightness = brightness; light.ambient = ambient; light.diffuse = diffuse; light.specular = specular; light.debug = debug; return light; } } }